diff --git a/project/assets/configs/hideout.json b/project/assets/configs/hideout.json index 733cabb2..2a63dd8f 100644 --- a/project/assets/configs/hideout.json +++ b/project/assets/configs/hideout.json @@ -33,6 +33,12 @@ ] }, "rewardItemBlacklist": [], - "additionalRewardItemPool": [] + "additionalRewardItemPool": [], + "currencyRewards": { + "5449016a4bdc2d6f028b456f": {"min": 20, "max": 50}, + "569668774bdc2da2298b4568": {"min": 20, "max": 50}, + "5696686a4bdc2da3298b456a": {"min": 20, "max": 50}, + "5d235b4d86f7742e017bc88a": {"min": 20, "max": 40} + } } } diff --git a/project/src/models/spt/config/IHideoutConfig.ts b/project/src/models/spt/config/IHideoutConfig.ts index 701556fc..2ca05bc2 100644 --- a/project/src/models/spt/config/IHideoutConfig.ts +++ b/project/src/models/spt/config/IHideoutConfig.ts @@ -26,4 +26,5 @@ export interface ICultistCircleSettings { rewardItemBlacklist: string[]; /** Item tpls to include in the reward pool */ additionalRewardItemPool: string[]; + currencyRewards: Record; } diff --git a/project/src/services/CircleOfCultistService.ts b/project/src/services/CircleOfCultistService.ts index 850fb4ed..232901b0 100644 --- a/project/src/services/CircleOfCultistService.ts +++ b/project/src/services/CircleOfCultistService.ts @@ -191,13 +191,13 @@ export class CircleOfCultistService { const rewards: Item[][] = []; // Pick random rewards until we have exhausted the sacrificed items budget - let totalCost = 0; - let itemsRewardedCount = 0; + let totalRewardCost = 0; + let rewardItemCount = 0; let failedAttempts = 0; while ( - totalCost < rewardBudget && + totalRewardCost < rewardBudget && rewardItemTplPool.length > 0 && - itemsRewardedCount < this.hideoutConfig.cultistCircle.maxRewardItemCount + rewardItemCount < this.hideoutConfig.cultistCircle.maxRewardItemCount ) { if (failedAttempts > this.hideoutConfig.cultistCircle.maxAttemptsToPickRewardsWithinBudget) { this.logger.warning(`Exiting reward generation after ${failedAttempts} failed attempts`); @@ -226,15 +226,18 @@ export class CircleOfCultistService { this.itemHelper.remapRootItemId(presetAndMods); - itemsRewardedCount++; - totalCost += this.itemHelper.getItemPrice(randomItemTplFromPool); + rewardItemCount++; + totalRewardCost += this.itemHelper.getItemPrice(randomItemTplFromPool); rewards.push(presetAndMods); continue; } - // Some items can have variable stack size, e.g. ammo - const stackSize = this.getRewardStackSize(randomItemTplFromPool); + // Some items can have variable stack size, e.g. ammo / currency + const stackSize = this.getRewardStackSize( + randomItemTplFromPool, + rewardBudget / (rewardItemCount === 0 ? 1 : rewardItemCount), // Remaining rouble budget + ); // Not a weapon/armor, standard single item const rewardItem: Item = { @@ -292,7 +295,7 @@ export class CircleOfCultistService { } // Some items can have variable stack size, e.g. ammo - const stackSize = this.getRewardStackSize(rewardTpl); + const stackSize = this.getRewardStackSize(rewardTpl, 20000); // Not a weapon/armor, standard single item const rewardItem: Item = { @@ -316,14 +319,34 @@ export class CircleOfCultistService { * Get the size of a reward items stack * 1 for everything except ammo, ammo can be between min stack and max stack * @param itemTpl Item chosen + * @param rewardPoolRemaining Rouble amount of pool remaining to fill * @returns Size of stack */ - protected getRewardStackSize(itemTpl: string) { + protected getRewardStackSize(itemTpl: string, rewardPoolRemaining: number) { if (this.itemHelper.isOfBaseclass(itemTpl, BaseClasses.AMMO)) { const ammoTemplate = this.itemHelper.getItem(itemTpl)[1]; return this.itemHelper.getRandomisedAmmoStackSize(ammoTemplate); } + if (this.itemHelper.isOfBaseclass(itemTpl, BaseClasses.MONEY)) { + // Get currency-specific values from config + const settings = this.hideoutConfig.cultistCircle.currencyRewards[itemTpl]; + + // What % of the pool remaining should be rewarded as chosen currency + const percentOfPoolToUse = this.randomUtil.getInt(settings.min, settings.max); + + // Rouble amount of pool we want to reward as currency + const roubleAmountToFill = this.randomUtil.getPercentOfValue(percentOfPoolToUse, rewardPoolRemaining); + + // Convert currency to roubles + const currencyPriceAsRouble = this.itemHelper.getItemPrice(itemTpl); + + // How many items can we fit into chosen pool + const itemCountToReward = Math.round(roubleAmountToFill / currencyPriceAsRouble); + + return itemCountToReward ?? 1; + } + return 1; }