189 lines
4.7 KiB
C#
189 lines
4.7 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using UnityEditor.Tilemaps;
|
|
|
|
public delegate string NameCallback();
|
|
|
|
public abstract class IInventory
|
|
{
|
|
private List<Action> changeCallbacks = new List<Action>();
|
|
|
|
public abstract string Name { get; }
|
|
|
|
public abstract IReadOnlyDictionary<string, float> Items { get; }
|
|
|
|
public abstract float Capacity { get; set; }
|
|
|
|
public float Load => Items.Sum(kvp => kvp.Value);
|
|
|
|
public float Free => Capacity < 0 ? int.MaxValue : Capacity - Load;
|
|
|
|
public abstract float GetAmount(string item);
|
|
|
|
protected abstract int DoClear();
|
|
protected abstract float DoAdd(string item, float amount, bool allowPartialAdd = false);
|
|
protected abstract float DoRemove(string item, float amount, bool allowPartialRemoval = false);
|
|
|
|
public float Clear()
|
|
{
|
|
var cleared = DoClear();
|
|
if (cleared > 0)
|
|
InvokeOnChange();
|
|
return cleared;
|
|
}
|
|
|
|
public float Add(string item, float amount, bool allowPartialAdd = false)
|
|
{
|
|
var added = DoAdd(item, amount, allowPartialAdd);
|
|
if (added > 0)
|
|
InvokeOnChange();
|
|
return added;
|
|
}
|
|
|
|
public float Remove(string item, float amount, bool allowPartialRemoval = false)
|
|
{
|
|
var removed = DoRemove(item, amount, allowPartialRemoval);
|
|
if (removed > 0)
|
|
InvokeOnChange();
|
|
return removed;
|
|
}
|
|
|
|
public void RegisterOnChangeCallback(Action callback)
|
|
{
|
|
changeCallbacks.Add(callback);
|
|
}
|
|
|
|
public void UnregisterOnChangeCallback(Action callback)
|
|
{
|
|
changeCallbacks.Remove(callback);
|
|
}
|
|
|
|
private void InvokeOnChange()
|
|
{
|
|
// Debug.Log(
|
|
// $"Resources: {String.Join("; ", resources.Values.ToArray().Select(r => r.Resource.Name + "=" + r.Amount + (r.Unlocked ? "" : "(locked)")))}"
|
|
// );
|
|
|
|
changeCallbacks.ForEach(a =>
|
|
{
|
|
try
|
|
{
|
|
a.Invoke();
|
|
}
|
|
catch { }
|
|
});
|
|
}
|
|
}
|
|
|
|
[Serializable]
|
|
public class Inventory2 : IInventory, IDataPersistence<InventoryData>
|
|
{
|
|
private NameCallback nameCallback;
|
|
private Dictionary<string, float> items = new Dictionary<string, float>();
|
|
|
|
public Inventory2(float capacity, NameCallback nameCallback)
|
|
{
|
|
this.nameCallback = nameCallback;
|
|
_capacity = capacity;
|
|
}
|
|
|
|
public override IReadOnlyDictionary<string, float> Items => items;
|
|
|
|
private float _capacity;
|
|
|
|
public override string Name => nameCallback();
|
|
|
|
public override float Capacity
|
|
{
|
|
get { return _capacity; }
|
|
set { _capacity = value; }
|
|
}
|
|
|
|
public override string ToString()
|
|
{
|
|
return this.ToString(Environment.NewLine);
|
|
}
|
|
|
|
public string ToString(string delimiter = "\n")
|
|
{
|
|
string text = string.Join(delimiter, items);
|
|
text += delimiter + $"Занято {Load}";
|
|
if (Capacity >= 0)
|
|
text += $", свободно {Capacity - Load}";
|
|
|
|
return text;
|
|
}
|
|
|
|
public override float GetAmount(string item)
|
|
{
|
|
return items.ContainsKey(item) ? items[item] : 0;
|
|
}
|
|
|
|
protected override int DoClear()
|
|
{
|
|
var itemCount = items.Count;
|
|
items.Clear();
|
|
return itemCount;
|
|
}
|
|
|
|
protected override float DoAdd(string item, float amount, bool allowPartialAdd = false)
|
|
{
|
|
if (!allowPartialAdd && (Capacity >= 0) && (Capacity < Load + amount))
|
|
return 0;
|
|
|
|
amount = Math.Min(amount, Free);
|
|
|
|
if (items.ContainsKey(item))
|
|
items[item] += amount;
|
|
else
|
|
items[item] = amount;
|
|
|
|
return amount;
|
|
}
|
|
|
|
protected override float DoRemove(string item, float amount, bool allowPartialRemoval = false)
|
|
{
|
|
var presentAmount = GetAmount(item);
|
|
|
|
if (!allowPartialRemoval && presentAmount < amount)
|
|
return 0;
|
|
|
|
amount = Math.Min(amount, presentAmount);
|
|
|
|
items[item] -= amount;
|
|
if (items[item] == 0)
|
|
items.Remove(item);
|
|
|
|
return amount;
|
|
}
|
|
|
|
public void LoadData(InventoryData data)
|
|
{
|
|
items = data.items;
|
|
_capacity = data.capacity;
|
|
}
|
|
|
|
public void SaveData(InventoryData data)
|
|
{
|
|
data.items = new SerializableDictionary<string, float>(items);
|
|
data.capacity = _capacity;
|
|
}
|
|
|
|
public Inventory2 Clone()
|
|
{
|
|
var clone = new Inventory2(Capacity, nameCallback);
|
|
foreach (var kvp in items)
|
|
clone.items.Add(kvp.Key, kvp.Value);
|
|
|
|
return clone;
|
|
}
|
|
|
|
public void OverrideItemsFrom(Inventory2 source)
|
|
{
|
|
Clear();
|
|
foreach (var kvp in source.Items)
|
|
items.Add(kvp.Key, kvp.Value);
|
|
}
|
|
}
|