137 lines
4.0 KiB
C#
137 lines
4.0 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using RebootKit.Engine.Foundation;
|
|
|
|
namespace RebootReality.jelycho.Items {
|
|
public class Inventory {
|
|
static readonly Logger s_Logger = new Logger(nameof(Inventory));
|
|
|
|
class SlotState {
|
|
public ushort ActorID;
|
|
public ItemActor Actor;
|
|
|
|
public void EmptySlot() {
|
|
ActorID = 0;
|
|
Actor = null;
|
|
}
|
|
}
|
|
|
|
readonly SlotState[] m_Slots;
|
|
|
|
public event Action<ItemActor> OnItemPickedUp = delegate { };
|
|
public event Action<ItemActor> OnItemDropped = delegate { };
|
|
public event Action<int> OnSlotUpdated = delegate { };
|
|
|
|
public int SlotsCount {
|
|
get {
|
|
return m_Slots.Length;
|
|
}
|
|
}
|
|
|
|
public Inventory(int slotsCount) {
|
|
m_Slots = new SlotState[slotsCount];
|
|
|
|
for (int i = 0; i < slotsCount; i++) {
|
|
m_Slots[i] = new SlotState();
|
|
}
|
|
}
|
|
|
|
//
|
|
// @MARK: Server API
|
|
//
|
|
public bool TryPickup(ItemActor actor) {
|
|
if (Contains(actor)) {
|
|
s_Logger.Error($"Item {actor.name} is already in the inventory.");
|
|
return false;
|
|
}
|
|
|
|
(int slotIndex, SlotState freeItemState) = FindFreeItemState();
|
|
if (freeItemState == null) {
|
|
s_Logger.Error("Inventory is full, cannot pick up item.");
|
|
return false;
|
|
}
|
|
|
|
freeItemState.Actor = actor;
|
|
OnItemPickedUp?.Invoke(actor);
|
|
OnSlotUpdated?.Invoke(slotIndex);
|
|
return true;
|
|
}
|
|
|
|
public bool TryDrop(int slotIndex, out ItemActor actor) {
|
|
if (slotIndex < 0 || slotIndex >= m_Slots.Length) {
|
|
s_Logger.Error($"Slot index {slotIndex} is out of range.");
|
|
actor = null;
|
|
return false;
|
|
}
|
|
|
|
if (m_Slots[slotIndex].Actor == null) {
|
|
s_Logger.Error($"No items in slot {slotIndex} to drop.");
|
|
actor = null;
|
|
return false;
|
|
}
|
|
|
|
actor = m_Slots[slotIndex].Actor;
|
|
m_Slots[slotIndex].Actor = null;
|
|
|
|
OnItemDropped?.Invoke(actor);
|
|
OnSlotUpdated?.Invoke(slotIndex);
|
|
return actor;
|
|
}
|
|
|
|
//
|
|
// @MARK: Common API
|
|
//
|
|
public void SetItem(int slotIndex, ItemActor actor) {
|
|
if (slotIndex < 0 || slotIndex >= m_Slots.Length) {
|
|
throw new ArgumentOutOfRangeException(nameof(slotIndex), "Slot index is out of range.");
|
|
}
|
|
|
|
if (actor == null) {
|
|
m_Slots[slotIndex].EmptySlot();
|
|
OnSlotUpdated?.Invoke(slotIndex);
|
|
return;
|
|
}
|
|
|
|
if (Contains(actor)) {
|
|
s_Logger.Error($"Item {actor.name} is already in the inventory.");
|
|
return;
|
|
}
|
|
|
|
m_Slots[slotIndex].Actor = actor;
|
|
m_Slots[slotIndex].ActorID = actor.ActorID;
|
|
OnSlotUpdated?.Invoke(slotIndex);
|
|
}
|
|
|
|
public ItemActor GetItem(int slotIndex) {
|
|
if (slotIndex < 0 || slotIndex >= m_Slots.Length) {
|
|
throw new ArgumentOutOfRangeException(nameof(slotIndex), "Slot index is out of range.");
|
|
}
|
|
|
|
return m_Slots[slotIndex].Actor;
|
|
}
|
|
|
|
public bool Contains(ItemActor actor) {
|
|
for (int i = 0; i < m_Slots.Length; i++) {
|
|
if (m_Slots[i].Actor == actor) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
(int slot, SlotState state) FindFreeItemState() {
|
|
for (int i = 0; i < m_Slots.Length; i++) {
|
|
if (m_Slots[i].Actor == null) {
|
|
return (i, m_Slots[i]);
|
|
}
|
|
}
|
|
|
|
return (-1, null);
|
|
}
|
|
|
|
//
|
|
// @MARK: Client API
|
|
//
|
|
|
|
}
|
|
} |