forked from phenom/healer-man
68 lines
2.8 KiB
TypeScript
68 lines
2.8 KiB
TypeScript
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<AbilityDefinition["effects"][number], { kind: "apply-aura" }> => (
|
|
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));
|
|
}
|