Update Healer Man server
This commit is contained in:
1 parent
4c768fbec6
commit
b16821e92e
330 files changed
+35406
-1760
No files matched your search
@@ -2,23 +2,50 @@ import type { AbilityDefinition, AbilityEffect } from "./abilityCatalog";
|
||||
import type { AuraDefinition, AuraModifier, AuraProcDefinition } from "./combatAuras";
|
||||
import type { RomGeneratedAbilityLike } from "./romAbilitySemantics";
|
||||
import {
|
||||
ROM_ROGUE_COERCE_TAG,
|
||||
ROM_ROGUE_DAGGER_MASTERY_TAG,
|
||||
ROM_ROGUE_OFF_HAND_MASTERY_TAG,
|
||||
ROM_ROGUE_TREASURE_HUNTER_TAG,
|
||||
romRogueCoerceLowBlowDamageMultiplier,
|
||||
} from "./romRogueMechanics";
|
||||
import { ROM_ROGUE_MAGE_CHAOS_DAGGER_TAG as ROM_CHAOS_DAGGER_TAG } from "./romRogueChaosDagger";
|
||||
import {
|
||||
ROM_ROGUE_CHAMPION_NERVE_GEAR_MARKER_TAG,
|
||||
ROM_ROGUE_CHAMPION_NERVE_GEAR_PASSIVE_SPELL_ID,
|
||||
} from "./romRogueChampionNerveGearRuntime";
|
||||
|
||||
export const ROM_ROGUE_MAGE_ENCHANTED_THROW_TAG = "rom-491178-enchanted-throw";
|
||||
export const ROM_ROGUE_MAGE_CHAOS_DAGGER_TAG = ROM_CHAOS_DAGGER_TAG;
|
||||
/** @deprecated Use ROM_ROGUE_MAGE_CHAOS_DAGGER_TAG for current CoA behavior. */
|
||||
export const ROM_ROGUE_MAGE_ENCHANTED_THROW_TAG = ROM_ROGUE_MAGE_CHAOS_DAGGER_TAG;
|
||||
export const ROM_ROGUE_PRIEST_SINISTER_METHODS_TAG = "rom-rogue-priest-sinister-methods";
|
||||
export const ROM_ROGUE_PRIEST_SINISTER_METHODS_COOLDOWN_KEY = "rom-rogue-priest-sinister-methods";
|
||||
export const ROM_SCOUT_PRIEST_SNIPER_TAG = "rom-scout-priest-sniper";
|
||||
const ROM_SCOUT_KNIGHT_ENHANCED_ARMOR_PERFECTION_TAG = "rom-scout-knight-enhanced-armor-perfection";
|
||||
// Local RuneWaker component 501823 sets Enhanced Armor's duration to 600s.
|
||||
const ROM_SCOUT_KNIGHT_ENHANCED_ARMOR_DURATION_MS = 600_000;
|
||||
/** RuneWaker itemobject/shop rows supply Poison Powder to the Scout/Rogue loadout. */
|
||||
export const ROM_SCOUT_ROGUE_POISON_POWDER_SUPPLY = Object.freeze({
|
||||
itemId: 200563,
|
||||
name: "Poison Powder",
|
||||
quantity: "unlimited",
|
||||
} as const);
|
||||
|
||||
function firstDamage(effects: readonly AbilityEffect[]): AbilityEffect[] {
|
||||
return effects.filter((effect) => effect.kind === "damage").slice(0, 1);
|
||||
}
|
||||
|
||||
function scaleDamageEffects(effects: readonly AbilityEffect[], factor: number): readonly AbilityEffect[] {
|
||||
return effects.map((effect) => effect.kind === "damage" || effect.kind === "dot" ? {
|
||||
...effect,
|
||||
coefficient: effect.coefficient * factor,
|
||||
...(effect.coefficientPerLevel === undefined ? {} : { coefficientPerLevel: effect.coefficientPerLevel * factor }),
|
||||
...(effect.basePoints === undefined ? {} : { basePoints: effect.basePoints * factor }),
|
||||
...(effect.pointsPerLevel === undefined ? {} : { pointsPerLevel: effect.pointsPerLevel * factor }),
|
||||
...(effect.bonusPowerCoefficient === undefined ? {} : { bonusPowerCoefficient: effect.bonusPowerCoefficient * factor }),
|
||||
...(effect.kind !== "damage" || effect.bonusFlat === undefined ? {} : { bonusFlat: effect.bonusFlat * factor }),
|
||||
} : effect);
|
||||
}
|
||||
|
||||
function taggedPassive(
|
||||
sourceId: number,
|
||||
name: string,
|
||||
@@ -137,13 +164,17 @@ export function overrideRomScoutRogueEffects(
|
||||
}
|
||||
case 490504:
|
||||
return taggedRoguePassive(490504, "Dagger Mastery", ROM_ROGUE_DAGGER_MASTERY_TAG);
|
||||
case 493019:
|
||||
if (row.classId !== "rom-rogue" || row.secondaryClassId !== "rom-scout") return null;
|
||||
// Current CoA Coerce directly increases Low Blow damage and reduces its
|
||||
// Energy cost. Its older RuneWaker below-30% temporary buff is obsolete.
|
||||
return taggedRoguePassive(493019, "Coerce", ROM_ROGUE_COERCE_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 [];
|
||||
// Keep the source modifiers scoped to actual off-hand attacks. A generic
|
||||
// melee aura would incorrectly buff the main hand as well.
|
||||
return taggedRoguePassive(490143, "Off Hand Mastery", ROM_ROGUE_OFF_HAND_MASTERY_TAG);
|
||||
case 493020: { // Successful Low Blow/Blind Spot hits trigger the local 10s crit buff.
|
||||
if (row.classId !== "rom-rogue" || row.secondaryClassId !== "rom-priest") return null;
|
||||
const buff = row.source?.components?.find((component) => component.id === 503265);
|
||||
@@ -170,20 +201,10 @@ export function overrideRomScoutRogueEffects(
|
||||
);
|
||||
case 491178:
|
||||
if (row.classId !== "rom-rogue" || row.secondaryClassId !== "rom-mage") return null;
|
||||
// Hidden child 491185 has no generated payload. The auto-attack runtime
|
||||
// applies its referenced Throw (490309) damage explicitly, so keep the
|
||||
// tag and avoid also registering the untranslated generic child proc.
|
||||
if (translated.some((effect) => effect.kind === "apply-aura")) {
|
||||
return translated.map((effect) => effect.kind === "apply-aura" ? {
|
||||
...effect,
|
||||
aura: {
|
||||
...effect.aura,
|
||||
procs: [],
|
||||
utilityTags: [...(effect.aura.utilityTags ?? []), ROM_ROGUE_MAGE_ENCHANTED_THROW_TAG],
|
||||
},
|
||||
} : effect);
|
||||
}
|
||||
return [...translated, ...taggedRoguePassive(491178, "Enchanted Throw", ROM_ROGUE_MAGE_ENCHANTED_THROW_TAG)];
|
||||
// Current CoA reuses this exact Rogue/Mage ID as passive Chaos Dagger.
|
||||
// Keep a marker for learned-passive consumers such as Day of Rain; do
|
||||
// not register the incompatible RuneWaker Throw child or local aura.
|
||||
return taggedRoguePassive(491178, "Chaos Dagger", ROM_ROGUE_MAGE_CHAOS_DAGGER_TAG);
|
||||
case 491552:
|
||||
if (row.classId !== "rom-rogue") return null;
|
||||
return translated.map((effect) => effect.kind === "apply-aura" ? {
|
||||
@@ -250,6 +271,9 @@ export function overrideRomScoutRogueEffects(
|
||||
case 492344:
|
||||
if (row.classId !== "rom-scout" || row.secondaryClassId !== "rom-priest") return null;
|
||||
return taggedPassive(492344, "Sniper", ROM_SCOUT_PRIEST_SNIPER_TAG);
|
||||
case 492346:
|
||||
if (row.classId !== "rom-scout" || row.secondaryClassId !== "rom-knight") return null;
|
||||
return taggedPassive(492346, "Enhanced Armor Perfection", ROM_SCOUT_KNIGHT_ENHANCED_ARMOR_PERFECTION_TAG);
|
||||
case 493007:
|
||||
return taggedPassive(493007, "Deadly Counterattack", "rom-deadly-counterattack",
|
||||
customProc(493007, "hit", "rom-deadly-counterattack", { internalCooldownMs: 20_000 }));
|
||||
@@ -321,6 +345,19 @@ export function romScoutRogueCastEffects(
|
||||
): readonly AbilityEffect[] {
|
||||
const passives = new Set(passiveTags);
|
||||
const target = new Set(targetTags);
|
||||
const coerceDamageMultiplier = romRogueCoerceLowBlowDamageMultiplier({
|
||||
classId: ability.classId,
|
||||
abilitySource: ability.source,
|
||||
abilitySpellId: ability.dbcSpellId,
|
||||
passiveTags,
|
||||
});
|
||||
if (coerceDamageMultiplier !== 1) return scaleDamageEffects(effects, coerceDamageMultiplier);
|
||||
if (ability.dbcSpellId === 490152 && passives.has(ROM_SCOUT_KNIGHT_ENHANCED_ARMOR_PERFECTION_TAG)) {
|
||||
// Component 501823 is the source's rank payload: Enhanced Armor lasts 600s.
|
||||
return effects.map((effect) => effect.kind === "apply-aura"
|
||||
? { ...effect, aura: { ...effect.aura, durationMs: ROM_SCOUT_KNIGHT_ENHANCED_ARMOR_DURATION_MS } }
|
||||
: effect);
|
||||
}
|
||||
if (ability.dbcSpellId === 490457) {
|
||||
// Replacement 499535 / component 623051 raises ranged DPS from 0.75 to 0.85.
|
||||
const masteryFactor = passives.has("rom-master-reflected-shot") ? 0.85 / 0.75 : 1;
|
||||
@@ -408,7 +445,7 @@ export function romScoutRogueCastEffects(
|
||||
return effects;
|
||||
}
|
||||
|
||||
/** Day of Rain has an exact 50% miss chance while Enchanted Throw is active. */
|
||||
/** Day of Rain has an exact 50% miss chance while the Rogue/Mage Chaos Dagger passive is learned. */
|
||||
export function romRogueMageDayOfRainBaseMissPercent(
|
||||
classId: string,
|
||||
secondaryClassId: string | null | undefined,
|
||||
@@ -419,7 +456,7 @@ export function romRogueMageDayOfRainBaseMissPercent(
|
||||
if (classId !== "rom-rogue"
|
||||
|| secondaryClassId !== "rom-mage"
|
||||
|| abilitySpellId !== 491183
|
||||
|| !activeAuraTags.includes(ROM_ROGUE_MAGE_ENCHANTED_THROW_TAG)) return null;
|
||||
|| !activeAuraTags.includes(ROM_ROGUE_MAGE_CHAOS_DAGGER_TAG)) return null;
|
||||
const hitPercent = Number.isFinite(attackerHitPercent)
|
||||
? Math.max(0, Math.min(100, attackerHitPercent))
|
||||
: 0;
|
||||
@@ -483,7 +520,7 @@ export type RomScoutRogueProcActionSpec =
|
||||
export function romScoutRogueProcActionSpec(
|
||||
actionId: string,
|
||||
triggeringSourceSkillId: number,
|
||||
casterPoisonous: boolean,
|
||||
_casterPoisonous: boolean,
|
||||
data: Readonly<Record<string, string | number | boolean>> = {},
|
||||
): RomScoutRogueProcActionSpec | null {
|
||||
switch (actionId) {
|
||||
@@ -561,7 +598,11 @@ export function romScoutRogueProcActionSpec(
|
||||
provenance: "hybrid-estimate",
|
||||
};
|
||||
case "rom-poisonous-spit":
|
||||
if (!casterPoisonous || ![490457, 490424].includes(triggeringSourceSkillId)) return null;
|
||||
// Poison Powder (item 200563) is supplied as an unlimited bag reagent by
|
||||
// the Scout/Rogue loadout model. Do not use Rogue's separate Poison
|
||||
// Bottle aura (490329) as a proxy for carrying this item.
|
||||
if (ROM_SCOUT_ROGUE_POISON_POWDER_SUPPLY.quantity !== "unlimited"
|
||||
|| ![490457, 490424].includes(triggeringSourceSkillId)) return null;
|
||||
return {
|
||||
kind: "dot",
|
||||
recipient: "target",
|
||||
@@ -575,7 +616,7 @@ export function romScoutRogueProcActionSpec(
|
||||
intervalMs: 2_000,
|
||||
tag: "rom-poisonous-spit",
|
||||
},
|
||||
provenance: "source", // 503522; the live Poison Powder aura gates the rider.
|
||||
provenance: "source", // 503522; Poison Powder is a carried item, not Rogue's Poison Bottle buff.
|
||||
};
|
||||
case "rom-reclaim-energy":
|
||||
if (triggeringSourceSkillId === 490306) return {
|
||||
|
||||
Reference in new issue
Block a user