import type { AbilityDefinition } from "./abilityCatalog"; /** Exact child 29703 from the pinned 3.3.5 Spell.dbc; its mechanic is SNARE (11). */ export const WOW335_SHIELD_BASH_DAZE: AbilityDefinition = { id: "wow335-trigger-29703", classId: "warrior", dbcSpellId: 29703, source: "wow335-progression", name: "Dazed", unlockLevel: 1, icon: "/assets/ui/spells/ability_warrior_shieldbash.png", sigil: "DZ", description: "Reduces movement speed by 50% for 6 sec.", target: "hostile", range: { min: 0, max: 50_000 }, castMode: "instant", castTimeMs: 0, cooldownMs: 0, gcdMs: 0, cost: { resource: "rage", amount: 0 }, wowSpellDefense: { damageClass: 0, schoolMask: 1, attributes0: 262416, attributes3: 0, directDamageFromEffects: false, sourceProfile: "wow335", }, effects: [{ kind: "apply-aura", recipient: "ability-target", sourceEffectType: 6, sourceAuraType: 33, miscValue: 0, triggerSpellId: 0, control: { kind: "slow", magnitude: 0.5 }, aura: { id: "wow335:warrior:shield-bash-daze-29703", name: "Dazed", disposition: "debuff", durationMs: 6_000, maxStacks: 1, stackBehavior: "refresh", utilityTags: ["wow335-shield-bash-daze", "source-mechanic:snare"], }, }], }; /** Never borrow the WoW child for another profile, unknown rank, or proc. */ export function isWow335ShieldBashDazeParent(parent: AbilityDefinition | undefined): boolean { const defense = parent?.wowSpellDefense; return parent?.dbcSpellId === 72 && parent.source === "wow335-progression" && defense?.sourceProfile === "wow335" && defense.damageClass === 2 && defense.schoolMask === 1 && defense.attributes0 === 327696 && defense.attributes3 === 8 && defense.directDamageFromEffects === false && parent.effects.some((effect) => effect.kind === "interrupt" && effect.lockoutMs === 6_000) && parent.effects.some((effect) => effect.kind === "trigger-spell" && effect.spellId === 29703); } /** The child is bounded to ordinary WoW NPCs and obeys its source SNARE/physical immunity. */ export function wow335ShieldBashDazeTargetEligible(target: { readonly dead: boolean; readonly serverEntry: number | null; readonly runewakerNpcId?: number | null; readonly summonedBy?: string | null; readonly characterDefender?: unknown; readonly mechanicImmunities: readonly string[]; readonly schoolImmunities: readonly string[]; } | undefined): boolean { return Boolean(target && !target.dead && target.serverEntry !== null && !target.runewakerNpcId && !target.summonedBy && !target.characterDefender && !target.mechanicImmunities.includes("snare") && !target.schoolImmunities.includes("physical")); }