forked from phenom/healer-man
163 lines
5.9 KiB
TypeScript
163 lines
5.9 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import type { AbilityDefinition } from "./abilityCatalog";
|
|
import {
|
|
isRomPriestScoutCuringShot,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_COOLDOWN_MS,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_DESCRIPTION,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_DURATION_MS,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_ELEMENTAL_AURA,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_ELEMENTAL_DAMAGE_BONUS,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_ELEMENTAL_SCHOOLS,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_HOT_TICKS,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_ID,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_IMMEDIATE_HEAL,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_RADIUS,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_RANGE,
|
|
ROM_PRIEST_SCOUT_CURING_SHOT_TICK_INTERVAL_MS,
|
|
romPriestScoutCuringShotCatalogOverride,
|
|
} from "./romPriestScoutCuringShot";
|
|
|
|
const localAbility: AbilityDefinition = {
|
|
id: "rom-priest-rom-scout-elite-35",
|
|
classId: "rom-priest",
|
|
secondaryClassId: "rom-scout",
|
|
dbcSpellId: ROM_PRIEST_SCOUT_CURING_SHOT_ID,
|
|
name: "Curing Shot",
|
|
unlockLevel: 35,
|
|
icon: "/assets/ui/rom-spells/577011.png",
|
|
sigil: "CS",
|
|
description: "Local two-second heal row.",
|
|
target: "friendly",
|
|
range: { min: 0, max: 20 },
|
|
radius: 20,
|
|
targeting: { shape: "circle", radius: 20, maximumTargets: 5 },
|
|
castMode: "cast",
|
|
castTimeMs: 2_000,
|
|
cooldownMs: 12_000,
|
|
gcdMs: 1_500,
|
|
cost: { resource: "mana", amount: 120 },
|
|
costs: [{ resource: "mana", amount: 120 }],
|
|
effects: [{ kind: "damage", coefficient: 0.2 }],
|
|
source: "runewaker",
|
|
romSkillGroup: "elite",
|
|
ranks: [{
|
|
rank: 1,
|
|
spellId: ROM_PRIEST_SCOUT_CURING_SHOT_ID,
|
|
level: 35,
|
|
description: "Local two-second heal row.",
|
|
castMode: "cast",
|
|
castTimeMs: 2_000,
|
|
cooldownMs: 12_000,
|
|
gcdMs: 1_500,
|
|
cost: { resource: "mana", amount: 120 },
|
|
costs: [{ resource: "mana", amount: 120 }],
|
|
effects: [{ kind: "damage", coefficient: 0.2 }],
|
|
}],
|
|
};
|
|
|
|
describe("current CoA Priest/Scout Curing Shot catalog overlay", () => {
|
|
it("uses current CoA cast, cooldown, radius, direct heal, HoT, and elemental-buff metadata", () => {
|
|
const ability = romPriestScoutCuringShotCatalogOverride(localAbility);
|
|
|
|
expect(ability).toMatchObject({
|
|
name: "Curing Shot",
|
|
target: "friendly",
|
|
range: { min: 0, max: ROM_PRIEST_SCOUT_CURING_SHOT_RANGE },
|
|
radius: ROM_PRIEST_SCOUT_CURING_SHOT_RADIUS,
|
|
targeting: { shape: "circle", radius: ROM_PRIEST_SCOUT_CURING_SHOT_RADIUS },
|
|
castMode: "instant",
|
|
castTimeMs: 0,
|
|
cooldownMs: ROM_PRIEST_SCOUT_CURING_SHOT_COOLDOWN_MS,
|
|
description: ROM_PRIEST_SCOUT_CURING_SHOT_DESCRIPTION,
|
|
passive: false,
|
|
});
|
|
expect(ability.effects).toEqual([
|
|
{
|
|
kind: "heal",
|
|
coefficient: 0,
|
|
basePoints: ROM_PRIEST_SCOUT_CURING_SHOT_IMMEDIATE_HEAL,
|
|
recipient: "caster",
|
|
scope: "party",
|
|
radius: ROM_PRIEST_SCOUT_CURING_SHOT_RADIUS,
|
|
},
|
|
{
|
|
kind: "hot",
|
|
coefficient: 0,
|
|
basePoints: 167.5,
|
|
ticks: ROM_PRIEST_SCOUT_CURING_SHOT_HOT_TICKS,
|
|
intervalMs: ROM_PRIEST_SCOUT_CURING_SHOT_TICK_INTERVAL_MS,
|
|
recipient: "caster",
|
|
scope: "party",
|
|
radius: ROM_PRIEST_SCOUT_CURING_SHOT_RADIUS,
|
|
},
|
|
expect.objectContaining({
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: ROM_PRIEST_SCOUT_CURING_SHOT_ELEMENTAL_AURA,
|
|
}),
|
|
]);
|
|
expect(ROM_PRIEST_SCOUT_CURING_SHOT_DURATION_MS).toBe(18_000);
|
|
expect(ROM_PRIEST_SCOUT_CURING_SHOT_ELEMENTAL_DAMAGE_BONUS).toBe(0.1);
|
|
expect(ROM_PRIEST_SCOUT_CURING_SHOT_ELEMENTAL_SCHOOLS).toEqual([
|
|
"frost",
|
|
]);
|
|
expect(ROM_PRIEST_SCOUT_CURING_SHOT_ELEMENTAL_AURA).toMatchObject({
|
|
durationMs: 18_000,
|
|
modifiers: [
|
|
{ kind: "damage", direction: "dealt", school: "frost", operation: "percent", value: 0.1 },
|
|
],
|
|
});
|
|
});
|
|
|
|
it("does not carry over the local five-target cap and preserves the unsupported-to-scale local cost", () => {
|
|
const ability = romPriestScoutCuringShotCatalogOverride(localAbility);
|
|
|
|
expect(ability.targeting).toEqual({ shape: "circle", radius: 10 });
|
|
expect(ability.cost).toEqual({ resource: "mana", amount: 120 });
|
|
expect(ability.costs).toEqual([{ resource: "mana", amount: 120 }]);
|
|
expect(ability.ranks?.[0]).toMatchObject({
|
|
castMode: "instant",
|
|
castTimeMs: 0,
|
|
cooldownMs: 6_000,
|
|
cost: { resource: "mana", amount: 120 },
|
|
costs: [{ resource: "mana", amount: 120 }],
|
|
targeting: { shape: "circle", radius: 10 },
|
|
effects: ability.effects,
|
|
});
|
|
expect(ability.ranks?.[0]?.targeting).not.toHaveProperty("maximumTargets");
|
|
});
|
|
|
|
it("recognizes only the exact Priest-primary/Scout-secondary source identity", () => {
|
|
expect(isRomPriestScoutCuringShot({
|
|
classId: "rom-priest",
|
|
secondaryClassId: "rom-scout",
|
|
sourceSkillId: ROM_PRIEST_SCOUT_CURING_SHOT_ID,
|
|
})).toBe(true);
|
|
expect(isRomPriestScoutCuringShot({
|
|
classId: "rom-scout",
|
|
secondaryClassId: "rom-priest",
|
|
sourceSkillId: ROM_PRIEST_SCOUT_CURING_SHOT_ID,
|
|
})).toBe(false);
|
|
expect(isRomPriestScoutCuringShot({
|
|
classId: "rom-priest",
|
|
secondaryClassId: "rom-mage",
|
|
sourceSkillId: ROM_PRIEST_SCOUT_CURING_SHOT_ID,
|
|
})).toBe(false);
|
|
expect(isRomPriestScoutCuringShot({
|
|
classId: "rom-priest",
|
|
secondaryClassId: "rom-scout",
|
|
sourceSkillId: ROM_PRIEST_SCOUT_CURING_SHOT_ID + 1,
|
|
})).toBe(false);
|
|
});
|
|
|
|
it("leaves other rows and non-RuneWaker copies unchanged", () => {
|
|
const wrongPair = { ...localAbility, secondaryClassId: "rom-mage" as const };
|
|
const wrongId = { ...localAbility, dbcSpellId: ROM_PRIEST_SCOUT_CURING_SHOT_ID + 1 };
|
|
const wrongSource = { ...localAbility, source: "core" as const };
|
|
|
|
expect(romPriestScoutCuringShotCatalogOverride(wrongPair)).toBe(wrongPair);
|
|
expect(romPriestScoutCuringShotCatalogOverride(wrongId)).toBe(wrongId);
|
|
expect(romPriestScoutCuringShotCatalogOverride(wrongSource)).toBe(wrongSource);
|
|
});
|
|
});
|