feat: void storm rotation (#2171)
Re #1512 Reviewed-on: #2171 Co-authored-by: Sainan <63328889+Sainan@users.noreply.github.com> Co-committed-by: Sainan <63328889+Sainan@users.noreply.github.com>
This commit is contained in:
parent
9731004de6
commit
3e99e069be
@ -16,6 +16,7 @@ import {
|
|||||||
ISortie,
|
ISortie,
|
||||||
ISortieMission,
|
ISortieMission,
|
||||||
ISyndicateMissionInfo,
|
ISyndicateMissionInfo,
|
||||||
|
IVoidStorm,
|
||||||
IWorldState
|
IWorldState
|
||||||
} from "../types/worldStateTypes";
|
} from "../types/worldStateTypes";
|
||||||
import { version_compare } from "../helpers/inventoryHelpers";
|
import { version_compare } from "../helpers/inventoryHelpers";
|
||||||
@ -963,6 +964,61 @@ const getCalendarSeason = (week: number): ICalendarSeason => {
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 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.
|
||||||
|
|
||||||
|
const voidStormMissionsA = {
|
||||||
|
VoidT1: ["CrewBattleNode519", "CrewBattleNode518", "CrewBattleNode515", "CrewBattleNode503"],
|
||||||
|
VoidT2: ["CrewBattleNode501", "CrewBattleNode534", "CrewBattleNode530"],
|
||||||
|
VoidT3: ["CrewBattleNode521", "CrewBattleNode516"],
|
||||||
|
VoidT4: [
|
||||||
|
"CrewBattleNode555",
|
||||||
|
"CrewBattleNode553",
|
||||||
|
"CrewBattleNode554",
|
||||||
|
"CrewBattleNode539",
|
||||||
|
"CrewBattleNode531",
|
||||||
|
"CrewBattleNode527"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const voidStormMissionsB = {
|
||||||
|
VoidT1: ["CrewBattleNode509", "CrewBattleNode522", "CrewBattleNode511", "CrewBattleNode512"],
|
||||||
|
VoidT2: ["CrewBattleNode535", "CrewBattleNode533"],
|
||||||
|
VoidT3: ["CrewBattleNode524", "CrewBattleNode525"],
|
||||||
|
VoidT4: [
|
||||||
|
"CrewBattleNode542",
|
||||||
|
"CrewBattleNode538",
|
||||||
|
"CrewBattleNode543",
|
||||||
|
"CrewBattleNode536",
|
||||||
|
"CrewBattleNode550",
|
||||||
|
"CrewBattleNode529"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
const pushVoidStorms = (arr: IVoidStorm[], hour: number): void => {
|
||||||
|
const activation = hour * unixTimesInMs.hour + 40 * unixTimesInMs.minute;
|
||||||
|
const expiry = activation + 90 * unixTimesInMs.minute;
|
||||||
|
let accum = 0;
|
||||||
|
const rng = new SRng(new SRng(hour).randomInt(0, 100_000));
|
||||||
|
const voidStormMissions = structuredClone(hour & 1 ? voidStormMissionsA : voidStormMissionsB);
|
||||||
|
for (const tier of ["VoidT1", "VoidT1", "VoidT2", "VoidT3", "VoidT4", "VoidT4"] as const) {
|
||||||
|
const idx = rng.randomInt(0, voidStormMissions[tier].length - 1);
|
||||||
|
const node = voidStormMissions[tier][idx];
|
||||||
|
voidStormMissions[tier].splice(idx, 1);
|
||||||
|
arr.push({
|
||||||
|
_id: {
|
||||||
|
$oid:
|
||||||
|
((activation / 1000) & 0xffffffff).toString(16).padStart(8, "0") +
|
||||||
|
"0321e89b" +
|
||||||
|
(accum++).toString().padStart(8, "0")
|
||||||
|
},
|
||||||
|
Node: node,
|
||||||
|
Activation: { $date: { $numberLong: activation.toString() } },
|
||||||
|
Expiry: { $date: { $numberLong: expiry.toString() } },
|
||||||
|
ActiveMissionTier: tier
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
const doesTimeSatsifyConstraints = (timeSecs: number): boolean => {
|
const doesTimeSatsifyConstraints = (timeSecs: number): boolean => {
|
||||||
if (config.worldState?.eidolonOverride) {
|
if (config.worldState?.eidolonOverride) {
|
||||||
const eidolonEpoch = 1391992660;
|
const eidolonEpoch = 1391992660;
|
||||||
@ -1032,6 +1088,7 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
Sorties: [],
|
Sorties: [],
|
||||||
LiteSorties: [],
|
LiteSorties: [],
|
||||||
GlobalUpgrades: [],
|
GlobalUpgrades: [],
|
||||||
|
VoidStorms: [],
|
||||||
EndlessXpChoices: [],
|
EndlessXpChoices: [],
|
||||||
KnownCalendarSeasons: [],
|
KnownCalendarSeasons: [],
|
||||||
...staticWorldState,
|
...staticWorldState,
|
||||||
@ -1228,6 +1285,18 @@ export const getWorldState = (buildLabel?: string): IWorldState => {
|
|||||||
worldState.KnownCalendarSeasons.push(getCalendarSeason(week + 1));
|
worldState.KnownCalendarSeasons.push(getCalendarSeason(week + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Void Storms
|
||||||
|
const hour = Math.trunc(timeMs / unixTimesInMs.hour);
|
||||||
|
const overLastHourStormExpiry = hour * unixTimesInMs.hour + 10 * unixTimesInMs.minute;
|
||||||
|
const thisHourStormActivation = hour * unixTimesInMs.hour + 40 * unixTimesInMs.minute;
|
||||||
|
if (overLastHourStormExpiry > timeMs) {
|
||||||
|
pushVoidStorms(worldState.VoidStorms, hour - 2);
|
||||||
|
}
|
||||||
|
pushVoidStorms(worldState.VoidStorms, hour - 1);
|
||||||
|
if (isBeforeNextExpectedWorldStateRefresh(timeMs, thisHourStormActivation)) {
|
||||||
|
pushVoidStorms(worldState.VoidStorms, hour);
|
||||||
|
}
|
||||||
|
|
||||||
// Sentient Anomaly cycling every 30 minutes
|
// Sentient Anomaly cycling every 30 minutes
|
||||||
const halfHour = Math.trunc(timeMs / (unixTimesInMs.hour / 2));
|
const halfHour = Math.trunc(timeMs / (unixTimesInMs.hour / 2));
|
||||||
const tmp = {
|
const tmp = {
|
||||||
|
@ -12,6 +12,7 @@ export interface IWorldState {
|
|||||||
GlobalUpgrades: IGlobalUpgrade[];
|
GlobalUpgrades: IGlobalUpgrade[];
|
||||||
ActiveMissions: IFissure[];
|
ActiveMissions: IFissure[];
|
||||||
NodeOverrides: INodeOverride[];
|
NodeOverrides: INodeOverride[];
|
||||||
|
VoidStorms: IVoidStorm[];
|
||||||
PVPChallengeInstances: IPVPChallengeInstance[];
|
PVPChallengeInstances: IPVPChallengeInstance[];
|
||||||
EndlessXpChoices: IEndlessXpChoice[];
|
EndlessXpChoices: IEndlessXpChoice[];
|
||||||
SeasonInfo?: {
|
SeasonInfo?: {
|
||||||
@ -131,6 +132,14 @@ export interface ILiteSortie {
|
|||||||
}[];
|
}[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IVoidStorm {
|
||||||
|
_id: IOid;
|
||||||
|
Node: string;
|
||||||
|
Activation: IMongoDate;
|
||||||
|
Expiry: IMongoDate;
|
||||||
|
ActiveMissionTier: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IPVPChallengeInstance {
|
export interface IPVPChallengeInstance {
|
||||||
_id: IOid;
|
_id: IOid;
|
||||||
challengeTypeRefID: string;
|
challengeTypeRefID: string;
|
||||||
|
@ -2562,50 +2562,6 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"VoidStorms": [
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7581ced28e18f694b550" },
|
|
||||||
"Node": "CrewBattleNode519",
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715109601821" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"ActiveMissionTier": "VoidT1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7581ced28e18f694b551" },
|
|
||||||
"Node": "CrewBattleNode515",
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715109601825" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"ActiveMissionTier": "VoidT1"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7581ced28e18f694b554" },
|
|
||||||
"Node": "CrewBattleNode536",
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715109601832" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"ActiveMissionTier": "VoidT4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7581ced28e18f694b555" },
|
|
||||||
"Node": "CrewBattleNode539",
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715109601834" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"ActiveMissionTier": "VoidT4"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7581ced28e18f694b553" },
|
|
||||||
"Node": "CrewBattleNode521",
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715109601829" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"ActiveMissionTier": "VoidT3"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"_id": { "$oid": "663a7581ced28e18f694b552" },
|
|
||||||
"Node": "CrewBattleNode535",
|
|
||||||
"Activation": { "$date": { "$numberLong": "1715109601827" } },
|
|
||||||
"Expiry": { "$date": { "$numberLong": "2000000000000" } },
|
|
||||||
"ActiveMissionTier": "VoidT2"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"PrimeAccessAvailability": { "State": "PRIME1" },
|
"PrimeAccessAvailability": { "State": "PRIME1" },
|
||||||
"PrimeVaultAvailabilities": [false, false, false, false, false],
|
"PrimeVaultAvailabilities": [false, false, false, false, false],
|
||||||
"PrimeTokenAvailability": true,
|
"PrimeTokenAvailability": true,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user