using UnityEngine;
using System.Collections;
namespace HQFPSWeapons
{
///
///
///
public class ItemPickup : InteractiveObject
{
///
public SaveableItem ItemInstance { get { return m_ItemInstance; } }
public float InterractionProgress = 0f;
public bool NeedToSwap { get; set; }
public float SwapTime => m_SwapTime;
public ItemContainerFlags TargetContainers => m_TargetContainers;
[Space]
[BHeader("Pick Up Method", order = 100)]
[SerializeField]
private PickUpMethod m_PickUpMethod = PickUpMethod.InteractionBased;
[SerializeField]
[ShowIf("m_PickUpMethod", (int)PickUpMethod.TriggerBased)]
[Tooltip("The radius of the auto-created trigger.")]
private float m_TriggerRadius = 0.5f;
[SerializeField]
[ShowIf("m_PickUpMethod", (int)PickUpMethod.InteractionBased)]
private float m_SwapTime = 0f;
[BHeader("Item", order = 100)]
[SerializeField]
[DatabaseItem]
private string m_Item = string.Empty;
[SerializeField]
private int m_ItemCount = 1;
[SerializeField]
[Tooltip("In what container of the Player will the picked up item go")]
private ItemContainerFlags m_TargetContainers = ItemContainerFlags.AmmoPouch;
[SerializeField]
private SoundPlayer m_CollideSounds = null;
[SerializeField]
private SoundPlayer m_PickupSounds = null;
[SerializeField]
private float m_PlayCollideSoundThresshold = 1f;
[SerializeField]
private LayerMask m_LayerMask = new LayerMask();
[BHeader("Pick Up Message", order = 100)]
[SerializeField]
private Color m_BaseMessageColor = new Color(1f, 1f, 1f, 0.678f);
[SerializeField]
private Color m_ItemCountColor = new Color(0.976f, 0.6f, 0.129f, 1f);
[SerializeField]
private Color m_InventoryFullColor = Color.red;
private SaveableItem m_ItemInstance;
private string m_InitialInteractionText;
private Rigidbody m_RigidB;
private float m_NextTimePlayCollideSound;
public void OnLoad()
{
SetInteractionText(m_ItemInstance);
}
public override void OnInteractionStart(Player player)
{
base.OnInteractionStart(player);
if(NeedToSwap)
InterractionProgress = 0;
else
OnPickUp(player);
}
public override void OnInteractionUpdate(Player player)
{
if (NeedToSwap)
{
InterractionProgress += Time.deltaTime;
if (InterractionProgress > m_SwapTime)
OnPickUp(player);
}
}
public override void OnInteractionEnd(Player player)
{
base.OnInteractionEnd(player);
InterractionProgress = 0;
}
public void EnablePickup(bool enable)
{
InteractionEnabled = enable;
}
public void SetItem(SaveableItem item)
{
m_ItemInstance = item;
if(m_ItemInstance != null)
{
m_Item = m_ItemInstance.Name;
SetInteractionText(m_ItemInstance);
}
}
private void OnCollisionEnter(Collision collision)
{
if (m_RigidB != null && m_LayerMask == (m_LayerMask | (1 << collision.collider.gameObject.layer)) && !collision.collider.isTrigger && Time.time > m_NextTimePlayCollideSound)
{
float collideVolume = Mathf.Clamp(collision.relativeVelocity.sqrMagnitude / 5f, 0.1f, 0.3f);
if (m_RigidB.velocity.sqrMagnitude > m_PlayCollideSoundThresshold)
m_CollideSounds.PlayAtPosition(ItemSelection.Method.Random, transform.position, collideVolume);
m_NextTimePlayCollideSound = Time.time + 0.5f;
}
}
private void Awake()
{
m_InitialInteractionText = m_InteractionText;
if(m_PickUpMethod != PickUpMethod.InteractionBased)
InteractionEnabled = false;
ItemData itemData;
if(ItemDatabase.Default.TryGetItem(m_Item, out itemData))
m_ItemInstance = new SaveableItem(itemData, m_ItemCount);
// Create a trigger if the pickup method is set to WalkOver
if(m_PickUpMethod == PickUpMethod.TriggerBased)
{
var sphereCol = gameObject.AddComponent();
sphereCol.isTrigger = true;
sphereCol.radius = m_TriggerRadius;
}
SetInteractionText(m_ItemInstance);
if (GetComponent() != null)
m_RigidB = GetComponent();
m_NextTimePlayCollideSound = Time.time + 0.025f;
}
private void SetInteractionText(SaveableItem item)
{
if(item.CurrentStackSize < 2)
m_InteractionText = string.Format(m_InitialInteractionText, item.Name.ToUpper());
else
m_InteractionText = string.Format(m_InitialInteractionText + " x " + item.CurrentStackSize, item.Name.ToUpper());
}
private void OnTriggerEnter(Collider col)
{
if(m_PickUpMethod != PickUpMethod.TriggerBased)
return;
var player = col.GetComponent();
if(player != null)
OnPickUp(player);
}
private void OnDrawGizmosSelected()
{
if(m_PickUpMethod == PickUpMethod.TriggerBased)
{
var prevColor = Gizmos.color;
Gizmos.color = new Color(0.2f, 1f, 0.3f, 0.2f);
Gizmos.DrawSphere(transform.position, m_TriggerRadius);
Gizmos.color = prevColor;
}
}
private void OnValidate()
{
m_TriggerRadius = Mathf.Clamp(m_TriggerRadius, 0f, 2f);
}
private void OnPickUp(Player player)
{
if(m_ItemInstance != null)
{
bool destroy = false;
bool swappedItems = false;
if (player.Inventory.GetContainerWithFlags(m_TargetContainers).ContainerIsFull())
{
if (player.EquippedItem.Get() != null && player.SwapItems.Try(ItemInstance))
swappedItems = true;
}
if(!swappedItems)
{
bool addedItem = player.Inventory.AddItem(m_ItemInstance, m_TargetContainers);
// Item added to inventory
if (addedItem)
{
if (m_ItemInstance.Data.StackSize > 1)
MessageDisplayer.Instance.PushMessage(string.Format("Picked up {1} x {2}", ColorUtils.ColorToHex(m_ItemCountColor), m_ItemInstance.Name, m_ItemInstance.CurrentStackSize), m_BaseMessageColor);
else
MessageDisplayer.Instance.PushMessage(string.Format("Picked up {1}", ColorUtils.ColorToHex(m_ItemCountColor), m_ItemInstance.Name), m_BaseMessageColor);
destroy = true;
//Play pickup sound
m_PickupSounds.Play2D(ItemSelection.Method.RandomExcludeLast);
}
// Item not added to inventory
else
{
MessageDisplayer.Instance.PushMessage(string.Format("Inventory Full", ColorUtils.ColorToHex(m_InventoryFullColor)), m_BaseMessageColor);
}
}
// Item swapped
else
{
destroy = true;
}
if(destroy)
Destroy(gameObject);
}
else
{
Debug.LogError("Item Instance is null, can't pick up anything.");
return;
}
}
public IEnumerator C_DelayedDestroy(float lifeTime)
{
yield return new WaitForSeconds(lifeTime);
Destroy(gameObject);
}
// ------------------- Internal ------------------
public enum PickUpMethod
{
TriggerBased,
InteractionBased
}
}
}