chore: use ideal time when going backwards to satisfy constraints #2438
@ -1033,75 +1033,124 @@ const pushVoidStorms = (arr: IVoidStorm[], hour: number): void => {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const doesTimeSatsifyConstraints = (timeSecs: number): boolean => {
 | 
					interface ITimeConstraint {
 | 
				
			||||||
    if (config.worldState?.eidolonOverride) {
 | 
					    //name: string;
 | 
				
			||||||
 | 
					    isValidTime: (timeSecs: number) => boolean;
 | 
				
			||||||
 | 
					    getIdealTimeBefore: (timeSecs: number) => number;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const eidolonDayConstraint: ITimeConstraint = {
 | 
				
			||||||
 | 
					    //name: "eidolon day",
 | 
				
			||||||
 | 
					    isValidTime: (timeSecs: number): boolean => {
 | 
				
			||||||
        const eidolonEpoch = 1391992660;
 | 
					        const eidolonEpoch = 1391992660;
 | 
				
			||||||
        const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
 | 
					        const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
 | 
				
			||||||
        const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
 | 
					        const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
 | 
				
			||||||
        const eidolonCycleEnd = eidolonCycleStart + 9000;
 | 
					        const eidolonCycleEnd = eidolonCycleStart + 9000;
 | 
				
			||||||
        const eidolonCycleNightStart = eidolonCycleEnd - 3000;
 | 
					        const eidolonCycleNightStart = eidolonCycleEnd - 3000;
 | 
				
			||||||
        if (config.worldState.eidolonOverride == "day") {
 | 
					        return !isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleNightStart * 1000);
 | 
				
			||||||
            if (
 | 
					    },
 | 
				
			||||||
                //timeSecs < eidolonCycleStart ||
 | 
					    getIdealTimeBefore: (timeSecs: number): number => {
 | 
				
			||||||
                isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleNightStart * 1000)
 | 
					        const eidolonEpoch = 1391992660;
 | 
				
			||||||
            ) {
 | 
					        const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
 | 
				
			||||||
                return false;
 | 
					        const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
 | 
				
			||||||
            }
 | 
					        return eidolonCycleStart;
 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            if (
 | 
					 | 
				
			||||||
                timeSecs < eidolonCycleNightStart ||
 | 
					 | 
				
			||||||
                isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleEnd * 1000)
 | 
					 | 
				
			||||||
            ) {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (config.worldState?.vallisOverride) {
 | 
					const eidolonNightConstraint: ITimeConstraint = {
 | 
				
			||||||
 | 
					    //name: "eidolon night",
 | 
				
			||||||
 | 
					    isValidTime: (timeSecs: number): boolean => {
 | 
				
			||||||
 | 
					        const eidolonEpoch = 1391992660;
 | 
				
			||||||
 | 
					        const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
 | 
				
			||||||
 | 
					        const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
 | 
				
			||||||
 | 
					        const eidolonCycleEnd = eidolonCycleStart + 9000;
 | 
				
			||||||
 | 
					        const eidolonCycleNightStart = eidolonCycleEnd - 3000;
 | 
				
			||||||
 | 
					        return (
 | 
				
			||||||
 | 
					            timeSecs >= eidolonCycleNightStart &&
 | 
				
			||||||
 | 
					            !isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, eidolonCycleEnd * 1000)
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getIdealTimeBefore: (timeSecs: number): number => {
 | 
				
			||||||
 | 
					        const eidolonEpoch = 1391992660;
 | 
				
			||||||
 | 
					        const eidolonCycle = Math.trunc((timeSecs - eidolonEpoch) / 9000);
 | 
				
			||||||
 | 
					        const eidolonCycleStart = eidolonEpoch + eidolonCycle * 9000;
 | 
				
			||||||
 | 
					        const eidolonCycleEnd = eidolonCycleStart + 9000;
 | 
				
			||||||
 | 
					        const eidolonCycleNightStart = eidolonCycleEnd - 3000;
 | 
				
			||||||
 | 
					        if (eidolonCycleNightStart > timeSecs) {
 | 
				
			||||||
 | 
					            // Night hasn't started yet, but we need to return a time in the past.
 | 
				
			||||||
 | 
					            return eidolonCycleNightStart - 9000;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return eidolonCycleNightStart;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const venusColdConstraint: ITimeConstraint = {
 | 
				
			||||||
 | 
					    //name: "venus cold",
 | 
				
			||||||
 | 
					    isValidTime: (timeSecs: number): boolean => {
 | 
				
			||||||
        const vallisEpoch = 1541837628;
 | 
					        const vallisEpoch = 1541837628;
 | 
				
			||||||
        const vallisCycle = Math.trunc((timeSecs - vallisEpoch) / 1600);
 | 
					        const vallisCycle = Math.trunc((timeSecs - vallisEpoch) / 1600);
 | 
				
			||||||
        const vallisCycleStart = vallisEpoch + vallisCycle * 1600;
 | 
					        const vallisCycleStart = vallisEpoch + vallisCycle * 1600;
 | 
				
			||||||
        const vallisCycleEnd = vallisCycleStart + 1600;
 | 
					        const vallisCycleEnd = vallisCycleStart + 1600;
 | 
				
			||||||
        const vallisCycleColdStart = vallisCycleStart + 400;
 | 
					        const vallisCycleColdStart = vallisCycleStart + 400;
 | 
				
			||||||
        if (config.worldState.vallisOverride == "cold") {
 | 
					        return (
 | 
				
			||||||
            if (
 | 
					            timeSecs >= vallisCycleColdStart &&
 | 
				
			||||||
                timeSecs < vallisCycleColdStart ||
 | 
					            !isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, vallisCycleEnd * 1000)
 | 
				
			||||||
                isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, vallisCycleEnd * 1000)
 | 
					        );
 | 
				
			||||||
            ) {
 | 
					    },
 | 
				
			||||||
                return false;
 | 
					    getIdealTimeBefore: (timeSecs: number): number => {
 | 
				
			||||||
            }
 | 
					        const vallisEpoch = 1541837628;
 | 
				
			||||||
        } else {
 | 
					        const vallisCycle = Math.trunc((timeSecs - vallisEpoch) / 1600);
 | 
				
			||||||
            if (
 | 
					        const vallisCycleStart = vallisEpoch + vallisCycle * 1600;
 | 
				
			||||||
                //timeSecs < vallisCycleStart ||
 | 
					        const vallisCycleColdStart = vallisCycleStart + 400;
 | 
				
			||||||
                isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, vallisCycleColdStart * 1000)
 | 
					        if (vallisCycleColdStart > timeSecs) {
 | 
				
			||||||
            ) {
 | 
					            // Cold hasn't started yet, but we need to return a time in the past.
 | 
				
			||||||
                return false;
 | 
					            return vallisCycleColdStart - 1600;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return vallisCycleColdStart;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const venusWarmConstraint: ITimeConstraint = {
 | 
				
			||||||
 | 
					    //name: "venus warm",
 | 
				
			||||||
 | 
					    isValidTime: (timeSecs: number): boolean => {
 | 
				
			||||||
 | 
					        const vallisEpoch = 1541837628;
 | 
				
			||||||
 | 
					        const vallisCycle = Math.trunc((timeSecs - vallisEpoch) / 1600);
 | 
				
			||||||
 | 
					        const vallisCycleStart = vallisEpoch + vallisCycle * 1600;
 | 
				
			||||||
 | 
					        const vallisCycleColdStart = vallisCycleStart + 400;
 | 
				
			||||||
 | 
					        return !isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, vallisCycleColdStart * 1000);
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    getIdealTimeBefore: (timeSecs: number): number => {
 | 
				
			||||||
 | 
					        const vallisEpoch = 1541837628;
 | 
				
			||||||
 | 
					        const vallisCycle = Math.trunc((timeSecs - vallisEpoch) / 1600);
 | 
				
			||||||
 | 
					        const vallisCycleStart = vallisEpoch + vallisCycle * 1600;
 | 
				
			||||||
 | 
					        return vallisCycleStart;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const getIdealTimeSatsifyingConstraints = (constraints: ITimeConstraint[]): number => {
 | 
				
			||||||
 | 
					    let timeSecs = Math.trunc(Date.now() / 1000);
 | 
				
			||||||
 | 
					    let allGood;
 | 
				
			||||||
 | 
					    do {
 | 
				
			||||||
 | 
					        allGood = true;
 | 
				
			||||||
 | 
					        for (const constraint of constraints) {
 | 
				
			||||||
 | 
					            if (!constraint.isValidTime(timeSecs)) {
 | 
				
			||||||
 | 
					                //logger.debug(`${constraint.name} is not happy with ${timeSecs}`);
 | 
				
			||||||
 | 
					                const prevTimeSecs = timeSecs;
 | 
				
			||||||
 | 
					                const suggestion = constraint.getIdealTimeBefore(timeSecs);
 | 
				
			||||||
 | 
					                timeSecs = suggestion;
 | 
				
			||||||
 | 
					                do {
 | 
				
			||||||
 | 
					                    timeSecs += 60;
 | 
				
			||||||
 | 
					                    if (timeSecs >= prevTimeSecs || !constraint.isValidTime(timeSecs)) {
 | 
				
			||||||
 | 
					                        timeSecs = suggestion; // Can't find a compromise; just take the suggestion and try to compromise on another constraint.
 | 
				
			||||||
 | 
					                        break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                } while (!constraints.every(constraint => constraint.isValidTime(timeSecs)));
 | 
				
			||||||
 | 
					                allGood = false;
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    } while (!allGood);
 | 
				
			||||||
 | 
					    return timeSecs;
 | 
				
			||||||
    if (config.worldState?.duviriOverride) {
 | 
					 | 
				
			||||||
        const duviriMoods = ["sorrow", "fear", "joy", "anger", "envy"];
 | 
					 | 
				
			||||||
        const desiredMood = duviriMoods.indexOf(config.worldState.duviriOverride);
 | 
					 | 
				
			||||||
        if (desiredMood == -1) {
 | 
					 | 
				
			||||||
            logger.warn(`ignoring invalid config value for worldState.duviriOverride`, {
 | 
					 | 
				
			||||||
                value: config.worldState.duviriOverride,
 | 
					 | 
				
			||||||
                valid_values: duviriMoods
 | 
					 | 
				
			||||||
            });
 | 
					 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            const moodIndex = Math.trunc(timeSecs / 7200);
 | 
					 | 
				
			||||||
            const moodStart = moodIndex * 7200;
 | 
					 | 
				
			||||||
            const moodEnd = moodStart + 7200;
 | 
					 | 
				
			||||||
            if (
 | 
					 | 
				
			||||||
                moodIndex % 5 != desiredMood ||
 | 
					 | 
				
			||||||
                isBeforeNextExpectedWorldStateRefresh(timeSecs * 1000, moodEnd * 1000)
 | 
					 | 
				
			||||||
            ) {
 | 
					 | 
				
			||||||
                return false;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const getVarziaRotation = (week: number): string => {
 | 
					const getVarziaRotation = (week: number): string => {
 | 
				
			||||||
@ -1179,10 +1228,38 @@ const getAllVarziaManifests = (): IPrimeVaultTraderOffer[] => {
 | 
				
			|||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
					export const getWorldState = (buildLabel?: string): IWorldState => {
 | 
				
			||||||
    let timeSecs = Math.round(Date.now() / 1000);
 | 
					    const constraints: ITimeConstraint[] = [];
 | 
				
			||||||
    while (!doesTimeSatsifyConstraints(timeSecs)) {
 | 
					    if (config.worldState?.eidolonOverride) {
 | 
				
			||||||
        timeSecs -= 60;
 | 
					        constraints.push(config.worldState.eidolonOverride == "day" ? eidolonDayConstraint : eidolonNightConstraint);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    if (config.worldState?.vallisOverride) {
 | 
				
			||||||
 | 
					        constraints.push(config.worldState.vallisOverride == "cold" ? venusColdConstraint : venusWarmConstraint);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (config.worldState?.duviriOverride) {
 | 
				
			||||||
 | 
					        const duviriMoods = ["sorrow", "fear", "joy", "anger", "envy"];
 | 
				
			||||||
 | 
					        const desiredMood = duviriMoods.indexOf(config.worldState.duviriOverride);
 | 
				
			||||||
 | 
					        if (desiredMood == -1) {
 | 
				
			||||||
 | 
					            logger.warn(`ignoring invalid config value for worldState.duviriOverride`, {
 | 
				
			||||||
 | 
					                value: config.worldState.duviriOverride,
 | 
				
			||||||
 | 
					                valid_values: duviriMoods
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            constraints.push({
 | 
				
			||||||
 | 
					                //name: `duviri ${config.worldState.duviriOverride}`,
 | 
				
			||||||
 | 
					                isValidTime: (timeSecs: number): boolean => {
 | 
				
			||||||
 | 
					                    const moodIndex = Math.trunc(timeSecs / 7200);
 | 
				
			||||||
 | 
					                    return moodIndex % 5 == desiredMood;
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                getIdealTimeBefore: (timeSecs: number): number => {
 | 
				
			||||||
 | 
					                    let moodIndex = Math.trunc(timeSecs / 7200);
 | 
				
			||||||
 | 
					                    moodIndex -= ((moodIndex % 5) - desiredMood + 5) % 5; // while (moodIndex % 5 != desiredMood) --moodIndex;
 | 
				
			||||||
 | 
					                    const moodStart = moodIndex * 7200;
 | 
				
			||||||
 | 
					                    return moodStart;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const timeSecs = getIdealTimeSatsifyingConstraints(constraints);
 | 
				
			||||||
    const timeMs = timeSecs * 1000;
 | 
					    const timeMs = timeSecs * 1000;
 | 
				
			||||||
    const day = Math.trunc((timeMs - EPOCH) / 86400000);
 | 
					    const day = Math.trunc((timeMs - EPOCH) / 86400000);
 | 
				
			||||||
    const week = Math.trunc(day / 7);
 | 
					    const week = Math.trunc(day / 7);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user