77 lines
4.4 KiB
Markdown
77 lines
4.4 KiB
Markdown
# Utility spell full-hit blocking — 2026-10-06
|
|
|
|
## Supported source contract
|
|
|
|
`src/game/enemyUtilitySpellBlocking.ts` records one complete utility-spell
|
|
contract: WoW 3.3.5a Shield Bash, selected spell/rank 72. The local generated
|
|
class data has this rank as a physical melee spell with `attributes0=327696`
|
|
and `attributes3=8` (`COMPLETELY_BLOCKED`). Its two present Spell.dbc effects
|
|
are effect 68 (mechanic 26, hostile target) and effect 64 (hostile target,
|
|
triggering spell 29703). Neither is a direct-damage effect in the pinned
|
|
AzerothCore `SpellMgr` list. The source helper supplies only the two known
|
|
blocking-relevant `AttributesCu` bits and records both as clear; it does not
|
|
invent the remainder of that custom word.
|
|
|
|
The contract requires the selected spell ID and source profile to be exactly
|
|
`72` and `wow335`, plus the same DBC defense scalars and a classified
|
|
`hit-table` phase. Other Shield Bash ranks, Ascension/Epoch rows, missing
|
|
metadata, or different signatures use the caller's current fallback. No
|
|
generic inference is made from `COMPLETELY_BLOCKED` alone.
|
|
|
|
## Runtime disposition contract
|
|
|
|
`enemyUtilitySpellBlockDisposition` consumes a hit result already resolved by
|
|
the caller. It only handles player or party casts against an ordinary enemy
|
|
NPC. A resolved `block` suppresses the whole cast-recipient utility effect
|
|
list, including interrupt and triggered aura/debuff effects. `miss`, `dodge`,
|
|
`parry`, or `resist` also suppress application for this exact hit-table spell;
|
|
`hit` or `crit` allows its utility effects. Missing/unresolved outcomes and
|
|
unsupported sources return `fallback`, preserving the caller's existing
|
|
behavior.
|
|
|
|
The hit-table path is enabled by melee/ranged damage class, physical school,
|
|
the `COMPLETELY_BLOCKED` attribute, and explicit evidence that
|
|
`CU_DIRECT_DAMAGE` is absent. `NO_ACTIVE_DEFENSE` and `ALWAYS_HIT` override
|
|
blocking. Facing, active non-melee cast, controlled state, no-block template
|
|
flag, totem, and skill-adjusted positive chance remain the resolver's gates;
|
|
this helper does not roll or bypass them. Shield Bash's source evidence also
|
|
shows `CU_REQ_CASTER_BEHIND_TARGET` clear for its aura-facing exception.
|
|
|
|
The helper is intended for the existing player/party outbound-to-ordinary-NPC
|
|
utility writers. NPC outbound casts into player/party targets need the
|
|
character defender's separate block model and do not consume this contract.
|
|
Native RoM casters/targets, character defenders, summoned actors, and unknown
|
|
targets stay on their existing paths. The helper contains no shared runtime
|
|
types and does not mutate combat state.
|
|
|
|
The shared player cast writer and companion `executePartyAbility` resolve one
|
|
source-bound block result before their utility effect loops. A full block
|
|
skips the entire recipient effect list while retaining the accepted cast's
|
|
resource cost and cooldown. Telemetry records a zero-amount `cast` result with
|
|
the block flag; it emits no fake damage packet. This bounded runtime stage
|
|
rolls block only and preserves existing other utility hit/avoidance behavior.
|
|
The helper's avoided-outcome disposition is available for a future sourced
|
|
full hit table, but this pass does not add miss/dodge/parry/resist rolls.
|
|
|
|
## Validation
|
|
|
|
`src/game/enemyUtilitySpellBlocking.test.ts` covers the exact signature,
|
|
block-before-utility suppression, hit-table misses/dodges/parries/resists,
|
|
missing rank/source/profile/signature and native/target exclusions. Runtime
|
|
integration, including the active-cast gate and an unblocked interrupt, belongs
|
|
to the `combatStore.ts` and `partyRuntime.ts` caller changes.
|
|
|
|
The final `enemyUtilitySpellBlocking.integration.test.ts` passes four tests:
|
|
an actual player cast blocks once and retains cost/cooldown; an actively
|
|
casting NPC cannot block and receives the six-second interrupted-school
|
|
lockout; a synthetic accepted pending companion cast completes through the
|
|
real companion executor and blocks; unbound metadata/ranks and native,
|
|
summoned, character and unknown source defenders stay excluded. The player's
|
|
utility result and existing completed-cast event are separate telemetry;
|
|
the block result is not a second completed cast or a damage packet.
|
|
|
|
The actual parent catalog retains its trigger 29703, but
|
|
`triggeredAbilityBySpellId(29703)` is currently null. This pass suppresses
|
|
trigger execution under a full block; it does not implement or certify an
|
|
imported/live Daze child. That child import remains a separate catalog gap.
|