import { abilityAtLevel, type AbilityDefinition } from "./abilityCatalog"; import { WOW335_ABILITIES_BY_CLASS } from "./wow335AbilityCatalog"; const IMPROVED_WATER_SHIELD_CRITICAL_CHANCE_BY_RANK = [0, 0.1, 0.2, 0.3] as const; const IMPROVED_WATER_SHIELD_NORMAL_CHANCE_BY_RANK = [0, 0.05, 0.1, 0.15] as const; const IMPROVED_SHIELDS_WATER_SHIELD_MANA_BONUS_BY_RANK = [0, 5, 10, 15] as const; export function wow335ShamanImprovedShieldsWaterShieldManaBonusPercent(rank: number): number { const normalizedRank = Number.isFinite(rank) ? Math.max(0, Math.min(3, Math.trunc(rank))) : 0; return IMPROVED_SHIELDS_WATER_SHIELD_MANA_BONUS_BY_RANK[normalizedRank] ?? 0; } export function wow335ShamanImprovedWaterShieldProcChance( rank: number, abilityName: string, school: string, critical: boolean, ): number { const normalizedRank = Number.isFinite(rank) ? Math.max(0, Math.min(3, Math.trunc(rank))) : 0; if (normalizedRank <= 0 || school !== "nature") return 0; const chances = critical ? IMPROVED_WATER_SHIELD_CRITICAL_CHANCE_BY_RANK : IMPROVED_WATER_SHIELD_NORMAL_CHANCE_BY_RANK; const chance = chances[normalizedRank] ?? 0; return abilityName === "Healing Wave" ? Math.min(1, chance * 2) : chance; } export function wow335ShamanImprovedWaterShieldShouldProc( rank: number, abilityName: string, school: string, critical: boolean, roll: number, ): boolean { const chance = wow335ShamanImprovedWaterShieldProcChance(rank, abilityName, school, critical); return chance > 0 && Number.isFinite(roll) && roll >= 0 && roll < chance; } export function wow335ShamanWaterShieldOrbManaAtLevel(level: number, improvedShieldsRank = 0): number { const waterShield = WOW335_ABILITIES_BY_CLASS.shaman.find((ability) => ability.name === "Water Shield"); if (!waterShield) return 0; const rankedWaterShield = abilityAtLevel(waterShield, level); const orbProc = rankedWaterShield.effects .filter((effect): effect is Extract => ( effect.kind === "apply-aura" )) .flatMap((effect) => effect.aura.procs ?? []) .find((proc) => proc.id.endsWith(":water-shield") && proc.action.kind === "resource" && proc.action.resource === "mana"); if (orbProc?.action.kind !== "resource") return 0; const baseMana = Math.max(0, orbProc.action.amount); return Math.round(baseMana * (1 + wow335ShamanImprovedShieldsWaterShieldManaBonusPercent(improvedShieldsRank) / 100)); } export function wow335ShamanImprovedWaterShieldCappedRestore( currentMana: number, maximumMana: number, requestedMana: number, ): number { if (![currentMana, maximumMana, requestedMana].every(Number.isFinite)) return 0; return Math.max(0, Math.min(Math.max(0, requestedMana), maximumMana - currentMana)); }