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,119 @@
|
||||
import { beforeEach, describe, expect, it } from "vitest";
|
||||
import { clearMobRuntimeRegistry, setMobPosition } from "./mobRuntimeRegistry";
|
||||
import { usePartyStore } from "./partyStore";
|
||||
import { createConfiguredPartyMember } from "./partyStore";
|
||||
import { EMPTY_ITEM_STATS } from "./itemStats";
|
||||
import { abilitiesForCharacter } from "./abilityCatalog";
|
||||
import { applyPartyRomCoaExhaustion } from "./partyRuntime";
|
||||
import { PLAYER_AGGRO_ID } from "./aggro";
|
||||
import { PLAYER_AURA_ENTITY_ID } from "./combatStore";
|
||||
import { stableCombatUnit, useCombatStore } from "./combatStore";
|
||||
import { ROM_LOCAL_ACTIVE_BLOCKING_STANCE_AURA_ID } from "./romWarriorCurrentCoaMechanics";
|
||||
|
||||
function stablePartyRoll(seed: string): number {
|
||||
let hash = 2166136261;
|
||||
for (const character of seed) {
|
||||
hash ^= character.charCodeAt(0);
|
||||
hash = Math.imul(hash, 16777619);
|
||||
}
|
||||
return (hash >>> 0) / 0x1_0000_0000;
|
||||
}
|
||||
|
||||
function registerTarget(id: string): void {
|
||||
useCombatStore.getState().registerMob(id, { name: id, level: 1, maxHealth: 50_000, xpReward: 0 });
|
||||
setMobPosition(id, [2, 0, 0]);
|
||||
useCombatStore.getState().selectMob(id);
|
||||
}
|
||||
|
||||
describe("current CoA Warrior mechanics runtime", () => {
|
||||
beforeEach(() => {
|
||||
clearMobRuntimeRegistry();
|
||||
useCombatStore.getState().initializeCharacter({
|
||||
classId: "rom-warrior", secondaryClassId: "rom-rogue", level: 50, xp: 0,
|
||||
});
|
||||
usePartyStore.getState().initializeParty("rom-warrior-coa-runtime", 50, useCombatStore.getState().health);
|
||||
useCombatStore.getState().setPlayerPosition([0, 0, 0]);
|
||||
});
|
||||
|
||||
it("awards Exhaustion resources on a seeded landed CoA Probing Attack and records capped resource events", () => {
|
||||
const targetId = "coa-probing-target";
|
||||
registerTarget(targetId);
|
||||
const state = useCombatStore.getState();
|
||||
const ability = state.abilities.find((candidate) => candidate.dbcSpellId === 493283);
|
||||
expect(ability).toBeDefined();
|
||||
useCombatStore.setState((current) => ({
|
||||
resource: 40,
|
||||
maxResource: 100,
|
||||
maxResourcePools: { ...current.maxResourcePools, rage: 100, energy: 100 },
|
||||
resourcePools: { ...current.resourcePools, rage: 40, energy: 0 },
|
||||
}));
|
||||
const now = Array.from({ length: 100 }, (_, index) => 1_000 + index * 1_000)
|
||||
.find((candidate) => stableCombatUnit(
|
||||
`${PLAYER_AGGRO_ID}:${ability!.id}:${targetId}:${candidate}:rom-coa-exhaustion`,
|
||||
) < 0.3)!;
|
||||
|
||||
expect(useCombatStore.getState().castAbility(ability!.id, { targetActorId: targetId, now }))
|
||||
.toMatchObject({ ok: true, affectedMobIds: [targetId] });
|
||||
const finalState = useCombatStore.getState();
|
||||
expect(finalState.resourcePools).toMatchObject({ energy: 25, rage: 70 });
|
||||
expect(finalState.combatEvents.filter((event) => event.kind === "resource" && event.abilityId === ability!.id))
|
||||
.toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ targetActorId: PLAYER_AURA_ENTITY_ID, rawAmount: 25, effectiveAmount: 25 }),
|
||||
expect.objectContaining({ targetActorId: PLAYER_AURA_ENTITY_ID, rawAmount: 50, effectiveAmount: 50 }),
|
||||
]));
|
||||
});
|
||||
|
||||
it("applies companion Exhaustion after a landed CoA Probing Attack and caps both resources", () => {
|
||||
const seed = "coa-probing-companion";
|
||||
const companion = createConfiguredPartyMember({
|
||||
name: "Warrior/Rogue",
|
||||
classId: "rom-warrior",
|
||||
secondaryClassId: "rom-rogue",
|
||||
raceId: "rom-dwarf",
|
||||
specialization: "Warrior/Rogue",
|
||||
role: "damage",
|
||||
}, 80, 0, seed);
|
||||
usePartyStore.getState().initializeParty(seed, 80, useCombatStore.getState().health, "damage", 2, "rom");
|
||||
usePartyStore.setState({ members: [{
|
||||
...companion,
|
||||
gearStats: EMPTY_ITEM_STATS,
|
||||
resourcePools: { ...companion.resourcePools, energy: 90, rage: 90 },
|
||||
}] });
|
||||
useCombatStore.getState().synchronizeActors();
|
||||
const probingAttack = abilitiesForCharacter("rom-warrior", "rom-rogue")
|
||||
.find((ability) => ability.dbcSpellId === 493283)!;
|
||||
const targetId = "coa-probing-companion-target";
|
||||
const now = Array.from({ length: 100 }, (_, index) => 10_000 + index)
|
||||
.find((candidate) => stablePartyRoll(
|
||||
`${companion.id}:${probingAttack.id}:${targetId}:${candidate}:rom-coa-exhaustion`,
|
||||
) < 0.3)!;
|
||||
const priorEventCount = useCombatStore.getState().combatEvents.length;
|
||||
|
||||
const updated = applyPartyRomCoaExhaustion(
|
||||
companion,
|
||||
probingAttack,
|
||||
true,
|
||||
`${companion.id}:${probingAttack.id}:${targetId}:${now}:rom-coa-exhaustion`,
|
||||
now,
|
||||
);
|
||||
|
||||
expect(updated.resourcePools).toMatchObject({ energy: 100, rage: 100 });
|
||||
expect(useCombatStore.getState().combatEvents.slice(priorEventCount).filter((event) => (
|
||||
event.kind === "resource" && event.sourceActorId === companion.id && event.abilityId === probingAttack.id
|
||||
))).toEqual(expect.arrayContaining([
|
||||
expect.objectContaining({ rawAmount: 25, effectiveAmount: 10 }),
|
||||
expect.objectContaining({ rawAmount: 50, effectiveAmount: 10 }),
|
||||
]));
|
||||
});
|
||||
|
||||
it("uses the Knight passive marker without carrying the retired active heal payload", () => {
|
||||
useCombatStore.getState().initializeCharacter({ classId: "rom-knight", level: 50, xp: 0 });
|
||||
const passive = useCombatStore.getState().abilities.find((candidate) => candidate.dbcSpellId === 490172);
|
||||
expect(passive).toMatchObject({ passive: true, target: "self", effects: [] });
|
||||
expect(passive?.description).toContain("198%");
|
||||
});
|
||||
|
||||
it("recognizes the local active stance separately from the current CoA passive marker", () => {
|
||||
expect(ROM_LOCAL_ACTIVE_BLOCKING_STANCE_AURA_ID).toBe("rom-aura-491480-502007-0-parry");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user