internal static void update(ElapseData data) { currentTime = data.TotalTime.Seconds; if (ScheduleResetTimer) { ResetTimerMethod(); ScheduleResetTimer = false; } if (DSDDisableOnTrainStop && data.Vehicle.Speed.KilometersPerHour < 1) { ResetTimerMethod(); } if (DSDTimerBrakeExceeded) { if (data.Vehicle.Speed.KilometersPerHour > 1) { data.Handles.PowerNotch = 0; data.Handles.BrakeNotch = SafetySystem.BrakeNotches + 1; } else { DSDTimerBrakeExceeded = false; } } if (DSDTimerTimeout != 0 && DSDTimer > DSDTimerTimeout) { if (DSDTimer < DSDTimerBrakeTimeout) { SoundManager.Play(ATSSoundManager.DSDTimerExceeded, 1.0, 1.0, true); } else if (DSDTimer > DSDTimerBrakeTimeout) { if (DSDTimerBrakeTimeout != DSDTimerTimeout) { DSDTimerBrakeExceeded = true; } SoundManager.Stop(ATSSoundManager.DSDTimerExceeded); SoundManager.Play(ATSSoundManager.DSDTimerBrake, 1.0, 1.0, true); } } else { DSDTimerExceeded = false; SoundManager.Stop(ATSSoundManager.DSDTimerExceeded); SoundManager.Stop(ATSSoundManager.DSDTimerBrake); } DSDTimer = data.TotalTime.Seconds - DSDLastTimer; }
/// <summary>Call this function from the traction manager to attempt to reset a Vigilante intervention</summary> internal void VigilanteReset() { if (Train.CurrentSpeed == 0 && VigilanteState == VigilanteStates.EbApplied) { if (SCMT.tpwswarningsound != -1) { SoundManager.Stop(SCMT.tpwswarningsound); } Train.TractionManager.ResetBrakeApplication(); SCMT.spiarossi_act = false; VigilanteState = VigilanteStates.None; } }
/// <summary>This function is called from the traction manager when the TPWS reset key is pressed.</summary> internal void tpwsresetkey() { if (trainstop == true && this.Enabled == true) { if (flagbrake == true) { SetIndicator(ref TraintripIndicator, 1); SetIndicator(ref BrakeDemandIndicator, 1); Train.TractionManager.ResetBrakeApplication(); //Something is a little funnny here //This would appear to reset the lights instantly? SetIndicator(ref TraintripIndicator, 0); SetIndicator(ref BrakeDemandIndicator, 0); if (beacon_type == 44003) { beacon_type = 44004; } if (tpwswarningsound != -1) { SoundManager.Stop(tpwswarningsound); } flagbrake = false; flagriarmo = false; SpiaRossiTimer.TimerActive = false; spiarossi_act = false; //flagspiarossi = false; ??? } else { SetIndicator(ref BrakeDemandIndicator, 1); if (flagriarmo == true) { flagriarmo = false; Train.TractionManager.ResetBrakeApplication(); SetIndicator(ref BrakeDemandIndicator, 0); trainstop = false; if (beacon_type == 44003) { beacon_type = 44004; } if (tpwswarningsound != -1) { SoundManager.Stop(tpwswarningsound); } SpiaRossiTimer.TimerActive = false; spiarossi_act = false; } } } }
/// <summary>Is called every frame.</summary> /// <param name="data">The data.</param> /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param> internal override void Elapse(ElapseData data, ref bool blocking) { if (this.Enabled) { CurrentVehicleState = data.Vehicle; if (NextSignalLocation < double.MaxValue) { double distance = NextSignalLocation - data.Vehicle.Location; if (distance < 350.0) { if (NextSignalAspect < CurrentAspect) { AcknowledgementCountdown = 7.0; } else if (NextSignalAspect > CurrentAspect && EBApplied != false) { if (UpgradeSound != -1) { SoundManager.Play(UpgradeSound, 1.0, 1.0, false); } } CurrentAspect = NextSignalAspect; NextSignalLocation = double.MaxValue; } } if (data.ElapsedTime.Seconds > 0.0 & data.ElapsedTime.Seconds < 1.0) { if (EmergencyBrakeCountdown > 0.0) { EmergencyBrakeCountdown -= data.ElapsedTime.Seconds; if (EmergencyBrakeCountdown < 0.0) { EBApplied = false; CurrentAspect = PendingAspect; EmergencyBrakeCountdown = 0.0; AcknowledgementCountdown = 0.0; Train.TractionManager.ResetBrakeApplication(); } else { EBApplied = true; Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches + 1, "Brake application demanded by the CAWS system"); } } else if (AcknowledgementCountdown > 0.0) { AcknowledgementPending = true; AcknowledgementCountdown -= data.ElapsedTime.Seconds; if (AcknowledgementCountdown < 0.0) { AcknowledgementCountdown = 0.0; EmergencyBrakeCountdown = 60.0; AcknowledgementPending = false; } } } //Panel Indicators if (AspectIndicator != -1) { this.Train.Panel[AspectIndicator] = CurrentAspect; if (EBApplied == true) { this.Train.Panel[AspectIndicator] = 0; } } if (AcknowlegementIndicator != -1) { if (AcknowledgementPending == true) { this.Train.Panel[AcknowlegementIndicator] = 1; } else { this.Train.Panel[AcknowlegementIndicator] = 0; } } if (EBIndicator != -1) { if (EBApplied == true) { this.Train.Panel[EBIndicator] = 1; } else { this.Train.Panel[EBIndicator] = 0; } } //Sounds if (DowngradeSound != -1) { if (AcknowledgementPending == true) { SoundManager.Play(DowngradeSound, 1.0, 1.0, true); } else { SoundManager.Stop(DowngradeSound); } } } }
/// <summary>Is called every frame.</summary> /// <param name="data">The data.</param> /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param> internal override void Elapse(ElapseData data, ref bool blocking) { //Required to reset the max notch before each frame this.Train.TractionManager.SetMaxPowerNotch(this.Train.Specs.PowerNotches, false); //If reverser is put into neutral when moving, block the gears if (reversercontrol != 0 && Train.CurrentSpeed > 0 && Train.Handles.Reverser == 0) { Train.DieselEngine.gearsblocked = true; } if (!nogears) { //Set gear ratio for current gear if (CurrentGear == 0) { gearratio = 0; } else if (CurrentGear <= geararray.Length) { gearratio = geararray[CurrentGear - 1]; } else { gearratio = geararray[geararray.Length - 1]; } //Set fade in ratio for current gear if (CurrentGear == 0) { fadeinratio = 0; } else if (CurrentGear <= gearfadeinarray.Length) { fadeinratio = gearfadeinarray[CurrentGear - 1]; } else { fadeinratio = gearfadeinarray[gearfadeinarray.Length - 1]; } //Set fade out ratio for current gear if (CurrentGear == 0) { fadeoutratio = 0; } else if (CurrentGear >= gearfadeoutarray.Length) { fadeoutratio = gearfadeoutarray[CurrentGear - 1]; } else { fadeoutratio = gearfadeoutarray[gearfadeoutarray.Length - 1]; } //If the fade in and fade out ratios would make this gear not work, set them both to zero if (fadeinratio + fadeoutratio >= 1000) { fadeinratio = 0; fadeoutratio = 0; } //Set current revolutions per minute currentrevs = Math.Max(0, Math.Min(1000, Train.CurrentSpeed * gearratio)); //Now calculate the maximumum power notch int power_limit; if (currentrevs < fadeinratio) { power_limit = (int)((float)currentrevs / fadeinratio * this.Train.Specs.PowerNotches); } else if (currentrevs > 1000 - fadeoutratio) { power_limit = (int)(this.Train.Specs.PowerNotches - (float)(currentrevs - (1000 - fadeoutratio)) / fadeoutratio * this.Train.Specs.PowerNotches); } else { power_limit = this.Train.Specs.PowerNotches; } //Next we need to set the gears //Manual gears are handled in the KeyUp function //Automatic gears are handled here if (this.Train.TractionManager.AutomaticAdvancedFunctions == true) { if (Train.DieselEngine.gearsblocked == true) { power_limit = 0; //Stop, drop to N with no power applied and the gears will unblock if (Train.CurrentSpeed == 0 && Train.Handles.Reverser == 0 && Train.Handles.PowerNotch == 0) { Train.DieselEngine.gearsblocked = false; } } //Test if all handles are in a position for a gear to be activated if (Train.Handles.Reverser != 0 && Train.Handles.PowerNotch != 0 && Train.Handles.BrakeNotch == 0) { gearplayed = false; //If we aren't in gear & gears aren't blocked if (CurrentGear == 0 && Train.DieselEngine.gearsblocked == false) { CurrentGear = 1; gearchange(); Train.DieselEngine.gearloop = false; Train.DieselEngine.gearlooptimer = 0.0; } if (currentrevs > Math.Min((2000 - fadeoutratio) / 2, 800) && CurrentGear < totalgears - 1) { CurrentGear++; gearchange(); Train.DieselEngine.gearloop = false; Train.DieselEngine.gearlooptimer = 0.0; } //Change down else if (currentrevs < Math.Max(fadeinratio / 2, 200) && CurrentGear > 1) { CurrentGear--; gearchange(); Train.DieselEngine.gearloop = false; Train.DieselEngine.gearlooptimer = 0.0; } } //If we're stopped with the power off, drop out of gear else if (Train.Handles.Reverser == 0 && Train.Handles.PowerNotch == 0) { CurrentGear = 0; if (gearplayed == false) { gearchange(); gearplayed = true; } } } //Finally set the power notch if (CurrentGear != 0) { this.Train.TractionManager.SetMaxPowerNotch(Math.Min(power_limit, this.Train.Handles.PowerNotch), false); //data.Handles.PowerNotch = Math.Min(power_limit, this.Train.Handles.PowerNotch); } else { this.Train.TractionManager.SetMaxPowerNotch(0, false); } //If revving the engine is allowed in neutral if (allowneutralrevs == 1 && (CurrentGear == 0 || Train.Handles.Reverser == 0)) { currentrevs = (int)Math.Abs((1000 / Train.Specs.PowerNotches) * Train.Handles.PowerNotch * 0.9); //Play sounds based upon revs state if (revsupsound != -1 && revsdownsound != -1 && motorsound != -1) { double pitch = (double)Train.Handles.PowerNotch / (double)Train.Specs.PowerNotches; if (currentrevs > 0 && currentrevs > previousrevs) { SoundManager.Play(motorsound, 0.8, pitch, true); SoundManager.Play(revsupsound, 1.0, 1.0, false); SoundManager.Stop(revsdownsound); } else if (currentrevs >= 0 && currentrevs < previousrevs) { SoundManager.Play(motorsound, 0.8, pitch, true); SoundManager.Play(revsdownsound, 1.0, 1.0, false); SoundManager.Stop(revsupsound); } else if (currentrevs == 0) { SoundManager.Stop(revsupsound); SoundManager.Stop(revsdownsound); SoundManager.Stop(motorsound); } previousrevs = currentrevs; } } //Check we've got a maximum temperature and a heating part if (overheat != 0 && heatingpart != 0) { this.heatingtimer += data.ElapsedTime.Milliseconds; if (heatingpart == 0 | overheat == 0) { //No heating part or overheat temperature not set this.temperature = 0.0; this.heatingtimer = 0.0; } else if (heatingpart == 1) { //Heats based upon power notch if (this.heatingtimer > 1000) { this.heatingtimer = 0.0; if (Train.Handles.PowerNotch == 0) { currentheat = heatingarray[0]; } else if (Train.Handles.PowerNotch < heatingarray.Length) { currentheat = heatingarray[Train.Handles.PowerNotch]; } else { currentheat = heatingarray[heatingarray.Length - 1]; } temperature += currentheat; } } else { //Heats based upon RPM int revspercentage = currentrevs / 100; if (this.heatingtimer > 1000) { this.heatingtimer = 0.0; if (revspercentage == 0) { currentheat = heatingarray[0]; } else if (revspercentage < heatingarray.Length) { currentheat = heatingarray[revspercentage]; } else { currentheat = heatingarray[heatingarray.Length - 1]; } temperature += currentheat; } } //Keep temperature below max & above zero if (temperature > overheat) { temperature = overheat; if (overheatresult == 1 && Train.TractionManager.EngineOverheated == false) { Train.TractionManager.DemandPowerCutoff("Power cutoff was demanded due to the diesel engine overheating"); Train.TractionManager.EngineOverheated = true; } } else if (temperature < overheat && temperature > 0) { Train.TractionManager.ResetPowerCutoff(); Train.TractionManager.EngineOverheated = false; } else if (temperature < 0) { temperature = 0; } } } //This section of code uses fuel fuelusetimer += data.ElapsedTime.Milliseconds; if (fuelusetimer > 1000) { fuelusetimer = 0.0; if (data.Handles.PowerNotch < fuelarray.Length) { fuel -= fuelarray[data.Handles.PowerNotch]; } else { fuel -= fuelarray[fuelarray.Length - 1]; } if (fuel <= 0) { fuel = 0; } } //This section of code fills our fuel tanks if (fuelling == true) { fuellingtimer += data.ElapsedTime.Milliseconds; if (fuellingtimer > 1000) { fuellingtimer = 0.0; fuel += (int)fuelfillspeed; } if (fuel > fuelcapacity) { fuel = (int)fuelcapacity; } } //This section of code runs the gear loop sound if (gearloopsound != -1 && CurrentGear != 0) { //Start the timer gearlooptimer += data.ElapsedTime.Milliseconds; if (gearlooptimer > gearlooptime && gearloop == false) { //Start playback and reset our conditions gearloop = true; SoundManager.Play(gearloopsound, 1.0, 1.0, true); } else if (gearloop == false) { SoundManager.Stop(gearloopsound); } } else if (gearloopsound != -1 && CurrentGear == 0) { SoundManager.Stop(gearloopsound); } { //Panel Variables //Ammeter if (Ammeter.PanelIndex != -1) { if (Train.TractionManager.PowerCutoffDemanded == true) { this.Train.Panel[Ammeter.PanelIndex] = 0; } else { this.Train.Panel[Ammeter.PanelIndex] = Ammeter.GetCurrentValue(); } } if (!nogears) { if (gearindicator != -1) { this.Train.Panel[(gearindicator)] = CurrentGear; } if (tachometer != -1) { this.Train.Panel[(tachometer)] = currentrevs; } } if (automaticindicator != -1) { if (this.Train.TractionManager.AutomaticAdvancedFunctions == false) { this.Train.Panel[(automaticindicator)] = 0; } else { this.Train.Panel[(automaticindicator)] = 1; } } if (thermometer != -1) { this.Train.Panel[(thermometer)] = (int)temperature; } if (overheatindicator != -1) { if (temperature > overheatwarn) { this.Train.Panel[(overheatindicator)] = 1; } else { this.Train.Panel[(overheatindicator)] = 0; } } if (fuelindicator != -1) { this.Train.Panel[(fuelindicator)] = fuel; } if (fuelfillindicator != -1) { if (fuelling == true) { this.Train.Panel[(fuelfillindicator)] = 1; } } } { //Sounds if (overheatalarm != -1) { if (temperature > overheatwarn) { SoundManager.Play(overheatalarm, 1.0, 1.0, true); } else { SoundManager.Stop(overheatalarm); } } } }
/// <summary>Is called every frame.</summary> /// <param name="data">The data.</param> /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param> internal override void Elapse(ElapseData data, ref bool blocking) { OverspeedDevice.Update(data.ElapsedTime.Milliseconds); { //Deadman's Handle if (deadmanshandle != 0) { //Initialise and set the start state if (Train.StartupSelfTestManager != null && Train.StartupSelfTestManager.SequenceState != StartupSelfTestManager.SequenceStates.Initialised) { //Startup self-test has not been performed, no systems active DeadmansHandleState = DeadmanStates.None; } else if (Train.ElectricEngine != null && Train.ElectricEngine.FrontPantograph.State != PantographStates.OnService && Train.ElectricEngine.RearPantograph.State != PantographStates.OnService && Train.CurrentSpeed == 0) { //Stationary with no available pantographs DeadmansHandleState = DeadmanStates.None; } else if (vigilanceinactivespeed == -2 && Train.Handles.Reverser == 0) { //Set to no action if inactive speed is -2 & in neutral DeadmansHandleState = DeadmanStates.None; } else if (vigilanceinactivespeed == -2 && Train.Handles.Reverser != 0) { //Otherwise set to the timer state DeadmansHandleState = DeadmanStates.OnTimer; } else if (vigilanceinactivespeed == -1) { //If inactive speed is -1 always set to the timer state DeadmansHandleState = DeadmanStates.OnTimer; } else if (Train.CurrentSpeed < vigilanceinactivespeed && DeadmansHandleState == DeadmanStates.OnTimer) { //If train speed is than the inactive speed and we're in the timer mode //Set to no action DeadmansHandleState = DeadmanStates.None; } else if (Train.CurrentSpeed > vigilanceinactivespeed && DeadmansHandleState == DeadmanStates.None) { //Set to the timer state DeadmansHandleState = DeadmanStates.OnTimer; } //Calculate vigilance time from the array int vigilancelength = vigilancearray.Length; if (Train.Handles.PowerNotch == 0) { vigilancetime = vigilancearray[0]; } else if (Train.Handles.PowerNotch <= vigilancelength) { vigilancetime = vigilancearray[(Train.Handles.PowerNotch - 1)]; } else { vigilancetime = vigilancearray[(vigilancelength - 1)]; } if (DeadmansHandleState == DeadmanStates.OnTimer) { //Reset other timers deadmansalarmtimer = 0.0; deadmansbraketimer = 0.0; //Elapse Timer this.deadmanstimer += data.ElapsedTime.Milliseconds; if (this.deadmanstimer > vigilancetime) { DeadmansHandleState = DeadmanStates.TimerExpired; } } else if (DeadmansHandleState == DeadmanStates.TimerExpired) { //Start the next timer deadmansalarmtimer += data.ElapsedTime.Milliseconds; if (deadmansalarmtimer > vigilancedelay1) { DeadmansHandleState = DeadmanStates.OnAlarm; } } else if (DeadmansHandleState == DeadmanStates.OnAlarm) { //Trigger the alarm sound and move on if (vigilancealarm != -1) { SoundManager.Play(vigilancealarm, 1.0, 1.0, true); } DeadmansHandleState = DeadmanStates.AlarmTimer; } else if (DeadmansHandleState == DeadmanStates.AlarmTimer) { //Start the next timer deadmansbraketimer += data.ElapsedTime.Milliseconds; if (deadmansbraketimer > vigilancedelay2) { DeadmansHandleState = DeadmanStates.BrakesApplied; } } else if (DeadmansHandleState == DeadmanStates.BrakesApplied) { //Demand brake application Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches + 1, "Brake application demanded by the deadman's handle"); //If we auto-release on coming to a full-stop if (AutoRelease == true && Train.CurrentSpeed == 0) { Train.TractionManager.ResetBrakeApplication(); deadmansalarmtimer = 0.0; deadmansbraketimer = 0.0; deadmanstimer = 0.0; DeadmansHandleState = DeadmanStates.OnTimer; } } } } if (Train.SCMT != null) { if (vigilanteEnabled == true && SCMT.testscmt == 4) { if (Train.CurrentSpeed > 2 && VigilanteState == VigilanteStates.None) { VigilanteState = VigilanteStates.AlarmSounding; } else if (VigilanteState == VigilanteStates.AlarmSounding) { if (vigilancealarm != -1) { SoundManager.Play(vigilancealarm, 1.0, 1.0, true); } if (Train.CurrentSpeed != 0) { vigilanteTimer += data.ElapsedTime.Milliseconds; if (vigilanteTimer > vigilancedelay1) { VigilanteState = VigilanteStates.EbApplied; } } } else if (VigilanteState == VigilanteStates.EbApplied) { vigilanteTimer = 0.0; Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches + 1, "Brake application demanded by the SCMT vigilante"); if (vigilancealarm != -1) { SoundManager.Stop(vigilancealarm); } if (SCMT.tpwswarningsound != -1) { SoundManager.Play(SCMT.tpwswarningsound, 1.0, 1.0, true); } } else if (VigilanteState == VigilanteStates.OnService) { vigilanteTimer = 0.0; if (Train.CurrentSpeed == 0) { VigilanteState = VigilanteStates.None; } } } } { //Set Panel Variables if (DRAIndicator != -1) { if (Train.drastate == true) { this.Train.Panel[(DRAIndicator)] = 1; } else { this.Train.Panel[(DRAIndicator)] = 0; } } if (vigilancelamp != -1) { if (DeadmansHandleState == DeadmanStates.None || DeadmansHandleState == DeadmanStates.OnTimer) { this.Train.Panel[(vigilancelamp)] = 0; } else { this.Train.Panel[(vigilancelamp)] = 1; } if (vigilanteEnabled == true) { if (VigilanteState == VigilanteStates.AlarmSounding || VigilanteState == VigilanteStates.EbApplied) { this.Train.Panel[(vigilancelamp)] = 1; } else { this.Train.Panel[(vigilancelamp)] = 0; } } } } }
internal static void PlayLoop(VirtualKeys key) { VirtualKeys virtualKey = key; switch (virtualKey) { case VirtualKeys.S: if (SoundManager.IsPlaying(Keysloop[10])) { SoundManager.Stop(Keysloop[10]); } else { SoundManager.Play(Keysloop[10], 1.0, 1.0, true); } break; case VirtualKeys.A1: if (SoundManager.IsPlaying(Keysloop[37])) { SoundManager.Stop(Keysloop[37]); } else { SoundManager.Play(Keysloop[37], 1.0, 1.0, true); } break; case VirtualKeys.A2: if (SoundManager.IsPlaying(Keysloop[36])) { SoundManager.Stop(Keysloop[36]); } else { SoundManager.Play(Keysloop[36], 1.0, 1.0, true); } break; case VirtualKeys.B1: if (SoundManager.IsPlaying(Keysloop[35])) { SoundManager.Stop(Keysloop[35]); } else { SoundManager.Play(Keysloop[35], 1.0, 1.0, true); } break; case VirtualKeys.B2: if (SoundManager.IsPlaying(Keysloop[34])) { SoundManager.Stop(Keysloop[34]); } else { SoundManager.Play(Keysloop[34], 1.0, 1.0, true); } break; case VirtualKeys.C1: if (SoundManager.IsPlaying(Keysloop[33])) { SoundManager.Stop(Keysloop[33]); } else { SoundManager.Play(Keysloop[33], 1.0, 1.0, true); } break; case VirtualKeys.C2: if (SoundManager.IsPlaying(Keysloop[32])) { SoundManager.Stop(Keysloop[32]); } else { SoundManager.Play(Keysloop[32], 1.0, 1.0, true); } break; case VirtualKeys.D: if (SoundManager.IsPlaying(Keysloop[2])) { SoundManager.Stop(Keysloop[2]); } else { SoundManager.Play(Keysloop[2], 1.0, 1.0, true); } break; case VirtualKeys.E: if (SoundManager.IsPlaying(Keysloop[3])) { SoundManager.Stop(Keysloop[3]); } else { SoundManager.Play(Keysloop[3], 1.0, 1.0, true); } break; case VirtualKeys.F: if (SoundManager.IsPlaying(Keysloop[4])) { SoundManager.Stop(Keysloop[4]); } else { SoundManager.Play(Keysloop[4], 1.0, 1.0, true); } break; case VirtualKeys.G: if (SoundManager.IsPlaying(Keysloop[5])) { SoundManager.Stop(Keysloop[5]); } else { SoundManager.Play(Keysloop[5], 1.0, 1.0, true); } break; case VirtualKeys.H: if (SoundManager.IsPlaying(Keysloop[6])) { SoundManager.Stop(Keysloop[6]); } else { SoundManager.Play(Keysloop[6], 1.0, 1.0, true); } break; case VirtualKeys.I: if (SoundManager.IsPlaying(Keysloop[7])) { SoundManager.Stop(Keysloop[7]); } else { SoundManager.Play(Keysloop[7], 1.0, 1.0, true); } break; case VirtualKeys.J: if (SoundManager.IsPlaying(Keysloop[8])) { SoundManager.Stop(Keysloop[8]); } else { SoundManager.Play(Keysloop[8], 1.0, 1.0, true); } break; case VirtualKeys.K: if (SoundManager.IsPlaying(Keysloop[9])) { SoundManager.Stop(Keysloop[9]); } else { SoundManager.Play(Keysloop[9], 1.0, 1.0, true); } break; case VirtualKeys.L: if (SoundManager.IsPlaying(Keysloop[0])) { SoundManager.Stop(Keysloop[0]); } else { SoundManager.Play(Keysloop[0], 1.0, 1.0, true); } break; case VirtualKeys.EngineStart: if (SoundManager.IsPlaying(Keysloop[31])) { SoundManager.Stop(Keysloop[31]); } else { SoundManager.Play(Keysloop[31], 1.0, 1.0, true); } break; case VirtualKeys.EngineStop: if (SoundManager.IsPlaying(Keysloop[30])) { SoundManager.Stop(Keysloop[30]); } else { SoundManager.Play(Keysloop[30], 1.0, 1.0, true); } break; case VirtualKeys.Blowers: if (SoundManager.IsPlaying(Keysloop[29])) { SoundManager.Stop(Keysloop[29]); } else { SoundManager.Play(Keysloop[29], 1.0, 1.0, true); } break; case VirtualKeys.ExhaustSteamInjector: if (SoundManager.IsPlaying(Keysloop[28])) { SoundManager.Stop(Keysloop[28]); } else { SoundManager.Play(Keysloop[28], 1.0, 1.0, true); } break; case VirtualKeys.IncreaseCutoff: if (SoundManager.IsPlaying(Keysloop[27])) { SoundManager.Stop(Keysloop[27]); } else { SoundManager.Play(Keysloop[27], 1.0, 1.0, true); } break; case VirtualKeys.DecreaseCutoff: if (SoundManager.IsPlaying(Keysloop[26])) { SoundManager.Stop(Keysloop[26]); } else { SoundManager.Play(Keysloop[26], 1.0, 1.0, true); } break; case VirtualKeys.FillFuel: if (SoundManager.IsPlaying(Keysloop[25])) { SoundManager.Stop(Keysloop[25]); } else { SoundManager.Play(Keysloop[25], 1.0, 1.0, true); } break; case VirtualKeys.GearDown: if (SoundManager.IsPlaying(Keysloop[24])) { SoundManager.Stop(Keysloop[24]); } else { SoundManager.Play(Keysloop[24], 1.0, 1.0, true); } break; case VirtualKeys.GearUp: if (SoundManager.IsPlaying(Keysloop[23])) { SoundManager.Stop(Keysloop[23]); } else { SoundManager.Play(Keysloop[23], 1.0, 1.0, true); } break; case VirtualKeys.LeftDoors: if (SoundManager.IsPlaying(Keysloop[22])) { SoundManager.Stop(Keysloop[22]); } else { SoundManager.Play(Keysloop[22], 1.0, 1.0, true); } break; case VirtualKeys.RightDoors: if (SoundManager.IsPlaying(Keysloop[21])) { SoundManager.Stop(Keysloop[21]); } else { SoundManager.Play(Keysloop[21], 1.0, 1.0, true); } break; case VirtualKeys.LiveSteamInjector: if (SoundManager.IsPlaying(Keysloop[20])) { SoundManager.Stop(Keysloop[20]); } else { SoundManager.Play(Keysloop[20], 1.0, 1.0, true); } break; case VirtualKeys.LowerPantograph: if (SoundManager.IsPlaying(Keysloop[19])) { SoundManager.Stop(Keysloop[19]); } else { SoundManager.Play(Keysloop[19], 1.0, 1.0, true); } break; case VirtualKeys.RaisePantograph: if (SoundManager.IsPlaying(Keysloop[18])) { SoundManager.Stop(Keysloop[18]); } else { SoundManager.Play(Keysloop[18], 1.0, 1.0, true); } break; case VirtualKeys.MainBreaker: if (SoundManager.IsPlaying(Keysloop[17])) { SoundManager.Stop(Keysloop[17]); } else { SoundManager.Play(Keysloop[17], 1.0, 1.0, true); } break; case VirtualKeys.WiperSpeedDown: if (SoundManager.IsPlaying(Keysloop[16])) { SoundManager.Stop(Keysloop[20]); } else { SoundManager.Play(Keysloop[16], 1.0, 1.0, true); } break; case VirtualKeys.WiperSpeedUp: if (SoundManager.IsPlaying(Keysloop[15])) { SoundManager.Stop(Keysloop[20]); } else { SoundManager.Play(Keysloop[15], 1.0, 1.0, true); } break; default: break; } }
/// <summary>Is called every frame.</summary> /// <param name="data">The data.</param> /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param> internal override void Elapse(ElapseData data, ref bool blocking) { //The Western requires special handling- Return if AWS has not been switched in from the cab if (Train.WesternDiesel != null && Train.AWS.Enabled == false) { if (Train.WesternDiesel.StartupManager.StartupState == WesternStartupManager.SequenceStates.AWSOnline) { //Enable AWS if the Western has switched it online Train.AWS.Enabled = true; } else { //Otherwise, we don't want to do any processing so back out //Doing anything else messes up the timing of the self-test sequence return; } } if (MySequenceState == SequenceStates.Pending) { Train.MasterSwitch = false; Train.selftest = false; /* Check the reverser state to see if the master switch has been set to on */ if (Train.Handles.Reverser == 1 || Train.Handles.Reverser == -1) { MySequenceState = SequenceStates.WaitingToStart; } } else if (MySequenceState == SequenceStates.WaitingToStart) { if (Train.Handles.Reverser == 0) { /* Turn the master switch on, and begin the startup and self-test procedure */ Train.selftest = true; Train.MasterSwitch = true; MySequenceState = SequenceStates.Initialising; /* Start the in-cab blower */ // if (PowerSupplyManager.SelectedPowerSupply != Plugin.MainBattery) { // Plugin.Fan.Reset(); // } /* Place the Automatic Warning System, and Train Protection and Warning System, into self-test mode */ Train.AWS.SelfTest(); Train.TPWS.SelfTest(); } } else if (MySequenceState != SequenceStates.Initialised) { /* Make sure that the master switch is on after reinitialisation */ Train.selftest = true; Train.MasterSwitch = true; /* Hold the brakes on until the AWS button is depressed */ if (MySequenceState == SequenceStates.AwaitingDriverInteraction) { Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches, "Brake application was demanded by the startup self-test sequence"); } else if (MySequenceState == SequenceStates.Finalising) { if (Train.AWS.WarningSound != -1) { if (SoundManager.IsPlaying(Train.AWS.WarningSound)) { SoundManager.Stop(Train.AWS.WarningSound); } } MySequenceState = SequenceStates.Initialised; Train.TractionManager.ResetBrakeApplication(); } /* Lastly, decrement the timer */ if (MySequenceState == SequenceStates.Initialising) { MySequenceTimer = MySequenceTimer - (int)data.ElapsedTime.Milliseconds; if (MySequenceTimer < 0) { MySequenceTimer = 0; MySequenceState = SequenceStates.AwaitingDriverInteraction; } } } else { if (this.firststart == false) { this.firststart = true; if (Train.AWS.Enabled == true) { Train.AWS.OnStartUp(SunflowerState); } if (Train.TPWS.Enabled) { Train.TPWS.Initialize(InitializationModes.OnService); } } } }
internal override void KeyDown(VirtualKeys key) { if (key == Train.CurrentKeyConfiguration.AWSKey) { awsKeyPressed = true; if (tpwsStartupTest == 2) { awsIndicatorLit = true; SoundManager.Stop(awsWarningSound); if (startupTest == 2) { SoundManager.Stop(awsClearSound); brakeDemandIndicatorLit = false; stopOverrideIndicatorLit = false; tpwsIndicator3Lit = false; } tpwsStartupTest = 0; } else if (awsTimer.TimerActive && awsTimer.TimeElapsed != -2) { awsIndicatorLit = true; SoundManager.Stop(awsWarningSound); awsTimer.TimerActive = false; } else if (awsTimer.TimeElapsed != -2 && (Train.CurrentSpeed == 0 || awsBrakeCancel != 0) && awsStop) { if (awsBrakeCancel == 1) { awsRelease = true; } else { Train.TractionManager.DemandBrakeApplication(Train.Specs.BrakeNotches + 1, "Brake application demanded by the LU Trainstop system self-test."); awsIndicatorLit = false; SoundManager.Stop(awsWarningSound); awsTimer.TimerActive = false; awsStop = false; } } if (key == Train.CurrentKeyConfiguration.SafetyKey && tpwsTrainstop) { brakeDemandIndicatorLit = true; if (tpwsBrakeCancel != 0 || (Train.CurrentSpeed == 0 && stopTimer.TimeElapsed > tpwsStopDelay * 1000)) { if (tpwsBrakeCancel == 1) { tpwsRelease = true; } else { Train.TractionManager.DemandBrakeApplication(Train.Specs.BrakeNotches + 1, "EB Brake application demanded by the LU Trainstop system."); brakeDemandIndicatorLit = false; tpwsTrainstop = false; } SoundManager.Stop(tpwsWarningSound); } } if (key == Train.CurrentKeyConfiguration.TPWSOverride && tpwsTrainstop == false && tpwsStartupTest == 0) { if (overrideTimer.TimerActive == false) { overrideTimer.TimeElapsed = 0; //BlinkIndicator(stopOverride, 1); } else { overrideTimer.TimerActive = false; stopOverrideIndicatorLit = false; } } } }
/// <summary>Is called every frame.</summary> /// <param name="data">The data.</param> /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param> internal override void Elapse(ElapseData data, ref bool blocking) { { if (TripcockActive == true) { if (DeadmansDeviceActive == true) { //We can accelerate! //If the throttle button is held down, then the train will accelerate towards the selected speed switch (CurrentSpeed) { case SelectorSpeeds.B25: data.Handles.Reverser = -1; if (Train.CurrentSpeed < 25 && Train.TractionManager.PowerCutoffDemanded == false) { data.Handles.PowerNotch = Train.Specs.PowerNotches; } else { data.Handles.PowerNotch = 0; } break; case SelectorSpeeds.B15: data.Handles.Reverser = -1; if (Train.CurrentSpeed < 15 && Train.TractionManager.PowerCutoffDemanded == false) { data.Handles.PowerNotch = Train.Specs.PowerNotches; } else { data.Handles.PowerNotch = 0; } break; case SelectorSpeeds.Neutral: data.Handles.Reverser = 0; data.Handles.PowerNotch = 0; break; case SelectorSpeeds.F15: data.Handles.Reverser = 1; if (Train.CurrentSpeed < 15 && Train.TractionManager.PowerCutoffDemanded == false) { data.Handles.PowerNotch = Train.Specs.PowerNotches; } else { data.Handles.PowerNotch = 0; } break; case SelectorSpeeds.F25: data.Handles.Reverser = 1; if (Train.CurrentSpeed < 25 && Train.TractionManager.PowerCutoffDemanded == false) { data.Handles.PowerNotch = Train.Specs.PowerNotches; } else { data.Handles.PowerNotch = 0; } break; case SelectorSpeeds.F50: data.Handles.Reverser = 1; if (Train.CurrentSpeed < 50 && Train.TractionManager.PowerCutoffDemanded == false) { data.Handles.PowerNotch = Train.Specs.PowerNotches; } else { data.Handles.PowerNotch = 0; } break; case SelectorSpeeds.F60: data.Handles.Reverser = 1; if (Train.CurrentSpeed < 60 && Train.TractionManager.PowerCutoffDemanded == false) { data.Handles.PowerNotch = Train.Specs.PowerNotches; } else { data.Handles.PowerNotch = 0; } break; case SelectorSpeeds.F70: data.Handles.Reverser = 1; if (Train.CurrentSpeed < 70 && Train.TractionManager.PowerCutoffDemanded == false) { data.Handles.PowerNotch = Train.Specs.PowerNotches; } else { data.Handles.PowerNotch = 0; } break; } } else { //The F92 has a counter for unwanted EB applications if (Train.TractionManager.BrakeInterventionDemanded == false) { EmergencyBrakeCounter++; } //If deadman's device is inactive, apply EB Train.TractionManager.DemandBrakeApplication(Train.Specs.BrakeNotches + 1, "Brake application demanded by the F92"); } } else { //If our tripcock is not currently turned on, then power must be cut off Train.TractionManager.DemandPowerCutoff("Power cutoff demanded by the F92 tripcock"); } //Max speed device if (Train.CurrentSpeed > 70 && Overspeed == false) { //I'm presuming that the overspeed device will also up the EB counter, need to check this.... EmergencyBrakeCounter++; Train.TractionManager.DemandBrakeApplication(Train.Specs.BrakeNotches, "Brake application demanded by the F92 overspeed device"); SoundManager.Play(OverspeedSound, 1.0, 1.0, true); Overspeed = true; } else { if (Overspeed == true) { //Only attempt to reset the brake application once, else this causes log spam Train.TractionManager.ResetBrakeApplication(); SoundManager.Stop(OverspeedSound); Overspeed = false; } } } //Sounds { //If our trainspeed is greater than 50km/h then we should play the curve flange sound if (Train.CurrentSpeed > 50 && CurveFlangeNoise == true) { //Requires fade-in sound SoundManager.Play(CurveFlangeSound, 1.0, 1.0, true); } else { SoundManager.Stop(CurveFlangeSound); //Requires fade-out sound } //This sound is played whilst in tight curves (Rumbling noise) whilst the speed is above 25km/h if (Train.CurrentSpeed > 25 && TightCurveNoise == true) { //Requires fade-in sound SoundManager.Play(TightCurveSound, 1.0, 1.0, true); } else { //Requires fade-out sound SoundManager.Stop(CurveFlangeSound); } } }
/// <summary>Is called every frame.</summary> /// <param name="data">The data.</param> /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param> internal override void Elapse(ElapseData data, ref bool blocking) { if (this.Enabled) { if (this.SafetyState != SafetyStates.Isolated) { if (this.suppressionactive) { /* Cancel any suppression which is in effect, if the train is not within range of the last suppression magnet location */ if (Train.CurrentSpeed > 0) { if (Train.TrainLocation > this.suppressionlocation + 2) { this.suppressionlocation = 0; this.suppressionactive = false; } } else { if (Train.TrainLocation < this.suppressionlocation - 2) { this.suppressionlocation = 0; this.suppressionactive = false; } } } else if (this.MySafetyState == SafetyStates.Primed) { /* An AWS magnet south pole has primed the AWS */ this.SunflowerState = SunflowerStates.Clear; this.detectiontimer = this.detectiontimer + (int)data.ElapsedTime.Milliseconds; if (this.detectiontimer > 1000) { /* No north pole has been detected within the timeout period, so reset the detection timer and issue an AWS warning */ this.detectiontimer = 0; this.MySafetyState = SafetyStates.CancelTimerActive; } } else if (this.MySafetyState == SafetyStates.Clear) { /* The AWS indicates a clear signal */ this.Reset(); this.SunflowerState = SunflowerStates.Clear; if (this.ClearSound != -1) { SoundManager.Play(ClearSound, 1.0, 1.0, false); } if (this.WarningSound != -1) { SoundManager.Stop(WarningSound); } } else if (this.MySafetyState == SafetyStates.CancelTimerActive) { /* An AWS warning has been issued */ if (this.WarningSound != -1) { SoundManager.Play(WarningSound, 1.0, 1.0, true); } this.SunflowerState = SunflowerStates.Clear; this.canceltimer -= (int)data.ElapsedTime.Milliseconds; if (this.canceltimer < 0) { this.canceltimer = 0; this.MySafetyState = SafetyStates.CancelTimerExpired; } } else if (this.MySafetyState == SafetyStates.WarningAcknowledged) { /* An AWS warning was acknowledged in time */ if (this.WarningSound != -1) { SoundManager.Stop(WarningSound); } this.Reset(); } else if (this.MySafetyState == SafetyStates.CancelTimerExpired) { /* An AWS warning was not acknowledged in time */ if (this.WarningSound != -1) { SoundManager.Play(WarningSound, 1.0, 1.0, true); } if (Train.TPWS.Enabled) { Train.TPWS.IssueBrakeDemand(); } else { if (Train.TractionManager.PowerCutoffDemanded == false) { Train.TractionManager.DemandPowerCutoff("Power cutoff was demanded by the AWS due to a warning not being acknowledged in time"); } if (Train.TractionManager.CurrentInterventionBrakeNotch != this.Train.Specs.BrakeNotches + 1) { Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches + 1, "Emergency brakes were demanded by the AWS due to a warning not being acknowledged in time"); } } } else if (this.MySafetyState == SafetyStates.SelfTest) { blinktimer += (int)data.ElapsedTime.Milliseconds; if (blinktimer > 1200) { if (Train.AWS.WarningSound != -1) { if (startuphorntriggered == false) { SoundManager.Play(WarningSound, 1.0, 1.0, true); startuphorntriggered = true; } } } else if (blinktimer > 1000) { this.SunflowerState = SunflowerStates.Clear; } else if (blinktimer > 400) { this.SunflowerState = SunflowerStates.Warn; } } else if (this.MySafetyState == SafetyStates.TPWSAWSBrakeDemandIssued) { /* The TPWS issued an AWS Brake Demand due to the AWS not being acknowledged in time */ if (TPWSWarningSound != -1) { SoundManager.Play(TPWSWarningSound, 1.0, 1.0, true); } } } else if (this.SafetyState == SafetyStates.Isolated) { if (WarningSound != -1) { if (SoundManager.IsPlaying(WarningSound)) { SoundManager.Stop(WarningSound); } } if (TPWSWarningSound != -1) { if (SoundManager.IsPlaying(TPWSWarningSound)) { SoundManager.Stop(TPWSWarningSound); } } this.canceltimer = (int)this.canceltimeout; this.SunflowerState = SunflowerStates.Warn; } /* Set the state of the AWS Sunflower instrument */ if (awsindicator != -1) { if (this.SunflowerState == SunflowerStates.Warn) { this.Train.Panel[awsindicator] = 1; } else { this.Train.Panel[awsindicator] = 0; } } } //Set the state of the cancel button panel index //As this is a physical button, it can be pressed at any time if (CancelButtonIndex != -1) { if (CancelButtonPressed) { this.Train.Panel[CancelButtonIndex] = 1; } else { this.Train.Panel[CancelButtonIndex] = 0; } } }
/// <summary>Is called every frame.</summary> /// <param name="data">The data.</param> /// <param name="blocking">Whether the device is blocked or will block subsequent devices.</param> internal override void Elapse(ElapseData data, ref bool blocking) { //Required to reset the max notch before each frame this.Train.TractionManager.SetMaxPowerNotch(this.Train.Specs.PowerNotches, false); //Check we've got a maximum temperature and a heating part if (overheat != 0 && heatingpart != 0) { this.heatingtimer += data.ElapsedTime.Milliseconds; if (heatingpart == 0 || overheat == 0) { //No heating part or overheat temperature not set this.temperature = 0.0; this.heatingtimer = 0.0; } else if (heatingpart == 1) { //Heats based upon power notch if (this.heatingtimer > 1000) { this.heatingtimer = 0.0; if (Train.Handles.PowerNotch == 0) { currentheat = HeatingRates[0]; } else if (Train.Handles.PowerNotch < HeatingRates.Length) { currentheat = HeatingRates[Train.Handles.PowerNotch]; } else { currentheat = HeatingRates[HeatingRates.Length - 1]; } temperature += currentheat; } } else { //Heats based upon RPM- Not on an electric loco! this.temperature = 0.0; this.heatingtimer = 0.0; } //Keep temperature below max & above zero if (temperature > overheat) { temperature = overheat; if (overheatresult == 1 && Train.TractionManager.EngineOverheated == false) { DemandPowerCutoff("Power cutoff was demanded due to the electric engine overheating"); Train.TractionManager.EngineOverheated = true; } } else if (temperature < overheat && temperature > 0) { if (BreakerTripped == false && ((FrontPantograph.State == PantographStates.Disabled && RearPantograph.State == PantographStates.OnService) || (RearPantograph.State == PantographStates.Disabled && FrontPantograph.State == PantographStates.OnService))) { ResetPowerCutoff("Power cutoff was released due to the electric engine temperature returning to safe levels"); } Train.TractionManager.EngineOverheated = false; } else if (temperature < 0) { temperature = 0; } } { //If we're in a power gap, check whether we have a pickup available if (PowerGap) { int new_power; //First check to see whether the first pickup is in the neutral section if (Train.TrainLocation - PickupLocations[0] > firstmagnet && Train.TrainLocation - PickupLocations[0] < nextmagnet) { //Cycle through the other pickups int j = 0; foreach (int t in PickupLocations) { if (Train.TrainLocation - t < firstmagnet) { j++; } } switch (PowerGapBehaviour) { case PowerGapBehaviour.ProportionalReduction: //Reduce max throttle by percentage of how many pickups are in the gap double throttlemultiplier = (double)j / (double)PickupLocations.Length; new_power = (int)(this.Train.Specs.PowerNotches * throttlemultiplier); this.Train.TractionManager.SetMaxPowerNotch(new_power, false); //data.Handles.PowerNotch = new_power; break; case PowerGapBehaviour.InactiveAny: //Kill traction power if any pickup is on the gap if (j != 0 && Train.TractionManager.PowerCutoffDemanded == false) { DemandPowerCutoff("Power cutoff was demanded due to a neutral gap in the overhead line"); } break; case PowerGapBehaviour.InactiveAll: if (j == PickupLocations.Length && Train.TractionManager.PowerCutoffDemanded == false) { DemandPowerCutoff("Power cutoff was demanded due to a neutral gap in the overhead line"); } break; } } //Now, check to see if the last pickup is in the neutral section else if (Train.TrainLocation - PickupLocations[PickupLocations.Length - 1] > firstmagnet && Train.TrainLocation - PickupLocations[PickupLocations.Length - 1] < nextmagnet) { //Cycle through the other pickups int j = 0; foreach (int t in PickupLocations) { if (Train.TrainLocation - t < firstmagnet) { j++; } } switch (PowerGapBehaviour) { case PowerGapBehaviour.ProportionalReduction: //Reduce max throttle by percentage of how many pickups are in the gap double throttlemultiplier = (double)j / (double)PickupLocations.Length; new_power = (int)(this.Train.Specs.PowerNotches * throttlemultiplier); this.Train.TractionManager.SetMaxPowerNotch(new_power, false); //data.Handles.PowerNotch = new_power; break; case PowerGapBehaviour.InactiveAny: //Kill traction power if any pickup is on the gap if (j != 0 && Train.TractionManager.PowerCutoffDemanded == false) { DemandPowerCutoff("Power cutoff was demanded due to a neutral gap in the overhead line"); } break; case PowerGapBehaviour.InactiveAll: //Kill traction power when all pickups are on the gap if (j == PickupLocations.Length && Train.TractionManager.PowerCutoffDemanded == false) { DemandPowerCutoff("Power cutoff was demanded due to a neutral gap in the overhead line"); } break; } } //Neither the first or last pickups are in the power gap, reset the power //However also check that the breaker has not been tripped by a UKTrainSys beacon else if (nextmagnet != 0 && (Train.TrainLocation - PickupLocations[PickupLocations.Length - 1]) > nextmagnet && (Train.TrainLocation - PickupLocations[0]) > nextmagnet) { PowerGap = false; if (LegacyPowerCut == true) { //Reset legacy power cutoff state and retrip breaker Train.ElectricEngine.TripBreaker(); LegacyPowerCut = false; } if (BreakerTripped == false && ((FrontPantograph.State == PantographStates.Disabled && RearPantograph.State == PantographStates.OnService) || (RearPantograph.State == PantographStates.Disabled && FrontPantograph.State == PantographStates.OnService))) { ResetPowerCutoff("Power cutoff was released due to leaving the neutral gap"); } } //If the final pickup has passed the UKTrainSys standard power gap location else if (Train.TrainLocation - PickupLocations[PickupLocations.Length - 1] < lastmagnet) { PowerGap = false; } } //This section of code handles a UKTrainSys compatible ACB/VCB // //If the ACB/VCB has tripped, always demand power cutoff if (BreakerTripped == true && Train.TractionManager.PowerCutoffDemanded == false) { DemandPowerCutoff("Power cutoff was demanded due to the ACB/VCB state"); } //If we're in a power gap, also always demand power cutoff else if (BreakerTripped == false && PowerGap == true && Train.TractionManager.PowerCutoffDemanded == false) { DemandPowerCutoff("Power cutoff was demanded due to a neutral gap in the overhead line"); } //If the ACB/VCB has now been reset with a pantograph available & we're not in a powergap reset traction power if (BreakerTripped == false && PowerGap == false && (FrontPantograph.State == PantographStates.OnService || RearPantograph.State == PantographStates.OnService)) { ResetPowerCutoff("Power cutoff was released due to the availability of overhead power"); } } { //This section of code handles raising the pantographs and the alarm state // //If both pantographs are lowered or disabled, then there are no line volts if ((FrontPantograph.State == PantographStates.Lowered || FrontPantograph.State == PantographStates.Disabled) && (RearPantograph.State == PantographStates.Lowered || RearPantograph.State == PantographStates.Disabled) && Train.TractionManager.PowerCutoffDemanded == false) { DemandPowerCutoff("Power cutoff was demanded due to no available pantographs"); PowerGap = true; } //If the powergap behaviour cuts power when *any* pantograph is disabled / lowered // //Line volts is lit, but power is still cut off else if (FrontPantograph.State != PantographStates.Disabled && RearPantograph.State != PantographStates.Disabled && (FrontPantograph.State != PantographStates.OnService || RearPantograph.State != PantographStates.OnService) && PowerGapBehaviour == PowerGapBehaviour.InactiveAny && Train.TractionManager.PowerCutoffDemanded == false) { DemandPowerCutoff("Power cutoff was demanded due to no available pantographs"); } //Pantographs //One pantograph has been raised, and the line volts indicator has lit, but the timer is active //Power cutoff is still in force FrontPantograph.Update(data.ElapsedTime.Milliseconds); RearPantograph.Update(data.ElapsedTime.Milliseconds); if ((FrontPantograph.State == PantographStates.RaisedTimer && RearPantograph.State != PantographStates.OnService) || (RearPantograph.State == PantographStates.RaisedTimer && FrontPantograph.State != PantographStates.OnService)) { PowerGap = false; DemandPowerCutoff(null); } if (Train.CurrentSpeed > AutomaticPantographLowerSpeed) { //Automatic pantograph lowering switch (PantographLoweringMode) { case AutomaticPantographLoweringModes.LowerAll: //In lower all mode, we don't need to check anything if (FrontPantograph.State == PantographStates.OnService || FrontPantograph.State == PantographStates.RaisedTimer || FrontPantograph.State == PantographStates.VCBReady) { FrontPantograph.Lower(true); } if (RearPantograph.State == PantographStates.OnService || RearPantograph.State == PantographStates.RaisedTimer || RearPantograph.State == PantographStates.VCBReady) { RearPantograph.Lower(true); } Train.DebugLogger.LogMessage("Automatically lowered all pantographs due to reaching the setspeed."); break; case AutomaticPantographLoweringModes.LowerFront: if (RearPantograph.State == PantographStates.OnService) { if (FrontPantograph.State == PantographStates.OnService || FrontPantograph.State == PantographStates.RaisedTimer || FrontPantograph.State == PantographStates.VCBReady) { FrontPantograph.Lower(true); Train.DebugLogger.LogMessage("Automatically lowered the front pantograph due to reaching the setspeed."); } } break; case AutomaticPantographLoweringModes.LowerRear: if (FrontPantograph.State == PantographStates.OnService) { if (RearPantograph.State == PantographStates.OnService || RearPantograph.State == PantographStates.RaisedTimer || RearPantograph.State == PantographStates.VCBReady) { RearPantograph.Lower(true); Train.DebugLogger.LogMessage("Automatically lowered the rear pantograph due to reaching the setspeed."); } } break; case AutomaticPantographLoweringModes.LowerFrontRegardless: if (FrontPantograph.State == PantographStates.OnService || FrontPantograph.State == PantographStates.RaisedTimer || FrontPantograph.State == PantographStates.VCBReady) { FrontPantograph.Lower(true); Train.DebugLogger.LogMessage("Automatically lowered the front pantograph due to reaching the setspeed."); } break; case AutomaticPantographLoweringModes.LowerRearRegardless: if (RearPantograph.State == PantographStates.OnService || RearPantograph.State == PantographStates.RaisedTimer || RearPantograph.State == PantographStates.VCBReady) { RearPantograph.Lower(true); Train.DebugLogger.LogMessage("Automatically lowered the rear pantograph due to reaching the setspeed."); } break; } } } //This section of code runs the power notch loop sound if (powerloopsound != -1 && data.Handles.PowerNotch != 0) { if (BreakerTripped == false) { //Start the timer powerlooptimer += data.ElapsedTime.Milliseconds; if (powerlooptimer > powerlooptime && powerloop == false) { //Start playback and reset our conditions powerloop = true; SoundManager.Play(powerloopsound, 1.0, 1.0, true); } else if (powerloop == false) { SoundManager.Stop(powerloopsound); } } else { SoundManager.Stop(powerloopsound); } } else if (powerloopsound != -1 && this.Train.Handles.PowerNotch == 0) { SoundManager.Stop(powerloopsound); } //This section of code runs the breaker loop sound if (breakerloopsound != -1 && BreakerTripped == false) { if (!PowerGap && SoundManager.IsPlaying(breakerloopsound) == false) { breakerlooptimer += data.ElapsedTime.Milliseconds; if (breakerlooptimer > breakerlooptime) { SoundManager.Play(breakerloopsound, 1.0, 1.0, true); breakerlooptimer = 0.0; } } } else if (breakerloopsound != -1 && BreakerTripped == true) { SoundManager.Stop(breakerloopsound); breakerlooptimer = 0.0; } //Panel Indicies { //Ammeter if (Ammeter.PanelIndex != -1) { if (PowerGap == true || BreakerTripped == true || Train.TractionManager.PowerCutoffDemanded == true) { this.Train.Panel[Ammeter.PanelIndex] = 0; } else { this.Train.Panel[Ammeter.PanelIndex] = Ammeter.GetCurrentValue(); } } //Line Volts indicator if (powerindicator != -1) { if (!PowerGap) { this.Train.Panel[powerindicator] = 1; } else { this.Train.Panel[powerindicator] = 0; } } //ACB/VCB Breaker Indicator if (breakerindicator != -1) { if (!BreakerTripped) { this.Train.Panel[breakerindicator] = 1; } else { this.Train.Panel[breakerindicator] = 0; } } if (thermometer != -1) { this.Train.Panel[(thermometer)] = (int)temperature; } if (overheatindicator != -1) { if (temperature > overheatwarn) { this.Train.Panel[(overheatindicator)] = 1; } else { this.Train.Panel[(overheatindicator)] = 0; } } //Pantograph Indicators if (FrontPantograph.PanelIndex != -1) { if (FrontPantograph.Raised() == true) { this.Train.Panel[FrontPantograph.PanelIndex] = 1; } else { this.Train.Panel[FrontPantograph.PanelIndex] = 0; } } if (RearPantograph.PanelIndex != -1) { if (RearPantograph.Raised() == true) { this.Train.Panel[RearPantograph.PanelIndex] = 1; } else { this.Train.Panel[RearPantograph.PanelIndex] = 0; } } } //Sounds { if (overheatalarm != -1) { if (temperature > overheatalarm) { SoundManager.Play(overheatalarm, 1.0, 1.0, true); } else { SoundManager.Stop(overheatalarm); } } } //Pass information to the advanced driving window if (AdvancedDriving.CheckInst != null) { TractionManager.debuginformation[14] = Convert.ToString(FrontPantograph.State); TractionManager.debuginformation[15] = Convert.ToString(RearPantograph.State); TractionManager.debuginformation[16] = Convert.ToString(!BreakerTripped); TractionManager.debuginformation[17] = Convert.ToString(!PowerGap); } }