111 lines
4.5 KiB
TypeScript
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);
|
|
});
|
|
});
|