zombie_mp/Assets/HQ FPS Weapons/Scripts/Inventory/Inventory.cs
Sewmina Dilshan 68183e5317 initial
2021-08-23 13:28:33 +05:30

331 lines
7.1 KiB
C#

using System.Collections.Generic;
using System.Collections;
using UnityEngine;
using Random = UnityEngine.Random;
namespace HQFPSWeapons
{
public class Inventory : LivingEntityComponent
{
public Message ContainerChanged = new Message();
public List<ItemContainer> Containers
{
get
{
if(m_AllContainers == null)
InitiateContainers();
return m_AllContainers;
}
}
[BHeader("Storage")]
[SerializeField]
private ContainerGenerator[] m_InitialContainers = null;
[BHeader("Item Drop")]
[SerializeField]
private bool m_DropItemsOnDeath = true;
[SerializeField]
private SoundPlayer m_DropSounds = null;
[Space]
[SerializeField]
private Vector3 m_DropOffset = new Vector3(0f, 0f, 0.8f);
[SerializeField]
private float m_DropAngularFactor = 150f;
[SerializeField]
private float m_DropSpeed = 8f;
[SerializeField]
private LayerMask m_WallsLayer = new LayerMask();
private List<ItemContainer> m_SavableContainers;
private List<ItemContainer> m_AllContainers;
public void AddContainer(ItemContainer itemContainer, bool add)
{
if(add && !Containers.Contains(itemContainer))
{
Containers.Add(itemContainer);
AddListeners(itemContainer, true);
}
else if(!add && Containers.Contains(itemContainer))
{
Containers.Remove(itemContainer);
AddListeners(itemContainer, false);
}
}
public bool HasContainerWithFlags(ItemContainerFlags flags)
{
for(int i = 0;i < Containers.Count;i ++)
if(flags.HasFlag(Containers[i].Flag))
return true;
return false;
}
public ItemContainer GetContainerWithFlags(ItemContainerFlags flags)
{
for(int i = 0;i < Containers.Count;i ++)
if(flags.HasFlag(Containers[i].Flag))
return Containers[i];
return null;
}
public ItemContainer GetContainerWithName(string name)
{
for(int i = 0;i < Containers.Count;i ++)
if(Containers[i].Name == name)
return Containers[i];
return null;
}
public bool AddItem(SaveableItem item, ItemContainerFlags flags)
{
for(int i = 0;i < Containers.Count;i ++)
{
if(flags.HasFlag(Containers[i].Flag))
{
bool added = Containers[i].AddItem(item);
if(added)
return true;
}
}
return false;
}
/// <summary>
/// </summary>
public int AddItem(string itemName, int amountToAdd, ItemContainerFlags flags)
{
int addedInTotal = 0;
for(int i = 0;i < Containers.Count;i ++)
{
if(flags.HasFlag(m_AllContainers[i].Flag))
{
int addedNow = Containers[i].AddItem(itemName, amountToAdd);
addedInTotal += addedNow;
if(addedNow == addedInTotal)
return addedInTotal;
}
}
return addedInTotal;
}
public bool RemoveItem(SaveableItem item)
{
for(int i = 0;i < Containers.Count;i ++)
{
if(m_AllContainers[i].RemoveItem(item))
return true;
}
return false;
}
/// <summary>
/// </summary>
public int RemoveItems(string itemName, int amountToRemove, ItemContainerFlags flags)
{
int removedInTotal = 0;
for(int i = 0;i < Containers.Count;i ++)
{
if(flags.HasFlag(Containers[i].Flag))
{
int removedNow = Containers[i].RemoveItem(itemName, amountToRemove);
removedInTotal += removedNow;
if (removedInTotal == amountToRemove)
break;
}
}
return removedInTotal;
}
/// <summary>
/// Counts all the items with name itemName, from all containers.
/// </summary>
public int GetItemCount(string itemName)
{
int count = 0;
for(int i = 0;i < Containers.Count;i ++)
count += Containers[i].GetItemCount(itemName);
return count;
}
public ItemSlot GetItemSlot(SaveableItem item)
{
foreach (var container in m_SavableContainers)
{
foreach (ItemSlot slot in container)
{
if (slot.Item == item)
return slot;
}
}
return null;
}
public bool TryDropItem(SaveableItem item, bool tryRemoveFromContainers = false)
{
bool canBeDropped = item != null && item.Data.WorldObject != null && (!tryRemoveFromContainers || RemoveItem(item));
if(canBeDropped)
{
Player player = Entity as Player;
float crouchHeightDrop = 1f;
if (player != null)
crouchHeightDrop = 1f;
StartCoroutine(C_Drop(item, crouchHeightDrop));
return true;
}
return false;
}
private IEnumerator C_Drop(SaveableItem item, float heightDropMultiplier)
{
if (item == null)
yield return null;
bool nearWall = false;
Vector3 dropPosition;
Quaternion dropRotation;
if (Physics.Raycast(transform.position, transform.InverseTransformDirection(Vector3.forward), m_DropOffset.z, m_WallsLayer))
{
dropPosition = transform.position + transform.TransformVector(new Vector3(0f, m_DropOffset.y * heightDropMultiplier, -0.2f));
dropRotation = Quaternion.LookRotation(Entity.LookDirection.Get());
nearWall = true;
}
else
{
dropPosition = transform.position + transform.TransformVector(new Vector3(m_DropOffset.x, m_DropOffset.y * heightDropMultiplier, m_DropOffset.z));
dropRotation = Random.rotationUniform;
}
GameObject droppedItem = Instantiate(item.Data.WorldObject, dropPosition, dropRotation) as GameObject;
var rigidbody = droppedItem.GetComponent<Rigidbody>();
var collider = droppedItem.GetComponent<Collider>();
if (rigidbody != null)
{
Physics.IgnoreCollision(GetComponent<Collider>(), collider);
rigidbody.isKinematic = false;
if (rigidbody != null && !nearWall)
{
rigidbody.AddTorque(Random.rotation.eulerAngles * m_DropAngularFactor);
rigidbody.AddForce(Entity.LookDirection.Get() * m_DropSpeed, ForceMode.VelocityChange);
}
}
m_DropSounds.Play2D(ItemSelection.Method.RandomExcludeLast);
var pickup = droppedItem.GetComponent<ItemPickup>();
if (pickup != null)
pickup.SetItem(item);
}
private void Awake()
{
if(ItemDatabase.Default == null)
{
Debug.LogError("No ItemDatabase found, this storage component will be disabled!", this);
enabled = false;
return;
}
Entity.Death.AddListener(OnEntityDeath);
InitiateContainers();
}
private void InitiateContainers()
{
m_SavableContainers = new List<ItemContainer>();
for (int i = 0; i < m_InitialContainers.Length; i++)
{
var container = m_InitialContainers[i].GenerateContainer(transform);
m_SavableContainers.Add(container);
AddListeners(container, true);
}
m_AllContainers = new List<ItemContainer>(m_SavableContainers);
}
private void AddListeners(ItemContainer container, bool add)
{
if (add)
container.Changed.AddListener(OnContainerChanged);
else
container.Changed.RemoveListener(OnContainerChanged);
}
private void OnContainerChanged(ItemSlot slot)
{
try
{
ContainerChanged.Send();
}
catch {
};
}
private void OnEntityDeath()
{
if(m_DropItemsOnDeath)
{
for(int i = 0; i < m_AllContainers.Count; i ++)
{
for(int j = 0; j < m_AllContainers[i].Slots.Length; j ++)
{
var slot = m_AllContainers[i].Slots[j];
if(slot.Item)
{
TryDropItem(slot.Item);
slot.SetItem(null);
}
}
}
}
}
}
public class NestedContainer
{
public ItemContainer Container;
public ItemSlot Slot;
}
}