Files
healer-man/src/game/enemyBloodlust.ts
T
2026-10-06 22:25:34 -04:00

77 lines
2.5 KiB
TypeScript

import type { ActiveAura } from "./combatAuras";
import type { EnemyAuraSourceProfile, EnemySourceAuraContract } from "./enemySourceAuras";
const BLOODLUST_EFFECT = Object.freeze({
effectType: 6,
auraType: 138,
basePoints: 30,
mechanic: 0,
implicitTargetA: 21,
implicitTargetB: 0,
radius: 0,
miscValue: 0,
periodMs: 0,
});
const bloodlustContract = (profile: EnemyAuraSourceProfile): EnemySourceAuraContract => Object.freeze({
spellId: 6742,
name: "Bloodlust",
profile,
signature: Object.freeze({
rangeIndex: 4,
schoolMask: 8,
damageClass: 1,
durationMs: 30_000,
effects: Object.freeze([BLOODLUST_EFFECT]),
}),
durationMs: 30_000,
targetGeometry: Object.freeze({ kind: "explicit-friendly", rangeYards: 30 }),
disposition: "buff",
dispelCategory: "magic",
stackAmount: 0,
childTriggerSpellIds: Object.freeze([]),
modifiers: Object.freeze([
Object.freeze({ kind: "stat", stat: "melee-haste", operation: "flat", value: 30, multiplicative: true }),
]),
unsupportedEffects: Object.freeze([]),
});
const CONTRACTS: Readonly<Record<EnemyAuraSourceProfile, EnemySourceAuraContract>> = Object.freeze({
ascension: bloodlustContract("ascension"),
epoch: bloodlustContract("epoch"),
});
/** Return the profile-specific audited Spell.dbc contract for NPC Bloodlust 6742. */
export function enemyBloodlustContract(profile: EnemyAuraSourceProfile): EnemySourceAuraContract {
return CONTRACTS[profile];
}
/**
* Return the remaining main-hand/off-hand swing interval multiplier for one
* enemy's already-filtered active auras. Marked source Aura 138 modifiers use
* AzerothCore's separate percent speed factors; unmarked modifiers retain the
* runtime's existing additive haste calculation as a compatibility fallback.
*/
export function enemyMeleeHasteIntervalMultiplier(auras: readonly ActiveAura[]): number {
let sourceIntervalMultiplier = 1;
let additiveHastePercent = 0;
for (const aura of auras) {
for (const modifier of aura.definition.modifiers ?? []) {
if (modifier.kind !== "stat" || modifier.stat !== "melee-haste" || modifier.operation !== "flat") continue;
const hastePercent = modifier.value * (modifier.perStack === false ? 1 : aura.stacks);
if (!modifier.multiplicative) {
additiveHastePercent += hastePercent;
continue;
}
sourceIntervalMultiplier *= hastePercent >= 0
? 1 / Math.max(0.01, 1 + hastePercent / 100)
: 1 + Math.abs(hastePercent) / 100;
}
}
return sourceIntervalMultiplier / Math.max(0.01, 1 + additiveHastePercent / 100);
}