rokojori_action_library/Runtime/Behavior/Fight/FightManager.cs

104 lines
2.2 KiB
C#

using Godot;
using System.Collections.Generic;
using System.Linq;
using Rokojori.Extensions;
namespace Rokojori;
[Tool]
[GlobalClass]
public partial class FightManager:Node
{
[Export]
public int maxEngaged = 3;
[Export]
public int maxAttacking = 1;
List<FightSlot> _slots = new List<FightSlot>();
Dictionary<FightSlot,double> _lastAttackTime = new Dictionary<FightSlot,double>();
ulong _cachedFrame = ulong.MaxValue;
List<FightSlot> _cachedEngaged = new List<FightSlot>();
List<FightSlot> _cachedAttackers = new List<FightSlot>();
public static FightManager Get()
{
return Unique<FightManager>.Get();
}
public int registeredCount => _slots.Count;
public int engagedCount => EngagedSlots().Count;
public int attackingCount => AttackingSlots().Count;
public void Register( FightSlot slot )
{
if ( slot == null || _slots.Contains( slot ) )
{
return;
}
_slots.Add( slot );
}
public void Unregister( FightSlot slot )
{
_slots.Remove( slot );
_lastAttackTime.Remove( slot );
}
List<FightSlot> EngagedSlots()
{
RefreshFrameCache();
return _cachedEngaged;
}
List<FightSlot> AttackingSlots()
{
RefreshFrameCache();
return _cachedAttackers;
}
void RefreshFrameCache()
{
var frame = Engine.GetPhysicsFrames();
if ( frame == _cachedFrame )
{
return;
}
_cachedFrame = frame;
_cachedEngaged = _slots
.OrderByDescending( s => s.priority )
.Take( Mathf.Max( 0, maxEngaged ) )
.ToList();
var now = Time.GetTicksMsec() / 1000.0;
_cachedAttackers = _cachedEngaged
.OrderByDescending( s => s.priority )
.ThenBy( s => _lastAttackTime.TryGetValue( s, out var t ) ? t : -1 )
.Take( Mathf.Max( 0, maxAttacking ) )
.ToList();
_cachedAttackers.ForEach( s => _lastAttackTime[ s ] = now );
}
public bool IsEngaged( FightSlot slot )
{
return slot != null && EngagedSlots().Contains( slot );
}
public bool HasAttackPermission( FightSlot slot )
{
return slot != null && AttackingSlots().Contains( slot );
}
public bool IsAnyOtherAttacking( FightSlot self )
{
return AttackingSlots().Any( s => s != self );
}
}