112 lines
5 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|