Beispiel #1
0
 private void SwitchToP(AtsP.States state)
 {
     if (this.State == AtsP.States.Standby)
     {
         if (this.Train.AtsSx == null || this.Train.AtsSx.State != AtsSx.States.Emergency)
         {
             this.State = state;
             if (!this.Blocked)
             {
                 if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                 {
                     SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                 }
                 return;
             }
         }
     }
     else if (state == AtsP.States.Service | state == AtsP.States.Emergency)
     {
         if (this.State != AtsP.States.Brake & this.State != AtsP.States.Service & this.State != AtsP.States.Emergency && !this.Blocked)
         {
             if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
             {
                 SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
             }
         }
         this.State = state;
     }
 }
Beispiel #2
0
 private void SwitchToSx()
 {
     if (this.Train.AtsSx != null)
     {
         AtsP.Pattern[] patterns = this.Patterns;
         for (int i = 0; i < (int)patterns.Length; i++)
         {
             patterns[i].Clear();
         }
         this.State = AtsP.States.Standby;
         if (!this.Blocked)
         {
             if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
             {
                 SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
             }
         }
         this.Train.AtsSx.State = AtsSx.States.Chime;
     }
     else if (this.State != AtsP.States.Emergency)
     {
         this.State = AtsP.States.Emergency;
         if (this.State != AtsP.States.Brake & this.State != AtsP.States.Service && !this.Blocked)
         {
             if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
             {
                 SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
             }
         }
     }
     this.SwitchToAtsSxPosition = double.MaxValue;
     this.DAtsPActive           = false;
 }
Beispiel #3
0
        internal override void Elapse(ElapseData data, ref bool blocking)
        {
            if (this.State == AtsSx.States.Suppressed && this.Train.TractionManager.CurrentInterventionBrakeNotch <= this.Train.Specs.BrakeNotches)
            {
                this.AlarmCountdown = this.DurationOfInitialization;
                this.State          = AtsSx.States.Initializing;
            }
            if (this.State == AtsSx.States.Initializing)
            {
                if (!SoundManager.IsPlaying(CommonSounds.ATSBell))
                {
                    SoundManager.Play(CommonSounds.ATSBell, 1.0, 1.0, false);
                }
                AtsSx alarmCountdown = this;
                alarmCountdown.AlarmCountdown = alarmCountdown.AlarmCountdown - data.ElapsedTime.Seconds;
                if (this.AlarmCountdown <= 0)
                {
                    this.State = AtsSx.States.Chime;
                }
            }
            if (!blocking)
            {
                if (this.State == AtsSx.States.Blocked)
                {
                    this.State = AtsSx.States.Chime;
                }
                if (this.State == AtsSx.States.Chime)
                {
                    if (!SoundManager.IsPlaying(CommonSounds.ATSChime))
                    {
                        SoundManager.Play(CommonSounds.ATSChime, 1.0, 1.0, false);
                    }
                }
                else if (this.State == AtsSx.States.Alarm)
                {
                    if (!SoundManager.IsPlaying(CommonSounds.ATSBell))
                    {
                        SoundManager.Play(CommonSounds.ATSBell, 1.0, 1.0, false);
                    }
                    AtsSx atsSx = this;
                    atsSx.AlarmCountdown = atsSx.AlarmCountdown - data.ElapsedTime.Seconds;
                    if (this.AlarmCountdown <= 0)
                    {
                        this.State = AtsSx.States.Emergency;
                    }
                }
                else if (this.State == AtsSx.States.Emergency)
                {
                    if (!SoundManager.IsPlaying(CommonSounds.ATSBell))
                    {
                        SoundManager.Play(CommonSounds.ATSBell, 1.0, 1.0, false);
                    }
                    if (!Train.TractionManager.BrakeInterventionDemanded)
                    {
                        Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches, "Brake application demanded by ATS-Sx");
                    }
                }
                if (this.SpeedCheckCountdown > 0 & data.ElapsedTime.Seconds > 0)
                {
                    AtsSx speedCheckCountdown = this;
                    speedCheckCountdown.SpeedCheckCountdown = speedCheckCountdown.SpeedCheckCountdown - data.ElapsedTime.Seconds;
                }
                if (this.CompatibilityDistanceAccumulator != 0)
                {
                    AtsSx compatibilityDistanceAccumulator = this;
                    compatibilityDistanceAccumulator.CompatibilityDistanceAccumulator = compatibilityDistanceAccumulator.CompatibilityDistanceAccumulator + data.Vehicle.Speed.MetersPerSecond * data.ElapsedTime.Seconds;
                    if (this.CompatibilityDistanceAccumulator > 27.7)
                    {
                        this.CompatibilityDistanceAccumulator = 0;
                    }
                }
            }
            else if (this.State != AtsSx.States.Disabled & this.State != AtsSx.States.Suppressed)
            {
                this.State = AtsSx.States.Blocked;
            }
            AtsSx compatibilityAccidentalDepartureCounter = this;

            compatibilityAccidentalDepartureCounter.CompatibilityAccidentalDepartureCounter = compatibilityAccidentalDepartureCounter.CompatibilityAccidentalDepartureCounter + data.ElapsedTime.Seconds;
            if (this.State == AtsSx.States.Chime | this.State == AtsSx.States.Normal)
            {
                this.Train.Panel[0]   = 1;
                this.Train.Panel[256] = 1;
            }
            if (this.State == AtsSx.States.Initializing | this.State == AtsSx.States.Alarm)
            {
                this.Train.Panel[1]   = 1;
                this.Train.Panel[257] = 1;
                this.Train.Panel[258] = 1;
                return;
            }
            if (this.State == AtsSx.States.Emergency)
            {
                int num = ((int)data.TotalTime.Milliseconds % 1000 < 500 ? 1 : 0);
                this.Train.Panel[1]   = num;
                this.Train.Panel[257] = 2;
                this.Train.Panel[258] = num;
            }
        }
Beispiel #4
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)
        {
            //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- Not on a steam 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.DemandPowerCutoff("Traction power cutoff was demanded due to the steam 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;
                }
            }

            //First try to set automatic cutoff without calculating
            if (this.Train.TractionManager.AutomaticAdvancedFunctions == true && Train.CurrentSpeed == 0)
            {
                if (Train.Handles.Reverser == 0)
                {
                    //If reverser is in neutral, reset cutoff to 30
                    cutoff = 30;
                }
                else if (Train.Handles.Reverser == 1 && cutoff >= cutoffineffective)
                {
                    cutoff = cutoffmax;
                }
                else if (Train.Handles.Reverser == -1 && cutoff >= cutoffineffective)
                {
                    cutoff = cutoffmin;
                }
            }
            else
            {
                double setcutoff = cutoff;
                if (cutoffstate == 1)
                {
                    //Set Cutoff Up
                    if (cutoff < cutoffmax)
                    {
                        this.cutofftimer += data.ElapsedTime.Milliseconds;
                        if (this.cutofftimer > cutoffchangespeed)
                        {
                            setcutoff   = setcutoff + 1;
                            cutofftimer = 0.0;
                        }
                    }
                }

                else if (cutoffstate == -1)
                {
                    //Set Cutoff Down
                    if (cutoff > cutoffmin)
                    {
                        this.cutofftimer += data.ElapsedTime.Milliseconds;
                        if (this.cutofftimer > cutoffchangespeed)
                        {
                            setcutoff   = setcutoff - 1;
                            cutofftimer = 0.0;
                        }
                    }
                }
                else
                {
                    //twiddle our thumbs
                }
                cutoff = setcutoff;
            }

            //Manual

            {
                //This section of code operates the reverser & cutoff
                if (cutoff > cutoffineffective && (cutoffdeviation != 0))
                {
                    new_reverser = 1;
                    //Called to workout the optimum cutoff if we're over the optimum max cutoff speed FW
                    if (data.Vehicle.Speed.KilometersPerHour > cutoffratiobase)
                    {
                        speed         = data.Vehicle.Speed.KilometersPerHour - cutoffratiobase;
                        optimalcutoff = cutoffmax - speed * cutoffratio / 10;
                        new_power     = Math.Max((int)(this.Train.Specs.PowerNotches - ((optimalcutoff - cutoff) < 0 ? -(optimalcutoff - cutoff) : (optimalcutoff - cutoff)) / (int)cutoffdeviation), 0);
                        //Automagically set cutofff
                        if (this.Train.TractionManager.AutomaticAdvancedFunctions == true)
                        {
                            cutoff = (int)Math.Max(optimalcutoff, cutoffineffective + 1);
                        }
                    }
                    else
                    {
                        new_power = Math.Max((int)(this.Train.Specs.PowerNotches - (((int)cutoffmax - cutoff) < 0 ? -((int)cutoffmax - cutoff) : ((int)cutoffmax - cutoff)) / cutoffdeviation), 0);
                    }
                }
                else if (cutoff < cutoffineffective && cutoffdeviation != 0)
                {
                    new_reverser = -1;
                    //Called to workout the optimum cutoff if we're over the optimum max cutoff speed RV
                    if (Math.Abs(data.Vehicle.Speed.KilometersPerHour) > cutoffratiobase)
                    {
                        speed         = Math.Abs(data.Vehicle.Speed.KilometersPerHour) - cutoffratiobase;
                        optimalcutoff = cutoffmin + speed * cutoffratio / 10;
                        new_power     = Math.Max((int)(this.Train.Specs.PowerNotches - ((optimalcutoff - cutoff) < 0 ? -(optimalcutoff - cutoff) : (optimalcutoff - cutoff)) / (int)cutoffdeviation), 0);
                        //Automagically set cutoff
                        if (this.Train.TractionManager.AutomaticAdvancedFunctions == true)
                        {
                            cutoff = (int)Math.Min(optimalcutoff, -cutoffineffective - 1);
                        }
                    }
                    else
                    {
                        new_power = Math.Max((int)(this.Train.Specs.PowerNotches - ((Math.Abs(cutoffmin) - Math.Abs(cutoff)) < 0 ? -((int)Math.Abs(cutoffmin)
                                                                                                                                     - Math.Abs(cutoff)) : ((int)Math.Abs(cutoffmin) - Math.Abs(cutoff))) / cutoffdeviation), 0);
                    }
                }
                else
                {
                    new_reverser = 0;
                    new_power    = 0;
                }
            }

            //CALL NEW FUNCTION TO SET THE REVERSER STATE
            if (new_reverser != stm_reverser)
            {
                stm_reverser          = new_reverser;
                data.Handles.Reverser = stm_reverser;
            }
            else
            {
                data.Handles.Reverser = stm_reverser;
            }

            {
                //This section of code operates the pressure power drop
                double bp        = Math.Max(stm_boilerpressure - boilerminpressure, 0);
                int    bp_range  = (int)boilermaxpressure - (int)boilerminpressure;
                int    pwr_limit = Math.Min(new_power, (int)((bp / (float)(bp_range) + (1.0 / this.Train.Specs.PowerNotches - 0.01)) * this.Train.Specs.PowerNotches));



                new_power = Math.Max(Train.Handles.PowerNotch - this.Train.Specs.PowerNotches + pwr_limit, 0);

                //CALL NEW FUNCTION TO CHANGE POWER
            }


            if (Train.drastate != true)
            {
                stm_power = new_power;
                LastPower = new_power;
                Train.TractionManager.SetMaxPowerNotch(stm_power, false);
            }

            {
                //This section of code generates pressure and operates the blowoff

                //First elapse the main timer function
                this.maintimer += data.ElapsedTime.Seconds;

                //This section of code handles the fire simulator
                if (advancedfiring == false)
                {
                    //Advanced firing is not enabled, use the standard boiler water to steam rate
                    finalsteamrate = calculatedsteamrate;
                }
                else
                {
                    //Advanced firing
                    if (this.maintimer > 1)
                    {
                        //Check whether we can shovel coal
                        //Firemass must be below maximum and shovelling true [Non automatic]
                        //If automatic firing is on, only shovel coal if we are below 50% of max fire mass- Change???
                        //Use automatic behaviour if no shovelling key is set as obviously we can't shovel coal manually with no key
                        if (shovelling == true && firemass < maximumfiremass || this.Train.TractionManager.AutomaticAdvancedFunctions == true && firemass < (firemass / 2) && firemass < maximumfiremass ||
                            Train.CurrentKeyConfiguration.ShovelFuel == null && firemass < (firemass / 2) && firemass < maximumfiremass)
                        {
                            //Add the amount of coal shovelled per second to the fire mass & decrease it from the fire temperature
                            firemass += (int)shovellingrate;
                            firetemp -= (int)shovellingrate;
                        }
                        int fire_tempchange;
                        if (firemass != 0)
                        {
                            if (Blowers.Active)
                            {
                                fire_tempchange = (int)Math.Ceiling((double)(((firemass * 0.5) - 10) / (firemass * 0.05)) * Blowers.FireTempIncreaseFactor);
                            }
                            else
                            {
                                fire_tempchange = (int)Math.Ceiling((double)(((firemass * 0.5) - 10) / (firemass * 0.05)));
                            }
                        }
                        else
                        {
                            //Temperature change must be zero if our fire mass is zero
                            //Otherwise causes a division by zero error....
                            fire_tempchange = 0;
                        }
                        firemass = (int)((double)firemass * 0.9875);
                        if (firetemp < 1000)
                        {
                            //Add calculated temperature increase to the fire temperature
                            firetemp += fire_tempchange;
                        }
                        else
                        {
                            //Otherwise set to max
                            firetemp = 1000;
                        }
                        if (Blowers.Active == true)
                        {
                            finalsteamrate = (int)((((double)calculatedsteamrate / 1000) * firetemp) * Blowers.PressureIncreaseFactor);
                        }
                        else
                        {
                            finalsteamrate = (int)(((double)calculatedsteamrate / 1000) * firetemp);
                        }
                    }
                }
                if (this.maintimer > 1)
                {
                    if (Blowers.Active == true)
                    {
                        pressureup = (int)(((boilerwatertosteamrate / 60) * maintimer) * Blowers.PressureIncreaseFactor);
                    }
                    else
                    {
                        pressureup = (int)((boilerwatertosteamrate / 60) * maintimer);
                    }
                    stm_boilerpressure = stm_boilerpressure + pressureup;
                    stm_boilerwater    = stm_boilerwater - pressureup;
                    //Newer standard blowoff handling
                    if (stm_boilerpressure > boilermaxpressure)
                    {
                        switch (Blowoff.BlowoffState)
                        {
                        case Blowoff.BlowoffStates.None:

                            //Switch to the over maximum pressure state, as we are over the max pressure
                            Blowoff.BlowoffState = Blowoff.BlowoffStates.OverMaxPressure;
                            Blowoff.Played       = false;
                            break;

                        case Blowoff.BlowoffStates.OverMaxPressure:
                            if (stm_boilerpressure > Blowoff.TriggerPressure)
                            {
                                //If our boiler pressure is over the blowoff pressure, then switch to blowoff
                                Blowoff.BlowoffState = Blowoff.BlowoffStates.Blowoff;
                                break;
                            }
                            //Otherwise, reduce the pressure by 4
                            //This is an OS_ATS quirk, remove???
                            stm_boilerpressure = stm_boilerpressure - 4;
                            break;

                        case Blowoff.BlowoffStates.Blowoff:
                            //Trigger the sound- Play only once
                            if (!SoundManager.IsPlaying(Blowoff.SoundIndex) && Blowoff.Played == false)
                            {
                                SoundManager.Play(Blowoff.SoundIndex, 1.0, 1.0, false);
                            }
                            Blowoff.Timer += maintimer;
                            if (Blowoff.BlowoffRate != 0)
                            {
                                //If a blowoff time has been set, then reduce the pressure by the calculated blowoff rate
                                stm_boilerpressure -= (int)Blowoff.BlowoffRate;
                            }
                            else
                            {
                                //Otherwise, just run a simple 10-second timer
                                if (Blowoff.Timer > 10)
                                {
                                    //Now reduce the boiler pressure to max, and drop the state back to none
                                    stm_boilerpressure   = (int)boilermaxpressure;
                                    Blowoff.BlowoffState = Blowoff.BlowoffStates.None;
                                }
                            }
                            break;
                        }
                    }
                    else
                    {
                        Blowoff.BlowoffState = Blowoff.BlowoffStates.None;
                    }
                }
            }

            if (this.Train.TractionManager.AutomaticAdvancedFunctions == true)
            {
                Blowers.Timer += data.ElapsedTime.Milliseconds;
                //This section of code operates the automatic injectors
                if (stm_boilerwater > boilermaxwaterlevel / 2 && stm_boilerpressure > boilermaxpressure / 4)
                {
                    if (LiveSteamInjector.Active == true && Blowers.Timer > 10000)
                    {
                        LiveSteamInjector.Active = false;
                        Train.DebugLogger.LogMessage("The automatic fireman de-activated the injectors");
                        Blowers.Timer = 0.0;
                    }
                    if (pressureuse > ((boilerwatertosteamrate / 60) * maintimer) * 1.5)
                    {
                        //Turn on the blowers if we're using 50% more pressure than we're generating
                        if (Blowers.Active == false && Blowers.Timer > 10000)
                        {
                            Train.DebugLogger.LogMessage("The automatic fireman activated the blowers");
                            Blowers.Active = true;
                            Blowers.Timer  = 0.0;
                        }
                    }
                    else
                    {
                        if (Blowers.Active == true && Blowers.Timer > 10000)
                        {
                            Train.DebugLogger.LogMessage("The automatic fireman de-activated the blowers");
                            Blowers.Active = false;
                            Blowers.Timer  = 0.0;
                        }
                    }
                }
                else
                {
                    //Blowers shouldn't be on at the same time as the injectors
                    if (LiveSteamInjector.Active == false && Blowers.Timer > 10000)
                    {
                        Train.DebugLogger.LogMessage("The automatic fireman activated the injectors");
                        LiveSteamInjector.Active = true;
                        Blowers.Timer            = 0.0;
                    }
                    Blowers.Active = false;
                }
            }

            LiveSteamInjector.Update(data.ElapsedTime.Seconds, ref stm_boilerwater, ref stm_boilerpressure, ref fuel);

            //This section of code governs pressure usage
            if (stm_reverser != 0)
            {
                double regpruse = ((double)Train.Handles.PowerNotch / (double)this.Train.Specs.PowerNotches) * regulatorpressureuse;
                //32
                float cutprboost = Math.Abs((float)cutoff) / Math.Abs((float)cutoffmax);
                //1
                float spdpruse = 1 + Math.Abs((float)data.Vehicle.Speed.KilometersPerHour) / 25;
                if (maintimer > 1)
                {
                    pressureuse        = (int)(regpruse * cutprboost * spdpruse);
                    stm_boilerpressure = stm_boilerpressure - pressureuse;
                }
            }
            //This section of code governs the pressure used by the horn
            if (klaxonpressureuse != -1 && (Train.TractionManager.primaryklaxonplaying || Train.TractionManager.secondaryklaxonplaying || Train.TractionManager.musicklaxonplaying))
            {
                if (this.maintimer > 1)
                {
                    stm_boilerpressure = stm_boilerpressure - (int)klaxonpressureuse;
                }
            }
            //This section of code defines the pressure used by the train's steam heating system
            if (steamheatpressureuse != -1 && steamheatlevel != 0)
            {
                if (maintimer > 1)
                {
                    stm_boilerpressure -= (int)(steamheatlevel * steamheatpressureuse);
                }
            }
            //This section of code fills our tanks from a water tower
            if (fuelling == true)
            {
                if (maintimer > 1)
                {
                    fuel += (int)fuelfillspeed;
                }
                if (fuel > fuelcapacity)
                {
                    fuel = (int)fuelcapacity;
                }
            }
            //Pass data to the debug window
            if (AdvancedDriving.CheckInst != null)
            {
                //Calculate total pressure usage figure
                int debugpressureuse = pressureuse;
                if (Train.TractionManager.primaryklaxonplaying || Train.TractionManager.secondaryklaxonplaying || Train.TractionManager.musicklaxonplaying)
                {
                    debugpressureuse += (int)klaxonpressureuse;
                }
                if (steamheatpressureuse != -1 && steamheatlevel != 0)
                {
                    debugpressureuse += (int)(steamheatlevel * steamheatpressureuse);
                }
                if (CylinderCocks.Active == true)
                {
                    debugpressureuse += (int)(cylindercocks_basepressureuse + (cylindercocks_notchpressureuse * Train.Handles.PowerNotch));
                }
                this.Train.TractionManager.DebugWindowData.SteamEngine.BoilerPressure         = (int)stm_boilerpressure;
                this.Train.TractionManager.DebugWindowData.SteamEngine.PressureGenerationRate = pressureup;
                this.Train.TractionManager.DebugWindowData.SteamEngine.PressureUsageRate      = debugpressureuse;
                this.Train.TractionManager.DebugWindowData.SteamEngine.CurrentCutoff          = (int)cutoff;
                this.Train.TractionManager.DebugWindowData.SteamEngine.OptimalCutoff          = (int)optimalcutoff;
                this.Train.TractionManager.DebugWindowData.SteamEngine.FireMass         = firemass;
                this.Train.TractionManager.DebugWindowData.SteamEngine.FireTemperature  = firetemp;
                this.Train.TractionManager.DebugWindowData.SteamEngine.Injectors        = LiveSteamInjector.Active;
                this.Train.TractionManager.DebugWindowData.SteamEngine.Blowers          = Blowers.Active;
                this.Train.TractionManager.DebugWindowData.SteamEngine.BoilerWaterLevel = Convert.ToString(stm_boilerwater) + " of " + Convert.ToString(boilermaxwaterlevel, CultureInfo.InvariantCulture);
                this.Train.TractionManager.DebugWindowData.SteamEngine.TanksWaterLevel  = Convert.ToString(fuel) + " of " + Convert.ToString(fuelcapacity, CultureInfo.InvariantCulture);
                this.Train.TractionManager.DebugWindowData.SteamEngine.AutoCutoff       = this.Train.TractionManager.AutomaticAdvancedFunctions;
                if (cylindercocks == true)
                {
                    this.Train.TractionManager.DebugWindowData.SteamEngine.CylinderCocks = "Open";
                }
                else
                {
                    this.Train.TractionManager.DebugWindowData.SteamEngine.CylinderCocks = "Closed";
                }
            }
            {
                //Set Panel Indicators
                if (cutoffindicator != -1)
                {
                    this.Train.Panel[(cutoffindicator)] = (int)cutoff;
                }
                if (boilerpressureindicator != -1)
                {
                    this.Train.Panel[boilerpressureindicator] = (int)stm_boilerpressure;
                }
                if (boilerwaterlevelindicator != -1)
                {
                    this.Train.Panel[boilerwaterlevelindicator] = (int)stm_boilerwater;
                }
                if (fuelindicator != -1)
                {
                    this.Train.Panel[fuelindicator] = (int)fuel;
                }

                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 (fuelfillindicator != -1)
                {
                    if (fuelling == true)
                    {
                        this.Train.Panel[fuelfillindicator] = 1;
                    }
                }
                if (Blowoff.PanelIndex != -1)
                {
                    if (Blowoff.BlowoffState == Blowoff.BlowoffStates.Blowoff)
                    {
                        this.Train.Panel[Blowoff.PanelIndex] = 1;
                    }
                    else
                    {
                        this.Train.Panel[Blowoff.PanelIndex] = 0;
                    }
                }
                if (steamheatindicator != -1)
                {
                    this.Train.Panel[steamheatindicator] = steamheatlevel;
                }
            }
            //Reset the main timer if it's over 1 second
            if (this.maintimer > 1)
            {
                this.maintimer = 0.0;
            }
        }
Beispiel #5
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;
            }
        }
Beispiel #6
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)
        {
            //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);
                    }
                }
            }
        }
Beispiel #7
0
        internal override void SetBeacon(BeaconData beacon)
        {
            int num;

            if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed & this.State != AtsP.States.Initializing)
            {
                switch (beacon.Type)
                {
                case 3:
                case 4:
                case 5:
                {
                    this.Position = this.Train.State.Location;
                    if (!(this.State != AtsP.States.Service & this.State != AtsP.States.Emergency))
                    {
                        break;
                    }
                    if (this.State == AtsP.States.Standby & beacon.Optional != -1)
                    {
                        this.SwitchToP(AtsP.States.Normal);
                    }
                    if (this.State == AtsP.States.Standby)
                    {
                        break;
                    }
                    if (!(beacon.Type == 3 & beacon.Optional >= 10 & beacon.Optional <= 19))
                    {
                        num = (!(beacon.Type == 3 & beacon.Optional >= 1 & beacon.Optional <= 9) ? 0 : beacon.Optional);
                        double position = this.Position + beacon.Signal.Distance;
                        bool   flag     = false;
                        if (num != 0)
                        {
                            flag = true;
                        }
                        else if (this.SignalPatterns[num].Position == double.MaxValue)
                        {
                            flag = true;
                        }
                        else if (position > this.SignalPatterns[num].Position - 30)
                        {
                            flag = true;
                        }
                        if (!flag)
                        {
                            break;
                        }
                        if (!(beacon.Signal.Aspect == 0 | beacon.Signal.Aspect >= 10))
                        {
                            this.SignalPatterns[num].SetGreenSignal(position);
                            break;
                        }
                        else
                        {
                            this.SignalPatterns[num].SetRedSignal(position);
                            if (!(beacon.Type != 3 & beacon.Signal.Distance < 50 & !this.BrakeRelease))
                            {
                                break;
                            }
                            if (beacon.Type != 4)
                            {
                                this.SwitchToP(AtsP.States.Service);
                                break;
                            }
                            else
                            {
                                this.SwitchToP(AtsP.States.Emergency);
                                break;
                            }
                        }
                    }
                    else
                    {
                        this.SignalPatterns[beacon.Optional - 10].Clear();
                        break;
                    }
                }

                case 6:
                {
                    int optional = beacon.Optional / 1000;
                    if (optional <= 0)
                    {
                        break;
                    }
                    if (this.State == AtsP.States.Standby)
                    {
                        this.SwitchToP(AtsP.States.Normal);
                    }
                    this.Position = this.Train.State.Location;
                    int optional1 = beacon.Optional % 1000;
                    this.DivergencePattern.SetLimit((double)optional1 / 3.6, this.Position + (double)optional);
                    break;
                }

                case 7:
                {
                    this.Position = this.Train.State.Location;
                    if (beacon.Optional <= 0)
                    {
                        this.SwitchToP(AtsP.States.Emergency);
                        break;
                    }
                    else
                    {
                        if (this.State == AtsP.States.Standby)
                        {
                            this.SwitchToP(AtsP.States.Normal);
                        }
                        this.RoutePermanentPattern.SetLimit((double)beacon.Optional / 3.6, double.MinValue);
                        break;
                    }
                }

                case 8:
                {
                    int num1 = beacon.Optional / 1000;
                    if (num1 <= 0)
                    {
                        break;
                    }
                    if (this.State == AtsP.States.Standby)
                    {
                        this.SwitchToP(AtsP.States.Normal);
                    }
                    this.Position = this.Train.State.Location;
                    int optional2 = beacon.Optional % 1000;
                    this.DownslopePattern.SetLimit((double)optional2 / 3.6, this.Position + (double)num1);
                    break;
                }

                case 9:
                {
                    int num2 = beacon.Optional / 1000;
                    if (num2 <= 0)
                    {
                        break;
                    }
                    if (this.State == AtsP.States.Standby)
                    {
                        this.SwitchToP(AtsP.States.Normal);
                    }
                    this.Position = this.Train.State.Location;
                    int optional3 = beacon.Optional % 1000;
                    this.CurvePattern.SetLimit((double)optional3 / 3.6, this.Position + (double)num2);
                    break;
                }

                case 10:
                {
                    int num3      = beacon.Optional / 1000;
                    int optional4 = beacon.Optional % 1000;
                    if (num3 == 0)
                    {
                        if (!(num3 == 0 & optional4 != 0))
                        {
                            break;
                        }
                        this.Position = this.Train.State.Location;
                        this.SwitchToAtsSxPosition = this.Position + (double)optional4;
                        break;
                    }
                    else
                    {
                        if (this.State == AtsP.States.Standby)
                        {
                            this.SwitchToP(AtsP.States.Normal);
                        }
                        this.Position = this.Train.State.Location;
                        this.TemporaryPattern.SetLimit((double)optional4 / 3.6, this.Position + (double)num3);
                        break;
                    }
                }

                case 16:
                {
                    if (beacon.Optional != 0)
                    {
                        break;
                    }
                    this.Position = this.Train.State.Location;
                    this.DivergencePattern.Clear();
                    break;
                }

                case 18:
                {
                    if (beacon.Optional != 0)
                    {
                        break;
                    }
                    this.Position = this.Train.State.Location;
                    this.DownslopePattern.Clear();
                    break;
                }

                case 19:
                {
                    if (beacon.Optional != 0)
                    {
                        break;
                    }
                    this.Position = this.Train.State.Location;
                    this.CurvePattern.Clear();
                    break;
                }

                case 20:
                {
                    if (beacon.Optional != 0)
                    {
                        break;
                    }
                    this.Position = this.Train.State.Location;
                    this.TemporaryPattern.Clear();
                    break;
                }

                case 25:
                {
                    if (beacon.Optional == 0)
                    {
                        this.Position = this.Train.State.Location;
                        if (!(this.State == AtsP.States.Normal | this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency))
                        {
                            break;
                        }
                        this.SwitchToAtsSxPosition = this.Position;
                        break;
                    }
                    else if (beacon.Optional != 1)
                    {
                        if (beacon.Optional != 2)
                        {
                            break;
                        }
                        this.Position = this.Train.State.Location;
                        if (this.State == AtsP.States.Standby)
                        {
                            this.SwitchToP(AtsP.States.Normal);
                        }
                        if (this.AtsSxPMode)
                        {
                            break;
                        }
                        this.AtsSxPMode = true;
                        if (!(this.Train.AtsSx != null & !this.Blocked))
                        {
                            break;
                        }
                        if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                        {
                            SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                        }
                        break;
                    }
                    else
                    {
                        this.Position = this.Train.State.Location;
                        if (this.State == AtsP.States.Standby)
                        {
                            this.SwitchToP(AtsP.States.Normal);
                        }
                        if (!this.AtsSxPMode)
                        {
                            break;
                        }
                        this.AtsSxPMode = false;
                        if (!(this.Train.AtsSx != null & !this.Blocked))
                        {
                            break;
                        }
                        if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                        {
                            SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                        }
                        break;
                    }
                }
                }
            }
            switch (beacon.Type)
            {
            case -16777213:
            {
                double num4      = (double)(beacon.Optional & 4095) / 3.6;
                double optional5 = (double)(beacon.Optional >> 12);
                AtsP.CompatibilityLimit compatibilityLimit = new AtsP.CompatibilityLimit(num4, optional5);
                if (this.CompatibilityLimits.Contains(compatibilityLimit))
                {
                    break;
                }
                this.CompatibilityLimits.Add(compatibilityLimit);
                return;
            }

            case -16777212:
            {
                if (beacon.Optional == 0)
                {
                    this.CompatibilityPermanentPattern.Clear();
                    return;
                }
                double num5 = (double)beacon.Optional / 3.6;
                this.CompatibilityPermanentPattern.SetLimit(num5, double.MinValue);
                break;
            }

            default:
            {
                return;
            }
            }
        }
Beispiel #8
0
        internal override void KeyDown(VirtualKeys key)
        {
            VirtualKeys virtualKey = key;

            switch (virtualKey)
            {
            case VirtualKeys.B1:
            {
                if (!((this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency) & this.Train.Handles.Reverser == 0 & this.Train.Handles.PowerNotch == 0 & this.Train.Handles.BrakeNotch >= this.Train.Specs.BrakeNotches))
                {
                    break;
                }
                AtsP.Pattern[] patterns = this.Patterns;
                for (int i = 0; i < (int)patterns.Length; i++)
                {
                    AtsP.Pattern pattern = patterns[i];
                    if (Math.Abs(this.Train.State.Speed.MetersPerSecond) >= pattern.WarningPattern)
                    {
                        pattern.Clear();
                    }
                }
                this.State = AtsP.States.Normal;
                Train.TractionManager.ResetBrakeApplication();
                if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                {
                    SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                }
                return;
            }

            case VirtualKeys.B2:
            {
                if (!((this.State == AtsP.States.Normal | this.State == AtsP.States.Pattern) & !this.BrakeRelease & this.DurationOfBrakeRelease > 0))
                {
                    break;
                }
                this.BrakeRelease          = true;
                this.BrakeReleaseCountdown = this.DurationOfBrakeRelease;
                if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                {
                    SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                }
                return;
            }

            default:
            {
                if (virtualKey != VirtualKeys.E)
                {
                    return;
                }
                if (this.State == AtsP.States.Disabled)
                {
                    this.State = AtsP.States.Suppressed;
                    return;
                }
                this.State = AtsP.States.Disabled;
                break;
            }
            }
        }
Beispiel #9
0
        internal override void Elapse(ElapseData data, ref bool blocking)
        {
            this.Blocked = blocking;
            if (this.State == AtsP.States.Suppressed && this.Train.TractionManager.CurrentInterventionBrakeNotch <= this.Train.Specs.BrakeNotches)
            {
                this.InitializationCountdown = this.DurationOfInitialization;
                this.State = AtsP.States.Initializing;
            }
            if (this.State == AtsP.States.Initializing)
            {
                AtsP initializationCountdown = this;
                initializationCountdown.InitializationCountdown = initializationCountdown.InitializationCountdown - data.ElapsedTime.Seconds;
                if (this.InitializationCountdown <= 0)
                {
                    this.State                 = AtsP.States.Standby;
                    this.BrakeRelease          = false;
                    this.SwitchToAtsSxPosition = double.MaxValue;
                    AtsP.Pattern[] patterns = this.Patterns;
                    for (int i = 0; i < (int)patterns.Length; i++)
                    {
                        AtsP.Pattern pattern = patterns[i];
                        if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern.WarningPattern)
                        {
                            pattern.Clear();
                        }
                    }
                    if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                    {
                        SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                    }
                }
            }
            if (this.BrakeRelease)
            {
                AtsP brakeReleaseCountdown = this;
                brakeReleaseCountdown.BrakeReleaseCountdown = brakeReleaseCountdown.BrakeReleaseCountdown - data.ElapsedTime.Seconds;
                if (this.BrakeReleaseCountdown <= 0)
                {
                    this.BrakeRelease = false;
                    if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                    {
                        SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                    }
                }
            }
            if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Initializing)
            {
                AtsP position = this;
                position.Position = position.Position + data.Vehicle.Speed.MetersPerSecond * data.ElapsedTime.Seconds;
            }
            if (!blocking)
            {
                if (this.DAtsPSupported && this.DAtsPFirstSignalPattern.Position - this.Train.State.Location < 0)
                {
                    this.DAtsPZerothSignalPattern.Position    = this.DAtsPFirstSignalPattern.Position;
                    this.DAtsPZerothSignalPattern.TargetSpeed = this.DAtsPFirstSignalPattern.TargetSpeed;
                    this.DAtsPFirstSignalPattern.Position     = this.DAtsPSecondSignalPattern.Position;
                    this.DAtsPFirstSignalPattern.TargetSpeed  = this.DAtsPSecondSignalPattern.TargetSpeed;
                    this.DAtsPSecondSignalPattern.Position    = double.MaxValue;
                    this.DAtsPSecondSignalPattern.TargetSpeed = double.MaxValue;
                }
                if (this.DAtsPActive & this.DAtsPContinuous)
                {
                    switch (this.DAtsPAspect)
                    {
                    case 1:
                    {
                        this.DAtsPFirstSignalPattern.TargetSpeed = 6.94444444444444;
                        break;
                    }

                    case 2:
                    {
                        this.DAtsPFirstSignalPattern.TargetSpeed = 12.5;
                        break;
                    }

                    case 3:
                    {
                        this.DAtsPFirstSignalPattern.TargetSpeed = 20.8333333333333;
                        break;
                    }

                    case 4:
                    case 5:
                    case 6:
                    {
                        this.DAtsPFirstSignalPattern.TargetSpeed = double.MaxValue;
                        break;
                    }

                    default:
                    {
                        this.DAtsPFirstSignalPattern.TargetSpeed = 0;
                        break;
                    }
                    }
                    if (this.DAtsPZerothSignalPattern.TargetSpeed < this.DAtsPFirstSignalPattern.TargetSpeed)
                    {
                        this.DAtsPZerothSignalPattern.TargetSpeed = this.DAtsPFirstSignalPattern.TargetSpeed;
                    }
                }
                if (this.State == AtsP.States.Normal | this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake)
                {
                    bool flag  = false;
                    bool flag1 = false;
                    bool flag2 = true;
                    if (this.DivergencePattern.Position > double.MinValue & this.DivergencePattern.Position < double.MaxValue && Math.Abs(data.Vehicle.Speed.MetersPerSecond) < this.DivergencePattern.BrakePattern && this.DivergencePattern.Position - this.Position < -50)
                    {
                        this.DivergencePattern.Clear();
                    }
                    this.UpdateCompatibilityTemporarySpeedPattern();
                    AtsP.Pattern[] patternArray = this.Patterns;
                    for (int j = 0; j < (int)patternArray.Length; j++)
                    {
                        AtsP.Pattern pattern1 = patternArray[j];
                        pattern1.Perform(this, data);
                        if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern1.WarningPattern - 0.277777777777778)
                        {
                            flag2 = false;
                        }
                        if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern1.WarningPattern)
                        {
                            flag1 = true;
                        }
                        if (Math.Abs(data.Vehicle.Speed.MetersPerSecond) >= pattern1.BrakePattern)
                        {
                            flag = true;
                        }
                    }
                    if (this.BrakeRelease)
                    {
                        flag = false;
                    }
                    if (flag & this.State != AtsP.States.Brake)
                    {
                        this.State = AtsP.States.Brake;
                        if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                        {
                            SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                        }
                    }
                    else if (flag1 & this.State == AtsP.States.Normal)
                    {
                        this.State = AtsP.States.Pattern;
                        if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                        {
                            SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                        }
                    }
                    else if (!flag & !flag1 & flag2 & (this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake))
                    {
                        this.State = AtsP.States.Normal;
                        if (!SoundManager.IsPlaying(CommonSounds.ATSPBell))
                        {
                            SoundManager.Play(CommonSounds.ATSPBell, 1.0, 1.0, false);
                        }
                    }
                    if (this.State == AtsP.States.Brake)
                    {
                        Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches, "Brake application demanded by ATS-P");
                    }
                    if (this.Position > this.SwitchToAtsSxPosition & this.State != AtsP.States.Brake & this.State != AtsP.States.Service & this.State != AtsP.States.Emergency)
                    {
                        this.SwitchToSx();
                    }
                }
                else if (this.State == AtsP.States.Service)
                {
                    Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches, "Brake application demanded by ATS-P");
                }
                else if (this.State == AtsP.States.Emergency)
                {
                    Train.TractionManager.DemandBrakeApplication(this.Train.Specs.BrakeNotches + 1, "Brake application demanded by ATS-P");
                }
                if (!this.AtsSxPMode & (this.State == AtsP.States.Normal | this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency))
                {
                    blocking = true;
                }
            }
            else if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed)
            {
                this.State = AtsP.States.Standby;
            }
            if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed)
            {
                this.Train.Panel[2]   = 1;
                this.Train.Panel[259] = 1;
            }
            if (this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency)
            {
                this.Train.Panel[3]   = 1;
                this.Train.Panel[260] = 1;
            }
            if (this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency)
            {
                this.Train.Panel[5]   = 1;
                this.Train.Panel[262] = 1;
            }
            if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed & this.State != AtsP.States.Standby)
            {
                this.Train.Panel[6]   = 1;
                this.Train.Panel[263] = 1;
            }
            if (this.State == AtsP.States.Initializing)
            {
                this.Train.Panel[7]   = 1;
                this.Train.Panel[264] = 1;
            }
            if (this.State == AtsP.States.Disabled)
            {
                this.Train.Panel[50] = 1;
            }
            if (this.State != AtsP.States.Disabled & this.State != AtsP.States.Suppressed & this.State != AtsP.States.Standby & this.BrakeRelease)
            {
                this.Train.Panel[4]   = 1;
                this.Train.Panel[261] = 1;
            }
            if (this.State == AtsP.States.Normal | this.State == AtsP.States.Pattern | this.State == AtsP.States.Brake | this.State == AtsP.States.Service | this.State == AtsP.States.Emergency)
            {
                StringBuilder stringBuilder = new StringBuilder();
                for (int k = 0; k < (int)this.SignalPatterns.Length; k++)
                {
                    this.SignalPatterns[k].AddToStringBuilder(string.Concat(k.ToString(), ":"), stringBuilder);
                }
                this.DivergencePattern.AddToStringBuilder("分岐/D:", stringBuilder);
                this.TemporaryPattern.AddToStringBuilder("臨時/T:", stringBuilder);
                this.CurvePattern.AddToStringBuilder("曲線/C:", stringBuilder);
                this.DownslopePattern.AddToStringBuilder("勾配/S:", stringBuilder);
                this.RoutePermanentPattern.AddToStringBuilder("P:", stringBuilder);
                this.TrainPermanentPattern.AddToStringBuilder("M:", stringBuilder);
                if (this.SwitchToAtsSxPosition != double.MaxValue)
                {
                    if (stringBuilder.Length != 0)
                    {
                        stringBuilder.Append(", ");
                    }
                    double switchToAtsSxPosition = this.SwitchToAtsSxPosition - this.Position;
                    stringBuilder.Append(string.Concat("Sx@", switchToAtsSxPosition.ToString("0")));
                }
                if (stringBuilder.Length == 0)
                {
                    data.DebugMessage = this.State.ToString();
                    return;
                }
                data.DebugMessage = string.Concat(this.State.ToString(), " - ", stringBuilder.ToString());
            }
        }
Beispiel #10
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)
        {
            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;
                }
            }
        }
Beispiel #11
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);
            }
        }