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 }, }); }); });