6.5 KiB
Pinned enemy equipment mapping — 2026-10-06
Result
Recovered the exact AzerothCore creature_equip_template.sql at the currently
pinned world commit and added its hash-checked fixture and importer path. The
generated reference now joins imported spawn GUIDs and selectors to equipment
sets, then to Item.dbc class and inventory type. The runtime helper resolves
only an explicit source spawn GUID and entry; unknown, mismatched, unsupported,
or unresolvable assignments produce no equipment contract.
The recovered SQL is
dungeon-pipeline/source-fixtures/azerothcore-4d9d1d4b5723e819c5c390f6ca1177283dbfb8e3/creature_equip_template.sql.
It hashes to 877205c149fd447b08f0ff2c65976f20c862cd42f068a6fcc294a76c7108936a
and belongs to AzerothCore commit
4d9d1d4b5723e819c5c390f6ca1177283dbfb8e3, matching the active
creature.sql and creature_template.sql pins. Its schema is
CreatureID, ID, ItemID1, ItemID2, ItemID3, VerifiedBuild; the source contains
10,854 SQL rows. The importer checks the full file hash before publishing the
equipment mapping and records it in azerothCoreSourceLock.json.
Imported runtime scope
azerothCoreReference.json stores three related mappings under
creature.equipment*:
equipmentAssignmentsBySpawnGuid[guid]records the sourceid1, optional alternate entriesid2/id3, and originalequipment_idselector.equipmentTemplatesByEntry[entry][equipmentId]records raw source item IDs and the three virtual item IDs retained after core loader validation.equipmentItemsById[itemId]stores the pinned Item.dbcitemClassandinventoryTypefor IDs referenced by those equipment rows.
These assignments cover the source dungeon maps imported by the pipeline, not
all 149,879 rows in the world spawn table. The current generated snapshot has
13,277 spawn-GUID assignments, 755 equipment entries, 763 equipment sets, and
442 referenced item IDs. The spawn selectors are 7,632 zeroes, 5,637 ones, two
twos, and six -1 values. Twenty-three spawn rows have alternate creature
entries. All 1,034 nonzero virtual item slots in this imported scope resolve
through the pinned Item.dbc and pass its hand-inventory validation.
The Item.dbc input is the WotLK 3.3.5a client file at
../wow335a/Data/patch-A.MPQ/DBFilesClient/Item.dbc, SHA-256
22061a811523790ddd2ee95b36ade2ac6e0c79a8b3121324d32a639acf50567f. Its
46,149 rows use eight 4-byte fields per 32-byte record; Class is field 1 and InventoryType is
field 6. The importer rejects a different hash or DBC layout. Both pins and
field indexes appear in the generated source lock and reference.
Source behavior and selectors
The source behavior was checked against the exact commit-pinned
Creature.cpp (SHA-256
ea19df5312b632bb7b9faf4323c1612fff8d8104e390d7193bae584318e3e11b) and
ObjectMgr.cpp (SHA-256
e4eae029cc30f84c26c258ba806d39eea61200f623aead1ee0813f6adebeed37).
The relevant operations are ObjectMgr::GetEquipmentInfo,
ObjectMgr::LoadEquipmentTemplates, spawn data loading, Creature::LoadEquipment,
and Creature::HasWeapon.
For a database spawn, selector 0 means no equipment. A positive selector
looks up that exact equipment ID. Selector -1 chooses a random row from the
entry's equipment map, then mutates the selector to distance(begin, row) + 1.
That is an ordinal-based ID, not the selected row's actual key. ObjectMgr checks
nonzero alternate entries using the mutated selector and clears the assignment
if a required alternate row is absent; the later creature load again looks up
the concrete ID. The runtime helper mirrors this sequence with an injected
uniform value in [0, 1). It fails closed if the resulting exact lookup or any
alternate lookup is absent rather than choosing the row's key as a substitute.
This distinction matters for sparse IDs. The pinned table has creature 32239
with only equipment ID 2. Its one-row -1 selection rewrites to ID 1, so a
later ID-1 lookup has no result; the helper will not grant its ID-2 equipment
under a random selector. An explicit selector 2 can resolve that row. The
focused test covers this ordinal-plus-one behavior.
ObjectMgr::LoadEquipmentTemplates also removes missing items and item rows
whose Item.dbc InventoryType is not one of 13, 14, 15, 17, 21, 22, 23, 25, 26 (weapon, shield, ranged, two-handed weapon, main-hand weapon, off-hand
weapon, holdable, thrown, or ranged-right). The importer applies this same
whitelist to all three virtual slots. After that validation,
Creature::HasWeapon(OFF_ATTACK) in AUTO mode checks the resolved Item.dbc
ClassID == ITEM_CLASS_WEAPON (2). No item_template lookup is needed for
that gate; this import does not claim to model item stats or item damage.
The helper enemySpawnEquipmentContract(entry, sourceCreatureGuid, randomUnit?)
returns the resolved virtual item IDs and offhand class, plus the existing
autoOffhand contract when the offhand item is a weapon. It requires a source
GUID whose imported entry list contains the requested creature. Database
spawns with selector zero resolve to empty virtual slots. Missing GUIDs,
synthetic spawns, entry mismatches, older references without equipment maps,
and failed selector lookups return no contract. Core's separate no-spawn-data
default LoadEquipment() selects ID 1; the GUID-based helper does not infer
that creation path for synthetic actors.
The mapping only supplies source equipment and AUTO offhand capability. It does not schedule attacks, import item stats, change loot, alter the level-80 cap, or certify CoA/native balance. Ready-five remains the certification set; CoA and native balance remain Needs Testing.
Validation
node --test scripts/dungeon-pipeline/import-azerothcore-world.test.mjs— 10 focused tests passed.npx vitest run src/game/enemyEquipment.test.ts— 7 focused tests passed.node scripts/dungeon-pipeline/import-azerothcore-world.mjs --item-dbc "F:\\Projects\\wow335a\\Data\\patch-A.MPQ\\DBFilesClient\\Item.dbc"— green; 54 imported dungeon snapshots, 13,277 creature spawns, 494 encounters, with the three expected Ascension-only fallback maps.
The isolated source-data subprocess did not run a production build or live QA.
Root's combined continuation subsequently passes the standard build, Ready-five,
avatar checks and the one frozen Cellblock Rush clear. Targorr's live source
GUID 84027 resolves virtual slots [5305, 5305, 0] and weapon Class 2; eight
offhand outcomes are observed. Combined evidence and limitations are in
the continuation report.