Update Healer Man server
This commit is contained in:
1 parent
4c768fbec6
commit
b16821e92e
330 files changed
+35406
-1760
No files matched your search
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user