using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using Godot; using Godot.Collections; namespace KarrotStarterTemplate.Common.StateMachines; public abstract partial class State : Node { [Export] public string id { get; private set; } // [Export] public bool queueable { get; private set; } [Export] public bool canTransitionToSelf { get; private set; } [Export] public float minimumStateDuration { get; private set; } public bool checkRelevance { get; protected set; } = true; public bool queueRelevance { get; protected set; } = true; protected List statesInQueue = new(); private double _startTime; protected float timeElapsed => (float)(Time.GetUnixTimeFromSystem() - _startTime); protected StateMachine parentStateMachine; public StateInputsPackage package => parentStateMachine.package; public bool isActive => parentStateMachine?.currentState == this; public bool isTransitioning => parentStateMachine?.currentState == this && parentStateMachine.isTransitioning; // Called when the node enters the scene tree for the first time. public override void _Ready() { parentStateMachine = GetParent(); } protected abstract Task OnEnter(); protected abstract Task OnExit(); protected virtual void OnStateProcess(double delta) {} protected virtual void OnStatePhysicsProcess(double delta) {} protected virtual string OnCheckRelevance() { return null; } public async Task Enter() { _startTime = Time.GetUnixTimeFromSystem(); await OnEnter(); } public async Task Exit() { statesInQueue.Clear(); await OnExit(); } public void StateProcess(double delta) { OnStateProcess(delta); } public void StatePhysicsProcess(double delta) { OnStatePhysicsProcess(delta); } public string CheckRelevance() { string value = OnCheckRelevance(); if (timeElapsed <= (minimumStateDuration <= 0 ? 0.01f : minimumStateDuration) || !checkRelevance) { // if (queueRelevance && value != null && parentStateMachine.states[value].queueable) // { // statesInQueue.Add(value); // } return null; } // if (statesInQueue.Count > 0) return statesInQueue.Last(); return value; } }