forked from phenom/healer-man
Release Healer Man 0.1.9
This commit is contained in:
1 parent
c245a199b6
commit
d060296ade
74 files changed
+5901
-334
No files matched your search
@@ -22,6 +22,7 @@ import { abilitiesForClass, defaultActionBarForClass } from "./abilityCatalog";
|
||||
import { defaultActionBindings } from "./actionBindings";
|
||||
import { deriveCharacterStats } from "./wotlkStats";
|
||||
import { subscribeCombatPresentation, type CombatPresentationEvent } from "./combatPresentation";
|
||||
import { loadCanonicalBenchmarkBuilds } from "./benchmark/benchmarkBuilds";
|
||||
|
||||
function allocateTalentRanks(name: string, ranks: number): void {
|
||||
const talent = TALENT_NODES.find((node) => node.name === name);
|
||||
@@ -843,6 +844,7 @@ describe("combat store", () => {
|
||||
|
||||
it("allocates the first WotLK talent point at level 10 and clamps settings", () => {
|
||||
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 10 });
|
||||
expect(useCombatStore.getState().settings.masterVolume).toBe(0);
|
||||
const holy = talentNodesForTree("priest-holy")[0];
|
||||
const shadow = talentNodesForTree("priest-shadow")[0];
|
||||
expect(useCombatStore.getState().allocateTalent(holy.id)).toBe(true);
|
||||
@@ -869,12 +871,44 @@ describe("combat store", () => {
|
||||
showMobAggroRanges: true,
|
||||
threatMeterPosition: { x: 0, y: 1 },
|
||||
});
|
||||
useCombatStore.getState().updateSettings({
|
||||
gameplayFrameRate: 30,
|
||||
previewFrameRate: 15,
|
||||
});
|
||||
expect(useCombatStore.getState().settings).toMatchObject({
|
||||
gameplayFrameRate: 30,
|
||||
previewFrameRate: 15,
|
||||
});
|
||||
useCombatStore.getState().initializeCharacter({ classId: "priest" });
|
||||
expect(useCombatStore.getState().settings.showThreatMeter).toBe(false);
|
||||
useCombatStore.getState().initializeCharacter({
|
||||
classId: "priest",
|
||||
settings: { masterVolume: 0.6 },
|
||||
});
|
||||
expect(useCombatStore.getState().settings.masterVolume).toBe(0.6);
|
||||
useCombatStore.getState().resetSettings();
|
||||
expect(useCombatStore.getState().settings).toEqual(DEFAULT_GAMEPLAY_SETTINGS);
|
||||
});
|
||||
|
||||
it("does not notify subscribers for unchanged positions or settings", () => {
|
||||
let notifications = 0;
|
||||
const unsubscribe = useCombatStore.subscribe(() => {
|
||||
notifications += 1;
|
||||
});
|
||||
|
||||
useCombatStore.getState().setPlayerPosition([0, 0, 0]);
|
||||
useCombatStore.getState().updateSettings({
|
||||
masterVolume: DEFAULT_GAMEPLAY_SETTINGS.masterVolume,
|
||||
gameplayFrameRate: DEFAULT_GAMEPLAY_SETTINGS.gameplayFrameRate,
|
||||
});
|
||||
useCombatStore.getState().resetSettings();
|
||||
expect(notifications).toBe(0);
|
||||
|
||||
useCombatStore.getState().updateSettings({ gameplayFrameRate: 30 });
|
||||
expect(notifications).toBe(1);
|
||||
unsubscribe();
|
||||
});
|
||||
|
||||
it("keeps a CoA tree ability uncastable until its exact node is purchased", () => {
|
||||
useCombatStore.getState().initializeCharacter({ classId: "stormbringer", level: 60 });
|
||||
const ability = abilitiesForClass("stormbringer").find((candidate) => (
|
||||
@@ -897,6 +931,40 @@ describe("combat store", () => {
|
||||
expect(useCombatStore.getState().castAbility(ability.id, [0, 0, 0], 3_000).reason).not.toBe("not-learned");
|
||||
});
|
||||
|
||||
it("breaks recursive hit-proc spell cycles in the canonical Felsworn tank build", async () => {
|
||||
const build = (await loadCanonicalBenchmarkBuilds(60, ["felsworn"]))
|
||||
.find((candidate) => candidate.role === "tank")!;
|
||||
useCombatStore.getState().initializeCharacter({
|
||||
classId: build.classId,
|
||||
level: build.level,
|
||||
talentRanks: build.talentRanks,
|
||||
});
|
||||
registerTarget("felsworn-proc-dummy", [10, 0, 0], 1_000_000, 0);
|
||||
|
||||
expect(useCombatStore.getState().auras).toContainEqual(expect.objectContaining({
|
||||
definition: expect.objectContaining({ name: "Doomstride (Aura 42)" }),
|
||||
}));
|
||||
const result = useCombatStore.getState().castAbility(
|
||||
"felsworn-sargeron-smite",
|
||||
[0, 0, 0],
|
||||
1,
|
||||
);
|
||||
const state = useCombatStore.getState();
|
||||
const damage = 1_000_000 - state.mobs["felsworn-proc-dummy"].health;
|
||||
const damageAbilityIds = state.combatEvents
|
||||
.filter((event) => event.kind === "damage")
|
||||
.map((event) => event.abilityId);
|
||||
|
||||
expect(result.ok).toBe(true);
|
||||
expect(damage).toBeGreaterThan(0);
|
||||
expect(damage).toBeLessThan(100_000);
|
||||
expect(damageAbilityIds.filter((abilityId) => abilityId === "coa-triggered-807962"))
|
||||
.toHaveLength(1);
|
||||
expect(state.auras).toContainEqual(expect.objectContaining({
|
||||
definition: expect.objectContaining({ name: "Felwracked (Aura 4)" }),
|
||||
}));
|
||||
});
|
||||
|
||||
it("resets encounter health without erasing earned progression", () => {
|
||||
registerTarget("mob", [2, 0, 0], 1, 100);
|
||||
useCombatStore.getState().damageMob("mob", 5, 1000);
|
||||
|
||||
Reference in new issue
Block a user