using Kryz.CharacterStats.Examples; using Photon.Pun; using System.Collections; using System.Collections.Generic; using UnityEngine; public class AbilityKeyBinder : MonoBehaviour { [Header("Listeners:")] [SerializeField] private GameEventListener onLocalPlayerFainted; [SerializeField] private GameEventListener onLocalPlayerPermaDeath; [SerializeField] private GameEventListener onLocalPlayerRevived; [Space] [SerializeField] private BaseAbility ability; [SerializeField] private GameKey key; [SerializeField] private CastingStateController castingStateController; [SerializeField] private GameEvent_AbilityKeyBinder onAbilityKeyBinderSpawned; private PhotonView user; private Taggable userTag; private Mana mana; private Health health; public Health Health => health; public Mana Mana => mana; public BaseAbility Ability => ability; public GameKey GameKey => key; Coroutine currentChanneling; NetworkedChanneling networkedChanneling; AbilityBindInstance abilityBindInstance; AbilityCooldownTracker cooldownTracker; bool isDead = false; float finalHealthCost; float finalManaCost; private void Awake() { user = GetComponentInParent(); userTag = GetComponentInParent(); mana = GetComponentInParent(); health = GetComponentInParent(); cooldownTracker = user.GetComponentInChildren(); } private void Start() { if (!user.IsMine) { this.enabled = false; return; } onLocalPlayerFainted.Response.AddListener(() => { isDead = true; }); onLocalPlayerPermaDeath.Response.AddListener(() => { isDead = true; }); onLocalPlayerRevived.Response.AddListener(() => { isDead = false; }); onAbilityKeyBinderSpawned.Raise(this); } // Update is called once per frame void Update() { if (isDead) return; if (Input.GetKeyDown(key.keyCode)) { if (abilityBindInstance != null) abilityBindInstance.pressed.SetActive(true); if (IsAbilityOffCooldown() && mana.EnoughMana(ability.GetFinalManaCost(mana)) && health.EnoughHealth(ability.GetFinalHealthCost(health))) { if (ability is ChanneledAbility) { castingStateController.RequestAbilityChannel(ability, () => { networkedChanneling = ((ChanneledAbility)ability).ExecuteChannel(user, userTag, ref currentChanneling); if (ability.cooldown > 0) { cooldownTracker.StartAbilityCooldown(ability); abilityBindInstance.StartCooldownTrackerUI(); } }); } else { castingStateController.RequestAbilityCast(ability, () => { ability.Execute(user, userTag); if (ability.cooldown > 0) { cooldownTracker.StartAbilityCooldown(ability); abilityBindInstance.StartCooldownTrackerUI(); } }); } } } if (Input.GetKeyUp(key.keyCode)) { if (abilityBindInstance != null) abilityBindInstance.pressed.SetActive(false); if (currentChanneling != null) { if (networkedChanneling != null) { networkedChanneling.StopCoroutine(currentChanneling); } else { StopCoroutine(currentChanneling); } castingStateController.ResetChannelingCast(); CastBarHandler.Instance.CancelChannelingOnButtonReleased(); } if (networkedChanneling != null) { networkedChanneling.channeling = false; networkedChanneling.DisableVisuals(); } } } public void SetupAbilityBindInstance(AbilityBindInstance abilityBindInstance) { this.abilityBindInstance = abilityBindInstance; mana.onResourceChanged.AddListener(OnManaChanged); health.onResourceChanged.AddListener(OnHealthChanged); } public void OnManaChanged(float currentMana) { finalManaCost = ability.GetFinalManaCost(mana); abilityBindInstance.manaCost.text = finalManaCost.ToString("F0"); abilityBindInstance.noMana.SetActive(!mana.EnoughMana(finalManaCost)); } public void OnHealthChanged(float currentHealth) { finalHealthCost = ability.GetFinalHealthCost(health); abilityBindInstance.healthCost.text = finalHealthCost.ToString("F0"); abilityBindInstance.healthCostGO.SetActive(finalHealthCost > 0); abilityBindInstance.noHealth.SetActive(!health.EnoughHealth(finalHealthCost)); } public bool IsAbilityOffCooldown() { return ability.cooldown <= 0 || !cooldownTracker.OnCooldown(ability); } public void BindAbility(BaseAbility ability) { this.ability = ability; onAbilityKeyBinderSpawned.Raise(this); } }