Train stop

main
Marc Riera 2024-10-13 13:03:44 +02:00
parent b32c1aafeb
commit 3aae76416c
2 changed files with 122 additions and 1 deletions

View File

@ -1,10 +1,125 @@
using System;
using OpenBveApi.Runtime;
namespace OpenbveFcmbTrainPlugin
{
/// <summary>A train stop device to stop the train if a stop signal is passed.</summary>
internal class TrainStop : Device
{
/// <summary>Represents the state of the device.</summary>
private enum DeviceStates
{
/// <summary>The device is inactive.</summary>
Inactive,
/// <summary>The device is active.</summary>
Active,
/// <summary>The device is in emergency state.</summary>
Emergency,
}
/// <summary>The current state of the device.</summary>
private DeviceStates DeviceState;
/// <summary>Is called when the device state should be updated.</summary>
/// <param name="train">The current train.</param>
/// <param name="route">The current route.</param>
/// <param name="init">Whether the device should initialize.</param>
/// <param name="elapsedTime">The time elapsed since the previous call.</param>
internal override void Update(Train train, Route route, bool init, Time elapsedTime)
{
if (init)
{
// Activate the device during initialization
DeviceState = DeviceStates.Active;
}
if (train.VigilanceOverride)
{
// If the train requires a vigilance override, deactivate the device
DeviceState = DeviceStates.Inactive;
}
else if (DeviceState != DeviceStates.Emergency)
{
// Activate the device if there is no emergency
DeviceState = DeviceStates.Active;
}
switch (DeviceState)
{
case DeviceStates.Emergency:
// Emergency stop required, potential SPAD
RequestedBrakeNotch = train.Specs.BrakeNotches + 1;
break;
default:
RequestedBrakeNotch = -1;
break;
}
}
/// <summary>Is called when the state of a key changes.</summary>
/// <param name="key">The key.</param>
/// <param name="pressed">Whether the key is pressed or released.</param>
/// <param name="train">The current train.</param>
internal override void KeyChange(VirtualKeys key, bool pressed, Train train)
{
if (pressed)
{
switch (key)
{
case VirtualKeys.C2:
// Reset the train stop device
if (!OpenbveFcmbTrainPlugin.KeysPressed[(int)key])
{
// Reset only possible with train stopped
if (train.State.Speed.KilometersPerHour < 0.05)
{
if (DeviceState == DeviceStates.Emergency)
{
DeviceState = DeviceStates.Active;
}
}
}
break;
}
}
}
/// <summary>Is called when a beacon is passed.</summary>
/// <param name="beacon">The beacon data.</param>
internal override void SetBeacon(BeaconData beacon)
{
switch (beacon.Type)
{
// Accidental departure beacon/transponder
case 2:
// Check if there is a potential SPAD and change to emergency mode
if (beacon.Signal.Aspect == 0)
{
if (DeviceState == DeviceStates.Active)
{
DeviceState = DeviceStates.Emergency;
}
}
break;
}
}
/// <summary>Is called when the device should perform the AI.</summary>
/// <param name="data">The AI data.</param>
/// <param name="train">The current train.</param>
/// <param name="route">The current route.</param>
internal override void PerformAI(AIData data, Train train, Route route)
{
// Reset device in case of emergency, once the train has stopped
if (DeviceState == DeviceStates.Emergency && train.State.Speed.KilometersPerHour < 0.05)
{
data.Handles.BrakeNotch = train.Specs.BrakeNotches;
KeyChange(VirtualKeys.C2, true, train);
data.Response = AIResponse.Long;
KeyChange(VirtualKeys.C2, false, train);
}
}
}
}

View File

@ -137,7 +137,13 @@ namespace OpenbveFcmbTrainPlugin
/// <summary>Is called when a beacon is passed.</summary>
/// <param name="beacon">The beacon data.</param>
internal void SetBeacon(BeaconData beacon) { }
internal void SetBeacon(BeaconData beacon)
{
foreach (Device dev in Devices)
{
dev.SetBeacon(beacon);
}
}
/// <summary>Is called when the plugin should perform the AI.</summary>
/// <param name="data">The AI data.</param>