import type { AuraDefinition } from "./combatAuras"; export const WOW335_MAGE_ARCANE_POTENCY_TALENT_ID = "talent-1725"; export const WOW335_MAGE_MASTER_OF_ELEMENTS_TALENT_ID = "talent-1639"; export const WOW335_MAGE_ARCANE_POTENCY_TAG = "wow335-mage-arcane-potency"; const ARCANE_POTENCY_CRIT_BONUS_PERCENT_BY_RANK = [0, 15, 30] as const; export type Wow335MageArcanePotencyTrigger = | "presence-of-mind" | "arcane-concentration-clearcasting" | "other"; export interface Wow335MageArcanePotencyCastProfile { readonly consumesCharge: boolean; readonly criticalChanceBonusPercent: number; } function normalizedRank(rank: number, maximum: number): number { return Number.isFinite(rank) ? Math.max(0, Math.min(maximum, Math.trunc(rank))) : 0; } /** Local talent rank rows 31571/31572 grant 15%/30% crit to the next damaging spell. */ export function wow335MageArcanePotencyCriticalChanceBonusPercent(rank: number): number { return ARCANE_POTENCY_CRIT_BONUS_PERCENT_BY_RANK[normalizedRank(rank, 2)] ?? 0; } /** * Arcane Potency is earned only from Presence of Mind or Arcane Concentration's * Clearcasting proc. A different source of Clearcasting does not qualify. */ export function wow335MageArcanePotencyCanProc( rank: number, trigger: Wow335MageArcanePotencyTrigger, ): boolean { return normalizedRank(rank, 2) > 0 && trigger !== "other"; } /** * The next damaging spell gains the rank's crit bonus. The tooltip consumes * the buff on any spell cast, so callers consume whenever `auraActive` is true, * even if the cast cannot deal damage or critically strike. */ export function wow335MageArcanePotencyCastProfile( rank: number, auraActive: boolean, abilityDealsDirectDamage: boolean, ): Wow335MageArcanePotencyCastProfile { return { consumesCharge: auraActive, criticalChanceBonusPercent: auraActive && abilityDealsDirectDamage ? wow335MageArcanePotencyCriticalChanceBonusPercent(rank) : 0, }; } export const WOW335_MAGE_ARCANE_POTENCY_AURA: AuraDefinition = { id: "wow335:mage:arcane-potency", name: "Arcane Potency", description: "Your next damaging spell gains critical strike chance after Presence of Mind or Clearcasting.", disposition: "buff", // The generated row supplies no expiration; the aura is consumed on the next spell cast. durationMs: null, maxStacks: 1, stackBehavior: "replace", utilityTags: [WOW335_MAGE_ARCANE_POTENCY_TAG], }; /** * The passive +1/2/3% spell crit is already represented by generated rank * descriptions in talentModifiers. Only rank 3 (spell 29076) has the * executable local auraType 4 mana-refund effect; ranks 1/2 have effectType 0. */ export function wow335MageMasterOfElementsManaRefundPercent(rank: number): number { return normalizedRank(rank, 3) === 3 ? 40 : 0; } /** * Refund 40% of the Mana actually spent by an eligible direct spell critical. * “Direct” excludes periodic damage, including channel pulses and DoT ticks; * callers supply false for those events. The caller supplies the resolved spend * after cast discounts (for example, Clearcasting makes that spend zero). */ export function wow335MageMasterOfElementsManaRefund( rank: number, manaSpent: number, directDamageSpell: boolean, critical: boolean, ): number { const refundPercent = wow335MageMasterOfElementsManaRefundPercent(rank); if (refundPercent <= 0 || !directDamageSpell || !critical || !Number.isFinite(manaSpent)) return 0; return Math.max(0, Math.round(Math.max(0, manaSpent) * refundPercent / 100)); }