forked from phenom/healer-man
Release Healer Man 0.1.39
This commit is contained in:
1 parent
b417b7c3c3
commit
ed0d2fea3d
51 files changed
+17811
-49
No files matched your search
@@ -0,0 +1,66 @@
|
||||
import { useEffect } from "react";
|
||||
import { useShellStore } from "../app/shellStore";
|
||||
import { useOnlineSessionStore } from "../app/onlineSessionStore";
|
||||
import { useOnlineGroupStore } from "../app/onlineGroupStore";
|
||||
import { activeDungeonCompletedObjectiveIds, subscribeDungeonEncounterSnapshots } from "./dungeonEncounterRuntime";
|
||||
import { useCombatStore } from "./combatStore";
|
||||
import { usePartyStore } from "./partyStore";
|
||||
import { useGameStore } from "./store";
|
||||
import { useDungeonRunStore } from "./dungeonRunStore";
|
||||
import type { DungeonRunMember } from "./dungeonRunTypes";
|
||||
|
||||
function currentRunParty(): readonly DungeonRunMember[] {
|
||||
const shell = useShellStore.getState();
|
||||
const character = shell.activeCharacter;
|
||||
if (!character) return [];
|
||||
const members: DungeonRunMember[] = [{ name: character.name, classId: character.classId,
|
||||
level: useCombatStore.getState().level, role: shell.activeDungeonRole, npc: false,
|
||||
...(character.secondaryClassId ? { secondaryClassId: character.secondaryClassId } : {}) }];
|
||||
const online = useOnlineSessionStore.getState().snapshot;
|
||||
for (const player of online?.players ?? []) {
|
||||
if (player.accountId === shell.session?.ownerId || !player.character) continue;
|
||||
members.push({ name: player.character.name, classId: player.character.classId,
|
||||
level: player.character.level, role: player.role ?? "damage", npc: false });
|
||||
}
|
||||
for (const member of usePartyStore.getState().members) {
|
||||
members.push({ name: member.name, classId: member.classId, level: member.level, role: member.role, npc: true });
|
||||
}
|
||||
return members.slice(0, 5);
|
||||
}
|
||||
|
||||
/** Wall-clock run timing survives wipes, pauses, checkpoints, and renderer retries. */
|
||||
export function DungeonRunBridge() {
|
||||
useEffect(() => {
|
||||
let announcedId: string | null = null;
|
||||
const advance = () => {
|
||||
const game = useGameStore.getState();
|
||||
const shell = useShellStore.getState();
|
||||
if (shell.phase !== "game" || game.gameMode !== "dungeon" || game.gmTestMode
|
||||
|| !["ready", "proxy"].includes(game.assetStatus)) return;
|
||||
const run = useDungeonRunStore.getState();
|
||||
if (run.progress?.dungeonId !== game.activeDungeonId) return;
|
||||
const party = currentRunParty();
|
||||
const activity = useOnlineGroupStore.getState().activeActivity;
|
||||
if (activity?.type === "dungeon" && activity.contentId === game.activeDungeonId
|
||||
&& run.progress.finishedAt === null && run.progress.id !== activity.id) {
|
||||
useDungeonRunStore.setState({ progress: { ...run.progress, id: activity.id,
|
||||
startedAt: activity.startedAt, party } });
|
||||
}
|
||||
run.start(Date.now(), party);
|
||||
run.advance(activeDungeonCompletedObjectiveIds(game.activeDungeonId),
|
||||
Object.values(useCombatStore.getState().mobs).filter((mob) => mob.dead && !mob.despawned).map((mob) => mob.id),
|
||||
Date.now(), party);
|
||||
const progress = useDungeonRunStore.getState().progress;
|
||||
if (progress?.finishedAt !== null && progress && announcedId !== progress.id) {
|
||||
announcedId = progress.id;
|
||||
useGameStore.getState().openOverlay("dungeon-results");
|
||||
}
|
||||
};
|
||||
const unsubscribeEncounters = subscribeDungeonEncounterSnapshots(advance);
|
||||
const unsubscribeGame = useGameStore.subscribe(advance);
|
||||
const interval = setInterval(advance, 250);
|
||||
advance();
|
||||
return () => { unsubscribeEncounters(); unsubscribeGame(); clearInterval(interval); };
|
||||
}, []);
|
||||
return null;
|
||||
}
|
||||
Reference in new issue
Block a user