Release Healer Man 0.1.37

This commit is contained in:
phenom committed 2026-09-12 21:14:41 -04:00
1 parent 03a4e3f51c
commit 361734bc41
41 files changed
+1714 -110

No files matched your search

+78
View File
@@ -0,0 +1,78 @@
import { beforeEach, describe, expect, it } from "vitest";
import { useCombatStore } from "./combatStore";
import { activateDungeonEncounterDefinitions, activeDungeonCompletedObjectiveIds, advanceDungeonEncounters, dispatchActiveDungeonEntityEvent, resetDungeonEncounters } from "./dungeonEncounterRuntime";
import { requireDungeonDefinition } from "./dungeonRegistry";
import { respawnDefeatedPlayer } from "./deathRespawn";
import { availableResurrectionCheckpoints, dungeonResurrectionCheckpoints } from "./resurrectionCheckpoints";
import { useGameStore } from "./store";
const dungeon = requireDungeonDefinition("stormwind-stockade");
describe("boss resurrection checkpoints", () => {
beforeEach(() => {
useGameStore.getState().activateDungeon("stormwind-stockade");
activateDungeonEncounterDefinitions(dungeon.id, dungeon.encounters ?? []);
resetDungeonEncounters("dungeon", dungeon.id);
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 16 });
useCombatStore.setState({ mobs: {} });
});
it("always offers the entrance and unlocks every killed boss, including optional bosses", () => {
expect(dungeonResurrectionCheckpoints(dungeon, {})).toHaveLength(1);
const result = dungeonResurrectionCheckpoints(dungeon, {}, dungeon.bosses.map((boss) => boss.id));
expect(result.map((checkpoint) => checkpoint.id)).toEqual(["entrance", ...dungeon.bosses.map((boss) => `boss:${boss.id}`)]);
dungeon.bosses.forEach((boss, index) => expect(result[index + 1].spawn.footPosition).toEqual(boss.position));
});
it("uses durable encounter completion after hydration when no corpse is registered", () => {
const boss = dungeon.bosses[0];
dispatchActiveDungeonEntityEvent({ kind: "entity-death", entityId: boss.id, now: 100 });
advanceDungeonEncounters(dungeon.id, { kind: "tick", now: 100, facts: { deadEntityIds: [boss.id], registeredEntityIds: [boss.id] } });
expect(activeDungeonCompletedObjectiveIds(dungeon.id)).toContain(boss.id);
expect(availableResurrectionCheckpoints().map((checkpoint) => checkpoint.id)).toContain(`boss:${boss.id}`);
resetDungeonEncounters("boss-wipe", dungeon.id);
expect(availableResurrectionCheckpoints().map((checkpoint) => checkpoint.id)).toContain(`boss:${boss.id}`);
resetDungeonEncounters("dungeon", dungeon.id);
expect(availableResurrectionCheckpoints()).toHaveLength(1);
});
it("does not award a checkpoint for an alive or script-despawned boss", () => {
const boss = dungeon.bosses[0];
useCombatStore.getState().registerMob(boss.id, { name: boss.name, maxHealth: 100, boss: true });
expect(availableResurrectionCheckpoints()).toHaveLength(1);
const mob = useCombatStore.getState().mobs[boss.id];
useCombatStore.setState({ mobs: { [boss.id]: { ...mob, dead: true, health: 0, despawned: true } } });
expect(availableResurrectionCheckpoints()).toHaveLength(1);
});
it("returns the defeated player and party reset signal to the selected boss, preserving the kill", () => {
const boss = dungeon.bosses[0];
useCombatStore.getState().registerMob(boss.id, { name: boss.name, maxHealth: 1, boss: true });
useCombatStore.getState().damageMob(boss.id, 1, 100);
useCombatStore.getState().damagePlayer(useCombatStore.getState().maxHealth * 10);
const before = useGameStore.getState().resetRevision;
expect(respawnDefeatedPlayer(`boss:${boss.id}`)).toBe(true);
expect(useGameStore.getState().playerPosition).toEqual(boss.position);
expect(useGameStore.getState().resetRevision).toBe(before + 1);
expect(useCombatStore.getState().playerPosition).toEqual(boss.position);
expect(useCombatStore.getState().health).toBe(useCombatStore.getState().maxHealth);
expect(useCombatStore.getState().mobs[boss.id].dead).toBe(true);
expect(availableResurrectionCheckpoints().map((checkpoint) => checkpoint.id)).toContain(`boss:${boss.id}`);
});
it("lets a defeated player explicitly choose the entrance instead of a previously saved boss spawn", () => {
useGameStore.setState({ activeSpawn: { footPosition: dungeon.bosses[0].position, yaw: 1 } });
useCombatStore.getState().damagePlayer(useCombatStore.getState().maxHealth * 10);
expect(respawnDefeatedPlayer("entrance")).toBe(true);
expect(useGameStore.getState().playerPosition).toEqual(dungeon.entrance.footPosition);
});
it("rejects locked boss choices and cannot teleport a living player", () => {
const before = useGameStore.getState();
expect(respawnDefeatedPlayer("entrance")).toBe(false);
useCombatStore.getState().damagePlayer(useCombatStore.getState().maxHealth * 10);
expect(respawnDefeatedPlayer(`boss:${dungeon.bosses[0].id}`)).toBe(false);
expect(useCombatStore.getState().health).toBe(0);
expect(useGameStore.getState()).toBe(before);
});
});