Groundwork for 7 weapon sets / 7 combat-art slots (docs/skill-slots.md). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
92 lines
4.1 KiB
Markdown
92 lines
4.1 KiB
Markdown
# 7 weapon sets and 7 combat-art slots (planned)
|
|
|
|
Goal (user request 2026-10-14): 7 weapon sets and 7 combat-art slots instead
|
|
of 5 each; skills on 1-7, weapon sets on F1-F7; old saves keep loading
|
|
(migration on read). Status: mapping, nothing changed yet.
|
|
|
|
## Where the slots live
|
|
|
|
### `cInventoryEntry` (one per player, no vtable)
|
|
|
|
All 32 inventories are one block from `cInventoryManager::Instance`
|
|
(`0x5deb80`, 32 x 0x1180 + 8 bytes at `*0xad23c8`); `GetInventory`
|
|
(`0x5dec50`) hardcodes the stride 0x1180. An inventory's index is therefore
|
|
`(inventory - block) / 0x1180`.
|
|
|
|
| Offset | Size | Content |
|
|
|---|---|---|
|
|
| +0x18 | 0x100 x 0xc | item grid |
|
|
| +0xc18 | 5 x 0x18 | weapon sets: 2 hands x (item id, 2 dwords) |
|
|
| +0xc90 | 5 x 2 x 0x14 | art slots: 2 variants (bit 2 of +0x1162, maybe mounted) x {u16 type 2/3/4, u16, id, 3 dwords} |
|
|
| +0xd58 | 2 x u16 | selected slot: [0] weapon set, [1] art slot |
|
|
| +0xd5c | 0x400 | (next field, unrelated) |
|
|
| +0x115c / +0x115e | u16 | grid width 0x14 / height 8 |
|
|
| +0x1160 | u16 | player index |
|
|
| +0x1162 | u16 | flags |
|
|
|
|
The three slot arrays are packed together, so there is no room for slots
|
|
6 and 7 in the object.
|
|
|
|
Methods (names in `tools/names.txt`): `GetWeaponSetItem` `0x5d86c0`,
|
|
`SetWeaponSetItem` `0x5d86f0`, `SetWeaponSet` `0x5d8930`,
|
|
`TakeWeaponSetItem` `0x5d8be0`, `GetWeaponSetItemPos` `0x5d8d00`,
|
|
`GetArtSlotType` `0x5d93e0`, `GetArtSlotRef` `0x5d9420`, `SetArtSlot`
|
|
`0x5d9480`, `ClearArtSlot` `0x5d9680`, `SelectSlot` `0x5d9820`,
|
|
`GetSelectedSlot` `0x5d9b60`, `SetArtVariant` `0x5d9200`; loops over the 5
|
|
weapon sets in `Clear` `0x5d7d30`, `ReplaceItemId` `0x5d80e0`,
|
|
`FixInventory` `0x5de8a0` and the load path of `Serialize`.
|
|
|
|
Accesses outside the class found so far: none to these offsets (searched
|
|
`+0xc18..+0xca0`, `+0xd58/+0xd5a`, `(x+0x102)*0xc`, `(x+0xa1)*0x14`,
|
|
`(x*3+0x183)*8`). The compiler also spells addresses in other ways, so the
|
|
list is a lower bound until the callers of the accessors are checked.
|
|
|
|
### Save format (`cInventoryEntry::Serialize` `0x5dd9f0`)
|
|
|
|
`(stream, write)`; stream vf04 read, vf08 write, vf14 position. Raw blocks in
|
|
this order, no version field:
|
|
|
|
flags +0x1162 (2), +0x1164 (2), +0x1166 (2), width (2), height (2),
|
|
+0xd5c (0x400), grid (0xc00), **weapon sets (0x78)**, **art slots (0xc8)**,
|
|
**selected (4)**, +0x1168 (4), quest items (count + 8 each), scrolls
|
|
(count + 4 each).
|
|
|
|
Returns the number of bytes processed. Called from `0x5dbd76`, `0x5df00c`,
|
|
`0x5df0e5`, `0x5df391`, `0x5df47e`, `0x604a26`, `0x604a7d`, `0x605cee`.
|
|
|
|
### Slot count by level
|
|
|
|
`SlotCountForLevel` (`0x57f750`): table at `0x95503c`, (level, count) pairs,
|
|
at most 5. Used by the taskbar (`+0x15c`).
|
|
|
|
### Taskbar (`cUI_Taskbar2`)
|
|
|
|
Slot controls: weapon sets at +0x164 (5), art slots at +0x178 (5), slot count
|
|
at +0x15c; selection highlight written into the controls (+0x54..+0x60,
|
|
+0x78) from `0x9ed058`. Layout, rendering (`0x6e3ac0`), hit test (`0x6dfb10`)
|
|
and drag & drop of the slots: not mapped yet.
|
|
|
|
### Network
|
|
|
|
Slot changes send network events 299 (`SetWeaponSetItem`), 300
|
|
(`SetWeaponSet`), 0x129 (`SetArtSlot`), 0x12a (`ClearArtSlot`), 0x130
|
|
(`SelectSlot`), 0x123 (`SetArtVariant`) with the slot index. A server or
|
|
client running the original only knows 5 slots: slots 6-7 are single player
|
|
only (or disabled in multiplayer).
|
|
|
|
## Plan
|
|
|
|
1. Slots 6-7 in a DLL table per inventory index (2 weapon sets, 2 x 2 art
|
|
slot variants); the original object keeps slots 1-5 unchanged.
|
|
2. Hook the accessors above: index >= 5 goes to the table. Extend the
|
|
5-slot loops (`Clear`, `ReplaceItemId`, `FixInventory`, load fix-up).
|
|
3. Save: after the original blocks, `Serialize` writes an extension block
|
|
(magic + version + slots 6-7). Reading checks for the magic; a save
|
|
without it (old save) gets empty slots 6-7 = the migration. Open: whether
|
|
the stream can peek / seek back, and whether the caller stores the
|
|
returned length.
|
|
4. Slot count table: 7 entries (unlock levels for slots 6 and 7 to choose).
|
|
5. Taskbar: 7 controls each (arrays inside the object are fixed at 5: own
|
|
table for the extra controls), layout, rendering, hit tests, drag & drop.
|
|
6. Keys: 1-7 select and cast art slots, F1-F7 select weapon sets.
|