import { beforeEach, describe, expect, it } from "vitest"; import { PLAYER_AGGRO_ID } from "./aggro"; import { preloadAbilityCatalogsForClasses } from "./abilityCatalog"; import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry"; import { clearPartyRuntimeRegistry } from "./partyRuntimeRegistry"; import { useCombatStore } from "./combatStore"; import { usePartyStore } from "./partyStore"; function soulshatterId(): string { const ability = useCombatStore.getState().abilities.find((candidate) => candidate.name === "Soulshatter"); expect(ability, "Soulshatter").toBeDefined(); return ability!.id; } function setPlayerThreat(id: string, amount: number): void { useCombatStore.setState((state) => ({ mobs: { ...state.mobs, [id]: { ...state.mobs[id], threatByActor: { ...state.mobs[id].threatByActor, [PLAYER_AGGRO_ID]: amount }, }, }, })); } describe("WoW 3.3.5 Warlock Soulshatter runtime", () => { beforeEach(async () => { clearMobRuntimeRegistry(); clearPartyRuntimeRegistry(); await preloadAbilityCatalogsForClasses(["warlock"]); useCombatStore.getState().initializeCharacter({ classId: "warlock", level: 80 }); useCombatStore.getState().resetSettings(); useCombatStore.getState().setPlayerPosition([0, 0, 0]); usePartyStore.getState().initializeParty("wow335-warlock-soulshatter-tests", 1, useCombatStore.getState().health); }); it("cuts threat in half inside the caster's 50-yard radius and leaves outside enemies alone", () => { useCombatStore.getState().registerMob("soulshatter-inside", { name: "Inside", maxHealth: 10_000 }); useCombatStore.getState().registerMob("soulshatter-outside", { name: "Outside", maxHealth: 10_000 }); setMobPosition("soulshatter-inside", [20, 0, 0]); setMobPosition("soulshatter-outside", [60, 0, 0]); setPlayerThreat("soulshatter-inside", 100); setPlayerThreat("soulshatter-outside", 100); const cast = useCombatStore.getState().castAbility(soulshatterId(), undefined, 1_000); expect(cast).toMatchObject({ ok: true, affectedMobIds: ["soulshatter-inside"] }); expect(useCombatStore.getState().mobs["soulshatter-inside"].threatByActor[PLAYER_AGGRO_ID]).toBe(50); expect(useCombatStore.getState().mobs["soulshatter-outside"].threatByActor[PLAYER_AGGRO_ID]).toBe(100); }); it("does not reduce distant enemies when nobody is within the caster-centered radius", () => { useCombatStore.getState().registerMob("soulshatter-far", { name: "Far", maxHealth: 10_000 }); setMobPosition("soulshatter-far", [60, 0, 0]); setPlayerThreat("soulshatter-far", 100); const cast = useCombatStore.getState().castAbility(soulshatterId(), undefined, 1_000); expect(cast).toMatchObject({ ok: true, affectedMobIds: [] }); expect(useCombatStore.getState().mobs["soulshatter-far"].threatByActor[PLAYER_AGGRO_ID]).toBe(100); }); });