From 3aae76416c7b35523aebe40cc25db569d7b0c523 Mon Sep 17 00:00:00 2001 From: Marc Riera Date: Sun, 13 Oct 2024 13:03:44 +0200 Subject: [PATCH] Train stop --- src/Devices/TrainStop.cs | 115 +++++++++++++++++++++++++++++++++++++++ src/Train/Train.cs | 8 ++- 2 files changed, 122 insertions(+), 1 deletion(-) 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.