Exemple #1
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)
        {
            //Is rain and windscreen wipers enabled?
            if (this.Enabled)
            {
                //First pull a random unlit drop from our array
                var unuseddrops = new List <int>();
                unuseddrops.Clear();
                int count        = 0;
                int unusedlength = 0;
                foreach (bool x in droparray)
                {
                    count++;
                    if (x == false)
                    {
                        //If this drop is not yet lit, add it's index to the unused drops
                        unuseddrops.Add(count);
                        unusedlength++;
                    }
                }
                if (count == 0)
                {
                    //Nothing to pick
                    nextdrop = -1;
                }
                else
                {
                    //Pick a random drop from the unused drops
                    nextdrop = unuseddrops[Plugin.Random.Next(0, unusedlength - 1)];
                }

                //If we're raining,
                if (israining == true)
                {
                    //Generate a random drop interval
                    var dev          = (int)(0.4 * 2000 / rainintensity);
                    int dropinterval = (2000 / rainintensity) + (Plugin.Random.Next(dev, dev * 2));

                    droptimer += (int)data.ElapsedTime.Milliseconds;
                    //If we're past the drop interval, try to add a drop
                    if (droptimer > dropinterval && nextdrop != -1)
                    {
                        droptimer           = 0;
                        droparray[nextdrop] = true;
                        //Play random drop sound
                        if (dropsound1 != -1)
                        {
                            SoundManager.Play((dropsound1 + Plugin.Random.Next(0, dropsound2)), 1.0, 1.0, false);
                        }
                    }
                    else if (droptimer > dropinterval && nextdrop == -1)
                    {
                        //Reset timer and play random drop sound
                        droptimer = 0;
                        if (dropsound1 != -1)
                        {
                            SoundManager.Play((dropsound1 + Plugin.Random.Next(0, dropsound2)), 1.0, 1.0, false);
                        }
                    }
                }

                //This section of code moves our windscreen wipers
                if (currentwiperposition > 0 && currentwiperposition < 100)
                {
                    //Always move wiper if not at rest- No need to set direction
                    movewiper(data.ElapsedTime.Milliseconds);
                    wiperheldtimer = 0.0;
                }
                else if (currentwiperposition == 0 && currentwiperposition == wiperholdposition)
                {
                    //Set new direction
                    wiperdirection = 1;
                    if (wiperspeed == 0)
                    {
                        heldwipers = true;
                    }
                    else if (wiperspeed == 1)
                    {
                        wiperheldtimer += data.ElapsedTime.Milliseconds;
                        if (wiperheldtimer > wiperdelay)
                        {
                            heldwipers     = false;
                            wiperheldtimer = 0.0;
                        }
                        else
                        {
                            heldwipers = true;
                        }
                    }
                    else
                    {
                        heldwipers = false;
                    }

                    if (heldwipers == false)
                    {
                        movewiper(data.ElapsedTime.Milliseconds);
                    }
                }
                else if (currentwiperposition == 0 && currentwiperposition != wiperholdposition)
                {
                    //Set new direction
                    wiperdirection = 1;
                    movewiper(data.ElapsedTime.Milliseconds);
                }
                else if (currentwiperposition == 100 && currentwiperposition != wiperholdposition)
                {
                    //Set new direction
                    wiperdirection = -1;
                    movewiper(data.ElapsedTime.Milliseconds);
                }
                else if (currentwiperposition == 100 && currentwiperposition == wiperholdposition)
                {
                    //Set new direction
                    wiperdirection = -1;
                    if (wiperspeed == 0)
                    {
                        heldwipers = true;
                    }
                    else if (wiperspeed == 1)
                    {
                        wiperheldtimer += data.ElapsedTime.Milliseconds;
                        if (wiperheldtimer > wiperdelay)
                        {
                            heldwipers     = false;
                            wiperheldtimer = 0.0;
                        }
                        else
                        {
                            heldwipers = true;
                        }
                    }
                    else
                    {
                        heldwipers = false;
                    }

                    if (heldwipers == false)
                    {
                        movewiper(data.ElapsedTime.Milliseconds);
                    }
                }
                else
                {
                    //Set new direction
                    wiperdirection = 1;
                    movewiper(data.ElapsedTime.Milliseconds);
                }

                //This section of code plays the wiper sounds
                {
                    int sound;
                    //Figure out if we should play the wetwipe or the drywipe sound
                    if ((double)unusedlength / (double)droparray.Length > 0.8 && wetwipesound != 1)
                    {
                        sound = drywipesound;
                    }
                    else
                    {
                        sound = wetwipesound;
                    }
                    if (currentwiperposition == 1 && wiperdirection == 1)
                    {
                        if (wiperholdposition == 0)
                        {
                            if (wipersoundbehaviour == 0)
                            {
                                SoundManager.Play(sound, 1.0, 1.0, false);
                            }
                        }
                        else
                        {
                            if (wipersoundbehaviour != 0)
                            {
                                SoundManager.Play(sound, 1.0, 1.0, false);
                            }
                        }
                    }
                    else if (currentwiperposition == 99 && wiperdirection == -1)
                    {
                        if (wiperholdposition == 0)
                        {
                            if (wipersoundbehaviour != 0)
                            {
                                SoundManager.Play(sound, 1.0, 1.0, false);
                            }
                        }
                        else
                        {
                            if (wipersoundbehaviour == 0)
                            {
                                SoundManager.Play(sound, 1.0, 1.0, false);
                            }
                        }
                    }
                }

                //This section of code should delete drops
                if (heldwipers == false)
                {
                    //int dropremove = Math.Min(49, (int)(currentwiperposition / (100 / numberofdrops)));
                    int dropremove = Math.Min(numberofdrops - 1, (int)(currentwiperposition / (100.0 / numberofdrops)));
                    droparray[dropremove] = false;
                }

                //Light Windscreen Drops
                {
                    int i = 0;
                    foreach (bool x in droparray)
                    {
                        i++;
                        if (x == true)
                        {
                            this.Train.Panel[(i + dropstartindex - 1)] = 1;
                        }
                        else
                        {
                            this.Train.Panel[(i + dropstartindex - 1)] = 0;
                        }
                    }
                }
                //Animate Windscreen Wiper
                if (wiperindex != -1)
                {
                    this.Train.Panel[wiperindex] = currentwiperposition;
                }
                //Animate Windscreen Wiper Switch
                if (wiperswitchindex != -1)
                {
                    this.Train.Panel[wiperswitchindex] = wiperspeed;
                }
            }
        }
Exemple #2
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;
                }
            }
        }
Exemple #3
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);
            }
        }