openbve-fcmb-train-plugin/src/Route/Route.cs
2024-10-13 00:31:40 +02:00

112 lines
5 KiB
C#

using System.Collections.Generic;
using OpenBveApi.Runtime;
namespace OpenbveFcmbTrainPlugin
{
internal class Route
{
/// <summary>Represents the state of the current station.</summary>
internal enum StationStates
{
/// <summary>The train has not arrived at the station yet.</summary>
Pending = 0,
/// <summary>The train has arrived at the station.</summary>
Arrived = 1,
/// <summary>The train is ready to depart.</summary>
Completed = 2,
}
/// <summary>The state of the current station.</summary>
internal StationStates StationState { get; private set; } = StationStates.Arrived;
/// <summary>The list of stations in the route.</summary>
internal List<Station> Stations;
/// <summary>The current station in the route.</summary>
internal Station CurrentStation;
/// <summary>The next station in the route.</summary>
internal Station NextStation;
/// <summary>The current state of the train doors.</summary>
private DoorStates DoorState;
/// <summary>The previous state of the train doors.</summary>
private DoorStates PreviousDoorState;
/// <summary>Is called every frame.</summary>
/// <param name="data">The data passed to the plugin.</param>
internal void Elapse(ElapseData data)
{
if (OpenbveFcmbTrainPlugin.Initializing)
{
// Get the list of stations and set the current station
Stations = data.Stations;
UpdateStationData(data.Vehicle.Location);
}
if (StationState == StationStates.Completed && data.Vehicle.Location > CurrentStation.StopPosition + CurrentStation.ForwardTolerance)
{
// The train is heading for the next station
StationState = StationStates.Pending;
UpdateStationData(data.Vehicle.Location);
}
if (StationState == StationStates.Pending && data.Vehicle.Location > CurrentStation.StopPosition + CurrentStation.ForwardTolerance + 100)
{
// The train has passed the station without stopping
UpdateStationData(data.Vehicle.Location);
}
// Update station status after closing the doors
if (StationState == StationStates.Arrived && DoorState == DoorStates.None)
{
// The train is ready to leave the station
StationState = StationStates.Completed;
}
// Check if the train is at a station where the doors should open
bool ArrivedDoorStop = (PreviousDoorState == DoorStates.None && DoorState != DoorStates.None && (CurrentStation.OpenLeftDoors || CurrentStation.OpenRightDoors));
// Check if the train is at a station where the doors should not open
bool ArrivedNoDoorStop = (DoorState == DoorStates.None && !CurrentStation.OpenLeftDoors && !CurrentStation.OpenRightDoors);
if (StationState == StationStates.Pending && (ArrivedDoorStop || ArrivedNoDoorStop) && data.Vehicle.Speed.KilometersPerHour < 0.05 && data.Vehicle.Location >= CurrentStation.DefaultTrackPosition)
{
// The train has arrived at the station
StationState = StationStates.Arrived;
}
}
/// <summary>Is called when the state of the doors changes.</summary>
/// <param name="oldState">The old state of the doors.</param>
/// <param name="newState">The new state of the doors.</param>
internal void DoorChange(DoorStates oldState, DoorStates newState)
{
PreviousDoorState = oldState;
DoorState = newState;
}
/// <summary>Updates the data for the current and next station.</summary>
/// <param name="location">The current location of the train.</param>
internal void UpdateStationData(double location)
{
// Calculate the index of the current station
double position = location;
int currentIndex = 0;
if (Stations.Count > 1)
{
while (currentIndex > 0 && (Stations[currentIndex].StopPosition + Stations[currentIndex].ForwardTolerance > position || !Stations[currentIndex].PlayerStops()))
{
// Detects the station index when driving or jumping backwards
currentIndex--;
}
while (currentIndex < Stations.Count - 1 && (Stations[currentIndex].StopPosition + Stations[currentIndex].ForwardTolerance <= position || !Stations[currentIndex].PlayerStops()))
{
// Detects the station index when driving or jumping forwards
currentIndex++;
}
}
CurrentStation = Stations[currentIndex];
NextStation = currentIndex < Stations.Count - 1 ? Stations[currentIndex + 1] : null;
}
}
}