Files
healer-man/docs/NPC_BLOCK_AURA_PARITY_2026-10-06.md
2026-10-06 22:25:34 -04:00

9.2 KiB
Raw Permalink Blame History

Ordinary enemy block aura parity — 2026-10-06

Implemented contract

src/game/enemyBlockAuras.ts records the source-backed aura inputs used by ordinary AzerothCore Creature blocking:

  • Aura 51 (SPELL_AURA_MOD_BLOCK_PERCENT) adds its percentage-point amount to the ordinary creature's 5% block chance.
  • Aura 253 (SPELL_AURA_MOD_BLOCK_CRIT_CHANCE) contributes to the separate critical-block roll after a block succeeds. The summed amount is truncated to an integer for roll_chance_i; a successful critical block doubles the block value, then the ordinary damage cap applies.
  • Aura 288 (SPELL_AURA_IGNORE_HIT_DIRECTION) bypasses the facing check. It does not bypass the independent eligibility gates. The hit-table full-block spell path still honors CU_REQ_CASTER_BEHIND_TARGET; the post-hit direct spell path does not add that separate attribute check.

resolveEnemyNpcBlockAuraInputs returns target-local active values as blockChanceAuraPercent, criticalBlockChancePercent, and ignoresHitDirection. It sums aura amounts and ignores expired or other- target auras. enemyNpcCriticalBlockChanceForRoll and enemyNpcBlockValueAfterCritical expose the integer roll argument and the post-roll multiplier as pure helpers. The caller must first resolve a block, then make the independent critical-block roll.

supportedEnemyBlockAuraDefinition returns an importable full-spell aura only when every DBC effect is represented. On these source rows, only Improved Blocking (3419) meets that rule. Critical Block (47294–47296) and Deterrence rows retain their full source signatures and explicit unsupported-sibling lists; enemyBlockAuraInputDefinition is only for a block-input fixture or a deliberately modeled passive. It must not be treated as an imported complete spell definition.

Raw source rows

The three Spell.dbc files below each have 234 fields. The parser's localized field shift applies only at 239 fields, so these rows use shift 0. Aura effects below are effect type 6, implicit targets 1/0, mechanic 0, radius 0, and period 0 unless otherwise stated. Base points are the parsed client amount (basePoints field plus one). Duration index 0 means permanent; the runtime contract represents that as durationMs: null.

Spell Profile Duration Present effects (auraType:basePoints:miscValue)
3419 Improved Blocking WoW 3.3.5a, Ascension, Epoch 6,000 ms 51:75:0
47294 Critical Block WoW 3.3.5a permanent 253:20:0, 107:5:7
47295 Critical Block WoW 3.3.5a permanent 253:40:0, 107:10:7
47296 Critical Block WoW 3.3.5a permanent 253:60:0, 107:15:7
47294 Critical Block Ascension permanent 253:100:0, 107:4:7, 107:8:3
47295 Critical Block Ascension permanent 253:100:0, 107:7:7, 107:16:3
47296 Critical Block Ascension permanent 253:100:0, 107:10:7, 107:25:3
47294–47296 Critical Block Epoch permanent Same as the corresponding WoW 3.3.5a row
67801 Deterrence WoW 3.3.5a, Epoch 5,000 ms 288:100:0, 185:-100:0
67801 Deterrence Ascension 60,000 ms 288:100:0, 4:0:0, 27:0:0
667801 Deterrence Ascension 5,000 ms 288:100:0, 185:-100:0, 27:0:0
1167801 Deterrence Ascension 5,000 ms 288:100:0, 185:-100:0

This preserves an important profile difference: the stock and Epoch Critical Block rows contain one aura-107 sibling; Ascension contains two. No effect 2 is present on the stock or Epoch rows. Aura 107 effects are preserved as unsupported effects because this contract implements critical-block chance, not their separate flat spell modifiers (SPELLMOD_CRITICAL_CHANCE, misc 7, and Ascension SPELLMOD_EFFECT1, misc 3). Deterrence's effects besides aura 288 are also preserved, not silently dropped.

A bounded follow-up found that the pinned core's ApplySpellMod returns for non-player targets (SpellAuraEffects.cpp:813–816), after aura 107 reaches the spell-modifier path. These siblings are therefore no-ops on that ordinary Creature self-buff path. This pass retains the complete-import gate because the shared definition API does not enforce that actor/target restriction; a future NPC-only importer can use an explicit ordinary-Creature self-target guard. This is not evidence for player/party handling or external custom script overrides. The source file SHA-256 is 107369aa671a26d68081fc65b0066cb00b2cd80dfa2174ddf55bd5919d5db772; SpellDefines.h is 635a025f615e16b6f10f39aa32d523f9b3d6df3959fdd0e4b49a8250da1db48f.

The local inputs and SHA-256 pins are:

Profile Spell.dbc path SHA-256
WoW 3.3.5a ../wow-pvt-server-backups-2/wow335a/Data/patch-A.MPQ/DBFilesClient/Spell.dbc 57011d528fd66cf39f5ab6fb168e389ab9e4cc1b8050f7201a54239d489b415c
Ascension ../LadiksMPQEditor/client-current/area-52/patch-D/DBFilesClient/Spell.dbc 2f77f18b91ffbae32a19568e4bc05ec78ee384b6ba8dd2a6e05f0e97abbb2dce
Epoch ../HealerMan-Storage/pipeline-work/dungeons/epoch-client/DBFilesClient/Spell.dbc d5cce1a83550dcfa9eb2f0251dbb11fd24c272534b2b1a9b230924a44d817ab3

All duration indexes use ../LadiksMPQEditor/client-current/patch-S/DBFilesClient/SpellDuration.dbc, SHA-256 eeae44ef0185924f3d6ec57ab2701c66566db86e51ab0bae017a9449126eb3a0. The parsed durations are index 32 = 6,000 ms, index 28 = 5,000 ms, and index 3 = 60,000 ms.

Non-direct full-hit block boundary

One non-direct row is source-proven for a bounded WoW 3.3.5a helper: Shield Bash (spell 72) has damage class 2, school mask 1, attributes0=327696, attributes3=8 (COMPLETELY_BLOCKED), and present effects 68 and 64. Neither effect is in the pinned core's direct-damage effect list. The pinned creature_template_spell.sql assigns spell 72 to creature entries 1540 and 3739 (rows 582 and 1442).

The AzerothCore checkout is pinned at commit e822d718322289dd036fb2daf8867ba41283bf9a. SpellMgr.cpp:3214–3222 derives CU_DIRECT_DAMAGE from its explicit direct/heal effect list; SpellMgr.cpp:3440–3470 sets CU_REQ_CASTER_BEHIND_TARGET from an explicit spell-ID list that does not include 72. The shipped data/sql/base/db_world/spell_custom_attr.sql and the checked active world SQL updates contain no spell-72 override. The source correction path has no spell-72 custom-attribute correction, and no loaded module replaces the custom-attribute hook in this checkout. These checks prove only the two blocking-relevant bits for this exact source snapshot. The helper records a known-bit mask and zero value for those bits; it does not claim that the full computed AttributesCu word is zero.

This contract is available only for spell 72 with the wow335 source profile. It is not an Ascension/Epoch assertion and is not a generic inference from a DBC row. Other non-direct candidates remain gated until their exact server custom-attribute evidence is imported. A database or core correction outside the pinned checkout can change this result.

enemyNpcSourceSpellBlockMetadata(72, "wow335") returns the metadata used by the pure phase classifier. It proves only the two block-relevant AttributesCu bits through customAttributeEvidence.knownMask/value; it never fills the unknown remainder of the custom word. The helper returns no row for other IDs or source profiles. Its phase and facing-gate behavior has focused unit coverage, but no source NPC non-direct spell importer/application has been wired in this pass, so this is not runtime Shield Bash coverage.

Historical core pins

Read-only source: ../wow-pvt-server-backups-2/azerothcore-wotlk, commit e822d718322289dd036fb2daf8867ba41283bf9a.

Source Verified behavior
src/server/game/Spells/Auras/SpellAuraDefines.h:114,316,351 Aura IDs 51, 253, and 288.
src/server/game/Entities/Unit/Unit.cpp:3276–3307 Post-hit spell block checks front-or-aura and the critical-block roll uses roll_chance_i(GetTotalAuraModifier(...253)).
src/server/game/Entities/Unit/Unit.cpp:1579–1590,1879–1887 Successful block removes block value; a successful critical-block roll doubles it. The direct spell packet can already be critical.
src/server/game/Entities/Unit/Unit.cpp:3364–3396 Hit-table full block requires the blockable attribute and absence of the direct-damage custom bit; the behind-required custom bit limits the aura-facing exception.
src/common/Utilities/Random.h:63–66 roll_chance_i compares an integer chance with an inclusive 0–99 roll.
src/server/game/Spells/SpellMgr.cpp:3214–3222,3440–3470 Direct-damage effect derivation and the explicit caster-behind spell list.
data/sql/base/db_world/creature_template_spell.sql:582,1442 Source NPC spell assignments for Shield Bash spell 72.

Validation

Focused source-aura, block-helper, and damageMob integration tests are src/game/enemyBlockAuras.test.ts, src/game/enemyBlocking.test.ts, and src/game/enemyBlockAuraRuntime.integration.test.ts. They verify profile rows, unsupported siblings, target-local duration behavior, behind-facing aura input for player and party attacks, the separate critical-block result, and the native RoM exclusion. The no-block flag is covered in the pure source gate tests in enemyBlocking.test.ts.