Files
healer-man/docs/UTILITY_HIT_EXTENSION_AUDIT_2026-10-06.md
2026-10-07 13:05:04 -04:00

4.7 KiB

Utility hit extension audit — 2026-10-06

Result

The exact WoW 3.3.5a single-rank Shield Bash (72), Kick (1766), and Pummel (6552) can share the existing ordinary-creature full-block result. The binding is intentionally exact to the selected playable row, source profile, class, rank, source effects, and projected effect list. It does not add miss, dodge, parry, or mechanic-resist rolls. Those outcomes remain on the current effect path until the runtime carries the source inputs needed to calculate them faithfully.

Kick's playable identity is rogue-kick; wow335-rogue-kick is its raw generated source-chain identity. The catalog merge must retain the source Kick's pure five-second interrupt rather than merge the legacy prototype's damage and second interrupt. Pummel's selected row is the level-38 rank, so the contract does not permit it before its source unlock. Shield Bash remains the only selected rank in its chain and retains its 29703 trigger alongside its six-second interrupt.

Source proof

The local wow335a/Data/patch-A.MPQ/DBFilesClient/Spell.dbc records for IDs 72, 1766, and 6552 share DmgClass=2 (melee), physical SchoolMask=1, Attributes0=327696, Attributes3=8, and Attributes7=0. Attributes3=8 is SPELL_ATTR3_COMPLETELY_BLOCKED. The relevant custom-attribute bits SPELL_ATTR0_CU_DIRECT_DAMAGE (0x00000100) and SPELL_ATTR0_CU_REQ_CASTER_BEHIND_TARGET (0x00020000) are both clear in the pinned core: SpellInfo::Initialize starts AttributesCu at zero, and the active custom-attribute update SQL contains no rows for these three IDs. This proves only those two custom bits, not the complete custom word.

The exact effect slots are:

Spell Source effects Selected projection
Shield Bash 72 Effect 68, mechanic 26, target A 6; effect 64, target A 6, trigger 29703 Interrupt 6,000 ms; trigger spell 29703
Kick 1766 Effect 68, mechanic 26, target A 6; second slot empty Interrupt 5,000 ms
Pummel 6552 Effect 68, mechanic 26, target A 6; second slot empty Interrupt 4,000 ms

These signatures are also present in src/game/wow335AbilityData.generated.json and are locked in src/game/enemyUtilitySpellBlocking.ts. SpellInfo.cpp identifies effect 68 as SPELL_EFFECT_INTERRUPT_CAST; SpellEffects.cpp dispatches it to EffectInterruptCast. It is not a direct-damage effect.

The pinned AzerothCore Unit::MeleeSpellHitResult in ../wow-pvt-server-backups-2/azerothcore-wotlk/ElunaTrinityWotlk/src/server/game/Entities/Unit/Unit.cpp explains why the source proof does not justify the whole table:

  • It checks MeleeSpellMissChance first. Attribute 7 bit 0x02000000 (SPELL_ATTR7_CANT_MISS) is clear for all three records, so they can miss.
  • It adds GetMechanicResistChance next. The interrupt effect's mechanic is 26; the target's SPELL_AURA_MOD_MECHANIC_RESISTANCE can resist it.
  • It then considers dodge, parry, and block. Melee attacks can block; casting or controlled defenders lose active avoidance/block; attacking from behind disables parry/block absent hit-direction immunity. Creature no-dodge, no-parry, and no-block flags and SPELL_AURA_IGNORE_COMBAT_RESULT also alter eligibility.

The generated defense projection currently omits Attributes7, while the utility resolver has no exact mechanic-resistance, miss-chance/weapon-skill, or complete target-state input for these spells. Consequently, a generic Magic miss/resist roll or guessed melee miss/dodge/parry values would not match this source. The implementation keeps those outcomes gated and resolves only the already modeled block result.

Runtime boundary and verification

enemyUtilitySpellBlockAbilityContract binds the policy to the selected ability ID (including the public Kick identity), class, exact source, DBC rank, defense metadata, and full projected effect signature. It reconstructs only the audited known custom-bit evidence when the generated row omits it; conflicting explicit metadata fails closed. resolveNpcUtilityBlockResult then restricts the check to player/party casters and ordinary source NPCs, and asks the existing defender model for a physical melee block result with miss, crit, dodge, and parry disabled. A block suppresses all utility effects while preserving the accepted cast's cost/cooldown path. Player and party effect application both consume that blocked result.

Validation: npx vitest run src/game/enemyUtilitySpellBlocking.test.ts src/game/wow335InterruptUtilityBlocking.integration.test.ts passes 13 tests across two files. The unit cases verify the three exact source/projection contracts, selected-rank identity, and mismatch rejection. The integration cases cover blocked player and companion Kick/Pummel casts and ensure the interrupt effect is not applied on a full block.