using System.Collections.Generic; using System.Text.Json.Serialization; using Core.Models.Common; using Core.Models.Eft.Common.Tables; namespace Core.Models.Spt.Config; public class BotConfig : BaseConfig { [JsonPropertyName("kind")] public string Kind { get; set; } = "spt-bot"; /** How many variants of each bot should be generated on raid start */ [JsonPropertyName("presetBatch")] public PresetBatch PresetBatch { get; set; } /** Bot roles that should not have PMC types (pmcBEAR/pmcUSEC) added as enemies to */ [JsonPropertyName("botsToNotAddPMCsAsEnemiesTo")] public List BotsToNotAddPMCsAsEnemiesTo { get; set; } /** What bot types should be classified as bosses */ [JsonPropertyName("bosses")] public List Bosses { get; set; } /** Control weapon/armor durability min/max values for each bot type */ [JsonPropertyName("durability")] public BotDurability Durability { get; set; } /** Controls the percentage values of randomization item resources */ [JsonPropertyName("lootItemResourceRandomization")] public Dictionary LootItemResourceRandomization { get; set; } /** Control what bots are added to a bots revenge list key: bottype, value: bottypes to revenge on seeing their death */ [JsonPropertyName("revenge")] public Dictionary> Revenge { get; set; } /** Control how many items are allowed to spawn on a bot * key: bottype, value: */ [JsonPropertyName("itemSpawnLimits")] public Dictionary> ItemSpawnLimits { get; set; } /** Blacklist/whitelist items on a bot */ [JsonPropertyName("equipment")] public Dictionary Equipment { get; set; } /** Show a bots botType value after their name */ [JsonPropertyName("showTypeInNickname")] public bool ShowTypeInNickname { get; set; } /** What ai brain should a normal scav use per map */ [JsonPropertyName("assaultBrainType")] public Dictionary> AssaultBrainType { get; set; } /** What ai brain should a player scav use per map */ [JsonPropertyName("playerScavBrainType")] public Dictionary> PlayerScavBrainType { get; set; } /** Max number of bots that can be spawned in a raid at any one time */ [JsonPropertyName("maxBotCap")] public Dictionary MaxBotCap { get; set; } /** Chance scav has fake pscav name e.g. Scav name (player name) */ [JsonPropertyName("chanceAssaultScavHasPlayerScavName")] public int ChanceAssaultScavHasPlayerScavName { get; set; } /** How many stacks of secret ammo should a bot have in its bot secure container */ [JsonPropertyName("secureContainerAmmoStackCount")] public int SecureContainerAmmoStackCount { get; set; } /** Bot roles in this array will be given a dog tag on generation */ [JsonPropertyName("botRolesWithDogTags")] public List BotRolesWithDogTags { get; set; } /** Settings to control the items that get added into wallets on bots */ [JsonPropertyName("walletLoot")] public WalletLootSettings WalletLoot { get; set; } /** Currency weights, Keyed by botrole / currency */ [JsonPropertyName("currencyStackSize")] public Dictionary>> CurrencyStackSize { get; set; } /** Tpls for low profile gas blocks */ [JsonPropertyName("lowProfileGasBlockTpls")] public List LowProfileGasBlockTpls { get; set; } /** What bottypes should be excluded from having loot generated on them (backpack/pocket/vest) does not disable food/drink/special/ */ [JsonPropertyName("disableLootOnBotTypes")] public List DisableLootOnBotTypes { get; set; } [JsonPropertyName("assaultToBossConversion")] public AssaultToBossConversion AssaultToBossConversion { get; set; } /** Max length a bots name can be */ [JsonPropertyName("botNameLengthLimit")] public int BotNameLengthLimit { get; set; } /** Bot roles that must have a unique name when generated vs other bots in raid */ [JsonPropertyName("botRolesThatMustHaveUniqueName")] public List BotRolesThatMustHaveUniqueName { get; set; } } public class AssaultToBossConversion { [JsonPropertyName("bossConvertEnabled")] public bool BossConvertEnabled { get; set; } [JsonPropertyName("bossesToConvertToWeights")] public Dictionary BossesToConvertToWeights { get; set; } [JsonPropertyName("bossConvertMinMax")] public Dictionary BossConvertMinMax { get; set; } } /** Number of bots to generate and store in cache on raid start per bot type */ public class PresetBatch { [JsonPropertyName("assault")] public int Assault { get; set; } [JsonPropertyName("bossBully")] public int BossBully { get; set; } [JsonPropertyName("bossGluhar")] public int BossGluhar { get; set; } [JsonPropertyName("bossKilla")] public int BossKilla { get; set; } [JsonPropertyName("bossKojaniy")] public int BossKojaniy { get; set; } [JsonPropertyName("bossSanitar")] public int BossSanitar { get; set; } [JsonPropertyName("bossTagilla")] public int BossTagilla { get; set; } [JsonPropertyName("bossKnight")] public int BossKnight { get; set; } [JsonPropertyName("bossZryachiy")] public int BossZryachiy { get; set; } [JsonPropertyName("bossKolontay")] public int BossKolontay { get; set; } [JsonPropertyName("bossPartisan")] public int BossPartisan { get; set; } [JsonPropertyName("bossTest")] public int BossTest { get; set; } [JsonPropertyName("cursedAssault")] public int CursedAssault { get; set; } [JsonPropertyName("followerBully")] public int FollowerBully { get; set; } [JsonPropertyName("followerGluharAssault")] public int FollowerGluharAssault { get; set; } [JsonPropertyName("followerGluharScout")] public int FollowerGluharScout { get; set; } [JsonPropertyName("followerGluharSecurity")] public int FollowerGluharSecurity { get; set; } [JsonPropertyName("followerGluharSnipe")] public int FollowerGluharSnipe { get; set; } [JsonPropertyName("followerKojaniy")] public int FollowerKojaniy { get; set; } [JsonPropertyName("followerSanitar")] public int FollowerSanitar { get; set; } [JsonPropertyName("followerTagilla")] public int FollowerTagilla { get; set; } [JsonPropertyName("followerBirdEye")] public int FollowerBirdEye { get; set; } [JsonPropertyName("followerBigPipe")] public int FollowerBigPipe { get; set; } [JsonPropertyName("followerTest")] public int FollowerTest { get; set; } [JsonPropertyName("followerBoar")] public int FollowerBoar { get; set; } [JsonPropertyName("followerBoarClose1")] public int FollowerBoarClose1 { get; set; } [JsonPropertyName("followerBoarClose2")] public int FollowerBoarClose2 { get; set; } [JsonPropertyName("followerZryachiy")] public int FollowerZryachiy { get; set; } [JsonPropertyName("followerKolontayAssault")] public int FollowerKolontayAssault { get; set; } [JsonPropertyName("followerKolontaySecurity")] public int FollowerKolontaySecurity { get; set; } [JsonPropertyName("marksman")] public int Marksman { get; set; } [JsonPropertyName("pmcBot")] public int PmcBot { get; set; } [JsonPropertyName("sectantPriest")] public int SectantPriest { get; set; } [JsonPropertyName("sectantWarrior")] public int SectantWarrior { get; set; } [JsonPropertyName("gifter")] public int Gifter { get; set; } [JsonPropertyName("test")] public int Test { get; set; } [JsonPropertyName("exUsec")] public int ExUsec { get; set; } [JsonPropertyName("arenaFighterEvent")] public int ArenaFighterEvent { get; set; } [JsonPropertyName("arenaFighter")] public int ArenaFighter { get; set; } [JsonPropertyName("crazyAssaultEvent")] public int CrazyAssaultEvent { get; set; } [JsonPropertyName("bossBoar")] public int BossBoar { get; set; } [JsonPropertyName("bossBoarSniper")] public int BossBoarSniper { get; set; } [JsonPropertyName("pmcUSEC")] public int PmcUSEC { get; set; } [JsonPropertyName("pmcBEAR")] public int PmcBEAR { get; set; } [JsonPropertyName("shooterBTR")] public int ShooterBTR { get; set; } [JsonExtensionData] public IDictionary AdditionalData { get; set; } } public class WalletLootSettings { /// /// Chance wallets have loot in them /// [JsonPropertyName("chancePercent")] public float ChancePercent { get; set; } [JsonPropertyName("itemCount")] public MinMax ItemCount { get; set; } [JsonPropertyName("stackSizeWeight")] public Dictionary StackSizeWeight { get; set; } [JsonPropertyName("currencyWeight")] public Dictionary CurrencyWeight { get; set; } /// /// What wallets will have money in them /// [JsonPropertyName("walletTplPool")] public List WalletTplPool { get; set; } } public class EquipmentFilters { /// /// Limits for mod types per weapon .e.g. scopes /// [JsonPropertyName("weaponModLimits")] public ModLimits WeaponModLimits { get; set; } /// /// Whitelist for weapon sight types allowed per gun /// [JsonPropertyName("weaponSightWhitelist")] public Dictionary> WeaponSightWhitelist { get; set; } /// /// Chance face shield is down/active /// [JsonPropertyName("faceShieldIsActiveChancePercent")] public float? FaceShieldIsActiveChancePercent { get; set; } /// /// Chance gun flashlight is active during the day /// [JsonPropertyName("lightIsActiveDayChancePercent")] public float? LightIsActiveDayChancePercent { get; set; } /// /// Chance gun flashlight is active during the night /// [JsonPropertyName("lightIsActiveNightChancePercent")] public float? LightIsActiveNightChancePercent { get; set; } /// /// Chance gun laser is active during the day /// [JsonPropertyName("laserIsActiveChancePercent")] public float? LaserIsActiveChancePercent { get; set; } /// /// Chance NODS are down/active during the day /// [JsonPropertyName("nvgIsActiveChanceDayPercent")] public float? NvgIsActiveChanceDayPercent { get; set; } /// /// Chance NODS are down/active during the night /// [JsonPropertyName("nvgIsActiveChanceNightPercent")] public float? NvgIsActiveChanceNightPercent { get; set; } [JsonPropertyName("forceOnlyArmoredRigWhenNoArmor")] public bool? ForceOnlyArmoredRigWhenNoArmor { get; set; } /// /// Should plates be filtered by level /// [JsonPropertyName("filterPlatesByLevel")] public bool? FilterPlatesByLevel { get; set; } /// /// What additional slot ids should be seen as required when choosing a mod to add to a weapon /// [JsonPropertyName("weaponSlotIdsToMakeRequired")] public List? WeaponSlotIdsToMakeRequired { get; set; } /// /// Adjust weighting/chances of items on bot by level of bot /// [JsonPropertyName("randomisation")] public List Randomisation { get; set; } /// /// Blacklist equipment by level of bot /// [JsonPropertyName("blacklist")] public List Blacklist { get; set; } /// /// Whitelist equipment by level of bot /// [JsonPropertyName("whitelist")] public List Whitelist { get; set; } /// /// Adjust equipment/ammo /// [JsonPropertyName("weightingAdjustmentsByBotLevel")] public List WeightingAdjustmentsByBotLevel { get; set; } /// /// Same as weightingAdjustments but based on player level instead of bot level /// [JsonPropertyName("weightingAdjustmentsByPlayerLevel")] public List? WeightingAdjustmentsByPlayerLevel { get; set; } /// /// Should the stock mod be forced to spawn on bot /// [JsonPropertyName("forceStock")] public bool? ForceStock { get; set; } [JsonPropertyName("armorPlateWeighting")] public List? ArmorPlateWeighting { get; set; } [JsonPropertyName("forceRigWhenNoVest")] public bool? ForceRigWhenNoVest { get; set; } } public class ModLimits { /// /// How many scopes are allowed on a weapon - hard coded to work with OPTIC_SCOPE, ASSAULT_SCOPE, COLLIMATOR, COMPACT_COLLIMATOR /// [JsonPropertyName("scopeLimit")] public int? ScopeLimit { get; set; } /// /// How many lasers or lights are allowed on a weapon - hard coded to work with TACTICAL_COMBO, and FLASHLIGHT /// [JsonPropertyName("lightLaserLimit")] public int? LightLaserLimit { get; set; } } public class RandomisationDetails { /// /// Between what levels do these randomisation setting apply to /// [JsonPropertyName("levelRange")] public MinMax LevelRange { get; set; } [JsonPropertyName("generation")] public Dictionary? Generation { get; set; } /// /// Mod slots that should be fully randomised -ignores mods from bottype.json and instead creates a pool using items.json /// [JsonPropertyName("randomisedWeaponModSlots")] public List? RandomisedWeaponModSlots { get; set; } /// /// Armor slots that should be randomised e.g. 'Headwear, Armband' /// [JsonPropertyName("randomisedArmorSlots")] public List? RandomisedArmorSlots { get; set; } /// /// Equipment chances /// [JsonPropertyName("equipment")] public Dictionary? Equipment { get; set; } /// /// Weapon mod chances /// [JsonPropertyName("weaponMods")] public Dictionary? WeaponMods { get; set; } /// /// Equipment mod chances /// [JsonPropertyName("equipmentMods")] public Dictionary? EquipmentMods { get; set; } [JsonPropertyName("nighttimeChanges")] public NighttimeChanges? NighttimeChanges { get; set; } /// /// Key = weapon tpl, value = min size of magazine allowed /// [JsonPropertyName("minimumMagazineSize")] public Dictionary? MinimumMagazineSize { get; set; } } public class NighttimeChanges { /// /// Applies changes to values stored in equipmentMods /// [JsonPropertyName("equipmentModsModifiers")] public Dictionary EquipmentModsModifiers { get; set; } //public Dictionary WeaponModsModifiers { get; set; } //TODO } public class EquipmentFilterDetails { /// /// Between what levels do these equipment filter setting apply to /// [JsonPropertyName("levelRange")] public MinMax LevelRange { get; set; } /// /// Key: mod slot name e.g. mod_magazine, value: item tpls /// [JsonPropertyName("equipment")] public Dictionary>? Equipment { get; set; } /// /// Key: equipment slot name e.g. FirstPrimaryWeapon, value: item tpls /// [JsonPropertyName("gear")] public Dictionary>? Gear { get; set; } /// /// Key: cartridge type e.g. Caliber23x75, value: item tpls /// [JsonPropertyName("cartridge")] public Dictionary>? Cartridge { get; set; } } public class WeightingAdjustmentDetails { /// /// Between what levels do these weight settings apply to /// [JsonPropertyName("levelRange")] public MinMax LevelRange { get; set; } /// /// Key: ammo type e.g. Caliber556x45NATO, value: item tpl + weight /// [JsonPropertyName("ammo")] public AdjustmentDetails? Ammo { get; set; } /// /// Key: equipment slot e.g. TacticalVest, value: item tpl + weight /// [JsonPropertyName("equipment")] public AdjustmentDetails? Equipment { get; set; } /// /// Key: clothing slot e.g. feet, value: item tpl + weight /// [JsonPropertyName("clothing")] public AdjustmentDetails? Clothing { get; set; } } public class AdjustmentDetails { [JsonPropertyName("add")] public Dictionary> Add { get; set; } [JsonPropertyName("edit")] public Dictionary> Edit { get; set; } } public class ArmorPlateWeights : Dictionary { [JsonPropertyName("levelRange")] public MinMax LevelRange { get; set; } } public class RandomisedResourceDetails { [JsonPropertyName("food")] public RandomisedResourceValues Food { get; set; } [JsonPropertyName("meds")] public RandomisedResourceValues Meds { get; set; } } public class RandomisedResourceValues { /// /// Minimum percent of item to randomized between min and max resource /// [JsonPropertyName("resourcePercent")] public float ResourcePercent { get; set; } /// /// Chance for randomization to not occur /// [JsonPropertyName("chanceMaxResourcePercent")] public float ChanceMaxResourcePercent { get; set; } }