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
This commit is contained in:
Dev 2024-06-04 18:57:36 +01:00
parent 5b4b0c1471
commit 0574392f28
6 changed files with 84 additions and 12 deletions

View File

@ -47,9 +47,11 @@
"648c1a965043c4052a4f8505",
"5ae089fb5acfc408fb13989b",
"6241c2c2117ad530666a5108",
"5580239d4bdc2de7118b4583",
"660bbc47c38b837877075e47"
"5580239d4bdc2de7118b4583"
],
"lootableItemBlacklist": [
"660bbc47c38b837877075e47"
],
"rewardItemBlacklist": [
"58ac60eb86f77401897560ff",
"5e997f0b86f7741ac73993e2",

View File

@ -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

View File

@ -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)

View File

@ -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 */

View File

@ -11,7 +11,8 @@ import { ICloner } from "@spt/utils/cloners/ICloner";
export class ItemFilterService
{
protected itemConfig: IItemConfig;
protected itemBlacklist: Set<string> = new Set<string>();
protected itemBlacklistCache: Set<string> = new Set<string>();
protected lootableItemBlacklistCache: Set<string> = new Set<string>();
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

View File

@ -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)