diff --git a/project/assets/configs/inventory.json b/project/assets/configs/inventory.json index 91997011..d0bea404 100644 --- a/project/assets/configs/inventory.json +++ b/project/assets/configs/inventory.json @@ -1319,6 +1319,99 @@ "635a758bfefc88a93f021b8a": 1, "544fb6cc4bdc2d34748b456e": 1 } + }, + "6694f4101ae1778e310f4f8e": { + "_type": "twitch 2024 - common", + "rewardCount": 3, + "foundInRaid": true, + "rewardTypePool": [ + "5b3f15d486f77432d0509248", + "57864a3d24597754843f8721", + "57864a66245977548f04a81f", + "57864ada245977548638de91", + "57864bb7245977548b3b66c2", + "57864e4c24597754843f8723", + "57864ee62459775490116fc1", + "55818add4bdc2d5b648b456f", + "55818ae44bdc2dde698b456c", + "5645bcb74bdc2ded0b8b4578", + "644120aa86ffbe10ee032b6f", + "550aa4dd4bdc2dc9348b4569", + "543be5e94bdc2df1348b4568", + "5c99f98d86f7745c314214b3", + "5d21f59b6dbe99052b54ef83", + "543be5664bdc2dd4348b4569", + "543be6674bdc2df1348b4569", + "5d650c3e815116009f6201d2", + "5448ecbe4bdc2d60728b4568", + "5448e8d64bdc2dce718b4568", + "5448e8d04bdc2ddf718b4569", + "616eb7aea207f41933308f46", + "5448e53e4bdc2d60728b4567", + "5a2c3a9486f774688b05e574" + ] + }, + "6694f418c74d8a180f0f78c0": { + "_type": "twitch 2024 - rare", + "rewardCount": 6, + "foundInRaid": true, + "rewardTypePool": [ + "5b3f15d486f77432d0509248", + "57864a3d24597754843f8721", + "57864a66245977548f04a81f", + "57864ada245977548638de91", + "57864bb7245977548b3b66c2", + "57864e4c24597754843f8723", + "57864ee62459775490116fc1", + "55818add4bdc2d5b648b456f", + "55818ae44bdc2dde698b456c", + "5645bcb74bdc2ded0b8b4578", + "644120aa86ffbe10ee032b6f", + "550aa4dd4bdc2dc9348b4569", + "543be5e94bdc2df1348b4568", + "5c99f98d86f7745c314214b3", + "5d21f59b6dbe99052b54ef83", + "543be5664bdc2dd4348b4569", + "543be6674bdc2df1348b4569", + "5d650c3e815116009f6201d2", + "5448ecbe4bdc2d60728b4568", + "5448e8d64bdc2dce718b4568", + "5448e8d04bdc2ddf718b4569", + "616eb7aea207f41933308f46", + "5448e53e4bdc2d60728b4567", + "5a2c3a9486f774688b05e574" + ] + }, + "6694f423909d2322a8073151": { + "_type": "twitch 2024 - epic", + "rewardCount": 10, + "foundInRaid": true, + "rewardTypePool": [ + "5b3f15d486f77432d0509248", + "57864a3d24597754843f8721", + "57864a66245977548f04a81f", + "57864ada245977548638de91", + "57864bb7245977548b3b66c2", + "57864e4c24597754843f8723", + "57864ee62459775490116fc1", + "55818add4bdc2d5b648b456f", + "55818ae44bdc2dde698b456c", + "5645bcb74bdc2ded0b8b4578", + "644120aa86ffbe10ee032b6f", + "550aa4dd4bdc2dc9348b4569", + "543be5e94bdc2df1348b4568", + "5c99f98d86f7745c314214b3", + "5d21f59b6dbe99052b54ef83", + "543be5664bdc2dd4348b4569", + "543be6674bdc2df1348b4569", + "5d650c3e815116009f6201d2", + "5448ecbe4bdc2d60728b4568", + "5448e8d64bdc2dce718b4568", + "5448e8d04bdc2ddf718b4569", + "616eb7aea207f41933308f46", + "5448e53e4bdc2d60728b4567", + "5a2c3a9486f774688b05e574" + ] } }, "sealedAirdropContainer": { diff --git a/project/src/generators/LootGenerator.ts b/project/src/generators/LootGenerator.ts index dd838b54..b514618a 100644 --- a/project/src/generators/LootGenerator.ts +++ b/project/src/generators/LootGenerator.ts @@ -44,23 +44,6 @@ export class LootGenerator { const result: Item[] = []; const itemTypeCounts = this.initItemLimitCounter(options.itemLimits); - const itemsDb = this.databaseService.getItems(); - let itemBlacklist = new Set([ - ...this.itemFilterService.getBlacklistedItems(), - ...options.itemBlacklist, - ]); - - if (options.useRewarditemBlacklist) { - const itemsToAdd = this.itemFilterService.getItemRewardBlacklist(); - itemBlacklist = new Set([...itemBlacklist, ...itemsToAdd]); - } - - if (!options.allowBossItems) { - for (const bossItem of this.itemFilterService.getBossItems()) { - itemBlacklist.add(bossItem); - } - } - // Handle sealed weapon containers const sealedWeaponCrateCount = this.randomUtil.getInt( options.weaponCrateCount.min, @@ -68,6 +51,7 @@ export class LootGenerator { ); if (sealedWeaponCrateCount > 0) { // Get list of all sealed containers from db - they're all the same, just for flavor + const itemsDb = this.itemHelper.getItems(); const sealedWeaponContainerPool = Object.values(itemsDb).filter((item) => item._name.includes("event_container_airdrop"), ); @@ -87,19 +71,18 @@ export class LootGenerator { } // Get items from items.json that have a type of item + not in global blacklist + basetype is in whitelist - const items = Object.entries(itemsDb).filter( - (item) => - !itemBlacklist.has(item[1]._id) && - item[1]._type.toLowerCase() === "item" && - !item[1]._props.QuestItem && - options.itemTypeWhitelist.includes(item[1]._parent), + const { itemPool, blacklist } = this.getItemRewardPool( + options.itemBlacklist, + options.itemTypeWhitelist, + options.useRewarditemBlacklist, + options.allowBossItems, ); // Pool has items we could add as loot, proceed - if (items.length > 0) { + if (itemPool.length > 0) { const randomisedItemCount = this.randomUtil.getInt(options.itemCount.min, options.itemCount.max); for (let index = 0; index < randomisedItemCount; index++) { - if (!this.findAndAddRandomItemToLoot(items, itemTypeCounts, options, result)) { + if (!this.findAndAddRandomItemToLoot(itemPool, itemTypeCounts, options, result)) { // Failed to add, reduce index so we get another attempt index--; } @@ -107,7 +90,7 @@ export class LootGenerator { } const globalDefaultPresets = Object.values(this.presetHelper.getDefaultPresets()); - const itemBlacklistArray = Array.from(itemBlacklist); + const itemBlacklistArray = Array.from(blacklist); // Filter default presets to just weapons const randomisedWeaponPresetCount = this.randomUtil.getInt( @@ -170,6 +153,37 @@ export class LootGenerator { return result; } + protected getItemRewardPool( + itemTplBlacklist: string[], + itemTypeWhitelist: string[], + useRewardItemBlacklist: boolean, + allowBossItems: boolean, + ): { itemPool: [string, ITemplateItem][]; blacklist: Set } { + const itemsDb = this.databaseService.getItems(); + let itemBlacklist = new Set([...this.itemFilterService.getBlacklistedItems(), ...itemTplBlacklist]); + + if (useRewardItemBlacklist) { + const itemsToAdd = this.itemFilterService.getItemRewardBlacklist(); + itemBlacklist = new Set([...itemBlacklist, ...itemsToAdd]); + } + + if (!allowBossItems) { + for (const bossItem of this.itemFilterService.getBossItems()) { + itemBlacklist.add(bossItem); + } + } + + const items = Object.entries(itemsDb).filter( + (item) => + !itemBlacklist.has(item[1]._id) && + item[1]._type.toLowerCase() === "item" && + !item[1]._props.QuestItem && + itemTypeWhitelist.includes(item[1]._parent), + ); + + return { itemPool: items, blacklist: itemBlacklist }; + } + /** * Filter armor items by their front plates protection level - top if its a helmet * @param armor Armor preset to check @@ -534,9 +548,7 @@ export class LootGenerator { // Get random items and add to newItemRequest for (let index = 0; index < rewardContainerDetails.rewardCount; index++) { // Pick random reward from pool, add to request object - const chosenRewardItemTpl = this.weightedRandomHelper.getWeightedValue( - rewardContainerDetails.rewardTplPool, - ); + const chosenRewardItemTpl = this.pickRewardItem(rewardContainerDetails); if (this.presetHelper.hasPreset(chosenRewardItemTpl)) { const preset = this.presetHelper.getDefaultPreset(chosenRewardItemTpl); @@ -556,4 +568,21 @@ export class LootGenerator { return itemsToReturn; } + + /** + * Pick a reward item based on the reward details data + * @param rewardContainerDetails + * @returns Single tpl + */ + protected pickRewardItem(rewardContainerDetails: RewardDetails): string { + if (rewardContainerDetails.rewardTplPool) { + return this.weightedRandomHelper.getWeightedValue(rewardContainerDetails.rewardTplPool); + } + + return this.randomUtil.getArrayValue( + this.getItemRewardPool([], rewardContainerDetails.rewardTypePool, true, true).itemPool.map( + (item) => item[1]._id, + ), + ); + } } diff --git a/project/src/models/spt/config/IInventoryConfig.ts b/project/src/models/spt/config/IInventoryConfig.ts index 8e763f9f..104c6ea2 100644 --- a/project/src/models/spt/config/IInventoryConfig.ts +++ b/project/src/models/spt/config/IInventoryConfig.ts @@ -17,7 +17,7 @@ export interface RewardDetails { rewardCount: number; foundInRaid: boolean; rewardTplPool?: Record; - rewardTypePool?: Record; + rewardTypePool?: string[]; } export interface ISealedAirdropContainerSettings {