fix(paperdoll): restore authored slot backgrounds
Port the retail UIItem catalog path so every supported equipment location resolves its exact empty-state silhouette from live DAT. Share one definition table between equip behavior and presentation, wire runtime plus UI Studio, pin all 21 prototypes and surfaces, and retire AP-66. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
6ba4148b24
commit
1be18cc4db
11 changed files with 335 additions and 52 deletions
|
|
@ -0,0 +1,100 @@
|
|||
# Retail paperdoll slot backgrounds — pseudocode
|
||||
|
||||
Date: 2026-07-13
|
||||
|
||||
Scope: the empty-cell art for the 21 currently supported equipment lists in
|
||||
`gmPaperDollUI`. This corrects the earlier visual inference that the slots had no
|
||||
per-location art. The paperdoll layout elements themselves inherit the same ItemList
|
||||
base, but retail creates their cells from distinct `UIElement_UIItem` prototypes in
|
||||
the shared catalog `0x21000037`.
|
||||
|
||||
## Retail anchors
|
||||
|
||||
- `gmPaperDollUI::GetLocationInfoFromElementID` @ `0x004A37F0`
|
||||
(`named-retail/acclient_2013_pseudo_c.txt:173620`) — exact paperdoll element-id to
|
||||
`INVENTORY_LOC`/`EquipMask` mapping.
|
||||
- `gmPaperDollUI::PostInit` @ `0x004A5360`
|
||||
(`named-retail/acclient_2013_pseudo_c.txt:175232`) — binds each element as a
|
||||
single-cell `UIElement_ItemList`; hides only the nine armor lists in doll view.
|
||||
- `UIElement_ItemList::InternalCreateItem` @ `0x004E3570`
|
||||
(`named-retail/acclient_2013_pseudo_c.txt:231486`) — resolves the UIItem catalog
|
||||
through enum-map `0x10000038`, category `5`, key `0x23`, then clones the selected
|
||||
`UIElement_UIItem` prototype.
|
||||
- `UIElement_ItemList::ItemList_AddItem` @ `0x004E3F50` and
|
||||
`gmPaperDollUI::SetUIItemIntoLocation` @ `0x004A5F90` — even an empty location is
|
||||
represented by a real UIItem cell in its list.
|
||||
- Live DAT `LayoutDesc 0x21000037` — each prototype's child `0x1000033B`, state
|
||||
`ItemSlot_Empty`, supplies the exact 32×32 RenderSurface below.
|
||||
|
||||
The retained `references/WorldBuilder` tree has no UI implementation. ACE/ACViewer
|
||||
are interpretation aids for `EquipMask` and surface decoding; neither owns the retail
|
||||
paperdoll widget behavior. The named client plus live DAT are therefore the oracle.
|
||||
|
||||
## Literal pseudocode
|
||||
|
||||
```text
|
||||
PaperDoll.PostInit:
|
||||
for every authored equipment-list element:
|
||||
list = GetChildRecursive(elementID).DynamicCast(UIElement_ItemList)
|
||||
RegisterItemListDragHandler(list, paperDoll)
|
||||
UpdateItemSlotTooltip(list, empty)
|
||||
|
||||
hide the nine armor-location lists in doll view
|
||||
|
||||
ItemList.InternalCreateItem:
|
||||
prototypeID = GetAttribute_Enum(ItemListCellTemplate)
|
||||
catalog = GetByEnum(UIElementCatalog, LayoutDesc, UIItemCatalog)
|
||||
return CreateChildElement(list, catalog, prototypeID).DynamicCast(UIElement_UIItem)
|
||||
|
||||
PaperDoll.SetUIItemIntoLocation(itemID, locationMask):
|
||||
for each paperdoll slot whose location bit intersects locationMask:
|
||||
flush that slot's one-cell item list
|
||||
add itemID to that list
|
||||
update its tooltip
|
||||
|
||||
UIItem empty draw:
|
||||
draw prototype.child(0x1000033B).state(ItemSlot_Empty).image
|
||||
```
|
||||
|
||||
## Authored slot-template table
|
||||
|
||||
| Paperdoll element | Equip location | UIItem prototype | Empty RenderSurface |
|
||||
|---|---|---|---|
|
||||
| `0x100001DA` | NeckWear | `0x10000446` | `0x06000F68` |
|
||||
| `0x100001DB` | WristWearLeft | `0x10000447` | `0x06000F5D` |
|
||||
| `0x100001DC` | FingerWearLeft | `0x10000448` | `0x06000F5A` |
|
||||
| `0x100001DD` | WristWearRight | `0x10000449` | `0x06000F6A` |
|
||||
| `0x100001DE` | FingerWearRight | `0x1000044A` | `0x06000F6B` |
|
||||
| `0x100001DF` | weapon composite | `0x1000044B` | `0x06000F66` |
|
||||
| `0x100001E0` | MissileAmmo | `0x1000044C` | `0x06000F5E` |
|
||||
| `0x100001E1` | Shield | `0x1000044D` | `0x06000F6C` |
|
||||
| `0x100001E2` | ChestWear | `0x1000044E` | `0x060032C5` |
|
||||
| `0x100001E3` | UpperLegWear | `0x1000044F` | `0x060032C4` |
|
||||
| `0x1000058E` | TrinketOne | `0x1000058F` | `0x06006A6C` |
|
||||
| `0x100005E9` | Cloak | `0x100005EA` | `0x0600708F` |
|
||||
| `0x100005AB` | HeadWear | `0x100005B4` | `0x06006D7F` |
|
||||
| `0x100005AC` | ChestArmor | `0x100005B5` | `0x06006D7B` |
|
||||
| `0x100005AD` | AbdomenArmor | `0x100005B6` | `0x06006D79` |
|
||||
| `0x100005AE` | UpperArmArmor | `0x100005B7` | `0x06006D87` |
|
||||
| `0x100005AF` | LowerArmArmor | `0x100005B8` | `0x06006D81` |
|
||||
| `0x100005B0` | HandWear | `0x100005B9` | `0x06006D7D` |
|
||||
| `0x100005B1` | UpperLegArmor | `0x100005BA` | `0x06006D89` |
|
||||
| `0x100005B2` | LowerLegArmor | `0x100005BB` | `0x06006D83` |
|
||||
| `0x100005B3` | FootWear | `0x100005BD` | `0x06006D85` |
|
||||
|
||||
The three Aetheria lists remain outside the current controller scope (AP-108). Their
|
||||
authored backgrounds are blue/yellow/red prototypes `0x10000592..94`, but this fix
|
||||
does not make those otherwise unimplemented slots reachable.
|
||||
|
||||
## Port mapping
|
||||
|
||||
- `PaperdollSlotBackgrounds` is the single table for element-id, `EquipMask`, and
|
||||
UIItem prototype. `PaperdollController` consumes the same definitions for behavior,
|
||||
preventing the visual and equip-location maps from drifting apart.
|
||||
- `ItemListCellTemplate.ResolvePrototypeEmptySprite` reuses the already-shipped
|
||||
inheritance-aware `ItemSlot_Empty` resolver instead of hardcoding surface IDs in
|
||||
the controller.
|
||||
- `RetailUiRuntime` and UI Studio resolve the 21 surfaces from the live DAT once at
|
||||
bind time and inject them into the controller. A missing authored surface is a startup
|
||||
error rather than a silently generic slot; the old inventory-grid sprite remains only
|
||||
for isolated controller bindings that do not supply the paperdoll catalog map.
|
||||
Loading…
Add table
Add a link
Reference in a new issue