feat(D.2b): main-pack cell draws the constant backpack icon (AP-51)

The m_topContainer cell (0x100001C9) rendered blank (tex=0). Retail's
IconData::RenderIcons (0x0058d1ee) has an IsThePlayer() branch that draws a
CONSTANT backpack — m_idIcon = GetDIDByEnum(0x10000004, 7) = 0x060011F4,
m_itemType = TYPE_CONTAINER — NOT the player's body icon (the original AP-51
"equipped-pack weenie icon" premise was wrong). Compose that base over the
Container type-underlay via the existing _iconIds delegate. Verified vs decomp
(407546-407549) + IconComposer.GetIcon (base=arg2, type drives underlay) + a
live dat dump (map 0x25000008 index 7 = 0x060011F4). Test locks type+literal.
AP-51 reworded to the residual hardcoded-vs-runtime-resolve nuance (cf. AP-55).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Erik 2026-06-22 15:04:08 +02:00
parent 9dc44c3a3d
commit c71b32f73d
3 changed files with 26 additions and 2 deletions

View file

@ -224,11 +224,17 @@ public sealed class InventoryController
}
// Main-pack cell: the player's own container — clicking it opens/selects the main pack.
// Retail draws a CONSTANT backpack icon here, NOT the player's body icon: IconData::RenderIcons
// (0x0058d1ee) has an IsThePlayer() branch that overrides m_idIcon with
// GetDIDByEnum(0x10000004, 7) = 0x060011F4 and m_itemType = TYPE_CONTAINER. Compose that
// backpack base over the Container type-underlay (the player object's own IconId is the
// character body, which would render wrong here). Retires AP-51.
if (_topContainer is not null)
{
const uint PlayerPackBaseIcon = 0x060011F4u; // GetDIDByEnum(0x10000004, 7)
_topContainer.Flush();
var main = new UiItemSlot { SpriteResolve = _topContainer.SpriteResolve };
main.SetItem(p, 0u);
main.SetItem(p, _iconIds(ItemType.Container, PlayerPackBaseIcon, 0u, 0u, 0u));
main.Clicked = () => OpenContainer(p);
_topContainer.AddItem(main);
}