Update Healer Man server

This commit is contained in:
phenom committed 2026-09-20 11:23:13 -04:00
1 parent 1fedb9368d
commit cc3b2fa4d5
27 files changed
+1988 -83

No files matched your search

+155
View File
@@ -25,6 +25,10 @@ import { deriveCharacterStats, MANA_POOL_MULTIPLIER } from "./wotlkStats";
import { subscribeCombatPresentation, type CombatPresentationEvent } from "./combatPresentation";
import { loadCanonicalBenchmarkBuilds } from "./benchmark/benchmarkBuilds";
import { runtimePartyTalentRanksForLevel } from "./partyTalentRuntime";
import {
ROGUE_DEADLY_POISON_DOSE_TAG,
ROGUE_ENVENOM_BUFF_TAG,
} from "./roguePoison";
function allocateTalentRanks(name: string, ranks: number): void {
const talent = TALENT_NODES.find((node) => node.name === name);
@@ -667,6 +671,38 @@ describe("combat store", () => {
});
});
it("drops or redirects companion threat and immediately retargets the enemy", () => {
const tank = usePartyStore.getState().members.find((member) => member.role === "tank")!;
const damage = usePartyStore.getState().members.find((member) => member.role === "damage")!;
registerPartyRuntimePosition(tank.id, [0, 0, 0]);
registerPartyRuntimePosition(damage.id, [0, 0, 0]);
useCombatStore.getState().registerMob("threat-effect-boss", {
name: "Threat effect boss", boss: true, maxHealth: 1_000, xpReward: 0,
});
setMobPosition("threat-effect-boss", [2, 0, 0]);
useCombatStore.getState().damageMob("threat-effect-boss", 10, 1_000,
{ actorId: tank.id, role: "tank" });
useCombatStore.getState().damageMob("threat-effect-boss", 100, 1_100,
{ actorId: damage.id, role: "damage" });
useCombatStore.getState().applyActorThreatEffect(damage.id,
{ kind: "threat", mode: "percent", amount: -100 }, null, 1_200);
expect(useCombatStore.getState().mobs["threat-effect-boss"]).toMatchObject({
targetActorId: tank.id,
threatByActor: { [damage.id]: 0 },
});
useCombatStore.getState().damageMob("threat-effect-boss", 80, 1_300,
{ actorId: damage.id, role: "damage" });
const tankThreat = useCombatStore.getState().mobs["threat-effect-boss"].threatByActor[tank.id];
useCombatStore.getState().applyActorThreatEffect(damage.id,
{ kind: "threat", mode: "redirect", amount: 100 }, tank.id, 1_400);
expect(useCombatStore.getState().mobs["threat-effect-boss"].threatByActor).toMatchObject({
[damage.id]: 0,
[tank.id]: tankThreat + 80,
});
});
it("taunts bosses at max plus one, forces immediately, and resumes normal threat after expiry", () => {
const tank = usePartyStore.getState().members.find((member) => member.role === "tank")!;
registerPartyRuntimePosition(tank.id, [0, 0, 0]);
@@ -1518,6 +1554,125 @@ describe("combat store", () => {
expect(useCombatStore.getState()).toMatchObject(beforeFelVitality);
});
it("builds, refreshes, and consumes source-specific Deadly Poison doses", () => {
useCombatStore.getState().initializeCharacter({
classId: "rogue",
level: 80,
specializationId: "rogue:assassination",
talentRanks: runtimePartyTalentRanksForLevel("rogue", "Assassination", 80),
});
useCombatStore.getState().synchronizeActors();
registerTarget("poison-target", [2, 0, 0], 1_000_000, 0);
for (const abilityId of ["rogue-instant-poison", "rogue-deadly-poison"]) {
const ability = useCombatStore.getState().abilities.find((candidate) => candidate.id === abilityId)!;
const effect = ability.effects.find((candidate) => candidate.kind === "apply-aura")!;
expect(useCombatStore.getState().applyActorAura(
PLAYER_AURA_ENTITY_ID,
PLAYER_AURA_ENTITY_ID,
ability,
effect,
1_000,
)).toBe(true);
}
expect(useCombatStore.getState().triggerRogueWeaponPoisons(
PLAYER_AURA_ENTITY_ID,
"poison-target",
"wow335-rogue-shiv",
1,
1_001,
)).toMatchObject({ deadlyApplications: 1, deadlyStacks: 1 });
for (let hit = 0; hit < 200; hit += 1) {
useCombatStore.getState().triggerRogueWeaponPoisons(
PLAYER_AURA_ENTITY_ID,
"poison-target",
`test-hit-${hit}`,
1,
1_002 + hit,
);
}
const stacked = useCombatStore.getState();
expect(stacked.auras.find((aura) => (
aura.targetId === "poison-target"
&& aura.definition.utilityTags?.includes(ROGUE_DEADLY_POISON_DOSE_TAG)
))?.stacks).toBe(5);
expect(stacked.effects.find((effect) => (
effect.targetId === "poison-target" && effect.sourceAbilityId === "rogue-deadly-poison"
))).toMatchObject({ kind: "dot", remainingTicks: 4 });
expect(stacked.combatEvents.some((event) => (
event.abilityId === "rogue-instant-poison" && event.effectiveAmount > 0
))).toBe(true);
expect(useCombatStore.getState().consumeRogueDeadlyPoison(
PLAYER_AURA_ENTITY_ID,
"poison-target",
4,
2_000,
)).toBe(4);
expect(useCombatStore.getState().auras.find((aura) => (
aura.targetId === "poison-target"
&& aura.definition.utilityTags?.includes(ROGUE_DEADLY_POISON_DOSE_TAG)
))?.stacks).toBe(1);
expect(useCombatStore.getState().consumeRogueDeadlyPoison(
PLAYER_AURA_ENTITY_ID,
"poison-target",
5,
2_001,
)).toBe(1);
expect(useCombatStore.getState().effects.some((effect) => (
effect.targetId === "poison-target" && effect.sourceAbilityId === "rogue-deadly-poison"
))).toBe(false);
});
it("casts Envenom with dose-scaled Nature damage and a combo-scaled poison buff", () => {
useCombatStore.getState().initializeCharacter({
classId: "rogue",
level: 80,
specializationId: "rogue:assassination",
talentRanks: runtimePartyTalentRanksForLevel("rogue", "Assassination", 80),
});
useCombatStore.getState().synchronizeActors();
registerTarget("envenom-target", [2, 0, 0], 1_000_000, 0);
for (const abilityId of ["rogue-instant-poison", "rogue-deadly-poison"]) {
const ability = useCombatStore.getState().abilities.find((candidate) => candidate.id === abilityId)!;
const effect = ability.effects.find((candidate) => candidate.kind === "apply-aura")!;
useCombatStore.getState().applyActorAura(
PLAYER_AURA_ENTITY_ID,
PLAYER_AURA_ENTITY_ID,
ability,
effect,
1_000,
);
}
for (let hit = 0; hit < 200; hit += 1) {
useCombatStore.getState().triggerRogueWeaponPoisons(
PLAYER_AURA_ENTITY_ID,
"envenom-target",
`envenom-setup-${hit}`,
1,
1_001 + hit,
);
}
useCombatStore.setState({ comboPoints: 5, comboTargetId: "envenom-target" });
const envenom = useCombatStore.getState().abilities.find((ability) => ability.name === "Envenom")!;
const result = useCombatStore.getState().castAbility(envenom.id, [0, 0, 0], 3_000);
expect(result).toMatchObject({ ok: true, abilityId: envenom.id });
expect(result.damage).toBeGreaterThan(0);
expect(useCombatStore.getState().auras.find((aura) => (
aura.targetId === "envenom-target"
&& aura.definition.utilityTags?.includes(ROGUE_DEADLY_POISON_DOSE_TAG)
))?.stacks).toBe(5);
expect(useCombatStore.getState().auras.find((aura) => (
aura.targetId === PLAYER_AURA_ENTITY_ID
&& aura.definition.utilityTags?.includes(ROGUE_ENVENOM_BUFF_TAG)
))?.expiresAt).toBe(9_000);
expect(useCombatStore.getState().combatEvents.some((event) => (
event.abilityId === envenom.id && event.school === "nature" && event.effectiveAmount > 0
))).toBe(true);
});
it("applies Manastorm boss multipliers and a single bonus-loot chance at registration", () => {
useCombatStore.getState().initializeCharacter({ classId: "priest", level: 10 });
useCombatStore.getState().registerMob("storm-boss", {