Rides/TrackRides/TrainCar.cs
namespace HC3.Rides;

#nullable enable

/// <summary>
/// One segment of a <see cref="Rides.Train"/>.
/// </summary>
public sealed class TrainCar : Component
{
	private float _trackPosition;

	[Property]
	public Train? Train { get; set; }

	[Property]
	public float Length { get; set; } = 64f;

	[Property]
	public float Mass { get; set; } = 250f;

	[Property]
	public float TrackPosition
	{
		get => _trackPosition;
		set
		{
			_trackPosition = value;
			UpdateTransform();
		}
	}

	protected override void OnEnabled()
	{
		GameObject.Parent?.GetComponent<Train>()?.InvalidateConsist();
	}

	protected override void OnDisabled()
	{
		GameObject.Parent?.GetComponent<Train>()?.InvalidateConsist();
	}

	protected override void OnDestroy()
	{
		GameObject.Parent?.GetComponent<Train>()?.InvalidateConsist();
	}

	private void UpdateTransform()
	{
		var trackSection = Train?.TrackSection ?? GameObject.Parent?.GetComponent<TrackSection>();

		if ( trackSection is null ) return;

		var transform = ((ITrackSection)trackSection).SampleAtDistance( TrackPosition, 24f );
		var railHeight = trackSection.TrackDefinition?.RailHeight ?? 12f;

		LocalPosition = transform.Position + transform.Rotation.Up * railHeight;
		LocalRotation = transform.Rotation;
	}
}