feat(D.2b): Slice 2 — paperdoll armor/non-armor partition + Slots toggle state
Adds ArmorSlotElementIds (the exact 9 ids gmPaperDollUI::ListenToElementMessage flips per decomp 175674-175706) and PaperdollViewState (SlotView/DollVisible/ ArmorSlotsVisible/Toggle) as a nested public class on PaperdollController. Wires ApplyView() into the constructor so the Slots button (0x100005BE) drives armor-slot Visible and the doll viewport Visible on every click. Initial state is doll-view (armor slots hidden). The doll viewport element (0x100001D5) is bound as UiElement? so this slice stays independent of Slice 3's IUiViewportRenderer seam; _armorSlots collects whichever of the 9 ids were found in the live layout. Three new unit tests verify the id set, the default state, and the round-trip toggle against the public PaperdollViewState surface only. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
1c7f20fd08
commit
c5604ff6ad
2 changed files with 97 additions and 0 deletions
|
|
@ -14,6 +14,32 @@ namespace AcDream.App.UI.Layout;
|
|||
/// </summary>
|
||||
public sealed class PaperdollController : IItemListDragHandler
|
||||
{
|
||||
// ── Slots-toggle public surface ───────────────────────────────────────────────────────────────
|
||||
/// <summary>
|
||||
/// The 9 armor-slot element-ids whose Visible state the Slots button (0x100005BE) toggles.
|
||||
/// Doll-view: hidden. Slot-view: shown. Source: gmPaperDollUI::ListenToElementMessage decomp
|
||||
/// 175674-175706 — these are the only 9 ids that element flips; the other ~12 equip slots
|
||||
/// (jewelry, weapon, wrists, feet…) are NON-armor and remain visible in both views.
|
||||
/// </summary>
|
||||
public static readonly uint[] ArmorSlotElementIds =
|
||||
{
|
||||
0x100005abu, 0x100005acu, 0x100005adu, 0x100005aeu, 0x100005afu,
|
||||
0x100005b0u, 0x100005b1u, 0x100005b2u, 0x100005b3u,
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// View-state model for the Slots toggle (pure logic, no UI coupling).
|
||||
/// Default is doll-view (SlotView == false): the 3-D character is visible,
|
||||
/// the 9 armor slots are hidden. Calling Toggle() alternates between views.
|
||||
/// </summary>
|
||||
public sealed class PaperdollViewState
|
||||
{
|
||||
public bool SlotView { get; private set; } // false = doll-view (default)
|
||||
public bool DollVisible => !SlotView;
|
||||
public bool ArmorSlotsVisible => SlotView;
|
||||
public void Toggle() => SlotView = !SlotView;
|
||||
}
|
||||
|
||||
// WEAPON_READY_SLOT_LOC (acclient.h:3235): the weapon-hand doll slot accepts any wieldable weapon.
|
||||
private const EquipMask WeaponSlotMask =
|
||||
EquipMask.MeleeWeapon | EquipMask.MissileWeapon | EquipMask.Held | EquipMask.TwoHanded;
|
||||
|
|
@ -51,6 +77,11 @@ public sealed class PaperdollController : IItemListDragHandler
|
|||
private readonly Action<uint, uint>? _sendWield; // (itemGuid, equipMask) → GetAndWieldItem 0x001A
|
||||
private readonly List<(EquipMask Mask, UiItemList List)> _slots = new();
|
||||
|
||||
// ── Slots-toggle state ────────────────────────────────────────────────────────────────────────
|
||||
private readonly PaperdollViewState _viewState = new();
|
||||
private readonly List<UiItemList> _armorSlots = new();
|
||||
private UiElement? _dollViewport; // UiViewport wired in Slice 3; UiElement? keeps this task independent
|
||||
|
||||
private PaperdollController(
|
||||
ImportedLayout layout, ClientObjectTable objects, Func<uint> playerGuid,
|
||||
Func<ItemType, uint, uint, uint, uint, uint> iconIds, Action<uint, uint>? sendWield,
|
||||
|
|
@ -80,6 +111,17 @@ public sealed class PaperdollController : IItemListDragHandler
|
|||
_objects.ObjectRemoved += OnObjectChanged;
|
||||
_objects.ObjectUpdated += OnObjectChanged;
|
||||
|
||||
// ── Slots-toggle wiring ───────────────────────────────────────────────────────────────────
|
||||
foreach (var id in ArmorSlotElementIds)
|
||||
if (layout.FindElement(id) is UiItemList armor) _armorSlots.Add(armor);
|
||||
|
||||
_dollViewport = layout.FindElement(0x100001D5u); // doll viewport (may be null until Slice 3)
|
||||
|
||||
if (layout.FindElement(0x100005BEu) is UiButton slotsBtn)
|
||||
slotsBtn.OnClick = () => { _viewState.Toggle(); ApplyView(); };
|
||||
|
||||
ApplyView(); // initial state = doll-view (armor slots hidden)
|
||||
|
||||
Populate();
|
||||
}
|
||||
|
||||
|
|
@ -161,6 +203,17 @@ public sealed class PaperdollController : IItemListDragHandler
|
|||
_sendWield?.Invoke(payload.ObjId, (uint)wieldMask);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Pushes the current <see cref="PaperdollViewState"/> onto the live widgets:
|
||||
/// hides/shows the doll viewport and each armor slot according to the toggle.
|
||||
/// Called once at construction (doll-view default) and on every button click.
|
||||
/// </summary>
|
||||
private void ApplyView()
|
||||
{
|
||||
if (_dollViewport is not null) _dollViewport.Visible = _viewState.DollVisible;
|
||||
foreach (var a in _armorSlots) a.Visible = _viewState.ArmorSlotsVisible;
|
||||
}
|
||||
|
||||
/// <summary>Detach event handlers (idempotent).</summary>
|
||||
public void Dispose()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue