import { beforeEach, describe, expect, it } from "vitest"; import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry"; import { resolvedAbilityCosts, useCombatStore } from "./combatStore"; import { abilitiesForClass, abilityAtLevel } from "./abilityCatalog"; import { respawnDefeatedPlayer } from "./deathRespawn"; import { useGameStore } from "./store"; import { useWailingEncounterStore } from "./wailingCavernsEncounter"; describe("death respawn", () => { beforeEach(() => { clearMobRuntimeRegistry(); useCombatStore.getState().initializeCharacter({ classId: "priest", level: 14, xp: 0 }); useGameStore.getState().resetAtEntrance(); useWailingEncounterStore.getState().reset(); }); it("resets only the current pull and preserves cleared enemies and run progress", () => { const startingResource = useCombatStore.getState().maxResource; const checkpointSpawn = { footPosition: [4, -70, 12] as const, yaw: 0.25 }; useGameStore.getState().relocatePlayer(checkpointSpawn, true); useGameStore.getState().updatePlayerSnapshot({ position: [10, -50, 20], yaw: 0.5, distanceDelta: 30 }); useGameStore.getState().setCameraLookActive(true); useCombatStore.getState().registerMob("respawn-pack:a", { name: "Ravager", maxHealth: 100 }); useCombatStore.getState().registerMob("cleared-boss", { name: "Cleared Boss", maxHealth: 50, boss: true }); useCombatStore.getState().registerMob("naralex-event:ravager:1", { name: "Event Ravager", maxHealth: 75, }); setMobPosition("respawn-pack:a", [11, -50, 20]); useCombatStore.getState().damageMob("cleared-boss", 50, 900); useCombatStore.getState().damageMob("naralex-event:ravager:1", 75, 950); useCombatStore.getState().selectMob("respawn-pack:a"); useCombatStore.getState().damageMob("respawn-pack:a", 1, 1000); const psychicScream = abilityAtLevel( abilitiesForClass("priest").find((ability) => ability.id === "priest-psychic-scream")!, 14, ); const psychicScreamCost = resolvedAbilityCosts( psychicScream, useCombatStore.getState().talentModifiers, useCombatStore.getState(), )[0].amount; expect(useCombatStore.getState().castAbility("priest-psychic-scream", [10, -50, 20], 2000).ok).toBe(true); expect(useCombatStore.getState().resource).toBe(startingResource - psychicScreamCost); const revisionBefore = useGameStore.getState().resetRevision; useWailingEncounterStore.setState({ phase: "mutanus", phaseStartedAt: 5_000, flags: { "dungeon-complete": true }, completedObjectiveIds: ["mutanus-spawn"], consumedActionIds: [ "complete-mutanus-objective", "save-mutanus-checkpoint", "mark-wailing-complete", ], checkpointId: "mutanus-spawn", }); useCombatStore.getState().damagePlayer(useCombatStore.getState().maxHealth); expect(useCombatStore.getState().health).toBe(0); expect(respawnDefeatedPlayer()).toBe(true); expect(useGameStore.getState()).toMatchObject({ playerPosition: checkpointSpawn.footPosition, cameraYaw: checkpointSpawn.yaw, cameraLookActive: false, resetRevision: revisionBefore + 1, }); expect(useCombatStore.getState()).toMatchObject({ health: useCombatStore.getState().maxHealth, resource: startingResource, selectedTargetId: null, playerPosition: checkpointSpawn.footPosition, }); expect(useCombatStore.getState().mobs["respawn-pack:a"]).toMatchObject({ health: 100, dead: false, engaged: false, }); expect(useCombatStore.getState().mobs["cleared-boss"]).toMatchObject({ health: 0, dead: true, engaged: false, }); expect(useCombatStore.getState().mobs["naralex-event:ravager:1"]).toMatchObject({ health: 75, dead: false, engaged: false, }); expect(useWailingEncounterStore.getState()).toMatchObject({ phase: "locked", phaseStartedAt: 0, flags: { "dungeon-complete": true }, completedObjectiveIds: ["mutanus-spawn"], checkpointId: "mutanus-spawn", }); expect(respawnDefeatedPlayer()).toBe(false); expect(useGameStore.getState().resetRevision).toBe(revisionBefore + 1); }); });