diff --git a/project/assets/configs/bot.json b/project/assets/configs/bot.json index efb9fa1b..0e6abea8 100644 --- a/project/assets/configs/bot.json +++ b/project/assets/configs/bot.json @@ -49,17 +49,17 @@ "pmcBEAR": 15 }, "bosses": [ - "bossbully", - "bossgluhar", - "bosskilla", - "bosskojaniy", - "bosssanitar", - "bosstagilla", - "bossknight", - "bosszryachiy", - "bossboar", - "bossboarSniper", - "bosskolontay" + "bossBully", + "bossGluhar", + "bossKilla", + "bossKojaniy", + "bossSanitar", + "bossTagilla", + "bossKnight", + "bossZryachiy", + "bossBoar", + "bossBoarSniper", + "bossKolontay" ], "durability": { "default": { @@ -2705,5 +2705,26 @@ } }, "lowProfileGasBlockTpls": ["61702f1b67085e45ef140b26", "5dfa3d45dfc58d14537c20b0", "5bb20dcad4351e3bac1212da", "56eabcd4d2720b66698b4574", "6065dc8a132d4d12c81fd8e3", "55d4af3a4bdc2d972f8b456f"], - "disableLootOnBotTypes": [] -} + "disableLootOnBotTypes": [], + "assaultToBossConversion": { + "bossConvertEnabled": false, + "bossesToConvertToWeights": { + "bossKilla": 1, + "bossSanitar": 1, + "bossTagilla": 1, + "bossBully": 1, + "bossGluhar": 1, + "bossKojaniy": 1, + "bossKolontay": 1, + "bossKnight": 1, + "followerBigPipe": 1, + "followerBirdEye": 1 + }, + "bossConvertMinMax": { + "assault": { + "min": 100, + "max": 100 + } + } + } +} \ No newline at end of file diff --git a/project/src/controllers/BotController.ts b/project/src/controllers/BotController.ts index 95902f0d..c893a5cf 100644 --- a/project/src/controllers/BotController.ts +++ b/project/src/controllers/BotController.ts @@ -5,6 +5,7 @@ import { BotGenerator } from "@spt/generators/BotGenerator"; import { BotDifficultyHelper } from "@spt/helpers/BotDifficultyHelper"; import { BotHelper } from "@spt/helpers/BotHelper"; import { ProfileHelper } from "@spt/helpers/ProfileHelper"; +import { WeightedRandomHelper } from "@spt/helpers/WeightedRandomHelper"; import { MinMax } from "@spt/models/common/MinMax"; import { Condition, IGenerateBotsRequestData } from "@spt/models/eft/bot/IGenerateBotsRequestData"; import { IPmcData } from "@spt/models/eft/common/IPmcData"; @@ -39,6 +40,7 @@ export class BotController @inject("BotGenerator") protected botGenerator: BotGenerator, @inject("BotHelper") protected botHelper: BotHelper, @inject("BotDifficultyHelper") protected botDifficultyHelper: BotDifficultyHelper, + @inject("WeightedRandomHelper") protected weightedRandomHelper: WeightedRandomHelper, @inject("BotGenerationCacheService") protected botGenerationCacheService: BotGenerationCacheService, @inject("MatchBotDetailsCacheService") protected matchBotDetailsCacheService: MatchBotDetailsCacheService, @inject("LocalisationService") protected localisationService: LocalisationService, @@ -434,6 +436,26 @@ export class BotController botGenerationDetails.botCountToGenerate = this.botConfig.presetBatch[botGenerationDetails.role]; } } + // Only convert to boss when not already converted to PMC & Boss Convert is enabled + const { + bossConvertEnabled, + bossConvertMinMax, + bossesToConvertToWeights } = this.botConfig.assaultToBossConversion; + if (bossConvertEnabled && !botGenerationDetails.isPmc) + { + const bossConvertPercent = bossConvertMinMax[requestedBot.Role.toLowerCase()]; + if (bossConvertPercent) + { + // Roll a percentage check if we should convert scav to boss + if (this.randomUtil.getChance100( + this.randomUtil.getInt(bossConvertPercent.min, bossConvertPercent.max))) + { + this.updateBotGenerationDetailsToRandomBoss( + botGenerationDetails, + bossesToConvertToWeights); + } + } + } // Construct cache key const cacheKey = `${ @@ -466,6 +488,19 @@ export class BotController return [desiredBot]; } + protected updateBotGenerationDetailsToRandomBoss( + botGenerationDetails: BotGenerationDetails, + possibleBossTypeWeights: Record): void + { + // Seems Actual bosses have the same Brain issues like PMC gaining Boss Brains We cant use all bosses + botGenerationDetails.role + = this.weightedRandomHelper.getWeightedValue(possibleBossTypeWeights); + + // Bosses are only ever 'normal' + botGenerationDetails.botDifficulty = "normal"; + botGenerationDetails.botCountToGenerate = this.botConfig.presetBatch[botGenerationDetails.role]; + } + /** * Get the difficulty passed in, if its not "asonline", get selected difficulty from config * @param requestedDifficulty diff --git a/project/src/helpers/BotHelper.ts b/project/src/helpers/BotHelper.ts index 0afb54b9..248f6598 100644 --- a/project/src/helpers/BotHelper.ts +++ b/project/src/helpers/BotHelper.ts @@ -139,6 +139,11 @@ export class BotHelper ); } + /** + * is the provided role a PMC, case-agnostic + * @param botRole Role to check + * @returns True if role is PMC + */ public botRoleIsPmc(botRole: string): boolean { return [this.pmcConfig.usecType.toLowerCase(), this.pmcConfig.bearType.toLowerCase()].includes( diff --git a/project/src/models/spt/config/IBotConfig.ts b/project/src/models/spt/config/IBotConfig.ts index 02647ddf..582987c7 100644 --- a/project/src/models/spt/config/IBotConfig.ts +++ b/project/src/models/spt/config/IBotConfig.ts @@ -45,6 +45,14 @@ export interface IBotConfig extends IBaseConfig lowProfileGasBlockTpls: string[] /** What bottypes should be excluded from having loot generated on them (backpack/pocket/vest) does not disable food/drink/special/ */ disableLootOnBotTypes: string[] + assaultToBossConversion: IAssaultToBossConversion +} + +export interface IAssaultToBossConversion +{ + bossConvertEnabled: boolean + bossesToConvertToWeights: Record + bossConvertMinMax: Record } /** Number of bots to generate and store in cache on raid start per bot type */