forked from phenom/healer-man
115 lines
4.3 KiB
TypeScript
115 lines
4.3 KiB
TypeScript
import type { AbilityEffect } from "./abilityCatalog";
|
||
import { resolveDamageValue, resolveStatValue, type ActiveAura, type DamageSchool } from "./combatAuras";
|
||
import type { RomGeneratedAbilityLike } from "./romAbilitySemantics";
|
||
|
||
export const ROM_PRIEST_HOLY_BLESSING = Object.freeze({
|
||
spellId: 490_274,
|
||
wisdomFlat: 115,
|
||
wisdomPercent: 10.5,
|
||
lightDamagePercent: 100.9,
|
||
});
|
||
|
||
export const ROM_PRIEST_HOLY_BLESSING_TAG = "rom-priest:490274:holy-blessing";
|
||
|
||
/** Resolve CoA's `(current Wisdom + 115) × 10.5% + 115` stat stage. */
|
||
export function romPriestHolyBlessingWisdom(currentWisdom: number): number {
|
||
const wisdom = Number.isFinite(currentWisdom) ? Math.max(0, currentWisdom) : 0;
|
||
return (wisdom + ROM_PRIEST_HOLY_BLESSING.wisdomFlat)
|
||
* (1 + ROM_PRIEST_HOLY_BLESSING.wisdomPercent / 100);
|
||
}
|
||
|
||
export interface RomPriestHolyBlessingStats {
|
||
readonly intellect: number;
|
||
readonly currentWisdom: number;
|
||
readonly wisdom: number;
|
||
readonly spellPowerBonus: number;
|
||
readonly active: boolean;
|
||
}
|
||
|
||
/**
|
||
* Resolve existing primary-stat modifiers first, then apply Holy Blessing to
|
||
* that current Wisdom. Its spell-power bonus is only the incremental Spirit
|
||
* conversion; generic spell-power aura modifiers remain on their normal path.
|
||
*/
|
||
export function romPriestHolyBlessingStats(
|
||
base: { readonly intellect: number; readonly spirit: number },
|
||
auras: readonly ActiveAura[],
|
||
): RomPriestHolyBlessingStats {
|
||
const active = auras.some((aura) => aura.definition.utilityTags?.includes(ROM_PRIEST_HOLY_BLESSING_TAG));
|
||
const existingAuras = active
|
||
? auras.filter((aura) => !aura.definition.utilityTags?.includes(ROM_PRIEST_HOLY_BLESSING_TAG))
|
||
: auras;
|
||
const primary = (value: number, ...names: string[]) => names.reduce(
|
||
(current, stat) => resolveStatValue(current, existingAuras, stat),
|
||
value,
|
||
);
|
||
const intellect = primary(base.intellect, "intellect", "all-primary", "all-primary-attributes");
|
||
const currentWisdom = primary(base.spirit, "spirit", "wisdom", "all-primary", "all-primary-attributes");
|
||
const wisdom = active ? romPriestHolyBlessingWisdom(currentWisdom) : currentWisdom;
|
||
const spellPowerBonus = active
|
||
? Math.round(intellect * 0.35 + wisdom * 0.15)
|
||
- Math.round(intellect * 0.35 + currentWisdom * 0.15)
|
||
: 0;
|
||
return { intellect, currentWisdom, wisdom, spellPowerBonus, active };
|
||
}
|
||
|
||
/** Apply Holy Blessing's source-only Light/Holy damage modifier without widening its school scope. */
|
||
export function romPriestHolyBlessingDamage(
|
||
amount: number,
|
||
auras: readonly ActiveAura[],
|
||
school: DamageSchool,
|
||
): number {
|
||
const blessingAuras = auras.filter((aura) => aura.definition.utilityTags?.includes(ROM_PRIEST_HOLY_BLESSING_TAG));
|
||
return resolveDamageValue(amount, blessingAuras, { direction: "dealt", school, attackKind: "spell" });
|
||
}
|
||
|
||
export const ROM_PRIEST_HOLY_BLESSING_PASSIVE_EFFECT: Extract<AbilityEffect, { kind: "apply-aura" }> = {
|
||
kind: "apply-aura",
|
||
recipient: "caster",
|
||
aura: {
|
||
id: ROM_PRIEST_HOLY_BLESSING_TAG,
|
||
name: "Holy Blessing",
|
||
description: "Increases Wisdom by (current Wisdom + 115) × 10.5% + 115 and Light Damage by 100.9%.",
|
||
disposition: "buff",
|
||
durationMs: null,
|
||
maxStacks: 1,
|
||
stackBehavior: "refresh",
|
||
utilityTags: [ROM_PRIEST_HOLY_BLESSING_TAG],
|
||
modifiers: [
|
||
{
|
||
kind: "stat",
|
||
stat: "wisdom",
|
||
operation: "flat",
|
||
value: ROM_PRIEST_HOLY_BLESSING.wisdomFlat,
|
||
},
|
||
{
|
||
kind: "stat",
|
||
stat: "wisdom",
|
||
operation: "percent",
|
||
value: ROM_PRIEST_HOLY_BLESSING.wisdomPercent / 100,
|
||
},
|
||
{
|
||
kind: "damage",
|
||
direction: "dealt",
|
||
school: "holy",
|
||
operation: "percent",
|
||
value: ROM_PRIEST_HOLY_BLESSING.lightDamagePercent / 100,
|
||
},
|
||
],
|
||
},
|
||
sourceEffectType: -1,
|
||
sourceAuraType: -1,
|
||
miscValue: ROM_PRIEST_HOLY_BLESSING.wisdomPercent,
|
||
triggerSpellId: ROM_PRIEST_HOLY_BLESSING.spellId,
|
||
};
|
||
|
||
/** Holy Blessing belongs only to the Priest primary skill set. */
|
||
export function romPriestHolyBlessingEffects(
|
||
row: RomGeneratedAbilityLike,
|
||
): readonly AbilityEffect[] | null {
|
||
if (row.classId !== "rom-priest"
|
||
|| row.secondaryClassId !== undefined
|
||
|| row.sourceSkillId !== ROM_PRIEST_HOLY_BLESSING.spellId) return null;
|
||
return [ROM_PRIEST_HOLY_BLESSING_PASSIVE_EFFECT];
|
||
}
|