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); }); });