Skip to content

Commit d2b7baa

Browse files
chompDevshibdibChomp
authored
Cultist circle improvements (#973)
Brings Cultist Cicle rewards closer to live behavior. --------- Co-authored-by: Bob S <shibdib@users.noreply.github.com> Co-authored-by: Chomp <dev@dev.sp-tarkov.com>
1 parent d34eca3 commit d2b7baa

File tree

6 files changed

+421
-209
lines changed

6 files changed

+421
-209
lines changed

project/assets/configs/hideout.json

+56-54
Original file line numberDiff line numberDiff line change
@@ -16,68 +16,70 @@
1616
"min": 0.7,
1717
"max": 1.4
1818
},
19+
"bonusChanceMultiplier": 0.25,
20+
"bonusAmountMultiplier": 0.43,
21+
"highValueThresholdRub": 70000,
22+
"hideoutTaskRewardTimeSeconds": 21600,
23+
"hideoutCraftSacrificeThresholdRub": 400000,
1924
"craftTimeThreshholds": [
2025
{
2126
"min": 1,
22-
"max": 25000,
23-
"timeSeconds": 21600
27+
"max": 350000,
28+
"craftTimeSeconds": 43200
2429
},
2530
{
26-
"min": 25001,
31+
"min": 350001,
32+
"max": 399999,
33+
"craftTimeSeconds": 50400
34+
},
35+
{
36+
"min": 400000,
2737
"max": 99999999,
28-
"timeSeconds": 43200
38+
"craftTimeSeconds": 50400
2939
}
3040
],
31-
"craftTimeOverride": 40,
32-
"directRewards": {
33-
"66572c82ad599021091c6118": { "rewardTpls": ["5c0e874186f7745dc7616606"], "craftTimeSeconds": 3960 },
34-
"5aa2b986e5b5b00014028f4c": { "rewardTpls": ["62a091170b9d3c46de5b6cf2"], "craftTimeSeconds": 3960 },
35-
"655c663a6689c676ce57af85": { "rewardTpls": ["5c0e655586f774045612eeb2"], "craftTimeSeconds": 3960 },
36-
"655c652d60d0ac437100fed7": { "rewardTpls": ["590c657e86f77412b013051d"], "craftTimeSeconds": 3960 },
37-
"655c67782a1356436041c9c5": {
38-
"rewardTpls": ["59e3577886f774176a362503", "5ed5166ad380ab312177c100"],
39-
"craftTimeSeconds": 3960
40-
},
41-
"655c673673a43e23e857aebd": {
42-
"rewardTpls": ["572b7adb24597762ae139821", "56e335e4d2720b6c058b456d"],
43-
"craftTimeSeconds": 3960
44-
},
45-
"655c66e40b2de553b618d4b8": {
46-
"rewardTpls": ["5d40407c86f774318526545a", "5d40407c86f774318526545a", "5d40407c86f774318526545a"],
47-
"craftTimeSeconds": 3960
48-
},
49-
"6582dbf0b8d7830efc45016f": { "rewardTpls": ["5d1b376e86f774252519444e"], "craftTimeSeconds": 3960 },
50-
"66572be36a723f7f005a066e": { "rewardTpls": ["5b3b713c5acfc4330140bd8d"], "craftTimeSeconds": 3960 },
51-
"655c669103999d3c810c025b": {
52-
"rewardTpls": ["635267ab3c89e2112001f826", "5fc64ea372b0dd78d51159dc"],
53-
"craftTimeSeconds": 3960
54-
},
55-
"66572cbdad599021091c611a": { "rewardTpls": ["60a7ad2a2198820d95707a2e"], "craftTimeSeconds": 3960 },
56-
"5c0530ee86f774697952d952": { "rewardTpls": ["6389c8c5dbfd5e4b95197e6b"], "craftTimeSeconds": 43260 },
57-
"66572b8d80b1cd4b6a67847f": {
58-
"rewardTpls": ["5bc9b9ecd4351e3bac122519", "62a09dd4621468534a797ac7"],
59-
"craftTimeSeconds": 3960
60-
},
61-
"5c093ca986f7740a1867ab12": { "rewardTpls": ["5732ee6a24597719ae0c0281"], "craftTimeSeconds": 3960 },
62-
"665ee77ccf2d642e98220bca": { "rewardTpls": ["5857a8bc2459772bad15db29"], "craftTimeSeconds": 360 },
63-
"59faff1d86f7746c51718c9c": {
64-
"rewardTpls": [
65-
"5c12620d86f7743f8b198b72",
66-
"5c12620d86f7743f8b198b72",
67-
"5e2aedd986f7746d404f3aa4",
68-
"5e2aedd986f7746d404f3aa4"
69-
],
70-
"craftTimeSeconds": 43260
71-
},
72-
"655c663a6689c676ce57af85": { "rewardTpls": ["5c0e655586f774045612eeb2"], "craftTimeSeconds": 3960 },
73-
"5aa2b986e5b5b00014028f4c": { "rewardTpls": ["62a091170b9d3c46de5b6cf2"], "craftTimeSeconds": 3960 },
74-
"5c13cd2486f774072c757944": { "rewardTpls": ["62a0a098de7ac8199358053b"], "craftTimeSeconds": 3960 },
75-
"5a0c27731526d80618476ac4": {
76-
"rewardTpls": ["5d1b392c86f77425243e98fe", "5d1b392c86f77425243e98fe"],
77-
"craftTimeSeconds": 3960
78-
},
79-
"5c0530ee86f774697952d952": { "rewardTpls": ["6389c8c5dbfd5e4b95197e6b"], "craftTimeSeconds": 39960 }
80-
},
41+
"craftTimeOverride": -1,
42+
"directRewards": [
43+
{"reward": ["5857a8bc2459772bad15db29"], "requiredItems": ["665ee77ccf2d642e98220bca"], "craftTimeSeconds": 360,
44+
"repeatable": false },
45+
{"reward": ["5c093ca986f7740a1867ab12"], "requiredItems": ["5732ee6a24597719ae0c0281"], "craftTimeSeconds": 3960,
46+
"repeatable": false },
47+
{"reward": ["655c669103999d3c810c025b"], "requiredItems": ["635267ab3c89e2112001f826"], "craftTimeSeconds": 3960,
48+
"repeatable": false },
49+
{"reward": ["5fc64ea372b0dd78d51159dc"], "requiredItems": ["635267ab3c89e2112001f826", "635267ab3c89e2112001f826",
50+
"635267ab3c89e2112001f826", "635267ab3c89e2112001f826", "635267ab3c89e2112001f826"], "craftTimeSeconds": 3960,
51+
"repeatable": false },
52+
{"reward": ["5c0e874186f7745dc7616606", "5c0e842486f77443a74d2976"], "requiredItems": ["66572c82ad599021091c6118"],
53+
"craftTimeSeconds": 3960, "repeatable": false },
54+
{"reward": ["60a7ad3a0c5cb24b0134664a", "60a7ad2a2198820d95707a2e"], "requiredItems": ["66572cbdad599021091c611a"],
55+
"craftTimeSeconds": 3960, "repeatable": false },
56+
{"reward": ["5b3b713c5acfc4330140bd8d"], "requiredItems": ["66572be36a723f7f005a066e"], "craftTimeSeconds": 3960,
57+
"repeatable": false },
58+
{"reward": ["62a09dd4621468534a797ac7", "5bc9b9ecd4351e3bac122519"], "requiredItems": ["66572b8d80b1cd4b6a67847f"],
59+
"craftTimeSeconds": 3960, "repeatable": false },
60+
{"reward": ["5d40407c86f774318526545a", "5d40407c86f774318526545a", "5d40407c86f774318526545a"], "requiredItems": ["655c66e40b2de553b618d4b8"],
61+
"craftTimeSeconds": 3960, "repeatable": false },
62+
{"reward": ["572b7adb24597762ae139821", "56e335e4d2720b6c058b456d"], "requiredItems": ["655c673673a43e23e857aebd"],
63+
"craftTimeSeconds": 3960, "repeatable": false },
64+
{"reward": ["637b60c3b7afa97bfc3d7001", "59e3577886f774176a362503"], "requiredItems": ["655c67782a1356436041c9c5"],
65+
"craftTimeSeconds": 3960, "repeatable": false },
66+
{"reward": ["590c657e86f77412b013051d"], "requiredItems": ["655c652d60d0ac437100fed7"], "craftTimeSeconds": 3960,
67+
"repeatable": false },
68+
{"reward": ["5c0e655586f774045612eeb2"], "requiredItems": ["655c663a6689c676ce57af85"], "craftTimeSeconds": 3960,
69+
"repeatable": false },
70+
{"reward": ["5d1b376e86f774252519444e"], "requiredItems": ["6582dbf0b8d7830efc45016f"], "craftTimeSeconds": 3960,
71+
"repeatable": true },
72+
{"reward": ["62a091170b9d3c46de5b6cf2"], "requiredItems": ["5aa2b986e5b5b00014028f4c"], "craftTimeSeconds": 3960,
73+
"repeatable": true },
74+
{"reward": ["62a0a098de7ac8199358053b"], "requiredItems": ["5c13cd2486f774072c757944"], "craftTimeSeconds": 3960,
75+
"repeatable": true },
76+
{"reward": ["5d1b392c86f77425243e98fe", "5d1b392c86f77425243e98fe"], "requiredItems": ["5a0c27731526d80618476ac4"],
77+
"craftTimeSeconds": 3960, "repeatable": true },
78+
{"reward": ["5e2aedd986f7746d404f3aa4", "5e2aedd986f7746d404f3aa4", "5c12620d86f7743f8b198b72", "5c12620d86f7743f8b198b72"],
79+
"requiredItems": ["59faff1d86f7746c51718c9c"], "craftTimeSeconds": 39960, "repeatable": true },
80+
{"reward": ["6389c8c5dbfd5e4b95197e6b"], "requiredItems": ["5c0530ee86f774697952d952"], "craftTimeSeconds": 39960,
81+
"repeatable": true }
82+
],
8183
"directRewardStackSize": {
8284
"exampleParentId": { "min": 1000, "max": 50000 }
8385
},

project/src/controllers/GameController.ts

+5
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,11 @@ export class GameController {
117117
fullProfile.spt.migrations = {};
118118
}
119119

120+
// Track one time use cultist rewards
121+
if (typeof fullProfile.spt.cultistRewards === "undefined") {
122+
fullProfile.spt.cultistRewards = new Map();
123+
}
124+
120125
//3.9 migrations
121126
if (fullProfile.spt.version.includes("3.9.") && !fullProfile.spt.migrations["39x"]) {
122127
// Check every item has a valid mongoid

project/src/generators/LocationLootGenerator.ts

+3
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,9 @@ export class LocationLootGenerator {
847847
throw new Error(`Item for tpl ${chosenComposedKey} was not found in the spawn point`);
848848
}
849849
const itemTemplate = this.itemHelper.getItem(chosenTpl)[1];
850+
if (!itemTemplate) {
851+
this.logger.error(`Item tpl: ${chosenTpl} cannot be found in database`);
852+
}
850853

851854
// Item array to return
852855
const itemWithMods: IItem[] = [];

project/src/models/eft/profile/ISptProfile.ts

+8
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,14 @@ export interface ISpt {
192192
freeRepeatableRefreshUsedCount?: Record<string, number>;
193193
/** When was a profile migrated, value is timestamp */
194194
migrations?: Record<string, number>;
195+
/** Cultist circle rewards received that are one time use, key (md5) is a combination of sacrificed + reward items */
196+
cultistRewards?: Map<string, IAcceptedCultistReward>;
197+
}
198+
199+
export interface IAcceptedCultistReward {
200+
timestamp: number;
201+
sacrificeItems: string[];
202+
rewardItems: string[];
195203
}
196204

197205
export interface IModDetails {

project/src/models/spt/config/IHideoutConfig.ts

+17-4
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,21 @@ export interface ICultistCircleSettings {
2020
maxRewardItemCount: number;
2121
maxAttemptsToPickRewardsWithinBudget: number;
2222
rewardPriceMultiplerMinMax: MinMax;
23+
/** The odds that meeting the highest threshold gives you a bonus to crafting time */
24+
bonusAmountMultiplier: number;
25+
bonusChanceMultiplier: number;
26+
/** What is considered a "high-value" item */
27+
highValueThresholdRub: number;
28+
/** Hideout/task reward crafts have a unique craft time */
29+
hideoutTaskRewardTimeSeconds: number;
30+
/** Rouble amount player needs to sacrifice to get chance of hideout/task rewards */
31+
hideoutCraftSacrificeThresholdRub: number;
2332
craftTimeThreshholds: ICraftTimeThreshhold[];
24-
/** -1 means no override */
33+
/** -1 means no override, value in seconds */
2534
craftTimeOverride: number;
26-
/** Specific reward pool when player sacrificed one specific item */
27-
directRewards: Record<string, IDirectRewardSettings>;
35+
/** Specific reward pool when player sacrifice specific item(s) */
36+
directRewards: IDirectRewardSettings[];
37+
/** Overrides for reward stack sizes, keyed by item tpl */
2838
directRewardStackSize: Record<string, MinMax>;
2939
/** Item tpls to exclude from the reward pool */
3040
rewardItemBlacklist: string[];
@@ -38,6 +48,9 @@ export interface ICraftTimeThreshhold extends MinMax {
3848
}
3949

4050
export interface IDirectRewardSettings {
41-
rewardTpls: string[];
51+
reward: string[];
52+
requiredItems: string[];
4253
craftTimeSeconds: number;
54+
/** Is the reward a one time reward or can it be given multiple times */
55+
repeatable: boolean;
4356
}

0 commit comments

Comments
 (0)