84 lines
3.2 KiB
TypeScript
84 lines
3.2 KiB
TypeScript
import type { AuraDefinition } from "./combatAuras";
|
|
import { WOW335_TALENT_NODES } from "./wow335Talents.generated";
|
|
|
|
export const WOW335_DEATH_KNIGHT_DESOLATION_TALENT_ID = "talent-2285";
|
|
export const WOW335_DEATH_KNIGHT_BLOOD_STRIKE_SPELL_ID = 45_902;
|
|
export const WOW335_DEATH_KNIGHT_BLOOD_STRIKE_ABILITY_ID = "wow335-death-knight-blood-strike";
|
|
export const WOW335_DEATH_KNIGHT_DESOLATION_AURA_ID = "wow335:death-knight:desolation";
|
|
|
|
const DESOLATION_NODE = WOW335_TALENT_NODES.find(
|
|
(node) => node.id === WOW335_DEATH_KNIGHT_DESOLATION_TALENT_ID,
|
|
);
|
|
|
|
export interface Wow335DeathKnightDesolationProfile {
|
|
readonly rank: number;
|
|
readonly damageBonus: number;
|
|
readonly durationMs: number;
|
|
readonly triggerSpellId: number;
|
|
}
|
|
|
|
/**
|
|
* Read the rank value and child trigger directly from the generated local DBC
|
|
* talent row. The resolved tooltip is the source for the hidden child buff's
|
|
* percentage and duration; fail closed if that generated text no longer fits.
|
|
*/
|
|
export function wow335DeathKnightDesolationProfile(
|
|
rank: number,
|
|
): Wow335DeathKnightDesolationProfile | null {
|
|
const normalizedRank = Math.trunc(rank);
|
|
const talentRank = DESOLATION_NODE?.rankEffects[normalizedRank - 1];
|
|
const description = DESOLATION_NODE?.rankDescriptions[normalizedRank - 1];
|
|
if (normalizedRank < 1 || !talentRank || !description || talentRank.procChance !== 100) return null;
|
|
|
|
const values = description.match(
|
|
/^Your Blood Strikes cause you to deal (\d+(?:\.\d+)?)% additional damage with all attacks for the next (\d+(?:\.\d+)?) seconds\.$/,
|
|
);
|
|
const triggerSpellId = talentRank.effects.find((effect) => effect.triggerSpellId > 0)?.triggerSpellId ?? 0;
|
|
if (!values || triggerSpellId <= 0) return null;
|
|
|
|
const damageBonus = Number(values[1]) / 100;
|
|
const durationMs = Number(values[2]) * 1_000;
|
|
if (!Number.isFinite(damageBonus) || damageBonus <= 0 || !Number.isFinite(durationMs) || durationMs <= 0) return null;
|
|
return { rank: normalizedRank, damageBonus, durationMs, triggerSpellId };
|
|
}
|
|
|
|
/** A landed Blood Strike refreshes the source-defined child buff. */
|
|
export function wow335DeathKnightDesolationShouldTrigger(
|
|
rank: number,
|
|
triggeringAbilityId: string,
|
|
hitLanded: boolean,
|
|
isMainHandHit = true,
|
|
): boolean {
|
|
return hitLanded
|
|
&& isMainHandHit
|
|
&& triggeringAbilityId === WOW335_DEATH_KNIGHT_BLOOD_STRIKE_ABILITY_ID
|
|
&& wow335DeathKnightDesolationProfile(rank) !== null;
|
|
}
|
|
|
|
/**
|
|
* Build the generic all-school damage-done aura used by both player and
|
|
* generated-companion casts. No school or attack-kind filter is present:
|
|
* the generated tooltip says "all attacks".
|
|
*/
|
|
export function wow335DeathKnightDesolationAuraDefinition(
|
|
rank: number,
|
|
): AuraDefinition | null {
|
|
const profile = wow335DeathKnightDesolationProfile(rank);
|
|
if (!profile) return null;
|
|
return {
|
|
id: WOW335_DEATH_KNIGHT_DESOLATION_AURA_ID,
|
|
name: "Desolation",
|
|
description: `Blood Strike increases damage dealt by ${Math.round(profile.damageBonus * 100)}% for ${profile.durationMs / 1_000} seconds.`,
|
|
disposition: "buff",
|
|
durationMs: profile.durationMs,
|
|
maxStacks: 1,
|
|
stackBehavior: "replace",
|
|
modifiers: [{
|
|
kind: "damage",
|
|
direction: "dealt",
|
|
operation: "percent",
|
|
value: profile.damageBonus,
|
|
}],
|
|
};
|
|
}
|