返回提交历史
Modified
src/services/worldStateService.ts
+340
-129
Modified
src/types/worldStateTypes.ts
+3
-2
Modified
static/fixed_responses/worldState/worldState.json
+0
-242
XFEstudio/SpaceNinjaServer
fix: provide upcoming bounties in worldState when new cycle is imminent (#1657)
Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/1657 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
c13615c4
代码差异
3 个文件
+343
-373
@@ -9,7 +9,6 @@ import { config } from "@/src/services/configService";
9
9
import { CRng } from "@/src/services/rngService";
10
10
import { eMissionType, ExportNightwave, ExportRegions } from "warframe-public-export-plus";
11
11
import { ISeasonChallenge, IWorldState } from "../types/worldStateTypes";
12
import { logger } from "../utils/logger";
13
12
14
13
const sortieBosses = [
15
14
"SORTIE_BOSS_HYENA",
@@ -80,73 +79,76 @@ const sortieBossNode: Record<string, string> = {
80
79
SORTIE_BOSS_INFALAD: "SolNode705"
81
80
};
82
81
83
const jobSets: string[][] = [
84
[
85
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyAss",
86
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyCap",
87
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountySab",
88
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountyLib",
89
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountyCap",
90
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountyExt",
91
"/Lotus/Types/Gameplay/Eidolon/Jobs/ReclamationBountyCap",
92
"/Lotus/Types/Gameplay/Eidolon/Jobs/ReclamationBountyTheft",
93
"/Lotus/Types/Gameplay/Eidolon/Jobs/ReclamationBountyCache",
94
"/Lotus/Types/Gameplay/Eidolon/Jobs/CaptureBountyCapOne",
95
"/Lotus/Types/Gameplay/Eidolon/Jobs/CaptureBountyCapTwo",
96
"/Lotus/Types/Gameplay/Eidolon/Jobs/SabotageBountySab",
97
"/Lotus/Types/Gameplay/Eidolon/Jobs/RescueBountyResc"
98
],
99
[
100
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AssassinateBountyAss",
101
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyExt",
102
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/ReclamationBountyTheft",
103
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyLib"
104
],
105
[
106
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobAmbush",
107
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobExcavation",
108
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobRecovery",
109
"/Lotus/Types/Gameplay/Venus/Jobs/VenusChaosJobAssassinate",
110
"/Lotus/Types/Gameplay/Venus/Jobs/VenusChaosJobExcavation",
111
"/Lotus/Types/Gameplay/Venus/Jobs/VenusCullJobAssassinate",
112
"/Lotus/Types/Gameplay/Venus/Jobs/VenusCullJobExterminate",
113
"/Lotus/Types/Gameplay/Venus/Jobs/VenusCullJobResource",
114
"/Lotus/Types/Gameplay/Venus/Jobs/VenusIntelJobRecovery",
115
"/Lotus/Types/Gameplay/Venus/Jobs/VenusIntelJobResource",
116
"/Lotus/Types/Gameplay/Venus/Jobs/VenusIntelJobSpy",
117
"/Lotus/Types/Gameplay/Venus/Jobs/VenusSpyJobSpy",
118
"/Lotus/Types/Gameplay/Venus/Jobs/VenusTheftJobAmbush",
119
"/Lotus/Types/Gameplay/Venus/Jobs/VenusTheftJobExcavation",
120
"/Lotus/Types/Gameplay/Venus/Jobs/VenusTheftJobResource",
121
"/Lotus/Types/Gameplay/Venus/Jobs/VenusHelpingJobCaches",
122
"/Lotus/Types/Gameplay/Venus/Jobs/VenusHelpingJobResource",
123
"/Lotus/Types/Gameplay/Venus/Jobs/VenusHelpingJobSpy",
124
"/Lotus/Types/Gameplay/Venus/Jobs/VenusPreservationJobDefense",
125
"/Lotus/Types/Gameplay/Venus/Jobs/VenusPreservationJobRecovery",
126
"/Lotus/Types/Gameplay/Venus/Jobs/VenusPreservationJobResource",
127
"/Lotus/Types/Gameplay/Venus/Jobs/VenusWetworkJobAssassinate",
128
"/Lotus/Types/Gameplay/Venus/Jobs/VenusWetworkJobSpy"
129
],
130
[
131
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobAssassinate",
132
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobExterminate",
133
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusPreservationJobDefense",
134
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusTheftJobExcavation"
135
],
136
[
137
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAreaDefenseBounty",
138
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAssassinateBounty",
139
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosCrpSurvivorBounty",
140
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosGrnSurvivorBounty",
141
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosKeyPiecesBounty",
142
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosExcavateBounty",
143
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosPurifyBounty"
144
],
145
[
146
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessAreaDefenseBounty",
147
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessExcavateBounty",
148
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessPurifyBounty"
149
]
82
const eidolonJobs = [
83
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyAss",
84
"/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyCap",
85
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountySab",
86
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountyLib",
87
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountyCap",
88
"/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountyExt",
89
"/Lotus/Types/Gameplay/Eidolon/Jobs/ReclamationBountyCap",
90
"/Lotus/Types/Gameplay/Eidolon/Jobs/ReclamationBountyTheft",
91
"/Lotus/Types/Gameplay/Eidolon/Jobs/ReclamationBountyCache",
92
"/Lotus/Types/Gameplay/Eidolon/Jobs/CaptureBountyCapOne",
93
"/Lotus/Types/Gameplay/Eidolon/Jobs/CaptureBountyCapTwo",
94
"/Lotus/Types/Gameplay/Eidolon/Jobs/SabotageBountySab",
95
"/Lotus/Types/Gameplay/Eidolon/Jobs/RescueBountyResc"
96
];
97
98
const eidolonNarmerJobs = [
99
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AssassinateBountyAss",
100
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyExt",
101
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/ReclamationBountyTheft",
102
"/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AttritionBountyLib"
103
];
104
105
const venusJobs = [
106
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobAmbush",
107
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobExcavation",
108
"/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobRecovery",
109
"/Lotus/Types/Gameplay/Venus/Jobs/VenusChaosJobAssassinate",
110
"/Lotus/Types/Gameplay/Venus/Jobs/VenusChaosJobExcavation",
111
"/Lotus/Types/Gameplay/Venus/Jobs/VenusCullJobAssassinate",
112
"/Lotus/Types/Gameplay/Venus/Jobs/VenusCullJobExterminate",
113
"/Lotus/Types/Gameplay/Venus/Jobs/VenusCullJobResource",
114
"/Lotus/Types/Gameplay/Venus/Jobs/VenusIntelJobRecovery",
115
"/Lotus/Types/Gameplay/Venus/Jobs/VenusIntelJobResource",
116
"/Lotus/Types/Gameplay/Venus/Jobs/VenusIntelJobSpy",
117
"/Lotus/Types/Gameplay/Venus/Jobs/VenusSpyJobSpy",
118
"/Lotus/Types/Gameplay/Venus/Jobs/VenusTheftJobAmbush",
119
"/Lotus/Types/Gameplay/Venus/Jobs/VenusTheftJobExcavation",
120
"/Lotus/Types/Gameplay/Venus/Jobs/VenusTheftJobResource",
121
"/Lotus/Types/Gameplay/Venus/Jobs/VenusHelpingJobCaches",
122
"/Lotus/Types/Gameplay/Venus/Jobs/VenusHelpingJobResource",
123
"/Lotus/Types/Gameplay/Venus/Jobs/VenusHelpingJobSpy",
124
"/Lotus/Types/Gameplay/Venus/Jobs/VenusPreservationJobDefense",
125
"/Lotus/Types/Gameplay/Venus/Jobs/VenusPreservationJobRecovery",
126
"/Lotus/Types/Gameplay/Venus/Jobs/VenusPreservationJobResource",
127
"/Lotus/Types/Gameplay/Venus/Jobs/VenusWetworkJobAssassinate",
128
"/Lotus/Types/Gameplay/Venus/Jobs/VenusWetworkJobSpy"
129
];
130
131
const venusNarmerJobs = [
132
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobAssassinate",
133
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobExterminate",
134
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusPreservationJobDefense",
135
"/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusTheftJobExcavation"
136
];
137
138
const microplanetJobs = [
139
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAreaDefenseBounty",
140
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAssassinateBounty",
141
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosCrpSurvivorBounty",
142
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosGrnSurvivorBounty",
143
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosKeyPiecesBounty",
144
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosExcavateBounty",
145
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosPurifyBounty"
146
];
147
148
const microplanetEndlessJobs = [
149
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessAreaDefenseBounty",
150
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessExcavateBounty",
151
"/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessPurifyBounty"
150
152
];
151
153
152
154
const EPOCH = 1734307200 * 1000; // Monday, Dec 16, 2024 @ 00:00 UTC+0; should logically be winter in 1999 iteration 0
@@ -218,6 +220,10 @@ const getSeasonWeeklyHardChallenge = (week: number, id: number): ISeasonChalleng
218
220
};
219
221
};
220
222
223
const expiresBeforeNextExpectedWorldStateRefresh = (date: number): boolean => {
224
return Date.now() + 300_000 > date;
225
};
226
221
227
export const getWorldState = (buildLabel?: string): IWorldState => {
222
228
const day = Math.trunc((Date.now() - EPOCH) / 86400000);
223
229
const week = Math.trunc(day / 7);
@@ -228,9 +234,10 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
228
234
BuildLabel: typeof buildLabel == "string" ? buildLabel.split(" ").join("+") : buildConfig.buildLabel,
229
235
Time: config.worldState?.lockTime || Math.round(Date.now() / 1000),
230
236
Goals: [],
231
GlobalUpgrades: [],
237
Alerts: [],
232
238
Sorties: [],
233
239
LiteSorties: [],
240
GlobalUpgrades: [],
234
241
EndlessXpChoices: [],
235
242
SeasonInfo: {
236
243
Activation: { $date: { $numberLong: "1715796000000" } },
@@ -268,7 +275,8 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
268
275
}
269
276
]
270
277
},
271
...staticWorldState
278
...staticWorldState,
279
SyndicateMissions: [...staticWorldState.SyndicateMissions]
272
280
};
273
281
274
282
if (config.worldState?.starDays) {
@@ -292,69 +300,272 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
292
300
worldState.NodeOverrides.find(x => x.Node == "SolNode802")!.Seed = week; // unfaithful
293
301
294
302
// Holdfast, Cavia, & Hex bounties cycling every 2.5 hours; unfaithful implementation
295
const bountyCycle = Math.trunc(Date.now() / 9000000);
296
const bountyCycleStart = bountyCycle * 9000000;
297
const bountyCycleEnd = bountyCycleStart + 9000000;
298
worldState.SyndicateMissions[worldState.SyndicateMissions.findIndex(x => x.Tag == "ZarimanSyndicate")] = {
299
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000029" },
300
Activation: { $date: { $numberLong: bountyCycleStart.toString() } },
301
Expiry: { $date: { $numberLong: bountyCycleEnd.toString() } },
302
Tag: "ZarimanSyndicate",
303
Seed: bountyCycle,
304
Nodes: []
305
};
306
worldState.SyndicateMissions[worldState.SyndicateMissions.findIndex(x => x.Tag == "EntratiLabSyndicate")] = {
307
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000004" },
308
Activation: { $date: { $numberLong: bountyCycleStart.toString() } },
309
Expiry: { $date: { $numberLong: bountyCycleEnd.toString() } },
310
Tag: "EntratiLabSyndicate",
311
Seed: bountyCycle,
312
Nodes: []
313
};
314
worldState.SyndicateMissions[worldState.SyndicateMissions.findIndex(x => x.Tag == "HexSyndicate")] = {
315
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000006" },
316
Activation: { $date: { $numberLong: bountyCycleStart.toString(10) } },
317
Expiry: { $date: { $numberLong: bountyCycleEnd.toString(10) } },
318
Tag: "HexSyndicate",
319
Seed: bountyCycle,
320
Nodes: []
321
};
322
for (const syndicateInfo of worldState.SyndicateMissions) {
323
if (syndicateInfo.Jobs && syndicateInfo.Seed != bountyCycle) {
324
syndicateInfo.Activation.$date.$numberLong = bountyCycleStart.toString(10);
325
syndicateInfo.Expiry.$date.$numberLong = bountyCycleEnd.toString(10);
326
syndicateInfo.Seed = bountyCycle;
327
logger.debug(`refreshing jobs for ${syndicateInfo.Tag}`);
303
let bountyCycle = Math.trunc(Date.now() / 9000000);
304
let bountyCycleEnd: number | undefined;
305
do {
306
const bountyCycleStart = bountyCycle * 9000000;
307
bountyCycleEnd = bountyCycleStart + 9000000;
308
worldState.SyndicateMissions.push({
309
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000029" },
310
Activation: { $date: { $numberLong: bountyCycleStart.toString() } },
311
Expiry: { $date: { $numberLong: bountyCycleEnd.toString() } },
312
Tag: "ZarimanSyndicate",
313
Seed: bountyCycle,
314
Nodes: []
315
});
316
worldState.SyndicateMissions.push({
317
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000004" },
318
Activation: { $date: { $numberLong: bountyCycleStart.toString() } },
319
Expiry: { $date: { $numberLong: bountyCycleEnd.toString() } },
320
Tag: "EntratiLabSyndicate",
321
Seed: bountyCycle,
322
Nodes: []
323
});
324
worldState.SyndicateMissions.push({
325
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000006" },
326
Activation: { $date: { $numberLong: bountyCycleStart.toString(10) } },
327
Expiry: { $date: { $numberLong: bountyCycleEnd.toString(10) } },
328
Tag: "HexSyndicate",
329
Seed: bountyCycle,
330
Nodes: []
331
});
332
333
const table = String.fromCharCode(65 + (bountyCycle % 3));
334
const vaultTable = String.fromCharCode(65 + ((bountyCycle + 1) % 3));
335
const deimosDTable = String.fromCharCode(65 + (bountyCycle % 2));
336
337
// TODO: xpAmounts need to be calculated based on the jobType somehow?
338
339
{
328
340
const rng = new CRng(bountyCycle);
329
const table = String.fromCharCode(65 + (bountyCycle % 3));
330
const vaultTable = String.fromCharCode(65 + ((bountyCycle + 1) % 3));
331
const deimosDTable = String.fromCharCode(65 + (bountyCycle % 2));
332
//console.log({ bountyCycleStart, bountyCycleEnd, table, vaultTable, deimosDTable });
333
for (const jobInfo of syndicateInfo.Jobs) {
334
if (jobInfo.jobType) {
335
let found = false;
336
for (const jobSet of jobSets) {
337
if (jobSet.indexOf(jobInfo.jobType) != -1) {
338
jobInfo.jobType = rng.randomElement(jobSet);
339
// TODO: xpAmounts seems like it might need to differ depending on the job?
340
found = true;
341
break;
342
}
341
worldState.SyndicateMissions.push({
342
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000008" },
343
Activation: { $date: { $numberLong: bountyCycleStart.toString(10) } },
344
Expiry: { $date: { $numberLong: bountyCycleEnd.toString(10) } },
345
Tag: "CetusSyndicate",
346
Seed: bountyCycle,
347
Nodes: [],
348
Jobs: [
349
{
350
jobType: rng.randomElement(eidolonJobs),
351
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierATable${table}Rewards`,
352
masteryReq: 0,
353
minEnemyLevel: 5,
354
maxEnemyLevel: 15,
355
xpAmounts: [430, 430, 430]
356
},
357
{
358
jobType: rng.randomElement(eidolonJobs),
359
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierBTable${table}Rewards`,
360
masteryReq: 1,
361
minEnemyLevel: 10,
362
maxEnemyLevel: 30,
363
xpAmounts: [620, 620, 620]
364
},
365
{
366
jobType: rng.randomElement(eidolonJobs),
367
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierCTable${table}Rewards`,
368
masteryReq: 2,
369
minEnemyLevel: 20,
370
maxEnemyLevel: 40,
371
xpAmounts: [670, 670, 670, 990]
372
},
373
{
374
jobType: rng.randomElement(eidolonJobs),
375
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierDTable${table}Rewards`,
376
masteryReq: 3,
377
minEnemyLevel: 30,
378
maxEnemyLevel: 50,
379
xpAmounts: [570, 570, 570, 570, 1110]
380
},
381
{
382
jobType: rng.randomElement(eidolonJobs),
383
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${table}Rewards`,
384
masteryReq: 5,
385
minEnemyLevel: 40,
386
maxEnemyLevel: 60,
387
xpAmounts: [740, 740, 740, 740, 1450]
388
},
389
{
390
jobType: rng.randomElement(eidolonJobs),
391
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETable${table}Rewards`,
392
masteryReq: 10,
393
minEnemyLevel: 100,
394
maxEnemyLevel: 100,
395
xpAmounts: [840, 840, 840, 840, 1660]
396
},
397
{
398
jobType: rng.randomElement(eidolonNarmerJobs),
399
rewards: `/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/NarmerTable${table}Rewards`,
400
masteryReq: 0,
401
minEnemyLevel: 50,
402
maxEnemyLevel: 70,
403
xpAmounts: [840, 840, 840, 840, 1650]
343
404
}
344
if (!found) {
345
logger.warn(`no job set found for type ${jobInfo.jobType}`);
405
]
406
});
407
}
408
409
{
410
const rng = new CRng(bountyCycle);
411
worldState.SyndicateMissions.push({
412
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000025" },
413
Activation: { $date: { $numberLong: bountyCycleStart.toString(10) } },
414
Expiry: { $date: { $numberLong: bountyCycleEnd.toString(10) } },
415
Tag: "SolarisSyndicate",
416
Seed: bountyCycle,
417
Nodes: [],
418
Jobs: [
419
{
420
jobType: rng.randomElement(venusJobs),
421
rewards: `Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierATable${table}Rewards`,
422
masteryReq: 0,
423
minEnemyLevel: 5,
424
maxEnemyLevel: 15,
425
xpAmounts: [340, 340, 340]
426
},
427
{
428
jobType: rng.randomElement(venusJobs),
429
rewards: `Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierBTable${table}Rewards`,
430
masteryReq: 1,
431
minEnemyLevel: 10,
432
maxEnemyLevel: 30,
433
xpAmounts: [660, 660, 660]
434
},
435
{
436
jobType: rng.randomElement(venusJobs),
437
rewards: `Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierCTable${table}Rewards`,
438
masteryReq: 2,
439
minEnemyLevel: 20,
440
maxEnemyLevel: 40,
441
xpAmounts: [610, 610, 610, 900]
442
},
443
{
444
jobType: rng.randomElement(venusJobs),
445
rewards: `Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierDTable${table}Rewards`,
446
masteryReq: 3,
447
minEnemyLevel: 30,
448
maxEnemyLevel: 50,
449
xpAmounts: [600, 600, 600, 600, 1170]
450
},
451
{
452
jobType: rng.randomElement(venusJobs),
453
rewards: `Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${table}Rewards`,
454
masteryReq: 5,
455
minEnemyLevel: 40,
456
maxEnemyLevel: 60,
457
xpAmounts: [690, 690, 690, 690, 1350]
458
},
459
{
460
jobType: rng.randomElement(venusJobs),
461
rewards: `Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETable${table}Rewards`,
462
masteryReq: 10,
463
minEnemyLevel: 100,
464
maxEnemyLevel: 100,
465
xpAmounts: [840, 840, 840, 840, 1660]
466
},
467
{
468
jobType: rng.randomElement(venusNarmerJobs),
469
rewards: "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/NarmerTableBRewards",
470
masteryReq: 0,
471
minEnemyLevel: 50,
472
maxEnemyLevel: 70,
473
xpAmounts: [780, 780, 780, 780, 1540]
346
474
}
347
}
348
if (jobInfo.endless || jobInfo.isVault) {
349
jobInfo.rewards = jobInfo.rewards.replace(/Table.Rewards/, `Table${vaultTable}Rewards`);
350
} else if (jobInfo.rewards.startsWith("/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierD")) {
351
jobInfo.rewards = jobInfo.rewards.replace(/Table.Rewards/, `Table${deimosDTable}Rewards`);
352
} else if (!jobInfo.rewards.startsWith("/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierE")) {
353
jobInfo.rewards = jobInfo.rewards.replace(/Table.Rewards/, `Table${table}Rewards`);
354
}
355
}
475
]
476
});
356
477
}
357
}
478
479
{
480
const rng = new CRng(bountyCycle);
481
worldState.SyndicateMissions.push({
482
_id: { $oid: Math.trunc(bountyCycleStart / 1000).toString(16) + "0000000000000002" },
483
Activation: { $date: { $numberLong: bountyCycleStart.toString(10) } },
484
Expiry: { $date: { $numberLong: bountyCycleEnd.toString(10) } },
485
Tag: "EntratiSyndicate",
486
Seed: bountyCycle,
487
Nodes: [],
488
Jobs: [
489
{
490
jobType: rng.randomElement(microplanetJobs),
491
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierATable${table}Rewards`,
492
masteryReq: 0,
493
minEnemyLevel: 5,
494
maxEnemyLevel: 15,
495
xpAmounts: [5, 5, 5]
496
},
497
{
498
jobType: rng.randomElement(microplanetJobs),
499
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierCTable${table}Rewards`,
500
masteryReq: 1,
501
minEnemyLevel: 15,
502
maxEnemyLevel: 25,
503
xpAmounts: [12, 12, 12]
504
},
505
{
506
jobType: rng.randomElement(microplanetEndlessJobs),
507
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTable${table}Rewards`,
508
masteryReq: 5,
509
minEnemyLevel: 25,
510
maxEnemyLevel: 30,
511
endless: true,
512
xpAmounts: [14, 14, 14]
513
},
514
{
515
jobType: rng.randomElement(microplanetJobs),
516
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierDTable${deimosDTable}Rewards`,
517
masteryReq: 2,
518
minEnemyLevel: 30,
519
maxEnemyLevel: 40,
520
xpAmounts: [17, 17, 17, 25]
521
},
522
{
523
jobType: rng.randomElement(microplanetJobs),
524
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards`,
525
masteryReq: 3,
526
minEnemyLevel: 40,
527
maxEnemyLevel: 60,
528
xpAmounts: [22, 22, 22, 22, 43]
529
},
530
{
531
jobType: rng.randomElement(microplanetJobs),
532
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards`,
533
masteryReq: 10,
534
minEnemyLevel: 100,
535
maxEnemyLevel: 100,
536
xpAmounts: [25, 25, 25, 25, 50]
537
},
538
{
539
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierATable${vaultTable}Rewards`,
540
masteryReq: 5,
541
minEnemyLevel: 30,
542
maxEnemyLevel: 40,
543
xpAmounts: [2, 2, 2, 4],
544
locationTag: "ChamberB",
545
isVault: true
546
},
547
{
548
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierBTable${vaultTable}Rewards`,
549
masteryReq: 5,
550
minEnemyLevel: 40,
551
maxEnemyLevel: 50,
552
xpAmounts: [4, 4, 4, 5],
553
locationTag: "ChamberA",
554
isVault: true
555
},
556
{
557
rewards: `/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierCTable${vaultTable}Rewards`,
558
masteryReq: 5,
559
minEnemyLevel: 50,
560
maxEnemyLevel: 60,
561
xpAmounts: [5, 5, 5, 7],
562
locationTag: "ChamberC",
563
isVault: true
564
}
565
]
566
});
567
}
568
} while (expiresBeforeNextExpectedWorldStateRefresh(bountyCycleEnd) && ++bountyCycle);
358
569
359
570
if (config.worldState?.creditBoost) {
360
571
worldState.GlobalUpgrades.push({
@@ -5,10 +5,11 @@ export interface IWorldState {
5
5
BuildLabel: string;
6
6
Time: number;
7
7
Goals: IGoal[];
8
SyndicateMissions: ISyndicateMissionInfo[];
9
GlobalUpgrades: IGlobalUpgrade[];
8
Alerts: [];
10
9
Sorties: ISortie[];
11
10
LiteSorties: ILiteSortie[];
11
SyndicateMissions: ISyndicateMissionInfo[];
12
GlobalUpgrades: IGlobalUpgrade[];
12
13
NodeOverrides: INodeOverride[];
13
14
EndlessXpChoices: IEndlessXpChoice[];
14
15
SeasonInfo: {
@@ -278,248 +278,6 @@
278
278
"Tag": "SteelMeridianSyndicate",
279
279
"Seed": 42366,
280
280
"Nodes": ["SolNode27", "SolNode107", "SolNode214", "SettlementNode1", "SolNode177", "SolNode141", "SolNode408"]
281
},
282
{
283
"_id": { "$oid": "663a71c80000000000000002" },
284
"Activation": { "$date": { "$numberLong": "1715106248403" } },
285
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
286
"Tag": "EntratiSyndicate",
287
"Seed": 99561,
288
"Nodes": [],
289
"Jobs": [
290
{
291
"jobType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosGrnSurvivorBounty",
292
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierATableBRewards",
293
"masteryReq": 0,
294
"minEnemyLevel": 5,
295
"maxEnemyLevel": 15,
296
"xpAmounts": [5, 5, 5]
297
},
298
{
299
"jobType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAreaDefenseBounty",
300
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierCTableBRewards",
301
"masteryReq": 1,
302
"minEnemyLevel": 15,
303
"maxEnemyLevel": 25,
304
"xpAmounts": [12, 12, 12]
305
},
306
{
307
"jobType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosEndlessExcavateBounty",
308
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierBTableARewards",
309
"masteryReq": 5,
310
"minEnemyLevel": 25,
311
"maxEnemyLevel": 30,
312
"endless": true,
313
"xpAmounts": [14, 14, 14]
314
},
315
{
316
"jobType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosAssassinateBounty",
317
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierDTableBRewards",
318
"masteryReq": 2,
319
"minEnemyLevel": 30,
320
"maxEnemyLevel": 40,
321
"xpAmounts": [17, 17, 17, 25]
322
},
323
{
324
"jobType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosKeyPiecesBounty",
325
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards",
326
"masteryReq": 3,
327
"minEnemyLevel": 40,
328
"maxEnemyLevel": 60,
329
"xpAmounts": [22, 22, 22, 22, 43]
330
},
331
{
332
"jobType": "/Lotus/Types/Gameplay/InfestedMicroplanet/Jobs/DeimosExcavateBounty",
333
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/TierETableARewards",
334
"masteryReq": 10,
335
"minEnemyLevel": 100,
336
"maxEnemyLevel": 100,
337
"xpAmounts": [25, 25, 25, 25, 50]
338
},
339
{
340
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierATableCRewards",
341
"masteryReq": 5,
342
"minEnemyLevel": 30,
343
"maxEnemyLevel": 40,
344
"xpAmounts": [2, 2, 2, 4],
345
"locationTag": "ChamberB",
346
"isVault": true
347
},
348
{
349
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierBTableCRewards",
350
"masteryReq": 5,
351
"minEnemyLevel": 40,
352
"maxEnemyLevel": 50,
353
"xpAmounts": [4, 4, 4, 5],
354
"locationTag": "ChamberA",
355
"isVault": true
356
},
357
{
358
"rewards": "/Lotus/Types/Game/MissionDecks/DeimosMissionRewards/VaultBountyTierCTableCRewards",
359
"masteryReq": 5,
360
"minEnemyLevel": 50,
361
"maxEnemyLevel": 60,
362
"xpAmounts": [5, 5, 5, 7],
363
"locationTag": "ChamberC",
364
"isVault": true
365
}
366
]
367
},
368
{
369
"_id": { "$oid": "663a71c80000000000000004" },
370
"Activation": { "$date": { "$numberLong": "1715106248403" } },
371
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
372
"Tag": "EntratiLabSyndicate",
373
"Seed": 99562,
374
"Nodes": []
375
},
376
{
377
"_id": { "$oid": "663a71c80000000000000008" },
378
"Activation": { "$date": { "$numberLong": "1715106248403" } },
379
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
380
"Tag": "CetusSyndicate",
381
"Seed": 99561,
382
"Nodes": [],
383
"Jobs": [
384
{
385
"jobType": "/Lotus/Types/Gameplay/Eidolon/Jobs/AssassinateBountyCap",
386
"rewards": "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierATableBRewards",
387
"masteryReq": 0,
388
"minEnemyLevel": 5,
389
"maxEnemyLevel": 15,
390
"xpAmounts": [430, 430, 430]
391
},
392
{
393
"jobType": "/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountyLib",
394
"rewards": "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierBTableBRewards",
395
"masteryReq": 1,
396
"minEnemyLevel": 10,
397
"maxEnemyLevel": 30,
398
"xpAmounts": [620, 620, 620]
399
},
400
{
401
"jobType": "/Lotus/Types/Gameplay/Eidolon/Jobs/RescueBountyResc",
402
"rewards": "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierCTableBRewards",
403
"masteryReq": 2,
404
"minEnemyLevel": 20,
405
"maxEnemyLevel": 40,
406
"xpAmounts": [670, 670, 670, 990]
407
},
408
{
409
"jobType": "/Lotus/Types/Gameplay/Eidolon/Jobs/CaptureBountyCapTwo",
410
"rewards": "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierDTableBRewards",
411
"masteryReq": 3,
412
"minEnemyLevel": 30,
413
"maxEnemyLevel": 50,
414
"xpAmounts": [570, 570, 570, 570, 1110]
415
},
416
{
417
"jobType": "/Lotus/Types/Gameplay/Eidolon/Jobs/ReclamationBountyCache",
418
"rewards": "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETableBRewards",
419
"masteryReq": 5,
420
"minEnemyLevel": 40,
421
"maxEnemyLevel": 60,
422
"xpAmounts": [740, 740, 740, 740, 1450]
423
},
424
{
425
"jobType": "/Lotus/Types/Gameplay/Eidolon/Jobs/AttritionBountyCap",
426
"rewards": "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/TierETableBRewards",
427
"masteryReq": 10,
428
"minEnemyLevel": 100,
429
"maxEnemyLevel": 100,
430
"xpAmounts": [840, 840, 840, 840, 1660]
431
},
432
{
433
"jobType": "/Lotus/Types/Gameplay/Eidolon/Jobs/Narmer/AssassinateBountyAss",
434
"rewards": "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/NarmerTableBRewards",
435
"masteryReq": 0,
436
"minEnemyLevel": 50,
437
"maxEnemyLevel": 70,
438
"xpAmounts": [840, 840, 840, 840, 1650]
439
}
440
]
441
},
442
{
443
"_id": { "$oid": "663a71c80000000000000025" },
444
"Activation": { "$date": { "$numberLong": "1715106248403" } },
445
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
446
"Tag": "SolarisSyndicate",
447
"Seed": 99561,
448
"Nodes": [],
449
"Jobs": [
450
{
451
"jobType": "/Lotus/Types/Gameplay/Venus/Jobs/VenusIntelJobSpy",
452
"rewards": "/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierATableBRewards",
453
"masteryReq": 0,
454
"minEnemyLevel": 5,
455
"maxEnemyLevel": 15,
456
"xpAmounts": [340, 340, 340]
457
},
458
{
459
"jobType": "/Lotus/Types/Gameplay/Venus/Jobs/VenusCullJobResource",
460
"rewards": "/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierBTableBRewards",
461
"masteryReq": 1,
462
"minEnemyLevel": 10,
463
"maxEnemyLevel": 30,
464
"xpAmounts": [660, 660, 660]
465
},
466
{
467
"jobType": "/Lotus/Types/Gameplay/Venus/Jobs/VenusIntelJobRecovery",
468
"rewards": "/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierCTableBRewards",
469
"masteryReq": 2,
470
"minEnemyLevel": 20,
471
"maxEnemyLevel": 40,
472
"xpAmounts": [610, 610, 610, 900]
473
},
474
{
475
"jobType": "/Lotus/Types/Gameplay/Venus/Jobs/VenusHelpingJobCaches",
476
"rewards": "/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierDTableBRewards",
477
"masteryReq": 3,
478
"minEnemyLevel": 30,
479
"maxEnemyLevel": 50,
480
"xpAmounts": [600, 600, 600, 600, 1170]
481
},
482
{
483
"jobType": "/Lotus/Types/Gameplay/Venus/Jobs/VenusArtifactJobAmbush",
484
"rewards": "/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETableBRewards",
485
"masteryReq": 5,
486
"minEnemyLevel": 40,
487
"maxEnemyLevel": 60,
488
"xpAmounts": [690, 690, 690, 690, 1350]
489
},
490
{
491
"jobType": "/Lotus/Types/Gameplay/Venus/Jobs/VenusChaosJobExcavation",
492
"rewards": "/Lotus/Types/Game/MissionDecks/VenusJobMissionRewards/VenusTierETableBRewards",
493
"masteryReq": 10,
494
"minEnemyLevel": 100,
495
"maxEnemyLevel": 100,
496
"xpAmounts": [840, 840, 840, 840, 1660]
497
},
498
{
499
"jobType": "/Lotus/Types/Gameplay/Venus/Jobs/Narmer/NarmerVenusCullJobExterminate",
500
"rewards": "/Lotus/Types/Game/MissionDecks/EidolonJobMissionRewards/NarmerTableBRewards",
501
"masteryReq": 0,
502
"minEnemyLevel": 50,
503
"maxEnemyLevel": 70,
504
"xpAmounts": [780, 780, 780, 780, 1540]
505
}
506
]
507
},
508
{
509
"_id": { "$oid": "663a71c80000000000000029" },
510
"Activation": { "$date": { "$numberLong": "1715106248403" } },
511
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
512
"Tag": "ZarimanSyndicate",
513
"Seed": 99562,
514
"Nodes": []
515
},
516
{
517
"_id": { "$oid": "676b8d340000000000000006" },
518
"Activation": { "$date": { "$numberLong": "1735101748215" } },
519
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
520
"Tag": "HexSyndicate",
521
"Seed": 33872,
522
"Nodes": []
523
281
}
524
282
],
525
283
"ActiveMissions": [