forked from phenom/healer-man
Release Healer Man 0.1.43
This commit is contained in:
1 parent
c7e8163790
commit
ccc01396cd
86 files changed
+2951
-198
No files matched your search
@@ -0,0 +1,82 @@
|
||||
import { afterEach, describe, expect, it } from "vitest";
|
||||
import { buildBossTestingCatalog, BOSS_TESTING_CATALOG, createBossTestingRoom, randomTestingBoss } from "./bossTesting";
|
||||
import { clearBossTestingDungeons, DUNGEON_DEFINITIONS, registerBossTestingDungeon, requireDungeonDefinition } from "./dungeonRegistry";
|
||||
import { activateDungeonSession, restartActiveDungeonSession } from "./dungeonSession";
|
||||
import { useGameStore } from "./store";
|
||||
import { useCombatStore } from "./combatStore";
|
||||
import { bossTestIsDefeated } from "./BossTestingBridge";
|
||||
import type { DungeonDefinition } from "./dungeonTypes";
|
||||
|
||||
afterEach(() => {
|
||||
useGameStore.getState().activateDungeon("wailing-caverns");
|
||||
clearBossTestingDungeons();
|
||||
});
|
||||
|
||||
describe("Boss Testing", () => {
|
||||
const boss = BOSS_TESTING_CATALOG.find((entry) => entry.dungeonId === "wailing-caverns" && entry.name === "Lady Anacondra")!;
|
||||
const source = requireDungeonDefinition(boss.dungeonId);
|
||||
|
||||
it("includes unready and event-only bosses and isolates catalog changes from shipped content", () => {
|
||||
const blocked: DungeonDefinition = { ...source, availability: "blocked", staticSpawns: [], roamingPacks: [],
|
||||
encounterSpawnGroups: [{ id: "event", spawns: [boss.spawn] }], entities: { [boss.entityId]: source.entities[boss.entityId] } };
|
||||
expect(buildBossTestingCatalog([blocked])).toHaveLength(1);
|
||||
const count = DUNGEON_DEFINITIONS.length;
|
||||
const room = createBossTestingRoom(source, boss);
|
||||
registerBossTestingDungeon(room.definition, source.id);
|
||||
expect(requireDungeonDefinition(source.id)).toBe(source);
|
||||
expect(DUNGEON_DEFINITIONS).toHaveLength(count);
|
||||
expect(room.definition.staticSpawns).toHaveLength(1);
|
||||
expect(room.definition.roamingPacks).toEqual([]);
|
||||
expect(room.definition.entities[boss.entityId].combat).toEqual(source.entities[boss.entityId].combat);
|
||||
expect(room.definition.staticSpawns[0].position).toEqual(boss.spawn.position);
|
||||
expect(room.definition.assets).toEqual({ visual: [], collision: [] });
|
||||
});
|
||||
|
||||
it("preserves boss phases and scripted summons without spawning unrelated dungeon packs", () => {
|
||||
const fixture: DungeonDefinition = { ...source, encounters: [
|
||||
{ id: "boss-mechanics", dungeonId: source.id, initialPhase: "idle", rules: [{ id: "adds", trigger: { kind: "entity-health", entityId: boss.spawn.id, atOrBelowPercent: 50 },
|
||||
actions: [{ id: "summon", kind: "activate-spawn-group", spawnGroupId: "boss-adds" }, { id: "loot", kind: "grant-loot", lootTableId: "test" }] }] },
|
||||
{ id: "other-boss", dungeonId: source.id, initialPhase: "idle", rules: [{ id: "other", trigger: { kind: "entity-engaged", entityId: "unrelated" }, actions: [] }] },
|
||||
], encounterSpawnGroups: [{ id: "boss-adds", spawns: [{ ...boss.spawn, id: "add", entityId: boss.entityId }] }, { id: "trash", spawns: [] }] };
|
||||
const room = createBossTestingRoom(fixture, boss);
|
||||
expect(room.definition.encounters?.map((entry) => entry.id)).toEqual([`${room.definition.id}:boss-mechanics`]);
|
||||
expect(room.definition.encounters?.[0].dungeonId).toBe(room.definition.id);
|
||||
expect(room.definition.encounters?.[0].rules[0].actions).toEqual([{ id: "summon", kind: "activate-spawn-group", spawnGroupId: "boss-adds" }]);
|
||||
expect(room.definition.encounterSpawnGroups?.map((entry) => entry.id)).toEqual(["boss-adds"]);
|
||||
expect(room.definition.staticSpawns).toHaveLength(1);
|
||||
});
|
||||
|
||||
it("starts an unready boss room, survives scene retries, and retains testing mode when restarted", () => {
|
||||
const room = createBossTestingRoom(source, boss);
|
||||
registerBossTestingDungeon(room.definition, source.id);
|
||||
expect(activateDungeonSession(room.definition.id)).toBe(false);
|
||||
expect(activateDungeonSession(room.definition.id, undefined, { gmTestMode: true, bossTest: room.session })).toBe(true);
|
||||
expect(restartActiveDungeonSession()).toBe(true);
|
||||
useGameStore.getState().resetAtEntrance();
|
||||
expect(useGameStore.getState()).toMatchObject({ gmTestMode: true, bossTest: room.session, overlay: null });
|
||||
});
|
||||
|
||||
it("recognizes actual boss deaths and awards no progression or collectible rewards", () => {
|
||||
const room = createBossTestingRoom(source, boss);
|
||||
registerBossTestingDungeon(room.definition, source.id);
|
||||
useGameStore.getState().activateDungeon(room.definition.id, undefined, { bossTest: room.session, gmTestMode: true });
|
||||
useCombatStore.getState().initializeCharacter({ classId: "mage", level: 20 });
|
||||
expect(bossTestIsDefeated()).toBe(false);
|
||||
useCombatStore.getState().registerMob(boss.spawn.id, { name: boss.name, boss: true, maxHealth: 10, xpReward: 500, hasLoot: true, lootSourceId: boss.entityId });
|
||||
const xp = useCombatStore.getState().xp;
|
||||
useCombatStore.getState().damageMob(boss.spawn.id, 100000, Date.now());
|
||||
expect(bossTestIsDefeated()).toBe(true);
|
||||
const combat = useCombatStore.getState();
|
||||
expect(combat.xp).toBe(xp);
|
||||
expect(combat.mobs[boss.spawn.id]).toMatchObject({ hasLoot: false, pendingLoot: [] });
|
||||
expect(combat.mobs[boss.spawn.id].bossCardDrop).toBeFalsy();
|
||||
});
|
||||
|
||||
it("draws a boss only from the selected filters and handles empty queues", () => {
|
||||
expect(randomTestingBoss([], () => 0.5)).toBeNull();
|
||||
const candidates = BOSS_TESTING_CATALOG.slice(0, 2);
|
||||
expect(randomTestingBoss(candidates, () => 0)).toBe(candidates[0]);
|
||||
expect(randomTestingBoss(candidates, () => 1)).toBe(candidates[1]);
|
||||
expect(randomTestingBoss(candidates, () => Number.NaN)).toBe(candidates[0]);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user