Added currency handling system to cultist circle rewards

This commit is contained in:
Dev 2024-09-13 09:43:39 +01:00
parent 3f583630e5
commit 94e990cedb
3 changed files with 41 additions and 11 deletions

View File

@ -33,6 +33,12 @@
] ]
}, },
"rewardItemBlacklist": [], "rewardItemBlacklist": [],
"additionalRewardItemPool": [] "additionalRewardItemPool": [],
"currencyRewards": {
"5449016a4bdc2d6f028b456f": {"min": 20, "max": 50},
"569668774bdc2da2298b4568": {"min": 20, "max": 50},
"5696686a4bdc2da3298b456a": {"min": 20, "max": 50},
"5d235b4d86f7742e017bc88a": {"min": 20, "max": 40}
}
} }
} }

View File

@ -26,4 +26,5 @@ export interface ICultistCircleSettings {
rewardItemBlacklist: string[]; rewardItemBlacklist: string[];
/** Item tpls to include in the reward pool */ /** Item tpls to include in the reward pool */
additionalRewardItemPool: string[]; additionalRewardItemPool: string[];
currencyRewards: Record<string, MinMax>;
} }

View File

@ -191,13 +191,13 @@ export class CircleOfCultistService {
const rewards: Item[][] = []; const rewards: Item[][] = [];
// Pick random rewards until we have exhausted the sacrificed items budget // Pick random rewards until we have exhausted the sacrificed items budget
let totalCost = 0; let totalRewardCost = 0;
let itemsRewardedCount = 0; let rewardItemCount = 0;
let failedAttempts = 0; let failedAttempts = 0;
while ( while (
totalCost < rewardBudget && totalRewardCost < rewardBudget &&
rewardItemTplPool.length > 0 && rewardItemTplPool.length > 0 &&
itemsRewardedCount < this.hideoutConfig.cultistCircle.maxRewardItemCount rewardItemCount < this.hideoutConfig.cultistCircle.maxRewardItemCount
) { ) {
if (failedAttempts > this.hideoutConfig.cultistCircle.maxAttemptsToPickRewardsWithinBudget) { if (failedAttempts > this.hideoutConfig.cultistCircle.maxAttemptsToPickRewardsWithinBudget) {
this.logger.warning(`Exiting reward generation after ${failedAttempts} failed attempts`); this.logger.warning(`Exiting reward generation after ${failedAttempts} failed attempts`);
@ -226,15 +226,18 @@ export class CircleOfCultistService {
this.itemHelper.remapRootItemId(presetAndMods); this.itemHelper.remapRootItemId(presetAndMods);
itemsRewardedCount++; rewardItemCount++;
totalCost += this.itemHelper.getItemPrice(randomItemTplFromPool); totalRewardCost += this.itemHelper.getItemPrice(randomItemTplFromPool);
rewards.push(presetAndMods); rewards.push(presetAndMods);
continue; continue;
} }
// Some items can have variable stack size, e.g. ammo // Some items can have variable stack size, e.g. ammo / currency
const stackSize = this.getRewardStackSize(randomItemTplFromPool); const stackSize = this.getRewardStackSize(
randomItemTplFromPool,
rewardBudget / (rewardItemCount === 0 ? 1 : rewardItemCount), // Remaining rouble budget
);
// Not a weapon/armor, standard single item // Not a weapon/armor, standard single item
const rewardItem: Item = { const rewardItem: Item = {
@ -292,7 +295,7 @@ export class CircleOfCultistService {
} }
// Some items can have variable stack size, e.g. ammo // 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 // Not a weapon/armor, standard single item
const rewardItem: Item = { const rewardItem: Item = {
@ -316,14 +319,34 @@ export class CircleOfCultistService {
* Get the size of a reward items stack * Get the size of a reward items stack
* 1 for everything except ammo, ammo can be between min stack and max stack * 1 for everything except ammo, ammo can be between min stack and max stack
* @param itemTpl Item chosen * @param itemTpl Item chosen
* @param rewardPoolRemaining Rouble amount of pool remaining to fill
* @returns Size of stack * @returns Size of stack
*/ */
protected getRewardStackSize(itemTpl: string) { protected getRewardStackSize(itemTpl: string, rewardPoolRemaining: number) {
if (this.itemHelper.isOfBaseclass(itemTpl, BaseClasses.AMMO)) { if (this.itemHelper.isOfBaseclass(itemTpl, BaseClasses.AMMO)) {
const ammoTemplate = this.itemHelper.getItem(itemTpl)[1]; const ammoTemplate = this.itemHelper.getItem(itemTpl)[1];
return this.itemHelper.getRandomisedAmmoStackSize(ammoTemplate); 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; return 1;
} }