Files
healer-man/src/game/romRogueChampionNerveGear.integration.test.ts
T
2026-09-30 09:57:13 -04:00

117 lines
4.6 KiB
TypeScript

import { beforeEach, describe, expect, it } from "vitest";
import { PLAYER_AGGRO_ID } from "./aggro";
import { abilitiesForCharacter, abilityById } from "./abilityCatalog";
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
import { useCombatStore } from "./combatStore";
import {
advanceDungeonPartyCombat,
resetPartyRuntimeClock,
} from "./partyRuntime";
import {
clearPartyRuntimeRegistry,
registerPartyRuntimePosition,
updatePartyRuntimeTargetVisibility,
} from "./partyRuntimeRegistry";
import { createConfiguredPartyMember, usePartyStore } from "./partyStore";
import {
ROM_ROGUE_CHAMPION_NERVE_GEAR_AURA_ID,
ROM_ROGUE_CHAMPION_NERVE_GEAR_MARKER_TAG,
} from "./romRogueChampionNerveGearRuntime";
const ELITE_ABILITY_ID = "rom-rogue-rom-champion-elite-30";
function nerveGearAura(actorId: string) {
return useCombatStore.getState().auras.find((aura) => (
aura.sourceId === actorId
&& aura.targetId === actorId
&& aura.definition.id === ROM_ROGUE_CHAMPION_NERVE_GEAR_AURA_ID
));
}
describe("RoM Rogue/Champion Nerve Gear cast integration", () => {
beforeEach(() => {
clearMobRuntimeRegistry();
clearPartyRuntimeRegistry();
resetPartyRuntimeClock();
useCombatStore.getState().initializeCharacter({ classId: "mage", level: 50, xp: 0 });
usePartyStore.getState().initializeParty("rom-rogue-champion-nerve-gear-tests", 50,
useCombatStore.getState().health);
});
it("grants one stack to a learned player Rogue/Champion after one elite cast", () => {
useCombatStore.getState().initializeCharacter({
classId: "rom-rogue", secondaryClassId: "rom-champion", level: 50, xp: 0,
});
useCombatStore.setState((state) => ({
resourcePools: { ...state.resourcePools, energy: 100, rage: 100 },
maxResourcePools: { ...state.maxResourcePools, energy: 100, rage: 100 },
}));
const ability = abilityById(ELITE_ABILITY_ID)!;
const marker = abilityById("rom-rogue-rom-champion-elite-50")!.effects.find((effect) => (
effect.kind === "apply-aura" && effect.aura.utilityTags?.includes(ROM_ROGUE_CHAMPION_NERVE_GEAR_MARKER_TAG)
));
expect(marker).toBeDefined();
expect(nerveGearAura(PLAYER_AGGRO_ID)).toBeUndefined();
const result = useCombatStore.getState().castAbility(ability.id, undefined, 1_000);
expect(result, JSON.stringify(result)).toMatchObject({ ok: true });
expect(nerveGearAura(PLAYER_AGGRO_ID)).toMatchObject({
appliedAt: 1_000,
expiresAt: 6_000,
stacks: 1,
definition: { id: ROM_ROGUE_CHAMPION_NERVE_GEAR_AURA_ID },
});
});
it("grants one stack to the party Rogue/Champion at cast scope for an area skill", () => {
const seed = "rom-rogue-champion-nerve-gear-party";
const member = createConfiguredPartyMember({
name: "Rogue companion",
classId: "rom-rogue",
secondaryClassId: "rom-champion",
specialization: "Primary",
role: "damage",
}, 50, 0, seed);
const selectedAbility = abilityById(ELITE_ABILITY_ID)!;
const lockedCooldowns = Object.fromEntries(abilitiesForCharacter("rom-rogue", "rom-champion")
.filter((ability) => ability.id !== selectedAbility.id)
.map((ability) => [ability.id, 50_000]));
usePartyStore.getState().initializeParty(seed, 50, useCombatStore.getState().health, "damage", 1, "rom");
usePartyStore.setState({ members: [{
...member,
nextActionAt: 100,
status: "attacking",
resource: 100,
resourcePools: { ...member.resourcePools, energy: 100, rage: 100 },
cooldowns: lockedCooldowns,
}] });
registerPartyRuntimePosition(member.id, [0, 0, 0]);
useCombatStore.getState().synchronizeActors();
const primaryTargetId = "nerve-gear-party-target-a";
const secondaryTargetId = "nerve-gear-party-target-b";
for (const targetId of [primaryTargetId, secondaryTargetId]) {
useCombatStore.getState().registerMob(targetId, { name: targetId, maxHealth: 10_000, xpReward: 0 });
setMobPosition(targetId, [2, 0, 0]);
useCombatStore.getState().damageMob(targetId, 1, 100);
updatePartyRuntimeTargetVisibility(member.id, targetId, true);
}
useCombatStore.getState().selectMob(primaryTargetId);
usePartyStore.setState((party) => ({
command: "attack",
activeMobId: primaryTargetId,
members: party.members.map((entry) => (
entry.id === member.id ? { ...entry, globalCooldownEndsAt: 0, nextActionAt: 0 } : entry
)),
}));
advanceDungeonPartyCombat(1_000);
expect(nerveGearAura(member.id)).toMatchObject({
appliedAt: 1_000,
expiresAt: 6_000,
stacks: 1,
definition: { id: ROM_ROGUE_CHAMPION_NERVE_GEAR_AURA_ID },
});
});
});