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

+89 -12
View File
@@ -21,6 +21,12 @@ import type {
} from "./combatAuras";
import generatedData from "./wow335AbilityData.generated.json";
import { playerCombatPower } from "./progression";
import {
WOW335_HUNTER_PET_KILL_COMMAND_COOLDOWN_MS,
WOW335_HUNTER_PET_KILL_COMMAND_DURATION_MS,
WOW335_HUNTER_PET_KILL_COMMAND_SPECIAL_CHARGES,
WOW335_HUNTER_PET_KILL_COMMAND_TAG,
} from "./wow335HunterPetRuntime";
import {
ROGUE_DEADLY_POISON_DOSE_TAG,
ROGUE_ENVENOM_BUFF_TAG,
@@ -37,6 +43,7 @@ import { WOW335_TALENT_NODES } from "./wow335Talents.generated";
export const BASE_CLASS_STARTER_SOURCE_LEVEL = 10;
interface Wow335Effect {
readonly index: number;
readonly effectType: number;
readonly auraType: number;
readonly basePoints: number;
@@ -831,6 +838,12 @@ function classScriptEffects(
triggerSpellId: 0,
});
switch (`${classId}:${abilityName}`) {
case "mage:Blink": return [{
kind: "movement",
movement: "teleport",
toward: "destination",
distance: rank.effects.find((effect) => effect.effectType === 29)?.radius ?? 0,
}];
case "paladin:Redemption": return [{
kind: "resurrection",
percentMaxHealth: 0,
@@ -1008,14 +1021,13 @@ function classScriptEffects(
aura: {
id: `wow335:${rank.spellId}:kill-command`,
name: abilityName,
description: rank.description,
description: "Increases your pet's damage from special attacks by 60% for 30 seconds. Each special attack reduces the bonus by 20%.",
disposition: "buff",
durationMs: rank.durationMs,
durationMs: WOW335_HUNTER_PET_KILL_COMMAND_DURATION_MS,
maxStacks: WOW335_HUNTER_PET_KILL_COMMAND_SPECIAL_CHARGES,
initialStacks: WOW335_HUNTER_PET_KILL_COMMAND_SPECIAL_CHARGES,
stackBehavior: "replace",
utilityTags: ["wow335-hunter-kill-command"],
// The generated row omits the starting damage bonus; leave the pet
// special-attack rider inert until that value and a special-hit event
// are both represented by the runtime.
utilityTags: [WOW335_HUNTER_PET_KILL_COMMAND_TAG],
},
sourceEffectType: 6,
sourceAuraType: 4,
@@ -1712,6 +1724,9 @@ function effectsForRank(classId: BaseClassId, rank: Wow335Rank, abilityName: str
...(classId === "hunter" && abilityName === "Bestial Wrath" && effect.implicitTargetA === 5
? { recipient: "pet" as const }
: {}),
...(classId === "hunter" && abilityName === "Mend Pet"
? { recipient: "pet" as const }
: {}),
...(effect.implicitTargetA === 1 ? { recipient: "caster" as const } : {}),
...([35, 65].includes(effect.effectType)
|| (classId === "warrior"
@@ -1735,7 +1750,14 @@ function effectsForRank(classId: BaseClassId, rank: Wow335Rank, abilityName: str
effects.push({ kind: "dot", coefficient, ...scaling, ticks, intervalMs: effect.periodMs, tag: `spell-${rank.spellId}` });
} else if (effect.auraType === 8 && effect.periodMs > 0) {
const ticks = Math.max(1, Math.round(Math.max(effect.periodMs, rank.durationMs) / effect.periodMs));
effects.push({ kind: "hot", coefficient, ...scaling, ticks, intervalMs: effect.periodMs });
effects.push({
kind: "hot",
coefficient,
...scaling,
ticks,
intervalMs: effect.periodMs,
...(classId === "hunter" && abilityName === "Mend Pet" ? { recipient: "pet" as const } : {}),
});
} else if (effect.auraType === 11) {
effects.push({ kind: "taunt", durationMs: Math.max(3_000, rank.durationMs) });
} else if (effect.auraType === 20 && effect.periodMs > 0) {
@@ -2056,8 +2078,8 @@ function effectsForRank(classId: BaseClassId, rank: Wow335Rank, abilityName: str
|| (classId === "death-knight" && abilityName === "Anti-Magic Zone" && effect.kind === "summon")
|| (classId === "death-knight" && ["Anti-Magic Shell", "Bone Shield", "Deathchill"].includes(abilityName)
&& effect.kind === "apply-aura")
// Blink's DBC teleport is forward, but the combat state has no player
// facing vector. Do not approximate it with a target-relative movement.
// Its DBC effect is converted into an explicit class fallback below so
// the source row's forward movement distance stays attached to the spell.
|| (classId === "mage" && abilityName === "Blink" && effect.kind === "movement")
))
.map((effect) => effect.kind === "utility" ? effect : effect);
@@ -2181,6 +2203,8 @@ function rankDefinition(
level: gameplaySourceLevel(classId, rank.level),
description: classId === "death-knight" && abilityName === "Anti-Magic Zone"
? "Creates a stationary 10-yard zone for 10 seconds. Party members inside it absorb 75% of incoming magic damage, up to 10000 plus twice your attack power."
: classId === "hunter" && abilityName === "Kill Command"
? "Give the command to kill, increasing your pet's damage from special attacks by 60% for 30 seconds. Each special attack done by the pet reduces the damage bonus by 20%."
: rank.description,
castMode: channeling ? "channel" : rank.castTimeMs > 0 ? "cast" : "instant",
castTimeMs,
@@ -2189,7 +2213,9 @@ function rankDefinition(
? { channelPulses: Math.max(1, Math.round(castTimeMs / channelTickMs) + (penance ? 1 : 0)) }
: {}),
...(penance ? { channelStartsWithPulse: true } : {}),
cooldownMs: classId === "shaman" && abilityName === "Nature's Swiftness"
cooldownMs: classId === "hunter" && abilityName === "Kill Command"
? WOW335_HUNTER_PET_KILL_COMMAND_COOLDOWN_MS
: classId === "shaman" && abilityName === "Nature's Swiftness"
? Math.max(180_000, rank.cooldownMs)
: rank.cooldownMs,
gcdMs: rank.gcdMs,
@@ -2281,8 +2307,59 @@ function abilityDefinition(classId: BaseClassId, chain: Wow335Chain): AbilityDef
const soulLinkTalentTooltip = classId === "warlock" && chain.name === "Soul Link"
? WOW335_TALENT_NODES.find((node) => node.id === chain.talentNodeId)?.rankDescriptions[0]
: undefined;
const ranks = castRanks.map((rank, index) => rankDefinition(classId, resource, rank, index, chain.name))
.map((rank) => soulLinkTalentTooltip ? { ...rank, description: soulLinkTalentTooltip } : rank);
const focusMagicTalent = classId === "mage" && chain.name === "Focus Magic"
? WOW335_TALENT_NODES.find((node) => node.id === chain.talentNodeId)
: undefined;
const hysteriaTalent = classId === "death-knight" && chain.name === "Hysteria"
? WOW335_TALENT_NODES.find((node) => node.id === chain.talentNodeId)
: undefined;
const auraMasteryTalent = classId === "paladin" && chain.name === "Aura Mastery"
? WOW335_TALENT_NODES.find((node) => (node.rankSpellIds as readonly number[]).includes(31821))
: undefined;
const focusMagicRankSpellIds = (focusMagicTalent?.rankSpellIds ?? []) as readonly number[];
const focusMagicTalentEffect = focusMagicTalent?.rankEffects[0]?.effects.find((effect) => (
effect.index === 0 && effect.auraType === 57
));
const focusMagicTalentTooltip = focusMagicTalent?.rankDescriptions[0];
const hysteriaTalentTooltip = hysteriaTalent?.rankDescriptions[0];
const auraMasteryTalentTooltip = auraMasteryTalent?.rankDescriptions[0];
const ranks = castRanks.map((rank, index) => {
// Focus Magic's current Area-52 talent row is generated from patch-D and
// gives the recipient +1% spell crit. The separate enUS Spell.dbc import
// conflicts at +3%, so use the current talent DBC effect and tooltip for
// the runtime ability.
const auraMasteryRank = auraMasteryTalentTooltip && rank.spellId === 31821
? { ...rank, durationMs: 6_000, description: auraMasteryTalentTooltip }
: rank;
const hysteriaTalentRank = hysteriaTalent?.rankEffects.find((talentRank) => talentRank.spellId === rank.spellId);
const resolvedRank = focusMagicTalentEffect
&& focusMagicRankSpellIds.includes(rank.spellId)
? {
...auraMasteryRank,
effects: auraMasteryRank.effects.map((effect) => effect.effectType === focusMagicTalentEffect.effectType
&& effect.auraType === focusMagicTalentEffect.auraType
? { ...effect, basePoints: focusMagicTalentEffect.basePoints }
: effect),
}
// Hysteria's active ability row is also a talent. Keep it on the current
// Area-52 talent DBC's 15% value instead of the separate stock enUS row.
: hysteriaTalentRank
? {
...auraMasteryRank,
effects: auraMasteryRank.effects.map((effect) => {
const talentEffect = hysteriaTalentRank.effects.find((candidate) => candidate.index === effect.index);
return talentEffect ? { ...effect, basePoints: talentEffect.basePoints } : effect;
}),
}
: auraMasteryRank;
return rankDefinition(classId, resource, resolvedRank, index, chain.name);
}).map((rank) => {
const talentTooltip = soulLinkTalentTooltip
?? focusMagicTalentTooltip
?? hysteriaTalentTooltip
?? auraMasteryTalentTooltip;
return talentTooltip ? { ...rank, description: talentTooltip } : rank;
});
const first = ranks[0];
const firstRaw = castRanks[0];
if (!first || !firstRaw) return null;