37 lines
1.5 KiB
TypeScript
37 lines
1.5 KiB
TypeScript
import { WOW335_TALENT_NODES } from "./wow335Talents.generated";
|
|
|
|
export const WOW335_WARRIOR_CRITICAL_BLOCK_TALENT_ID = "talent-1893";
|
|
export const WOW335_PALADIN_TOUCHED_BY_THE_LIGHT_TALENT_ID = "talent-2195";
|
|
|
|
const CRITICAL_BLOCK_SOURCE = WOW335_TALENT_NODES.find((node) => (
|
|
node.id === WOW335_WARRIOR_CRITICAL_BLOCK_TALENT_ID
|
|
));
|
|
|
|
function normalizedRank(rank: number): number {
|
|
return Number.isFinite(rank) ? Math.max(0, Math.min(3, Math.trunc(rank))) : 0;
|
|
}
|
|
|
|
/** Reads the generated tooltip's rank-specific extra reduction on a blocked hit. */
|
|
export function wow335WarriorCriticalBlockReductionPercent(rank: number): number {
|
|
const safeRank = normalizedRank(rank);
|
|
if (safeRank === 0) return 0;
|
|
const description = CRITICAL_BLOCK_SOURCE?.rankDescriptions[safeRank - 1];
|
|
const value = Number(description?.match(/reduce the damage you take from the blocked hit by (\d+)%/i)?.[1]);
|
|
return Number.isFinite(value) ? value : 0;
|
|
}
|
|
|
|
/** Applies the generated reduction to post-block damage when source exclusions allow it. */
|
|
export function wow335WarriorCriticalBlockDamage(
|
|
postBlockDamage: number,
|
|
rank: number,
|
|
blocked: boolean,
|
|
attackerIsPlayer: boolean,
|
|
touchedByTheLightRank: number,
|
|
): number {
|
|
if (!Number.isFinite(postBlockDamage)) return 0;
|
|
const damage = Math.max(0, postBlockDamage);
|
|
if (!blocked || attackerIsPlayer || normalizedRank(touchedByTheLightRank) > 0) return Math.round(damage);
|
|
const reductionPercent = wow335WarriorCriticalBlockReductionPercent(rank);
|
|
return Math.round(damage * (1 - reductionPercent / 100));
|
|
}
|