First devices
parent
51ef0ececc
commit
8d9c08276a
|
@ -1,7 +1,7 @@
|
||||||
|
|
||||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
# Visual Studio 15
|
# Visual Studio 15
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenBveFcmbTrainPlugin", "src/OpenBveFcmbTrainPlugin.csproj", "{9197FFA4-D95A-410C-A705-4E7CD187546A}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "OpenbveFcmbTrainPlugin", "src/OpenbveFcmbTrainPlugin.csproj", "{9197FFA4-D95A-410C-A705-4E7CD187546A}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
|
@ -0,0 +1,111 @@
|
||||||
|
using System;
|
||||||
|
using OpenBveApi.Runtime;
|
||||||
|
|
||||||
|
namespace OpenbveFcmbTrainPlugin
|
||||||
|
{
|
||||||
|
/// <summary>A deadman switch device to stop the train if the driver does not periodically acknowledge it.</summary>
|
||||||
|
internal class Deadman : 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>The counter. This starts at zero and counts up until the brake delay time is reached.</summary>
|
||||||
|
private double Counter;
|
||||||
|
|
||||||
|
/// <summary>The delay time until the service brake is applied, in seconds.</summary>
|
||||||
|
private double BrakeDelay = 5.0;
|
||||||
|
|
||||||
|
/// <summary>Whether the train must be completely stopped to release the brakes.</summary>
|
||||||
|
private bool FullReset = false;
|
||||||
|
|
||||||
|
/// <summary>Is called when the device state should be updated.</summary>
|
||||||
|
/// <param name="train">The current train.</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, bool init, Time elapsedTime)
|
||||||
|
{
|
||||||
|
if (train.VigilanceOverride)
|
||||||
|
{
|
||||||
|
// The train wants to override vigilance devices, so the device is inactive
|
||||||
|
DeviceState = DeviceStates.Inactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (DeviceState)
|
||||||
|
{
|
||||||
|
case DeviceStates.Active:
|
||||||
|
// The device is active, update the counter every frame
|
||||||
|
Counter += elapsedTime.Seconds;
|
||||||
|
RequestedBrakeNotch = -1;
|
||||||
|
if (Counter > BrakeDelay)
|
||||||
|
{
|
||||||
|
// Switch to emergency mode when the counter reaches the brake delay time
|
||||||
|
DeviceState = DeviceStates.Emergency;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DeviceStates.Inactive:
|
||||||
|
// The device is being overridden, release the brakes
|
||||||
|
RequestedBrakeNotch = -1;
|
||||||
|
if (!train.VigilanceOverride)
|
||||||
|
{
|
||||||
|
// If the device is no longer overridden, it should be active again
|
||||||
|
DeviceState = DeviceStates.Active;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case DeviceStates.Emergency:
|
||||||
|
// Apply the brakes when the device is in emergency mode
|
||||||
|
RequestedBrakeNotch = train.Specs.BrakeNotches;
|
||||||
|
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.S:
|
||||||
|
if (DeviceState == DeviceStates.Active || (DeviceState == DeviceStates.Emergency & !FullReset))
|
||||||
|
{
|
||||||
|
// Reset the counter if the delay time has not been exceeded or if a full reset is not required
|
||||||
|
Counter = 0;
|
||||||
|
DeviceState = DeviceStates.Active;
|
||||||
|
}
|
||||||
|
else if (DeviceState == DeviceStates.Emergency & Math.Abs(train.State.Speed.KilometersPerHour) < 0.01)
|
||||||
|
{
|
||||||
|
// Reset the counter after the train has stopped
|
||||||
|
Counter = 0;
|
||||||
|
DeviceState = DeviceStates.Active;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Is called when the plugin should perform the AI.</summary>
|
||||||
|
/// <param name="data">The AI data.</param>
|
||||||
|
/// <param name="train">The current train.</param>
|
||||||
|
internal override void PerformAI(AIData data, Train train)
|
||||||
|
{
|
||||||
|
if (DeviceState != DeviceStates.Inactive)
|
||||||
|
{
|
||||||
|
KeyChange(VirtualKeys.S, true, train);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,64 @@
|
||||||
|
using OpenBveApi.Runtime;
|
||||||
|
|
||||||
|
namespace OpenbveFcmbTrainPlugin
|
||||||
|
{
|
||||||
|
/// <summary>Represents an abstract device.</summary>
|
||||||
|
internal abstract class Device
|
||||||
|
{
|
||||||
|
|
||||||
|
/// <summary>The power notch requested by the device.</summary>
|
||||||
|
internal int RequestedPowerNotch = -1;
|
||||||
|
|
||||||
|
/// <summary>The brake notch requested by the device.</summary>
|
||||||
|
internal int RequestedBrakeNotch = -1;
|
||||||
|
|
||||||
|
/// <summary>The door interlock requested by the device.</summary>
|
||||||
|
internal DoorInterlockStates RequestedDoorInterlock;
|
||||||
|
|
||||||
|
/// <summary>Is called when the device state should be updated.</summary>
|
||||||
|
/// <param name="train">The current train.</param>
|
||||||
|
/// <param name="init">Whether the device should initialize.</param>
|
||||||
|
/// <param name="elapsedTime">The time elapsed since the previous call.</param>
|
||||||
|
internal virtual void Update(Train train, bool init, Time elapsedTime) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when the driver changes the reverser.</summary>
|
||||||
|
/// <param name="reverser">The new reverser position.</param>
|
||||||
|
internal virtual void SetReverser(int reverser) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when the driver changes the power notch.</summary>
|
||||||
|
/// <param name="powerNotch">The new power notch.</param>
|
||||||
|
internal virtual void SetPower(int powerNotch) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when the driver changes the brake notch.</summary>
|
||||||
|
/// <param name="brakeNotch">The new brake notch.</param>
|
||||||
|
internal virtual void SetBrake(int brakeNotch) { }
|
||||||
|
|
||||||
|
/// <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 virtual void KeyChange(VirtualKeys key, bool pressed, Train train) { }
|
||||||
|
|
||||||
|
/// <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 virtual void DoorChange(DoorStates oldState, DoorStates newState) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when a horn is played or when the music horn is stopped.</summary>
|
||||||
|
/// <param name="type">The type of horn.</param>
|
||||||
|
internal virtual void HornBlow(HornTypes type) { }
|
||||||
|
|
||||||
|
/// <summary>Is called to inform about signals.</summary>
|
||||||
|
/// <param name="signal">The signal data.</param>
|
||||||
|
internal virtual void SetSignal(SignalData[] signal) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when a beacon is passed.</summary>
|
||||||
|
/// <param name="beacon">The beacon data.</param>
|
||||||
|
internal virtual void SetBeacon(BeaconData beacon) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when the plugin should perform the AI.</summary>
|
||||||
|
/// <param name="data">The AI data.</param>
|
||||||
|
/// <param name="train">The current train.</param>
|
||||||
|
internal virtual void PerformAI(AIData data, Train train) { }
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,167 @@
|
||||||
|
using System;
|
||||||
|
using OpenBveApi.Runtime;
|
||||||
|
|
||||||
|
namespace OpenbveFcmbTrainPlugin
|
||||||
|
{
|
||||||
|
/// <summary>A device controlling the door operation.</summary>
|
||||||
|
internal class Doors : Device
|
||||||
|
{
|
||||||
|
/// <summary>Whether the left doors are closing.</summary>
|
||||||
|
private bool LeftDoorsClosing;
|
||||||
|
|
||||||
|
/// <summary>Whether the right doors are closing.</summary>
|
||||||
|
private bool RightDoorsClosing;
|
||||||
|
|
||||||
|
/// <summary>Is called when the device state should be updated.</summary>
|
||||||
|
/// <param name="train">The current train.</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, bool init, Time elapsedTime)
|
||||||
|
{
|
||||||
|
if (init)
|
||||||
|
{
|
||||||
|
// Set the selection state of the doors during initialization
|
||||||
|
switch (train.DoorState)
|
||||||
|
{
|
||||||
|
case DoorStates.None:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Locked;
|
||||||
|
break;
|
||||||
|
case DoorStates.Both:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Unlocked;
|
||||||
|
break;
|
||||||
|
case DoorStates.Left:
|
||||||
|
case DoorStates.Right:
|
||||||
|
RequestedDoorInterlock = (DoorInterlockStates)train.DoorState;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Cut power when the doors are open
|
||||||
|
RequestedPowerNotch = (train.DoorState != DoorStates.None) ? 0 : -1;
|
||||||
|
|
||||||
|
// Update panel variables for door selection state
|
||||||
|
train.Panel[50] = (RequestedDoorInterlock == DoorInterlockStates.Left || RequestedDoorInterlock == DoorInterlockStates.Unlocked) ? 1 : 0;
|
||||||
|
train.Panel[51] = (RequestedDoorInterlock == DoorInterlockStates.Right || RequestedDoorInterlock == DoorInterlockStates.Unlocked) ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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.G:
|
||||||
|
// Change the selection state of the left doors
|
||||||
|
if (!OpenbveFcmbTrainPlugin.KeysPressed[(int)key])
|
||||||
|
{
|
||||||
|
// Button active only if the doors are not open
|
||||||
|
if ((train.DoorState & DoorStates.Left) == 0 || LeftDoorsClosing)
|
||||||
|
{
|
||||||
|
switch (RequestedDoorInterlock)
|
||||||
|
{
|
||||||
|
case DoorInterlockStates.Locked:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Left;
|
||||||
|
break;
|
||||||
|
case DoorInterlockStates.Left:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Locked;
|
||||||
|
break;
|
||||||
|
case DoorInterlockStates.Right:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Unlocked;
|
||||||
|
break;
|
||||||
|
case DoorInterlockStates.Unlocked:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Right;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VirtualKeys.H:
|
||||||
|
// Change the selection state of the right doors
|
||||||
|
if (!OpenbveFcmbTrainPlugin.KeysPressed[(int)key])
|
||||||
|
{
|
||||||
|
// Button active only if the doors are not open
|
||||||
|
if ((train.DoorState & DoorStates.Right) == 0 || RightDoorsClosing)
|
||||||
|
{
|
||||||
|
switch (RequestedDoorInterlock)
|
||||||
|
{
|
||||||
|
case DoorInterlockStates.Locked:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Right;
|
||||||
|
break;
|
||||||
|
case DoorInterlockStates.Left:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Unlocked;
|
||||||
|
break;
|
||||||
|
case DoorInterlockStates.Right:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Locked;
|
||||||
|
break;
|
||||||
|
case DoorInterlockStates.Unlocked:
|
||||||
|
RequestedDoorInterlock = DoorInterlockStates.Left;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VirtualKeys.LeftDoors:
|
||||||
|
if (!OpenbveFcmbTrainPlugin.KeysPressed[(int)key])
|
||||||
|
{
|
||||||
|
// Unselect doors automatically when closing
|
||||||
|
if ((train.DoorState & DoorStates.Left) > 0 && (RequestedDoorInterlock == DoorInterlockStates.Left || RequestedDoorInterlock == DoorInterlockStates.Unlocked))
|
||||||
|
{
|
||||||
|
LeftDoorsClosing = true;
|
||||||
|
RequestedDoorInterlock = RequestedDoorInterlock == DoorInterlockStates.Left ? DoorInterlockStates.Locked : DoorInterlockStates.Right;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case VirtualKeys.RightDoors:
|
||||||
|
if (!OpenbveFcmbTrainPlugin.KeysPressed[(int)key])
|
||||||
|
{
|
||||||
|
// Unselect doors automatically when closing
|
||||||
|
if ((train.DoorState & DoorStates.Right) > 0 && (RequestedDoorInterlock == DoorInterlockStates.Right || RequestedDoorInterlock == DoorInterlockStates.Unlocked))
|
||||||
|
{
|
||||||
|
RightDoorsClosing = true;
|
||||||
|
RequestedDoorInterlock = RequestedDoorInterlock == DoorInterlockStates.Right ? DoorInterlockStates.Locked : DoorInterlockStates. Left;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// TODO: OpenBVE does not trigger virtual buttons when the AI driver is active, needs changes to main program
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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 override void DoorChange(DoorStates oldState, DoorStates newState)
|
||||||
|
{
|
||||||
|
LeftDoorsClosing = false;
|
||||||
|
RightDoorsClosing = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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>
|
||||||
|
internal override void PerformAI(AIData data, Train train)
|
||||||
|
{
|
||||||
|
//// Select the correct doors for the current station
|
||||||
|
//if (Stations.State != Stations.StationStates.Completed)
|
||||||
|
//{
|
||||||
|
// if (((Stations.Current.OpenLeftDoors && !LeftDoorsSelected) || (!Stations.Current.OpenLeftDoors && LeftDoorsSelected)) && !LeftDoorsClosing)
|
||||||
|
// {
|
||||||
|
// // Select or unselect the doors on the left.
|
||||||
|
// KeyDown(VirtualKeys.G);
|
||||||
|
// data.Response = AIResponse.Short;
|
||||||
|
// }
|
||||||
|
// if (((Stations.Current.OpenRightDoors && !RightDoorsSelected) || (!Stations.Current.OpenRightDoors && RightDoorsSelected)) && !RightDoorsClosing)
|
||||||
|
// {
|
||||||
|
// // Select or unselect the doors on the right.
|
||||||
|
// KeyDown(VirtualKeys.H);
|
||||||
|
// data.Response = AIResponse.Short;
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace OpenbveFcmbTrainPlugin
|
||||||
|
{
|
||||||
|
/// <summary>A train stop device to stop the train if a stop signal is passed.</summary>
|
||||||
|
internal class TrainStop : Device
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,27 +4,25 @@ using OpenBveApi.Runtime;
|
||||||
namespace OpenbveFcmbTrainPlugin
|
namespace OpenbveFcmbTrainPlugin
|
||||||
{
|
{
|
||||||
/// <summary>The interface to be implemented by the plugin.</summary>
|
/// <summary>The interface to be implemented by the plugin.</summary>
|
||||||
public partial class OpenbveFcmbTrainPlugin : IRuntime
|
public class OpenbveFcmbTrainPlugin : IRuntime
|
||||||
{
|
{
|
||||||
|
/// <summary>The train that is simulated by this plugin.</summary>
|
||||||
|
private Train Train;
|
||||||
|
|
||||||
/// <summary>Holds the aspect last reported to the plugin in the SetSignal call.</summary>
|
/// <summary>Whether the train is initializing or reinitializing.</summary>
|
||||||
int LastAspect = -1;
|
internal static bool Initializing = true;
|
||||||
|
|
||||||
/// <summary>Holds the array of panel variables.</summary>
|
|
||||||
/// <remarks>Be sure to initialize in the Load call.</remarks>
|
|
||||||
public static int[] Panel;
|
|
||||||
|
|
||||||
/// <summary>Remembers which of the virtual keys are currently pressed down.</summary>
|
/// <summary>Remembers which of the virtual keys are currently pressed down.</summary>
|
||||||
public static bool[] KeysPressed = new bool[34];
|
internal static bool[] KeysPressed = new bool[Enum.GetNames(typeof(VirtualKeys)).Length];
|
||||||
|
|
||||||
/// <summary>Whether the plugin is initializing or reinitializing.</summary>
|
|
||||||
public static bool Initializing;
|
|
||||||
|
|
||||||
/// <summary>Is called when the plugin is loaded.</summary>
|
/// <summary>Is called when the plugin is loaded.</summary>
|
||||||
/// <param name="properties">The properties supplied to the plugin on loading.</param>
|
/// <param name="properties">The properties supplied to the plugin on loading.</param>
|
||||||
/// <returns>Whether the plugin was loaded successfully.</returns>
|
/// <returns>Whether the plugin was loaded successfully.</returns>
|
||||||
public bool Load(LoadProperties properties)
|
public bool Load(LoadProperties properties)
|
||||||
{
|
{
|
||||||
|
properties.AISupport = AISupport.Basic;
|
||||||
|
properties.Panel = new int[256];
|
||||||
|
Train = new Train(properties.Panel);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,18 +35,24 @@ namespace OpenbveFcmbTrainPlugin
|
||||||
/// <param name="specs">The specifications of the train.</param>
|
/// <param name="specs">The specifications of the train.</param>
|
||||||
public void SetVehicleSpecs(VehicleSpecs specs)
|
public void SetVehicleSpecs(VehicleSpecs specs)
|
||||||
{
|
{
|
||||||
|
Train.SetVehicleSpecs(specs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Is called when the plugin should initialize or reinitialize.</summary>
|
/// <summary>Is called when the plugin should initialize or reinitialize.</summary>
|
||||||
/// <param name="mode">The mode of initialization.</param>
|
/// <param name="mode">The mode of initialization.</param>
|
||||||
public void Initialize(InitializationModes mode)
|
public void Initialize(InitializationModes mode)
|
||||||
{
|
{
|
||||||
|
// On initialization, a variable is set so the first call to Elapse() can be used for initialization
|
||||||
|
Initializing = true;
|
||||||
|
Train.Initialize(mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Is called every frame.</summary>
|
/// <summary>Is called every frame.</summary>
|
||||||
/// <param name="data">The data passed to the plugin.</param>
|
/// <param name="data">The data passed to the plugin.</param>
|
||||||
public void Elapse(ElapseData data)
|
public void Elapse(ElapseData data)
|
||||||
{
|
{
|
||||||
|
Train.Elapse(data);
|
||||||
|
Initializing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Is called when the driver changes the reverser.</summary>
|
/// <summary>Is called when the driver changes the reverser.</summary>
|
||||||
|
@ -73,12 +77,16 @@ namespace OpenbveFcmbTrainPlugin
|
||||||
/// <param name="key">The virtual key that was pressed.</param>
|
/// <param name="key">The virtual key that was pressed.</param>
|
||||||
public void KeyDown(VirtualKeys key)
|
public void KeyDown(VirtualKeys key)
|
||||||
{
|
{
|
||||||
|
Train.KeyDown(key);
|
||||||
|
KeysPressed[(int)key] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Is called when a virtual key is released.</summary>
|
/// <summary>Is called when a virtual key is released.</summary>
|
||||||
/// <param name="key">The virtual key that was released.</param>
|
/// <param name="key">The virtual key that was released.</param>
|
||||||
public void KeyUp(VirtualKeys key)
|
public void KeyUp(VirtualKeys key)
|
||||||
{
|
{
|
||||||
|
Train.KeyUp(key);
|
||||||
|
KeysPressed[(int)key] = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Is called when a horn is played or when the music horn is stopped.</summary>
|
/// <summary>Is called when a horn is played or when the music horn is stopped.</summary>
|
||||||
|
@ -92,16 +100,13 @@ namespace OpenbveFcmbTrainPlugin
|
||||||
/// <param name="newState">The new state of the doors.</param>
|
/// <param name="newState">The new state of the doors.</param>
|
||||||
public void DoorChange(DoorStates oldState, DoorStates newState)
|
public void DoorChange(DoorStates oldState, DoorStates newState)
|
||||||
{
|
{
|
||||||
|
Train.DoorChange(oldState, newState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Is called when the aspect in the current or in any of the upcoming sections changes, or when passing section boundaries.</summary>
|
/// <summary>Is called when the aspect in the current or in any of the upcoming sections changes, or when passing section boundaries.</summary>
|
||||||
/// <remarks>The signal array is guaranteed to have at least one element. When accessing elements other than index 0, you must check the bounds of the array first.</remarks>
|
/// <remarks>The signal array is guaranteed to have at least one element. When accessing elements other than index 0, you must check the bounds of the array first.</remarks>
|
||||||
public void SetSignal(SignalData[] signal)
|
public void SetSignal(SignalData[] signal)
|
||||||
{
|
{
|
||||||
int aspect = signal[0].Aspect;
|
|
||||||
if (aspect != LastAspect)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>Is called when the train passes a beacon.</summary>
|
/// <summary>Is called when the train passes a beacon.</summary>
|
||||||
|
@ -114,6 +119,7 @@ namespace OpenbveFcmbTrainPlugin
|
||||||
/// <param name="data">The AI data.</param>
|
/// <param name="data">The AI data.</param>
|
||||||
public void PerformAI(AIData data)
|
public void PerformAI(AIData data)
|
||||||
{
|
{
|
||||||
|
Train.PerformAI(data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -5,8 +5,8 @@
|
||||||
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
<ProjectGuid>{9197FFA4-D95A-410C-A705-4E7CD187546A}</ProjectGuid>
|
<ProjectGuid>{9197FFA4-D95A-410C-A705-4E7CD187546A}</ProjectGuid>
|
||||||
<OutputType>Library</OutputType>
|
<OutputType>Library</OutputType>
|
||||||
<RootNamespace>OpenBveFcmbTrainPlugin</RootNamespace>
|
<RootNamespace>OpenbveFcmbTrainPlugin</RootNamespace>
|
||||||
<AssemblyName>OpenBveFcmbTrainPlugin</AssemblyName>
|
<AssemblyName>OpenbveFcmbTrainPlugin</AssemblyName>
|
||||||
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
<TargetFrameworkVersion>v4.7</TargetFrameworkVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
@ -29,13 +29,21 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
<Reference Include="OpenBveApi">
|
<Reference Include="OpenBveApi">
|
||||||
<HintPath>..\..\..\..\lib\openbve\OpenBveApi.dll</HintPath>
|
<HintPath>..\..\..\Documents\OpenBVE\OpenBveApi.dll</HintPath>
|
||||||
<Private>False</Private>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Compile Include="OpenBveFcmbTrainPlugin.cs" />
|
<Compile Include="OpenbveFcmbTrainPlugin.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
<Compile Include="Devices\Device.cs" />
|
||||||
|
<Compile Include="Devices\Doors.cs" />
|
||||||
|
<Compile Include="Train\Train.cs" />
|
||||||
|
<Compile Include="Devices\TrainStop.cs" />
|
||||||
|
<Compile Include="Devices\Deadman.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Folder Include="Devices\" />
|
||||||
|
<Folder Include="Train\" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
|
@ -0,0 +1,152 @@
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using OpenBveApi.Runtime;
|
||||||
|
|
||||||
|
namespace OpenbveFcmbTrainPlugin
|
||||||
|
{
|
||||||
|
/// <summary>Represents a train that is simulated by this plugin.</summary>
|
||||||
|
internal class Train
|
||||||
|
{
|
||||||
|
/// <summary>The train panel variables.</summary>
|
||||||
|
internal int[] Panel;
|
||||||
|
|
||||||
|
/// <summary>The specifications of the train.</summary>
|
||||||
|
internal VehicleSpecs Specs { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>The current state of the train.</summary>
|
||||||
|
internal VehicleState State { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>The current state of the train doors.</summary>
|
||||||
|
internal DoorStates DoorState { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>The previous state of the train doors.</summary>
|
||||||
|
internal DoorStates PreviousDoorState { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>The latest initialization mode of the train.</summary>
|
||||||
|
internal InitializationModes InitializationMode { get; private set; }
|
||||||
|
|
||||||
|
/// <summary>The devices equipped in the train.</summary>
|
||||||
|
private List<Device> Devices;
|
||||||
|
|
||||||
|
/// <summary>Whether the train's vigilance device is overridden.</summary>
|
||||||
|
internal bool VigilanceOverride;
|
||||||
|
|
||||||
|
/// <summary>Whether the train is using a continuous protection system instead of an intermittent protection system.</summary>
|
||||||
|
internal bool ContinuousProtection;
|
||||||
|
|
||||||
|
/// <summary>Creates a new train with the device configuration provided.</summary>
|
||||||
|
/// <param name="panel">The array of panel variables.</pa
|
||||||
|
internal Train(int[] panel)
|
||||||
|
{
|
||||||
|
Specs = new VehicleSpecs(0, BrakeTypes.ElectromagneticStraightAirBrake, 0, false, 0);
|
||||||
|
State = new VehicleState(0.0, new Speed(0.0), 0.0, 0.0, 0.0, 0.0, 0.0);
|
||||||
|
Panel = panel;
|
||||||
|
Devices = new List<Device>();
|
||||||
|
Devices.Add(new Doors());
|
||||||
|
Devices.Add(new Deadman());
|
||||||
|
Devices.Add(new TrainStop());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Is called when the train should initialize.</summary>
|
||||||
|
/// <param name="mode">The initialization mode.</param>
|
||||||
|
internal void Initialize(InitializationModes mode)
|
||||||
|
{
|
||||||
|
InitializationMode = mode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Is called after loading to inform the plugin about the specifications of the train.</summary>
|
||||||
|
/// <param name="specs">The specifications of the train.</param>
|
||||||
|
internal void SetVehicleSpecs(VehicleSpecs specs)
|
||||||
|
{
|
||||||
|
Specs = specs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Is called every frame.</summary>
|
||||||
|
/// <param name="data">The data.</param>
|
||||||
|
internal void Elapse(ElapseData data)
|
||||||
|
{
|
||||||
|
State = data.Vehicle;
|
||||||
|
|
||||||
|
// Reset data to be passed to the simulator
|
||||||
|
data.DoorInterlockState = DoorInterlockStates.Unlocked;
|
||||||
|
data.Handles.PowerNotch = data.Handles.PowerNotch;
|
||||||
|
data.Handles.BrakeNotch = data.Handles.BrakeNotch;
|
||||||
|
|
||||||
|
// Retrieve data from all devices
|
||||||
|
foreach (Device dev in Devices)
|
||||||
|
{
|
||||||
|
dev.Update(this, OpenbveFcmbTrainPlugin.Initializing, data.ElapsedTime);
|
||||||
|
data.DoorInterlockState |= dev.RequestedDoorInterlock;
|
||||||
|
if (dev.RequestedPowerNotch != -1) data.Handles.PowerNotch = dev.RequestedPowerNotch;
|
||||||
|
if (dev.RequestedBrakeNotch != -1) data.Handles.BrakeNotch = dev.RequestedBrakeNotch;
|
||||||
|
}
|
||||||
|
data.DebugMessage = DoorState.ToString() + " " + data.DoorInterlockState.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Is called when the driver changes the reverser.</summary>
|
||||||
|
/// <param name="reverser">The new reverser position.</param>
|
||||||
|
internal void SetReverser(int reverser) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when the driver changes the power notch.</summary>
|
||||||
|
/// <param name="powerNotch">The new power notch.</param>
|
||||||
|
internal void SetPower(int powerNotch) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when the driver changes the brake notch.</summary>
|
||||||
|
/// <param name="brakeNotch">The new brake notch.</param>
|
||||||
|
internal void SetBrake(int brakeNotch) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when a key is pressed.</summary>
|
||||||
|
/// <param name="key">The key.</param>
|
||||||
|
internal void KeyDown(VirtualKeys key)
|
||||||
|
{
|
||||||
|
foreach (Device dev in Devices)
|
||||||
|
{
|
||||||
|
dev.KeyChange(key, true, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Is called when a key is released.</summary>
|
||||||
|
/// <param name="key">The key.</param>
|
||||||
|
internal void KeyUp(VirtualKeys key)
|
||||||
|
{
|
||||||
|
foreach (Device dev in Devices)
|
||||||
|
{
|
||||||
|
dev.KeyChange(key, false, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <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;
|
||||||
|
foreach (Device dev in Devices)
|
||||||
|
{
|
||||||
|
dev.DoorChange(oldState, newState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>Is called when a horn is played or when the music horn is stopped.</summary>
|
||||||
|
/// <param name="type">The type of horn.</param>
|
||||||
|
internal void HornBlow(HornTypes type) { }
|
||||||
|
|
||||||
|
/// <summary>Is called to inform about signals.</summary>
|
||||||
|
/// <param name="signal">The signal data.</param>
|
||||||
|
internal void SetSignal(SignalData[] signal) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when a beacon is passed.</summary>
|
||||||
|
/// <param name="beacon">The beacon data.</param>
|
||||||
|
internal void SetBeacon(BeaconData beacon) { }
|
||||||
|
|
||||||
|
/// <summary>Is called when the plugin should perform the AI.</summary>
|
||||||
|
/// <param name="data">The AI data.</param>
|
||||||
|
internal void PerformAI(AIData data)
|
||||||
|
{
|
||||||
|
foreach (Device dev in Devices)
|
||||||
|
{
|
||||||
|
dev.PerformAI(data, this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue