feat(ui): complete retail item drop branches
Give retained buttons a reusable item-drop seam, wire the toolbar backpack target, and port retail stack-merge legality, capacity clamping, wire dispatch, destination selection, and immediate shortcut rekey notice. Record the live ACE merge gate and keep split quantity under AP-101. Co-Authored-By: Codex <codex@openai.com>
This commit is contained in:
parent
3281e0acb4
commit
dc1649c493
19 changed files with 479 additions and 28 deletions
|
|
@ -92,8 +92,8 @@ public static class ShortcutDropPlanner
|
|||
|
||||
/// <summary>
|
||||
/// Plan the toolbar side of <c>RecvNotice_FullMergingItem @ 0x004BE9B0</c>.
|
||||
/// The normal retail invariant is one object shortcut; all matching records are
|
||||
/// rekeyed here so a malformed duplicate cannot retain a destroyed stack id.
|
||||
/// <c>CreateShortcutToItem</c> removes an existing destination shortcut before
|
||||
/// placing it into the source shortcut's former slot.
|
||||
/// </summary>
|
||||
public static ShortcutMutation[] PlanFullStackMerge(
|
||||
IReadOnlyList<ShortcutEntry?> slots,
|
||||
|
|
@ -104,15 +104,21 @@ public static class ShortcutDropPlanner
|
|||
if (slots.Count != ShortcutStore.SlotCount || oldObjectId == 0 || newObjectId == 0)
|
||||
return Array.Empty<ShortcutMutation>();
|
||||
|
||||
var mutations = new List<ShortcutMutation>();
|
||||
var state = new ShortcutEntry?[ShortcutStore.SlotCount];
|
||||
for (int slot = 0; slot < slots.Count; slot++)
|
||||
{
|
||||
if (VisibleEntry(slots[slot]) is not { } entry || entry.ObjectId != oldObjectId)
|
||||
continue;
|
||||
|
||||
mutations.Add(ShortcutMutation.Remove(slot));
|
||||
mutations.Add(ShortcutMutation.Add(entry with { ObjectId = newObjectId }));
|
||||
state[slot] = slots[slot];
|
||||
}
|
||||
|
||||
var mutations = new List<ShortcutMutation>(3);
|
||||
int sourceSlot = FindFirstVisibleObject(state, oldObjectId);
|
||||
if (sourceSlot < 0)
|
||||
return Array.Empty<ShortcutMutation>();
|
||||
|
||||
ShortcutEntry sourceEntry = state[sourceSlot]!.Value;
|
||||
RemoveVisibleAt(state, sourceSlot, mutations);
|
||||
RemoveFirstVisibleObject(state, newObjectId, mutations);
|
||||
Add(state, sourceEntry with { ObjectId = newObjectId }, mutations);
|
||||
return mutations.ToArray();
|
||||
}
|
||||
|
||||
|
|
@ -149,6 +155,14 @@ public static class ShortcutDropPlanner
|
|||
}
|
||||
}
|
||||
|
||||
private static int FindFirstVisibleObject(ShortcutEntry?[] state, uint objectId)
|
||||
{
|
||||
for (int slot = 0; slot < state.Length; slot++)
|
||||
if (VisibleEntry(state[slot]) is { } entry && entry.ObjectId == objectId)
|
||||
return slot;
|
||||
return -1;
|
||||
}
|
||||
|
||||
private static void Add(
|
||||
ShortcutEntry?[] state,
|
||||
ShortcutEntry entry,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue