Update Healer Man server

This commit is contained in:
phenom committed 2026-09-28 22:46:45 -04:00
1 parent 9d7e0e2f9e
commit 35dfdaed61
94 files changed
+17034 -418

No files matched your search

+40 -3
View File
@@ -69,8 +69,14 @@ export type AuraModifier =
export interface AuraAbsorbDefinition {
readonly id: string;
readonly amount: number;
/** Number of matching attacks this absorb fully negates instead of consuming a point pool. */
readonly hitCharges?: number;
/** Omit to absorb all damage schools. */
readonly school?: DamageSchool;
/** Optional school set for absorbs such as Anti-Magic Shell. */
readonly schools?: readonly DamageSchool[];
/** Fraction of each incoming packet this absorb can consume; defaults to 1. */
readonly fraction?: number;
/** Defaults to true, granting `amount` of capacity for each aura stack. */
readonly perStack?: boolean;
}
@@ -78,7 +84,10 @@ export interface AuraAbsorbDefinition {
export interface AuraAbsorbState {
readonly id: string;
readonly school?: DamageSchool;
readonly schools?: readonly DamageSchool[];
readonly fraction?: number;
readonly remaining: number;
readonly remainingHits?: number;
}
export type AuraProcAction =
@@ -114,6 +123,8 @@ export type AuraProcAction =
export interface AuraProcDefinition {
readonly id: string;
readonly triggers: ProcTrigger | readonly ProcTrigger[];
/** Limit attack-triggered procs to the listed landed attack types. */
readonly attackKinds?: readonly AttackKind[];
/** Probability from 0 through 1. */
readonly chance: number;
readonly internalCooldownMs?: number;
@@ -157,6 +168,8 @@ export interface AuraDefinition {
readonly reflectSpellChance?: number;
/** Portion of incoming target damage transferred to the aura source. */
readonly redirectDamagePercent?: number;
/** Shared source-max-health cap for Paladin Divine Sacrifice redirection. */
readonly redirectDamageCapPercent?: number;
readonly dispelCategory?: DispelCategory;
readonly dispelPriority?: number;
readonly modifiers?: readonly AuraModifier[];
@@ -174,6 +187,8 @@ export interface ActiveAura {
readonly stacks: number;
readonly absorbs: readonly AuraAbsorbState[];
readonly procStates: readonly AuraProcState[];
/** Cumulative redirected damage for an aura that owns a shared redirect cap. */
readonly redirectedDamage?: number;
/** Number of Fire critical hits landed during the current Combustion buff. */
readonly combustionCriticalHits?: number;
}
@@ -214,6 +229,7 @@ export interface AbsorbDamageRequest {
readonly amount: number;
readonly school: DamageSchool;
readonly now: number;
readonly countsAsAttack?: boolean;
}
export interface AbsorbConsumption {
@@ -288,7 +304,12 @@ function newAbsorbStates(definition: AuraDefinition, stacks: number): readonly A
return (definition.absorbs ?? []).map((absorb) => ({
id: absorb.id,
school: absorb.school,
schools: absorb.schools,
fraction: absorb.fraction,
remaining: nonNegative(absorb.amount) * (absorb.perStack === false ? 1 : stacks),
...(absorb.hitCharges === undefined
? {}
: { remainingHits: Math.max(0, Math.floor(nonNegative(absorb.hitCharges))) }),
}));
}
@@ -313,6 +334,7 @@ function makeAura(request: ApplyAuraRequest, stacks: number): ActiveAura {
stacks,
absorbs: newAbsorbStates(definition, stacks),
procStates: newProcStates(definition),
...(definition.redirectDamageCapPercent === undefined ? {} : { redirectedDamage: 0 }),
};
}
@@ -498,15 +520,28 @@ export function absorbDamage(
if (index < 0) continue;
const aura = next[index];
const absorbs = aura.absorbs.map((absorb) => {
if (remainingDamage <= 0 || (absorb.school !== undefined && absorb.school !== request.school)) {
if (remainingDamage <= 0
|| (absorb.school !== undefined && absorb.school !== request.school)
|| (absorb.schools !== undefined && !absorb.schools.includes(request.school))) {
return absorb;
}
const amount = Math.min(absorb.remaining, remainingDamage);
const packetFraction = Math.max(0, Math.min(1, absorb.fraction ?? 1));
const isChargedAttackAbsorb = absorb.remainingHits !== undefined
&& request.countsAsAttack === true
&& absorb.remainingHits > 0;
if (absorb.remainingHits !== undefined && !isChargedAttackAbsorb) return absorb;
const amount = isChargedAttackAbsorb
? remainingDamage * packetFraction
: Math.min(absorb.remaining, remainingDamage * packetFraction);
remainingDamage -= amount;
if (amount > 0) {
consumptions.push({ auraInstanceId: aura.instanceId, absorbId: absorb.id, amount });
}
return { ...absorb, remaining: absorb.remaining - amount };
return {
...absorb,
remaining: absorb.remaining - amount,
...(isChargedAttackAbsorb ? { remainingHits: absorb.remainingHits! - 1 } : {}),
};
});
next[index] = { ...aura, absorbs };
}
@@ -545,6 +580,8 @@ export function evaluateAuraProcs(
if (
proc === undefined ||
!procHasTrigger(proc, event.trigger) ||
(proc.attackKinds !== undefined
&& (event.attackKind === undefined || !proc.attackKinds.includes(event.attackKind))) ||
state.readyAt > now ||
state.remainingCharges === 0
) {