Release Healer Man 0.1.59

This commit is contained in:
phenom committed 2026-09-27 10:16:42 -04:00
1 parent 11934a3979
commit ab1434a3b8
44 files changed
+1242 -103

No files matched your search

+42
View File
@@ -354,6 +354,48 @@ describe("party combat runtime", () => {
.toBeGreaterThan(startingHealth);
});
it("keeps companion Penance active for three healing pulses", () => {
useCombatStore.getState().initializeCharacter({ classId: "mage", role: "damage", level: 80 });
const tank = createConfiguredPartyMember({
name: "Tank", classId: "warrior", specialization: "Protection",
specializationId: "warrior:protection", talentTreeId: "warrior-protection", role: "tank",
}, 80, 0, "penance-runtime");
const healer = createConfiguredPartyMember({
name: "Discipline", classId: "priest", specialization: "Discipline",
specializationId: "priest:discipline", talentTreeId: "priest-discipline",
talentRanks: runtimePartyTalentRanksForLevel("priest", "Discipline", 80), role: "healer",
}, 80, 1, "penance-runtime");
const priestAbilities = abilitiesForClass("priest");
const penance = priestAbilities.find((ability) => ability.name === "Penance")!;
const startingHealth = Math.round(tank.maxHealth * 0.2);
usePartyStore.getState().initializeParty("penance-runtime", 80, useCombatStore.getState().health, "damage");
usePartyStore.setState({ members: [
{ ...tank, health: startingHealth },
{ ...healer, cooldowns: Object.fromEntries(priestAbilities
.filter((ability) => ability.id !== penance.id)
.map((ability) => [ability.id, 60_000])) },
] });
for (const member of usePartyStore.getState().members) registerPartyRuntimePosition(member.id, [0, 0, 0]);
useCombatStore.getState().synchronizeActors();
registerEngagedMob("penance-boss", 100_000);
advanceDungeonPartyCombat(1_000);
expect(usePartyStore.getState().members.find((member) => member.id === healer.id)?.activeCast)
.toMatchObject({ mode: "channel", startedAt: 1_000, completesAt: 3_000 });
expect(usePartyStore.getState().members.find((member) => member.id === tank.id)?.health).toBe(startingHealth);
advanceDungeonPartyCombat(1_001);
const first = usePartyStore.getState().members.find((member) => member.id === tank.id)!.health;
expect(first).toBeGreaterThan(startingHealth);
advanceDungeonPartyCombat(1_999);
expect(usePartyStore.getState().members.find((member) => member.id === tank.id)?.health).toBe(first);
advanceDungeonPartyCombat(2_000);
expect(usePartyStore.getState().members.find((member) => member.id === tank.id)?.health).toBeGreaterThan(first);
advanceDungeonPartyCombat(3_000);
expect(usePartyStore.getState().members.find((member) => member.id === healer.id)?.activeCast).toBeNull();
expect(usePartyStore.getState().members.find((member) => member.id === healer.id)?.nextActionAt).toBe(3_250);
expect(useCombatStore.getState().effects.some((effect) => effect.sourceAbilityId === penance.id)).toBe(false);
});
it("lets a resurrected tank rejoin independently instead of taunting or casting from its checkpoint", () => {
registerEngagedMob();
const tank = usePartyStore.getState().members.find((member) => member.role === "tank")!;