Update Healer Man server

This commit is contained in:
phenom committed 2026-09-30 13:25:55 -04:00
1 parent 4fb7a0b9c8
commit 4c768fbec6
24 files changed
+654 -22

No files matched your search

+68 -1
View File
@@ -23,10 +23,11 @@ import { createConfiguredPartyMember, usePartyStore } from "./partyStore";
import { EMPTY_ITEM_STATS } from "./itemStats";
import { subscribeCombatPresentation, type CombatPresentationEvent } from "./combatPresentation";
import { subscribeCombatEvents, type StructuredCombatEvent } from "./combatEvents";
import { abilitiesForClass, abilityAtLevel } from "./abilityCatalog";
import { abilitiesForClass, abilityAtLevel, abilityTalentNodeId } from "./abilityCatalog";
import { runtimePartyTalentRanksForLevel } from "./partyTalentRuntime";
import { channelPulseAt, channelPulseCount } from "./combatChannelAmounts";
import { baseClassFor } from "../app/characterCatalog";
import { WOW335_GLYPH_OF_SWIFTMEND_ID } from "./wow335GlyphCatalog";
function registerEngagedMob(id = "pack:a", maxHealth = 200): void {
useCombatStore.getState().registerMob(id, { name: id, maxHealth, xpReward: 0 });
@@ -130,6 +131,72 @@ describe("party combat runtime", () => {
expect(effects.find(effect => effect.targetId === first.targetId)?.nextTickAt).toBe(first.nextTickAt);
});
it.each([false, true])("companion Swiftmend preserves the HoT only with the configured glyph (%s)", (glyphActive) => {
useCombatStore.getState().initializeCharacter({ classId: "mage", role: "damage", level: 80 });
const druidAbilities = abilitiesForClass("druid");
const swiftmendBase = druidAbilities.find((ability) => ability.name === "Swiftmend")!;
const swiftmendNodeId = abilityTalentNodeId(swiftmendBase)!;
const swiftmend = abilityAtLevel(swiftmendBase, 80);
const rejuvenation = abilityAtLevel(druidAbilities.find((ability) => ability.name === "Rejuvenation")!, 80);
const rejuvenationHot = rejuvenation.effects.find((effect) => effect.kind === "hot")!;
const druid = createConfiguredPartyMember({
name: "Configured Druid",
classId: "druid",
specialization: "Restoration",
specializationId: "druid:restoration",
talentTreeId: "druid-restoration",
talentRanks: { [swiftmendNodeId]: 1 },
glyphIds: glyphActive ? [WOW335_GLYPH_OF_SWIFTMEND_ID] : [],
role: "healer",
}, 80, 0, "party-swiftmend-glyph");
const target = createConfiguredPartyMember({
name: "Injured Tank",
classId: "warrior",
specialization: "Protection",
specializationId: "warrior:protection",
talentTreeId: "warrior-protection",
role: "tank",
}, 80, 1, "party-swiftmend-glyph");
const startedAt = 1_000;
usePartyStore.getState().initializeParty("party-swiftmend-glyph", 80,
useCombatStore.getState().health, "damage");
usePartyStore.setState({ members: [
{ ...target, health: 100 },
{
...druid,
activeCast: {
abilityId: swiftmend.id,
school: "nature",
mode: "cast",
startedAt,
completesAt: startedAt,
originalDurationMs: 0,
pushbackHits: 0,
origin: [0, 0, 0],
targetId: target.id,
},
activeCastTargetId: target.id,
status: "healing",
},
] });
registerPartyRuntimePosition(druid.id, [0, 0, 0]);
registerPartyRuntimePosition(target.id, [0, 0, 0]);
useCombatStore.getState().synchronizeActors();
expect(useCombatStore.getState().applyTimedActorEffect(
druid.id, target.id, rejuvenation, rejuvenationHot, startedAt,
)).toBe(true);
const originalHot = useCombatStore.getState().effects.find((effect) => (
effect.kind === "hot" && effect.sourceActorId === druid.id && effect.targetId === target.id
))!;
advanceDungeonPartyCombat(startedAt);
expect(useCombatStore.getState().actors[target.id]!.health).toBeGreaterThan(100);
expect(useCombatStore.getState().effects.some((effect) => effect.id === originalHot.id)).toBe(glyphActive);
expect(usePartyStore.getState().members.find((member) => member.id === druid.id)?.glyphIds)
.toEqual(glyphActive ? [WOW335_GLYPH_OF_SWIFTMEND_ID] : []);
});
it("refreshes a companion Priest's Shadow Word: Pain from its own completed Mind Blast", () => {
useCombatStore.getState().initializeCharacter({ classId: "mage", role: "damage", level: 80 });
const priest = createConfiguredPartyMember({