Files
healer-man/src/game/wow335ShamanisticRageRuntime.test.ts
T
2026-09-28 22:46:45 -04:00

78 lines
3.7 KiB
TypeScript

import { beforeEach, describe, expect, it } from "vitest";
import { abilityTalentNodeId } from "./abilityCatalog";
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
import { clearPartyRuntimeRegistry } from "./partyRuntimeRegistry";
import { PLAYER_AURA_ENTITY_ID, useCombatStore } from "./combatStore";
import { usePartyStore } from "./partyStore";
function unlockShamanTalent(abilityName: string): string {
const ability = useCombatStore.getState().abilities.find((candidate) => candidate.name === abilityName);
expect(ability, abilityName).toBeDefined();
const nodeId = abilityTalentNodeId(ability!);
expect(nodeId, abilityName).toBeTruthy();
useCombatStore.setState((state) => ({ talentRanks: { ...state.talentRanks, [nodeId!]: 1 } }));
return ability!.id;
}
describe("WoW Shaman Shamanistic Rage source proc", () => {
beforeEach(() => {
clearMobRuntimeRegistry();
clearPartyRuntimeRegistry();
useCombatStore.getState().initializeCharacter({ classId: "shaman", level: 80, xp: 0 });
useCombatStore.getState().resetSettings();
useCombatStore.getState().setPlayerPosition([0, 0, 0]);
usePartyStore.getState().initializeParty("wow-shamanistic-rage-runtime-tests", 1, useCombatStore.getState().health);
useCombatStore.getState().registerMob("shamanistic-rage-target", { name: "Shamanistic Rage target", maxHealth: 100_000, xpReward: 0 });
setMobPosition("shamanistic-rage-target", [2, 0, 0]);
useCombatStore.getState().selectMob("shamanistic-rage-target");
});
it("restores 15% attack power as mana on landed melee hits for the 15-second aura window", () => {
const rageId = unlockShamanTalent("Shamanistic Rage");
const rageAbility = useCombatStore.getState().abilities.find((candidate) => candidate.id === rageId);
expect(rageAbility?.dbcSpellId).toBe(30823);
useCombatStore.setState((state) => ({
resource: 300,
resourcePools: { ...state.resourcePools, mana: 300 },
}));
const rageCast = useCombatStore.getState().castAbility(rageId, undefined, 1_000);
expect(rageCast.ok).toBe(true);
const aura = useCombatStore.getState().auras.find((candidate) => (
candidate.targetId === PLAYER_AURA_ENTITY_ID
&& candidate.definition.procs?.some((proc) => proc.action.kind === "custom"
&& proc.action.id === "wow335-shamanistic-rage-mana")
));
expect(aura).toBeDefined();
expect(aura?.expiresAt).toBe(16_000);
for (let now = 3_000; now < 16_000; now += 2_500) {
useCombatStore.setState({ autoAttackTargetId: "shamanistic-rage-target", nextAutoAttackAt: now });
useCombatStore.getState().tick(0.1, now);
if (useCombatStore.getState().combatEvents.some((event) => (
event.kind === "resource" && event.abilityId === rageId && event.effectiveAmount > 0
))) break;
}
const afterMelee = useCombatStore.getState();
expect(afterMelee.resourcePools.mana).toBeGreaterThan(0);
expect(afterMelee.combatEvents.some((event) => (
event.kind === "resource"
&& event.abilityId === rageId
&& event.effectiveAmount > 0
))).toBe(true);
const rageRestoresBeforeExpiry = afterMelee.combatEvents.filter((event) => (
event.kind === "resource" && event.abilityId === rageId
)).length;
useCombatStore.setState({
autoAttackTargetId: "shamanistic-rage-target",
nextAutoAttackAt: 20_000,
});
useCombatStore.getState().tick(0.1, 20_000);
expect(useCombatStore.getState().auras.some((entry) => entry.instanceId === aura?.instanceId)).toBe(false);
expect(useCombatStore.getState().combatEvents.filter((event) => (
event.kind === "resource" && event.abilityId === rageId
))).toHaveLength(rageRestoresBeforeExpiry);
});
});