This commit is contained in:
2026-07-09 21:33:33 +02:00
commit 84a2a365f3
2364 changed files with 950134 additions and 0 deletions
@@ -0,0 +1,27 @@
using System.Collections.Generic;
using System.Linq;
using Sirenix.OdinInspector;
using VOID.Generic.Objects.Item;
namespace VOID.Generic.Objects.Container
{
public class ContainerObject : ItemObject
{
[Title("=== Container properties ===")]
public ContainerObjectContent containerContent;
public ContainerObjectEvents containerEvents;
public ContainerObjectState containerState;
protected override List<ObjectComponent> GetObjectComponents()
{
return base.GetObjectComponents()
.Union(new List<ObjectComponent>
{
containerContent,
containerEvents,
containerState
})
.ToList();
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 37f8cee46dd9b8543acc23235bbe540b
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {fileID: 2800000, guid: 68c775dbd783c454186a68b886426716, type: 3}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,211 @@
using System;
using JetBrains.Annotations;
using Sirenix.OdinInspector;
using UnityEngine;
using VOID.Generic.Dict;
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Container.Events;
using VOID.Generic.Objects.Item;
using VOID.Generic.Objects.Unit;
using VOID.Generic.Util;
using Object = UnityEngine.Object;
namespace VOID.Generic.Objects.Container
{
[Serializable]
public class ContainerObjectContent : ObjectComponent<ContainerObject>
{
#region Initialize
protected override void SelfInitialize()
{
// Empty GameObject where all items from backpack are "attached"
_content = new GameObject("_content");
_content.transform.parent = parent.gameObject.transform;
_content.transform.localPosition = Vector3.zero;
}
protected override void Initialize()
{
// Instantiate all prefabs
for (var i = 0; i < _items.Length; i++)
{
if (!_items[i]) continue;
var item = _items[i];
_items[i] = null;
// Selected item is ASSET (prefab), we need to instantiate it first
if (!item.gameObject.scene.IsValid())
item = Object.Instantiate(item.gameObject).GetComponent<ItemObject>();
// Instantiate prefab and get references to its GameObject and ItemObject
MoveIn(i, item);
}
Resize();
}
#endregion
private GameObject _content;
// Items in content (list of ItemObjects and their GameObjects)
[SerializeField, DisableInPlayMode] private ItemObject[] _items = Array.Empty<ItemObject>();
public ItemObject[] items => _items;
public void MoveIn(int itemIndex, ItemObject item, UnitObject byWho = null)
{
if (items.Length <= itemIndex)
Resize(itemIndex);
if (items[itemIndex])
{
MoveIn(item, byWho);
return;
}
items[itemIndex] = item;
var moveInEvent = new ContainerMoveInEvent
{
byWho = byWho,
item = item,
slotIndex = itemIndex,
container = parent,
};
parent.containerEvents.onMoveIn.Invoke(moveInEvent);
item.itemEvents.onMovedIntoContainer.Invoke(moveInEvent);
var itemGameObject = item.gameObject;
itemGameObject.transform.parent = _content.transform;
itemGameObject.transform.localPosition = Vector3.zero;
itemGameObject.transform.localRotation = new Quaternion();
item.basicEvents.onRemove.AddListener(OnItemRemove);
Resize();
}
public void MoveIn(ItemObject item, UnitObject byWho = null)
{
// Find first free slot in backpack
var firstFreeIndex = Array.IndexOf(items, null);
// No free slots, we need to resize array
if (firstFreeIndex == -1)
{
firstFreeIndex = items.Length;
Resize();
}
MoveIn(firstFreeIndex, item, byWho);
}
public void MoveOut(int itemIndex, UnitObject byWho = null)
{
var tempMoveOutItem = items[itemIndex];
items[itemIndex].basicEvents.onRemove.RemoveListener(OnItemRemove);
items[itemIndex] = null;
var moveOutEvent = new ContainerMoveOutEvent
{
byWho = byWho,
item = tempMoveOutItem,
slotIndex = itemIndex,
container = parent,
};
parent.containerEvents.onMoveOut.Invoke(moveOutEvent);
tempMoveOutItem.itemEvents.onMovedOutOfContainer.Invoke(moveOutEvent);
var tempItemGameObject = tempMoveOutItem.gameObject;
tempItemGameObject.gameObject.transform.parent = null;
tempItemGameObject.gameObject.transform.position = parent.transform.position;
Resize();
}
public void MoveOut(ItemObject item, UnitObject byWho = null)
{
MoveOut(Array.IndexOf(items, item), byWho);
}
public void Swap(int firstItemIndex, int secondItemIndex, UnitObject byWho = null)
{
Resize(Math.Max(firstItemIndex, secondItemIndex));
(items[firstItemIndex], items[secondItemIndex]) = (items[secondItemIndex], items[firstItemIndex]);
var swapEvent = new ContainerSwapEvent
{
byWho = byWho,
firstSlotIndex = firstItemIndex,
firstItem = items[firstItemIndex],
secondSlotIndex = secondItemIndex,
secondItem = items[secondItemIndex],
};
parent.containerEvents.onSwap.Invoke(swapEvent);
Resize();
}
public void Sort(Func<ItemObject, IComparable> valueGetter, SortDirectionType sortDirection, [CanBeNull] UnitObject byWho = null) {
ItemObjectSortUtil.Sort(ref _items, valueGetter, sortDirection);
var containerSortEvent = new ContainerSortEvent {
container = parent,
byUnit = byWho
};
parent.containerEvents.onSort.Invoke(containerSortEvent);
Resize();
}
private void OnItemRemove(RemoveEvent removeEvent)
{
var removedItem = removeEvent.obj as ItemObject;
MoveOut(removedItem);
}
public void Resize(int minSize = 0, int rowSize = 10)
{
var beforeSlotCount = items.Length;
var lastItemIndex = 0;
// Find last slotIndex with existing item (not null)
for (var i = beforeSlotCount - 1; i >= 0; i--)
{
lastItemIndex = i;
if (items[i] is not null) break;
}
// Count how many slots backpack will have after resize
var afterSlotCount = Mathf.CeilToInt((Mathf.Max(lastItemIndex, minSize) + rowSize) / (float)rowSize) * rowSize;
// Size not changed, do nothing
if (beforeSlotCount == afterSlotCount) return;
// Resize backpack's arrays
var tempItems = items;
Array.Resize(ref tempItems, afterSlotCount);
_items = tempItems;
var containerResizeEvent = new ContainerResizeEvent
{
container = parent,
beforeSlotCount = beforeSlotCount,
afterSlotCount = afterSlotCount,
lastItemIndex = lastItemIndex,
};
parent.containerEvents.onResize.Invoke(containerResizeEvent);
}
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 15d9b66f28cc25b43b63a1f5e103fc3e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,19 @@
using Sirenix.OdinInspector;
using UnityEngine.Events;
using VOID.Generic.Objects.Container.Events;
namespace VOID.Generic.Objects.Container
{
[System.Serializable]
public class ContainerObjectEvents : ObjectComponent<ContainerObject>
{
[Title("Usage")]
public UnityEvent<ContainerCloseEvent> onClose;
public UnityEvent<ContainerOpenEvent> onOpen;
public UnityEvent<ContainerMoveInEvent> onMoveIn;
public UnityEvent<ContainerMoveOutEvent> onMoveOut;
public UnityEvent<ContainerSwapEvent> onSwap;
public UnityEvent<ContainerResizeEvent> onResize;
public UnityEvent<ContainerSortEvent> onSort;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eb8542ecd6532ad409c44825793bab9f
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,51 @@
using Sirenix.Utilities;
using System;
using System.Collections.Generic;
using VOID.Generic.Objects.Container;
using VOID.Generic.Objects.Container.Events;
using VOID.Generic.Objects.Item.Events;
using VOID.Generic.Objects.Unit;
namespace VOID.Generic.Objects.Item
{
[Serializable]
public class ContainerObjectState : ObjectComponent<ContainerObject>
{
#region Initialize
protected override void EventInitialize()
{
parent.containerEvents.onOpen.AddListener(OnOpen);
parent.containerEvents.onClose.AddListener(OnClose);
parent.itemEvents.onPickedAfter.AddListener(OnPick);
}
#endregion
public List<UnitObject> openedBy { get; private set; } = new();
private void OnOpen(ContainerOpenEvent containerOpenEvent)
{
openedBy.Add(containerOpenEvent.openedBy);
}
private void OnClose(ContainerCloseEvent containerCloseEvent)
{
openedBy.Remove(containerCloseEvent.closedBy);
}
private void OnPick(PickEvent pickEvent)
{
Array.FindAll(parent.containerContent.items, item => item != null).ForEach(item =>
{
var itemPickEvent = new PickEvent
{
item = item,
unit = pickEvent.unit
};
item.itemEvents.onPickedAfter.Invoke(itemPickEvent);
});
}
}
}
@@ -0,0 +1,3 @@
fileFormatVersion: 2
guid: b35b3ac08e39415b9f1e00545c767359
timeCreated: 1694902221
@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 2fc349196cde3db4aaaff97ae6ba8d1e
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Unit;
namespace VOID.Generic.Objects.Container.Events
{
public class ContainerCloseEvent : AbstractEvent
{
public ContainerObject container;
public UnitObject closedBy;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 70372499eaf8ddf40baa8eb28c12de8a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,14 @@
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Item;
using VOID.Generic.Objects.Unit;
namespace VOID.Generic.Objects.Container.Events
{
public class ContainerMoveInEvent : AbstractEvent
{
public ContainerObject container;
public ItemObject item;
public UnitObject byWho;
public int slotIndex;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: f13301de95085544aa495fd5f4fe1ecf
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,14 @@
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Item;
using VOID.Generic.Objects.Unit;
namespace VOID.Generic.Objects.Container.Events
{
public class ContainerMoveOutEvent : AbstractEvent
{
public ContainerObject container;
public ItemObject item;
public UnitObject byWho;
public int slotIndex;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: be8a0191932d5b149af6d43b2c3a2be6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,11 @@
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Unit;
namespace VOID.Generic.Objects.Container.Events
{
public class ContainerOpenEvent : AbstractEvent
{
public ContainerObject container;
public UnitObject openedBy;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a0c16043a285e284d9402cfa592c760c
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using VOID.Generic.Objects.Abstract.Events;
namespace VOID.Generic.Objects.Container.Events
{
public class ContainerResizeEvent : AbstractEvent
{
public ContainerObject container;
public int beforeSlotCount;
public int afterSlotCount;
public int lastItemIndex;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 8963991c7bd010b41be0dfeb46facce8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
@@ -0,0 +1,12 @@
using JetBrains.Annotations;
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Unit;
namespace VOID.Generic.Objects.Container.Events
{
public class ContainerSortEvent : AbstractEvent
{
public ContainerObject container;
[CanBeNull] public UnitObject byUnit;
}
}
@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: d44467820dd6ab94b9f2b723623d5288
@@ -0,0 +1,16 @@
using VOID.Generic.Objects.Abstract.Events;
using VOID.Generic.Objects.Item;
using VOID.Generic.Objects.Unit;
namespace VOID.Generic.Objects.Container.Events
{
public class ContainerSwapEvent : AbstractEvent
{
public ContainerObject container;
public UnitObject byWho;
public int firstSlotIndex;
public ItemObject firstItem;
public int secondSlotIndex;
public ItemObject secondItem;
}
}
@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: ba97578f98b3599488f085ee67819676
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: