forked from phenom/healer-man
531 lines
21 KiB
TypeScript
531 lines
21 KiB
TypeScript
import type { AbilityDefinition, AbilityEffect } from "./abilityCatalog";
|
|
import type { RomGeneratedAbilityLike } from "./romAbilitySemantics";
|
|
import { romPriestChampionCastEffects } from "./romPriestChampionOverrides";
|
|
import {
|
|
ROM_KNIGHT_SCOUT_BLOOD_PUNISHMENT_TAG,
|
|
romKnightScoutBloodPunishmentActivationEffects,
|
|
} from "./romKnightScoutBloodPunishment";
|
|
|
|
export const ROM_PRIEST_WARRIOR_BATTLE_MONK_STANCE_TAG = "rom-priest-warrior-battle-monk-stance";
|
|
|
|
const BATTLE_MONK_STANCE_GATED_SKILLS = new Set([491362, 491363, 491364, 492635, 493038]);
|
|
export const ROM_PRIEST_KNIGHT_HOLY_POWER_HEAL_USES_TAG = "rom-priest-knight-holy-power-heal-uses";
|
|
|
|
export function romPriestWarriorStanceRequired(
|
|
ability: Pick<AbilityDefinition, "source" | "classId" | "secondaryClassId" | "dbcSpellId">,
|
|
): boolean {
|
|
return ability.source === "runewaker"
|
|
&& ability.classId === "rom-priest"
|
|
&& ability.secondaryClassId === "rom-warrior"
|
|
&& BATTLE_MONK_STANCE_GATED_SKILLS.has(ability.dbcSpellId);
|
|
}
|
|
|
|
/** Player and companion cast gates share the source-specific Priest/Warrior condition. */
|
|
export function romPriestWarriorStanceUseAllowed(
|
|
ability: Pick<AbilityDefinition, "source" | "classId" | "secondaryClassId" | "dbcSpellId">,
|
|
activeAuraTags: readonly string[] | ReadonlySet<string>,
|
|
): boolean {
|
|
if (!romPriestWarriorStanceRequired(ability)) return true;
|
|
return Array.isArray(activeAuraTags)
|
|
? activeAuraTags.includes(ROM_PRIEST_WARRIOR_BATTLE_MONK_STANCE_TAG)
|
|
: (activeAuraTags as ReadonlySet<string>).has(ROM_PRIEST_WARRIOR_BATTLE_MONK_STANCE_TAG);
|
|
}
|
|
|
|
function passiveState(sourceId: number, name: string, tag: string): readonly AbilityEffect[] {
|
|
return [{
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: {
|
|
id: `rom-pair-passive-${sourceId}`,
|
|
name,
|
|
disposition: "buff",
|
|
durationMs: null,
|
|
utilityTags: [tag],
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: -1,
|
|
miscValue: 0,
|
|
triggerSpellId: sourceId,
|
|
}];
|
|
}
|
|
|
|
/** Source-specific pair mechanics that the generic component translator cannot infer. */
|
|
export function overrideRomPriestKnightEffects(
|
|
row: RomGeneratedAbilityLike,
|
|
translated: readonly AbilityEffect[],
|
|
): readonly AbilityEffect[] | null {
|
|
// These RuneWaker party buffs are self-targeted in their source rows, and
|
|
// their tooltip wording does not match the generic party-scope detector.
|
|
// Preserve the locally translated components and apply their auras to the
|
|
// party named by the source descriptions.
|
|
const partyBuff = (row.classId === "rom-priest" && row.secondaryClassId === undefined && row.sourceSkillId === 490298)
|
|
|| (row.classId === "rom-priest" && row.secondaryClassId === "rom-scout" && row.sourceSkillId === 491323)
|
|
|| (row.classId === "rom-priest" && row.secondaryClassId === "rom-rogue" && row.sourceSkillId === 492932);
|
|
if (partyBuff) {
|
|
return translated.map((effect) => effect.kind === "apply-aura" && (effect.aura.modifiers?.length ?? 0) > 0
|
|
? { ...effect, scope: "party" as const }
|
|
: effect);
|
|
}
|
|
|
|
if (row.classId === "rom-priest" && row.secondaryClassId === "rom-warrior" && row.sourceSkillId === 491600) {
|
|
return translated.map((effect) => effect.kind === "apply-aura" && effect.recipient === "caster"
|
|
? {
|
|
...effect,
|
|
aura: {
|
|
...effect.aura,
|
|
// All native Battle Monk stance components have a 900-second duration.
|
|
durationMs: 900_000,
|
|
utilityTags: [...(effect.aura.utilityTags ?? []), ROM_PRIEST_WARRIOR_BATTLE_MONK_STANCE_TAG],
|
|
},
|
|
}
|
|
: effect);
|
|
}
|
|
|
|
switch (row.sourceSkillId) {
|
|
case 492355: // Enhanced Grace of Life: Grace of Life also raises maximum MP.
|
|
return passiveState(492355, row.name, "rom-enhanced-grace-of-life");
|
|
case 492361: // Life Link: Urgent Heal also heals its caster.
|
|
return passiveState(492361, row.name, "rom-life-link");
|
|
case 499968: // Splendor Ripple: a triggered extra heal on source skill 499967.
|
|
return passiveState(499968, row.name, "rom-splendor-ripple");
|
|
case 499957: // Light Guidance: activate healing bonus only with source state 499966.
|
|
return passiveState(499957, row.name, "rom-light-guidance");
|
|
case 492638: // Lightning Rod: Lightning shocks targets already afflicted by Bone Chill.
|
|
return passiveState(492638, row.name, "rom-priest-mage-lightning-rod");
|
|
case 492928: // Grand Dispel: Purify also removes harmful effects, beyond curses.
|
|
return passiveState(492928, row.name, "rom-priest-mage-grand-dispel");
|
|
case 491610: // Enhanced Holy Strike: improves Holy Strike weapon damage.
|
|
return passiveState(491610, row.name, "rom-enhanced-holy-strike");
|
|
case 490066: // Weaken Weapon Strength: Heavenly Arrow weakens target physical damage.
|
|
return passiveState(490066, row.name, "rom-weaken-weapon-strength");
|
|
case 499926: // Evil Shackles: Holy Chains can root any creature with shorter duration.
|
|
return passiveState(499926, row.name, "rom-evil-shackles");
|
|
case 499923: // Blood Punishment modifies Blood Arrow while its source aura is active.
|
|
return passiveState(499923, row.name, ROM_KNIGHT_SCOUT_BLOOD_PUNISHMENT_TAG);
|
|
case 491648: // Last Prayer affects only the next spell's cast time.
|
|
return [{
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: {
|
|
id: "rom-pair-last-prayer-next-spell",
|
|
name: row.name,
|
|
disposition: "buff",
|
|
durationMs: null,
|
|
utilityTags: ["rom-last-prayer"],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: 51,
|
|
miscValue: -1_000,
|
|
triggerSpellId: 0,
|
|
}];
|
|
case 493271: // Light Fairy has source lifetime -1; keep it until dismissal or session end.
|
|
return translated.map((effect) => effect.kind === "summon"
|
|
? { ...effect, durationMs: 86_400_000 }
|
|
: effect);
|
|
case 492639: // Calm Heart, component 502908: 10 seconds of Fear immunity.
|
|
return [{
|
|
kind: "apply-aura",
|
|
recipient: "ability-target",
|
|
aura: {
|
|
id: "rom-pair-calm-heart-fear-immunity",
|
|
name: row.name,
|
|
disposition: "buff",
|
|
durationMs: 10_000,
|
|
controlImmunities: ["fear"],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: -1,
|
|
miscValue: 0,
|
|
triggerSpellId: 0,
|
|
}];
|
|
case 493046: // Sacred Protection, component 503290: +100 shield block for 20 seconds.
|
|
return [{
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: {
|
|
id: "rom-pair-sacred-protection-block",
|
|
name: row.name,
|
|
disposition: "buff",
|
|
durationMs: 20_000,
|
|
modifiers: [{ kind: "stat", stat: "block-chance", operation: "flat", value: 100 }],
|
|
utilityTags: ["rom-sacred-protection"],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: 172,
|
|
miscValue: 100,
|
|
triggerSpellId: 0,
|
|
}];
|
|
case 493273: // Disregard Danger: redirect 40% of one hit; caster gains 20 Parry.
|
|
return [
|
|
{
|
|
kind: "apply-aura",
|
|
recipient: "ability-target",
|
|
aura: {
|
|
id: "rom-pair-disregard-danger-redirect",
|
|
name: row.name,
|
|
disposition: "buff",
|
|
durationMs: 10_000,
|
|
redirectDamagePercent: 0.4,
|
|
utilityTags: ["rom-disregard-danger-one-hit"],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: 143,
|
|
miscValue: 40,
|
|
triggerSpellId: 491614,
|
|
},
|
|
{
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: {
|
|
id: "rom-pair-disregard-danger-parry",
|
|
name: `${row.name}: Parry`,
|
|
disposition: "buff",
|
|
durationMs: 10_000,
|
|
modifiers: [{ kind: "stat", stat: "parry", operation: "flat", value: 20 }],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: 22,
|
|
miscValue: 20,
|
|
triggerSpellId: 0,
|
|
},
|
|
];
|
|
case 491613: // Holy Chains only roots; source flag 67 is not three controls.
|
|
return translated.filter((effect) => effect.kind === "apply-aura" && effect.control?.kind === "root");
|
|
default:
|
|
return null;
|
|
}
|
|
}
|
|
|
|
function hasTag(tags: readonly string[] | ReadonlySet<string>, tag: string): boolean {
|
|
return Array.isArray(tags) ? tags.includes(tag) : (tags as ReadonlySet<string>).has(tag);
|
|
}
|
|
|
|
/** Apply passive pair upgrades when their parent skill is actually cast. */
|
|
export function romPriestKnightCastEffects(
|
|
ability: AbilityDefinition,
|
|
effects: readonly AbilityEffect[],
|
|
passiveTags: readonly string[] | ReadonlySet<string>,
|
|
casterMaxHealth: number,
|
|
targetTags: readonly string[] | ReadonlySet<string> = [],
|
|
friendlyTargetHealthPercent = 1,
|
|
learnedPassiveSpellIds: readonly number[] = [],
|
|
): readonly AbilityEffect[] {
|
|
if (ability.source !== "runewaker" || casterMaxHealth <= 0) return effects;
|
|
const priestChampionEffects = romPriestChampionCastEffects(ability, effects, learnedPassiveSpellIds);
|
|
if (priestChampionEffects !== effects) return priestChampionEffects;
|
|
const bloodPunishmentEffects = romKnightScoutBloodPunishmentActivationEffects(ability, effects, passiveTags);
|
|
if (bloodPunishmentEffects !== effects) return bloodPunishmentEffects;
|
|
if (ability.dbcSpellId === 490276
|
|
&& ability.classId === "rom-priest"
|
|
&& ability.secondaryClassId === undefined) {
|
|
// Current CoA keeps Holy Void as Priest-primary and its Voidal Infection
|
|
// lowers physical defense. Normalize that local stat alias to armor so the
|
|
// generic aura resolver applies it to both character and NPC targets. Keep
|
|
// magical-defense intact; NPCs use it for modeled resistances, but the
|
|
// simulator has no Light/Holy resistance stat to reduce this spell's hit.
|
|
return effects.map((effect) => effect.kind === "apply-aura"
|
|
&& effect.aura.id === "rom-priest-holy-void"
|
|
? {
|
|
...effect,
|
|
aura: {
|
|
...effect.aura,
|
|
modifiers: effect.aura.modifiers?.map((modifier) => (
|
|
modifier.kind === "stat" && modifier.stat === "physical-defense"
|
|
? { ...modifier, stat: "armor" }
|
|
: modifier
|
|
)),
|
|
},
|
|
}
|
|
: effect);
|
|
}
|
|
if (ability.dbcSpellId === 491588
|
|
&& ability.classId === "rom-mage"
|
|
&& ability.secondaryClassId === "rom-priest"
|
|
&& hasTag(passiveTags, "rom-priest-mage-grand-dispel")) {
|
|
// Purify's base tooltip/source row allows curse removal. Grand Dispel
|
|
// broadens the same one-effect friendly cleanse to harmful status types.
|
|
return effects.map((effect) => effect.kind === "dispel" && effect.mode === "cleanse"
|
|
? { ...effect, categories: ["magic", "curse", "poison", "disease"] }
|
|
: effect);
|
|
}
|
|
if (ability.dbcSpellId === 490261
|
|
&& learnedPassiveSpellIds.includes(493039)
|
|
&& friendlyTargetHealthPercent < 0.3) {
|
|
// Saint's Blessing's active source components grant +30 healing points and
|
|
// +1% healing power for 10 seconds. Put the aura before Heal so the
|
|
// triggering cast itself receives the sourced bonus as well.
|
|
return [{
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: {
|
|
id: "rom-priest-saints-blessing-healing",
|
|
name: "Saint's Blessing",
|
|
disposition: "buff",
|
|
durationMs: 10_000,
|
|
modifiers: [
|
|
{ kind: "healing", direction: "done", operation: "flat", value: 30 },
|
|
{ kind: "healing", direction: "done", operation: "percent", value: 0.01 },
|
|
],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: -1,
|
|
miscValue: 0,
|
|
triggerSpellId: 493039,
|
|
}, ...effects];
|
|
}
|
|
switch (ability.dbcSpellId) {
|
|
case 493044: // Holy Power expires after three successful casts of Heal.
|
|
return effects.map((effect) => effect.kind === "apply-aura" && effect.recipient === "caster"
|
|
? {
|
|
...effect,
|
|
aura: {
|
|
...effect.aura,
|
|
maxStacks: 3,
|
|
initialStacks: 3,
|
|
stackBehavior: "replace",
|
|
utilityTags: [...(effect.aura.utilityTags ?? []), ROM_PRIEST_KNIGHT_HOLY_POWER_HEAL_USES_TAG],
|
|
},
|
|
}
|
|
: effect);
|
|
case 490290: // Enhanced Grace of Life mirrors source Grace's +50 and +1% HP as MP.
|
|
if (!hasTag(passiveTags, "rom-enhanced-grace-of-life")) return effects;
|
|
return [...effects, {
|
|
kind: "apply-aura",
|
|
recipient: "ability-target",
|
|
aura: {
|
|
id: "rom-pair-enhanced-grace-mana",
|
|
name: "Enhanced Grace of Life: Mana",
|
|
disposition: "buff",
|
|
durationMs: 1_800_000,
|
|
modifiers: [
|
|
{ kind: "resource", resource: "mana", property: "maximum", operation: "flat", value: 50 },
|
|
{ kind: "resource", resource: "mana", property: "maximum", operation: "percent", value: 0.01 },
|
|
],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: 8,
|
|
miscValue: 50,
|
|
triggerSpellId: 492355,
|
|
}];
|
|
case 491147: // Life Link duplicates Urgent Heal's effective payload on the caster.
|
|
if (!hasTag(passiveTags, "rom-life-link")) return effects;
|
|
return [...effects, ...effects.filter((effect) => effect.kind === "heal")
|
|
.map((effect) => ({ ...effect, recipient: "caster" as const }))];
|
|
case 490148: // Enhanced Holy Strike adds a conservative hybrid weapon bonus.
|
|
if (!hasTag(passiveTags, "rom-enhanced-holy-strike")) return effects;
|
|
return effects.map((effect) => effect.kind === "damage"
|
|
? { ...effect, coefficient: effect.coefficient * 1.1 }
|
|
: effect);
|
|
case 491354: // Weaken Weapon Strength debuffs targets hit by Heavenly Arrow.
|
|
if (!hasTag(passiveTags, "rom-weaken-weapon-strength")) return effects;
|
|
return [...effects, {
|
|
kind: "apply-aura",
|
|
recipient: "ability-target",
|
|
aura: {
|
|
id: "rom-pair-heavenly-arrow-weaken",
|
|
name: "Weaken Weapon Strength",
|
|
disposition: "debuff",
|
|
durationMs: 10_000,
|
|
modifiers: [{ kind: "damage", direction: "dealt", school: "physical", operation: "percent", value: -0.1 }],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: -1,
|
|
miscValue: -10,
|
|
triggerSpellId: 490066,
|
|
}];
|
|
case 491613: { // Evil Shackles halves duration on non-undead/demon targets.
|
|
if (!hasTag(passiveTags, "rom-evil-shackles") || hasTag(targetTags, "rom-target-undead-demon")) return effects;
|
|
return effects.map((effect) => effect.kind === "apply-aura" && effect.control?.kind === "root"
|
|
? { ...effect, aura: { ...effect.aura, durationMs: Math.max(1_000, Math.round((effect.aura.durationMs ?? 10_000) / 2)) } }
|
|
: effect);
|
|
}
|
|
case 490273: // Source 499967 keeps Wave Armor's shield and adds heal component 623009.
|
|
if (!hasTag(passiveTags, "rom-splendor-ripple")) return effects;
|
|
return [...effects, {
|
|
kind: "heal",
|
|
recipient: "ability-target",
|
|
coefficient: 0,
|
|
basePoints: 106.25,
|
|
pointsPerLevel: 21.25,
|
|
sourceLevel: 1,
|
|
}];
|
|
case 499966: // Devotion Halo refreshes Light Guidance while the halo is active.
|
|
if (!hasTag(passiveTags, "rom-light-guidance")) return effects;
|
|
return [...effects, {
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: {
|
|
id: "rom-pair-light-guidance-healing",
|
|
name: "Light Guidance",
|
|
disposition: "buff",
|
|
durationMs: 900_000,
|
|
modifiers: [{ kind: "healing", direction: "done", operation: "percent", value: 0.05 }],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: 149,
|
|
miscValue: 5,
|
|
triggerSpellId: 623015,
|
|
}];
|
|
case 490212: // Lightning Rod adds source child 502907 only while Bone Chill is on the target.
|
|
if (!hasTag(passiveTags, "rom-priest-mage-lightning-rod")
|
|
|| !hasTag(targetTags, "rom-491165-501548-0")) return effects;
|
|
return [...effects, {
|
|
kind: "apply-aura",
|
|
recipient: "ability-target",
|
|
aura: {
|
|
id: "rom-priest-mage-lightning-rod-shock",
|
|
name: "Electric Shock",
|
|
disposition: "debuff",
|
|
durationMs: 20_000,
|
|
modifiers: [
|
|
{ kind: "stat", stat: "resistance:frost", operation: "flat", value: -50 },
|
|
{ kind: "stat", stat: "resistance:nature", operation: "flat", value: -50 },
|
|
],
|
|
utilityTags: ["rom-priest-mage-lightning-rod-shock"],
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: -1,
|
|
miscValue: 0,
|
|
triggerSpellId: 502907,
|
|
}];
|
|
default:
|
|
return effects;
|
|
}
|
|
}
|
|
|
|
/** Select the pair-specific payload branches that depend on target state. */
|
|
export function romPriestKnightConditionalCastEffects(
|
|
ability: AbilityDefinition,
|
|
effects: readonly AbilityEffect[],
|
|
sealStacks: number,
|
|
targetIsCaster: boolean,
|
|
): readonly AbilityEffect[] {
|
|
if (ability.source !== "runewaker"
|
|
|| ability.classId !== "rom-knight"
|
|
|| ability.secondaryClassId !== "rom-priest") return effects;
|
|
|
|
if (ability.dbcSpellId === 490194) {
|
|
const baseHit = effects.find((effect) => effect.kind === "damage");
|
|
if (!baseHit) return effects;
|
|
// The generated row carries a placeholder heal with no source-backed
|
|
// amount; only the Holy Seal components grant healing.
|
|
const nonDamage = effects.filter((effect) => effect.kind !== "damage" && effect.kind !== "heal");
|
|
const seals = Math.min(4, Math.max(0, Math.trunc(sealStacks)));
|
|
if (seals === 0) return [baseHit, ...nonDamage];
|
|
const healPercent = Math.min(8, seals * 2) / 100;
|
|
return [
|
|
baseHit,
|
|
...nonDamage,
|
|
{ kind: "heal", coefficient: 0, percentMaxHealth: healPercent, recipient: "caster" },
|
|
{
|
|
kind: "heal",
|
|
coefficient: 0,
|
|
percentMaxHealth: healPercent,
|
|
scope: "party",
|
|
center: "caster",
|
|
maximumTargets: 1,
|
|
excludeCaster: true,
|
|
},
|
|
{ kind: "combo", amount: -seals },
|
|
];
|
|
}
|
|
|
|
if (ability.dbcSpellId === 491640) {
|
|
const selectedThreatPolarity = targetIsCaster ? 1 : -1;
|
|
const hasThreatPayload = effects.some((effect) => effect.kind === "apply-aura"
|
|
&& effect.aura.modifiers?.some((modifier) => modifier.kind === "stat" && modifier.stat === "threat"));
|
|
if (!hasThreatPayload) return effects;
|
|
return effects.map((effect) => effect.kind === "apply-aura" && effect.aura.modifiers?.some((modifier) =>
|
|
modifier.kind === "stat" && modifier.stat === "threat")
|
|
? {
|
|
...effect,
|
|
aura: {
|
|
...effect.aura,
|
|
modifiers: effect.aura.modifiers?.map((modifier) => modifier.kind === "stat" && modifier.stat === "threat"
|
|
? { ...modifier, value: Math.abs(modifier.value) * selectedThreatPolarity }
|
|
: modifier),
|
|
},
|
|
}
|
|
: effect);
|
|
}
|
|
|
|
return effects;
|
|
}
|
|
|
|
/** Source skill 499966 is granted by the level-70 Priest/Knight elite pair. */
|
|
export function romPriestKnightAdditionalAbilities(
|
|
catalog: readonly AbilityDefinition[],
|
|
): readonly AbilityDefinition[] {
|
|
const lightGuidance = catalog.find((ability) => ability.dbcSpellId === 499957
|
|
&& ability.classId === "rom-priest" && ability.secondaryClassId === "rom-knight");
|
|
if (!lightGuidance) return [];
|
|
const effects: readonly AbilityEffect[] = [{
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
scope: "party",
|
|
aura: {
|
|
id: "rom-pair-devotion-halo",
|
|
name: "Devotion Halo",
|
|
disposition: "buff",
|
|
durationMs: 900_000,
|
|
modifiers: [{ kind: "stat", stat: "wisdom", operation: "percent", value: 0.05 }],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: 164,
|
|
miscValue: 5,
|
|
triggerSpellId: 623016,
|
|
}, {
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
scope: "party",
|
|
excludeCaster: true,
|
|
aura: {
|
|
id: "rom-pair-devotion-halo-mana",
|
|
name: "Devotion Halo Mana",
|
|
disposition: "buff",
|
|
durationMs: 900_000,
|
|
modifiers: [{ kind: "resource", resource: "mana", property: "cost", operation: "percent", value: -0.06 }],
|
|
dispelCategory: "magic",
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: 164,
|
|
miscValue: -6,
|
|
triggerSpellId: 623016,
|
|
}];
|
|
return [{
|
|
id: "rom-priest-rom-knight-elite-70-devotion-halo",
|
|
classId: "rom-priest",
|
|
secondaryClassId: "rom-knight",
|
|
dbcSpellId: 499966,
|
|
name: "Devotion Halo",
|
|
unlockLevel: 70,
|
|
icon: lightGuidance.icon,
|
|
sigil: "DH",
|
|
description: "Raises party Wisdom by 5% and lowers party mana costs by 6% for 15 minutes.",
|
|
target: "self",
|
|
range: { min: 0, max: 5 },
|
|
radius: 20,
|
|
castMode: "instant",
|
|
castTimeMs: 0,
|
|
cooldownMs: 0,
|
|
gcdMs: 1_500,
|
|
cost: { resource: "mana", amount: 0 },
|
|
costs: [],
|
|
effects,
|
|
passive: false,
|
|
source: "runewaker",
|
|
sourceUnlockLevel: 70,
|
|
romSkillGroup: "elite",
|
|
}];
|
|
}
|