fix(studio): Task 4 — bind PaperdollController + wire empty-slot sprites
FixtureProvider.Populate for 0x21000023 was binding only InventoryController and omitting PaperdollController, so the ~21 equip slots rendered empty even though sample equipped items existed in the table. Also, the three per-list empty-slot sprites were not being resolved from the dat (contentsEmpty / sideBagEmpty / mainPackEmpty all defaulted to 0), so the slot cells had no background art. Fixes: - FixtureProvider.Populate gains a DatCollection dats param (mirrors the GameWindow.OnLoad lookup at line 2233-2235). The 0x21000023 case now resolves all three empty sprites via ItemListCellTemplate.ResolveEmptySprite and passes them to InventoryController.Bind. - PaperdollController.Bind is now called after InventoryController in the same 0x21000023 case, matching GameWindow:2257-2265 (same layout subtree, contentsEmpty as the equip-slot placeholder, sendWield: null since there is no live session in the studio). - StudioWindow.OnLoad passes _dats! to the updated Populate signature. SampleData.AddEquipped was already correct: MoveItem(guid, PlayerGuid, -1, equipMask) at ClientObjectTable.cs:134 sets CurrentlyEquippedLocation = newEquipLocation and calls Reindex which places the item in _containerIndex[PlayerGuid]. No SampleData change needed. Tests: 2 new assertions in FixtureProviderTests — sideBags_matchInventoryControllerFilter (Type.HasFlag(Container) || ItemsCapacity > 0 filter must match both bags) and equippedItems_retainLocationAndAreInContents (equipped items have CurrentlyEquippedLocation != None AND appear in GetContents so the paperdoll controller can find them). 604 pass / 2 skip / 0 fail. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
0bdc866c15
commit
9ed9d8dbd9
3 changed files with 92 additions and 7 deletions
|
|
@ -3,6 +3,7 @@ using AcDream.App.UI;
|
|||
using AcDream.App.UI.Layout;
|
||||
using AcDream.Core.Items;
|
||||
using AcDream.Core.Net.Messages;
|
||||
using DatReaderWriter;
|
||||
|
||||
namespace AcDream.App.Studio;
|
||||
|
||||
|
|
@ -41,11 +42,14 @@ public static class FixtureProvider
|
|||
/// and <see cref="RenderStack.VitalsDatFont"/>).</param>
|
||||
/// <param name="objects">A <see cref="ClientObjectTable"/> already seeded by
|
||||
/// <see cref="SampleData.BuildObjectTable"/>.</param>
|
||||
/// <param name="dats">The live DAT collection used to resolve per-list empty-slot sprites
|
||||
/// (same lookup GameWindow.OnLoad performs for the production binding).</param>
|
||||
public static void Populate(
|
||||
uint layoutId,
|
||||
ImportedLayout layout,
|
||||
RenderStack stack,
|
||||
ClientObjectTable objects)
|
||||
ClientObjectTable objects,
|
||||
DatCollection dats)
|
||||
{
|
||||
switch (layoutId)
|
||||
{
|
||||
|
|
@ -74,15 +78,41 @@ public static class FixtureProvider
|
|||
sendRemoveShortcut: null);
|
||||
break;
|
||||
|
||||
case 0x21000023u: // inventory
|
||||
case 0x21000023u: // inventory + paperdoll
|
||||
{
|
||||
// Resolve the per-list empty-slot art from the dat cell template, matching the
|
||||
// exact lookup GameWindow.OnLoad performs (UIElement_ItemList::InternalCreateItem
|
||||
// 0x004e3570 → attr 0x1000000e → catalog 0x21000037 → ItemSlot_Empty).
|
||||
uint contentsEmpty = ItemListCellTemplate.ResolveEmptySprite(dats, 0x21000021u, 0x100001C6u);
|
||||
uint sideBagEmpty = ItemListCellTemplate.ResolveEmptySprite(dats, 0x21000022u, 0x100001CAu);
|
||||
uint mainPackEmpty = ItemListCellTemplate.ResolveEmptySprite(dats, 0x21000022u, 0x100001C9u);
|
||||
|
||||
var iconIds = MakeIconIds(stack);
|
||||
|
||||
InventoryController.Bind(
|
||||
layout,
|
||||
objects,
|
||||
playerGuid: () => SampleData.PlayerGuid,
|
||||
iconIds: MakeIconIds(stack),
|
||||
strength: () => 100,
|
||||
datFont: stack.VitalsDatFont);
|
||||
playerGuid: () => SampleData.PlayerGuid,
|
||||
iconIds: iconIds,
|
||||
strength: () => 100,
|
||||
datFont: stack.VitalsDatFont,
|
||||
contentsEmptySprite: contentsEmpty,
|
||||
sideBagEmptySprite: sideBagEmpty,
|
||||
mainPackEmptySprite: mainPackEmpty);
|
||||
|
||||
// Bind the paperdoll equip slots (same imported subtree as the inventory).
|
||||
// Mirrors GameWindow:2257-2265: PaperdollController.Bind with contentsEmpty as
|
||||
// emptySlotSprite (each slot shows the same square-frame placeholder as the grid).
|
||||
PaperdollController.Bind(
|
||||
layout,
|
||||
objects,
|
||||
playerGuid: () => SampleData.PlayerGuid,
|
||||
iconIds: iconIds,
|
||||
sendWield: null, // no live session in the studio
|
||||
emptySlotSprite: contentsEmpty,
|
||||
datFont: stack.VitalsDatFont);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
// Unknown layout — no-op; the panel renders structurally.
|
||||
|
|
|
|||
|
|
@ -130,7 +130,7 @@ public sealed class StudioWindow : IDisposable
|
|||
{
|
||||
uint layoutId = _opts.LayoutId ?? 0x2100006Cu;
|
||||
_objects = SampleData.BuildObjectTable();
|
||||
FixtureProvider.Populate(layoutId, _source.CurrentLayout, _stack, _objects);
|
||||
FixtureProvider.Populate(layoutId, _source.CurrentLayout, _stack, _objects, _dats);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue