Update class mechanics, stat rulesets, and CoA reference catalogs

This commit is contained in:
phenom committed 2026-10-04 12:56:30 -04:00
1 parent b16821e92e
commit 39458d5de6
221 files changed
+2584962 -568

No files matched your search

@@ -0,0 +1,83 @@
import { beforeEach, describe, expect, it } from "vitest";
import { abilitiesForCharacter } from "./abilityCatalog";
import { useCombatStore, stableCombatUnit } from "./combatStore";
import { ROM_PRIEST_CHAMPION_REGENERATE_PROC_AURA_ID } from "./romPriestChampionOverrides";
import { createConfiguredPartyMember, usePartyStore } from "./partyStore";
import { advanceDungeonPartyCombat, resetPartyRuntimeClock } from "./partyRuntime";
import { clearPartyRuntimeRegistry, registerPartyRuntimePosition } from "./partyRuntimeRegistry";
describe("RoM Priest/Champion Protection Rune Seal companion reset", () => {
beforeEach(() => {
clearPartyRuntimeRegistry();
resetPartyRuntimeClock();
useCombatStore.getState().initializeCharacter({
classId: "rom-warrior", raceId: "rom-human", level: 80,
});
usePartyStore.getState().initializeParty("priest-protection-rune-seal", 80,
useCombatStore.getState().health, "damage", 1, "rom");
});
it("resets only its Priest/Champion owner's Heart Rune Energy on a successful Regenerate heal tick", () => {
const member = createConfiguredPartyMember({
name: "Priest Champion",
classId: "rom-priest",
secondaryClassId: "rom-champion",
specialization: "Healer",
role: "healer",
talentRanks: {},
}, 80, 0, "protection-rune-seal");
const abilities = abilitiesForCharacter(member.classId, member.secondaryClassId);
const regenerate = abilities.find((ability) => ability.dbcSpellId === 490_269)!;
const heartRuneEnergy = abilities.find((ability) => ability.dbcSpellId === 498_612)!;
const unrelatedCooldowns = { ...member.cooldowns, [heartRuneEnergy.id]: 33_333 };
const readyAtFirstTick = {
...member,
cooldowns: unrelatedCooldowns,
activeCast: {
abilityId: regenerate.id,
school: "nature" as const,
mode: "cast" as const,
startedAt: 1_000,
completesAt: 1_000,
originalDurationMs: 0,
pushbackHits: 0,
origin: [0, 0, 0] as const,
targetId: member.id,
},
activeCastTargetId: member.id,
status: "healing" as const,
};
usePartyStore.setState({ members: [readyAtFirstTick] });
useCombatStore.setState((state) => ({
cooldowns: { ...state.cooldowns, [heartRuneEnergy.id]: 22_222 },
}));
registerPartyRuntimePosition(member.id, [0, 0, 0]);
useCombatStore.getState().synchronizeActors();
advanceDungeonPartyCombat(1_000);
const protectionAura = useCombatStore.getState().auras.find((aura) => (
aura.definition.id === ROM_PRIEST_CHAMPION_REGENERATE_PROC_AURA_ID
));
expect(protectionAura).toMatchObject({ sourceId: member.id, targetId: member.id });
const hot = useCombatStore.getState().effects.find((effect) => (
effect.kind === "hot" && effect.sourceActorId === member.id && effect.sourceAbilityId === regenerate.id
));
expect(hot).toBeDefined();
const partyCooldown = () => usePartyStore.getState().members
.find((candidate) => candidate.id === member.id)!.cooldowns[heartRuneEnergy.id];
expect(partyCooldown()).toBe(33_333);
useCombatStore.getState().tick(0, 2_999);
expect(partyCooldown()).toBe(33_333);
// The actor-owned proc rolls below the established local 8% boundary at this first tick.
expect(stableCombatUnit(
`${protectionAura!.instanceId}:rom-priest-protection-rune-seal-reset:periodic:${regenerate.id}:${member.id}:3000`,
)).toBeLessThan(0.08);
useCombatStore.getState().tick(0, 3_000);
expect(partyCooldown()).toBe(0);
expect(useCombatStore.getState().cooldowns[heartRuneEnergy.id]).toBe(22_222);
});
});