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
MeleeSpellMissChancefirst. Attribute 7 bit0x02000000(SPELL_ATTR7_CANT_MISS) is clear for all three records, so they can miss. - It adds
GetMechanicResistChancenext. The interrupt effect's mechanic is 26; the target'sSPELL_AURA_MOD_MECHANIC_RESISTANCEcan 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_RESULTalso 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.