Update Healer Man server

This commit is contained in:
phenom committed 2026-10-02 10:38:12 -04:00
1 parent 4c768fbec6
commit b16821e92e
330 files changed
+35406 -1760

No files matched your search

+40 -5
View File
@@ -8,6 +8,10 @@ import { romChampionCastEffects } from "./romChampionOverrides";
import { romWardenCastEffects } from "./romWardenOverrides";
import { romWarlockCastEffects } from "./romWarlockOverrides";
import { romKnightCastEffects } from "./romKnightOverrides";
import { romPriestWarriorCondensedRagePhysicalDamageMultiplier } from "./romPriestChampionOverrides";
import { withoutCurrentCoaHolySealPeriodicDamage } from "./romWarriorCurrentCoaMechanics";
import { romCoaWarriorRogueProbingAttackDpsCoefficient } from "./romWarriorRogueExhaustion";
import { isRomDruidRoguePair, ROM_DRUID_ROGUE_CORROSIVE_POISON_TAG } from "./romDruidRogueCurrentCoa";
const ROGUE_BLEED_ABILITIES = new Set([
"rom-rogue-primary-1", // Low Blow's conditional Grievous Wound
@@ -21,12 +25,16 @@ export interface RomCastMechanics {
readonly bleedCount: number;
readonly charged: boolean;
readonly mainHandDagger: boolean;
readonly mainHandTwoHandHammer?: boolean;
readonly casterMaxHealth: number;
readonly targetHealthPercent: number;
readonly friendlyTargetHealthPercent?: number;
readonly naturePower?: number;
readonly passiveTags?: readonly string[];
readonly learnedPassiveSpellIds?: readonly number[];
/** True when the ability's default damage school resolves to Physical. */
readonly defaultDamageIsPhysical?: boolean;
readonly selectedTargetRelationship?: "friendly" | "hostile";
readonly eruptionProcRoll?: number;
readonly targetTags?: readonly string[];
readonly slashBleed?: boolean;
@@ -46,7 +54,7 @@ export function romSelfDrainPercent(spellId: number): number {
export function romSingleTargetControl(ability: AbilityDefinition | null): boolean {
return ability?.source === "runewaker"
&& [490347, 490454, 491172].includes(ability.dbcSpellId);
&& [490454, 491172].includes(ability.dbcSpellId);
}
export function romAbilityNeedsShield(ability: AbilityDefinition): boolean {
@@ -80,6 +88,7 @@ export function romAbilityNeedsRangedWeapon(ability: AbilityDefinition): boolean
export function romAbilityRequiredTargetStateTag(ability: AbilityDefinition): string | null {
if (ability.source !== "runewaker") return null;
if (ability.dbcSpellId === 494321 && isRomDruidRoguePair(ability)) return ROM_DRUID_ROGUE_CORROSIVE_POISON_TAG;
if (ability.dbcSpellId === 492617) return "rom-weakened";
if (ability.dbcSpellId === 491136 || ability.dbcSpellId === 492619) return "rom-vulnerable";
return null;
@@ -102,7 +111,6 @@ export function romWarriorAbilityAdjustment(
491458: { abilitySpellId: 490121, rageCostReduction: 10, cooldownReductionMs: 20_000 }, // Moon Cleave Perfection
493248: { abilitySpellId: 490133, rageCostReduction: 20, cooldownReductionMs: 10_000 }, // Exhaustion
499491: { abilitySpellId: 490133, rageCostReduction: 25, cooldownReductionMs: 15_000 }, // Whirlwind Battle Technique
494377: { abilitySpellId: 490133, rageCostReduction: 10, cooldownReductionMs: 10_000 }, // Recovery of Life
499827: { abilitySpellId: 490053, rageCostReduction: 10, cooldownReductionMs: 0 }, // Speed Slash
};
const applicable = Object.entries(rules)
@@ -195,7 +203,12 @@ export function romEffectsForCast(ability: AbilityDefinition, context: RomCastMe
context.friendlyTargetHealthPercent ?? 1,
context.passiveTags ?? [],
);
const knightEffects = romKnightCastEffects(ability, priestWarlockEffects, context.passiveTags ?? []);
const knightEffects = romKnightCastEffects(
ability,
priestWarlockEffects,
context.passiveTags ?? [],
context.sealStacks,
);
const mageWarlockEffects = romMageWarlockCastEffects(
ability,
knightEffects,
@@ -216,13 +229,26 @@ export function romEffectsForCast(ability: AbilityDefinition, context: RomCastMe
context.targetTags ?? [],
context.learnedPassiveSpellIds ?? [],
context.targetHealthPercent,
context.selectedTargetRelationship ?? "hostile",
);
const coaEffects = withoutCurrentCoaHolySealPeriodicDamage(ability.dbcSpellId, effects);
const warriorPassives = new Set(context.learnedPassiveSpellIds ?? []);
const condensedRageMultiplier = ability.classId === "rom-priest"
? romPriestWarriorCondensedRagePhysicalDamageMultiplier(
(context.learnedPassiveSpellIds ?? []).includes(493038),
)
: 1;
const condensedRageEffects = condensedRageMultiplier > 1
? coaEffects.map((effect) => (effect.kind === "damage" || effect.kind === "dot")
&& (effect.school ?? (context.defaultDamageIsPhysical ? "physical" : undefined)) === "physical"
? scaleOutput(effect, condensedRageMultiplier)
: effect)
: coaEffects;
const sourceSchoolAdjustedEffects = romWarriorPhysicalWeaponTooltip(ability)
? effects.map((effect) => (effect.kind === "damage" || effect.kind === "dot") && effect.school === "arcane"
? condensedRageEffects.map((effect) => (effect.kind === "damage" || effect.kind === "dot") && effect.school === "arcane"
? { ...effect, school: "physical" as const }
: effect)
: effects;
: condensedRageEffects;
const warriorAdjustedEffects = ability.classId === "rom-warrior" && warriorPassives.has(499806)
? sourceSchoolAdjustedEffects.map((effect) => (effect.kind === "damage" || effect.kind === "dot")
&& (effect.school === undefined || effect.school === "physical")
@@ -234,6 +260,15 @@ export function romEffectsForCast(ability: AbilityDefinition, context: RomCastMe
const damage = warriorAdjustedEffects.filter((effect) => effect.kind === "damage");
const seals = Math.max(0, Math.min(4, context.sealStacks));
switch (ability.dbcSpellId) {
case 493283: { // Current CoA Warrior/Rogue Probing Attack has a sourced empowered weapon-DPS branch.
const weaponDpsCoefficient = romCoaWarriorRogueProbingAttackDpsCoefficient({
hasCasterOwnedBleed: context.bleedCount > 0,
equippedTwoHandHammer: context.mainHandTwoHandHammer ?? false,
});
return warriorAdjustedEffects.map((effect) => effect.kind === "damage"
? { ...effect, weaponDpsCoefficient }
: effect);
}
case 491142: // Tactical Attack's copied Slash bleed only applies when Slash is already bleeding the target.
return [
...damage,