75 lines
3.4 KiB
TypeScript
75 lines
3.4 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
import { abilityById } from "./abilityCatalog";
|
|
import { applyAura as applyCombatAura, type ActiveAura } from "./combatAuras";
|
|
import {
|
|
ROM_ROGUE_CHAMPION_NERVE_GEAR_AURA_ID,
|
|
ROM_ROGUE_CHAMPION_NERVE_GEAR_DURATION_MS,
|
|
ROM_ROGUE_CHAMPION_NERVE_GEAR_MARKER_TAG,
|
|
ROM_ROGUE_CHAMPION_NERVE_GEAR_MAX_STACKS,
|
|
romRogueChampionNerveGearEffect,
|
|
romRogueChampionNerveGearShouldTrigger,
|
|
} from "./romRogueChampionNerveGearRuntime";
|
|
|
|
describe("RoM Rogue/Champion Nerve Gear", () => {
|
|
const passive = abilityById("rom-rogue-rom-champion-elite-50")!;
|
|
const elite = abilityById("rom-rogue-rom-champion-elite-25")!;
|
|
const primaryAbility = abilityById("rom-rogue-primary-1")!;
|
|
|
|
it("requires the learned Rogue/Champion passive and a non-passive RuneWaker elite skill", () => {
|
|
expect(romRogueChampionNerveGearShouldTrigger("rom-rogue", "rom-champion", elite, true)).toBe(true);
|
|
expect(romRogueChampionNerveGearShouldTrigger("rom-rogue", "rom-champion", elite, false)).toBe(false);
|
|
expect(romRogueChampionNerveGearShouldTrigger("rom-rogue", "rom-warrior", elite, true)).toBe(false);
|
|
expect(romRogueChampionNerveGearShouldTrigger("rom-rogue", "rom-champion", primaryAbility, true)).toBe(false);
|
|
expect(romRogueChampionNerveGearShouldTrigger("rom-rogue", "rom-champion", passive, true)).toBe(false);
|
|
expect(romRogueChampionNerveGearShouldTrigger("rom-champion", "rom-rogue", elite, true)).toBe(false);
|
|
});
|
|
|
|
it("keeps the learned passive as a marker instead of an unconditional stat aura", () => {
|
|
const marker = passive.effects.find((effect) => effect.kind === "apply-aura");
|
|
expect(marker?.kind).toBe("apply-aura");
|
|
if (marker?.kind !== "apply-aura") throw new Error("Missing Nerve Gear passive marker.");
|
|
expect(marker.aura.utilityTags).toContain(ROM_ROGUE_CHAMPION_NERVE_GEAR_MARKER_TAG);
|
|
expect(marker.aura.durationMs).toBeNull();
|
|
expect(marker.aura.modifiers).toBeUndefined();
|
|
});
|
|
|
|
it("uses the local 5-second, five-stack attack-speed and dodge payload", () => {
|
|
const effect = romRogueChampionNerveGearEffect();
|
|
expect(effect).toMatchObject({
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: {
|
|
id: ROM_ROGUE_CHAMPION_NERVE_GEAR_AURA_ID,
|
|
durationMs: ROM_ROGUE_CHAMPION_NERVE_GEAR_DURATION_MS,
|
|
maxStacks: ROM_ROGUE_CHAMPION_NERVE_GEAR_MAX_STACKS,
|
|
stackBehavior: "add",
|
|
modifiers: [
|
|
{ kind: "stat", stat: "attack-speed", operation: "flat", value: 5 },
|
|
{ kind: "stat", stat: "dodge", operation: "flat", value: 2 },
|
|
],
|
|
},
|
|
});
|
|
});
|
|
|
|
it("adds up to five stacks and refreshes the five-second duration", () => {
|
|
const effect = romRogueChampionNerveGearEffect();
|
|
if (effect.kind !== "apply-aura") throw new Error("Missing Nerve Gear aura.");
|
|
let auras: readonly ActiveAura[] = [];
|
|
for (let stack = 1; stack <= ROM_ROGUE_CHAMPION_NERVE_GEAR_MAX_STACKS + 2; stack += 1) {
|
|
auras = applyCombatAura(auras, {
|
|
definition: effect.aura,
|
|
sourceId: "rogue-actor",
|
|
targetId: "rogue-actor",
|
|
now: stack * 1_000,
|
|
}).auras;
|
|
}
|
|
expect(auras).toHaveLength(1);
|
|
expect(auras[0]).toMatchObject({
|
|
stacks: ROM_ROGUE_CHAMPION_NERVE_GEAR_MAX_STACKS,
|
|
appliedAt: 7_000,
|
|
expiresAt: 7_000 + ROM_ROGUE_CHAMPION_NERVE_GEAR_DURATION_MS,
|
|
definition: { id: ROM_ROGUE_CHAMPION_NERVE_GEAR_AURA_ID },
|
|
});
|
|
});
|
|
});
|