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

111 lines
5.4 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { ROM_ALL_ABILITIES } from "./romAbilityCatalog";
import { romEffectsForCast } from "./romCombatMechanics";
import {
romWarlockPriestSpreadingPainCriticalMultiplier,
romWarlockPriestSpreadingPainEffects,
ROM_WARLOCK_PRIEST_SPREADING_PAIN_CRIT_TAG,
ROM_WARLOCK_PRIEST_SPREADING_PAIN_HEALING_BONUS,
ROM_WARLOCK_PRIEST_SPREADING_PAIN_HEALING_DURATION_MS,
ROM_WARLOCK_PRIEST_SPREADING_PAIN_ID,
ROM_WARLOCK_PRIEST_SPREADING_PAIN_MAGIC_ATTACK_BONUS,
ROM_WARLOCK_PRIEST_SPREADING_PAIN_MAGIC_BUFF_DURATION_MS,
} from "./romWarlockPriestSpreadingPain";
function spreadingPain() {
const result = ROM_ALL_ABILITIES.find((ability) => ability.dbcSpellId === ROM_WARLOCK_PRIEST_SPREADING_PAIN_ID);
expect(result).toBeDefined();
return result!;
}
describe("RoM Warlock/Priest Spreading Pain source effects", () => {
it("routes the exact pair through the cast pipeline and retains RuneWaker cost/range", () => {
const ability = spreadingPain();
const castEffects = romEffectsForCast(ability, {
sealStacks: 0,
bleedCount: 0,
charged: false,
mainHandDagger: false,
casterMaxHealth: 1_000,
targetHealthPercent: 1,
});
const auras = castEffects.filter((effect) => effect.kind === "apply-aura");
expect(ability.costs).toEqual([{ resource: "focus", amount: 15 }]);
expect(ability.range).toMatchObject({ min: 0, max: 22.5 });
expect(ability.description).toContain("10% MP cost plus 15 Focus and range 150");
expect(castEffects.filter((effect) => effect.kind === "trigger-spell").map((effect) => (
effect.kind === "trigger-spell" ? effect.spellId : 0
)).sort((a, b) => a - b)).toEqual([497_959, 497_960, 497_964]);
expect(auras).toHaveLength(3);
expect(auras.map((effect) => effect.kind === "apply-aura" ? effect.aura.durationMs : null))
.toEqual([30_000, 30_000, 20_000]);
});
it("keeps the three RuneWaker child spells and adds only the current CoA caster buffs", () => {
const ability = spreadingPain();
const originalTriggers = ability.effects.filter((effect) => effect.kind === "trigger-spell");
expect(originalTriggers).toHaveLength(3);
expect(originalTriggers.map((effect) => effect.kind === "trigger-spell" ? effect.spellId : 0).sort((a, b) => a - b))
.toEqual([497_959, 497_960, 497_964]);
const effects = romWarlockPriestSpreadingPainEffects(ability, ability.effects);
expect(effects).toHaveLength(ability.effects.length + 3);
expect(effects?.filter((effect) => effect.kind === "trigger-spell")).toEqual(originalTriggers);
const auras = effects?.filter((effect) => effect.kind === "apply-aura") ?? [];
expect(auras).toHaveLength(3);
expect(auras).toEqual(expect.arrayContaining([
expect.objectContaining({
recipient: "caster",
aura: expect.objectContaining({
durationMs: ROM_WARLOCK_PRIEST_SPREADING_PAIN_MAGIC_BUFF_DURATION_MS,
utilityTags: [ROM_WARLOCK_PRIEST_SPREADING_PAIN_CRIT_TAG],
modifiers: [expect.objectContaining({
kind: "stat", stat: "critical-damage", operation: "percent", value: 0.25,
})],
}),
}),
expect.objectContaining({
recipient: "caster",
aura: expect.objectContaining({
durationMs: ROM_WARLOCK_PRIEST_SPREADING_PAIN_MAGIC_BUFF_DURATION_MS,
modifiers: [expect.objectContaining({
kind: "stat", stat: "magical-attack", operation: "percent", value: ROM_WARLOCK_PRIEST_SPREADING_PAIN_MAGIC_ATTACK_BONUS,
})],
}),
}),
expect.objectContaining({
recipient: "caster",
aura: expect.objectContaining({
durationMs: ROM_WARLOCK_PRIEST_SPREADING_PAIN_HEALING_DURATION_MS,
modifiers: [expect.objectContaining({
kind: "healing", direction: "done", operation: "percent", value: ROM_WARLOCK_PRIEST_SPREADING_PAIN_HEALING_BONUS,
})],
}),
}),
]));
// Patch 10.6.1 says Spreading Pain grants the healing portion of Healing
// Fortune; its independent Wisdom and Warp Charge clauses are not copied.
expect(auras.some((effect) => effect.kind === "apply-aura"
&& effect.aura.modifiers?.some((modifier) => modifier.kind === "stat" && modifier.stat === "wisdom"))).toBe(false);
});
it("requires the exact local Warlock/Priest pairing and spell ID", () => {
const ability = spreadingPain();
expect(romWarlockPriestSpreadingPainEffects({ ...ability, secondaryClassId: "rom-warrior" }, ability.effects)).toBeNull();
expect(romWarlockPriestSpreadingPainEffects({ ...ability, classId: "rom-priest" }, ability.effects)).toBeNull();
expect(romWarlockPriestSpreadingPainEffects({ ...ability, name: "Reused ID" }, ability.effects)).toBeNull();
expect(romWarlockPriestSpreadingPainEffects({ ...ability, dbcSpellId: 499_858 }, ability.effects)).toBeNull();
expect(romWarlockPriestSpreadingPainEffects({ ...ability, source: "coa-tree" }, ability.effects)).toBeNull();
});
it("adds 25% to magical spell critical bonus damage, not crit chance or ordinary hits", () => {
expect(romWarlockPriestSpreadingPainCriticalMultiplier(2, true, true)).toBe(2.25);
expect(romWarlockPriestSpreadingPainCriticalMultiplier(1.5, true, true)).toBe(1.625);
expect(romWarlockPriestSpreadingPainCriticalMultiplier(2, false, true)).toBe(2);
expect(romWarlockPriestSpreadingPainCriticalMultiplier(2, true, false)).toBe(2);
});
});