40 lines
1.7 KiB
TypeScript
40 lines
1.7 KiB
TypeScript
import { useCombatStore, type MobCombatState } from "./combatStore";
|
|
import { activeDungeonCompletedObjectiveIds } from "./dungeonEncounterRuntime";
|
|
import { requireDungeonDefinition } from "./dungeonRegistry";
|
|
import type { DungeonDefinition, WorldSpawn } from "./dungeonTypes";
|
|
import { useGameStore } from "./store";
|
|
|
|
export interface ResurrectionCheckpoint {
|
|
readonly id: string;
|
|
readonly name: string;
|
|
readonly spawn: WorldSpawn;
|
|
}
|
|
|
|
/** Authored boss positions only: never accept a corpse position or arbitrary UI coordinates. */
|
|
export function dungeonResurrectionCheckpoints(
|
|
dungeon: DungeonDefinition,
|
|
mobs: Readonly<Record<string, MobCombatState>>,
|
|
completedObjectiveIds: readonly string[] = [],
|
|
): ResurrectionCheckpoint[] {
|
|
const completed = new Set(completedObjectiveIds);
|
|
return [
|
|
{ id: "entrance", name: "Dungeon entrance", spawn: dungeon.entrance },
|
|
...dungeon.bosses.filter((boss) => completed.has(boss.id)
|
|
|| (mobs[boss.id]?.dead && !mobs[boss.id]?.despawned)).map((boss) => ({
|
|
id: `boss:${boss.id}`, name: boss.name,
|
|
spawn: { footPosition: boss.position, yaw: dungeon.entrance.yaw },
|
|
})),
|
|
];
|
|
}
|
|
|
|
export function availableResurrectionCheckpoints(): ResurrectionCheckpoint[] {
|
|
const game = useGameStore.getState();
|
|
return dungeonResurrectionCheckpoints(requireDungeonDefinition(game.activeDungeonId),
|
|
useCombatStore.getState().mobs, activeDungeonCompletedObjectiveIds(game.activeDungeonId));
|
|
}
|
|
|
|
export function resolveResurrectionCheckpoint(id: string): ResurrectionCheckpoint | null {
|
|
if (useGameStore.getState().gameMode !== "dungeon") return null;
|
|
return availableResurrectionCheckpoints().find((checkpoint) => checkpoint.id === id) ?? null;
|
|
}
|