forked from phenom/healer-man
169 lines
8.9 KiB
Markdown
169 lines
8.9 KiB
Markdown
# Hunter Deterrence catalog selection — 2026-10-07
|
||
|
||
## Result
|
||
|
||
The selected Hunter catalog now exposes the exact Spell.dbc player action
|
||
Deterrence 19263 as `wow335-hunter-deterrence`, with its source level, cooldown,
|
||
resource, GCD, target, item requirement, source attributes, and three parent
|
||
aura rows preserved. Its 67801 linked-aura rows remain a separate, explicit
|
||
package descriptor; 67801 is not a learned action or a triggered-spell child.
|
||
|
||
The generated progression file and its generator were not changed. The
|
||
catalog-local fallback is inserted only when the generated Hunter chains
|
||
contain no Deterrence name or package IDs. An imported candidate is accepted
|
||
only if its selected row matches the verified source fields; a same-name
|
||
65871 row, an imported linked child, or any candidate drift suppresses the
|
||
package rather than substituting a row.
|
||
|
||
## Why the generated Hunter entry was missing
|
||
|
||
The read-only source was the local 3.3.5a `patch-enUS.MPQ` at
|
||
`../wow335a/Data/enUS/patch-enUS.MPQ`, SHA-256
|
||
`c1c06b0d0c34c331b21df7cdd25cc422a650efbd477e42b80849ba30b2e5fc99`.
|
||
Its `SkillLineAbility.dbc` contains this row for 19263:
|
||
|
||
```text
|
||
[10865, 51, 19263, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0]
|
||
```
|
||
|
||
The Hunter source in `scripts/generate-wow335-abilities.mjs` includes skill
|
||
line 51 and class mask 4, but `classSpellIds` also requires the row's class-mask
|
||
field 4 to contain bit 4. The selected row has class mask zero, so the import
|
||
filter drops it even though the Hunter skill-line row is present. A read-only
|
||
generation to a temporary output reproduced the omission; no generated files
|
||
were written.
|
||
|
||
## Selected parent row
|
||
|
||
The same archive's `Spell.dbc` has 239 fields and selects spell 19263 named
|
||
Deterrence. The imported field shift is six. The exact catalog values are:
|
||
|
||
| Field | Selected value |
|
||
| --- | --- |
|
||
| Source and base level | 60 / 60 |
|
||
| Maximum scaling level | 0 |
|
||
| Target and range | Self, range index 1, 0–0 |
|
||
| Cast time | 0 ms |
|
||
| Duration | index 28, 5,000 ms |
|
||
| Cooldown | 90,000 ms; category recovery 0 |
|
||
| Global cooldown | 0 ms |
|
||
| Power | Mana, 0 flat cost, 0 percent cost |
|
||
| Prevention type | 0 (`NONE`) |
|
||
| Equipped item | class 2, subclass mask 173555, inventory mask 0 |
|
||
| Attributes 0–7 | `[327696, 16, 0, 0, 0, 0, 0, 0]` |
|
||
| Damage class / school mask | 0 / 1 |
|
||
| Icon | `Ability_Whirlwind` |
|
||
|
||
The exact DBC effect rows are self-targeted `APPLY_AURA` effects with no
|
||
triggered spells, period, radius, or mechanic:
|
||
|
||
| Index | Aura | Parsed amount | Raw base points | DBC coefficient |
|
||
| ---: | ---: | ---: | ---: | ---: |
|
||
| 0 | 47 | +100 | 99 | 1 |
|
||
| 1 | 287 | +100 | 99 | 1 |
|
||
| 2 | 25 | 0 | -1 | 0 |
|
||
|
||
`wow335AbilityCatalog.ts` maps this one verified row through the ordinary
|
||
rank path, then uses the source-bound parent aura descriptors from
|
||
`wow335DeterrenceRuntime.ts`. That override matters for Aura 47: its source
|
||
payload is +100 parry percentage points, so the descriptor uses a flat parry
|
||
modifier. The generic Aura 47 mapper uses a percent multiplier and would not
|
||
represent this row correctly. The descriptors preserve the existing source
|
||
IDs and five-second duration; the 287 effect has no generic deflect tag.
|
||
|
||
The parent row's selected client tooltip resolves to: “When activated,
|
||
increases parry chance by 100% and grants a 100% chance to deflect spells.
|
||
While Deterrence is active, you cannot attack. Lasts 5 sec.” The linked server
|
||
row `(19263, 67801, 2, 'Deterrence')` and exact 67801 child signature are
|
||
documented in [the source audit](WOW335_DETERRENCE_SOURCE_2026-10-06.md).
|
||
|
||
The same DBC field distinguishes attacks blocked by the pacify prevention
|
||
type from silence-only spells. In the 239-field archive, PreventionType is at
|
||
raw field 220 (the import shift of six from field 214 in the pinned 234-field
|
||
layout). The source enum defines 2 as PACIFY, 1 as SILENCE, and 0 as NONE.
|
||
Direct read-only parsing of the pinned archive verified every one of the 189
|
||
selected Hunter rank rows plus Deterrence: 32 NONE, 67 SILENCE, and 91 PACIFY.
|
||
Five additional IDs appear in generated Hunter spell chains but do not become
|
||
selected cast ranks: rank-zero Tame Beast 13481 and Volley damage children
|
||
42234, 42243, 42244, and 42245. They are excluded from the runtime lookup
|
||
because the ability mapper selects the player cast/channel wrappers.
|
||
Arcane Shot (3044), Steady Shot (56641), Aimed Shot (19434), and Wing Clip
|
||
(2974) are PACIFY; Explosive Trap (13813) and Mend Pet (136) are SILENCE;
|
||
Deterrence (19263) is NONE. The complete spell-ID table is in
|
||
`WOW335_HUNTER_PREVENTION_TYPES_BY_SPELL_ID` in
|
||
`src/game/wow335AbilityCatalog.ts`. The lookup also checks the selected
|
||
Hunter/source identity and accepts the public stable ID used when a generated
|
||
source action overlays a core action. Unknown IDs, another class, source, or
|
||
name return no prevention value.
|
||
|
||
The static cast-gate table is deliberately local to the selected catalog. It
|
||
was read from `Spell.dbc` with the archive's WDBC record framing and the same
|
||
six-field schema shift implemented by
|
||
`scripts/generate-wow335-abilities.mjs::parseSpells`; the DBC generator does
|
||
not currently retain PreventionType. A second read-only comparison against
|
||
all 190 table IDs verified every stored value against raw field 220. The DBC
|
||
source pin is WoW build 3.3.5a.12340 and the MPQ SHA-256 recorded above. Field
|
||
semantics are pinned to AzerothCore revision
|
||
`e822d718322289dd036fb2daf8867ba41283bf9a`: `src/server/shared/SharedDefines.h`
|
||
defines `NONE=0`, `SILENCE=1`, and `PACIFY=2`, and
|
||
`src/server/game/Spells/Spell.cpp` gates casts using those values. A future
|
||
change to the selected archive, DBC field layout, selected Hunter ranks, or
|
||
source profile must re-verify the raw table and update this local mapping. It
|
||
should move into generated metadata only with explicit profile, class,
|
||
source-row, and rank provenance; this change does not broaden the generated
|
||
schema.
|
||
|
||
## Linked package and runtime boundary
|
||
|
||
`wow335DeterrenceRuntime.ts` owns three parent `apply-aura` descriptors and
|
||
two linked 67801 descriptors. The child source effects are Aura 288 (+100,
|
||
raw base 99) and Aura 185 (-100, raw base -101), each lasting 5,000 ms. Aura
|
||
185 retains its ordinary `incoming-ranged-hit` modifier. Aura 288 has no
|
||
generic tag; its ignore-facing meaning is resolved only from the complete
|
||
source-bound Deterrence package.
|
||
|
||
The catalog exposes the selected parent action in Hunter progression at level
|
||
60 and keeps the two linked child descriptors separate. Shared cast/runtime
|
||
integration applies and removes the full five-aura package atomically. The
|
||
runtime validator requires the exact parent ability identity and all five
|
||
active aura instances to share source owner, target, applied time, and exact
|
||
expiry. It rejects partial, duplicate, expired, foreign-profile, or same-name
|
||
65871 packages. See `src/game/wow335DeterrenceRuntime.ts`,
|
||
`src/game/wow335DeterrenceRuntime.test.ts`, and the
|
||
[Deterrence integration report](DETERRENCE_INTEGRATION_2026-10-07.md).
|
||
|
||
## Hunter NPC defensive selection
|
||
|
||
The configured Hunter companion can now select the learned 19263 action from
|
||
its own eligible abilities. The early self-defensive branch considers only
|
||
engaged mobs currently targeting that companion, and requires the companion to
|
||
have no active cast and no active Deterrence package. It triggers below the
|
||
configured defensive-health threshold (55% by default) or when a recognized
|
||
incoming cooldown mechanic is imminent. The source action must also pass the
|
||
normal readiness and target checks, including cooldown, resource, equipment,
|
||
and current pacify restrictions. The branch uses the ordinary ability commit
|
||
and execution path, preserving its source cost, 90-second cooldown, and zero
|
||
GCD. The runtime package applies all five source-linked auras and expires them
|
||
together.
|
||
|
||
This is a Hunter-specific defensive choice based on the companion's own threat
|
||
and health/mechanic state; it does not change the general NPC defensive
|
||
candidate rules. The player and companion cast gates both consult the exact
|
||
selected-row PreventionType lookup: PACIFY (2) spells are blocked while the
|
||
actor has an active pacified aura, while SILENCE (1) actions such as Explosive
|
||
Trap and Mend Pet remain available. Ordinary melee attacks keep their
|
||
existing pacify gate. The focused catalog prevention test covers every
|
||
selected Hunter rank and merged public IDs; shared cast/runtime evidence is in
|
||
[the Deterrence integration report](DETERRENCE_INTEGRATION_2026-10-07.md).
|
||
|
||
## Focused verification
|
||
|
||
`npx vitest run src/game/wow335AbilityCatalog.test.ts -t "selects Hunter Deterrence|retains pinned PreventionType"` passes both selected catalog tests.
|
||
The Deterrence case checks the stable selected ID, level 60 unlock, 90-second
|
||
cooldown, zero cost/GCD, exact source attributes and weapon requirement, all
|
||
three parent aura rows, both linked child rows, and rejection of 65871/67801
|
||
as independent Hunter actions. The prevention case checks all 190 selected
|
||
rank IDs against the source map, class/source/name/rank rejection, and public
|
||
merged IDs for Arcane Shot and Steady Shot. Source-contract tests separately
|
||
cover profile, parent/child, and link drift.
|