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

+83 -3
View File
@@ -1,6 +1,10 @@
import type { AbilityDefinition, AbilityEffect } from "./abilityCatalog";
import type { AuraDefinition, AuraModifier, AuraProcDefinition } from "./combatAuras";
import type { RomGeneratedAbilityLike } from "./romAbilitySemantics";
import {
ROM_ROGUE_DAGGER_MASTERY_TAG,
ROM_ROGUE_TREASURE_HUNTER_TAG,
} from "./romRogueMechanics";
function firstDamage(effects: readonly AbilityEffect[]): AbilityEffect[] {
return effects.filter((effect) => effect.kind === "damage").slice(0, 1);
@@ -30,6 +34,24 @@ function taggedPassive(
}];
}
function taggedRoguePassive(sourceId: number, name: string, tag: string): AbilityEffect[] {
return [{
kind: "apply-aura",
recipient: "caster",
aura: {
id: `rom-aura:${sourceId}:rogue-passive`,
name,
disposition: "buff",
durationMs: null,
utilityTags: [tag],
},
sourceEffectType: -1,
sourceAuraType: -1,
miscValue: 0,
triggerSpellId: sourceId,
}];
}
function customProc(
sourceId: number,
trigger: "hit" | "crit",
@@ -78,6 +100,35 @@ export function overrideRomScoutRogueEffects(
translated: readonly AbilityEffect[],
): readonly AbilityEffect[] | null {
switch (row.sourceSkillId) {
case 490504:
return taggedRoguePassive(490504, "Dagger Mastery", ROM_ROGUE_DAGGER_MASTERY_TAG);
case 490316:
return taggedRoguePassive(490316, "Treasure Hunter", ROM_ROGUE_TREASURE_HUNTER_TAG);
case 490143:
// The source applies damage and accuracy only to off-hand attacks; there
// is no distinct RoM off-hand hit yet, so do not turn either value into a
// generic player melee modifier.
return [];
case 491552:
if (row.classId !== "rom-rogue") return null;
return translated.map((effect) => effect.kind === "apply-aura" ? {
...effect,
aura: { ...effect.aura, utilityTags: [...(effect.aura.utilityTags ?? []), "rom-491552"] },
} : effect);
case 490445: // Bow/crossbow accuracy must not grant melee hit; keep its range scope explicit.
return translated.filter((effect) => effect.kind !== "apply-aura" || effect.sourceAuraType !== 54)
.map((effect) => effect.kind === "apply-aura" ? {
...effect,
aura: {
...effect.aura,
modifiers: effect.aura.modifiers?.map((modifier) => modifier.kind === "stat"
&& modifier.stat === "physical-hit"
? { ...modifier, stat: "ranged-hit" }
: modifier),
},
} : effect);
case 490505: // Bow and crossbow each carry an equivalent +11% attack-speed modifier in the source.
return translated.filter((effect) => effect.kind !== "apply-aura" || effect.sourceAuraType !== 70);
case 490400: // Piercing Arrow: one projectile, then a line hit behind its target.
return firstDamage(translated);
case 490424: { // Combo Shot: three impacts of the same source shot.
@@ -88,6 +139,8 @@ export function overrideRomScoutRogueEffects(
const hit = firstDamage(translated)[0];
return hit?.kind === "damage" ? [{ ...hit, falloffPerJump: 0.5 }] : translated;
}
case 498803: // Soul Stab's first hit is unconditional; its second hit requires Weakened.
return translated.filter((effect) => effect.kind === "damage");
case 490354: // Vanish is an aggro/stealth transition, not a self-heal.
return translated.filter((effect) => effect.kind !== "heal").map((effect) => effect.kind === "apply-aura"
? { ...effect, aura: { ...effect.aura, utilityTags: ["stealth", "rom-vanish"] } }
@@ -108,6 +161,9 @@ export function overrideRomScoutRogueEffects(
case 492916:
return taggedPassive(492916, "Exploiting Shot", "rom-exploiting-shot",
customProc(492916, "crit", "rom-exploiting-shot", { internalCooldownMs: 20_000 }));
case 493006:
return taggedPassive(493006, "Accurate Targeting", "rom-accurate-targeting",
customProc(493006, "hit", "rom-accurate-targeting", { internalCooldownMs: 30_000 }));
case 493007:
return taggedPassive(493007, "Deadly Counterattack", "rom-deadly-counterattack",
customProc(493007, "hit", "rom-deadly-counterattack", { internalCooldownMs: 20_000 }));
@@ -193,6 +249,15 @@ export function romScoutRogueCastEffects(
falloffPerJump: passives.has("rom-poisonous-spit") ? 1 : effect.falloffPerJump,
} : effect);
}
if (ability.dbcSpellId === 498803) {
let seenDamage = 0;
const weakened = target.has("rom-weakened");
return effects.filter((effect) => {
if (effect.kind !== "damage") return true;
seenDamage += 1;
return seenDamage === 1 || weakened;
});
}
if (ability.dbcSpellId === 490451 && passives.has("rom-meridian-attack")) {
// 499537/623061 replaces Wrist Attack: -30 physical and magical damage for 10s.
return effects.map((effect) => effect.kind === "apply-aura" && effect.recipient !== "caster"
@@ -298,9 +363,24 @@ export type RomScoutRogueProcActionSpec =
export function romScoutRogueProcActionSpec(
actionId: string,
triggeringSourceSkillId: number,
_casterPoisonous: boolean,
casterPoisonous: boolean,
): RomScoutRogueProcActionSpec | null {
switch (actionId) {
case "rom-accurate-targeting": {
if (triggeringSourceSkillId !== 490423) return null;
return {
kind: "aura",
recipient: "caster",
aura: {
id: "rom-scout-accurate-targeting",
name: "Accurate Targeting",
disposition: "buff",
durationMs: 15_000, // Source component 503255.
modifiers: [{ kind: "stat", stat: "physical-attack", operation: "flat", value: 50 }],
},
provenance: "source",
};
}
case "rom-exploiting-shot":
if (triggeringSourceSkillId !== 490423) return null;
return {
@@ -332,7 +412,7 @@ export function romScoutRogueProcActionSpec(
provenance: "hybrid-estimate",
};
case "rom-poisonous-spit":
if (![490457, 490424].includes(triggeringSourceSkillId)) return null;
if (!casterPoisonous || ![490457, 490424].includes(triggeringSourceSkillId)) return null;
return {
kind: "dot",
recipient: "target",
@@ -346,7 +426,7 @@ export function romScoutRogueProcActionSpec(
intervalMs: 2_000,
tag: "rom-poisonous-spit",
},
provenance: "source", // 499535/503522. Poison Powder is supplied without inventory gating.
provenance: "source", // 503522; the live Poison Powder aura gates the rider.
};
case "rom-reclaim-energy":
if (triggeringSourceSkillId === 490306) return {