forked from phenom/healer-man
Update Healer Man server
This commit is contained in:
1 parent
4c768fbec6
commit
b16821e92e
330 files changed
+35406
-1760
No files matched your search
@@ -0,0 +1,97 @@
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
|
||||
import { clearPartyRuntimeRegistry } from "./partyRuntimeRegistry";
|
||||
import { PLAYER_AGGRO_ID } from "./aggro";
|
||||
import { useCombatStore } from "./combatStore";
|
||||
import { usePartyStore } from "./partyStore";
|
||||
import { abilityById } from "./abilityCatalog";
|
||||
|
||||
function registerFrozenTestTarget(id: string, now: number, frozen: boolean): void {
|
||||
useCombatStore.getState().registerMob(id, { name: id, maxHealth: 100_000, xpReward: 0 });
|
||||
setMobPosition(id, [8, 0, 0]);
|
||||
if (!frozen) return;
|
||||
useCombatStore.setState((state) => {
|
||||
const target = state.mobs[id]!;
|
||||
return {
|
||||
mobs: {
|
||||
...state.mobs,
|
||||
[id]: {
|
||||
...target,
|
||||
statuses: [{ kind: "freeze", sourceAbilityId: "shatter-test-freeze", endsAt: now + 5_000 }],
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
function spellCritPercent(targetId: string, abilityId: string, now: number, periodic = false, sourceActorId?: string): number {
|
||||
const member = sourceActorId
|
||||
? usePartyStore.getState().members.find((candidate) => candidate.id === sourceActorId)
|
||||
: null;
|
||||
useCombatStore.getState().damageMob(targetId, 100, now, sourceActorId && member ? {
|
||||
actorId: sourceActorId,
|
||||
role: member.role,
|
||||
abilityId,
|
||||
} : { actorId: PLAYER_AGGRO_ID, role: "damage", abilityId }, "frost", {
|
||||
attackKind: "spell",
|
||||
seed: `mage-shatter-${sourceActorId ?? "player"}-${targetId}-${now}`,
|
||||
abilityId,
|
||||
periodic,
|
||||
rules: { canMiss: false, canCrit: true, canDodge: false, canParry: false, canBlock: false },
|
||||
});
|
||||
return useCombatStore.getState().lastCombatResult!.attackTable.criticalPercent;
|
||||
}
|
||||
|
||||
describe("WoW Mage Shatter combat integration", () => {
|
||||
beforeEach(() => {
|
||||
clearMobRuntimeRegistry();
|
||||
clearPartyRuntimeRegistry();
|
||||
useCombatStore.getState().initializeCharacter({ classId: "mage", level: 80, xp: 0 });
|
||||
usePartyStore.getState().initializeParty("mage-shatter-tests", 1, useCombatStore.getState().health);
|
||||
});
|
||||
|
||||
it("adds the generated rank bonus only for nonperiodic Mage spells against a frozen target", () => {
|
||||
const fireball = useCombatStore.getState().abilities.find((ability) => ability.name === "Fireball")!;
|
||||
useCombatStore.setState((state) => ({
|
||||
talentRanks: { ...state.talentRanks, "talent-67": 3 },
|
||||
}));
|
||||
|
||||
registerFrozenTestTarget("shatter-unfrozen", 1_000, false);
|
||||
const unfrozenCrit = spellCritPercent("shatter-unfrozen", fireball.id, 1_000);
|
||||
|
||||
registerFrozenTestTarget("shatter-frozen", 2_000, true);
|
||||
const frozenCrit = spellCritPercent("shatter-frozen", fireball.id, 2_000);
|
||||
const periodicCrit = spellCritPercent("shatter-frozen", fireball.id, 3_000, true);
|
||||
|
||||
expect(frozenCrit - unfrozenCrit).toBe(50);
|
||||
expect(periodicCrit).toBe(unfrozenCrit);
|
||||
});
|
||||
|
||||
it("uses the party Mage's own Shatter rank against frozen targets", () => {
|
||||
const fireball = abilityById("wow335-mage-fireball")!;
|
||||
const member = usePartyStore.getState().members[0]!;
|
||||
usePartyStore.setState((state) => ({
|
||||
members: state.members.map((candidate) => candidate.id === member.id ? {
|
||||
...candidate,
|
||||
classId: "mage",
|
||||
talentRanks: {},
|
||||
resourceType: "mana",
|
||||
resourceName: "Mana",
|
||||
maxResource: 10_000,
|
||||
resource: 9_000,
|
||||
resourcePools: { ...candidate.resourcePools, mana: 9_000 },
|
||||
} : candidate),
|
||||
}));
|
||||
registerFrozenTestTarget("party-shatter-frozen", 1_000, true);
|
||||
const baselineCrit = spellCritPercent("party-shatter-frozen", fireball.id, 1_000, false, member.id);
|
||||
usePartyStore.setState((state) => ({
|
||||
members: state.members.map((candidate) => candidate.id === member.id ? {
|
||||
...candidate,
|
||||
talentRanks: { "talent-67": 2 },
|
||||
} : candidate),
|
||||
}));
|
||||
const partyCrit = spellCritPercent("party-shatter-frozen", fireball.id, 2_000, false, member.id);
|
||||
|
||||
expect(partyCrit - baselineCrit).toBe(34);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user