canto/Assets/Scripts/Item/Item.cs

103 lines
2.9 KiB
C#

using System.Collections.Generic;
using System.Text;
using KitsuneCafe.Sys;
using KitsuneCafe.Sys.Attributes;
using MessagePack;
using MessagePack.Formatters;
using UnityEngine;
using UnityEngine.AddressableAssets;
using UnityEngine.ResourceManagement.AsyncOperations;
namespace KitsuneCafe.ItemSystem
{
public class ItemSystemResolver : IFormatterResolver
{
public static ItemSystemResolver Instance = new();
private readonly ItemFormatter itemFormatter = new();
public IMessagePackFormatter<T> GetFormatter<T>()
{
if (typeof(T) == typeof(Item))
{
return (IMessagePackFormatter<T>)itemFormatter;
}
return null;
}
}
public class ItemFormatter : IMessagePackFormatter<Item>
{
private readonly Dictionary<string, Item> items = new();
private readonly Dictionary<Item, string> addresses = new();
public ItemFormatter()
{
var handle = Addressables.LoadResourceLocationsAsync(
new string[] { "Item" },
Addressables.MergeMode.Union
);
handle.WaitForCompletion();
var ops = new List<AsyncOperationHandle>();
foreach (var location in handle.Result)
{
var assetHandle = Addressables.LoadAssetAsync<Item>(location);
assetHandle.Completed += item =>
{
items.Add(location.PrimaryKey, item.Result);
addresses.Add(item.Result, location.PrimaryKey);
};
ops.Add(assetHandle);
}
var groupOp = Addressables.ResourceManager.CreateGenericGroupOperation(ops);
groupOp.WaitForCompletion();
Addressables.Release(handle);
}
public Item Deserialize(ref MessagePackReader reader, MessagePackSerializerOptions options)
{
if (reader.TryReadNil())
{
return null;
}
var address = reader.ReadString();
return items[address];
}
public void Serialize(ref MessagePackWriter writer, Item value, MessagePackSerializerOptions options)
{
if (value == null)
{
writer.WriteNil();
return;
}
var address = addresses[value];
var bytes = Encoding.ASCII.GetBytes(address);
writer.WriteString(bytes);
}
}
[CreateAssetMenu(menuName = KitsuneCafeMenu.Item + "Item")]
public class Item : BaseItem, IStackable
{
[SerializeField]
private bool stackable;
public bool IsStackable => stackable;
[SerializeField, ShowIf("stackable")]
private int maxStackCount = 1;
public int MaxStackCount => maxStackCount;
private void Reset()
{
GenerateNewId();
}
}
}