import { WOW335_TALENT_NODES } from "./wow335Talents.generated"; import type { AuraDefinition } from "./combatAuras"; export const WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_TALENT_ID = "talent-161"; export const WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_READY_TAG = "wow335-warrior-improved-victory-rush-ready"; export const WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_COOLDOWN_TAG = "wow335-warrior-improved-victory-rush-cooldown"; export const WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_ABILITY_ID = "wow335-warrior-improved-victory-rush"; export const WOW335_WARRIOR_VICTORY_RUSH_KILL_READY_TAG = "wow335-warrior-victory-rush-kill-ready"; export const WOW335_WARRIOR_VICTORY_RUSH_KILL_WINDOW_MS = 20_000; export interface Wow335WarriorImprovedVictoryRushProfile { readonly rank: number; readonly parryProcChancePercent: number; readonly criticalChanceBonusPercent: number; readonly additionalThreatPercent: number; readonly readyDurationMs: number; readonly internalCooldownMs: number; } const talent = WOW335_TALENT_NODES.find((node) => ( node.id === WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_TALENT_ID )); function boundedRank(rank: number): number { return Math.min(3, Math.max(0, Math.trunc(Number.isFinite(rank) ? rank : 0))); } function parsePositiveMatch(text: string | undefined, pattern: RegExp): number { const value = Number(text?.match(pattern)?.[1]); return Number.isFinite(value) && value > 0 ? value : 0; } export function wow335WarriorImprovedVictoryRushProfile( rank: number, ): Wow335WarriorImprovedVictoryRushProfile { const safeRank = boundedRank(rank); const rankIndex = safeRank - 1; const rankDescription = safeRank > 0 ? talent?.rankDescriptions[rankIndex] : undefined; return { rank: safeRank, parryProcChancePercent: safeRank > 0 ? talent?.rankEffects[rankIndex]?.procChance ?? 0 : 0, criticalChanceBonusPercent: parsePositiveMatch( rankDescription, /critical strike chance of your Victory Rush by (\d+)%/i, ), additionalThreatPercent: parsePositiveMatch( rankDescription, /additional (\d+)% threat/i, ), readyDurationMs: parsePositiveMatch( talent?.description, /allow the use of Victory Rush for (\d+) seconds/i, ) * 1_000, internalCooldownMs: parsePositiveMatch( talent?.description, /once every (\d+) seconds/i, ) * 1_000, }; } /** A successful parry can arm the generated Victory Rush window unless its ICD is active. */ export function wow335WarriorImprovedVictoryRushShouldProc( rank: number, parried: boolean, internalCooldownActive: boolean, rollPercent: number, ): boolean { const profile = wow335WarriorImprovedVictoryRushProfile(rank); return profile.rank > 0 && parried && !internalCooldownActive && Number.isFinite(rollPercent) && rollPercent >= 0 && rollPercent < profile.parryProcChancePercent; } /** The tooltip's permanent rank bonus applies to every Victory Rush hit. */ export function wow335WarriorImprovedVictoryRushCriticalChanceBonusPercent( rank: number, abilityName: string, ): number { if (abilityName.trim().toLowerCase() !== "victory rush") return 0; return wow335WarriorImprovedVictoryRushProfile(rank).criticalChanceBonusPercent; } /** The extra-threat rider applies only to Victory Rush casts made from the parry window. */ export function wow335WarriorImprovedVictoryRushThreatScale( rank: number, abilityName: string, parryWindowReady: boolean, ): number { if (!parryWindowReady || abilityName.trim().toLowerCase() !== "victory rush") return 1; return 1 + wow335WarriorImprovedVictoryRushProfile(rank).additionalThreatPercent / 100; } export function wow335WarriorImprovedVictoryRushReadyAuraDefinition( rank: number, ): AuraDefinition | null { const profile = wow335WarriorImprovedVictoryRushProfile(rank); if (profile.rank <= 0 || profile.readyDurationMs <= 0) return null; return { id: WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_READY_TAG, name: "Victory Rush ready", description: `A parry enables Victory Rush with ${profile.additionalThreatPercent}% additional threat.`, disposition: "buff", durationMs: profile.readyDurationMs, maxStacks: 1, stackBehavior: "refresh", uniqueBySource: true, utilityTags: [WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_READY_TAG], }; } export function wow335WarriorImprovedVictoryRushCooldownAuraDefinition( rank: number, ): AuraDefinition | null { const profile = wow335WarriorImprovedVictoryRushProfile(rank); if (profile.rank <= 0 || profile.internalCooldownMs <= 0) return null; return { id: WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_COOLDOWN_TAG, name: "Improved Victory Rush cooldown", disposition: "buff", durationMs: profile.internalCooldownMs, maxStacks: 1, stackBehavior: "refresh", hideFromAuraStrip: true, uniqueBySource: true, utilityTags: [WOW335_WARRIOR_IMPROVED_VICTORY_RUSH_COOLDOWN_TAG], }; } export function wow335WarriorVictoryRushKillAuraDefinition(): AuraDefinition { return { id: WOW335_WARRIOR_VICTORY_RUSH_KILL_READY_TAG, name: "Victory Rush ready", description: "A qualifying kill enables Victory Rush for 20 seconds.", disposition: "buff", durationMs: WOW335_WARRIOR_VICTORY_RUSH_KILL_WINDOW_MS, maxStacks: 1, stackBehavior: "refresh", uniqueBySource: true, utilityTags: [WOW335_WARRIOR_VICTORY_RUSH_KILL_READY_TAG], }; }