diff --git a/Source/Orts.Simulation/MultiPlayer/Message.cs b/Source/Orts.Simulation/MultiPlayer/Message.cs index 1ba00a1e..1036722b 100644 --- a/Source/Orts.Simulation/MultiPlayer/Message.cs +++ b/Source/Orts.Simulation/MultiPlayer/Message.cs @@ -3534,6 +3534,9 @@ public MSGSignalChange(string m) sigHead.draw_state = sigHead.def_draw_state(sigHead.state); } break; + case 4: + signal.SetManualCallOn(true); + break; } } diff --git a/Source/Orts.Simulation/Simulation/Physics/Train.cs b/Source/Orts.Simulation/Simulation/Physics/Train.cs index 4fe2d2e7..d68b6b04 100644 --- a/Source/Orts.Simulation/Simulation/Physics/Train.cs +++ b/Source/Orts.Simulation/Simulation/Physics/Train.cs @@ -236,6 +236,7 @@ public enum TRAINTYPE public int IndexNextSignal = -1; // Index in SignalObjectItems for next signal public int IndexNextSpeedlimit = -1; // Index in SignalObjectItems for next speedpost public SignalObject[] NextSignalObject = new SignalObject[2]; // direct reference to next signal + public SignalObject AllowedCallOnSignal; // Signal for which train has call on allowed by dispatcher public float TrainMaxSpeedMpS; // Max speed as set by route (default value) public float AllowedMaxSpeedMpS; // Max speed as allowed @@ -2483,6 +2484,8 @@ public void UpdateManual(float elapsedClockSeconds) // system will take back control of the signal if (signalObject.holdState == SignalObject.HoldState.ManualPass || signalObject.holdState == SignalObject.HoldState.ManualApproach) signalObject.holdState = SignalObject.HoldState.None; + + AllowedCallOnSignal = null; } UpdateSectionStateManual(); // update track occupation // UpdateManualMode(SignalObjIndex); // update route clearance // @@ -2510,6 +2513,8 @@ public void UpdateExplorer(float elapsedClockSeconds) // system will take back control of the signal if (signalObject.holdState == SignalObject.HoldState.ManualPass || signalObject.holdState == SignalObject.HoldState.ManualApproach) signalObject.holdState = SignalObject.HoldState.None; + + AllowedCallOnSignal = null; } UpdateSectionStateExplorer(); // update track occupation // UpdateExplorerMode(SignalObjIndex); // update route clearance // @@ -7064,6 +7069,8 @@ public void UpdateRouteClearanceAhead(int signalObjectIndex, int backward, float signalObject.holdState = SignalObject.HoldState.None; } + AllowedCallOnSignal = null; + signalObject.resetSignalEnabled(); } } @@ -7215,6 +7222,9 @@ public bool CheckStoppedTrains(TCSubpathRoute thisRoute) public virtual bool TestCallOn(SignalObject thisSignal, bool allowOnNonePlatform, TCSubpathRoute thisRoute, string dumpfile) { + if (AllowedCallOnSignal == thisSignal) + return true; + bool intoPlatform = false; foreach (Train.TCRouteElement routeElement in thisSignal.signalRoute) @@ -7559,6 +7569,8 @@ public void UpdateManualMode(int signalObjectIndex) if (thisSignal.holdState == SignalObject.HoldState.ManualPass || thisSignal.holdState == SignalObject.HoldState.ManualApproach) thisSignal.holdState = SignalObject.HoldState.None; + AllowedCallOnSignal = null; + thisSignal.resetSignalEnabled(); } diff --git a/Source/Orts.Simulation/Simulation/Signalling/SIGSCRfile.cs b/Source/Orts.Simulation/Simulation/Signalling/SIGSCRfile.cs index c541fd6c..d6cf72be 100644 --- a/Source/Orts.Simulation/Simulation/Signalling/SIGSCRfile.cs +++ b/Source/Orts.Simulation/Simulation/Signalling/SIGSCRfile.cs @@ -1026,6 +1026,7 @@ public void SH_process_script(SignalHead thisHead, SignalScripts.SCRScripts sign dumpfile = String.Concat(dpr_fileLoc, "printproc.txt"); } #endif + thisHead.mainSignal.CallOnEnabled = true; temp_value = thisHead.mainSignal.TrainHasCallOn(true, dumpfile); return_value = Convert.ToInt32(temp_value); break; @@ -1048,6 +1049,7 @@ public void SH_process_script(SignalHead thisHead, SignalScripts.SCRScripts sign dumpfile = String.Concat(dpr_fileLoc, "printproc.txt"); } #endif + thisHead.mainSignal.CallOnEnabled = true; temp_value = thisHead.mainSignal.TrainHasCallOn(false, dumpfile); return_value = Convert.ToInt32(temp_value); break; diff --git a/Source/Orts.Simulation/Simulation/Signalling/Signals.cs b/Source/Orts.Simulation/Simulation/Signalling/Signals.cs index 9658b8d6..b166aab0 100644 --- a/Source/Orts.Simulation/Simulation/Signalling/Signals.cs +++ b/Source/Orts.Simulation/Simulation/Signalling/Signals.cs @@ -8358,6 +8358,8 @@ public enum HoldState // signal is locked in hold public bool StationHold = false; // Set if signal must be held at station - processed by signal script protected List> LockedTrains; + public bool CallOnEnabled = false; // set if signal script file uses CallOn functionality + public bool enabled { get @@ -12512,6 +12514,8 @@ public bool[] requestHoldSignalDispatcher(bool requestResetSignal) bool[] returnValue = new bool[2] { false, false }; MstsSignalAspect thisAspect = this_sig_lr(MstsSignalFunction.NORMAL); + SetManualCallOn(false); + // signal not enabled - set lock, reset if cleared (auto signal can clear without enabling) if (enabledTrain == null || enabledTrain.Train == null) @@ -12577,6 +12581,25 @@ public void clearHoldSignalDispatcher() holdState = HoldState.None; } + //================================================================================================// + /// + /// Set call on manually from dispatcher + /// + public void SetManualCallOn(bool state) + { + if (enabledTrain != null) + { + if (state && CallOnEnabled) + { + enabledTrain.Train.AllowedCallOnSignal = this; + clearHoldSignalDispatcher(); + } + else if (enabledTrain.Train.AllowedCallOnSignal == this) + { + enabledTrain.Train.AllowedCallOnSignal = null; + } + } + } } // SignalObject diff --git a/Source/RunActivity/Viewer3D/Debugging/DebugViewerForm.cs b/Source/RunActivity/Viewer3D/Debugging/DebugViewerForm.cs index 8d7111e2..7c789755 100644 --- a/Source/RunActivity/Viewer3D/Debugging/DebugViewerForm.cs +++ b/Source/RunActivity/Viewer3D/Debugging/DebugViewerForm.cs @@ -1530,6 +1530,20 @@ private void HandlePickedSignal() var y = LastCursorPosition.Y; if (LastCursorPosition.Y < 100) y = 100; if (LastCursorPosition.Y > pictureBox1.Size.Height - 100) y = pictureBox1.Size.Height - 100; + + if (boxSetSignal.Items.Count == 5) + boxSetSignal.Items.RemoveAt(4); + + if (signalPickedItem.Signal.enabledTrain != null && signalPickedItem.Signal.CallOnEnabled) + { + if (signalPickedItem.Signal.enabledTrain.Train.AllowedCallOnSignal != signalPickedItem.Signal) + boxSetSignal.Items.Add("Enable call on"); + /*else + boxSetSignal.Items.Add("Disable call on");*/ + // To disable Call On signal must be manually set to stop, to avoid signal state change + // in the interval between this list is shown and the option is selected by dispatcher + } + boxSetSignal.Location = new System.Drawing.Point(LastCursorPosition.X + 2, y); boxSetSignal.Enabled = true; boxSetSignal.Focus(); @@ -1965,6 +1979,9 @@ private void boxSetSignalChosen(object sender, EventArgs e) sigHead.draw_state = sigHead.def_draw_state(sigHead.state); } break; + case 4: + signal.SetManualCallOn(true); + break; } UnHandleItemPick(); }