Files
healer-man/src/game/wow335WarriorVictoryRushRuntime.ts
T
2026-10-02 10:38:12 -04:00

147 lines
5.3 KiB
TypeScript

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],
};
}