From 0574392f28b7b949013c02ff31af9d5b8ea23420 Mon Sep 17 00:00:00 2001 From: Dev Date: Tue, 4 Jun 2024 18:57:36 +0100 Subject: [PATCH] Added new lootable item blacklist and added checks to bot and map loot generator code Remove event quest item from global blacklist and move to loot item blacklist --- project/assets/configs/item.json | 6 ++- project/src/generators/BotGenerator.ts | 42 +++++++++++++++++++- project/src/generators/LocationGenerator.ts | 7 ++-- project/src/models/spt/config/IItemConfig.ts | 2 + project/src/services/ItemFilterService.ts | 35 +++++++++++++--- project/src/services/SeasonalEventService.ts | 4 ++ 6 files changed, 84 insertions(+), 12 deletions(-) diff --git a/project/assets/configs/item.json b/project/assets/configs/item.json index 8b590a0c..7bf953fa 100644 --- a/project/assets/configs/item.json +++ b/project/assets/configs/item.json @@ -47,9 +47,11 @@ "648c1a965043c4052a4f8505", "5ae089fb5acfc408fb13989b", "6241c2c2117ad530666a5108", - "5580239d4bdc2de7118b4583", - "660bbc47c38b837877075e47" + "5580239d4bdc2de7118b4583" ], + "lootableItemBlacklist": [ + "660bbc47c38b837877075e47" + ], "rewardItemBlacklist": [ "58ac60eb86f77401897560ff", "5e997f0b86f7741ac73993e2", diff --git a/project/src/generators/BotGenerator.ts b/project/src/generators/BotGenerator.ts index e92e1edd..33f367cf 100644 --- a/project/src/generators/BotGenerator.ts +++ b/project/src/generators/BotGenerator.ts @@ -15,7 +15,7 @@ import { Health as PmcHealth, Skills as botSkills, } from "@spt/models/eft/common/tables/IBotBase"; -import { Appearance, Health, IBotType } from "@spt/models/eft/common/tables/IBotType"; +import { Appearance, Health, IBotType, Inventory } from "@spt/models/eft/common/tables/IBotType"; import { Item, Upd } from "@spt/models/eft/common/tables/IItem"; import { BaseClasses } from "@spt/models/enums/BaseClasses"; import { ConfigTypes } from "@spt/models/enums/ConfigTypes"; @@ -27,6 +27,7 @@ import { ILogger } from "@spt/models/spt/utils/ILogger"; import { ConfigServer } from "@spt/servers/ConfigServer"; import { BotEquipmentFilterService } from "@spt/services/BotEquipmentFilterService"; import { DatabaseService } from "@spt/services/DatabaseService"; +import { ItemFilterService } from "@spt/services/ItemFilterService"; import { LocalisationService } from "@spt/services/LocalisationService"; import { SeasonalEventService } from "@spt/services/SeasonalEventService"; import { ICloner } from "@spt/utils/cloners/ICloner"; @@ -55,6 +56,7 @@ export class BotGenerator @inject("BotDifficultyHelper") protected botDifficultyHelper: BotDifficultyHelper, @inject("SeasonalEventService") protected seasonalEventService: SeasonalEventService, @inject("LocalisationService") protected localisationService: LocalisationService, + @inject("ItemFilterService") protected itemFilterService: ItemFilterService, @inject("ConfigServer") protected configServer: ConfigServer, @inject("PrimaryCloner") protected cloner: ICloner, ) @@ -130,7 +132,7 @@ export class BotGenerator /** * Create a IBotBase object with equipment/loot/exp etc * @param sessionId Session id - * @param bot bots base file + * @param bot Bots base file * @param botJsonTemplate Bot template from db/bots/x.json * @param botGenerationDetails details on how to generate the bot * @returns IBotBase object @@ -173,6 +175,8 @@ export class BotGenerator } } + this.removeBlacklistedLootFromBotTemplate(botJsonTemplate.inventory); + // Remove hideout data if bot is not a PMC or pscav if (!(botGenerationDetails.isPmc || botGenerationDetails.isPlayerScav)) { @@ -226,6 +230,40 @@ export class BotGenerator return bot; } + /** + * Remove items from item.json/lootableItemBlacklist from bots inventory + * @param botInventory Bot to filter + */ + protected removeBlacklistedLootFromBotTemplate(botInventory: Inventory): void + { + const lootContainersToFilter = ["Backpack", "Pockets", "TacticalVest"]; + + // Remove blacklisted loot from loot containers + for (const lootContainerKey of lootContainersToFilter) + { + // No container, skip + if (botInventory.items[lootContainerKey]?.length === 0) + { + continue; + } + + const tplsToRemove: string[] = []; + const containerItems = botInventory.items[lootContainerKey]; + for (const tplKey of Object.keys(containerItems)) + { + if (this.itemFilterService.isLootableItemBlacklisted(tplKey)) + { + tplsToRemove.push(tplKey); + } + } + + for (const blacklistedTplToRemove of tplsToRemove) + { + delete containerItems[blacklistedTplToRemove]; + } + } + } + /** * Choose various appearance settings for a bot using weights * @param bot Bot to adjust diff --git a/project/src/generators/LocationGenerator.ts b/project/src/generators/LocationGenerator.ts index da574a7c..0a121ecc 100644 --- a/project/src/generators/LocationGenerator.ts +++ b/project/src/generators/LocationGenerator.ts @@ -572,7 +572,8 @@ export class LocationGenerator continue; } - if (this.itemFilterService.isItemBlacklisted(icd.tpl)) + // Ensure no blacklisted lootable items are in pool + if (this.itemFilterService.isLootableItemBlacklisted(icd.tpl)) { continue; } @@ -704,9 +705,9 @@ export class LocationGenerator continue; } - // Ensure no blacklisted items are in pool + // Ensure no blacklisted lootable items are in pool spawnPoint.template.Items = spawnPoint.template.Items - .filter((item) => !this.itemFilterService.isItemBlacklisted(item._tpl)); + .filter((item) => !this.itemFilterService.isLootableItemBlacklisted(item._tpl)); // Ensure no seasonal items are in pool if (!seasonalEventActive) diff --git a/project/src/models/spt/config/IItemConfig.ts b/project/src/models/spt/config/IItemConfig.ts index 1f8dc7fb..5c78e889 100644 --- a/project/src/models/spt/config/IItemConfig.ts +++ b/project/src/models/spt/config/IItemConfig.ts @@ -5,6 +5,8 @@ export interface IItemConfig extends IBaseConfig kind: "spt-item" /** Items that should be globally blacklisted */ blacklist: string[] + /** Items that should not be lootable from any location */ + lootableItemBlacklist: string[] /** items that should not be given as rewards */ rewardItemBlacklist: string[] /** Items that can only be found on bosses */ diff --git a/project/src/services/ItemFilterService.ts b/project/src/services/ItemFilterService.ts index 0ca1abed..37f176eb 100644 --- a/project/src/services/ItemFilterService.ts +++ b/project/src/services/ItemFilterService.ts @@ -11,7 +11,8 @@ import { ICloner } from "@spt/utils/cloners/ICloner"; export class ItemFilterService { protected itemConfig: IItemConfig; - protected itemBlacklist: Set = new Set(); + protected itemBlacklistCache: Set = new Set(); + protected lootableItemBlacklistCache: Set = new Set(); constructor( @inject("PrimaryLogger") protected logger: ILogger, @@ -24,18 +25,33 @@ export class ItemFilterService } /** - * Check if the provided template id is blacklisted in config/item.json + * Check if the provided template id is blacklisted in config/item.json/blacklist * @param tpl template id * @returns true if blacklisted */ public isItemBlacklisted(tpl: string): boolean { - if (this.itemBlacklist.size === 0) + if (this.itemBlacklistCache.size === 0) { - this.itemConfig.blacklist.forEach((item) => this.itemBlacklist.add(item)); + this.itemConfig.blacklist.forEach((item) => this.itemBlacklistCache.add(item)); } - return this.itemBlacklist.has(tpl); + return this.itemBlacklistCache.has(tpl); + } + + /** + * Check if the provided template id is blacklisted in config/item.json/lootableItemBlacklist + * @param tpl template id + * @returns true if blacklisted + */ + public isLootableItemBlacklisted(tpl: string): boolean + { + if (this.lootableItemBlacklistCache.size === 0) + { + this.itemConfig.lootableItemBlacklist.forEach((item) => this.itemBlacklistCache.add(item)); + } + + return this.lootableItemBlacklistCache.has(tpl); } /** @@ -66,6 +82,15 @@ export class ItemFilterService return this.cloner.clone(this.itemConfig.blacklist); } + /** + * Return every template id blacklisted in config/item.json/lootableItemBlacklist + * @returns string array of blacklisted tempalte ids + */ + public getBlacklistedLootableItems(): string[] + { + return this.cloner.clone(this.itemConfig.lootableItemBlacklist); + } + /** * Check if the provided template id is boss item in config/item.json * @param tpl template id diff --git a/project/src/services/SeasonalEventService.ts b/project/src/services/SeasonalEventService.ts index 0417a967..56ed970f 100644 --- a/project/src/services/SeasonalEventService.ts +++ b/project/src/services/SeasonalEventService.ts @@ -343,6 +343,10 @@ export class SeasonalEventService // Get non-christmas items const nonChristmasTpls = Object.keys(containerItems).filter((tpl) => !christmasItems.includes(tpl)); + if (nonChristmasTpls.length === 0) + { + continue; + } const intermediaryDict = {}; for (const tpl of nonChristmasTpls)