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

+39 -1
View File
@@ -37,6 +37,7 @@ import { usePartyStore, type PartyCommand, type PartyMember } from "./partyStore
import { baseClassFor, classById } from "../app/characterCatalog";
import { useGameStore } from "./store";
import { useManastormStore } from "./manastormStore";
import { WOW335_GLYPH_OF_SWIFTMEND_ID } from "./wow335GlyphCatalog";
import { activeDungeonCompletedObjectiveIds } from "./dungeonEncounterRuntime";
import { PLAYER_AGGRO_ID, type ThreatSource } from "./aggro";
import {
@@ -296,6 +297,24 @@ function partyShamanRiptideHotOnTarget(memberId: string, targetId: string, now:
&& effect.nextTickAt + Math.max(0, effect.remainingTicks - 1) * effect.intervalMs > now);
}
function partySwiftmendHotOnTarget(memberId: string, targetId: string, now: number) {
const candidates = useCombatStore.getState().effects.filter((effect) => {
if (effect.kind !== "hot" || (effect.targetId ?? PLAYER_AGGRO_ID) !== targetId
|| effect.remainingTicks <= 0
|| effect.nextTickAt + Math.max(0, effect.remainingTicks - 1) * effect.intervalMs <= now) return false;
const name = abilityById(effect.sourceAbilityId)?.name;
return name === "Rejuvenation" || name === "Regrowth";
});
const own = candidates.filter((effect) => effect.sourceActorId === memberId);
const pool = own.length ? own : candidates;
return pool.reduce<typeof pool[number] | undefined>((shortest, candidate) => {
if (!shortest) return candidate;
const expiry = candidate.nextTickAt + Math.max(0, candidate.remainingTicks - 1) * candidate.intervalMs;
const shortestExpiry = shortest.nextTickAt + Math.max(0, shortest.remainingTicks - 1) * shortest.intervalMs;
return expiry < shortestExpiry ? candidate : shortest;
}, undefined);
}
function maybeProcPartyShamanImprovedWaterShield(
member: PartyMember,
ability: AbilityDefinition,
@@ -1349,6 +1368,8 @@ export function partyAbilityTargetIsValid(
.flatMap((aura) => aura.definition.utilityTags ?? []);
if (!romPriestWarriorStanceUseAllowed(ability, activeAuraTags)) return false;
}
if (member.classId === "druid" && ability.name === "Swiftmend"
&& !partySwiftmendHotOnTarget(member.id, targetId, now)) return false;
if (member.classId === "warlock") {
const metamorphosisActive = combat.auras.some((aura) => aura.targetId === member.id
&& aura.definition.utilityTags?.includes(WOW335_WARLOCK_METAMORPHOSIS_AURA_TAG)
@@ -2186,6 +2207,18 @@ function executePartyAbility(
&& targetIndex === 0
? partyShamanRiptideHotOnTarget(member.id, friendlyTargetId, now)
: undefined;
const swiftmendHot = member.classId === "druid" && ability.name === "Swiftmend"
? partySwiftmendHotOnTarget(member.id, friendlyTargetId, now)
: undefined;
const swiftmendHotAbility = swiftmendHot ? abilityById(swiftmendHot.sourceAbilityId) : null;
const swiftmendHotEffect = swiftmendHotAbility?.effects.find((candidate) => candidate.kind === "hot");
const swiftmendTickCount = swiftmendHotAbility?.name === "Rejuvenation" ? 4
: swiftmendHotAbility?.name === "Regrowth" ? 6
: 0;
const swiftmendAmount = swiftmendHot && swiftmendHotAbility && swiftmendHotEffect?.kind === "hot"
? (swiftmendHot.fixedAmount ?? partyAbilityAmount(runtimeMember, swiftmendHotAbility, swiftmendHotEffect))
* swiftmendTickCount
: null;
if (riptideHot) {
useCombatStore.setState((state) => ({
effects: state.effects.filter((candidate) => candidate.id !== riptideHot.id),
@@ -2196,7 +2229,7 @@ function executePartyAbility(
const healingSchool = member.classId === "shaman"
? abilityDamageSchool("shaman", ability)
: spellSchool;
const requested = Math.round((partyAbilityAmount(runtimeMember, ability, effect)
const requested = Math.round(((swiftmendAmount ?? partyAbilityAmount(runtimeMember, ability, effect))
+ tidalWavesBonus
+ Math.round(actor.maxHealth * (effect.percentMaxHealth ?? 0)))
* (riptideHot ? PARTY_SHAMAN_RIPTIDE_CHAIN_HEAL_MULTIPLIER : 1));
@@ -2208,6 +2241,11 @@ function executePartyAbility(
seed: `${member.id}:${ability.id}:${friendlyTargetId}:${now}:heal`,
now,
});
if (swiftmendHot && !runtimeMember.glyphIds?.includes(WOW335_GLYPH_OF_SWIFTMEND_ID)) {
useCombatStore.setState((state) => ({
effects: state.effects.filter((candidate) => candidate.id !== swiftmendHot.id),
}));
}
effectiveAmount += result.effectiveAmount;
directHealingRawAmount += result.rawAmount;
runtimeMember = maybeProcPartyShamanImprovedWaterShield(