2026-06-13 19:48:59 +01:00

96 lines
3.2 KiB
C#

using System;
using Intrepid.Core.TimeControl;
using Intrepid.Diagnostics;
using Intrepid.Utilities;
using UnityEngine;
namespace Intrepid.Gameplay.Entities.Player.Sentinel.Cadence
{
[Serializable]
[CreateAssetMenu(fileName = "Cadence Service", menuName = "GON/Services/Cadence/Cadence Service")]
public class CadenceService : SingletonScriptableObject<CadenceService>
{
private Timer CadenceProfileTimer { get; set; } = new();
private Timer CadenceTotalTimer { get; set; } = new();
private CadenceProfile CurrentProfile { get; set; }
private float TargetTime { get; set; }
private float StartedProfileAt { get; set; }
public bool IsCadenceRunning => CadenceProfileTimer.IsRunning;
private float CadenceProfileElapsedTime => (float)CadenceProfileTimer.ElapsedTime; // elapsed time since a single cadence began
public float TotalCadenceElapsedTime => (float)CadenceTotalTimer.ElapsedTime; // elapsed time since first cadence began
protected override void WhenInstantiate(CadenceService s)
{
base.WhenInstantiate(s);
ResetCadenceProfile();
CadenceTotalTimer.Stop();
}
public void BeginCadence(CadenceProfile profile, float targetTime)
{
if (profile is null || targetTime <= 0)
{
DLogger.LogError($"profile should not be null: (is null? {profile.IsNull()}); targetTime should be > 0: {targetTime}");
ResetCadenceProfile();
return;
}
StartedProfileAt = TimeSimulation.Instance.ScaledElapsedTime;
CurrentProfile = profile;
TargetTime = targetTime;
CadenceProfileTimer.Start();
if (CadenceTotalTimer.IsNotRunning) CadenceTotalTimer.Start();
}
public CadenceEvaluation EndCadence()
{
CadenceTotalTimer.Stop();
if (!IsCadenceRunning || CurrentProfile is null) // if cadence was already ended
{
return CadenceEvaluation.None;
}
var cadenceEvaluation = CurrentProfile.LateEvaluation();
ResetCadenceProfile();
return cadenceEvaluation;
}
public CadenceEvaluation TryEndCadenceProfileWithInputAt(float inputAt)
{
if (!IsCadenceRunning || CurrentProfile is null)
{
return CadenceEvaluation.None;
}
var elapsedAtInput = Mathf.Max(0f, inputAt - StartedProfileAt);
var evaluation = CurrentProfile.Evaluate(elapsedAtInput / TargetTime);
ResetCadenceProfile();
return evaluation;
}
public bool UpdateCadence(float deltaTime)
{
if (!IsCadenceRunning || CurrentProfile is null)
{
return false;
}
CadenceProfileTimer.Update(deltaTime);
CadenceTotalTimer.Update(deltaTime);
return true;
}
public void ResetCadenceProfile()
{
CadenceProfileTimer.Stop();
CurrentProfile = null;
TargetTime = 0;
}
}
}