Files
healer-man/src/game/romPriestChampionProtectionRuneRuntime.test.ts
T

111 lines
4.5 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { applyAura, evaluateAuraProcs } from "./combatAuras";
import {
ROM_PRIEST_CHAMPION_HEART_RUNE_ENERGY_SPELL_ID,
ROM_PRIEST_CHAMPION_PROTECTION_RUNE_SEAL_SPELL_ID,
ROM_PRIEST_CHAMPION_REGENERATE_PROC_AURA_ID,
ROM_PRIEST_CHAMPION_REGENERATE_PROC_CHANCE,
ROM_PRIEST_CHAMPION_REGENERATE_PROC_ID,
ROM_PRIEST_CHAMPION_REGENERATE_SPELL_ID,
romPriestChampionCastEffects,
romPriestChampionProtectionRuneSealProcIsEligible,
} from "./romPriestChampionOverrides";
import { abilitiesForCharacter } from "./abilityCatalog";
const base = {
primaryClassId: "rom-priest",
secondaryClassId: "rom-champion",
learnedPassiveSpellIds: [ROM_PRIEST_CHAMPION_PROTECTION_RUNE_SEAL_SPELL_ID],
trigger: "periodic" as const,
triggeringAbilitySpellId: ROM_PRIEST_CHAMPION_REGENERATE_SPELL_ID,
healingAmount: 1,
};
describe("RoM Priest/Champion Protection Rune Seal proc profile", () => {
it("requires the exact pair, learned passive, positive heal tick, and Regenerate periodic event", () => {
expect(romPriestChampionProtectionRuneSealProcIsEligible(base)).toBe(true);
expect(romPriestChampionProtectionRuneSealProcIsEligible({
...base,
primaryClassId: "rom-champion",
secondaryClassId: "rom-priest",
})).toBe(false);
expect(romPriestChampionProtectionRuneSealProcIsEligible({
...base,
secondaryClassId: "rom-warrior",
})).toBe(false);
expect(romPriestChampionProtectionRuneSealProcIsEligible({
...base,
learnedPassiveSpellIds: [],
})).toBe(false);
expect(romPriestChampionProtectionRuneSealProcIsEligible({
...base,
trigger: "heal",
})).toBe(false);
expect(romPriestChampionProtectionRuneSealProcIsEligible({
...base,
triggeringAbilitySpellId: ROM_PRIEST_CHAMPION_HEART_RUNE_ENERGY_SPELL_ID,
})).toBe(false);
for (const healingAmount of [0, -1, Number.NaN, Number.POSITIVE_INFINITY]) {
expect(romPriestChampionProtectionRuneSealProcIsEligible({ ...base, healingAmount })).toBe(false);
}
});
it("attaches the chance aura only to the Priest/Champion's Regenerate cast", () => {
const regenerate = abilitiesForCharacter("rom-priest", "rom-champion")
.find((ability) => ability.dbcSpellId === ROM_PRIEST_CHAMPION_REGENERATE_SPELL_ID)!;
const [effect] = romPriestChampionCastEffects(regenerate, regenerate.effects, [
ROM_PRIEST_CHAMPION_PROTECTION_RUNE_SEAL_SPELL_ID,
]);
expect(effect).toMatchObject({
kind: "apply-aura",
recipient: "caster",
triggerSpellId: ROM_PRIEST_CHAMPION_PROTECTION_RUNE_SEAL_SPELL_ID,
aura: {
id: ROM_PRIEST_CHAMPION_REGENERATE_PROC_AURA_ID,
durationMs: 20_001,
procs: [{
id: ROM_PRIEST_CHAMPION_REGENERATE_PROC_ID,
chance: ROM_PRIEST_CHAMPION_REGENERATE_PROC_CHANCE,
triggers: "periodic",
}],
},
});
expect(romPriestChampionCastEffects(regenerate, regenerate.effects, [])).toBe(regenerate.effects);
const heartRuneEnergy = abilitiesForCharacter("rom-priest", "rom-champion")
.find((ability) => ability.dbcSpellId === ROM_PRIEST_CHAMPION_HEART_RUNE_ENERGY_SPELL_ID)!;
expect(romPriestChampionCastEffects(
heartRuneEnergy,
heartRuneEnergy.effects,
[ROM_PRIEST_CHAMPION_PROTECTION_RUNE_SEAL_SPELL_ID],
)).toBe(heartRuneEnergy.effects);
});
it("uses the documented 8% proc boundary, with equality excluded", () => {
const regenerate = abilitiesForCharacter("rom-priest", "rom-champion")
.find((ability) => ability.dbcSpellId === ROM_PRIEST_CHAMPION_REGENERATE_SPELL_ID)!;
const auraEffect = romPriestChampionCastEffects(regenerate, regenerate.effects, [
ROM_PRIEST_CHAMPION_PROTECTION_RUNE_SEAL_SPELL_ID,
])[0];
if (auraEffect.kind !== "apply-aura") throw new Error("Protection Rune Seal should add a proc aura.");
const activeAura = applyAura([], {
definition: auraEffect.aura,
sourceId: "priest-champion",
targetId: "priest-champion",
now: 1_000,
}).auras;
const event = {
trigger: "periodic" as const,
subjectId: "priest-champion",
otherId: "priest-champion",
abilityId: regenerate.id,
amount: 1,
};
expect(evaluateAuraProcs(activeAura, event, 3_000, () => ROM_PRIEST_CHAMPION_REGENERATE_PROC_CHANCE - 0.000_001)
.triggered).toHaveLength(1);
expect(evaluateAuraProcs(activeAura, event, 3_000, () => ROM_PRIEST_CHAMPION_REGENERATE_PROC_CHANCE)
.triggered).toHaveLength(0);
});
});