using Invector.vCharacterController.AI.FSMBehaviour;
using UnityEngine;
namespace DemonBoss.Magic
{
///
/// Decision node checking cooldown for different boss abilities
/// Stores Time.time in FSM timers and checks if required cooldown time has passed
///
[CreateAssetMenu(menuName = "Invector/FSM/Decisions/DemonBoss/Check Cooldown")]
public class DEC_CheckCooldown : vStateDecision
{
public override string categoryName => "DemonBoss/Magic";
public override string defaultName => "Check Cooldown";
[Header("Cooldown Configuration")]
[Tooltip("Unique key for this ability (e.g. 'Shield', 'Turret', 'Meteor')")]
public string cooldownKey = "Shield";
[Tooltip("Cooldown time in seconds")]
public float cooldownTime = 10f;
[Tooltip("Whether ability should be available immediately at fight start")]
public bool availableAtStart = true;
[Header("Debug")]
[Tooltip("Enable debug logging")]
public bool enableDebug = false;
///
/// Main method checking if ability is available
///
/// True if cooldown has passed and ability can be used
public override bool Decide(vIFSMBehaviourController fsmBehaviour)
{
if (fsmBehaviour == null)
{
if (enableDebug) Debug.LogWarning($"[DEC_CheckCooldown] No FSM Behaviour for key: {cooldownKey}");
return false;
}
string timerKey = "cooldown_" + cooldownKey;
if (!fsmBehaviour.HasTimer(timerKey))
{
if (availableAtStart)
{
if (enableDebug) Debug.Log($"[DEC_CheckCooldown] First use for {cooldownKey} - available");
return true;
}
else
{
SetCooldown(fsmBehaviour, cooldownTime);
if (enableDebug) Debug.Log($"[DEC_CheckCooldown] First use for {cooldownKey} - setting cooldown");
return false;
}
}
float lastUsedTime = fsmBehaviour.GetTimer(timerKey);
float timeSinceLastUse = Time.time - lastUsedTime;
bool isAvailable = timeSinceLastUse >= cooldownTime;
if (enableDebug)
{
if (isAvailable)
{
Debug.Log($"[DEC_CheckCooldown] {cooldownKey} available - {timeSinceLastUse:F1}s passed of required {cooldownTime}s");
}
else
{
float remainingTime = cooldownTime - timeSinceLastUse;
Debug.Log($"[DEC_CheckCooldown] {cooldownKey} on cooldown - {remainingTime:F1}s remaining");
}
}
return isAvailable;
}
///
/// Sets cooldown for ability - call this after using ability
///
public void SetCooldown(vIFSMBehaviourController fsmBehaviour)
{
SetCooldown(fsmBehaviour, cooldownTime);
}
///
/// Sets cooldown with custom time
///
/// FSM behaviour reference
/// Custom cooldown time
public void SetCooldown(vIFSMBehaviourController fsmBehaviour, float customCooldownTime)
{
if (fsmBehaviour == null)
{
if (enableDebug) Debug.LogWarning($"[DEC_CheckCooldown] Cannot set cooldown - no FSM Behaviour");
return;
}
string timerKey = "cooldown_" + cooldownKey;
fsmBehaviour.SetTimer(timerKey, Time.time);
if (enableDebug)
{
Debug.Log($"[DEC_CheckCooldown] Set cooldown for {cooldownKey}: {customCooldownTime}s");
}
}
///
/// Resets cooldown - ability becomes immediately available
///
public void ResetCooldown(vIFSMBehaviourController fsmBehaviour)
{
if (fsmBehaviour == null)
{
if (enableDebug) Debug.LogWarning($"[DEC_CheckCooldown] Cannot reset cooldown - no FSM Behaviour");
return;
}
string timerKey = "cooldown_" + cooldownKey;
float pastTime = Time.time - cooldownTime - 1f;
fsmBehaviour.SetTimer(timerKey, pastTime);
if (enableDebug) Debug.Log($"[DEC_CheckCooldown] Reset cooldown for {cooldownKey}");
}
///
/// Returns remaining cooldown time in seconds
///
/// Remaining cooldown time (0 if available)
public float GetRemainingCooldown(vIFSMBehaviourController fsmBehaviour)
{
if (fsmBehaviour == null) return 0f;
string timerKey = "cooldown_" + cooldownKey;
if (!fsmBehaviour.HasTimer(timerKey))
{
return availableAtStart ? 0f : cooldownTime;
}
float lastUsedTime = fsmBehaviour.GetTimer(timerKey);
float timeSinceLastUse = Time.time - lastUsedTime;
return Mathf.Max(0f, cooldownTime - timeSinceLastUse);
}
///
/// Checks if ability is available without running main Decision logic
///
/// True if ability is available
public bool IsAvailable(vIFSMBehaviourController fsmBehaviour)
{
return GetRemainingCooldown(fsmBehaviour) <= 0f;
}
///
/// Returns cooldown progress percentage (0-1)
///
/// Progress percentage: 0 = just used, 1 = fully recharged
public float GetCooldownProgress(vIFSMBehaviourController fsmBehaviour)
{
if (cooldownTime <= 0f) return 1f;
float remainingTime = GetRemainingCooldown(fsmBehaviour);
return 1f - (remainingTime / cooldownTime);
}
///
/// Helper method for setting cooldown from external code (e.g. from StateAction)
///
/// FSM reference
/// Ability key
/// Cooldown time
public static void SetCooldownStatic(vIFSMBehaviourController fsmBehaviour, string key, float cooldown)
{
if (fsmBehaviour == null) return;
string timerKey = "cooldown_" + key;
fsmBehaviour.SetTimer(timerKey, Time.time);
}
///
/// Helper method for checking cooldown from external code
///
/// FSM reference
/// Ability key
/// Cooldown time
/// True if available
public static bool CheckCooldownStatic(vIFSMBehaviourController fsmBehaviour, string key, float cooldown)
{
if (fsmBehaviour == null) return false;
string timerKey = "cooldown_" + key;
if (!fsmBehaviour.HasTimer(timerKey)) return true;
float lastUsedTime = fsmBehaviour.GetTimer(timerKey);
return (Time.time - lastUsedTime) >= cooldown;
}
}
}