using System.Collections.Generic;
namespace Cyber.Items {
///
/// A drive containing items, and has a limited capacity that cannot be changed.
///
public class Drive {
private Slot[] Slots = new Slot[0];
///
/// The capacity of the drive, meaning how much stuff can this drive contain.
///
public readonly float Capacity;
///
/// Creates a drive with given capacity. Capacity cannot be changed after this.
///
/// Capacity of the drive
public Drive(float capacity) {
Capacity = capacity;
}
///
/// Current total weight of all the items combined.
///
/// The totam weight
public float TotalWeight() {
float sum = 0;
foreach (Slot slot in Slots) {
if (slot.Item != null) {
sum += slot.Item.Weight;
}
}
return sum;
}
///
/// Current free space in the drive. Literally is Capacity - TotalWeight()
///
/// Current Free space.
public float FreeSpace() {
return Capacity - TotalWeight();
}
///
/// Clears the drive, completely wiping it empty. Mainly used for
///
///
public void Clear() {
Slots = new Slot[0];
}
///
/// Adds the item in the drive. If the addition was not successful, returns false, true otherwise.
///
/// Weather the drive had enough space.
public bool AddItem(Item item) {
if (item.Weight > FreeSpace()) {
return false;
}
bool foundEmpty = false;
for (int i = 0; i < Slots.Length; i++) {
if (Slots[i].Item == null) {
Slots[i] = new Slot(item, false);
foundEmpty = true;
}
}
if (!foundEmpty) {
// Add space and set the item there
IncreaseCapacity(1);
Slots[Slots.Length - 1] = new Slot(item, false);
}
return true;
}
///
/// Tries to add an item to a specific slot. Returns false if slot already occupied.
///
/// Item to add.
/// Index in the inventory.
/// Weather the slot was empty or not.
public bool AddItemToIndex(Item item, int idx) {
if (idx < 0) {
return false;
}
if (GetItemAt(idx) == null) {
if (Slots.Length > idx) {
Slots[idx].Item = item;
} else {
IncreaseCapacity(idx - Slots.Length + 1);
Slots[idx].Item = item;
}
return true;
}
return false;
}
///
/// Switches two slots at given indices, allowing moving items around the inventory.
///
/// The first index.
/// The second index.
public void SwitchSlots(int idx1, int idx2) {
if (idx1 == idx2) {
return;
}
Slot Slot1 = GetSlotAt(idx1);
Slot Slot2 = GetSlotAt(idx2);
SetSlotAt(idx1, Slot2);
SetSlotAt(idx2, Slot1);
}
private void SetSlotAt(int idx, Slot slot) {
if (idx >= Slots.Length) {
IncreaseCapacity(idx - Slots.Length + 1);
}
Slots[idx] = slot;
}
///
/// Gets the item at the given index, or null if there is nothing.
///
/// The index of the desired item
/// The item or null if nothing was found.
public Item GetItemAt(int idx) {
return GetSlotAt(idx).Item;
}
///
/// Returns the list of all items currently in the drive.
///
///
public List- GetItems() {
List
- Items = new List
- ();
foreach (Slot slot in Slots) {
if (slot.Item != null) {
Items.Add(slot.Item);
}
}
return Items;
}
///
/// Gets the item at the given slot. Loops through all items and checks if there is an item equipped at the given slot and returns it if there is.
///
/// The desired slot
/// The item at the slot, or null if no items
public Item GetSlot(EquipSlot slot) {
Item Item = null;
foreach (Slot s in Slots) {
if (s.Item != null && s.Item.Slot == slot && s.Equipped) {
Item = s.Item;
break;
}
}
return Item;
}
///
/// Returns all the equipped items in a dictionary.
///
/// The dictionary of items.
public Dictionary GetEquippedItems() {
Dictionary Items = new Dictionary();
foreach (Slot s in Slots) {
if (s.Item != null && s.Equipped) {
Items.Add(s.Item.Slot, s.Item);
}
}
return Items;
}
///
/// Attempt to equip the item at the given index.
///
/// Equip the iten at the given slot
/// Weather the item could be equipped or if there already exists something on that equip slot.
public bool EquipItem(int idx) {
Slot Slot = GetSlotAt(idx);
if (Slot.Item != null && GetSlot(Slot.Item.Slot) == null) {
Slots[idx].Equipped = true;
return true;
}
return false;
}
///
/// Unequips the item at the given inventory index.
///
/// The index to unequip.
public void UnequipItem(int idx) {
Slot Slot = GetSlotAt(idx);
if (Slot.Item != null) {
Slots[idx].Equipped = false;
}
}
///
/// Unequip all items that are in this slot.
///
/// The slot of the desired item to be unequipped.
public void UnequipSlot(EquipSlot equipSlot) {
for (int i = 0; i < Slots.Length; i++) {
if (Slots[i].Item != null && Slots[i].Item.Slot == equipSlot) {
Slots[i].Equipped = false;
}
}
}
///
/// Simply returns the slots-array. The fastest way to get all of inventory if needed.
///
/// The Slot-structs
public Slot[] GetSlots() {
return Slots;
}
private void IncreaseCapacity(int moreCapacity) {
Slot[] NewSlots = new Slot[Slots.Length + moreCapacity];
for (int i = 0; i < Slots.Length; i++) {
NewSlots[i] = Slots[i];
}
Slots = NewSlots;
}
private Slot GetSlotAt(int idx) {
if (idx < 0 || idx >= Slots.Length) {
return new Slot(null, false);
}
return Slots[idx];
}
}
}