forked from phenom/healer-man
158 lines
6.0 KiB
TypeScript
158 lines
6.0 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
||
import { parseTalentModifiers } from "./talentModifiers";
|
||
import { ROM_ALL_ABILITIES } from "./romAbilityCatalog";
|
||
|
||
function priestSkill(sourceSkillId: number) {
|
||
const ability = ROM_ALL_ABILITIES.find((entry) => entry.dbcSpellId === sourceSkillId);
|
||
if (!ability) throw new Error(`Missing Priest source skill ${sourceSkillId}`);
|
||
return ability;
|
||
}
|
||
|
||
describe("current CoA Priest catalog reworks", () => {
|
||
it("models Beacon of Regeneration as one 30-second friendly target mark and preserves local costs", () => {
|
||
const ability = priestSkill(498620);
|
||
expect(ability).toMatchObject({
|
||
name: "Beacon of Regeneration",
|
||
classId: "rom-priest",
|
||
secondaryClassId: "rom-champion",
|
||
target: "friendly",
|
||
castMode: "instant",
|
||
castTimeMs: 0,
|
||
cooldownMs: 30_000,
|
||
range: { max: 20 },
|
||
cost: { resource: "mana", amount: 29 },
|
||
});
|
||
expect(ability.costs).toEqual([
|
||
{ resource: "mana", amount: 29 },
|
||
{ resource: "mana", amount: 1, percentage: true },
|
||
]);
|
||
expect(ability.effects).toHaveLength(1);
|
||
expect(ability.effects[0]).toMatchObject({
|
||
kind: "apply-aura",
|
||
recipient: "ability-target",
|
||
triggerSpellId: 498_620,
|
||
aura: {
|
||
name: "Beacon of Regeneration",
|
||
durationMs: 30_000,
|
||
utilityTags: ["rom-priest-champion-beacon-of-regeneration"],
|
||
},
|
||
});
|
||
expect(ability.description).toContain("770 at skill level +105 (the maximum)");
|
||
expect(ability.description).toContain("applies this value at every unlocked rank");
|
||
expect(ability.ranks?.[0]?.effects).toEqual(ability.effects);
|
||
});
|
||
|
||
it("models 490274 as a passive Wisdom and Light-damage aura", () => {
|
||
const ability = priestSkill(490274);
|
||
expect(ability).toMatchObject({
|
||
name: "Holy Blessing",
|
||
passive: true,
|
||
target: "self",
|
||
castMode: "instant",
|
||
castTimeMs: 0,
|
||
cooldownMs: 0,
|
||
range: { max: 1 },
|
||
});
|
||
expect(ability.effects).toHaveLength(1);
|
||
expect(ability.effects[0]).toMatchObject({
|
||
kind: "apply-aura",
|
||
recipient: "caster",
|
||
triggerSpellId: 490_274,
|
||
aura: {
|
||
durationMs: null,
|
||
},
|
||
});
|
||
const aura = ability.effects[0].kind === "apply-aura" ? ability.effects[0].aura : undefined;
|
||
expect(aura?.modifiers).toEqual(expect.arrayContaining([
|
||
{ kind: "stat", stat: "wisdom", operation: "flat", value: 115 },
|
||
{ kind: "stat", stat: "wisdom", operation: "percent", value: 0.105 },
|
||
expect.objectContaining({ kind: "damage", direction: "dealt", school: "holy", operation: "percent" }),
|
||
]));
|
||
const lightDamage = aura?.modifiers?.find((modifier) => modifier.kind === "damage");
|
||
if (lightDamage?.kind !== "damage") throw new Error("Missing Holy Blessing Light damage modifier");
|
||
expect(lightDamage.value).toBeCloseTo(1.009);
|
||
expect(ability.ranks?.[0]?.effects).toEqual(ability.effects);
|
||
expect(ability.description).toContain("Wisdom bonus: (current Wisdom + 115) × 10.5% + 115");
|
||
expect(ability.description).toContain("Light Damage bonus: +100.9%");
|
||
expect(parseTalentModifiers(ability.description)).toEqual([]);
|
||
});
|
||
|
||
it("models Vow of Silence's interrupt and NPC silence duration with current spell data", () => {
|
||
const ability = priestSkill(490275);
|
||
expect(ability).toMatchObject({
|
||
name: "Vow of Silence",
|
||
target: "hostile",
|
||
castMode: "instant",
|
||
castTimeMs: 0,
|
||
cooldownMs: 18_000,
|
||
range: { max: 150 },
|
||
cost: { resource: "mana", amount: 120 },
|
||
});
|
||
expect(ability.effects).toEqual(expect.arrayContaining([
|
||
expect.objectContaining({ kind: "interrupt", lockoutMs: 8_400 }),
|
||
expect.objectContaining({
|
||
kind: "apply-aura",
|
||
control: { kind: "silence" },
|
||
aura: expect.objectContaining({ durationMs: 8_400 }),
|
||
}),
|
||
]));
|
||
expect(ability.description).toContain("8.4 seconds");
|
||
expect(ability.description).toContain("4.2 seconds against players");
|
||
expect(ability.ranks?.[0]?.description).toContain("Vow of Silence");
|
||
});
|
||
|
||
it("models Holy Void's flat Light hit and 20-second dual-defense reduction", () => {
|
||
const ability = priestSkill(490276);
|
||
expect(ability).toMatchObject({
|
||
name: "Holy Void",
|
||
target: "hostile",
|
||
castMode: "instant",
|
||
castTimeMs: 0,
|
||
cooldownMs: 18_000,
|
||
range: { max: 150 },
|
||
cost: { resource: "mana", amount: 10, percentage: true, percentageBasis: "base-mana" },
|
||
});
|
||
expect(ability.effects).toEqual(expect.arrayContaining([
|
||
expect.objectContaining({ kind: "damage", basePoints: 1_655, school: "holy" }),
|
||
expect.objectContaining({
|
||
kind: "apply-aura",
|
||
aura: expect.objectContaining({
|
||
name: "Voidal Infection",
|
||
durationMs: 20_000,
|
||
modifiers: expect.arrayContaining([
|
||
{ kind: "stat", stat: "physical-defense", operation: "percent", value: -0.188 },
|
||
{ kind: "stat", stat: "magical-defense", operation: "percent", value: -0.188 },
|
||
]),
|
||
}),
|
||
}),
|
||
]));
|
||
});
|
||
|
||
it("models Heart Rune Energy's caster-centered damage and cooldown reduction", () => {
|
||
const ability = priestSkill(498612);
|
||
expect(ability).toMatchObject({
|
||
name: "Heart Rune Energy",
|
||
target: "self",
|
||
castMode: "instant",
|
||
castTimeMs: 0,
|
||
cooldownMs: 12_000,
|
||
range: { max: 150 },
|
||
radius: 80,
|
||
targeting: { shape: "circle", radius: 80 },
|
||
cost: { resource: "rage", amount: 15 },
|
||
});
|
||
expect(ability.effects).toEqual(expect.arrayContaining([
|
||
expect.objectContaining({ kind: "damage", coefficient: 9.751, school: "holy" }),
|
||
expect.objectContaining({
|
||
kind: "cooldown-reset",
|
||
mode: "reduce",
|
||
abilityName: "Blessing of Humility",
|
||
amountMs: 15_000,
|
||
}),
|
||
]));
|
||
expect(ability.description).toContain("975.1% CPS Light Damage");
|
||
expect(ability.description).toContain("15 seconds");
|
||
expect(ability.ranks?.[0]?.effects).toEqual(ability.effects);
|
||
});
|
||
});
|