Expanded direct rewards to have a custom craft time
Migrated direct reward stack count system to use items parent id instead of tpl
This commit is contained in:
parent
a578e01402
commit
a380db2995
@ -29,23 +29,23 @@
|
||||
],
|
||||
"craftTimeOverride": 40,
|
||||
"directRewards": {
|
||||
"66572c82ad599021091c6118": ["5c0e874186f7745dc7616606"],
|
||||
"66572be36a723f7f005a066e": ["5b3b713c5acfc4330140bd8d"],
|
||||
"655c669103999d3c810c025b": ["635267ab3c89e2112001f826"],
|
||||
"66572cbdad599021091c611a": ["60a7ad2a2198820d95707a2e"],
|
||||
"5c0530ee86f774697952d952": ["6389c8c5dbfd5e4b95197e6b"],
|
||||
"66572b8d80b1cd4b6a67847f": ["5bc9b9ecd4351e3bac122519", "62a09dd4621468534a797ac7"],
|
||||
"5c093ca986f7740a1867ab12": ["5732ee6a24597719ae0c0281"],
|
||||
"665ee77ccf2d642e98220bca": ["5857a8bc2459772bad15db29"],
|
||||
"59faff1d86f7746c51718c9c": [
|
||||
"66572c82ad599021091c6118": {"rewardTpls": ["5c0e874186f7745dc7616606"], "craftTimeSeconds": 100},
|
||||
"66572be36a723f7f005a066e": {"rewardTpls": ["5b3b713c5acfc4330140bd8d"], "craftTimeSeconds": 100},
|
||||
"655c669103999d3c810c025b": {"rewardTpls": ["635267ab3c89e2112001f826"], "craftTimeSeconds": 100},
|
||||
"66572cbdad599021091c611a": {"rewardTpls": ["60a7ad2a2198820d95707a2e"], "craftTimeSeconds": 100},
|
||||
"5c0530ee86f774697952d952": {"rewardTpls": ["6389c8c5dbfd5e4b95197e6b"], "craftTimeSeconds": 100},
|
||||
"66572b8d80b1cd4b6a67847f": {"rewardTpls": ["5bc9b9ecd4351e3bac122519", "62a09dd4621468534a797ac7"], "craftTimeSeconds": 100},
|
||||
"5c093ca986f7740a1867ab12": {"rewardTpls": ["5732ee6a24597719ae0c0281"], "craftTimeSeconds": 100},
|
||||
"665ee77ccf2d642e98220bca": {"rewardTpls": ["5857a8bc2459772bad15db29"], "craftTimeSeconds": 100},
|
||||
"59faff1d86f7746c51718c9c": {"rewardTpls": [
|
||||
"5c12620d86f7743f8b198b72",
|
||||
"5c12620d86f7743f8b198b72",
|
||||
"5e2aedd986f7746d404f3aa4",
|
||||
"5e2aedd986f7746d404f3aa4"
|
||||
]
|
||||
], "craftTimeSeconds": 100}
|
||||
},
|
||||
"directRewardStackSize": {
|
||||
"exampleTpl": {"min": 1000, "max": 50000}
|
||||
"exampleParentId": {"min": 1000, "max": 50000}
|
||||
},
|
||||
"rewardItemBlacklist": [],
|
||||
"additionalRewardItemPool": [],
|
||||
|
@ -24,7 +24,7 @@ export interface ICultistCircleSettings {
|
||||
/** -1 means no override */
|
||||
craftTimeOverride: number;
|
||||
/** Specific reward pool when player sacrificed one specific item */
|
||||
directRewards: Record<string, string[]>;
|
||||
directRewards: Record<string, DirectRewardSettings>;
|
||||
directRewardStackSize: Record<string, MinMax>;
|
||||
/** Item tpls to exclude from the reward pool */
|
||||
rewardItemBlacklist: string[];
|
||||
@ -34,5 +34,10 @@ export interface ICultistCircleSettings {
|
||||
}
|
||||
|
||||
export interface CraftTimeThreshhold extends MinMax {
|
||||
timeSeconds: number;
|
||||
craftTimeSeconds: number;
|
||||
}
|
||||
|
||||
export interface DirectRewardSettings {
|
||||
rewardTpls: string[];
|
||||
craftTimeSeconds: number;
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ import { ConfigTypes } from "@spt/models/enums/ConfigTypes";
|
||||
import { HideoutAreas } from "@spt/models/enums/HideoutAreas";
|
||||
import { ItemTpl } from "@spt/models/enums/ItemTpl";
|
||||
import { SkillTypes } from "@spt/models/enums/SkillTypes";
|
||||
import { IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig";
|
||||
import { DirectRewardSettings, IHideoutConfig } from "@spt/models/spt/config/IHideoutConfig";
|
||||
import { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||
import { EventOutputHolder } from "@spt/routers/EventOutputHolder";
|
||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
||||
@ -97,6 +97,10 @@ export class CircleOfCultistService {
|
||||
// Get the rouble amount we generate rewards with from cost of sacrified items * above multipler
|
||||
const rewardAmountRoubles = sacrificedItemCostRoubles * rewardAmountMultiplier;
|
||||
|
||||
// Has player sacrified a single item in directReward dict
|
||||
const directRewardSettings = this.hideoutConfig.cultistCircle.directRewards[sacrificedItems[0]._tpl];
|
||||
const hasSacrificedSingleItemFlaggedInConfig = sacrificedItems.length === 1 && !!directRewardSettings;
|
||||
|
||||
// Create production in pmc profile
|
||||
this.registerCircleOfCultistProduction(
|
||||
sessionId,
|
||||
@ -104,6 +108,7 @@ export class CircleOfCultistService {
|
||||
cultistCraftData._id,
|
||||
sacrificedItems,
|
||||
rewardAmountRoubles,
|
||||
directRewardSettings,
|
||||
);
|
||||
|
||||
const output = this.eventOutputHolder.getOutput(sessionId);
|
||||
@ -115,13 +120,9 @@ export class CircleOfCultistService {
|
||||
}
|
||||
}
|
||||
|
||||
// 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,
|
||||
);
|
||||
if (hasSacrificedSingleItemFlaggedInConfig) {
|
||||
rewards = this.getExplicitRewards(directRewardSettings, cultistCircleStashId);
|
||||
} else {
|
||||
const rewardItemPool = this.getCultistCircleRewardPool(sessionId, pmcData);
|
||||
rewards = this.getRewardsWithinBudget(rewardItemPool, rewardAmountRoubles, cultistCircleStashId);
|
||||
@ -159,36 +160,59 @@ export class CircleOfCultistService {
|
||||
return output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register production inside player profile
|
||||
* @param sessionId Session id
|
||||
* @param pmcData Player profile
|
||||
* @param recipeId Recipe id
|
||||
* @param sacrificedItems Items player sacrificed
|
||||
* @param rewardAmountRoubles Rouble amount to reward player in items with
|
||||
* @param directRewardSettings OPTIONAL: If craft is giving direct rewards
|
||||
*/
|
||||
protected registerCircleOfCultistProduction(
|
||||
sessionId: string,
|
||||
pmcData: IPmcData,
|
||||
recipeId: string,
|
||||
sacrificedItems: Item[],
|
||||
rewardAmountRoubles: number,
|
||||
directRewardSettings?: DirectRewardSettings,
|
||||
): void {
|
||||
// Create circle production/craft object to add to player profile
|
||||
const cultistProduction = this.hideoutHelper.initProduction(
|
||||
recipeId,
|
||||
this.getCircleCraftTime(rewardAmountRoubles),
|
||||
this.getCircleCraftTimeSeconds(rewardAmountRoubles, directRewardSettings),
|
||||
false,
|
||||
true,
|
||||
);
|
||||
|
||||
// Add items player sacrificed
|
||||
cultistProduction.GivenItemsInStart = sacrificedItems;
|
||||
|
||||
// Add circle production to profile
|
||||
// Add circle production to profile keyed to recipe id
|
||||
pmcData.Hideout.Production[recipeId] = cultistProduction;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the circle craft time as seconds, value is based on reward item value
|
||||
* OR rewards are direct, then use custom craft time defined in oarameter object
|
||||
* @param rewardAmountRoubles Value of rewards in roubles
|
||||
* @param directRewardSettings OPTIONAL: If craft is giving direct rewards
|
||||
* @returns craft time seconds
|
||||
*/
|
||||
protected getCircleCraftTime(rewardAmountRoubles: number): number {
|
||||
protected getCircleCraftTimeSeconds(
|
||||
rewardAmountRoubles: number,
|
||||
directRewardSettings?: DirectRewardSettings,
|
||||
): number {
|
||||
// Edge case, check if override exists
|
||||
if (this.hideoutConfig.cultistCircle.craftTimeOverride !== -1) {
|
||||
return this.hideoutConfig.cultistCircle.craftTimeOverride;
|
||||
}
|
||||
|
||||
// Craft is rewarding items directly, use custom craft time
|
||||
if (directRewardSettings) {
|
||||
return directRewardSettings.craftTimeSeconds;
|
||||
}
|
||||
|
||||
const thresholds = this.hideoutConfig.cultistCircle.craftTimeThreshholds;
|
||||
const matchingThreshold = thresholds.find(
|
||||
(craftThreshold) => craftThreshold.min <= rewardAmountRoubles && craftThreshold.max >= rewardAmountRoubles,
|
||||
@ -198,7 +222,7 @@ export class CircleOfCultistService {
|
||||
return this.timeUtil.getHoursAsSeconds(12);
|
||||
}
|
||||
|
||||
return matchingThreshold.timeSeconds;
|
||||
return matchingThreshold.craftTimeSeconds;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -319,10 +343,10 @@ export class CircleOfCultistService {
|
||||
* @param cultistCircleStashId Id of stash item
|
||||
* @returns Array of item arrays
|
||||
*/
|
||||
protected getExplicitRewards(rewardTpls: string[], cultistCircleStashId: string): Item[][] {
|
||||
protected getExplicitRewards(explicitRewardSettings: DirectRewardSettings, cultistCircleStashId: string): Item[][] {
|
||||
// Prep rewards array (reward can be item with children, hence array of arrays)
|
||||
const rewards: Item[][] = [];
|
||||
for (const rewardTpl of rewardTpls) {
|
||||
for (const rewardTpl of explicitRewardSettings.rewardTpls) {
|
||||
if (
|
||||
this.itemHelper.armorItemHasRemovableOrSoftInsertSlots(rewardTpl) ||
|
||||
this.itemHelper.isOfBaseclass(rewardTpl, BaseClasses.WEAPON)
|
||||
@ -345,7 +369,7 @@ export class CircleOfCultistService {
|
||||
}
|
||||
|
||||
// Some items can have variable stack size, e.g. ammo
|
||||
const stackSize = this.getExplicitRewardStackSize(rewardTpl);
|
||||
const stackSize = this.getExplicitRewardBaseTypeStackSize(rewardTpl);
|
||||
|
||||
// Not a weapon/armor, standard single item
|
||||
const rewardItem: Item = {
|
||||
@ -365,8 +389,21 @@ export class CircleOfCultistService {
|
||||
return rewards;
|
||||
}
|
||||
|
||||
protected getExplicitRewardStackSize(rewardTpl: string) {
|
||||
const settings = this.hideoutConfig.cultistCircle.directRewardStackSize[rewardTpl];
|
||||
/**
|
||||
* Explicit rewards have thier own stack sizes as they dont use a reward rouble pool
|
||||
* @param rewardTpl Item being rewarded to get stack size of
|
||||
* @returns stack size of item
|
||||
*/
|
||||
protected getExplicitRewardBaseTypeStackSize(rewardTpl: string) {
|
||||
const itemDetails = this.itemHelper.getItem(rewardTpl);
|
||||
if (!itemDetails[0]) {
|
||||
this.logger.warning(`${rewardTpl} is not an item, setting stack size to 1`);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
// Look for parent in dict
|
||||
const settings = this.hideoutConfig.cultistCircle.directRewardStackSize[itemDetails[1]._parent];
|
||||
if (!settings) {
|
||||
return 1;
|
||||
}
|
||||
@ -512,6 +549,12 @@ export class CircleOfCultistService {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all recipes the player has access to, includes base + unlocked recipes
|
||||
* @param unlockedRecipes Recipes player has flagged as unlocked
|
||||
* @param allRecipes All recipes
|
||||
* @returns Array of recipes
|
||||
*/
|
||||
protected getPlayerAccessibleRecipes(
|
||||
unlockedRecipes: string[],
|
||||
allRecipes: IHideoutProductionData,
|
||||
|
Loading…
x
Reference in New Issue
Block a user