106 lines
3.3 KiB
C#
106 lines
3.3 KiB
C#
using System.Collections.Generic;
|
|
using UnityEngine;
|
|
|
|
namespace Ashwild.Inventory
|
|
{
|
|
/// <summary>
|
|
/// Network-safe registry mapping every ItemData to a stable numeric id and back. Because
|
|
/// ScriptableObject references cannot be sent over the network, the inventory syncs item ids
|
|
/// instead and resolves them through this database. All machines share the same asset (same
|
|
/// build → same order → same ids). Lives in a Resources folder so it loads without wiring.
|
|
/// </summary>
|
|
[CreateAssetMenu(fileName = "ItemDatabase", menuName = "Items/Item Database")]
|
|
public class ItemDatabase : ScriptableObject
|
|
{
|
|
#region Serialized Fields
|
|
|
|
/// <summary>
|
|
/// All items, in a fixed order. The network id of an item is its index + 1 (0 = none).
|
|
/// Rebuilt by Tools ▸ Ashwild ▸ Rebuild Item Database.
|
|
/// </summary>
|
|
[SerializeField] private ItemData[] items;
|
|
|
|
#endregion
|
|
|
|
#region State
|
|
|
|
private static ItemDatabase instance;
|
|
private Dictionary<ItemData, ushort> idByItem;
|
|
|
|
#endregion
|
|
|
|
#region Public API
|
|
|
|
/// <summary>
|
|
/// The shared database, lazily loaded from Resources/ItemDatabase.
|
|
/// </summary>
|
|
public static ItemDatabase Instance
|
|
{
|
|
get
|
|
{
|
|
if (instance == null)
|
|
{
|
|
instance = Resources.Load<ItemDatabase>("ItemDatabase");
|
|
if (instance == null)
|
|
Debug.LogError("[ItemDatabase] No 'ItemDatabase' asset found in a Resources folder — run Tools ▸ Ashwild ▸ Rebuild Item Database.");
|
|
else
|
|
instance.BuildLookup();
|
|
}
|
|
return instance;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// All registered items, in id order.
|
|
/// </summary>
|
|
public ItemData[] Items => items;
|
|
|
|
/// <summary>
|
|
/// Returns the network id of an item (0 when null or not registered).
|
|
/// </summary>
|
|
public ushort GetId(ItemData item)
|
|
{
|
|
if (item == null) return 0;
|
|
if (idByItem == null) BuildLookup();
|
|
return idByItem.TryGetValue(item, out ushort id) ? id : (ushort)0;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resolves a network id back to its ItemData (null when id is 0 or out of range).
|
|
/// </summary>
|
|
public ItemData GetItem(ushort id)
|
|
{
|
|
if (id == 0 || items == null || id > items.Length) return null;
|
|
return items[id - 1];
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Internal Helpers
|
|
|
|
/// <summary>
|
|
/// (Re)builds the item → id lookup from the serialized array.
|
|
/// </summary>
|
|
private void BuildLookup()
|
|
{
|
|
idByItem = new Dictionary<ItemData, ushort>();
|
|
if (items == null) return;
|
|
|
|
for (int i = 0; i < items.Length; i++)
|
|
if (items[i] != null) idByItem[items[i]] = (ushort)(i + 1);
|
|
}
|
|
|
|
#endregion
|
|
|
|
#if UNITY_EDITOR
|
|
/// <summary>
|
|
/// Editor-only: replaces the item list (used by the rebuild tool).
|
|
/// </summary>
|
|
public void EditorSetItems(ItemData[] all)
|
|
{
|
|
items = all;
|
|
}
|
|
#endif
|
|
}
|
|
}
|