Park/Rides/FlatRides/HelterSkelterRide.cs
using HC3;

public sealed class HelterSkelterRide : BasicRide
{
	[Property] public GameObject Guest { get; set; }
	[Property] public List<GameObject> PathPoints { get; set; } = new();

	private int currentPoint = 0;
	private float rideSpeed = 150f; // Units per second

	protected override void OnRideStarted()
	{
		base.OnRideStarted();

		if ( PathPoints.Count < 2 )
		{
			Log.Warning( "Not enough path points for HelterSkelterRide!" );
			return;
		}

		currentPoint = 0;

		// Move to start point
		if ( Guest.IsValid() && PathPoints[0].IsValid() )
		{
			Guest.WorldPosition = PathPoints[0].WorldPosition;
		}
	}

	protected override void OnUpdate()
	{
		base.OnUpdate();

		if ( !RideStarted || Guest == null || PathPoints.Count == 0 )
			return;

		if ( currentPoint >= PathPoints.Count - 1 )
		{
			EndRide();
			return;
		}

		var from = PathPoints[currentPoint].WorldPosition;
		var to = PathPoints[currentPoint + 1].WorldPosition;

		var direction = (to - from).Normal;
		Guest.WorldPosition += direction * rideSpeed * Time.Delta;

		// Rotate the cart to face direction
		if ( direction.Length > 0.1f )
			Guest.WorldRotation = Rotation.LookAt( direction, Vector3.Up );

		// Check if we passed next point
		if ( (Guest.WorldPosition - to).LengthSquared < 100f )
		{
			currentPoint++;
		}
	}

	protected override void DrawGizmos()
	{
		base.DrawGizmos();

		if ( PathPoints.Count < 2 )
			return;

		Gizmo.Draw.Color = Color.Yellow;
		Gizmo.Draw.IgnoreDepth = false;
		Gizmo.Draw.LineThickness = 4f;

		for ( int i = 0; i < PathPoints.Count - 1; i++ )
		{
			if ( PathPoints[i].IsValid() && PathPoints[i + 1].IsValid() )
			{
				Gizmo.Draw.Line( PathPoints[i].WorldPosition, PathPoints[i + 1].WorldPosition );
			}
		}
	}
}