@@ -2108,10 +2108,10 @@ public override void Update(float elapsedClockSeconds)
21082108 if ( DynamicBrakeCommandStartTime + DynamicBrakeDelayS < Simulator . ClockTime )
21092109 {
21102110 DynamicBrake = true ; // Engage
2111- if ( IsLeadLocomotive ( ) && DynamicBrakeController . CurrentValue > 0 )
2111+ if ( IsLeadLocomotive ( ) && DynamicBrakeController ? . CurrentValue > 0 )
21122112 Simulator . Confirmer . ConfirmWithPerCent ( CabControl . DynamicBrake , DynamicBrakeController . CurrentValue * 100 ) ;
21132113 }
2114- else if ( IsLeadLocomotive ( ) && DynamicBrakeController . CurrentValue > 0 )
2114+ else if ( IsLeadLocomotive ( ) && DynamicBrakeController ? . CurrentValue > 0 )
21152115 Simulator . Confirmer . Confirm ( CabControl . DynamicBrake , CabSetting . On ) ; // Keeping status string on screen so user knows what's happening
21162116 }
21172117 }
@@ -2396,24 +2396,31 @@ protected virtual void UpdateControllers(float elapsedClockSeconds)
23962396 {
23972397 LocalDynamicBrakePercent = TrainBrakeController . TrainDynamicBrakeIntervention * 100 ;
23982398 }
2399- if ( DynamicBrakeController != null && DynamicBrakeController . CurrentValue > 0 )
2399+ if ( DynamicBrakeController != null && ( DynamicBrakeController . CurrentValue > 0 || DynamicBrakeController . UpdateValue > 0 ) )
24002400 {
24012401 float prevValue = DynamicBrakeController . CurrentValue ;
2402+
24022403 if ( DynamicBrake || ! DynamicBrakeControllerSetupLock )
24032404 DynamicBrakeController . Update ( elapsedClockSeconds ) ;
2404- // Dynamic brake is about to be disabled, pause motion of controller to prevent accidental shut-off
2405- if ( DynamicBrakeController . CurrentValue <= 0 )
2405+
2406+ // Dynamic brake is about to be enabled or disabled, pause motion of controller to prevent accidental overshooting
2407+ if ( ( DynamicBrakeController . CurrentValue <= 0 && prevValue > 0 ) || ( DynamicBrakeController . CurrentValue > 0 && prevValue <= 0 ) )
24062408 {
24072409 if ( ! DynamicBrakePause )
24082410 {
24092411 DynamicBrakePause = true ;
2410- StopDynamicBrakeDecrease ( ) ;
2411- DynamicBrakeController . CurrentValue = prevValue ;
2412+ if ( DynamicBrakeController . UpdateValue < 0 )
2413+ {
2414+ StopDynamicBrakeDecrease ( ) ;
2415+ DynamicBrakeController . CurrentValue = prevValue ;
2416+ }
2417+ else if ( DynamicBrakeController . UpdateValue > 0 )
2418+ StopDynamicBrakeIncrease ( ) ;
24122419 }
24132420 else
24142421 DynamicBrakePause = false ;
24152422 }
2416- else if ( DynamicBrakeController . CurrentValue > prevValue )
2423+ else if ( DynamicBrakeController . UpdateValue != 0 )
24172424 DynamicBrakePause = false ;
24182425
24192426 LocalDynamicBrakePercent = Math . Max ( DynamicBrakeController . CurrentValue * 100 , LocalDynamicBrakePercent ) ;
@@ -4100,7 +4107,7 @@ public void SetCombinedHandleValue(float value)
41004107 ThrottleController . IntermediateValue = 0 ;
41014108 }
41024109 // Return to throttling
4103- else if ( ( DynamicBrakeController . CurrentValue <= 0 && value < CombinedControlSplitPosition ) ||
4110+ else if ( ( DynamicBrakeController ? . CurrentValue ?? 0 ) <= 0 ||
41044111 ( CruiseControl != null && ! CruiseControl . DynamicBrakePriority && CruiseControl . SpeedRegMode == CruiseControl . SpeedRegulatorMode . Auto ) )
41054112 {
41064113 SetThrottleValue ( 1 - MathHelper . Clamp ( value , 0 , CombinedControlSplitPosition ) / CombinedControlSplitPosition ) ;
@@ -4120,9 +4127,9 @@ public void SetCombinedHandleValue(float value)
41204127 /// <returns>Combined position into 0-1 range, where arrangement is [[1--throttle--0]split[0--dynamic|airbrake--1]]</returns>
41214128 public float GetCombinedHandleValue ( bool intermediateValue )
41224129 {
4123- float throttleValue = intermediateValue ? ThrottleController . IntermediateValue : ThrottleController . CurrentValue ;
4124- float dynamicsValue = intermediateValue ? DynamicBrakeController . IntermediateValue : DynamicBrakeController . CurrentValue ;
4125- float brakesValue = intermediateValue ? TrainBrakeController . IntermediateValue : TrainBrakeController . CurrentValue ;
4130+ var throttleValue = intermediateValue ? ThrottleController ? . IntermediateValue : ThrottleController ? . CurrentValue ;
4131+ var dynamicsValue = intermediateValue ? DynamicBrakeController ? . IntermediateValue : DynamicBrakeController ? . CurrentValue ;
4132+ var brakesValue = intermediateValue ? TrainBrakeController ? . IntermediateValue : TrainBrakeController ? . CurrentValue ;
41264133
41274134 if ( CruiseControl ? . SpeedRegMode == CruiseControl . SpeedRegulatorMode . Auto )
41284135 {
@@ -4144,14 +4151,14 @@ public float GetCombinedHandleValue(bool intermediateValue)
41444151 if ( CruiseControl != null && CruiseControl . SkipThrottleDisplay && ! CruiseControl . DynamicBrakeCommandHasPriorityOverCruiseControl )
41454152 return CombinedControlSplitPosition ;
41464153 else
4147- return CombinedControlSplitPosition + ( 1 - CombinedControlSplitPosition ) * dynamicsValue ;
4154+ return CombinedControlSplitPosition + ( 1 - CombinedControlSplitPosition ) * ( dynamicsValue ?? 0 ) ;
41484155 }
41494156 else if ( CombinedControlType == CombinedControl . ThrottleAir && throttleValue <= 0 && brakesValue > 0 )
4150- return CombinedControlSplitPosition + ( 1 - CombinedControlSplitPosition ) * brakesValue ;
4157+ return CombinedControlSplitPosition + ( 1 - CombinedControlSplitPosition ) * ( brakesValue ?? 0 ) ;
41514158 else if ( CruiseControl == null )
4152- return CombinedControlSplitPosition * ( 1 - throttleValue ) ;
4159+ return CombinedControlSplitPosition * ( 1 - ( throttleValue ?? 0 ) ) ;
41534160 else if ( CruiseControl . SpeedRegMode == CruiseControl . SpeedRegulatorMode . Manual )
4154- return CombinedControlSplitPosition * ( 1 - throttleValue ) ;
4161+ return CombinedControlSplitPosition * ( 1 - ( throttleValue ?? 0 ) ) ;
41554162 else if ( CruiseControl . UseThrottleAsSpeedSelector )
41564163 return CombinedControlSplitPosition * ( 1 - ( CruiseControl . SelectedSpeedMpS / MaxSpeedMpS ) ) ;
41574164 else if ( CruiseControl . UseThrottleAsForceSelector && CruiseControl . UseThrottleInCombinedControl )
@@ -4729,6 +4736,8 @@ public void StartDynamicBrakeIncrease(float? target)
47294736 // Only allow increasing dynamic brake if dynamic braking is off, there's no setup lock, or dynamic braking is already active
47304737 if ( DynamicBrake || ! DynamicBrakeControllerSetupLock || DynamicBrakeController . CurrentValue <= 0 )
47314738 {
4739+ float prevValue = DynamicBrakeController . CurrentValue ;
4740+
47324741 DynamicBrakeController . StartIncrease ( target ) ;
47334742
47344743 AlerterReset ( TCSEvent . DynamicBrakeChanged ) ;
@@ -4738,6 +4747,12 @@ public void StartDynamicBrakeIncrease(float? target)
47384747 StopDynamicBrakeIncrease ( ) ;
47394748 Simulator . Confirmer . ConfirmWithPerCent ( CabControl . DynamicBrake , DynamicBrakeController . CurrentValue * 100 ) ;
47404749 }
4750+ // If this is the first application of dynamics, pause movement to prevent accidental over-application
4751+ else if ( DynamicBrakeController . CurrentValue > 0 && prevValue <= 0 )
4752+ {
4753+ DynamicBrakePause = true ;
4754+ StopDynamicBrakeIncrease ( ) ;
4755+ }
47414756 }
47424757 }
47434758
@@ -4865,7 +4880,8 @@ public void SetDynamicBrakePercentWithSound(float percent)
48654880
48664881 public bool CheckDisableDynamicBrake ( )
48674882 {
4868- if ( DynamicBrakeController . CurrentValue <= 0 )
4883+ // Only disable the dynamic brake if the lever is in the off position and the controller isn't trying to increase
4884+ if ( DynamicBrakeController . CurrentValue <= 0 && DynamicBrakeController . UpdateValue <= 0 )
48694885 {
48704886 StopDynamicBrakeDecrease ( ) ;
48714887 Simulator . Confirmer . Confirm ( CabControl . DynamicBrake , CabSetting . Off ) ;
0 commit comments