Files
healer-man/src/game/romWarlockPriestSoulEnlightenment.integration.test.ts
2026-10-02 10:38:12 -04:00

145 lines
6.0 KiB
TypeScript

import { beforeEach, describe, expect, it } from "vitest";
import { resolveDamageValue, resolveHealingValue } from "./combatAuras";
import { abilityById } from "./abilityCatalog";
import { useCombatStore } from "./combatStore";
import { clearPartyRuntimeRegistry, registerPartyRuntimePosition } from "./partyRuntimeRegistry";
import { advanceDungeonPartyCombat, resetPartyRuntimeClock } from "./partyRuntime";
import { PLAYER_AGGRO_ID } from "./aggro";
import { createConfiguredPartyMember, usePartyStore } from "./partyStore";
import { clearMobRuntimeRegistry } from "./mobRuntimeRegistry";
const SOUL_ENLIGHTENMENT_ID = "rom-warlock-rom-priest-elite-40";
const SOUL_ENLIGHTENMENT_AURA_ID = "rom-warlock-priest-soul-enlightenment-498649";
function activeCast(abilityId: string, targetId: string, at: number) {
return {
abilityId,
school: "shadow" as const,
mode: "cast" as const,
startedAt: at,
completesAt: at,
originalDurationMs: 0,
pushbackHits: 0,
origin: [0, 0, 0] as const,
targetId,
};
}
describe("CoA Warlock/Priest Soul Enlightenment integration", () => {
beforeEach(() => {
clearMobRuntimeRegistry();
clearPartyRuntimeRegistry();
resetPartyRuntimeClock();
useCombatStore.getState().initializeCharacter({
classId: "rom-warlock",
secondaryClassId: "rom-priest",
raceId: "rom-human",
level: 80,
});
useCombatStore.setState((state) => ({
resourcePools: { ...state.resourcePools, psi: 6 },
maxResourcePools: { ...state.maxResourcePools, psi: 6 },
}));
usePartyStore.getState().initializeParty(
"rom-warlock-priest-soul-enlightenment", 80, useCombatStore.getState().health, "damage", 2, "rom",
);
});
it("casts for the player, pays Psi, and applies the radius-limited modifiers", () => {
const seed = "rom-warlock-priest-soul-enlightenment-player";
const inside = createConfiguredPartyMember({
name: "Inside recipient",
classId: "rom-warrior",
raceId: "rom-human",
specialization: "Primary",
role: "damage",
}, 80, 0, seed);
const outside = createConfiguredPartyMember({
name: "Outside recipient",
classId: "rom-priest",
raceId: "rom-human",
specialization: "Primary",
role: "healer",
}, 80, 1, seed);
usePartyStore.setState({ members: [inside, outside] });
registerPartyRuntimePosition(inside.id, [7.5, 0, 0]);
registerPartyRuntimePosition(outside.id, [7.51, 0, 0]);
useCombatStore.getState().synchronizeActors();
const ability = abilityById(SOUL_ENLIGHTENMENT_ID)!;
expect(useCombatStore.getState().castAbility(ability.id, { now: 1_000 })).toMatchObject({ ok: true });
expect(useCombatStore.getState().resourcePools.psi).toBe(4);
const auras = useCombatStore.getState().auras;
const casterAura = auras.find((aura) => aura.sourceId === PLAYER_AGGRO_ID
&& aura.targetId === PLAYER_AGGRO_ID && aura.definition.id === SOUL_ENLIGHTENMENT_AURA_ID);
expect(casterAura?.expiresAt).toBe(31_000);
expect(auras.some((aura) => aura.sourceId === PLAYER_AGGRO_ID
&& aura.targetId === inside.id && aura.definition.id === SOUL_ENLIGHTENMENT_AURA_ID)).toBe(true);
expect(auras.some((aura) => aura.sourceId === PLAYER_AGGRO_ID
&& aura.targetId === outside.id && aura.definition.id === SOUL_ENLIGHTENMENT_AURA_ID)).toBe(false);
expect(resolveDamageValue(1_000, [casterAura!], {
direction: "dealt", school: "physical", attackKind: "melee",
})).toBe(1_057);
expect(resolveHealingValue(1_000, [casterAura!], "taken")).toBe(1_171);
expect(casterAura?.definition.modifiers?.some((modifier) => modifier.kind === "stat"
&& modifier.stat === "maximum-health")).toBe(false);
});
it("uses the existing companion party-cast route and applies the same area aura", () => {
const seed = "rom-warlock-priest-soul-enlightenment-companion";
const caster = createConfiguredPartyMember({
name: "Warlock/Priest Companion",
classId: "rom-warlock",
secondaryClassId: "rom-priest",
raceId: "rom-dwarf",
specialization: "Warlock/Priest",
role: "damage",
}, 80, 0, seed);
const inside = createConfiguredPartyMember({
name: "Inside companion recipient",
classId: "rom-warrior",
raceId: "rom-human",
specialization: "Primary",
role: "damage",
}, 80, 1, seed);
const outside = createConfiguredPartyMember({
name: "Outside companion recipient",
classId: "rom-priest",
raceId: "rom-human",
specialization: "Primary",
role: "healer",
}, 80, 2, seed);
const soulEnlightenment = abilityById(SOUL_ENLIGHTENMENT_ID)!;
usePartyStore.setState({
command: "stop",
members: [{
...caster,
resourcePools: { ...caster.resourcePools, psi: 6 },
activeCast: activeCast(soulEnlightenment.id, caster.id, 1_000),
activeCastTargetId: caster.id,
status: "attacking",
}, inside, outside],
});
registerPartyRuntimePosition(caster.id, [0, 0, 0]);
registerPartyRuntimePosition(inside.id, [7.5, 0, 0]);
registerPartyRuntimePosition(outside.id, [7.51, 0, 0]);
useCombatStore.getState().synchronizeActors();
advanceDungeonPartyCombat(1_000);
const auras = useCombatStore.getState().auras;
const casterAura = auras.find((aura) => aura.sourceId === caster.id
&& aura.targetId === caster.id && aura.definition.id === SOUL_ENLIGHTENMENT_AURA_ID);
expect(casterAura?.expiresAt).toBe(31_000);
expect(auras.some((aura) => aura.sourceId === caster.id
&& aura.targetId === inside.id && aura.definition.id === SOUL_ENLIGHTENMENT_AURA_ID)).toBe(true);
expect(auras.some((aura) => aura.sourceId === caster.id
&& aura.targetId === outside.id && aura.definition.id === SOUL_ENLIGHTENMENT_AURA_ID)).toBe(false);
expect(resolveDamageValue(1_000, [casterAura!], {
direction: "dealt", school: "shadow", attackKind: "spell",
})).toBe(1_057);
expect(resolveHealingValue(1_000, [casterAura!], "taken")).toBe(1_171);
});
});