Park/Rides/FlatRides/FerrisWheelRide.cs
using HC3;
using System;
public sealed class FerrisWheelRide : BasicRide
{
[Property] public GameObject Wheel { get; set; }
[Property] public List<GameObject> Carts { get; set; } = new();
[Property, Feature( "Ride" )] public float RotationSpeed { get; set; } = 90.0f; // degrees per second
[Property, Feature( "Ride" ), Title( "Number of Circuits" ), Inspectable] public int CycleCount { get; set; } = 2;
private float _rotPerCart => 360.0f / Carts.Count;
private float _curRotation = 0.0f;
private int _curCartIdx = 0;
private Dictionary<int, int> _cartCycles = new();
protected override void OnUpdate()
{
base.OnUpdate();
if ( !Wheel.IsValid() || Carts.Count == 0 )
return;
if ( !RideStarted )
return;
float rotDelta = System.MathF.Min( RotationSpeed * Time.Delta, _rotPerCart - _curRotation );
_curRotation += rotDelta;
Wheel.LocalRotation *= Rotation.FromAxis( Vector3.Forward, rotDelta );
OrientCarts();
if ( _curRotation >= _rotPerCart )
{
_curRotation = 0.0f;
_curCartIdx = (_curCartIdx + 1) % Carts.Count;
int count = 0;
if ( _cartCycles.ContainsKey( _curCartIdx ) )
{
count = _cartCycles[_curCartIdx]++;
}
var cart = Carts[_curCartIdx];
bool isEmpty = true;
foreach ( var s in cart.Components.GetAll<SlotMarker>() )
{
if ( !s.IsFree() ) { isEmpty = false; break; }
}
if ( (isEmpty && QueueingCount > 0) || count >= CycleCount )
{
EndRide();
}
}
}
protected override void OnRideStarted()
{
_curRotation = 0f;
_cartCycles[_curCartIdx] = 0;
}
protected override void OnRideEnded()
{
UnloadCart( Carts[_curCartIdx] );
}
private void UnloadCart( GameObject cart )
{
// Collect occupied slots first to avoid mutation during iteration
var slots = cart.Components.GetAll<SlotMarker>();
foreach ( var slot in slots )
{
if ( !slot.Contents.IsValid() ) continue;
OnUse( slot.Contents );
Unload( slot.Contents );
}
}
private void OrientCarts()
{
foreach ( var cart in Carts )
{
var uprightRotation = Rotation.LookAt( WorldRotation.Forward, WorldRotation.Right );
cart.WorldRotation = uprightRotation;
}
}
protected override IEnumerable<SlotMarker> GetLoadableSlots()
{
if ( Carts.Count < 1 ) return Array.Empty<SlotMarker>();
return Carts[_curCartIdx].Components.GetAll<SlotMarker>();
}
}