diff --git a/src/Devices/Doors.cs b/src/Devices/Doors.cs
index 26ed1e4..d943dca 100644
--- a/src/Devices/Doors.cs
+++ b/src/Devices/Doors.cs
@@ -33,6 +33,21 @@ namespace OpenbveFcmbTrainPlugin
/// Whether the AI should trigger the door closing sound.
private bool AiTriggerDoorClosingSound;
+ /// The timeout after which the AI needs to close doors if they become stuck, in seconds.
+ private double AiDoorStuckTimeout = 10;
+
+ /// The counter for the AI to close doors if they become stuck.
+ private double AiDoorStuckCounter;
+
+ /// The index of the door closing sound.
+ private int DoorClosingSoundIndex = 10;
+
+ /// The current time.
+ private Time CurrentTime = new Time(0);
+
+ /// The time when the doors last opened.
+ private Time DoorOpenTime = new Time(0);
+
/// Is called when the device state should be updated.
/// The current train.
@@ -41,6 +56,9 @@ namespace OpenbveFcmbTrainPlugin
/// The time elapsed since the previous call.
internal override void Update(Train train, Route route, bool init, Time elapsedTime)
{
+ // Update current time
+ CurrentTime = route.CurrentTime;
+
if (init)
{
if (!RequireDoorClosingSound)
@@ -109,8 +127,32 @@ namespace OpenbveFcmbTrainPlugin
}
// Check if AI needs to trigger the door closing sound
- // TODO: check departure time
- AiTriggerDoorClosingSound |= (train.DoorState != DoorStates.None && DoorClosingSoundCounter > DoorClosingSoundDuration + DoorClosingSoundTimeout);
+ if (train.DoorState != DoorStates.None && DoorClosingSoundCounter > DoorClosingSoundDuration + DoorClosingSoundTimeout)
+ {
+ if (route.CurrentStation.Type == StationType.Normal || route.CurrentStation.Type == StationType.RequestStop)
+ {
+ // The current station is an intermediate stop
+ if (route.CurrentStation.DepartureTime < 0)
+ {
+ // The current station has dwell time, not a specific departure time
+ // Calculate departure time from the time when the doors opened
+ AiTriggerDoorClosingSound |= CurrentTime.Seconds >= DoorOpenTime.Seconds + (route.CurrentStation.StopTime - DoorClosingSoundDuration);
+ }
+ else
+ {
+ // Use departure time - door closing sound duration
+ AiTriggerDoorClosingSound |= CurrentTime.Seconds >= route.CurrentStation.DepartureTime - DoorClosingSoundDuration;
+ }
+ }
+ else
+ {
+ AiTriggerDoorClosingSound = false;
+ }
+ }
+ else
+ {
+ AiTriggerDoorClosingSound = false;
+ }
// Update panel variables for door selection state
train.Panel[50] = (RequestedDoorInterlock == DoorInterlockStates.Left || RequestedDoorInterlock == DoorInterlockStates.Unlocked) || (((train.DoorState & DoorStates.Left) != 0) && !LeftDoorsClosing) ? 1 : 0;
@@ -133,6 +175,10 @@ namespace OpenbveFcmbTrainPlugin
// Play the door closing sound and reset timeout
DoorClosingSoundCounter = 0;
TriggerDoorUnlock = true;
+ if (!SoundManager.Playing(DoorClosingSoundIndex))
+ {
+ SoundManager.Play(DoorClosingSoundIndex, 1, 1, false);
+ }
}
break;
case VirtualKeys.G:
@@ -189,22 +235,30 @@ namespace OpenbveFcmbTrainPlugin
if (!OpenbveFcmbTrainPlugin.KeysPressed[(int)key])
{
// Unselect doors automatically when closing
- if ((train.DoorState & DoorStates.Left) > 0 && (RequestedDoorInterlock == DoorInterlockStates.Left || RequestedDoorInterlock == DoorInterlockStates.Unlocked))
+ if ((train.DoorState & DoorStates.Left) > 0 && !LeftDoorsClosing && (RequestedDoorInterlock == DoorInterlockStates.Left || RequestedDoorInterlock == DoorInterlockStates.Unlocked))
{
LeftDoorsClosing = true;
RequestedDoorInterlock = RequestedDoorInterlock == DoorInterlockStates.Left ? DoorInterlockStates.Locked : DoorInterlockStates.Right;
}
+ else
+ {
+ LeftDoorsClosing = false;
+ }
}
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))
+ if ((train.DoorState & DoorStates.Right) > 0 && !RightDoorsClosing && (RequestedDoorInterlock == DoorInterlockStates.Right || RequestedDoorInterlock == DoorInterlockStates.Unlocked))
{
RightDoorsClosing = true;
RequestedDoorInterlock = RequestedDoorInterlock == DoorInterlockStates.Right ? DoorInterlockStates.Locked : DoorInterlockStates.Left;
}
+ else
+ {
+ RightDoorsClosing = false;
+ }
}
break;
}
@@ -246,6 +300,12 @@ namespace OpenbveFcmbTrainPlugin
RequestedDoorInterlock = RequestedDoorInterlock == DoorInterlockStates.Right ? DoorInterlockStates.Right : DoorInterlockStates.Locked;
}
}
+
+ // Set arrival time when doors open
+ if (oldState == DoorStates.None && newState != DoorStates.None)
+ {
+ DoorOpenTime = CurrentTime;
+ }
}
/// Is called when the device should perform the AI.