205 lines
6.1 KiB
C#
205 lines
6.1 KiB
C#
using Invector.vCharacterController.AI.FSMBehaviour;
|
|
using UnityEngine;
|
|
|
|
namespace DemonBoss.Magic
|
|
{
|
|
/// <summary>
|
|
/// Decision node checking cooldown for different boss abilities
|
|
/// Stores Time.time in FSM timers and checks if required cooldown time has passed
|
|
/// </summary>
|
|
[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;
|
|
|
|
/// <summary>
|
|
/// Main method checking if ability is available
|
|
/// </summary>
|
|
/// <returns>True if cooldown has passed and ability can be used</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets cooldown for ability - call this after using ability
|
|
/// </summary>
|
|
public void SetCooldown(vIFSMBehaviourController fsmBehaviour)
|
|
{
|
|
SetCooldown(fsmBehaviour, cooldownTime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets cooldown with custom time
|
|
/// </summary>
|
|
/// <param name="fsmBehaviour">FSM behaviour reference</param>
|
|
/// <param name="customCooldownTime">Custom cooldown time</param>
|
|
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");
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Resets cooldown - ability becomes immediately available
|
|
/// </summary>
|
|
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}");
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns remaining cooldown time in seconds
|
|
/// </summary>
|
|
/// <returns>Remaining cooldown time (0 if available)</returns>
|
|
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);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Checks if ability is available without running main Decision logic
|
|
/// </summary>
|
|
/// <returns>True if ability is available</returns>
|
|
public bool IsAvailable(vIFSMBehaviourController fsmBehaviour)
|
|
{
|
|
return GetRemainingCooldown(fsmBehaviour) <= 0f;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns cooldown progress percentage (0-1)
|
|
/// </summary>
|
|
/// <returns>Progress percentage: 0 = just used, 1 = fully recharged</returns>
|
|
public float GetCooldownProgress(vIFSMBehaviourController fsmBehaviour)
|
|
{
|
|
if (cooldownTime <= 0f) return 1f;
|
|
|
|
float remainingTime = GetRemainingCooldown(fsmBehaviour);
|
|
return 1f - (remainingTime / cooldownTime);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper method for setting cooldown from external code (e.g. from StateAction)
|
|
/// </summary>
|
|
/// <param name="fsmBehaviour">FSM reference</param>
|
|
/// <param name="key">Ability key</param>
|
|
/// <param name="cooldown">Cooldown time</param>
|
|
public static void SetCooldownStatic(vIFSMBehaviourController fsmBehaviour, string key, float cooldown)
|
|
{
|
|
if (fsmBehaviour == null) return;
|
|
|
|
string timerKey = "cooldown_" + key;
|
|
fsmBehaviour.SetTimer(timerKey, Time.time);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Helper method for checking cooldown from external code
|
|
/// </summary>
|
|
/// <param name="fsmBehaviour">FSM reference</param>
|
|
/// <param name="key">Ability key</param>
|
|
/// <param name="cooldown">Cooldown time</param>
|
|
/// <returns>True if available</returns>
|
|
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;
|
|
}
|
|
}
|
|
} |