using System.Collections.Generic; using UnityEngine; using EmeraldAI.Utility; namespace EmeraldAI { [HelpURL("https://black-horizon-studios.gitbook.io/emerald-ai-wiki/emerald-components-optional/items-component")] public class EmeraldItems : MonoBehaviour { #region Items Variables public YesOrNo UseDroppableWeapon = YesOrNo.No; [SerializeField] public List Type1EquippableWeapons = new List(); [SerializeField] public List Type2EquippableWeapons = new List(); [System.Serializable] public class EquippableWeapons { public bool HeldToggle; public GameObject HeldObject; public bool HolsteredToggle; public GameObject HolsteredObject; public bool DroppableToggle; public GameObject DroppableObject; } public delegate void OnEquipWeaponHandler(string WeaponType); public event OnEquipWeaponHandler OnEquipWeapon; public delegate void OnUnequipWeaponHandler(string WeaponType); public event OnUnequipWeaponHandler OnUnequipWeapon; [System.Serializable] public class ItemClass { public int ItemID = 1; public GameObject ItemObject; } [SerializeField] public List ItemList = new List(); #endregion #region Editor Variables public bool HideSettingsFoldout; public bool WeaponsFoldout; public bool ItemsFoldout; #endregion void Start() { InitializeDroppableWeapon(); } /// /// Intializes the AI's droppable weapon to be used when the AI dies. /// public void InitializeDroppableWeapon() { GetComponent().OnDeath += CreateDroppableWeapon; //Subscribe to the OnDeath event for when dropping an AI's weapon on death, given that it's enabled. } /// /// Instantiates an AI's Droppable Weapon Object on death. /// public void CreateDroppableWeapon() { EmeraldSystem EmeraldComponent = GetComponent(); if (EmeraldComponent.CombatComponent.CurrentWeaponType == EmeraldCombat.WeaponTypes.Type1) { for (int i = 0; i < Type1EquippableWeapons.Count; i++) { if (Type1EquippableWeapons[i].DroppableObject != null && Type1EquippableWeapons[i].DroppableToggle) { if (Type1EquippableWeapons[i].HeldObject != null) { //Instantiate a copy of the DroppableObject and position it to HeldObject var DroppableMeleeWeapon = EmeraldObjectPool.Spawn(Type1EquippableWeapons[i].DroppableObject, Type1EquippableWeapons[i].HeldObject.transform.position, Type1EquippableWeapons[i].HeldObject.transform.rotation); DroppableMeleeWeapon.transform.localScale = Type1EquippableWeapons[i].HeldObject.transform.lossyScale; DroppableMeleeWeapon.transform.SetParent(Type1EquippableWeapons[i].HeldObject.transform.parent); DroppableMeleeWeapon.transform.localPosition = Type1EquippableWeapons[i].HeldObject.transform.localPosition; DroppableMeleeWeapon.gameObject.name = Type1EquippableWeapons[i].HeldObject.gameObject.name + " (Droppable Copy)"; DroppableMeleeWeapon.transform.SetParent(EmeraldSystem.ObjectPool.transform); //Check for a collider on the WeaponObject, if there isn't one, add one. if (DroppableMeleeWeapon.GetComponent() == null) DroppableMeleeWeapon.AddComponent(); if (DroppableMeleeWeapon.GetComponent() == null) DroppableMeleeWeapon.AddComponent(); //Apply the AI's current velocity to the weapon object. Rigidbody WeaponRigidbody = DroppableMeleeWeapon.GetComponent(); WeaponRigidbody.interpolation = RigidbodyInterpolation.Interpolate; //Used to provide the force to the AI's weapon in the opposite direction of the last target to hit the AI. Transform LastAttacker = EmeraldComponent.CombatComponent.LastAttacker; if (EmeraldComponent.CombatTarget != null) { if (LastAttacker != null && LastAttacker != EmeraldComponent.CombatTarget) WeaponRigidbody.AddForce((LastAttacker.position - transform.position).normalized * EmeraldComponent.CombatComponent.ReceivedRagdollForceAmount * 0.01f, ForceMode.Impulse); else WeaponRigidbody.AddForce((EmeraldComponent.CombatTarget.position - transform.position).normalized * EmeraldComponent.CombatComponent.ReceivedRagdollForceAmount * 0.01f, ForceMode.Impulse); } //Disable the held object Type1EquippableWeapons[i].HeldObject.SetActive(false); } else { Debug.LogError("The AI '" + gameObject.name + "' does not have a held object for the '" + Type1EquippableWeapons[i].DroppableObject.name + "' Droppable Object (Type 1) with the Items Component, please assign one."); } } } for (int i = 0; i < Type2EquippableWeapons.Count; i++) { if (Type2EquippableWeapons[i].DroppableObject != null && Type2EquippableWeapons[i].DroppableToggle) { if (Type2EquippableWeapons[i].HeldObject != null) { //Instantiate a copy of the DroppableObject and position it to HeldObject var DroppableMeleeWeapon = EmeraldObjectPool.Spawn(Type2EquippableWeapons[i].DroppableObject, Type2EquippableWeapons[i].HeldObject.transform.position, Type2EquippableWeapons[i].HeldObject.transform.rotation); DroppableMeleeWeapon.transform.localScale = Type2EquippableWeapons[i].HeldObject.transform.lossyScale; DroppableMeleeWeapon.transform.SetParent(Type2EquippableWeapons[i].HeldObject.transform.parent); DroppableMeleeWeapon.transform.localPosition = Type2EquippableWeapons[i].HeldObject.transform.localPosition; DroppableMeleeWeapon.gameObject.name = Type2EquippableWeapons[i].HeldObject.gameObject.name + " (Droppable Copy)"; DroppableMeleeWeapon.transform.SetParent(EmeraldSystem.ObjectPool.transform); //Check for a collider on the WeaponObject, if there isn't one, add one. if (DroppableMeleeWeapon.GetComponent() == null) DroppableMeleeWeapon.AddComponent(); if (DroppableMeleeWeapon.GetComponent() == null) DroppableMeleeWeapon.AddComponent(); //Apply the AI's current velocity to the weapon object. Rigidbody WeaponRigidbody = DroppableMeleeWeapon.GetComponent(); WeaponRigidbody.interpolation = RigidbodyInterpolation.Interpolate; //Used to provide the force to the AI's weapon in the opposite direction of the last target to hit the AI. Transform LastAttacker = EmeraldComponent.CombatComponent.LastAttacker; if (EmeraldComponent.CombatTarget != null) { if (LastAttacker != null && LastAttacker != EmeraldComponent.CombatTarget) WeaponRigidbody.AddForce((LastAttacker.position - transform.position).normalized * -EmeraldComponent.CombatComponent.ReceivedRagdollForceAmount, ForceMode.Impulse); else WeaponRigidbody.AddForce((EmeraldComponent.CombatTarget.position - transform.position).normalized * -EmeraldComponent.CombatComponent.ReceivedRagdollForceAmount, ForceMode.Impulse); } //Disable the held object Type2EquippableWeapons[i].HeldObject.SetActive(false); } else { Debug.LogError("The AI '" + gameObject.name + "' does not have a held object for the '" + Type2EquippableWeapons[i].DroppableObject.name + "' Droppable Object (Type 2) with the Items Component, please assign one."); } } } } } /// /// Enables the AI's weapon object and plays the AI's equip sound effect, if one is applied. /// public void EquipWeapon(string WeaponTypeToEnable) { EmeraldSystem EmeraldComponent = GetComponent(); if (WeaponTypeToEnable == "Weapon Type 1") { for (int i = 0; i < Type1EquippableWeapons.Count; i++) { if (!Type1EquippableWeapons[i].HolsteredToggle) return; if (Type1EquippableWeapons[i].HeldObject != null) Type1EquippableWeapons[i].HeldObject.SetActive(true); //Enable the held weapon if (Type1EquippableWeapons[i].HolsteredObject != null) Type1EquippableWeapons[i].HolsteredObject.SetActive(false); //Disable the holstered weapon } OnEquipWeapon?.Invoke(WeaponTypeToEnable); //Invoke the OnEquipWeapon event. } else if (WeaponTypeToEnable == "Weapon Type 2") { for (int i = 0; i < Type2EquippableWeapons.Count; i++) { if (!Type2EquippableWeapons[i].HolsteredToggle) return; if (Type2EquippableWeapons[i].HeldObject != null) Type2EquippableWeapons[i].HeldObject.SetActive(true); //Enable the held weapon if (Type2EquippableWeapons[i].HolsteredObject != null) Type2EquippableWeapons[i].HolsteredObject.SetActive(false); //Disable the holstered weapon } OnEquipWeapon?.Invoke(WeaponTypeToEnable); //Invoke the OnEquipWeapon event. } else { Debug.Log("This string withing the EquipWeapon Animation Event is blank or incorrect. Ensure that it's either Weapon Type 1 or Weapon Type 2."); } } /// /// Disables the AI's weapon object and plays the AI's unequip sound effect, if one is applied. /// public void UnequipWeapon(string WeaponTypeToDisable) { EmeraldSystem EmeraldComponent = GetComponent(); if (WeaponTypeToDisable == "Weapon Type 1") { for (int i = 0; i < Type1EquippableWeapons.Count; i++) { if (!Type1EquippableWeapons[i].HolsteredToggle) return; if (Type1EquippableWeapons[i].HeldObject != null) Type1EquippableWeapons[i].HeldObject.SetActive(false); //Disable the held weapon if (Type1EquippableWeapons[i].HolsteredObject != null) Type1EquippableWeapons[i].HolsteredObject.SetActive(true); //Enable the holstered weapon } OnUnequipWeapon?.Invoke(WeaponTypeToDisable); //Invoke the OnUnequipWeapon event. } else if (WeaponTypeToDisable == "Weapon Type 2") { for (int i = 0; i < Type2EquippableWeapons.Count; i++) { if (!Type2EquippableWeapons[i].HolsteredToggle) return; if (Type2EquippableWeapons[i].HeldObject != null) Type2EquippableWeapons[i].HeldObject.SetActive(false); //Disable the held weapon if (Type2EquippableWeapons[i].HolsteredObject != null) Type2EquippableWeapons[i].HolsteredObject.SetActive(true); //Enable the holstered weapon } OnUnequipWeapon?.Invoke(WeaponTypeToDisable); //Invoke the OnUnequipWeapon event. } else { Debug.Log("This string withing the UnequipWeapon Animation Event is blank or incorrect. Ensure that it's either Type 2 or Type 1."); } } /// /// Enables an item from your AI's Item list using the Item ID. /// public void EnableItem(int ItemID) { //Look through each item in the ItemList for the appropriate ID. //Once found, enable the item of the same index as the found ID. for (int i = 0; i < ItemList.Count; i++) { if (ItemList[i].ItemID == ItemID) { if (ItemList[i].ItemObject != null) { ItemList[i].ItemObject.SetActive(true); } } } } /// /// Disables an item from your AI's Item list using the Item ID. /// public void DisableItem(int ItemID) { //Look through each item in the ItemList for the appropriate ID. //Once found, enable the item of the same index as the found ID. for (int i = 0; i < ItemList.Count; i++) { if (ItemList[i].ItemID == ItemID) { if (ItemList[i].ItemObject != null) { ItemList[i].ItemObject.SetActive(false); } } } } /// /// Disables all items from your AI's Item list. /// public void DisableAllItems() { //Disable all of an AI's items for (int i = 0; i < ItemList.Count; i++) { if (ItemList[i].ItemObject != null) { ItemList[i].ItemObject.SetActive(false); } } } /// /// Reset any equipped items to their defaults. /// public void ResetSettings() { EmeraldSystem EmeraldComponent = GetComponent(); if (EmeraldComponent.CombatComponent.CurrentWeaponType == EmeraldCombat.WeaponTypes.Type1) { for (int i = 0; i < Type1EquippableWeapons.Count; i++) { if (EmeraldComponent.AnimationComponent.m_AnimationProfile.Type1Animations.PullOutWeapon.AnimationClip != null && EmeraldComponent.AnimationComponent.m_AnimationProfile.Type1Animations.PutAwayWeapon.AnimationClip != null) { if (Type1EquippableWeapons[i].HeldObject != null && Type1EquippableWeapons[i].HolsteredObject != null) { Type1EquippableWeapons[i].HeldObject.SetActive(false); //Disable the held weapon Type1EquippableWeapons[i].HolsteredObject.SetActive(true); //Enable the holstered weapon } else { if (Type1EquippableWeapons[i].HeldObject) Type1EquippableWeapons[i].HeldObject.SetActive(true); //Enable the held weapon } } else { if (Type1EquippableWeapons[i].HeldObject) Type1EquippableWeapons[i].HeldObject.SetActive(true); //Enable the held weapon } } } else if (EmeraldComponent.CombatComponent.CurrentWeaponType == EmeraldCombat.WeaponTypes.Type2) { for (int i = 0; i < Type2EquippableWeapons.Count; i++) { if (EmeraldComponent.AnimationComponent.m_AnimationProfile.Type2Animations.PullOutWeapon.AnimationClip != null && EmeraldComponent.AnimationComponent.m_AnimationProfile.Type2Animations.PutAwayWeapon.AnimationClip != null) { if (Type2EquippableWeapons[i].HeldObject != null && Type2EquippableWeapons[i].HolsteredObject != null) { Type2EquippableWeapons[i].HeldObject.SetActive(false); //Disable the held weapon Type2EquippableWeapons[i].HolsteredObject.SetActive(true); //Enable the holstered weapon } else { if (Type2EquippableWeapons[i].HeldObject) Type2EquippableWeapons[i].HeldObject.SetActive(true); //Enable the held weapon } } else { if (Type2EquippableWeapons[i].HeldObject) Type2EquippableWeapons[i].HeldObject.SetActive(true); //Enable the held weapon } } } } public void EnableWeaponCollider(string Name) { EmeraldSystem EmeraldComponent = GetComponent(); if (EmeraldComponent.CombatComponent.CurrentWeaponType == EmeraldCombat.WeaponTypes.Type1) { for (int i = 0; i < Type1EquippableWeapons.Count; i++) { if (Type1EquippableWeapons[i].HeldObject.GetComponent() != null) { Type1EquippableWeapons[i].HeldObject.GetComponent().EnableWeaponCollider(Name); } } } else if (EmeraldComponent.CombatComponent.CurrentWeaponType == EmeraldCombat.WeaponTypes.Type2) { for (int i = 0; i < Type2EquippableWeapons.Count; i++) { if (Type2EquippableWeapons[i].HeldObject.GetComponent() != null) { Type2EquippableWeapons[i].HeldObject.GetComponent().EnableWeaponCollider(Name); } } } } public void DisableWeaponCollider(string Name) { EmeraldSystem EmeraldComponent = GetComponent(); if (EmeraldComponent.CombatComponent.CurrentWeaponType == EmeraldCombat.WeaponTypes.Type1) { for (int i = 0; i < Type1EquippableWeapons.Count; i++) { if (Type1EquippableWeapons[i].HeldObject.GetComponent() != null) { Type1EquippableWeapons[i].HeldObject.GetComponent().DisableWeaponCollider(Name); } } } else if (EmeraldComponent.CombatComponent.CurrentWeaponType == EmeraldCombat.WeaponTypes.Type2) { for (int i = 0; i < Type2EquippableWeapons.Count; i++) { if (Type2EquippableWeapons[i].HeldObject.GetComponent() != null) { Type2EquippableWeapons[i].HeldObject.GetComponent().DisableWeaponCollider(Name); } } } } } }