Matches the ClientObjectTable model-placement convention; Load now takes (slot,objGuid) pairs so the store has no Core.Net dependency. + self-drop wire-count assert + comment fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
34 lines
1.7 KiB
C#
34 lines
1.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
|
|
namespace AcDream.Core.Items;
|
|
|
|
/// <summary>
|
|
/// Mutable client-side model of the 18 toolbar shortcut slots — port of retail
|
|
/// <c>ShortCutManager::shortCuts_[18]</c> (acclient.h:36492). Holds the bound object guid per
|
|
/// slot (0 = empty). Loaded from the login shortcut list, then mutated by drag-drop (lift
|
|
/// removes, drop places); the server is notified via AddShortcut/RemoveShortcut so the store
|
|
/// stays the client's source of truth within a session (retail: client owns the array).
|
|
/// Item shortcuts only — entries with ObjGuid 0 (spell-only) are skipped on Load. Pure model
|
|
/// (no Core.Net dependency): callers project their wire entries to (slot, objGuid) pairs.
|
|
/// </summary>
|
|
public sealed class ShortcutStore
|
|
{
|
|
public const int SlotCount = 18;
|
|
private readonly uint[] _objIds = new uint[SlotCount];
|
|
|
|
/// <summary>Replace all slots from a (slot, objectGuid) sequence (item entries only;
|
|
/// ObjGuid 0 and out-of-range slots are skipped).</summary>
|
|
public void Load(IEnumerable<(int Slot, uint ObjGuid)> entries)
|
|
{
|
|
Array.Clear(_objIds);
|
|
foreach (var (slot, objGuid) in entries)
|
|
if ((uint)slot < SlotCount && objGuid != 0) _objIds[slot] = objGuid;
|
|
}
|
|
|
|
/// <summary>Bound object guid at <paramref name="slot"/>, or 0 (empty / out of range).</summary>
|
|
public uint Get(int slot) => (uint)slot < SlotCount ? _objIds[slot] : 0u;
|
|
public bool IsEmpty(int slot) => Get(slot) == 0u;
|
|
public void Set(int slot, uint objId) { if ((uint)slot < SlotCount) _objIds[slot] = objId; }
|
|
public void Remove(int slot) { if ((uint)slot < SlotCount) _objIds[slot] = 0u; }
|
|
}
|