diff --git a/project/assets/configs/hideout.json b/project/assets/configs/hideout.json index 4d5b1ec2..f128b434 100644 --- a/project/assets/configs/hideout.json +++ b/project/assets/configs/hideout.json @@ -15,6 +15,12 @@ "rewardPriceMultiplerMinMax": { "min": 0.7, "max": 1.4 + }, + "directRewards": { + "66572c82ad599021091c6118": ["5c0e874186f7745dc7616606"], + "66572be36a723f7f005a066e": ["5b3b713c5acfc4330140bd8d"], + "655c669103999d3c810c025b": ["5fc64ea372b0dd78d51159dc"], + "66572cbdad599021091c611a": ["60a7ad2a2198820d95707a2e"] } } } diff --git a/project/src/models/spt/config/IHideoutConfig.ts b/project/src/models/spt/config/IHideoutConfig.ts index 648b2b4a..0da37182 100644 --- a/project/src/models/spt/config/IHideoutConfig.ts +++ b/project/src/models/spt/config/IHideoutConfig.ts @@ -20,4 +20,5 @@ export interface ICultistCircleSettings { maxRewardItemCount: number; maxAttemptsToPickRewardsWithinBudget: number; rewardPriceMultiplerMinMax: MinMax; + directRewards: Record; } diff --git a/project/src/services/CircleOfCultistService.ts b/project/src/services/CircleOfCultistService.ts index cb040905..ec5ef2b8 100644 --- a/project/src/services/CircleOfCultistService.ts +++ b/project/src/services/CircleOfCultistService.ts @@ -97,10 +97,19 @@ export class CircleOfCultistService { } } - const rewardItemPool = this.getCultistCircleRewardPool(sessionId, pmcData); - this.logger.warning(`Reward pool item count: ${rewardItemPool.length}`); + // Player has sacrified a single item that's in directReward dict, return specific reward pool + let rewards: Item[][]; + if (sacrificedItems.length === 1 && this.hideoutConfig.cultistCircle.directRewards[sacrificedItems[0]._tpl]) { + rewards = this.getExplicitRewards( + this.hideoutConfig.cultistCircle.directRewards[sacrificedItems[0]._tpl], + cultistCircleStashId, + ); + } else { + const rewardItemPool = this.getCultistCircleRewardPool(sessionId, pmcData); + this.logger.warning(`Reward pool item count: ${rewardItemPool.length}`); - const rewards = this.getRewardsWithinBudget(rewardItemPool, rewardAmountRoubles, cultistCircleStashId); + rewards = this.getRewardsWithinBudget(rewardItemPool, rewardAmountRoubles, cultistCircleStashId); + } // Get the container grid for cultist stash area const cultistStashDbItem = this.itemHelper.getItem(ItemTpl.HIDEOUTAREACONTAINER_CIRCLEOFCULTISTS_STASH_1); @@ -164,7 +173,7 @@ export class CircleOfCultistService { * @param rewardItemTplPool Items that can be picekd * @param rewardBudget Rouble budget to reach * @param cultistCircleStashId Id of stash item - * @returns Array of items + * @returns Array of item arrays */ protected getRewardsWithinBudget( rewardItemTplPool: string[], @@ -240,6 +249,58 @@ export class CircleOfCultistService { return rewards; } + /** + * Give every item as a reward that's passed in + * @param rewardTpls Item tpls to turn into reward items + * @param cultistCircleStashId Id of stash item + * @returns Array of item arrays + */ + protected getExplicitRewards(rewardTpls: string[], cultistCircleStashId: string): Item[][] { + // Prep rewards array (reward can be item with children, hence array of arrays) + const rewards: Item[][] = []; + for (const rewardTpl of rewardTpls) { + if ( + this.itemHelper.armorItemHasRemovableOrSoftInsertSlots(rewardTpl) || + this.itemHelper.isOfBaseclass(rewardTpl, BaseClasses.WEAPON) + ) { + const defaultPreset = this.presetHelper.getDefaultPreset(rewardTpl); + if (!defaultPreset) { + this.logger.warning(`Reward tpl: ${rewardTpl} lacks a default preset, skipping reward`); + + continue; + } + + // Ensure preset has unique ids and is cloned so we don't alter the preset data stored in memory + const presetAndMods: Item[] = this.itemHelper.replaceIDs(defaultPreset._items); + + this.itemHelper.remapRootItemId(presetAndMods); + + rewards.push(presetAndMods); + + continue; + } + + // Some items can have variable stack size, e.g. ammo + const stackSize = this.getRewardStackSize(rewardTpl); + + // Not a weapon/armor, standard single item + const rewardItem: Item = { + _id: this.hashUtil.generate(), + _tpl: rewardTpl, + parentId: cultistCircleStashId, + slotId: CircleOfCultistService.circleOfCultistSlotId, + upd: { + StackObjectsCount: stackSize, + SpawnedInSession: true, + }, + }; + + rewards.push([rewardItem]); + } + + return rewards; + } + /** * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack