Game/ControlSystem/ControlSystem.cs
public class ControlSystem : GameObjectSystem<ControlSystem>
{
// When each chair first became occupied. Used to sort seats so the earliest occupant is in charge
private readonly Dictionary<BaseChair, RealTimeSince> _occupiedSince = new();
public ControlSystem( Scene scene ) : base( scene )
{
Listen( Stage.StartFixedUpdate, 10, OnTick, "ControlSystem" );
}
void OnTick()
{
// TODO this should be more generic, some kind of interface?
var driven = new HashSet<GameObject>();
//foreach ( var chair in GetSortedSeats() )
//{
// var builder = new LinkedGameObjectBuilder();
// builder.AddConnected( chair.GameObject );
// // Skip if a seat occupied earlier already claimed this
// if ( builder.Objects.Any( driven.Contains ) ) continue;
// driven.UnionWith( builder.Objects );
// RunControl( chair, builder );
//}
}
IEnumerable<BaseChair> GetSortedSeats()
{
var chairs = Scene.GetAll<BaseChair>();
foreach ( var chair in chairs )
{
if ( !chair.IsValid() || !chair.IsOccupied )
_occupiedSince.Remove( chair );
else
_occupiedSince.TryAdd( chair, 0 );
}
return chairs
.Where( c => c.IsValid() && c.IsOccupied )
.OrderBy( c => (float)_occupiedSince.GetValueOrDefault( c, default ) );
}
//void RunControl( BaseChair chair, LinkedGameObjectBuilder builder )
//{
// var controller = chair.GetOccupant();
// if ( !controller.IsValid() ) return;
// var player = controller.GetComponent<Player>();
// if ( !player.IsValid() ) return;
// using var scope = ClientInput.PushScope( player );
// foreach ( var o in builder.Objects )
// {
// foreach ( var controllable in o.GetComponentsInChildren<IPlayerControllable>() )
// {
// if ( controllable is null ) continue;
// if ( !controllable.CanControl( player ) ) continue;
// controllable.OnControl();
// }
// }
//}
}