diff --git a/src/Devices/TrainStop.cs b/src/Devices/TrainStop.cs
index f2797cd..a56b083 100644
--- a/src/Devices/TrainStop.cs
+++ b/src/Devices/TrainStop.cs
@@ -1,10 +1,125 @@
using System;
+using OpenBveApi.Runtime;
namespace OpenbveFcmbTrainPlugin
{
/// A train stop device to stop the train if a stop signal is passed.
internal class TrainStop : Device
{
+ /// Represents the state of the device.
+ private enum DeviceStates
+ {
+ /// The device is inactive.
+ Inactive,
+ /// The device is active.
+ Active,
+ /// The device is in emergency state.
+ Emergency,
+ }
+ /// The current state of the device.
+ private DeviceStates DeviceState;
+
+ /// Is called when the device state should be updated.
+ /// The current train.
+ /// The current route.
+ /// Whether the device should initialize.
+ /// The time elapsed since the previous call.
+ 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;
+ }
+ }
+
+
+ /// Is called when the state of a key changes.
+ /// The key.
+ /// Whether the key is pressed or released.
+ /// The current train.
+ 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;
+ }
+ }
+ }
+
+ /// Is called when a beacon is passed.
+ /// The beacon data.
+ 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;
+ }
+ }
+
+
+ /// Is called when the device should perform the AI.
+ /// The AI data.
+ /// The current train.
+ /// The current route.
+ 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);
+ }
+ }
}
}
diff --git a/src/Train/Train.cs b/src/Train/Train.cs
index daf2898..cf62add 100644
--- a/src/Train/Train.cs
+++ b/src/Train/Train.cs
@@ -137,7 +137,13 @@ namespace OpenbveFcmbTrainPlugin
/// Is called when a beacon is passed.
/// The beacon data.
- internal void SetBeacon(BeaconData beacon) { }
+ internal void SetBeacon(BeaconData beacon)
+ {
+ foreach (Device dev in Devices)
+ {
+ dev.SetBeacon(beacon);
+ }
+ }
/// Is called when the plugin should perform the AI.
/// The AI data.