154 lines
5.3 KiB
C#
154 lines
5.3 KiB
C#
using System;
|
|
using System.Linq;
|
|
using RPGCore.BackpackEquipment.ObjectModules.Content;
|
|
using RPGCore.BackpackEquipment.ObjectModules.UnitBackpack.Events;
|
|
using RPGCore.BackpackEquipment.Objects;
|
|
using RPGCore.Core;
|
|
using RPGCore.Core.Objects;
|
|
using RPGCoreCommon.Helpers.PropertyAttributeDrawers;
|
|
using UnityEngine;
|
|
|
|
namespace RPGCore.BackpackEquipment.ObjectModules.UnitBackpack
|
|
{
|
|
[RequireComponent(typeof(UnitObject))]
|
|
[RequireComponent(typeof(ContentModule))]
|
|
[DisallowMultipleComponent]
|
|
public sealed class UnitBackpackModule : ObjectModule<UnitObject>, IContentOwner
|
|
{
|
|
// TODO: implementacja stackowania tutaj
|
|
[SerializeField] private ItemObject[] _serializedItems;
|
|
[SerializeField] public bool isLimited = true;
|
|
[SerializeField] public int itemsLimit = 5;
|
|
[SerializeField] public int itemsPerChunk = 5;
|
|
[SerializeField] public int minimumChunks = 3;
|
|
[SerializeField] public int additionalChunks = 1;
|
|
|
|
private ItemObject[] _items;
|
|
public ItemObject[] items => _items.ToArray();
|
|
|
|
private void Awake()
|
|
{
|
|
_items = _serializedItems.ToArray();
|
|
Resize();
|
|
}
|
|
|
|
private void Start()
|
|
{
|
|
InitializeItems();
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
private void InitializeItems()
|
|
{
|
|
// TODO: inicjalizacja serializowanych itemkow + ich eventy
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
public bool CanAdd(ItemObject item, int index)
|
|
{
|
|
return !isLimited || _items.Any(i => i == null);
|
|
}
|
|
|
|
bool IContentOwner.Add(ItemObject item, int index)
|
|
{
|
|
if (index < 0) index = Array.IndexOf(_items, false);
|
|
if (index < 0) return false;
|
|
if (isLimited && index >= itemsLimit) return false;
|
|
|
|
_items[index] = item;
|
|
Resize();
|
|
|
|
parent.events.Invoke(new BackpackAddEvent { unit = parent, item = item, index = index });
|
|
|
|
return true;
|
|
}
|
|
|
|
bool IContentOwner.Remove(ItemObject item)
|
|
{
|
|
var index = Array.IndexOf(_items, item);
|
|
if (index < 0) return false;
|
|
|
|
_items[index] = null;
|
|
Resize();
|
|
|
|
parent.events.Invoke(new BackpackRemoveEvent { unit = parent, item = item, index = index });
|
|
|
|
return true;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
|
|
public void Swap(int firstItemIndex, int secondItemIndex)
|
|
{
|
|
var wantedSize = Math.Max(firstItemIndex, secondItemIndex) + 1;
|
|
|
|
if (isLimited && wantedSize > itemsLimit) return;
|
|
|
|
Resize(wantedSize);
|
|
|
|
(items[firstItemIndex], items[secondItemIndex]) = (items[secondItemIndex], items[firstItemIndex]);
|
|
|
|
parent.events.Invoke(new BackpackSwapEvent
|
|
{
|
|
unit = parent,
|
|
firstSlotIndex = firstItemIndex,
|
|
firstItem = items[firstItemIndex],
|
|
secondSlotIndex = secondItemIndex,
|
|
secondItem = items[secondItemIndex],
|
|
});
|
|
}
|
|
|
|
private void Resize(int wantedSize = 0)
|
|
{
|
|
if (isLimited)
|
|
{
|
|
// TODO: obsłużyć itemki w miejscach, które zaraz zostaną "ucięte" (przy zmniejszaniu slotów) - TYLKO w limitowanym plecaku
|
|
if (_items.Length != itemsLimit)
|
|
{
|
|
Array.Resize(ref _items, itemsLimit);
|
|
}
|
|
return;
|
|
}
|
|
|
|
var limitBefore = items.Length;
|
|
var lastItemIndex = Array.FindLastIndex(items, item => item);
|
|
var limitMinimum = Mathf.Max(wantedSize, lastItemIndex, minimumChunks * itemsPerChunk);
|
|
var limitAfter = Mathf.CeilToInt((float)limitMinimum / itemsPerChunk + additionalChunks) * itemsPerChunk;
|
|
|
|
// Size not changed, do nothing
|
|
if (limitBefore == limitAfter) return;
|
|
|
|
// Resize backpack's arrays
|
|
Array.Resize(ref _items, limitAfter);
|
|
|
|
parent.events.Invoke(new BackpackResizeEvent
|
|
{
|
|
unit = parent,
|
|
beforeSlotCount = limitBefore,
|
|
afterSlotCount = limitAfter
|
|
});
|
|
}
|
|
|
|
public void Sort(Func<ItemObject, IComparable> valueGetter, bool sortDescending = false)
|
|
{
|
|
Array.Sort(items, (item1, item2) =>
|
|
{
|
|
// NULLS always to the end
|
|
if (!item1 && !item2) return 0;
|
|
if (!item1) return 1;
|
|
if (!item2) return -1;
|
|
|
|
// Existing items sort by given value getter with given sort direction
|
|
var result = valueGetter(item1).CompareTo(valueGetter(item2));
|
|
if (sortDescending) result *= - 1;
|
|
return result;
|
|
});
|
|
|
|
parent.events.Invoke(new BackpackSortEvent { unit = parent });
|
|
|
|
Resize();
|
|
}
|
|
}
|
|
} |