PlaySound() статический приватный Метод

Plays a sound.
static private PlaySound ( SoundBuffer buffer, double pitch, double volume, OpenBveApi position, TrainManager train, int car, bool looped ) : SoundSource
buffer SoundBuffer The sound buffer.
pitch double The pitch change factor.
volume double The volume change factor.
position OpenBveApi The position. If a train and car are specified, the position is relative to the car, otherwise absolute.
train TrainManager The train the sound is attached to, or a null reference.
car int The car in the train the sound is attached to.
looped bool Whether to play the sound in a loop.
Результат SoundSource
Пример #1
0
            /// <summary>Releases the emergency brake</summary>
            internal void UnapplyEmergencyBrake()
            {
                if (Handles.EmergencyBrake.Driver)
                {
                    // sound
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                    if (buffer != null)
                    {
                        Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }

                    // apply

                    if (Handles.Brake is AirBrakeHandle)
                    {
                        ApplyAirBrakeHandle(AirBrakeHandleState.Service);
                    }
                    else
                    {
                        ApplyNotch(0, !Handles.SingleHandle, Handles.Brake.MaximumNotch, true);
                    }
                    Handles.EmergencyBrake.Driver = false;
                    // plugin
                    if (Plugin == null)
                    {
                        return;
                    }

                    Plugin.UpdatePower();
                    Plugin.UpdateBrake();
                }
            }
Пример #2
0
 /// <summary>Triggers the playback of a sound</summary>
 /// <param name="Direction">The direction of travel- 1 for forwards, and -1 for backwards</param>
 /// <param name="TriggerType">They type of event which triggered this sound</param>
 /// <param name="Train">The root train which triggered this sound</param>
 /// <param name="CarIndex">The car index which triggered this sound</param>
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (SuppressSoundEvents)
     {
         return;
     }
     if (TriggerType == EventTriggerType.FrontCarFrontAxle | TriggerType == EventTriggerType.OtherCarFrontAxle | TriggerType == EventTriggerType.OtherCarRearAxle | TriggerType == EventTriggerType.RearCarRearAxle)
     {
         if (!PlayerTrainOnly | Train == TrainManager.PlayerTrain)
         {
             Vector3            p      = this.Position;
             double             pitch  = 1.0;
             double             gain   = 1.0;
             Sounds.SoundBuffer buffer = this.SoundBuffer;
             if (buffer != null)
             {
                 if (this.Dynamic)
                 {
                     double spd = Math.Abs(Train.Specs.CurrentAverageSpeed);
                     pitch = spd / this.Speed;
                     gain  = pitch < 0.5 ? 2.0 * pitch : 1.0;
                     if (pitch < 0.2 | gain < 0.2)
                     {
                         buffer = null;
                     }
                 }
                 if (buffer != null)
                 {
                     Sounds.PlaySound(buffer, pitch, gain, p, Train, CarIndex, false);
                 }
             }
             this.DontTriggerAnymore = this.Once;
         }
     }
 }
Пример #3
0
 /// <summary>Called by the controls loop to stop playback of this horn</summary>
 internal void Stop()
 {
     //Reset loop control variable
     LoopStarted = false;
     if (!StartEndSounds & !Loop)
     {
         //Don't stop horns which are play-once single part sounds
         return;
     }
     if (!StartEndSounds & Loop)
     {
         //This sound is a toggle music horn sound
         return;
     }
     if (Sounds.IsPlaying(Source))
     {
         //Stop the loop sound playing
         Sounds.StopSound(Source);
     }
     if (StartEndSounds && !Sounds.IsPlaying(Source) && EndSound != null)
     {
         //If our end sound is defined and in use, play once
         Source = Sounds.PlaySound(EndSound, 1.0, 1.0, SoundPosition,
                                   TrainManager.PlayerTrain,
                                   TrainManager.PlayerTrain.DriverCar, false);
     }
 }
Пример #4
0
            /// <summary>Applies a loco brake notch to this train</summary>
            /// <param name="NotchValue">The loco brake notch value</param>
            /// <param name="Relative">Whether this is relative to the current notch</param>
            internal void ApplyLocoBrakeNotch(int NotchValue, bool Relative)
            {
                int b = Relative ? NotchValue + Handles.LocoBrake.Driver : NotchValue;

                if (b < 0)
                {
                    b = 0;
                }
                else if (b > Handles.LocoBrake.MaximumNotch)
                {
                    b = Handles.LocoBrake.MaximumNotch;
                }

                // brake sound
                if (b < Handles.LocoBrake.Driver)
                {
                    // brake release
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.Brake.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }

                    if (b > 0)
                    {
                        // brake release (not min)
                        buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                    else
                    {
                        // brake min
                        buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer;
                        if (buffer != null)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }
                else if (b > Handles.LocoBrake.Driver)
                {
                    // brake
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }
                }

                Handles.LocoBrake.Driver = b;
                Handles.LocoBrake.Actual = b;                 //TODO: FIXME
            }
Пример #5
0
            /// <summary>Triggers the playback of a sound</summary>
            /// <param name="Direction">The direction of travel- 1 for forwards, and -1 for backwards</param>
            /// <param name="TriggerType">They type of event which triggered this sound</param>
            /// <param name="Train">The root train which triggered this sound</param>
            /// <param name="CarIndex">The car index which triggered this sound</param>
            internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
            {
                if (SuppressSoundEvents)
                {
                    return;
                }

                if (TriggerType == EventTriggerType.FrontCarFrontAxle | TriggerType == EventTriggerType.OtherCarFrontAxle | TriggerType == EventTriggerType.OtherCarRearAxle | TriggerType == EventTriggerType.RearCarRearAxle)
                {
                    Vector3            p;
                    Sounds.SoundBuffer buffer;
                    if (TriggerType == EventTriggerType.FrontCarFrontAxle | TriggerType == EventTriggerType.OtherCarFrontAxle)
                    {
                        if (Train.Specs.CurrentAverageSpeed <= 0.0)
                        {
                            return;
                        }

                        int bufferIndex = Train.Cars[CarIndex].FrontAxle.RunIndex;
                        if (Train.Cars[CarIndex].FrontAxle.PointSounds == null || Train.Cars[CarIndex].FrontAxle.PointSounds.Length == 0)
                        {
                            //No point sounds defined at all
                            return;
                        }
                        if (bufferIndex > Train.Cars[CarIndex].FrontAxle.PointSounds.Length - 1 ||
                            Train.Cars[CarIndex].FrontAxle.PointSounds[bufferIndex].Buffer == null)
                        {
                            //If the switch sound does not exist, return zero
                            //Required to handle legacy trains which don't have idx specific run sounds defined
                            bufferIndex = 0;
                        }
                        buffer = Train.Cars[CarIndex].FrontAxle.PointSounds[bufferIndex].Buffer;
                        p      = Train.Cars[CarIndex].FrontAxle.PointSounds[bufferIndex].Position;
                    }
                    else
                    {
                        return;                         // HACK: Don't trigger sound for the rear axles
                        //buffer = Train.Cars[CarIndex].RearAxle.PointSounds.Buffer;
                        //p = Train.Cars[CarIndex].RearAxle.PointSounds.Position;
                    }
                    if (buffer != null)
                    {
                        double spd   = Math.Abs(Train.Specs.CurrentAverageSpeed);
                        double pitch = spd / this.Speed;
                        double gain  = pitch < 0.5 ? 2.0 * pitch : 1.0;
                        if (pitch < 0.2 | gain < 0.2)
                        {
                            buffer = null;
                        }
                        if (buffer != null)
                        {
                            Sounds.PlaySound(buffer, pitch, gain, p, Train, CarIndex, false);
                        }
                    }
                    this.DontTriggerAnymore = false;
                }
            }
Пример #6
0
        /// <summary>Opens the left-hand or right-hand doors for the specified train</summary>
        /// <param name="Train">The train</param>
        /// <param name="Left">Whether to open the left-hand doors</param>
        /// <param name="Right">Whether to open the right-hand doors</param>
        internal static void OpenTrainDoors(Train Train, bool Left, bool Right)
        {
            bool sl = false, sr = false;

            for (int i = 0; i < Train.Cars.Length; i++)
            {
                if (Left & !Train.Cars[i].Doors[0].AnticipatedOpen)
                {
                    Train.Cars[i].Doors[0].AnticipatedOpen = true;
                    sl = true;
                }
                if (Right & !Train.Cars[i].Doors[1].AnticipatedOpen)
                {
                    Train.Cars[i].Doors[1].AnticipatedOpen = true;
                    sr = true;
                }
            }
            if (sl)
            {
                for (int i = 0; i < Train.Cars.Length; i++)
                {
                    Sounds.SoundBuffer buffer = Train.Cars[i].Doors[0].OpenSound.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[i].Doors[0].OpenSound.Position;
                        Sounds.PlaySound(buffer, Train.Cars[i].Specs.DoorOpenPitch, 1.0, pos, Train, i, false);
                    }
                    for (int j = 0; j < Train.Cars[i].Doors.Length; j++)
                    {
                        if (Train.Cars[i].Doors[j].Direction == -1)
                        {
                            Train.Cars[i].Doors[j].DoorLockDuration = 0.0;
                        }
                    }
                }
            }
            if (sr)
            {
                for (int i = 0; i < Train.Cars.Length; i++)
                {
                    Sounds.SoundBuffer buffer = Train.Cars[i].Doors[1].OpenSound.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[i].Doors[1].OpenSound.Position;
                        Sounds.PlaySound(buffer, Train.Cars[i].Specs.DoorOpenPitch, 1.0, pos, Train, i, false);
                    }
                    for (int j = 0; j < Train.Cars[i].Doors.Length; j++)
                    {
                        if (Train.Cars[i].Doors[j].Direction == 1)
                        {
                            Train.Cars[i].Doors[j].DoorLockDuration = 0.0;
                        }
                    }
                }
            }
        }
Пример #7
0
            /// <summary>Applies a reverser notch</summary>
            /// <param name="Value">The notch to apply</param>
            /// <param name="Relative">Whether this is an absolute value or relative to the previous</param>
            internal void ApplyReverser(int Value, bool Relative)
            {
                int a = (int)Handles.Reverser.Driver;
                int r = Relative ? a + Value : Value;

                if (r < -1)
                {
                    r = -1;
                }

                if (r > 1)
                {
                    r = 1;
                }

                if (a != r)
                {
                    Handles.Reverser.Driver = (ReverserPosition)r;
                    if (Plugin != null)
                    {
                        Plugin.UpdateReverser();
                    }
                    Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None);
                    // sound
                    if (a == 0 & r != 0)
                    {
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.ReverserOn.Buffer;
                        if (buffer == null)
                        {
                            return;
                        }

                        Vector3 pos = Cars[DriverCar].Sounds.ReverserOn.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }
                    else if (a != 0 & r == 0)
                    {
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.ReverserOff.Buffer;
                        if (buffer == null)
                        {
                            return;
                        }

                        Vector3 pos = Cars[DriverCar].Sounds.ReverserOff.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }
                }
            }
Пример #8
0
 internal SoundHandleEx PlaySound(int index, double volume, double pitch, bool looped)
 {
     if (index < 0 || index >= this.Train.Cars[this.Train.DriverCar].Sounds.Plugin.Length || this.Train.Cars[this.Train.DriverCar].Sounds.Plugin[index].Buffer == null)
     {
         return(null);
     }
     Sounds.SoundBuffer buffer         = this.Train.Cars[this.Train.DriverCar].Sounds.Plugin[index].Buffer;
     OpenBveApi.Math.Vector3D position = this.Train.Cars[this.Train.DriverCar].Sounds.Plugin[index].Position;
     Sounds.SoundSource source         = Sounds.PlaySound(buffer, pitch, volume, position, this.Train, this.Train.DriverCar, looped);
     if (this.SoundHandlesCount == this.SoundHandles.Length)
     {
         Array.Resize <SoundHandleEx>(ref this.SoundHandles, this.SoundHandles.Length << 1);
     }
     this.SoundHandles[this.SoundHandlesCount] = new SoundHandleEx(volume, pitch, source);
     this.SoundHandlesCount++;
     return(this.SoundHandles[this.SoundHandlesCount - 1]);
 }
Пример #9
0
        /// <summary>Closes the left-hand or right-hand doors for the specified train</summary>
        /// <param name="Train">The train</param>
        /// <param name="Left">Whether to close the left-hand doors</param>
        /// <param name="Right">Whether to close the right-hand doors</param>
        internal static void CloseTrainDoors(Train Train, bool Left, bool Right)
        {
            bool sl = false, sr = false;

            for (int i = 0; i < Train.Cars.Length; i++)
            {
                if (Left & Train.Cars[i].Doors[0].AnticipatedOpen)
                {
                    Train.Cars[i].Doors[0].AnticipatedOpen = false;
                    sl = true;
                }
                if (Right & Train.Cars[i].Doors[1].AnticipatedOpen)
                {
                    Train.Cars[i].Doors[1].AnticipatedOpen = false;
                    sr = true;
                }
            }
            if (sl)
            {
                for (int i = 0; i < Train.Cars.Length; i++)
                {
                    Sounds.SoundBuffer buffer = Train.Cars[i].Doors[0].CloseSound.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[i].Doors[0].CloseSound.Position;
                        Sounds.PlaySound(buffer, Train.Cars[i].Specs.DoorClosePitch, 1.0, pos, Train, i, false);
                    }
                }
            }
            if (sr)
            {
                for (int i = 0; i < Train.Cars.Length; i++)
                {
                    Sounds.SoundBuffer buffer = Train.Cars[i].Doors[1].CloseSound.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[i].Doors[1].CloseSound.Position;
                        Sounds.PlaySound(buffer, Train.Cars[i].Specs.DoorClosePitch, 1.0, pos, Train, i, false);
                    }
                }
            }
        }
Пример #10
0
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (TriggerType == EventTriggerType.FrontCarFrontAxle)
     {
         if (Direction > 0)
         {
             int d = Train.DriverCar;
             Sounds.SoundBuffer buffer = Train.Cars[d].Sounds.Halt.Buffer;
             if (buffer != null)
             {
                 OpenBveApi.Math.Vector3 pos = Train.Cars[d].Sounds.Halt.Position;
                 if (Train.Specs.PassAlarm == TrainManager.PassAlarmType.Single)
                 {
                     Train.Cars[d].Sounds.Halt.Source = Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, d, false);
                 }
                 else if (Train.Specs.PassAlarm == TrainManager.PassAlarmType.Loop)
                 {
                     Train.Cars[d].Sounds.Halt.Source = Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, d, true);
                 }
             }
             this.DontTriggerAnymore = true;
         }
     }
 }
Пример #11
0
            /// <summary>Called by the controls loop to start playback of this horn</summary>
            internal void Play()
            {
                if (StartEndSounds == true)
                {
                    //New style three-part sounds
                    if (LoopStarted == false)
                    {
                        if (!Sounds.IsPlaying(Source))
                        {
                            if (StartSound != null)
                            {
                                //The start sound is not currently playing, so start it
                                Source = Sounds.PlaySound(StartSound, 1.0, 1.0, SoundPosition,
                                                          TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, false);

                                //Set the loop control variable to started
                                LoopStarted = true;
                            }
                            else
                            {
                                Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition,
                                                          TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, true);
                            }
                        }
                    }
                    else
                    {
                        if (!Sounds.IsPlaying(Source))
                        {
                            //Start our loop sound playing if the start sound is finished
                            Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition,
                                                      TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, true);
                        }
                    }
                }
                else
                {
                    //Original single part sounds
                    if (LoopSound != null)
                    {
                        //Loop is ONLY true if this is a Music Horn
                        if (Loop)
                        {
                            if (!Sounds.IsPlaying(Source) && !LoopStarted)
                            {
                                //On the first keydown event, start the sound source playing and trigger the loop control variable
                                Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition,
                                                          TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, true);
                                LoopStarted = true;
                            }
                            else
                            {
                                if (!LoopStarted)
                                {
                                    //Our loop control variable is reset by the keyup event so this code will only trigger on the
                                    //second keydown meaning our horn toggles
                                    Sounds.StopSound(Source);
                                    LoopStarted = true;
                                }
                            }
                        }
                        else
                        {
                            if (!LoopStarted)
                            {
                                Source = Sounds.PlaySound(LoopSound, 1.0, 1.0, SoundPosition, TrainManager.PlayerTrain,
                                                          TrainManager.PlayerTrain.DriverCar, false);
                            }
                            LoopStarted = true;
                        }
                    }
                }
            }
Пример #12
0
        protected override void Elapse(ElapseData data)
        {
            try {
                double            time = data.TotalTime.Milliseconds;
                Win32VehicleState win32State;
                win32State.Location    = data.Vehicle.Location;
                win32State.Speed       = (float)data.Vehicle.Speed.KilometersPerHour;
                win32State.Time        = (int)Math.Floor(time - 2073600000.0 * Math.Floor(time / 2073600000.0));
                win32State.BcPressure  = (float)data.Vehicle.BcPressure;
                win32State.MrPressure  = (float)data.Vehicle.MrPressure;
                win32State.ErPressure  = (float)data.Vehicle.ErPressure;
                win32State.BpPressure  = (float)data.Vehicle.BpPressure;
                win32State.SapPressure = (float)data.Vehicle.SapPressure;
                win32State.Current     = 0.0f;
                Win32Handles win32Handles;
                win32Handles.Brake         = data.Handles.BrakeNotch;
                win32Handles.Power         = data.Handles.PowerNotch;
                win32Handles.Reverser      = data.Handles.Reverser;
                win32Handles.ConstantSpeed = data.Handles.ConstSpeed ? ConstSpeedInstructions.Enable : ConstSpeedInstructions.Disable;
                Win32Elapse(ref win32Handles.Brake, ref win32State.Location, ref base.Panel[0], ref this.Sound[0]);
                data.Handles.Reverser   = win32Handles.Reverser;
                data.Handles.PowerNotch = win32Handles.Power;
                data.Handles.BrakeNotch = win32Handles.Brake;
                if (win32Handles.ConstantSpeed == ConstSpeedInstructions.Enable)
                {
                    data.Handles.ConstSpeed = true;
                }
                else if (win32Handles.ConstantSpeed == ConstSpeedInstructions.Disable)
                {
                    data.Handles.ConstSpeed = false;
                }
                else if (win32Handles.ConstantSpeed != ConstSpeedInstructions.Continue)
                {
                    this.PluginValid = false;
                }

                /*
                 * Process the sound instructions
                 * */
                for (int i = 0; i < this.Sound.Length; i++)
                {
                    if (this.Sound[i] != this.LastSound[i])
                    {
                        if (this.Sound[i] == SoundInstructions.Stop)
                        {
                            if (i < base.Train.Cars[base.Train.DriverCar].Sounds.Plugin.Length)
                            {
                                Sounds.StopSound(base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source);
                            }
                        }
                        else if (this.Sound[i] > SoundInstructions.Stop & this.Sound[i] <= SoundInstructions.PlayLooping)
                        {
                            if (i < base.Train.Cars[base.Train.DriverCar].Sounds.Plugin.Length)
                            {
                                Sounds.SoundBuffer buffer = base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Buffer;
                                if (buffer != null)
                                {
                                    double volume = (double)(this.Sound[i] - SoundInstructions.Stop) / (double)(SoundInstructions.PlayLooping - SoundInstructions.Stop);
                                    if (Sounds.IsPlaying(base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source))
                                    {
                                        base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source.Volume = volume;
                                    }
                                    else
                                    {
                                        base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source = Sounds.PlaySound(buffer, 1.0, volume, base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Position, base.Train, base.Train.DriverCar, true);
                                    }
                                }
                            }
                        }
                        else if (this.Sound[i] == SoundInstructions.PlayOnce)
                        {
                            if (i < base.Train.Cars[base.Train.DriverCar].Sounds.Plugin.Length)
                            {
                                Sounds.SoundBuffer buffer = base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Buffer;
                                if (buffer != null)
                                {
                                    base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Source = Sounds.PlaySound(buffer, 1.0, 1.0, base.Train.Cars[base.Train.DriverCar].Sounds.Plugin[i].Position, base.Train, base.Train.DriverCar, false);
                                }
                            }
                            this.Sound[i] = SoundInstructions.Continue;
                        }
                        else if (this.Sound[i] != SoundInstructions.Continue)
                        {
                            this.PluginValid = false;
                        }
                        this.LastSound[i] = this.Sound[i];
                    }
                    else
                    {
                        if ((this.Sound[i] < SoundInstructions.Stop | this.Sound[i] > SoundInstructions.PlayLooping) && this.Sound[i] != SoundInstructions.PlayOnce & this.Sound[i] != SoundInstructions.Continue)
                        {
                            this.PluginValid = false;
                        }
                    }
                }
            } catch (Exception ex) {
                base.LastException = ex;
                throw;
            }
        }
Пример #13
0
            /// <summary>Moves the air brake handle to the specified state</summary>
            /// <param name="newState">The state</param>
            internal void ApplyLocoAirBrakeHandle(AirBrakeHandleState newState)
            {
                if (Handles.LocoBrake is LocoAirBrakeHandle)
                {
                    if ((int)newState != Handles.LocoBrake.Driver)
                    {
                        // sound when moved to service
                        if (newState == AirBrakeHandleState.Service)
                        {
                            Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer;
                            if (buffer != null)
                            {
                                Vector3 pos = Cars[DriverCar].Sounds.Brake.Position;
                                Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                            }
                        }

                        // sound
                        if ((int)newState < (int)Handles.Brake.Driver)
                        {
                            // brake release
                            if ((int)newState > 0)
                            {
                                // brake release (not min)
                                Sounds.SoundBuffer buffer;
                                if ((Handles.Brake.Driver - (int)newState > 2 | Cars[DriverCar].Sounds.BrakeHandleFast) && Cars[DriverCar].Sounds.BrakeHandleReleaseFast.Buffer != null)
                                {
                                    buffer = Cars[DriverCar].Sounds.BrakeHandleReleaseFast.Buffer;
                                }
                                else
                                {
                                    buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                                }
                                if (buffer != null)
                                {
                                    Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                                }
                            }
                            else
                            {
                                // brake min
                                Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer;
                                if (buffer != null)
                                {
                                    Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position;
                                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                                }
                            }
                        }
                        else if ((int)newState > (int)Handles.LocoBrake.Driver)
                        {
                            // brake
                            Sounds.SoundBuffer buffer;
                            if (((int)newState - (int)Handles.LocoBrake.Driver > 2 | Cars[DriverCar].Sounds.BrakeHandleFast) && Cars[DriverCar].Sounds.BrakeHandleApplyFast.Buffer != null)
                            {
                                buffer = Cars[DriverCar].Sounds.BrakeHandleApplyFast.Buffer;
                            }
                            else
                            {
                                buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer;
                            }
                            if (buffer != null)
                            {
                                Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position;
                                Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                            }
                        }

                        // apply
                        Handles.LocoBrake.Driver = (int)newState;
                        Handles.LocoBrake.Actual = (int)newState;                         //TODO: FIXME
                        Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None);
                        // plugin
                        if (Plugin != null)
                        {
                            Plugin.UpdatePower();
                            Plugin.UpdateBrake();
                        }
                    }
                }
            }
Пример #14
0
            /// <summary>Moves the air brake handle to the specified state</summary>
            /// <param name="State">The state</param>
            internal void ApplyAirBrakeHandle(AirBrakeHandleState State)
            {
                if (Handles.Brake is AirBrakeHandle)
                {
                    if ((int)State != Handles.Brake.Driver)
                    {
                        // sound when moved to service
                        if (State == AirBrakeHandleState.Service)
                        {
                            Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer;
                            if (buffer != null)
                            {
                                OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.Brake.Position;
                                Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                            }
                        }

                        // sound
                        if ((int)State < (int)Handles.Brake.Driver)
                        {
                            // brake release
                            if ((int)State > 0)
                            {
                                // brake release (not min)
                                Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                                if (buffer != null)
                                {
                                    OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                                }
                            }
                            else
                            {
                                // brake min
                                Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer;
                                if (buffer != null)
                                {
                                    OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position;
                                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                                }
                            }
                        }
                        else if ((int)State > (int)Handles.Brake.Driver)
                        {
                            // brake
                            Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer;
                            if (buffer != null)
                            {
                                OpenBveApi.Math.Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position;
                                Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                            }
                        }

                        // apply
                        Handles.Brake.Driver = (int)State;
                        Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None);
                        // plugin
                        if (Plugin != null)
                        {
                            Plugin.UpdatePower();
                            Plugin.UpdateBrake();
                        }
                    }
                }
            }
Пример #15
0
            /// <summary>Applies the emergency brake</summary>
            internal void ApplyEmergencyBrake()
            {
                // sound
                if (!Handles.EmergencyBrake.Driver)
                {
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.BrakeHandleMax.Buffer;
                    if (buffer != null)
                    {
                        Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMax.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }

                    for (int i = 0; i < Cars.Length; i++)
                    {
                        buffer = Cars[DriverCar].Sounds.EmrBrake.Buffer;
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[i].Sounds.EmrBrake.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }

                // apply
                ApplyNotch(0, !Handles.SingleHandle, Handles.Brake.MaximumNotch, true);
                ApplyAirBrakeHandle(AirBrakeHandleState.Service);
                Handles.EmergencyBrake.Driver = true;
                Handles.HoldBrake.Driver      = false;
                Specs.CurrentConstSpeed       = false;
                if (Handles.EmergencyBrake.Driver)
                {
                    switch (Handles.EmergencyBrake.OtherHandlesBehaviour)
                    {
                    case EbHandleBehaviour.PowerNeutral:
                        if (!Handles.SingleHandle)
                        {
                            ApplyNotch(0, false, 0, true);
                        }

                        break;

                    case EbHandleBehaviour.ReverserNeutral:
                        ApplyReverser(0, false);
                        break;

                    case EbHandleBehaviour.PowerReverserNeutral:
                        if (!Handles.SingleHandle)
                        {
                            ApplyNotch(0, false, 0, true);
                        }

                        ApplyReverser(0, false);
                        break;
                    }
                }

                // plugin
                if (Plugin == null)
                {
                    return;
                }

                Plugin.UpdatePower();
                Plugin.UpdateBrake();
            }
Пример #16
0
        internal static void LeaveCheck(Vector2 Point)
        {
            if (!Loading.SimulationSetup)
            {
                return;
            }

            if (World.CameraMode != CameraViewMode.Interior && World.CameraMode != CameraViewMode.InteriorLookAhead)
            {
                return;
            }

            TrainManager.Car Car = TrainManager.PlayerTrain.Cars[TrainManager.PlayerTrain.DriverCar];
            int add = Car.CarSections[0].CurrentAdditionalGroup + 1;

            if (add < Car.CarSections[0].Groups.Length)
            {
                TrainManager.TouchElement[] TouchElements = Car.CarSections[0].Groups[add].TouchElements;

                if (TouchElements != null)
                {
                    foreach (var TouchElement in TouchElements)
                    {
                        int o = TouchElement.Element.ObjectIndex;
                        ShowObjectSelection(o);
                    }

                    int[] SelectBuffer = new int[2048];

                    PickPre(SelectBuffer, Point, new Vector2(5));

                    RenderSceneSelection();

                    int PickedObjectIndex = PickPost(SelectBuffer);

                    foreach (var TouchElement in TouchElements)
                    {
                        int o = TouchElement.Element.ObjectIndex;
                        HideObjectSelection(o);
                        if (o == PickedObjectIndex)
                        {
                            Car.CarSections[0].CurrentAdditionalGroup = TouchElement.JumpScreenIndex;
                            Car.ChangeCarSection(TrainManager.CarSectionType.Interior);
                            if (TouchElement.SoundIndex >= 0 && TouchElement.SoundIndex < Car.Sounds.Touch.Length)
                            {
                                Sounds.SoundBuffer      Buffer   = Car.Sounds.Touch[TouchElement.SoundIndex].Buffer;
                                OpenBveApi.Math.Vector3 Position = Car.Sounds.Touch[TouchElement.SoundIndex].Position;
                                Sounds.PlaySound(Buffer, 1.0, 1.0, Position, TrainManager.PlayerTrain, TrainManager.PlayerTrain.DriverCar, false);
                            }
                        }

                        // HACK: Normally terminate the command issued once.
                        if (o == PickedObjectIndex || (PickedObjectIndex != PrePickedObjectIndex && o == PrePickedObjectIndex))
                        {
                            for (int i = 0; i < Interface.CurrentControls.Length; i++)
                            {
                                if (Interface.CurrentControls[i].Method != Interface.ControlMethod.Touch)
                                {
                                    continue;
                                }
                                bool EnableOption = false;
                                for (int j = 0; j < Translations.CommandInfos.Length; j++)
                                {
                                    if (Interface.CurrentControls[i].Command == Translations.CommandInfos[j].Command)
                                    {
                                        EnableOption = Translations.CommandInfos[j].EnableOption;
                                        break;
                                    }
                                }
                                if (TouchElement.Command == Interface.CurrentControls[i].Command)
                                {
                                    if (EnableOption && TouchElement.CommandOption != Interface.CurrentControls[i].Option)
                                    {
                                        continue;
                                    }
                                    Interface.CurrentControls[i].AnalogState  = 0.0;
                                    Interface.CurrentControls[i].DigitalState = Interface.DigitalControlState.Released;
                                    MainLoop.RemoveControlRepeat(i);
                                }
                            }
                        }
                    }
                }
            }
        }
Пример #17
0
            /// <summary>Applies a power and / or brake notch to this train</summary>
            /// <param name="PowerValue">The power notch value</param>
            /// <param name="PowerRelative">Whether this is relative to the current notch</param>
            /// <param name="BrakeValue">The brake notch value</param>
            /// <param name="BrakeRelative">Whether this is relative to the current notch</param>
            /// <param name="IsOverMaxDriverNotch"></param>
            internal void ApplyNotch(int PowerValue, bool PowerRelative, int BrakeValue, bool BrakeRelative, bool IsOverMaxDriverNotch = false)
            {
                // determine notch
                int p = PowerRelative ? PowerValue + Handles.Power.Driver : PowerValue;

                if (p < 0)
                {
                    p = 0;
                }
                else if (p > Handles.Power.MaximumNotch)
                {
                    p = Handles.Power.MaximumNotch;
                }
                if (!IsOverMaxDriverNotch && p > Handles.Power.MaximumDriverNotch)
                {
                    p = Handles.Power.MaximumDriverNotch;
                }

                int b = BrakeRelative ? BrakeValue + Handles.Brake.Driver : BrakeValue;

                if (b < 0)
                {
                    b = 0;
                }
                else if (b > Handles.Brake.MaximumNotch)
                {
                    b = Handles.Brake.MaximumNotch;
                }
                if (!IsOverMaxDriverNotch && b > Handles.Brake.MaximumDriverNotch)
                {
                    b = Handles.Brake.MaximumDriverNotch;
                }

                // power sound
                if (p < Handles.Power.Driver)
                {
                    if (p > 0)
                    {
                        // down (not min)
                        Sounds.SoundBuffer buffer;
                        if ((Handles.Power.Driver - p > 2 | Cars[DriverCar].Sounds.PowerHandleFast) && Cars[DriverCar].Sounds.MasterControllerDownFast.Buffer != null)
                        {
                            buffer = Cars[DriverCar].Sounds.MasterControllerDownFast.Buffer;
                        }
                        else
                        {
                            buffer = Cars[DriverCar].Sounds.MasterControllerDown.Buffer;
                        }
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[DriverCar].Sounds.MasterControllerDown.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                    else
                    {
                        // min
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerMin.Buffer;
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[DriverCar].Sounds.MasterControllerMin.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }
                else if (p > Handles.Power.Driver)
                {
                    if (p < Handles.Power.MaximumDriverNotch)
                    {
                        // up (not max)
                        Sounds.SoundBuffer buffer;
                        if ((Handles.Power.Driver - p > 2 | Cars[DriverCar].Sounds.PowerHandleFast) && Cars[DriverCar].Sounds.MasterControllerUpFast.Buffer != null)
                        {
                            buffer = Cars[DriverCar].Sounds.MasterControllerUpFast.Buffer;
                        }
                        else
                        {
                            buffer = Cars[DriverCar].Sounds.MasterControllerUp.Buffer;
                        }
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[DriverCar].Sounds.MasterControllerUp.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                    else
                    {
                        // max
                        Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.MasterControllerMax.Buffer;
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[DriverCar].Sounds.MasterControllerMax.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }

                // brake sound
                if (b < Handles.Brake.Driver)
                {
                    // brake release
                    Sounds.SoundBuffer buffer = Cars[DriverCar].Sounds.Brake.Buffer;
                    if (buffer != null)
                    {
                        Vector3 pos = Cars[DriverCar].Sounds.Brake.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }

                    if (b > 0)
                    {
                        // brake release (not min)
                        if ((Handles.Brake.Driver - b > 2 | Cars[DriverCar].Sounds.BrakeHandleFast) && Cars[DriverCar].Sounds.BrakeHandleReleaseFast.Buffer != null)
                        {
                            buffer = Cars[DriverCar].Sounds.BrakeHandleReleaseFast.Buffer;
                        }
                        else
                        {
                            buffer = Cars[DriverCar].Sounds.BrakeHandleRelease.Buffer;
                        }
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleRelease.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                    else
                    {
                        // brake min
                        buffer = Cars[DriverCar].Sounds.BrakeHandleMin.Buffer;
                        if (buffer != null)
                        {
                            Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleMin.Position;
                            Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                        }
                    }
                }
                else if (b > Handles.Brake.Driver)
                {
                    // brake
                    Sounds.SoundBuffer buffer;
                    if ((b - Handles.Brake.Driver > 2 | Cars[DriverCar].Sounds.BrakeHandleFast) && Cars[DriverCar].Sounds.BrakeHandleApplyFast.Buffer != null)
                    {
                        buffer = Cars[DriverCar].Sounds.BrakeHandleApplyFast.Buffer;
                    }
                    else
                    {
                        buffer = Cars[DriverCar].Sounds.BrakeHandleApply.Buffer;
                    }

                    if (buffer != null)
                    {
                        Vector3 pos = Cars[DriverCar].Sounds.BrakeHandleApply.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, DriverCar, false);
                    }
                }

                // apply notch
                if (Handles.SingleHandle)
                {
                    if (b != 0)
                    {
                        p = 0;
                    }
                }

                Handles.Power.Driver = p;
                Handles.Brake.Driver = b;
                Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None);
                // plugin
                if (Plugin != null)
                {
                    Plugin.UpdatePower();
                    Plugin.UpdateBrake();
                }
            }
Пример #18
0
            /// <summary>Updates the brake system for a car within this train</summary>
            /// <remarks>This must remain a property of the train, for easy access to various base properties</remarks>
            /// <param name="CarIndex">The induvidual car</param>
            /// <param name="TimeElapsed">The frame time elapsed</param>
            /// <param name="DecelerationDueToBrake">The total brake deceleration this car provides</param>
            /// <param name="DecelerationDueToMotor">The total motor deceleration this car provides</param>
            private void UpdateBrakeSystem(int CarIndex, double TimeElapsed, out double DecelerationDueToBrake, out double DecelerationDueToMotor)
            {
                DecelerationDueToBrake = 0.0;
                // air compressor
                if (Cars[CarIndex].CarBrake.brakeType == BrakeType.Main)
                {
                    if (Cars[CarIndex].CarBrake.airCompressor.Enabled)
                    {
                        if (Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure > Cars[CarIndex].CarBrake.mainReservoir.MaximumPressure)
                        {
                            Cars[CarIndex].CarBrake.airCompressor.Enabled = false;
                            Cars[CarIndex].Sounds.CpLoopStarted           = false;
                            Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpEnd.Buffer;
                            if (buffer != null)
                            {
                                OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpEnd.Position;
                                Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false);
                            }

                            buffer = Cars[CarIndex].Sounds.CpLoop.Buffer;
                            if (buffer != null)
                            {
                                Sounds.StopSound(Cars[CarIndex].Sounds.CpLoop.Source);
                            }
                        }
                        else
                        {
                            Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure += Cars[CarIndex].CarBrake.airCompressor.Rate * TimeElapsed;
                            if (!Cars[CarIndex].Sounds.CpLoopStarted && Game.SecondsSinceMidnight > Cars[CarIndex].Sounds.CpStartTimeStarted + 5.0)
                            {
                                Cars[CarIndex].Sounds.CpLoopStarted = true;
                                Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpLoop.Buffer;
                                if (buffer != null)
                                {
                                    OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpLoop.Position;
                                    Cars[CarIndex].Sounds.CpLoop.Source = Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, true);
                                }
                            }
                        }
                    }
                    else
                    {
                        if (Cars[CarIndex].CarBrake.mainReservoir.CurrentPressure < Cars[CarIndex].CarBrake.mainReservoir.MinimumPressure)
                        {
                            Cars[CarIndex].CarBrake.airCompressor.Enabled = true;
                            Cars[CarIndex].Sounds.CpStartTimeStarted      = Game.SecondsSinceMidnight;
                            Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.CpStart.Buffer;
                            if (buffer != null)
                            {
                                OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.CpStart.Position;
                                Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false);
                            }
                        }
                    }
                }

                if (CarIndex == DriverCar && Handles.HasLocoBrake)
                {
                    switch (Handles.LocoBrakeType)
                    {
                    case LocoBrakeType.Independant:
                        //With an independant Loco brake, we always want to use this handle
                        Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake);
                        break;

                    case LocoBrakeType.Combined:
                        if (Handles.LocoBrake is LocoBrakeHandle && Handles.Brake is NotchedHandle)
                        {
                            //Both handles are of the notched type
                            if (Handles.Brake.MaximumNotch == Handles.LocoBrake.MaximumNotch)
                            {
                                //Identical number of notches, so return the handle with the higher setting
                                if (Handles.LocoBrake.Actual >= Handles.Brake.Actual)
                                {
                                    Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake);
                                }
                                else
                                {
                                    Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake);
                                }
                            }
                            else if (Handles.Brake.MaximumNotch > Handles.LocoBrake.MaximumNotch)
                            {
                                double nc = ((double)Handles.LocoBrake.Actual / Handles.LocoBrake.MaximumNotch) * Handles.Brake.MaximumNotch;
                                if (nc > Handles.Brake.Actual)
                                {
                                    Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake);
                                }
                                else
                                {
                                    Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake);
                                }
                            }
                            else
                            {
                                double nc = ((double)Handles.Brake.Actual / Handles.Brake.MaximumNotch) * Handles.LocoBrake.MaximumNotch;
                                if (nc > Handles.LocoBrake.Actual)
                                {
                                    Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake);
                                }
                                else
                                {
                                    Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake);
                                }
                            }
                        }
                        else if (Handles.LocoBrake is LocoAirBrakeHandle && Handles.Brake is AirBrakeHandle)
                        {
                            if (Handles.LocoBrake.Actual < Handles.Brake.Actual)
                            {
                                Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake);
                            }
                            else
                            {
                                Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake);
                            }
                        }
                        else
                        {
                            double p, tp;
                            //Calculate the pressure differentials for the two handles
                            if (Handles.LocoBrake is LocoAirBrakeHandle)
                            {
                                //Air brake handle
                                p  = Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure;
                                tp = (Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure / Handles.Brake.MaximumNotch) * Handles.Brake.Actual;
                            }
                            else
                            {
                                //Notched handle
                                p  = Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure;
                                tp = (Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure / Handles.LocoBrake.MaximumNotch) * Handles.LocoBrake.Actual;
                            }

                            if (p < tp)
                            {
                                Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake);
                            }
                            else
                            {
                                Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake);
                            }
                        }
                        break;

                    case LocoBrakeType.Blocking:
                        if (Handles.LocoBrake.Actual != 0)
                        {
                            Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.LocoBrake, out DecelerationDueToBrake);
                        }
                        else
                        {
                            Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake);
                        }

                        break;
                    }
                }
                else
                {
                    Cars[CarIndex].CarBrake.Update(TimeElapsed, Cars[DriverCar].Specs.CurrentSpeed, Handles.Brake, out DecelerationDueToBrake);
                }


                switch (Cars[CarIndex].CarBrake.airSound)
                {
                case AirSound.AirZero:
                {
                    Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.AirZero.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.AirZero.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false);
                    }

                    break;
                }

                case AirSound.Air:
                {
                    Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.Air.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.Air.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false);
                    }
                    break;
                }

                case AirSound.AirHigh:
                {
                    Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.AirHigh.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.AirHigh.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, this, CarIndex, false);
                    }
                    break;
                }
                }

                // deceleration provided by motor
                if (!(Cars[CarIndex].CarBrake is AutomaticAirBrake) && Math.Abs(Cars[CarIndex].Specs.CurrentSpeed) >= Cars[CarIndex].CarBrake.brakeControlSpeed & Handles.Reverser.Actual != 0 & !Handles.EmergencyBrake.Actual)
                {
                    double f;
                    if (Handles.LocoBrake.Actual != 0 && CarIndex == DriverCar)
                    {
                        f = (double)Handles.LocoBrake.Actual / (double)Handles.Brake.MaximumNotch;
                    }
                    else
                    {
                        f = (double)Handles.Brake.Actual / (double)Handles.Brake.MaximumNotch;
                    }

                    double a = Cars[CarIndex].Specs.MotorDeceleration;
                    DecelerationDueToMotor = f * a;
                }
                else
                {
                    DecelerationDueToMotor = 0.0;
                }

                // hold brake
                Cars[CarIndex].Specs.HoldBrake.Update(ref DecelerationDueToMotor, Handles.HoldBrake.Actual);
                {
                    // rub sound
                    Sounds.SoundBuffer buffer = Cars[CarIndex].Sounds.Rub.Buffer;
                    if (buffer != null)
                    {
                        double spd   = Math.Abs(Cars[CarIndex].Specs.CurrentSpeed);
                        double pitch = 1.0 / (spd + 1.0) + 1.0;
                        double gain  = Cars[CarIndex].Derailed ? 0.0 : Cars[CarIndex].CarBrake.brakeCylinder.CurrentPressure / Cars[CarIndex].CarBrake.brakeCylinder.ServiceMaximumPressure;
                        if (spd < 1.38888888888889)
                        {
                            double t = spd * spd;
                            gain *= 1.5552 * t - 0.746496 * spd * t;
                        }
                        else if (spd > 12.5)
                        {
                            double       t          = spd - 12.5;
                            const double fadefactor = 0.1;
                            gain *= 1.0 / (fadefactor * t * t + 1.0);
                        }

                        if (Sounds.IsPlaying(Cars[CarIndex].Sounds.Rub.Source))
                        {
                            if (pitch > 0.01 & gain > 0.001)
                            {
                                Cars[CarIndex].Sounds.Rub.Source.Pitch  = pitch;
                                Cars[CarIndex].Sounds.Rub.Source.Volume = gain;
                            }
                            else
                            {
                                Sounds.StopSound(Cars[CarIndex].Sounds.Rub.Source);
                            }
                        }
                        else if (pitch > 0.02 & gain > 0.01)
                        {
                            OpenBveApi.Math.Vector3 pos = Cars[CarIndex].Sounds.Rub.Position;
                            Cars[CarIndex].Sounds.Rub.Source = Sounds.PlaySound(buffer, pitch, gain, pos, this, CarIndex, true);
                        }
                    }
                }
            }
            internal override void Update(double TimeElapsed, bool ForceUpdate)
            {
                const double extraRadius = 10.0;
                double       z           = Object.TranslateZFunction == null ? 0.0 : Object.TranslateZFunction.LastResult;
                double       pa          = TrackPosition + z - Radius - extraRadius;
                double       pb          = TrackPosition + z + Radius + extraRadius;
                double       ta          = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z - World.BackgroundImageDistance - World.ExtraViewingDistance;
                double       tb          = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z + World.BackgroundImageDistance + World.ExtraViewingDistance;
                bool         visible     = pb >= ta & pa <= tb;

                if (visible | ForceUpdate)
                {
                    if (Object.SecondsSinceLastUpdate >= Object.RefreshRate | ForceUpdate)
                    {
                        double timeDelta = Object.SecondsSinceLastUpdate + TimeElapsed;
                        Object.SecondsSinceLastUpdate = 0.0;
                        TrainManager.Train train         = null;
                        double             trainDistance = double.MaxValue;
                        for (int j = 0; j < TrainManager.Trains.Length; j++)
                        {
                            if (TrainManager.Trains[j].State == TrainManager.TrainState.Available)
                            {
                                double distance;
                                if (TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition < TrackPosition)
                                {
                                    distance = TrackPosition - TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition;
                                }
                                else if (TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition > TrackPosition)
                                {
                                    distance = TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition - TrackPosition;
                                }
                                else
                                {
                                    distance = 0;
                                }
                                if (distance < trainDistance)
                                {
                                    train         = TrainManager.Trains[j];
                                    trainDistance = distance;
                                }
                            }
                        }
                        Object.Update(false, train, train == null ? 0 : train.DriverCar, SectionIndex, TrackPosition, Position, Direction, Up, Side, false, true, true, timeDelta, true);
                        if (this.Object.CurrentState != this.lastState && Loading.SimulationSetup)
                        {
                            if (this.SingleBuffer && this.Buffers[0] != null)
                            {
                                switch (this.Object.CurrentState)
                                {
                                case -1:
                                    if (this.PlayOnHide)
                                    {
                                        this.Source = Sounds.PlaySound(this.Buffers[0], this.currentPitch, this.currentVolume, this.Position, false);
                                    }
                                    break;

                                case 0:
                                    if (this.PlayOnShow || this.lastState != -1)
                                    {
                                        this.Source = Sounds.PlaySound(this.Buffers[0], this.currentPitch, this.currentVolume, this.Position, false);
                                    }
                                    break;

                                default:
                                    this.Source = Sounds.PlaySound(this.Buffers[0], this.currentPitch, this.currentVolume, this.Position, false);
                                    break;
                                }
                            }
                            else
                            {
                                int bufferIndex = this.Object.CurrentState + 1;
                                if (bufferIndex < this.Buffers.Length && this.Buffers[bufferIndex] != null)
                                {
                                    switch (bufferIndex)
                                    {
                                    case 0:
                                        if (this.PlayOnHide)
                                        {
                                            this.Source = Sounds.PlaySound(this.Buffers[bufferIndex], this.currentPitch, this.currentVolume, this.Position, false);
                                        }
                                        break;

                                    case 1:
                                        if (this.PlayOnShow || this.lastState != -1)
                                        {
                                            this.Source = Sounds.PlaySound(this.Buffers[bufferIndex], this.currentPitch, this.currentVolume, this.Position, false);
                                        }
                                        break;

                                    default:
                                        this.Source = Sounds.PlaySound(this.Buffers[bufferIndex], this.currentPitch, this.currentVolume, this.Position, false);
                                        break;
                                    }
                                }
                            }
                        }
                    }
                    else
                    {
                        Object.SecondsSinceLastUpdate += TimeElapsed;
                    }
                    if (!Visible)
                    {
                        Renderer.ShowObject(Object.ObjectIndex, ObjectType.Dynamic);
                        Visible = true;
                    }
                }
                else
                {
                    Object.SecondsSinceLastUpdate += TimeElapsed;
                    if (Visible)
                    {
                        Renderer.HideObject(Object.ObjectIndex);
                        Visible = false;
                    }
                }
                this.lastState = this.Object.CurrentState;
            }
Пример #20
0
        /// <summary>Is called once a frame to update the station state for the given train</summary>
        /// <param name="Train">The train</param>
        /// <param name="TimeElapsed">The frame time elapsed</param>
        private static void UpdateTrainStation(Train Train, double TimeElapsed)
        {
            if (Train.Station >= 0)
            {
                int    i = Train.Station;
                int    n = Game.Stations[Train.Station].GetStopIndex(Train.Cars.Length);
                double tf, tb;
                if (n >= 0)
                {
                    double p0 = Train.Cars[0].FrontAxle.Follower.TrackPosition - Train.Cars[0].FrontAxle.Position + 0.5 * Train.Cars[0].Length;
                    double p1 = Game.Stations[i].Stops[n].TrackPosition;
                    tf = Game.Stations[i].Stops[n].ForwardTolerance;
                    tb = Game.Stations[i].Stops[n].BackwardTolerance;
                    Train.StationDistanceToStopPoint = p1 - p0;
                }
                else
                {
                    Train.StationDistanceToStopPoint = 0.0;
                    tf = 5.0;
                    tb = 5.0;
                }
                if (Train.StationState == TrainStopState.Pending)
                {
                    Train.StationDepartureSoundPlayed = false;
                    if (Game.StopsAtStation(i, Train))
                    {
                        Train.StationDepartureSoundPlayed = false;
                        //Check whether all doors are controlled by the driver
                        if (Train.Specs.DoorOpenMode != DoorMode.Manual)
                        {
                            //Check that we are not moving
                            if (Math.Abs(Train.Specs.CurrentAverageSpeed) < 0.1 / 3.6 &
                                Math.Abs(Train.Specs.CurrentAverageAcceleration) < 0.1 / 3.6)
                            {
                                //Check the interlock state for the doors
                                switch (Train.Specs.DoorInterlockState)
                                {
                                case DoorInterlockStates.Unlocked:
                                    if (Game.Stations[i].OpenLeftDoors || Game.Stations[i].OpenRightDoors)
                                    {
                                        AttemptToOpenDoors(Train, i, tb, tf);
                                    }
                                    break;

                                case DoorInterlockStates.Left:
                                    if (Game.Stations[i].OpenLeftDoors && !Game.Stations[i].OpenRightDoors)
                                    {
                                        AttemptToOpenDoors(Train, i, tb, tf);
                                    }
                                    break;

                                case DoorInterlockStates.Right:
                                    if (!Game.Stations[i].OpenLeftDoors && Game.Stations[i].OpenRightDoors)
                                    {
                                        AttemptToOpenDoors(Train, i, tb, tf);
                                    }
                                    break;

                                case DoorInterlockStates.Locked:
                                    //All doors are currently locked, do nothing
                                    break;
                                }
                            }
                        }
                        // detect arrival
                        if (Train.Specs.CurrentAverageSpeed > -0.277777777777778 & Train.Specs.CurrentAverageSpeed < 0.277777777777778)
                        {
                            bool left, right;
                            if (Game.Stations[i].OpenLeftDoors)
                            {
                                left = false;
                                for (int j = 0; j < Train.Cars.Length; j++)
                                {
                                    if (Train.Cars[j].Doors[0].AnticipatedOpen)
                                    {
                                        left = true; break;
                                    }
                                }
                            }
                            else
                            {
                                left = true;
                            }
                            if (Game.Stations[i].OpenRightDoors)
                            {
                                right = false;
                                for (int j = 0; j < Train.Cars.Length; j++)
                                {
                                    if (Train.Cars[j].Doors[1].AnticipatedOpen)
                                    {
                                        right = true; break;
                                    }
                                }
                            }
                            else
                            {
                                right = true;
                            }
                            if (left & right)
                            {
                                // arrival
                                Train.StationState  = TrainStopState.Boarding;
                                Train.StationAdjust = false;
                                Train.Specs.DoorClosureAttempted = false;
                                Sounds.StopSound(Train.Cars[Train.DriverCar].Sounds.Halt.Source);
                                Sounds.SoundBuffer buffer = Game.Stations[i].ArrivalSoundBuffer;
                                if (buffer != null)
                                {
                                    OpenBveApi.Math.Vector3 pos = Game.Stations[i].SoundOrigin;
                                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, false);
                                }
                                Train.StationArrivalTime   = Game.SecondsSinceMidnight;
                                Train.StationDepartureTime = Game.Stations[i].DepartureTime - Train.TimetableDelta;
                                if (Train.StationDepartureTime - Game.SecondsSinceMidnight < Game.Stations[i].StopTime)
                                {
                                    Train.StationDepartureTime = Game.SecondsSinceMidnight + Game.Stations[i].StopTime;
                                }
                                Train.Passengers.PassengerRatio = Game.Stations[i].PassengerRatio;
                                UpdateTrainMassFromPassengerRatio(Train);
                                if (Train == PlayerTrain)
                                {
                                    double early = 0.0;
                                    if (Game.Stations[i].ArrivalTime >= 0.0)
                                    {
                                        early = (Game.Stations[i].ArrivalTime - Train.TimetableDelta) - Train.StationArrivalTime;
                                    }
                                    string s;
                                    if (early < -1.0)
                                    {
                                        s = Translations.GetInterfaceString("message_station_arrival_late");
                                    }
                                    else if (early > 1.0)
                                    {
                                        s = Translations.GetInterfaceString("message_station_arrival_early");
                                    }
                                    else
                                    {
                                        s = Translations.GetInterfaceString("message_station_arrival");
                                    }
                                    System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
                                    TimeSpan a = TimeSpan.FromSeconds(Math.Abs(early));
                                    string   b = a.Hours.ToString("00", Culture) + ":" + a.Minutes.ToString("00", Culture) + ":" + a.Seconds.ToString("00", Culture);
                                    if (Train.StationDistanceToStopPoint < -0.1)
                                    {
                                        s += Translations.GetInterfaceString("message_delimiter") + Translations.GetInterfaceString("message_station_overrun");
                                    }
                                    else if (Train.StationDistanceToStopPoint > 0.1)
                                    {
                                        s += Translations.GetInterfaceString("message_delimiter") + Translations.GetInterfaceString("message_station_underrun");
                                    }
                                    double d = Math.Abs(Train.StationDistanceToStopPoint);
                                    string c = d.ToString("0.0", Culture);
                                    if (Game.Stations[i].Type == StationType.Terminal)
                                    {
                                        s += Translations.GetInterfaceString("message_delimiter") + Translations.GetInterfaceString("message_station_terminal");
                                    }
                                    s = s.Replace("[name]", Game.Stations[i].Name);
                                    s = s.Replace("[time]", b);
                                    s = s.Replace("[difference]", c);
                                    Game.AddMessage(s, MessageManager.MessageDependency.StationArrival, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 10.0, null);
                                    if (Game.Stations[i].Type == StationType.Normal)
                                    {
                                        s = Translations.GetInterfaceString("message_station_deadline");
                                        Game.AddMessage(s, MessageManager.MessageDependency.StationDeparture, Interface.GameMode.Normal, MessageColor.White, double.PositiveInfinity, null);
                                    }
                                    Timetable.UpdateCustomTimetable(Game.Stations[i].TimetableDaytimeTexture, Game.Stations[i].TimetableNighttimeTexture);
                                }
                                // schedule door locks (passengers stuck between the doors)
                                for (int j = 0; j < Train.Cars.Length; j++)
                                {
                                    for (int k = 0; k < Train.Cars[j].Doors.Length; k++)
                                    {
                                        Train.Cars[j].Doors[k].DoorLockDuration = 0.0;
                                        if (Game.Stations[i].OpenLeftDoors & Train.Cars[j].Doors[k].Direction == -1 | Game.Stations[i].OpenRightDoors & Train.Cars[j].Doors[k].Direction == 1)
                                        {
                                            double p = 0.005 * Game.Stations[i].PassengerRatio * Game.Stations[i].PassengerRatio * Game.Stations[i].PassengerRatio * Game.Stations[i].PassengerRatio;
                                            if (Program.RandomNumberGenerator.NextDouble() < p)
                                            {
                                                /*
                                                 * -- door lock at state --
                                                 * minimum: 0.2 (nearly closed)
                                                 * maximum: 0.8 (nearly opened)
                                                 * */
                                                Train.Cars[j].Doors[k].DoorLockState = 0.2 + 0.6 * Program.RandomNumberGenerator.NextDouble();

                                                /* -- waiting time --
                                                 * minimum: 2.9 s
                                                 * maximum: 40.0 s
                                                 * average: 7.6 s
                                                 * */
                                                p = Program.RandomNumberGenerator.NextDouble();
                                                Train.Cars[j].Doors[k].DoorLockDuration = (50.0 - 10.0 * p) / (17.0 - 16.0 * p);
                                            }
                                        }
                                    }
                                }
                            }
                            else if (Train.Specs.CurrentAverageSpeed > -0.277777777777778 & Train.Specs.CurrentAverageSpeed < 0.277777777777778)
                            {
                                // correct stop position
                                if (!Train.StationAdjust & (Train.StationDistanceToStopPoint > tb | Train.StationDistanceToStopPoint < -tf))
                                {
                                    Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.Adjust.Buffer;
                                    if (buffer != null)
                                    {
                                        OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.Adjust.Position;
                                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                                    }
                                    if (Train == TrainManager.PlayerTrain)
                                    {
                                        Game.AddMessage(Translations.GetInterfaceString("message_station_correct"), MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.Orange, Game.SecondsSinceMidnight + 5.0, null);
                                    }
                                    Train.StationAdjust = true;
                                }
                            }
                            else
                            {
                                Train.StationAdjust = false;
                            }
                        }
                    }
                }
                else if (Train.StationState == TrainStopState.Boarding)
                {
                    for (int j = 0; j < Train.Cars.Length; j++)
                    {
                        if (GetDoorsState(Train, j, Game.Stations[i].OpenLeftDoors, Game.Stations[i].OpenRightDoors) == (TrainDoorState.Opened | TrainDoorState.AllOpened))
                        {
                            //Check whether all doors are controlled by the driver, and whether this is a non-standard station type
                            //e.g. Change ends
                            if (Train.Specs.DoorCloseMode != DoorMode.Manual & Game.Stations[i].Type == StationType.Normal)
                            {
                                //Check the interlock state for the doors
                                switch (Train.Specs.DoorInterlockState)
                                {
                                case DoorInterlockStates.Unlocked:
                                    AttemptToCloseDoors(Train);
                                    break;

                                case DoorInterlockStates.Left:
                                    if (Game.Stations[i].OpenLeftDoors)
                                    {
                                        AttemptToCloseDoors(Train);
                                    }
                                    break;

                                case DoorInterlockStates.Right:
                                    if (Game.Stations[i].OpenRightDoors)
                                    {
                                        AttemptToCloseDoors(Train);
                                    }
                                    break;

                                case DoorInterlockStates.Locked:
                                    //All doors are currently locked, do nothing
                                    break;
                                }

                                if (Train.Specs.DoorInterlockState != DoorInterlockStates.Locked & Train.Specs.DoorClosureAttempted)
                                {
                                    if (Game.Stations[i].OpenLeftDoors && !Train.Cars[j].Doors[0].AnticipatedReopen && Program.RandomNumberGenerator.NextDouble() < Game.Stations[i].ReopenDoor)
                                    {
                                        Train.Cars[j].Doors[0].ReopenLimit           = Program.RandomNumberGenerator.Next(1, Game.Stations[i].ReopenStationLimit);
                                        Train.Cars[j].Doors[0].ReopenCounter         = 0;
                                        Train.Cars[j].Doors[0].InterferingObjectRate = Program.RandomNumberGenerator.Next(1, Game.Stations[i].MaxInterferingObjectRate) * 0.01;
                                        if (Train.Cars[j].Doors[0].InterferingObjectRate * Train.Specs.DoorWidth >= Train.Specs.DoorMaxTolerance)
                                        {
                                            Train.Cars[j].Doors[0].AnticipatedReopen = true;
                                        }
                                    }
                                    if (Game.Stations[i].OpenRightDoors && !Train.Cars[j].Doors[1].AnticipatedReopen && Program.RandomNumberGenerator.NextDouble() < Game.Stations[i].ReopenDoor)
                                    {
                                        Train.Cars[j].Doors[1].ReopenLimit           = Program.RandomNumberGenerator.Next(1, Game.Stations[i].ReopenStationLimit);
                                        Train.Cars[j].Doors[1].ReopenCounter         = 0;
                                        Train.Cars[j].Doors[1].InterferingObjectRate = Program.RandomNumberGenerator.Next(1, Game.Stations[i].MaxInterferingObjectRate) * 0.01;
                                        if (Train.Cars[j].Doors[1].InterferingObjectRate * Train.Specs.DoorWidth >= Train.Specs.DoorMaxTolerance)
                                        {
                                            Train.Cars[j].Doors[1].AnticipatedReopen = true;
                                        }
                                    }
                                }
                            }
                        }
                    }
                    // detect departure
                    bool left, right;
                    if (!Game.Stations[i].OpenLeftDoors & !Game.Stations[i].OpenRightDoors)
                    {
                        left  = true;
                        right = true;
                    }
                    else
                    {
                        if (Game.Stations[i].OpenLeftDoors)
                        {
                            left = false;
                            for (int j = 0; j < Train.Cars.Length; j++)
                            {
                                for (int k = 0; k < Train.Cars[j].Doors.Length; k++)
                                {
                                    if (Train.Cars[j].Doors[k].State != 0.0)
                                    {
                                        left = true; break;
                                    }
                                }
                                if (left)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            left = false;
                        }
                        if (Game.Stations[i].OpenRightDoors)
                        {
                            right = false;
                            for (int j = 0; j < Train.Cars.Length; j++)
                            {
                                for (int k = 0; k < Train.Cars[j].Doors.Length; k++)
                                {
                                    if (Train.Cars[j].Doors[k].State != 0.0)
                                    {
                                        right = true; break;
                                    }
                                }
                                if (right)
                                {
                                    break;
                                }
                            }
                        }
                        else
                        {
                            right = false;
                        }
                    }
                    // departure sound
                    if (!Train.StationDepartureSoundPlayed)
                    {
                        Sounds.SoundBuffer buffer = Game.Stations[i].DepartureSoundBuffer;
                        if (buffer != null)
                        {
                            double dur = Sounds.GetDuration(buffer);
                            if (Game.SecondsSinceMidnight >= Train.StationDepartureTime - dur)
                            {
                                Sounds.PlaySound(buffer, 1.0, 1.0, Game.Stations[i].SoundOrigin, false);
                                Train.StationDepartureSoundPlayed = true;
                            }
                        }
                    }
                    for (int j = 0; j < Train.Cars.Length; j++)
                    {
                        if (Train.Cars[j].Doors[0].AnticipatedReopen && Train.Cars[j].Doors[0].State == Train.Cars[j].Doors[0].InterferingObjectRate)
                        {
                            if (Train.Cars[j].Doors[0].NextReopenTime == 0.0)
                            {
                                Train.Cars[j].Doors[0].NextReopenTime = Game.SecondsSinceMidnight + Game.Stations[i].InterferenceInDoor;
                            }
                            else if (Train.Cars[j].Doors[0].ReopenCounter < Train.Cars[j].Doors[0].ReopenLimit)
                            {
                                if (Game.SecondsSinceMidnight >= Train.Cars[j].Doors[0].NextReopenTime)
                                {
                                    OpenTrainDoors(Train, j, true, false);
                                }
                            }
                            else
                            {
                                Train.Cars[j].Doors[0].AnticipatedReopen = false;
                            }
                        }
                        if (Train.Cars[j].Doors[1].AnticipatedReopen && Train.Cars[j].Doors[1].State == Train.Cars[j].Doors[1].InterferingObjectRate)
                        {
                            if (Train.Cars[j].Doors[1].NextReopenTime == 0.0)
                            {
                                Train.Cars[j].Doors[1].NextReopenTime = Game.SecondsSinceMidnight + Game.Stations[i].InterferenceInDoor;
                            }
                            else if (Train.Cars[j].Doors[1].ReopenCounter < Train.Cars[j].Doors[1].ReopenLimit)
                            {
                                if (Game.SecondsSinceMidnight >= Train.Cars[j].Doors[1].NextReopenTime)
                                {
                                    OpenTrainDoors(Train, j, false, true);
                                }
                            }
                            else
                            {
                                Train.Cars[j].Doors[1].AnticipatedReopen = false;
                            }
                        }
                    }
                    TrainDoorState doorState = GetDoorsState(Train, Game.Stations[i].OpenLeftDoors, Game.Stations[i].OpenRightDoors);
                    if (Train.Specs.DoorCloseMode == DoorMode.Manual || doorState == TrainDoorState.None || doorState == (TrainDoorState.Closed | TrainDoorState.AllClosed))
                    {
                        if (left | right)
                        {
                            // departure message
                            if (Game.SecondsSinceMidnight > Train.StationDepartureTime && (Game.Stations[i].Type != StationType.Terminal || Train != PlayerTrain))
                            {
                                Train.StationState = TrainStopState.Completed;
                                if (Train == PlayerTrain & Game.Stations[i].Type == StationType.Normal)
                                {
                                    if (!Game.Stations[i].OpenLeftDoors & !Game.Stations[i].OpenRightDoors | Train.Specs.DoorCloseMode != DoorMode.Manual)
                                    {
                                        Game.AddMessage(Translations.GetInterfaceString("message_station_depart"), MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 5.0, null);
                                    }
                                    else
                                    {
                                        Game.AddMessage(Translations.GetInterfaceString("message_station_depart_closedoors"), MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 5.0, null);
                                    }
                                }
                                else if (Game.Stations[i].Type == StationType.ChangeEnds)
                                {
                                    JumpTrain(Train, i + 1);
                                }
                            }
                            if (Interface.CurrentOptions.LoadingSway)
                            {
                                // passengers boarding
                                for (int j = 0; j < Train.Cars.Length; j++)
                                {
                                    double r = 2.0 * Game.Stations[i].PassengerRatio * TimeElapsed;
                                    if (r >= Program.RandomNumberGenerator.NextDouble())
                                    {
                                        int d =
                                            (int)Math.Floor(Program.RandomNumberGenerator.NextDouble() * (double)Train.Cars[j].Doors.Length);
                                        if (Train.Cars[j].Doors[d].State == 1.0)
                                        {
                                            Train.Cars[j].Specs.CurrentRollShakeDirection += (double)Train.Cars[j].Doors[d].Direction;
                                        }
                                    }
                                }
                            }
                        }
                        else
                        {
                            Train.StationState = TrainStopState.Completed;
                            if (Train == PlayerTrain & Game.Stations[i].Type == StationType.Normal)
                            {
                                Game.AddMessage(Translations.GetInterfaceString("message_station_depart"), MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.White, Game.SecondsSinceMidnight + 5.0, null);
                            }
                        }
                    }
                }
            }
            else
            {
                if (Train.StationState != TrainStopState.Jumping)
                {
                    Train.StationState = TrainStopState.Pending;
                }
            }
            // automatically close doors
            if (Train.Specs.DoorCloseMode != DoorMode.Manual & Train.Specs.DoorInterlockState != DoorInterlockStates.Locked & !Train.Specs.DoorClosureAttempted)
            {
                if (Train.Station == -1 | Train.StationState == TrainStopState.Completed)
                {
                    if ((GetDoorsState(Train, true, true) & TrainDoorState.AllClosed) == 0)
                    {
                        CloseTrainDoors(Train, true, true);
                        Train.Specs.DoorClosureAttempted = true;
                    }
                }
            }
        }
Пример #21
0
        /// <summary>Is called once a frame, to update the door states of the specified train</summary>
        /// <param name="Train">The train</param>
        /// <param name="TimeElapsed">The frame time elapsed</param>
        private static void UpdateTrainDoors(Train Train, double TimeElapsed)
        {
            OpenBveApi.Runtime.DoorStates oldState = OpenBveApi.Runtime.DoorStates.None;
            OpenBveApi.Runtime.DoorStates newState = OpenBveApi.Runtime.DoorStates.None;
            for (int i = 0; i < Train.Cars.Length; i++)
            {
                bool   ld = Train.Cars[i].Doors[0].AnticipatedOpen;
                bool   rd = Train.Cars[i].Doors[1].AnticipatedOpen;
                double os = Train.Cars[i].Specs.DoorOpenFrequency;
                double cs = Train.Cars[i].Specs.DoorCloseFrequency;

                for (int j = 0; j < Train.Cars[i].Doors.Length; j++)
                {
                    if (Train.Cars[i].Doors[j].Direction == -1 | Train.Cars[i].Doors[j].Direction == 1)
                    {
                        bool shouldBeOpen = Train.Cars[i].Doors[j].Direction == -1 ? ld : rd;
                        if (Train.Cars[i].Doors[j].State > 0.0)
                        {
                            if (Train.Cars[i].Doors[j].Direction == -1)
                            {
                                oldState |= OpenBveApi.Runtime.DoorStates.Left;
                            }
                            else
                            {
                                oldState |= OpenBveApi.Runtime.DoorStates.Right;
                            }
                        }
                        if (shouldBeOpen)
                        {
                            // open
                            Train.Cars[i].Doors[j].State += os * TimeElapsed;
                            if (Train.Cars[i].Doors[j].State > 1.0)
                            {
                                Train.Cars[i].Doors[j].State = 1.0;
                            }
                        }
                        else
                        {
                            // close
                            if (Train.Cars[i].Doors[j].DoorLockDuration > 0.0)
                            {
                                if (Train.Cars[i].Doors[j].State > Train.Cars[i].Doors[j].DoorLockState)
                                {
                                    Train.Cars[i].Doors[j].State -= cs * TimeElapsed;
                                }
                                if (Train.Cars[i].Doors[j].State < Train.Cars[i].Doors[j].DoorLockState)
                                {
                                    Train.Cars[i].Doors[j].State = Train.Cars[i].Doors[j].DoorLockState;
                                }
                                Train.Cars[i].Doors[j].DoorLockDuration -= TimeElapsed;
                                if (Train.Cars[i].Doors[j].DoorLockDuration < 0.0)
                                {
                                    Train.Cars[i].Doors[j].DoorLockDuration = 0.0;
                                }
                            }
                            else
                            {
                                Train.Cars[i].Doors[j].State -= cs * TimeElapsed;
                            }
                            if (Train.Cars[i].Doors[j].AnticipatedReopen && Train.Cars[i].Doors[j].State < Train.Cars[i].Doors[j].InterferingObjectRate)
                            {
                                Train.Cars[i].Doors[j].State = Train.Cars[i].Doors[j].InterferingObjectRate;
                            }
                            if (Train.Cars[i].Doors[j].State < 0.0)
                            {
                                Train.Cars[i].Doors[j].State = 0.0;
                            }
                        }
                        if (Train.Cars[i].Doors[j].State > 0.0)
                        {
                            if (Train.Cars[i].Doors[j].Direction == -1)
                            {
                                newState |= OpenBveApi.Runtime.DoorStates.Left;
                            }
                            else
                            {
                                newState |= OpenBveApi.Runtime.DoorStates.Right;
                            }
                        }
                    }
                }
            }

            if (oldState != OpenBveApi.Runtime.DoorStates.None & newState == OpenBveApi.Runtime.DoorStates.None)
            {
                Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.PilotLampOn.Buffer;
                if (buffer != null)
                {
                    OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.PilotLampOn.Position;
                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                }
            }
            else if (oldState == OpenBveApi.Runtime.DoorStates.None & newState != OpenBveApi.Runtime.DoorStates.None)
            {
                Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.PilotLampOff.Buffer;
                if (buffer != null)
                {
                    OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.PilotLampOff.Position;
                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                }
            }
            if (oldState != newState)
            {
                if (Train.Plugin != null)
                {
                    Train.Plugin.DoorChange(oldState, newState);
                }
            }
        }
Пример #22
0
            internal override void Update(double TimeElapsed, bool ForceUpdate)
            {
                const double extraRadius = 10.0;
                const double Radius      = 25.0;

                double pa      = currentTrackPosition + Radius - extraRadius;
                double pb      = currentTrackPosition + Radius + extraRadius;
                double ta      = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z - World.BackgroundImageDistance - World.ExtraViewingDistance;
                double tb      = World.CameraTrackFollower.TrackPosition + World.CameraCurrentAlignment.Position.Z + World.BackgroundImageDistance + World.ExtraViewingDistance;
                bool   visible = pb >= ta & pa <= tb;

                if (visible | ForceUpdate)
                {
                    if (Game.MinimalisticSimulation || TimeElapsed > 0.05)
                    {
                        return;
                    }
                    TrainManager.Train train         = null;
                    double             trainDistance = double.MaxValue;
                    for (int j = 0; j < TrainManager.Trains.Length; j++)
                    {
                        if (TrainManager.Trains[j].State == TrainState.Available)
                        {
                            double distance;
                            if (TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition < this.Follower.TrackPosition)
                            {
                                distance = this.Follower.TrackPosition - TrainManager.Trains[j].Cars[0].FrontAxle.Follower.TrackPosition;
                            }
                            else if (TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition > this.Follower.TrackPosition)
                            {
                                distance = TrainManager.Trains[j].Cars[TrainManager.Trains[j].Cars.Length - 1].RearAxle.Follower.TrackPosition - this.Follower.TrackPosition;
                            }
                            else
                            {
                                distance = 0;
                            }
                            if (distance < trainDistance)
                            {
                                train         = TrainManager.Trains[j];
                                trainDistance = distance;
                            }
                        }
                    }
                    if (this.TrackFollowerFunction != null)
                    {
                        double delta = this.TrackFollowerFunction.Perform(train, train == null ? 0 : train.DriverCar, this.Position, this.Follower.TrackPosition, 0, false, TimeElapsed, 0);
                        this.Follower.Update(this.currentTrackPosition + delta, true, true);
                        this.Follower.UpdateWorldCoordinates(false);
                    }
                    if (this.VolumeFunction != null)
                    {
                        this.currentVolume = this.VolumeFunction.Perform(train, train == null ? 0 : train.DriverCar, this.Position, this.Follower.TrackPosition, 0, false, TimeElapsed, 0);
                    }
                    if (this.PitchFunction != null)
                    {
                        this.currentPitch = this.PitchFunction.Perform(train, train == null ? 0 : train.DriverCar, this.Position, this.Follower.TrackPosition, 0, false, TimeElapsed, 0);
                    }
                    if (this.Source != null)
                    {
                        this.Source.Pitch  = this.currentPitch;
                        this.Source.Volume = this.currentVolume;
                    }
                    //Buffer should never be null, but check it anyways
                    if (!Sounds.IsPlaying(Source) && this.Buffer != null)
                    {
                        Source = Sounds.PlaySound(Buffer, 1.0, 1.0, Follower.WorldPosition + Position, this, true);
                    }
                }
                else
                {
                    if (Sounds.IsPlaying(Source))
                    {
                        Sounds.StopSound(Source);
                    }
                }
            }
Пример #23
0
            /// <summary>Call this method to update the train</summary>
            /// <param name="TimeElapsed">The elapsed time this frame</param>
            internal new void Update(double TimeElapsed)
            {
                if (State == TrainState.Pending)
                {
                    // pending train
                    if (Game.SecondsSinceMidnight >= AppearanceTime)
                    {
                        double PlayerTrainTrackPosition = PlayerTrain.Cars[0].FrontAxle.Follower.TrackPosition + 0.5 * PlayerTrain.Cars[0].Length - PlayerTrain.Cars[0].FrontAxle.Position;
                        if (PlayerTrainTrackPosition < AppearanceStartPosition || (PlayerTrainTrackPosition > AppearanceEndPosition && AppearanceEndPosition > AppearanceStartPosition))
                        {
                            return;
                        }

                        // train is introduced
                        State = TrainState.Available;
                        for (int i = 0; i < Cars.Length; i++)
                        {
                            if (Cars[i].CarSections.Length != 0)
                            {
                                Cars[i].ChangeCarSection(CarSectionType.Exterior);
                            }
                            Cars[i].FrontBogie.ChangeSection(0);
                            Cars[i].RearBogie.ChangeSection(0);

                            if (Cars[i].Specs.IsMotorCar)
                            {
                                if (Cars[i].Sounds.Loop.Buffer != null)
                                {
                                    Vector3 pos = Cars[i].Sounds.Loop.Position;
                                    Cars[i].Sounds.Loop.Source = Sounds.PlaySound(Cars[i].Sounds.Loop.Buffer, 1.0, 1.0, pos, this, i, true);
                                }
                            }
                        }
                    }
                }
                else if (State == TrainState.Available)
                {
                    // available train
                    UpdatePhysicsAndControls(TimeElapsed);
                    for (int i = 0; i < Cars.Length; i++)
                    {
                        byte dnb;
                        {
                            float b = (float)(Cars[i].Brightness.NextTrackPosition - Cars[i].Brightness.PreviousTrackPosition);

                            //1.0f represents a route brightness value of 255
                            //0.0f represents a route brightness value of 0

                            if (b != 0.0f)
                            {
                                b = (float)(Cars[i].FrontAxle.Follower.TrackPosition - Cars[i].Brightness.PreviousTrackPosition) / b;
                                if (b < 0.0f)
                                {
                                    b = 0.0f;
                                }
                                if (b > 1.0f)
                                {
                                    b = 1.0f;
                                }
                                b = Cars[i].Brightness.PreviousBrightness * (1.0f - b) + Cars[i].Brightness.NextBrightness * b;
                            }
                            else
                            {
                                b = Cars[i].Brightness.PreviousBrightness;
                            }

                            //Calculate the cab brightness
                            double ccb = Math.Round(255.0 * (double)(1.0 - b));
                            //DNB then must equal the smaller of the cab brightness value & the dynamic brightness value
                            dnb = (byte)Math.Min(LibRender.Renderer.DynamicCabBrightness, ccb);
                        }
                        int cs = Cars[i].CurrentCarSection;
                        if (cs >= 0 && Cars[i].CarSections.Length > 0 && Cars[i].CarSections.Length >= cs)
                        {
                            if (Cars[i].CarSections[cs].Groups.Length > 0)
                            {
                                for (int k = 0; k < Cars[i].CarSections[cs].Groups[0].Elements.Length; k++)
                                {
                                    int o = Cars[i].CarSections[cs].Groups[0].Elements[k].ObjectIndex;
                                    if (ObjectManager.Objects[o] != null)
                                    {
                                        for (int j = 0; j < ObjectManager.Objects[o].Mesh.Materials.Length; j++)
                                        {
                                            ObjectManager.Objects[o].Mesh.Materials[j].DaytimeNighttimeBlend = dnb;
                                        }
                                    }
                                }
                            }
                        }

                        if (AI != null)
                        {
                            AI.Trigger(TimeElapsed);
                        }
                    }
                }
                else if (State == TrainState.Bogus)
                {
                    // bogus train
                    if (AI != null)
                    {
                        AI.Trigger(TimeElapsed);
                    }
                }
            }
Пример #24
0
        // apply notch
        internal static void ApplyNotch(Train Train, int PowerValue, bool PowerRelative, int BrakeValue, bool BrakeRelative)
        {
            // determine notch
            int p = PowerRelative ? PowerValue + Train.Specs.CurrentPowerNotch.Driver : PowerValue;

            if (p < 0)
            {
                p = 0;
            }
            else if (p > Train.Specs.MaximumPowerNotch)
            {
                p = Train.Specs.MaximumPowerNotch;
            }
            int b = BrakeRelative ? BrakeValue + Train.Specs.CurrentBrakeNotch.Driver : BrakeValue;

            if (b < 0)
            {
                b = 0;
            }
            else if (b > Train.Specs.MaximumBrakeNotch)
            {
                b = Train.Specs.MaximumBrakeNotch;
            }
            // power sound
            if (p < Train.Specs.CurrentPowerNotch.Driver)
            {
                if (p > 0)
                {
                    // down (not min)
                    Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.MasterControllerDown.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.MasterControllerDown.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                    }
                }
                else
                {
                    // min
                    Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.MasterControllerMin.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.MasterControllerMin.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                    }
                }
            }
            else if (p > Train.Specs.CurrentPowerNotch.Driver)
            {
                if (p < Train.Specs.MaximumPowerNotch)
                {
                    // up (not max)
                    Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.MasterControllerUp.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.MasterControllerUp.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                    }
                }
                else
                {
                    // max
                    Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.MasterControllerMax.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.MasterControllerMax.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                    }
                }
            }
            // brake sound
            if (b < Train.Specs.CurrentBrakeNotch.Driver)
            {
                // brake release
                Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.Brake.Buffer;
                if (buffer != null)
                {
                    OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.Brake.Position;
                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                }
                if (b > 0)
                {
                    // brake release (not min)
                    buffer = Train.Cars[Train.DriverCar].Sounds.BrakeHandleRelease.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.BrakeHandleRelease.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                    }
                }
                else
                {
                    // brake min
                    buffer = Train.Cars[Train.DriverCar].Sounds.BrakeHandleMin.Buffer;
                    if (buffer != null)
                    {
                        OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.BrakeHandleMin.Position;
                        Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                    }
                }
            }
            else if (b > Train.Specs.CurrentBrakeNotch.Driver)
            {
                // brake
                Sounds.SoundBuffer buffer = Train.Cars[Train.DriverCar].Sounds.BrakeHandleApply.Buffer;
                if (buffer != null)
                {
                    OpenBveApi.Math.Vector3 pos = Train.Cars[Train.DriverCar].Sounds.BrakeHandleApply.Position;
                    Sounds.PlaySound(buffer, 1.0, 1.0, pos, Train, Train.DriverCar, false);
                }
            }
            // apply notch
            if (Train.Specs.SingleHandle)
            {
                if (b != 0)
                {
                    p = 0;
                }
            }
            Train.Specs.CurrentPowerNotch.Driver = p;
            Train.Specs.CurrentBrakeNotch.Driver = b;
            Game.AddBlackBoxEntry(Game.BlackBoxEventToken.None);
            // plugin
            if (Train.Plugin != null)
            {
                Train.Plugin.UpdatePower();
                Train.Plugin.UpdateBrake();
            }
        }