80 lines
3.0 KiB
TypeScript
80 lines
3.0 KiB
TypeScript
import type { AbilityDefinition, AbilityEffect } from "./abilityCatalog";
|
|
|
|
const SOUL_CLEANSING_TAG = "rom-priest-warlock-soul-cleansing-ceremony";
|
|
|
|
/** Source-specific Priest/Warlock passive and cleanse mechanics. */
|
|
export function overrideRomPriestWarlockEffects(
|
|
row: { readonly sourceSkillId: number; readonly name: string; readonly classId?: string; readonly secondaryClassId?: string },
|
|
translated: readonly AbilityEffect[],
|
|
): readonly AbilityEffect[] | null {
|
|
if (row.sourceSkillId === 498771
|
|
&& row.classId === "rom-priest"
|
|
&& row.secondaryClassId === "rom-warlock") {
|
|
return [{
|
|
kind: "apply-aura",
|
|
recipient: "caster",
|
|
aura: {
|
|
id: "rom-priest-warlock-soul-cleansing-ceremony",
|
|
name: row.name,
|
|
disposition: "buff",
|
|
durationMs: null,
|
|
utilityTags: [SOUL_CLEANSING_TAG],
|
|
},
|
|
sourceEffectType: -1,
|
|
sourceAuraType: -1,
|
|
miscValue: 0,
|
|
triggerSpellId: 498771,
|
|
}];
|
|
}
|
|
|
|
if (row.sourceSkillId === 491175 && row.classId === "rom-priest") {
|
|
// Soul Cleansing Ceremony explicitly adds cursed states to Cleanse. Keep
|
|
// the base cleanse on the other modeled harmful categories so the
|
|
// passive has a real, pair-specific effect.
|
|
return translated.map((effect) => effect.kind === "dispel" && effect.mode === "cleanse"
|
|
? { ...effect, categories: ["magic", "poison", "disease"] }
|
|
: effect);
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
/** Select local Prayer of Tribulation buff stacks from its tooltip HP gates. */
|
|
export function romPriestWarlockCastEffects(
|
|
ability: AbilityDefinition,
|
|
effects: readonly AbilityEffect[],
|
|
friendlyTargetHealthPercent: number,
|
|
passiveTags: readonly string[] | ReadonlySet<string> = [],
|
|
): readonly AbilityEffect[] {
|
|
if (ability.source !== "runewaker" || ability.classId !== "rom-priest") return effects;
|
|
const hasSoulCleansing = Array.isArray(passiveTags)
|
|
? passiveTags.includes(SOUL_CLEANSING_TAG)
|
|
: (passiveTags as ReadonlySet<string>).has(SOUL_CLEANSING_TAG);
|
|
if (ability.dbcSpellId === 491175 && hasSoulCleansing) {
|
|
return effects.map((effect) => effect.kind === "dispel" && effect.mode === "cleanse"
|
|
? { ...effect, categories: [...(effect.categories ?? []), "curse"] }
|
|
: effect);
|
|
}
|
|
if (ability.secondaryClassId !== "rom-warlock" || ability.dbcSpellId !== 498770) return effects;
|
|
|
|
const buff = effects.find((effect): effect is Extract<AbilityEffect, { kind: "apply-aura" }> => (
|
|
effect.kind === "apply-aura"
|
|
));
|
|
if (!buff || friendlyTargetHealthPercent === 0.4) return effects.filter((effect) => effect !== buff);
|
|
|
|
const stacks = friendlyTargetHealthPercent < 0.4 ? 2 : 1;
|
|
const stackedBuff: Extract<AbilityEffect, { kind: "apply-aura" }> = {
|
|
...buff,
|
|
aura: {
|
|
...buff.aura,
|
|
maxStacks: 8,
|
|
stackBehavior: "add",
|
|
modifiers: buff.aura.modifiers?.map((modifier) => ({ ...modifier, perStack: true })),
|
|
},
|
|
};
|
|
return [
|
|
...effects.filter((effect) => effect !== buff),
|
|
...Array.from({ length: stacks }, () => stackedBuff),
|
|
];
|
|
}
|