返回提交历史
Modified
src/services/worldStateService.ts
+69
-0
Modified
src/types/worldStateTypes.ts
+9
-0
Modified
static/fixed_responses/worldState/worldState.json
+0
-44
XFEstudio/XFESpaceNinjaServer
feat: void storm rotation (#2171)
Re #1512 Reviewed-on: https://onlyg.it/OpenWF/SpaceNinjaServer/pulls/2171 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
3e99e069
代码差异
3 个文件
+78
-44
@@ -16,6 +16,7 @@ import {
16
16
ISortie,
17
17
ISortieMission,
18
18
ISyndicateMissionInfo,
19
IVoidStorm,
19
20
IWorldState
20
21
} from "../types/worldStateTypes";
21
22
import { version_compare } from "../helpers/inventoryHelpers";
@@ -963,6 +964,61 @@ const getCalendarSeason = (week: number): ICalendarSeason => {
963
964
};
964
965
};
965
966
967
// Not very faithful, but to avoid the same node coming up back-to-back (which is not valid), I've split these into 2 arrays which we're alternating between.
968
969
const voidStormMissionsA = {
970
VoidT1: ["CrewBattleNode519", "CrewBattleNode518", "CrewBattleNode515", "CrewBattleNode503"],
971
VoidT2: ["CrewBattleNode501", "CrewBattleNode534", "CrewBattleNode530"],
972
VoidT3: ["CrewBattleNode521", "CrewBattleNode516"],
973
VoidT4: [
974
"CrewBattleNode555",
975
"CrewBattleNode553",
976
"CrewBattleNode554",
977
"CrewBattleNode539",
978
"CrewBattleNode531",
979
"CrewBattleNode527"
980
]
981
};
982
983
const voidStormMissionsB = {
984
VoidT1: ["CrewBattleNode509", "CrewBattleNode522", "CrewBattleNode511", "CrewBattleNode512"],
985
VoidT2: ["CrewBattleNode535", "CrewBattleNode533"],
986
VoidT3: ["CrewBattleNode524", "CrewBattleNode525"],
987
VoidT4: [
988
"CrewBattleNode542",
989
"CrewBattleNode538",
990
"CrewBattleNode543",
991
"CrewBattleNode536",
992
"CrewBattleNode550",
993
"CrewBattleNode529"
994
]
995
};
996
997
const pushVoidStorms = (arr: IVoidStorm[], hour: number): void => {
998
const activation = hour * unixTimesInMs.hour + 40 * unixTimesInMs.minute;
999
const expiry = activation + 90 * unixTimesInMs.minute;
1000
let accum = 0;
1001
const rng = new SRng(new SRng(hour).randomInt(0, 100_000));
1002
const voidStormMissions = structuredClone(hour & 1 ? voidStormMissionsA : voidStormMissionsB);
1003
for (const tier of ["VoidT1", "VoidT1", "VoidT2", "VoidT3", "VoidT4", "VoidT4"] as const) {
1004
const idx = rng.randomInt(0, voidStormMissions[tier].length - 1);
1005
const node = voidStormMissions[tier][idx];
1006
voidStormMissions[tier].splice(idx, 1);
1007
arr.push({
1008
_id: {
1009
$oid:
1010
((activation / 1000) & 0xffffffff).toString(16).padStart(8, "0") +
1011
"0321e89b" +
1012
(accum++).toString().padStart(8, "0")
1013
},
1014
Node: node,
1015
Activation: { $date: { $numberLong: activation.toString() } },
1016
Expiry: { $date: { $numberLong: expiry.toString() } },
1017
ActiveMissionTier: tier
1018
});
1019
}
1020
};
1021
966
1022
const doesTimeSatsifyConstraints = (timeSecs: number): boolean => {
967
1023
if (config.worldState?.eidolonOverride) {
968
1024
const eidolonEpoch = 1391992660;
@@ -1032,6 +1088,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1032
1088
Sorties: [],
1033
1089
LiteSorties: [],
1034
1090
GlobalUpgrades: [],
1091
VoidStorms: [],
1035
1092
EndlessXpChoices: [],
1036
1093
KnownCalendarSeasons: [],
1037
1094
...staticWorldState,
@@ -1228,6 +1285,18 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
1228
1285
worldState.KnownCalendarSeasons.push(getCalendarSeason(week + 1));
1229
1286
}
1230
1287
1288
// Void Storms
1289
const hour = Math.trunc(timeMs / unixTimesInMs.hour);
1290
const overLastHourStormExpiry = hour * unixTimesInMs.hour + 10 * unixTimesInMs.minute;
1291
const thisHourStormActivation = hour * unixTimesInMs.hour + 40 * unixTimesInMs.minute;
1292
if (overLastHourStormExpiry > timeMs) {
1293
pushVoidStorms(worldState.VoidStorms, hour - 2);
1294
}
1295
pushVoidStorms(worldState.VoidStorms, hour - 1);
1296
if (isBeforeNextExpectedWorldStateRefresh(timeMs, thisHourStormActivation)) {
1297
pushVoidStorms(worldState.VoidStorms, hour);
1298
}
1299
1231
1300
// Sentient Anomaly cycling every 30 minutes
1232
1301
const halfHour = Math.trunc(timeMs / (unixTimesInMs.hour / 2));
1233
1302
const tmp = {
@@ -12,6 +12,7 @@ export interface IWorldState {
12
12
GlobalUpgrades: IGlobalUpgrade[];
13
13
ActiveMissions: IFissure[];
14
14
NodeOverrides: INodeOverride[];
15
VoidStorms: IVoidStorm[];
15
16
PVPChallengeInstances: IPVPChallengeInstance[];
16
17
EndlessXpChoices: IEndlessXpChoice[];
17
18
SeasonInfo?: {
@@ -131,6 +132,14 @@ export interface ILiteSortie {
131
132
}[];
132
133
}
133
134
135
export interface IVoidStorm {
136
_id: IOid;
137
Node: string;
138
Activation: IMongoDate;
139
Expiry: IMongoDate;
140
ActiveMissionTier: string;
141
}
142
134
143
export interface IPVPChallengeInstance {
135
144
_id: IOid;
136
145
challengeTypeRefID: string;
@@ -2562,50 +2562,6 @@
2562
2562
]
2563
2563
}
2564
2564
],
2565
"VoidStorms": [
2566
{
2567
"_id": { "$oid": "663a7581ced28e18f694b550" },
2568
"Node": "CrewBattleNode519",
2569
"Activation": { "$date": { "$numberLong": "1715109601821" } },
2570
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
2571
"ActiveMissionTier": "VoidT1"
2572
},
2573
{
2574
"_id": { "$oid": "663a7581ced28e18f694b551" },
2575
"Node": "CrewBattleNode515",
2576
"Activation": { "$date": { "$numberLong": "1715109601825" } },
2577
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
2578
"ActiveMissionTier": "VoidT1"
2579
},
2580
{
2581
"_id": { "$oid": "663a7581ced28e18f694b554" },
2582
"Node": "CrewBattleNode536",
2583
"Activation": { "$date": { "$numberLong": "1715109601832" } },
2584
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
2585
"ActiveMissionTier": "VoidT4"
2586
},
2587
{
2588
"_id": { "$oid": "663a7581ced28e18f694b555" },
2589
"Node": "CrewBattleNode539",
2590
"Activation": { "$date": { "$numberLong": "1715109601834" } },
2591
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
2592
"ActiveMissionTier": "VoidT4"
2593
},
2594
{
2595
"_id": { "$oid": "663a7581ced28e18f694b553" },
2596
"Node": "CrewBattleNode521",
2597
"Activation": { "$date": { "$numberLong": "1715109601829" } },
2598
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
2599
"ActiveMissionTier": "VoidT3"
2600
},
2601
{
2602
"_id": { "$oid": "663a7581ced28e18f694b552" },
2603
"Node": "CrewBattleNode535",
2604
"Activation": { "$date": { "$numberLong": "1715109601827" } },
2605
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
2606
"ActiveMissionTier": "VoidT2"
2607
}
2608
],
2609
2565
"PrimeAccessAvailability": { "State": "PRIME1" },
2610
2566
"PrimeVaultAvailabilities": [false, false, false, false, false],
2611
2567
"PrimeTokenAvailability": true,