33 lines
1.6 KiB
TypeScript
33 lines
1.6 KiB
TypeScript
import { useEffect } from "react";
|
|
import { useDungeonRaceStore } from "../app/dungeonRaceStore";
|
|
import { useDungeonRunStore } from "./dungeonRunStore";
|
|
import { useGameStore } from "./store";
|
|
|
|
/** Keeps match readiness and settlement separate from the local boss and loot lifecycle. */
|
|
export function DungeonRaceBridge() {
|
|
useEffect(() => {
|
|
let reportingRun: string | null = null;
|
|
const interval = window.setInterval(() => {
|
|
const race = useDungeonRaceStore.getState();
|
|
if (!race.inGame || !race.seed || !race.dungeonId) return;
|
|
const game = useGameStore.getState();
|
|
if (game.activeDungeonId !== race.dungeonId) return;
|
|
race.tick();
|
|
const ready = !game.dungeonIntroActive && ["ready", "proxy"].includes(game.assetStatus);
|
|
if (ready && !race.ready && race.status === "preparing") void race.readyUp();
|
|
const started = race.startAt !== null && Date.now() + race.serverOffset >= race.startAt;
|
|
if (game.raceStartBlocked && started && ready) useGameStore.setState({ raceStartBlocked: false });
|
|
if (game.raceStartBlocked && ["void", "idle"].includes(race.status))
|
|
useGameStore.setState({ raceStartBlocked: false });
|
|
const progress = useDungeonRunStore.getState().progress;
|
|
if (started && !["void", "idle"].includes(race.status) && progress?.id === race.seed && progress.finishedAt !== null
|
|
&& race.clearDurationMs === null && reportingRun !== race.seed) {
|
|
reportingRun = race.seed;
|
|
void race.reportClear(progress.killedBossIds).finally(() => { reportingRun = null; });
|
|
}
|
|
}, 100);
|
|
return () => window.clearInterval(interval);
|
|
}, []);
|
|
return null;
|
|
}
|