Update Healer Man server

This commit is contained in:
phenom committed 2026-10-06 22:25:34 -04:00
1 parent 6114a2295f
commit 69809f7228
593 files changed
+903643 -40774

No files matched your search

+23 -2
View File
@@ -1,6 +1,11 @@
import type { ClassId } from "../app/characterCatalog";
import type { AbilityDefinition, ResourceType } from "./abilityCatalog";
import { coaBarbarianDecapitateTargetAllowed } from "./coaBarbarianExecuteRuntime";
import {
COA_GUARDIAN_TOWER_FORMATION_SPELL_ID,
COA_GUARDIAN_LINE_FORMATION_SPELL_ID,
} from "./coaGuardianFormationRuntime";
import { coaPeriodicActionMaintainedOnTarget, usesCoaTargetedPeriodicMaintenance } from "./coaPeriodicRotationRuntime";
import { aiHintsForAbility, canAbilityCastWhileMoving, runeCostForAbility } from "./abilityRules";
import type { DeathKnightRuneState } from "./combatActors";
import { channelAmountEffects } from "./combatChannelAmounts";
@@ -15,7 +20,7 @@ import {
type CompanionCooldownPolicy,
} from "./companionCooldownPolicy";
export const COMBAT_ROTATION_VERSION = "playerbots-inspired-v8-native-rom-healer-reserve";
export const COMBAT_ROTATION_VERSION = "playerbots-inspired-v12-coa-guardian-formations-paragon";
export interface RotationProfile {
readonly id: string;
@@ -274,6 +279,10 @@ function isPersistentPetPreparation(
/** Long-lived self maintenance and permanent pets that should exist before the first pull. */
export function precombatPreparationEffects(ability: AbilityDefinition): readonly AbilityDefinition["effects"][number][] {
// Formations must pay and project through a real player/NPC cast. Raw aura
// seeding would activate both forms and bypass shield/Footman's Calling rules.
if (ability.classId === "guardian" && (ability.dbcSpellId === COA_GUARDIAN_TOWER_FORMATION_SPELL_ID
|| ability.dbcSpellId === COA_GUARDIAN_LINE_FORMATION_SPELL_ID)) return [];
return ability.effects.filter((effect) => (
effect.kind === "pet"
? isPersistentPetPreparation(ability, effect)
@@ -339,6 +348,12 @@ function targetForAbility(
return context.friendlyTargets?.find((target) => target.role === "tank" && !target.fallen)?.id
?? context.selfId ?? null;
}
// An incidental caster aura does not redirect a sourced friendly periodic
// heal (for example Mojo Beam) away from its selected injured recipient.
if (ability.target === "friendly" && usesCoaTargetedPeriodicMaintenance(ability, context)
&& ability.effects.some((effect) => effect.kind === "hot" && effect.recipient !== "caster")) {
return lowest?.id ?? null;
}
const casterOnly = ability.target === "self" || (ability.effects.some((effect) => (
"recipient" in effect && effect.recipient === "caster"
)) && !ability.effects.some((effect) => (
@@ -392,7 +407,12 @@ function scoreAbility(
const nativePeriodic = nativeRotationProfileFor(context) !== null
&& context.maintainedPeriodicEffects !== undefined
&& ability.effects.some((effect) => effect.kind === "dot" || effect.kind === "hot");
const maintained = (!nativePeriodic && (context.maintainedAbilityIds?.has(ability.id) ?? false))
const coaPeriodic = context.maintainedPeriodicEffects !== undefined && Boolean(context.selfId)
&& usesCoaTargetedPeriodicMaintenance(ability, context);
const periodicMaintained = coaPeriodic
? coaPeriodicActionMaintainedOnTarget(ability, context, targetForAbility(ability, context, lowest))
: !nativePeriodic && (context.maintainedAbilityIds?.has(ability.id) ?? false);
const maintained = periodicMaintained
|| ability.effects.some((effect) => effect.kind === "apply-aura"
&& Boolean(effect.aura.exclusiveGroup
&& context.activeAuraExclusiveGroups?.has(effect.aura.exclusiveGroup)));
@@ -599,6 +619,7 @@ function scoreAbility(
const threshold = cooldownPolicy.generic.defensiveHealthPercent / 100;
if (selfHealth >= threshold && lowestHealth >= threshold) return null;
}
if (coaPeriodic && periodicMaintained) return null;
if (maintained && (categories.has("debuff") || categories.has("buff"))) return null;
if (activeSummon && (categories.has("summon") || categories.has("pet"))) return null;
if (rotationProfile && profileIndex < 0 && !damaging && (maintenanceBuff || petSummon || offensiveSummon)) return null;