using System; using System.Collections.Concurrent; namespace AcDream.Core.Items; /// /// Last server-reported mana fraction for queried inventory items. /// Retail routes QueryItemManaResponse (0x0264) through /// ClientUISystem::Handle_Item__QueryItemManaResponse @ 0x00563FE0, including /// the response's validity flag, before notifying the selected-object toolbar. /// public sealed class ItemManaState { private readonly ConcurrentDictionary _manaByGuid = new(); private long _revision; /// Fires for every valid or invalid query response. public event Action? ItemManaChanged; public float GetManaPercent(uint guid) => _manaByGuid.TryGetValue(guid, out float percent) ? percent : 0f; public bool HasMana(uint guid) => _manaByGuid.ContainsKey(guid); public int Count => _manaByGuid.Count; public long Revision => Interlocked.Read(ref _revision); public bool TryGetManaPercent(uint guid, out float fraction) => _manaByGuid.TryGetValue(guid, out fraction); public void OnQueryItemManaResponse(uint itemGuid, float manaPercent, bool valid) { if (valid) _manaByGuid[itemGuid] = manaPercent; else _manaByGuid.TryRemove(itemGuid, out _); Interlocked.Increment(ref _revision); ItemManaChanged?.Invoke(itemGuid, manaPercent, valid); } public void Clear() { _manaByGuid.Clear(); Interlocked.Increment(ref _revision); } }