RobotFactoryIncrementalGame/Assets/Scripts/Inventory.cs

187 lines
4.5 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 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);
}
protected 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 Dictionary<string, float> items = new Dictionary<string, float>();
public Inventory2(float capacity)
{
_capacity = capacity;
}
public override IReadOnlyDictionary<string, float> Items => items;
private float _capacity;
public override float Capacity
{
get { return _capacity; }
set
{
_capacity = value;
InvokeOnChange();
}
}
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);
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);
}
}