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,
|
"craftTimeOverride": 40,
|
||||||
"directRewards": {
|
"directRewards": {
|
||||||
"66572c82ad599021091c6118": ["5c0e874186f7745dc7616606"],
|
"66572c82ad599021091c6118": {"rewardTpls": ["5c0e874186f7745dc7616606"], "craftTimeSeconds": 100},
|
||||||
"66572be36a723f7f005a066e": ["5b3b713c5acfc4330140bd8d"],
|
"66572be36a723f7f005a066e": {"rewardTpls": ["5b3b713c5acfc4330140bd8d"], "craftTimeSeconds": 100},
|
||||||
"655c669103999d3c810c025b": ["635267ab3c89e2112001f826"],
|
"655c669103999d3c810c025b": {"rewardTpls": ["635267ab3c89e2112001f826"], "craftTimeSeconds": 100},
|
||||||
"66572cbdad599021091c611a": ["60a7ad2a2198820d95707a2e"],
|
"66572cbdad599021091c611a": {"rewardTpls": ["60a7ad2a2198820d95707a2e"], "craftTimeSeconds": 100},
|
||||||
"5c0530ee86f774697952d952": ["6389c8c5dbfd5e4b95197e6b"],
|
"5c0530ee86f774697952d952": {"rewardTpls": ["6389c8c5dbfd5e4b95197e6b"], "craftTimeSeconds": 100},
|
||||||
"66572b8d80b1cd4b6a67847f": ["5bc9b9ecd4351e3bac122519", "62a09dd4621468534a797ac7"],
|
"66572b8d80b1cd4b6a67847f": {"rewardTpls": ["5bc9b9ecd4351e3bac122519", "62a09dd4621468534a797ac7"], "craftTimeSeconds": 100},
|
||||||
"5c093ca986f7740a1867ab12": ["5732ee6a24597719ae0c0281"],
|
"5c093ca986f7740a1867ab12": {"rewardTpls": ["5732ee6a24597719ae0c0281"], "craftTimeSeconds": 100},
|
||||||
"665ee77ccf2d642e98220bca": ["5857a8bc2459772bad15db29"],
|
"665ee77ccf2d642e98220bca": {"rewardTpls": ["5857a8bc2459772bad15db29"], "craftTimeSeconds": 100},
|
||||||
"59faff1d86f7746c51718c9c": [
|
"59faff1d86f7746c51718c9c": {"rewardTpls": [
|
||||||
"5c12620d86f7743f8b198b72",
|
"5c12620d86f7743f8b198b72",
|
||||||
"5c12620d86f7743f8b198b72",
|
"5c12620d86f7743f8b198b72",
|
||||||
"5e2aedd986f7746d404f3aa4",
|
"5e2aedd986f7746d404f3aa4",
|
||||||
"5e2aedd986f7746d404f3aa4"
|
"5e2aedd986f7746d404f3aa4"
|
||||||
]
|
], "craftTimeSeconds": 100}
|
||||||
},
|
},
|
||||||
"directRewardStackSize": {
|
"directRewardStackSize": {
|
||||||
"exampleTpl": {"min": 1000, "max": 50000}
|
"exampleParentId": {"min": 1000, "max": 50000}
|
||||||
},
|
},
|
||||||
"rewardItemBlacklist": [],
|
"rewardItemBlacklist": [],
|
||||||
"additionalRewardItemPool": [],
|
"additionalRewardItemPool": [],
|
||||||
|
@ -24,7 +24,7 @@ export interface ICultistCircleSettings {
|
|||||||
/** -1 means no override */
|
/** -1 means no override */
|
||||||
craftTimeOverride: number;
|
craftTimeOverride: number;
|
||||||
/** Specific reward pool when player sacrificed one specific item */
|
/** Specific reward pool when player sacrificed one specific item */
|
||||||
directRewards: Record<string, string[]>;
|
directRewards: Record<string, DirectRewardSettings>;
|
||||||
directRewardStackSize: Record<string, MinMax>;
|
directRewardStackSize: Record<string, MinMax>;
|
||||||
/** Item tpls to exclude from the reward pool */
|
/** Item tpls to exclude from the reward pool */
|
||||||
rewardItemBlacklist: string[];
|
rewardItemBlacklist: string[];
|
||||||
@ -34,5 +34,10 @@ export interface ICultistCircleSettings {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface CraftTimeThreshhold extends MinMax {
|
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 { HideoutAreas } from "@spt/models/enums/HideoutAreas";
|
||||||
import { ItemTpl } from "@spt/models/enums/ItemTpl";
|
import { ItemTpl } from "@spt/models/enums/ItemTpl";
|
||||||
import { SkillTypes } from "@spt/models/enums/SkillTypes";
|
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 { ILogger } from "@spt/models/spt/utils/ILogger";
|
||||||
import { EventOutputHolder } from "@spt/routers/EventOutputHolder";
|
import { EventOutputHolder } from "@spt/routers/EventOutputHolder";
|
||||||
import { ConfigServer } from "@spt/servers/ConfigServer";
|
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
|
// Get the rouble amount we generate rewards with from cost of sacrified items * above multipler
|
||||||
const rewardAmountRoubles = sacrificedItemCostRoubles * rewardAmountMultiplier;
|
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
|
// Create production in pmc profile
|
||||||
this.registerCircleOfCultistProduction(
|
this.registerCircleOfCultistProduction(
|
||||||
sessionId,
|
sessionId,
|
||||||
@ -104,6 +108,7 @@ export class CircleOfCultistService {
|
|||||||
cultistCraftData._id,
|
cultistCraftData._id,
|
||||||
sacrificedItems,
|
sacrificedItems,
|
||||||
rewardAmountRoubles,
|
rewardAmountRoubles,
|
||||||
|
directRewardSettings,
|
||||||
);
|
);
|
||||||
|
|
||||||
const output = this.eventOutputHolder.getOutput(sessionId);
|
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[][];
|
let rewards: Item[][];
|
||||||
if (sacrificedItems.length === 1 && this.hideoutConfig.cultistCircle.directRewards[sacrificedItems[0]._tpl]) {
|
if (hasSacrificedSingleItemFlaggedInConfig) {
|
||||||
rewards = this.getExplicitRewards(
|
rewards = this.getExplicitRewards(directRewardSettings, cultistCircleStashId);
|
||||||
this.hideoutConfig.cultistCircle.directRewards[sacrificedItems[0]._tpl],
|
|
||||||
cultistCircleStashId,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
const rewardItemPool = this.getCultistCircleRewardPool(sessionId, pmcData);
|
const rewardItemPool = this.getCultistCircleRewardPool(sessionId, pmcData);
|
||||||
rewards = this.getRewardsWithinBudget(rewardItemPool, rewardAmountRoubles, cultistCircleStashId);
|
rewards = this.getRewardsWithinBudget(rewardItemPool, rewardAmountRoubles, cultistCircleStashId);
|
||||||
@ -159,36 +160,59 @@ export class CircleOfCultistService {
|
|||||||
return output;
|
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(
|
protected registerCircleOfCultistProduction(
|
||||||
sessionId: string,
|
sessionId: string,
|
||||||
pmcData: IPmcData,
|
pmcData: IPmcData,
|
||||||
recipeId: string,
|
recipeId: string,
|
||||||
sacrificedItems: Item[],
|
sacrificedItems: Item[],
|
||||||
rewardAmountRoubles: number,
|
rewardAmountRoubles: number,
|
||||||
|
directRewardSettings?: DirectRewardSettings,
|
||||||
): void {
|
): void {
|
||||||
|
// Create circle production/craft object to add to player profile
|
||||||
const cultistProduction = this.hideoutHelper.initProduction(
|
const cultistProduction = this.hideoutHelper.initProduction(
|
||||||
recipeId,
|
recipeId,
|
||||||
this.getCircleCraftTime(rewardAmountRoubles),
|
this.getCircleCraftTimeSeconds(rewardAmountRoubles, directRewardSettings),
|
||||||
false,
|
false,
|
||||||
true,
|
true,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// Add items player sacrificed
|
||||||
cultistProduction.GivenItemsInStart = sacrificedItems;
|
cultistProduction.GivenItemsInStart = sacrificedItems;
|
||||||
|
|
||||||
// Add circle production to profile
|
// Add circle production to profile keyed to recipe id
|
||||||
pmcData.Hideout.Production[recipeId] = cultistProduction;
|
pmcData.Hideout.Production[recipeId] = cultistProduction;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the circle craft time as seconds, value is based on reward item value
|
* 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 rewardAmountRoubles Value of rewards in roubles
|
||||||
|
* @param directRewardSettings OPTIONAL: If craft is giving direct rewards
|
||||||
* @returns craft time seconds
|
* @returns craft time seconds
|
||||||
*/
|
*/
|
||||||
protected getCircleCraftTime(rewardAmountRoubles: number): number {
|
protected getCircleCraftTimeSeconds(
|
||||||
|
rewardAmountRoubles: number,
|
||||||
|
directRewardSettings?: DirectRewardSettings,
|
||||||
|
): number {
|
||||||
// Edge case, check if override exists
|
// Edge case, check if override exists
|
||||||
if (this.hideoutConfig.cultistCircle.craftTimeOverride !== -1) {
|
if (this.hideoutConfig.cultistCircle.craftTimeOverride !== -1) {
|
||||||
return this.hideoutConfig.cultistCircle.craftTimeOverride;
|
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 thresholds = this.hideoutConfig.cultistCircle.craftTimeThreshholds;
|
||||||
const matchingThreshold = thresholds.find(
|
const matchingThreshold = thresholds.find(
|
||||||
(craftThreshold) => craftThreshold.min <= rewardAmountRoubles && craftThreshold.max >= rewardAmountRoubles,
|
(craftThreshold) => craftThreshold.min <= rewardAmountRoubles && craftThreshold.max >= rewardAmountRoubles,
|
||||||
@ -198,7 +222,7 @@ export class CircleOfCultistService {
|
|||||||
return this.timeUtil.getHoursAsSeconds(12);
|
return this.timeUtil.getHoursAsSeconds(12);
|
||||||
}
|
}
|
||||||
|
|
||||||
return matchingThreshold.timeSeconds;
|
return matchingThreshold.craftTimeSeconds;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -319,10 +343,10 @@ export class CircleOfCultistService {
|
|||||||
* @param cultistCircleStashId Id of stash item
|
* @param cultistCircleStashId Id of stash item
|
||||||
* @returns Array of item arrays
|
* @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)
|
// Prep rewards array (reward can be item with children, hence array of arrays)
|
||||||
const rewards: Item[][] = [];
|
const rewards: Item[][] = [];
|
||||||
for (const rewardTpl of rewardTpls) {
|
for (const rewardTpl of explicitRewardSettings.rewardTpls) {
|
||||||
if (
|
if (
|
||||||
this.itemHelper.armorItemHasRemovableOrSoftInsertSlots(rewardTpl) ||
|
this.itemHelper.armorItemHasRemovableOrSoftInsertSlots(rewardTpl) ||
|
||||||
this.itemHelper.isOfBaseclass(rewardTpl, BaseClasses.WEAPON)
|
this.itemHelper.isOfBaseclass(rewardTpl, BaseClasses.WEAPON)
|
||||||
@ -345,7 +369,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.getExplicitRewardStackSize(rewardTpl);
|
const stackSize = this.getExplicitRewardBaseTypeStackSize(rewardTpl);
|
||||||
|
|
||||||
// Not a weapon/armor, standard single item
|
// Not a weapon/armor, standard single item
|
||||||
const rewardItem: Item = {
|
const rewardItem: Item = {
|
||||||
@ -365,8 +389,21 @@ export class CircleOfCultistService {
|
|||||||
return rewards;
|
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) {
|
if (!settings) {
|
||||||
return 1;
|
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(
|
protected getPlayerAccessibleRecipes(
|
||||||
unlockedRecipes: string[],
|
unlockedRecipes: string[],
|
||||||
allRecipes: IHideoutProductionData,
|
allRecipes: IHideoutProductionData,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user