The root class for a train within the simulation
			// --- constructors ---
			/// <summary>Creates a new sound source.</summary>
			/// <param name="buffer">The sound buffer.</param>
			/// <param name="radius">The effective sound radius.</param>
			/// <param name="pitch">The pitch change factor.</param>
			/// <param name="volume">The volume change factor.</param>
			/// <param name="position">The position. If a train and car are specified, the position is relative to the car, otherwise absolute.</param>
			/// <param name="train">The train this sound source is attached to, or a null reference.</param>
			/// <param name="car">The car this sound source is attached to, or a null reference.</param>
			/// <param name="looped">Whether this sound source plays in a loop.</param>
			internal SoundSource(SoundBuffer buffer, double radius, double pitch, double volume, OpenBveApi.Math.Vector3D position, TrainManager.Train train, int car, bool looped) {
				this.Buffer = buffer;
				this.Radius = radius;
				this.Pitch = pitch;
				this.Volume = volume;
				this.Position = position;
				this.Train = train;
				this.Car = car;
				this.Looped = looped;
				this.State = SoundSourceState.PlayPending;
				this.OpenAlSourceName = 0;
			}
Example #2
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;
         }
     }
 }
Example #3
0
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (TriggerType == EventTriggerType.FrontCarFrontAxle)
     {
         if (Direction < 0)
         {
             Train.StationFrontCar = true;
         }
         else if (Direction > 0)
         {
             Train.StationFrontCar = false;
             if (Train == TrainManager.PlayerTrain)
             {
                 Timetable.UpdateCustomTimetable(Game.Stations[this.StationIndex].TimetableDaytimeTexture, Game.Stations[this.StationIndex].TimetableNighttimeTexture);
             }
         }
     }
     else if (TriggerType == EventTriggerType.RearCarRearAxle)
     {
         if (Direction < 0)
         {
             Train.Station        = this.StationIndex;
             Train.StationRearCar = true;
             if (Train.NextStopSkipped != TrainManager.StopSkipMode.None)
             {
                 Train.LastStation = this.StationIndex;
             }
             Train.NextStopSkipped = TrainManager.StopSkipMode.None;
         }
         else if (Direction > 0)
         {
             if (Train.Station == StationIndex)
             {
                 if (Train == TrainManager.PlayerTrain)
                 {
                     if (Game.PlayerStopsAtStation(StationIndex) & TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Pending)
                     {
                         string s = Interface.GetInterfaceString("message_station_passed");
                         s = s.Replace("[name]", Game.Stations[StationIndex].Name);
                         Game.AddMessage(s, MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.Orange, Game.SecondsSinceMidnight + 10.0, null);
                     }
                     else if (Game.PlayerStopsAtStation(StationIndex) & TrainManager.PlayerTrain.StationState == TrainManager.TrainStopState.Boarding)
                     {
                         string s = Interface.GetInterfaceString("message_station_passed_boarding");
                         s = s.Replace("[name]", Game.Stations[StationIndex].Name);
                         Game.AddMessage(s, MessageManager.MessageDependency.None, Interface.GameMode.Normal, MessageColor.Red, Game.SecondsSinceMidnight + 10.0, null);
                     }
                 }
                 Train.Station        = -1;
                 Train.StationRearCar = false;
                 Train.StationState   = TrainManager.TrainStopState.Pending;
                 int d = Train.DriverCar;
                 Sounds.StopSound(Train.Cars[d].Sounds.Halt.Source);
             }
         }
     }
 }
Example #4
0
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (Train != null)
     {
         if (TriggerType == EventTriggerType.FrontCarFrontAxle)
         {
             if (Direction < 0)
             {
                 if (this.NextSectionIndex >= 0)
                 {
                     Game.Sections[this.NextSectionIndex].TrainReachedStopPoint = false;
                 }
                 UpdateFrontBackward(Train, true);
             }
             else if (Direction > 0)
             {
                 UpdateFrontForward(Train, true, true);
             }
         }
         else if (TriggerType == EventTriggerType.RearCarRearAxle)
         {
             if (Direction < 0)
             {
                 UpdateRearBackward(Train, true);
             }
             else if (Direction > 0)
             {
                 if (this.PreviousSectionIndex >= 0)
                 {
                     Game.Sections[this.PreviousSectionIndex].TrainReachedStopPoint = false;
                 }
                 UpdateRearForward(Train, true);
             }
         }
     }
 }
Example #5
0
        /// <summary>Loads the specified plugin for the specified train.</summary>
        /// <param name="train">The train to attach the plugin to.</param>
        /// <param name="pluginFile">The file to the plugin.</param>
        /// <param name="trainFolder">The train folder.</param>
        /// <returns>Whether the plugin was loaded successfully.</returns>
        private static bool LoadPlugin(TrainManager.Train train, string pluginFile, string trainFolder)
        {
            string pluginTitle = System.IO.Path.GetFileName(pluginFile);

            if (!System.IO.File.Exists(pluginFile))
            {
                Debug.AddMessage(Debug.MessageType.Error, true, "The train plugin " + pluginTitle + " could not be found.");
                return(false);
            }

            /*
             * Unload plugin if already loaded.
             * */
            if (train.Plugin != null)
            {
                UnloadPlugin(train);
            }

            /*
             * Prepare initialization data for the plugin.
             * */
            BrakeTypes brakeType = (BrakeTypes)train.Cars[train.DriverCar].Specs.BrakeType;
            int        brakeNotches;
            int        powerNotches;
            bool       hasHoldBrake;

            if (brakeType == BrakeTypes.AutomaticAirBrake)
            {
                brakeNotches = 2;
                powerNotches = train.Specs.MaximumPowerNotch;
                hasHoldBrake = false;
            }
            else
            {
                brakeNotches = train.Specs.MaximumBrakeNotch + (train.Specs.HasHoldBrake ? 1 : 0);
                powerNotches = train.Specs.MaximumPowerNotch;
                hasHoldBrake = train.Specs.HasHoldBrake;
            }
            int                 cars  = train.Cars.Length;
            VehicleSpecs        specs = new VehicleSpecs(powerNotches, brakeType, brakeNotches, hasHoldBrake, cars);
            InitializationModes mode  = (InitializationModes)Game.TrainStart;

            /*
             * Check if the plugin is a .NET plugin.
             * */
            Assembly assembly;

            try {
                assembly = Assembly.LoadFile(pluginFile);
            } catch (BadImageFormatException) {
                assembly = null;
            } catch (Exception ex) {
                Debug.AddMessage(Debug.MessageType.Error, false, "The train plugin " + pluginTitle + " could not be loaded due to the following exception: " + ex.Message);
                return(false);
            }
            if (assembly != null)
            {
                Type[] types;
                try {
                    types = assembly.GetTypes();
                } catch (ReflectionTypeLoadException ex) {
                    foreach (Exception e in ex.LoaderExceptions)
                    {
                        Debug.AddMessage(Debug.MessageType.Error, false, "The train plugin " + pluginTitle + " raised an exception on loading: " + e.Message);
                    }
                    return(false);
                }
                foreach (Type type in types)
                {
                    if (typeof(IRuntime).IsAssignableFrom(type))
                    {
                        IRuntime api = assembly.CreateInstance(type.FullName) as IRuntime;
                        train.Plugin = new NetPlugin(pluginFile, trainFolder, api, train);
                        if (train.Plugin.Load(specs, mode))
                        {
                            return(true);
                        }
                        train.Plugin = null;
                        return(false);
                    }
                }
                Debug.AddMessage(Debug.MessageType.Error, false, "The train plugin " + pluginTitle + " does not export a train interface and therefore cannot be used with openBVE.");
                return(false);
            }

            /*
             * Check if the plugin is a Win32 plugin.
             * */
            try {
                if (!CheckWin32Header(pluginFile))
                {
                    Debug.AddMessage(Debug.MessageType.Error, false, "The train plugin " + pluginTitle + " is of an unsupported binary format and therefore cannot be used with openBVE.");
                    return(false);
                }
            } catch (Exception ex) {
                Debug.AddMessage(Debug.MessageType.Error, false, "The train plugin " + pluginTitle + " could not be read due to the following reason: " + ex.Message);
                return(false);
            }
            if (!Program.CurrentlyRunningOnWindows | IntPtr.Size != 4)
            {
                Debug.AddMessage(Debug.MessageType.Warning, false, "The train plugin " + pluginTitle + " can only be used on 32-bit Microsoft Windows or compatible.");
                return(false);
            }
            train.Plugin = new Win32Plugin(pluginFile, train);
            if (train.Plugin.Load(specs, mode))
            {
                return(true);
            }
            train.Plugin = null;
            return(false);
        }
Example #6
0
 internal abstract void Trigger(TrainManager.Train Train, double TimeElapsed);
Example #7
0
            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, Renderer.ObjectType.Dynamic);
                        Visible = true;
                    }
                }
                else
                {
                    Object.SecondsSinceLastUpdate += TimeElapsed;
                    if (Visible)
                    {
                        Renderer.HideObject(Object.ObjectIndex);
                        Visible = false;
                    }
                }
                this.lastState = this.Object.CurrentState;
            }
Example #8
0
 /// <summary>Gets the signal data for a plugin.</summary>
 /// <param name="train">The train.</param>
 /// <param name="section">The absolute section index, referencing Game.Sections[].</param>
 /// <returns>The signal data.</returns>
 internal static OpenBveApi.Runtime.SignalData GetPluginSignal(TrainManager.Train train, int section)
 {
     if (Sections[section].Exists(train))
     {
         int aspect;
         if (Sections[section].IsFree(train))
         {
             if (Sections[section].Type == SectionType.IndexBased)
             {
                 if (section + 1 < Sections.Length)
                 {
                     int value = Sections[section + 1].FreeSections;
                     if (value == -1)
                     {
                         value = Sections[section].Aspects.Length - 1;
                     }
                     else
                     {
                         value++;
                         if (value >= Sections[section].Aspects.Length)
                         {
                             value = Sections[section].Aspects.Length - 1;
                         }
                         if (value < 0)
                         {
                             value = 0;
                         }
                     }
                     aspect = Sections[section].Aspects[value].Number;
                 }
                 else
                 {
                     aspect = Sections[section].Aspects[Sections[section].Aspects.Length - 1].Number;
                 }
             }
             else
             {
                 aspect = Sections[section].Aspects[Sections[section].Aspects.Length - 1].Number;
                 if (section < Sections.Length - 1)
                 {
                     int value = Sections[section + 1].Aspects[Sections[section + 1].CurrentAspect].Number;
                     for (int i = 0; i < Sections[section].Aspects.Length; i++)
                     {
                         if (Sections[section].Aspects[i].Number > value)
                         {
                             aspect = Sections[section].Aspects[i].Number;
                             break;
                         }
                     }
                 }
             }
         }
         else
         {
             aspect = Sections[section].Aspects[Sections[section].CurrentAspect].Number;
         }
         double position = train.Cars[0].FrontAxle.Follower.TrackPosition - train.Cars[0].FrontAxle.Position + 0.5 * train.Cars[0].Length;
         double distance = Sections[section].TrackPosition - position;
         return(new OpenBveApi.Runtime.SignalData(aspect, distance));
     }
     else
     {
         int    aspect   = Sections[section].Aspects[Sections[section].CurrentAspect].Number;
         double position = train.Cars[0].FrontAxle.Follower.TrackPosition - train.Cars[0].FrontAxle.Position + 0.5 * train.Cars[0].Length;
         double distance = Sections[section].TrackPosition - position;
         return(new OpenBveApi.Runtime.SignalData(aspect, distance));
     }
 }
Example #9
0
        internal static void PlaySound(int SoundBufferIndex, TrainManager.Train Train, int CarIndex, World.Vector3D Position, Importance Important, bool Looped)
        {
            int a = -1;

            PlaySound(ref a, false, SoundBufferIndex, Train, CarIndex, Position, Important, Looped, 1.0, 1.0);
        }
Example #10
0
        internal static void ParseExtensionsConfig(string filePath, Encoding encoding, out UnifiedObject[] carObjects, out UnifiedObject[] bogieObjects, out double[] axleLocations, out TrainManager.Train train, bool loadObjects)
        {
            CultureInfo Culture = CultureInfo.InvariantCulture;

            carObjects    = new UnifiedObject[] { };
            bogieObjects  = new UnifiedObject[] { };
            axleLocations = new double[] { };
            train         = new TrainManager.Train();

            if (!System.IO.File.Exists(filePath))
            {
                return;
            }

            train.Cars = new TrainManager.Car[] { };
            bool[] carObjectsReversed   = new bool[train.Cars.Length];
            bool[] bogieObjectsReversed = new bool[train.Cars.Length * 2];
            bool[] carsDefined          = new bool[train.Cars.Length];
            bool[] bogiesDefined        = new bool[train.Cars.Length * 2];
            axleLocations = new double[train.Cars.Length * 2];

            string trainPath = System.IO.Path.GetDirectoryName(filePath);

            System.Globalization.CultureInfo culture     = System.Globalization.CultureInfo.InvariantCulture;
            TextEncoding.Encoding            newEncoding = TextEncoding.GetEncodingFromFile(filePath);
            if (newEncoding != TextEncoding.Encoding.Unknown)
            {
                switch (newEncoding)
                {
                case TextEncoding.Encoding.Utf7:
                    encoding = Encoding.UTF7;
                    break;

                case TextEncoding.Encoding.Utf8:
                    encoding = Encoding.UTF8;
                    break;

                case TextEncoding.Encoding.Utf16Le:
                    encoding = Encoding.Unicode;
                    break;

                case TextEncoding.Encoding.Utf16Be:
                    encoding = Encoding.BigEndianUnicode;
                    break;

                case TextEncoding.Encoding.Utf32Le:
                    encoding = Encoding.UTF32;
                    break;

                case TextEncoding.Encoding.Utf32Be:
                    encoding = Encoding.GetEncoding(12001);
                    break;

                case TextEncoding.Encoding.Shift_JIS:
                    encoding = Encoding.GetEncoding(932);
                    break;
                }
            }

            string[] lines = System.IO.File.ReadAllLines(filePath, encoding);
            for (int i = 0; i < lines.Length; i++)
            {
                int j = lines[i].IndexOf(';');
                if (j >= 0)
                {
                    lines[i] = lines[i].Substring(0, j).Trim(new char[] { });
                }
                else
                {
                    lines[i] = lines[i].Trim(new char[] { });
                }
            }

            for (int i = 0; i < lines.Length; i++)
            {
                if (lines[i].Length != 0)
                {
                    switch (lines[i].ToLowerInvariant())
                    {
                    case "[exterior]":
                        // exterior
                        i++;
                        while (i < lines.Length && !lines[i].StartsWith("[", StringComparison.Ordinal) & !lines[i].EndsWith("]", StringComparison.Ordinal))
                        {
                            if (lines[i].Length != 0)
                            {
                                int j = lines[i].IndexOf("=", StringComparison.Ordinal);
                                if (j >= 0)
                                {
                                    string a = lines[i].Substring(0, j).TrimEnd(new char[] { });
                                    string b = lines[i].Substring(j + 1).TrimStart(new char[] { });
                                    int    n;
                                    if (int.TryParse(a, System.Globalization.NumberStyles.Integer, culture, out n))
                                    {
                                        if (n >= 0)
                                        {
                                            if (n >= train.Cars.Length)
                                            {
                                                Array.Resize(ref train.Cars, n + 1);
                                                train.Cars[n] = new TrainManager.Car(train);
                                                Array.Resize(ref carObjects, n + 1);
                                                Array.Resize(ref bogieObjects, (n + 1) * 2);
                                                Array.Resize(ref carObjectsReversed, n + 1);
                                                Array.Resize(ref bogieObjectsReversed, (n + 1) * 2);
                                                Array.Resize(ref carsDefined, n + 1);
                                                Array.Resize(ref bogiesDefined, (n + 1) * 2);
                                                Array.Resize(ref axleLocations, (n + 1) * 2);
                                            }
                                            if (Path.ContainsInvalidChars(b))
                                            {
                                                Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                            }
                                            else
                                            {
                                                string file = OpenBveApi.Path.CombineFile(trainPath, b);
                                                if (System.IO.File.Exists(file))
                                                {
                                                    if (loadObjects)
                                                    {
                                                        carObjects[n] = ObjectManager.LoadObject(file, encoding, false);
                                                    }
                                                }
                                                else
                                                {
                                                    Interface.AddMessage(MessageType.Error, true, "The car object " + file + " does not exist at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                }
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "The car index " + a + " does not reference an existing car at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                        }
                                    }
                                    else
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                    }
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Invalid statement " + lines[i] + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                }
                            }
                            i++;
                        }
                        i--;
                        break;

                    default:
                        if (lines[i].StartsWith("[car", StringComparison.OrdinalIgnoreCase) & lines[i].EndsWith("]", StringComparison.Ordinal))
                        {
                            // car
                            string t = lines[i].Substring(4, lines[i].Length - 5);
                            int    n;
                            if (int.TryParse(t, System.Globalization.NumberStyles.Integer, culture, out n))
                            {
                                if (n >= 0)
                                {
                                    if (n >= train.Cars.Length)
                                    {
                                        Array.Resize(ref train.Cars, n + 1);
                                        train.Cars[n] = new TrainManager.Car(train);
                                        Array.Resize(ref carObjects, n + 1);
                                        Array.Resize(ref bogieObjects, (n + 1) * 2);
                                        Array.Resize(ref carObjectsReversed, n + 1);
                                        Array.Resize(ref bogieObjectsReversed, (n + 1) * 2);
                                        Array.Resize(ref carsDefined, n + 1);
                                        Array.Resize(ref bogiesDefined, (n + 1) * 2);
                                        Array.Resize(ref axleLocations, (n + 1) * 2);
                                    }
                                    if (carsDefined[n])
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "Car " + n.ToString(culture) + " has already been declared at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                    }
                                    carsDefined[n] = true;
                                    i++;
                                    while (i < lines.Length && !lines[i].StartsWith("[", StringComparison.Ordinal) & !lines[i].EndsWith("]", StringComparison.Ordinal))
                                    {
                                        if (lines[i].Length != 0)
                                        {
                                            int j = lines[i].IndexOf("=", StringComparison.Ordinal);
                                            if (j >= 0)
                                            {
                                                string a = lines[i].Substring(0, j).TrimEnd(new char[] { });
                                                string b = lines[i].Substring(j + 1).TrimStart(new char[] { });
                                                switch (a.ToLowerInvariant())
                                                {
                                                case "object":
                                                    if (string.IsNullOrEmpty(b))
                                                    {
                                                        Interface.AddMessage(MessageType.Error, true, "An empty car object was supplied at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                        break;
                                                    }
                                                    if (Path.ContainsInvalidChars(b))
                                                    {
                                                        Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                    }
                                                    else
                                                    {
                                                        string file = OpenBveApi.Path.CombineFile(trainPath, b);
                                                        if (System.IO.File.Exists(file))
                                                        {
                                                            if (loadObjects)
                                                            {
                                                                carObjects[n] = ObjectManager.LoadObject(file, encoding, false);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            Interface.AddMessage(MessageType.Error, true, "The car object " + file + " does not exist at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                        }
                                                    }
                                                    break;

                                                case "length":
                                                {
                                                    double m;
                                                    if (double.TryParse(b, System.Globalization.NumberStyles.Float, culture, out m))
                                                    {
                                                        if (m > 0.0)
                                                        {
                                                            train.Cars[n].Length = m;
                                                        }
                                                        else
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "Value is expected to be a positive floating-point number in " + a + " at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                        }
                                                    }
                                                    else
                                                    {
                                                        Interface.AddMessage(MessageType.Error, false, "Value is expected to be a positive floating-point number in " + a + " at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                    }
                                                }
                                                break;

                                                case "reversed":
                                                    carObjectsReversed[n] = b.Equals("true", StringComparison.OrdinalIgnoreCase);
                                                    break;

                                                case "axles":
                                                    int k = b.IndexOf(',');
                                                    if (k >= 0)
                                                    {
                                                        string c = b.Substring(0, k).TrimEnd(new char[] { });
                                                        string d = b.Substring(k + 1).TrimStart(new char[] { });
                                                        double rear, front;
                                                        if (!double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out rear))
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "Rear is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + filePath);
                                                        }
                                                        else if (!double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out front))
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "Front is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + filePath);
                                                        }
                                                        else if (rear >= front)
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "Rear is expected to be less than Front in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + filePath);
                                                        }
                                                        else
                                                        {
                                                            if (n == 0)
                                                            {
                                                                axleLocations[n]     = rear;
                                                                axleLocations[n + 1] = front;
                                                            }
                                                            else
                                                            {
                                                                axleLocations[n * 2]     = rear;
                                                                axleLocations[n * 2 + 1] = front;
                                                            }
                                                        }
                                                    }
                                                    else
                                                    {
                                                        Interface.AddMessage(MessageType.Error, false, "An argument-separating comma is expected in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + filePath);
                                                    }
                                                    break;

                                                default:
                                                    Interface.AddMessage(MessageType.Warning, false, "Unsupported key-value pair " + a + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                Interface.AddMessage(MessageType.Error, false, "Invalid statement " + lines[i] + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                            }
                                        }
                                        i++;
                                    }
                                    i--;
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "The car index " + t + " does not reference an existing car at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                }
                            }
                            else
                            {
                                Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(culture) + " in file " + filePath);
                            }
                        }
                        else if (lines[i].StartsWith("[bogie", StringComparison.OrdinalIgnoreCase) & lines[i].EndsWith("]", StringComparison.Ordinal))
                        {
                            // car
                            string t = lines[i].Substring(6, lines[i].Length - 7);
                            int    n;
                            if (int.TryParse(t, System.Globalization.NumberStyles.Integer, culture, out n))
                            {
                                if (n >= train.Cars.Length * 2)
                                {
                                    Array.Resize(ref train.Cars, n / 2 + 1);
                                    if (n == 0)
                                    {
                                        train.Cars[0] = new TrainManager.Car(train);
                                        Array.Resize(ref axleLocations, 2);
                                    }
                                    else
                                    {
                                        train.Cars[n / 2] = new TrainManager.Car(train);
                                        Array.Resize(ref axleLocations, ((n / 2) + 1) * 2);
                                    }

                                    Array.Resize(ref carObjects, n / 2 + 1);
                                    Array.Resize(ref bogieObjects, n + 2);
                                    Array.Resize(ref carObjectsReversed, n / 2 + 1);
                                    Array.Resize(ref bogieObjectsReversed, n + 2);
                                    Array.Resize(ref carsDefined, n / 2 + 1);
                                    Array.Resize(ref bogiesDefined, n + 2);
                                }

                                if (n > bogiesDefined.Length - 1)
                                {
                                    continue;
                                }
                                if (bogiesDefined[n])
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Bogie " + n.ToString(culture) + " has already been declared at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                }
                                bogiesDefined[n] = true;
                                //Assuming that there are two bogies per car
                                if (n >= 0 & n < train.Cars.Length * 2)
                                {
                                    i++;
                                    while (i < lines.Length && !lines[i].StartsWith("[", StringComparison.Ordinal) & !lines[i].EndsWith("]", StringComparison.Ordinal))
                                    {
                                        if (lines[i].Length != 0)
                                        {
                                            int j = lines[i].IndexOf("=", StringComparison.Ordinal);
                                            if (j >= 0)
                                            {
                                                string a = lines[i].Substring(0, j).TrimEnd(new char[] { });
                                                string b = lines[i].Substring(j + 1).TrimStart(new char[] { });
                                                switch (a.ToLowerInvariant())
                                                {
                                                case "object":
                                                    if (Path.ContainsInvalidChars(b))
                                                    {
                                                        Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                    }
                                                    else
                                                    {
                                                        if (string.IsNullOrEmpty(b))
                                                        {
                                                            Interface.AddMessage(MessageType.Error, true, "An empty bogie object was supplied at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                            break;
                                                        }
                                                        string file = OpenBveApi.Path.CombineFile(trainPath, b);
                                                        if (System.IO.File.Exists(file))
                                                        {
                                                            if (loadObjects)
                                                            {
                                                                bogieObjects[n] = ObjectManager.LoadObject(file, encoding, false);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            Interface.AddMessage(MessageType.Error, true, "The bogie object " + file + " does not exist at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                        }
                                                    }
                                                    break;

                                                case "length":
                                                {
                                                    Interface.AddMessage(MessageType.Error, false, "A defined length is not supported for bogies at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                }
                                                break;

                                                case "reversed":
                                                    bogieObjectsReversed[n] = b.Equals("true", StringComparison.OrdinalIgnoreCase);
                                                    break;

                                                case "axles":
                                                    //Axles aren't used in bogie positioning, just in rotation
                                                    break;

                                                default:
                                                    Interface.AddMessage(MessageType.Warning, false, "Unsupported key-value pair " + a + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                                    break;
                                                }
                                            }
                                            else
                                            {
                                                Interface.AddMessage(MessageType.Error, false, "Invalid statement " + lines[i] + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                            }
                                        }
                                        i++;
                                    }
                                    i--;
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "The car index " + t + " does not reference an existing car at line " + (i + 1).ToString(culture) + " in file " + filePath);
                                }
                            }
                            else
                            {
                                Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(culture) + " in file " + filePath);
                            }
                        }
                        else if (lines[i].StartsWith("[coupler", StringComparison.OrdinalIgnoreCase) & lines[i].EndsWith("]", StringComparison.Ordinal))
                        {
                            i++;
                            while (i < lines.Length && !lines[i].StartsWith("[", StringComparison.Ordinal) & !lines[i].EndsWith("]", StringComparison.Ordinal))
                            {
                                /*
                                 * Coupler statments are currently not supported in Object Viewer
                                 */
                                i++;
                            }

                            i--;
                        }
                        else
                        {
                            // default
                            if (lines.Length == 1 && encoding.Equals(Encoding.Unicode))
                            {
                                /*
                                 * If only one line, there's a good possibility that our file is NOT Unicode at all
                                 * and that the misdetection has turned it into garbage
                                 *
                                 * Try again with ASCII instead
                                 */
                                ParseExtensionsConfig(filePath, Encoding.GetEncoding(1252), out carObjects, out bogieObjects, out axleLocations, out train, loadObjects);
                                return;
                            }
                            Interface.AddMessage(MessageType.Error, false, "Invalid statement " + lines[i] + " encountered at line " + (i + 1).ToString(culture) + " in file " + filePath);
                        }
                        break;
                    }
                }
            }

            // check for car objects and reverse if necessary
            int carObjectsCount = 0;

            for (int i = 0; i < train.Cars.Length; i++)
            {
                if (carObjects[i] != null)
                {
                    carObjectsCount++;
                    if (carObjectsReversed[i] && loadObjects)
                    {
                        if (carObjects[i] is StaticObject)
                        {
                            StaticObject obj = (StaticObject)carObjects[i];
                            obj.ApplyScale(-1.0, 1.0, -1.0);
                        }
                        else if (carObjects[i] is AnimatedObjectCollection)
                        {
                            AnimatedObjectCollection obj = (AnimatedObjectCollection)carObjects[i];
                            for (int j = 0; j < obj.Objects.Length; j++)
                            {
                                for (int h = 0; h < obj.Objects[j].States.Length; h++)
                                {
                                    obj.Objects[j].States[h].Prototype.ApplyScale(-1.0, 1.0, -1.0);
                                    Matrix4D t = obj.Objects[j].States[h].Translation;
                                    t.Row3.X *= -1.0f;
                                    t.Row3.Z *= -1.0f;
                                    obj.Objects[j].States[h].Translation = t;
                                }
                                obj.Objects[j].TranslateXDirection.X *= -1.0;
                                obj.Objects[j].TranslateXDirection.Z *= -1.0;
                                obj.Objects[j].TranslateYDirection.X *= -1.0;
                                obj.Objects[j].TranslateYDirection.Z *= -1.0;
                                obj.Objects[j].TranslateZDirection.X *= -1.0;
                                obj.Objects[j].TranslateZDirection.Z *= -1.0;
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }
            }

            //Check for bogie objects and reverse if necessary.....
            int bogieObjectsCount = 0;

            for (int i = 0; i < train.Cars.Length * 2; i++)
            {
                if (bogieObjects[i] != null)
                {
                    bogieObjectsCount++;
                    if (bogieObjectsReversed[i] && loadObjects)
                    {
                        if (bogieObjects[i] is StaticObject)
                        {
                            StaticObject obj = (StaticObject)bogieObjects[i];
                            obj.ApplyScale(-1.0, 1.0, -1.0);
                        }
                        else if (bogieObjects[i] is AnimatedObjectCollection)
                        {
                            AnimatedObjectCollection obj = (AnimatedObjectCollection)bogieObjects[i];
                            for (int j = 0; j < obj.Objects.Length; j++)
                            {
                                for (int h = 0; h < obj.Objects[j].States.Length; h++)
                                {
                                    obj.Objects[j].States[h].Prototype.ApplyScale(-1.0, 1.0, -1.0);
                                    Matrix4D t = obj.Objects[j].States[h].Translation;
                                    t.Row3.X *= -1.0f;
                                    t.Row3.Z *= -1.0f;
                                    obj.Objects[j].States[h].Translation = t;
                                }
                                obj.Objects[j].TranslateXDirection.X *= -1.0;
                                obj.Objects[j].TranslateXDirection.Z *= -1.0;
                                obj.Objects[j].TranslateYDirection.X *= -1.0;
                                obj.Objects[j].TranslateYDirection.Z *= -1.0;
                                obj.Objects[j].TranslateZDirection.X *= -1.0;
                                obj.Objects[j].TranslateZDirection.Z *= -1.0;
                            }
                        }
                        else
                        {
                            throw new NotImplementedException();
                        }
                    }
                }
            }

            if (carObjectsCount > 0 & carObjectsCount < train.Cars.Length)
            {
                Interface.AddMessage(MessageType.Warning, false, "An incomplete set of exterior objects was provided in file " + filePath);
            }

            if (bogieObjectsCount > 0 & bogieObjectsCount < train.Cars.Length * 2)
            {
                Interface.AddMessage(MessageType.Warning, false, "An incomplete set of bogie objects was provided in file " + filePath);
            }
        }
Example #11
0
            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);
                    }
                    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;
                    }
                }
            }
Example #12
0
 internal DriverBody(TrainManager.Train train)
 {
     this.Train = train;
 }
Example #13
0
        // parse extensions config
        internal static void ParseExtensionsConfig(string TrainPath, System.Text.Encoding Encoding, ref UnifiedObject[] CarObjects, ref UnifiedObject[] BogieObjects, TrainManager.Train Train, bool LoadObjects)
        {
            bool[] CarObjectsReversed   = new bool[Train.Cars.Length];
            bool[] BogieObjectsReversed = new bool[Train.Cars.Length * 2];

            bool[] CarsDefined   = new bool[Train.Cars.Length];
            bool[] BogiesDefined = new bool[Train.Cars.Length * 2];
            System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
            string FileName = OpenBveApi.Path.CombineFile(TrainPath, "extensions.cfg");

            if (System.IO.File.Exists(FileName))
            {
                TextEncoding.Encoding newEncoding = TextEncoding.GetEncodingFromFile(FileName);
                if (newEncoding != TextEncoding.Encoding.Unknown)
                {
                    switch (newEncoding)
                    {
                    case TextEncoding.Encoding.Utf7:
                        Encoding = System.Text.Encoding.UTF7;
                        break;

                    case TextEncoding.Encoding.Utf8:
                        Encoding = System.Text.Encoding.UTF8;
                        break;

                    case TextEncoding.Encoding.Utf16Le:
                        Encoding = System.Text.Encoding.Unicode;
                        break;

                    case TextEncoding.Encoding.Utf16Be:
                        Encoding = System.Text.Encoding.BigEndianUnicode;
                        break;

                    case TextEncoding.Encoding.Utf32Le:
                        Encoding = System.Text.Encoding.UTF32;
                        break;

                    case TextEncoding.Encoding.Utf32Be:
                        Encoding = System.Text.Encoding.GetEncoding(12001);
                        break;

                    case TextEncoding.Encoding.Shift_JIS:
                        Encoding = System.Text.Encoding.GetEncoding(932);
                        break;
                    }
                }

                string[] Lines = System.IO.File.ReadAllLines(FileName, Encoding);
                for (int i = 0; i < Lines.Length; i++)
                {
                    int j = Lines[i].IndexOf(';');
                    if (j >= 0)
                    {
                        Lines[i] = Lines[i].Substring(0, j).Trim();
                    }
                    else
                    {
                        Lines[i] = Lines[i].Trim();
                    }
                }
                for (int i = 0; i < Lines.Length; i++)
                {
                    if (Lines[i].Length != 0)
                    {
                        switch (Lines[i].ToLowerInvariant())
                        {
                        case "[exterior]":
                            // exterior
                            i++;
                            while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal))
                            {
                                if (Lines[i].Length != 0)
                                {
                                    int j = Lines[i].IndexOf("=", StringComparison.Ordinal);
                                    if (j >= 0)
                                    {
                                        string a = Lines[i].Substring(0, j).TrimEnd();
                                        string b = Lines[i].Substring(j + 1).TrimStart();
                                        int    n;
                                        if (int.TryParse(a, System.Globalization.NumberStyles.Integer, Culture, out n))
                                        {
                                            if (n >= 0 & n < Train.Cars.Length)
                                            {
                                                if (Path.ContainsInvalidChars(b))
                                                {
                                                    Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                }
                                                else
                                                {
                                                    string File = OpenBveApi.Path.CombineFile(TrainPath, b);
                                                    if (System.IO.File.Exists(File))
                                                    {
                                                        if (LoadObjects)
                                                        {
                                                            CarObjects[n] = ObjectManager.LoadObject(File, Encoding, false);
                                                        }
                                                    }
                                                    else
                                                    {
                                                        Interface.AddMessage(MessageType.Error, true, "The car object " + File + " does not exist at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                    }
                                                }
                                            }
                                            else
                                            {
                                                Interface.AddMessage(MessageType.Error, false, "The car index " + a + " does not reference an existing car at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                        }
                                    }
                                    else
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "Invalid statement " + Lines[i] + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                    }
                                }
                                i++;
                            }
                            i--;
                            break;

                        default:
                            if (Lines[i].StartsWith("[car", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal))
                            {
                                // car
                                string t = Lines[i].Substring(4, Lines[i].Length - 5);
                                int    n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n))
                                {
                                    if (n >= 0 & n < Train.Cars.Length)
                                    {
                                        if (CarsDefined[n])
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "Car " + n.ToString(Culture) + " has already been declared at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                        }
                                        CarsDefined[n] = true;
                                        bool DefinedLength = false;
                                        bool DefinedAxles  = false;
                                        i++;
                                        while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal))
                                        {
                                            if (Lines[i].Length != 0)
                                            {
                                                int j = Lines[i].IndexOf("=", StringComparison.Ordinal);
                                                if (j >= 0)
                                                {
                                                    string a = Lines[i].Substring(0, j).TrimEnd();
                                                    string b = Lines[i].Substring(j + 1).TrimStart();
                                                    switch (a.ToLowerInvariant())
                                                    {
                                                    case "object":
                                                        if (string.IsNullOrEmpty(b))
                                                        {
                                                            Interface.AddMessage(MessageType.Error, true, "An empty car object was supplied at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            break;
                                                        }
                                                        if (Path.ContainsInvalidChars(b))
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        }
                                                        else
                                                        {
                                                            string File = OpenBveApi.Path.CombineFile(TrainPath, b);
                                                            if (System.IO.File.Exists(File))
                                                            {
                                                                if (LoadObjects)
                                                                {
                                                                    CarObjects[n] = ObjectManager.LoadObject(File, Encoding, false);
                                                                }
                                                            }
                                                            else
                                                            {
                                                                Interface.AddMessage(MessageType.Error, true, "The car object " + File + " does not exist at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                        }
                                                        break;

                                                    case "length":
                                                    {
                                                        double m;
                                                        if (double.TryParse(b, System.Globalization.NumberStyles.Float, Culture, out m))
                                                        {
                                                            if (m > 0.0)
                                                            {
                                                                Train.Cars[n].Length = m;
                                                                Train.Cars[n].BeaconReceiverPosition = 0.5 * m;
                                                                DefinedLength = true;
                                                            }
                                                            else
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Value is expected to be a positive floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                        }
                                                        else
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "Value is expected to be a positive floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        }
                                                    }
                                                    break;

                                                    case "axles":
                                                    {
                                                        int k = b.IndexOf(',');
                                                        if (k >= 0)
                                                        {
                                                            string c = b.Substring(0, k).TrimEnd();
                                                            string d = b.Substring(k + 1).TrimStart();
                                                            double rear, front;
                                                            if (!double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out rear))
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Rear is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else if (!double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out front))
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Front is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else if (rear >= front)
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Rear is expected to be less than Front in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else
                                                            {
                                                                Train.Cars[n].RearAxle.Position  = rear;
                                                                Train.Cars[n].FrontAxle.Position = front;
                                                                DefinedAxles = true;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "An argument-separating comma is expected in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        }
                                                    }
                                                    break;

                                                    case "reversed":
                                                        CarObjectsReversed[n] = b.Equals("true", StringComparison.OrdinalIgnoreCase);
                                                        break;

                                                    case "loadingsway":
                                                        Train.Cars[n].EnableLoadingSway = b.Equals("true", StringComparison.OrdinalIgnoreCase);
                                                        break;

                                                    default:
                                                        Interface.AddMessage(MessageType.Warning, false, "Unsupported key-value pair " + a + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        break;
                                                    }
                                                }
                                                else
                                                {
                                                    Interface.AddMessage(MessageType.Error, false, "Invalid statement " + Lines[i] + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                }
                                            }
                                            i++;
                                        }
                                        i--;
                                        if (DefinedLength & !DefinedAxles)
                                        {
                                            double AxleDistance = 0.4 * Train.Cars[n].Length;
                                            Train.Cars[n].RearAxle.Position  = -AxleDistance;
                                            Train.Cars[n].FrontAxle.Position = AxleDistance;
                                        }
                                    }
                                    else
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "The car index " + t + " does not reference an existing car at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                    }
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                }
                            }
                            else if (Lines[i].StartsWith("[coupler", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal))
                            {
                                // coupler
                                string t = Lines[i].Substring(8, Lines[i].Length - 9);
                                int    n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n))
                                {
                                    if (n >= 0 & n < Train.Couplers.Length)
                                    {
                                        i++; while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal))
                                        {
                                            if (Lines[i].Length != 0)
                                            {
                                                int j = Lines[i].IndexOf("=", StringComparison.Ordinal);
                                                if (j >= 0)
                                                {
                                                    string a = Lines[i].Substring(0, j).TrimEnd();
                                                    string b = Lines[i].Substring(j + 1).TrimStart();
                                                    switch (a.ToLowerInvariant())
                                                    {
                                                    case "distances":
                                                    {
                                                        int k = b.IndexOf(',');
                                                        if (k >= 0)
                                                        {
                                                            string c = b.Substring(0, k).TrimEnd();
                                                            string d = b.Substring(k + 1).TrimStart();
                                                            double min, max;
                                                            if (!double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out min))
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Minimum is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else if (!double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out max))
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Maximum is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else if (min > max)
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Minimum is expected to be less than Maximum in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else
                                                            {
                                                                Train.Couplers[n].MinimumDistanceBetweenCars = min;
                                                                Train.Couplers[n].MaximumDistanceBetweenCars = max;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "An argument-separating comma is expected in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        }
                                                    } break;

                                                    default:
                                                        Interface.AddMessage(MessageType.Warning, false, "Unsupported key-value pair " + a + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        break;
                                                    }
                                                }
                                                else
                                                {
                                                    Interface.AddMessage(MessageType.Error, false, "Invalid statement " + Lines[i] + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                }
                                            }
                                            i++;
                                        }
                                        i--;
                                    }
                                    else
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "The coupler index " + t + " does not reference an existing coupler at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                    }
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "The coupler index is expected to be an integer at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                }
                            }
                            else if (Lines[i].StartsWith("[bogie", StringComparison.OrdinalIgnoreCase) & Lines[i].EndsWith("]", StringComparison.Ordinal))
                            {
                                // car
                                string t = Lines[i].Substring(6, Lines[i].Length - 7);
                                int    n; if (int.TryParse(t, System.Globalization.NumberStyles.Integer, Culture, out n))
                                {
                                    if (n > BogiesDefined.Length - 1)
                                    {
                                        continue;
                                    }
                                    if (BogiesDefined[n])
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "Bogie " + n.ToString(Culture) + " has already been declared at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                    }
                                    BogiesDefined[n] = true;
                                    //Assuming that there are two bogies per car
                                    bool IsOdd    = (n % 2 != 0);
                                    int  CarIndex = n / 2;
                                    if (n >= 0 & n < Train.Cars.Length * 2)
                                    {
                                        bool DefinedAxles = false;
                                        i++;
                                        while (i < Lines.Length && !Lines[i].StartsWith("[", StringComparison.Ordinal) & !Lines[i].EndsWith("]", StringComparison.Ordinal))
                                        {
                                            if (Lines[i].Length != 0)
                                            {
                                                int j = Lines[i].IndexOf("=", StringComparison.Ordinal);
                                                if (j >= 0)
                                                {
                                                    string a = Lines[i].Substring(0, j).TrimEnd();
                                                    string b = Lines[i].Substring(j + 1).TrimStart();
                                                    switch (a.ToLowerInvariant())
                                                    {
                                                    case "object":
                                                        if (Path.ContainsInvalidChars(b))
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "File contains illegal characters at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        }
                                                        else
                                                        {
                                                            if (string.IsNullOrEmpty(b))
                                                            {
                                                                Interface.AddMessage(MessageType.Error, true, "An empty bogie object was supplied at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                                break;
                                                            }
                                                            string File = OpenBveApi.Path.CombineFile(TrainPath, b);
                                                            if (System.IO.File.Exists(File))
                                                            {
                                                                if (LoadObjects)
                                                                {
                                                                    BogieObjects[n] = ObjectManager.LoadObject(File, Encoding, false);
                                                                }
                                                            }
                                                            else
                                                            {
                                                                Interface.AddMessage(MessageType.Error, true, "The bogie object " + File + " does not exist at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                        }
                                                        break;

                                                    case "length":
                                                    {
                                                        Interface.AddMessage(MessageType.Error, false, "A defined length is not supported for bogies at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                    }
                                                    break;

                                                    case "axles":
                                                    {
                                                        int k = b.IndexOf(',');
                                                        if (k >= 0)
                                                        {
                                                            string c = b.Substring(0, k).TrimEnd();
                                                            string d = b.Substring(k + 1).TrimStart();
                                                            double rear, front;
                                                            if (!double.TryParse(c, System.Globalization.NumberStyles.Float, Culture, out rear))
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Rear is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else if (!double.TryParse(d, System.Globalization.NumberStyles.Float, Culture, out front))
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Front is expected to be a floating-point number in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else if (rear >= front)
                                                            {
                                                                Interface.AddMessage(MessageType.Error, false, "Rear is expected to be less than Front in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                            }
                                                            else
                                                            {
                                                                if (IsOdd)
                                                                {
                                                                    Train.Cars[CarIndex].FrontBogie.RearAxle.Position  = rear;
                                                                    Train.Cars[CarIndex].FrontBogie.FrontAxle.Position = front;
                                                                }
                                                                else
                                                                {
                                                                    Train.Cars[CarIndex].RearBogie.RearAxle.Position  = rear;
                                                                    Train.Cars[CarIndex].RearBogie.FrontAxle.Position = front;
                                                                }
                                                                DefinedAxles = true;
                                                            }
                                                        }
                                                        else
                                                        {
                                                            Interface.AddMessage(MessageType.Error, false, "An argument-separating comma is expected in " + a + " at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        }
                                                    }
                                                    break;

                                                    case "reversed":
                                                        BogieObjectsReversed[n] = b.Equals("true", StringComparison.OrdinalIgnoreCase);
                                                        break;

                                                    default:
                                                        Interface.AddMessage(MessageType.Warning, false, "Unsupported key-value pair " + a + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                        break;
                                                    }
                                                }
                                                else
                                                {
                                                    Interface.AddMessage(MessageType.Error, false, "Invalid statement " + Lines[i] + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                                }
                                            }
                                            i++;
                                        }
                                        i--;
                                        if (!DefinedAxles)
                                        {
                                            if (IsOdd)
                                            {
                                                double AxleDistance = 0.4 * Train.Cars[CarIndex].FrontBogie.Length;
                                                Train.Cars[CarIndex].FrontBogie.RearAxle.Position  = -AxleDistance;
                                                Train.Cars[CarIndex].FrontBogie.FrontAxle.Position = AxleDistance;
                                            }
                                            else
                                            {
                                                double AxleDistance = 0.4 * Train.Cars[CarIndex].RearBogie.Length;
                                                Train.Cars[CarIndex].RearBogie.RearAxle.Position  = -AxleDistance;
                                                Train.Cars[CarIndex].RearBogie.FrontAxle.Position = AxleDistance;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "The car index " + t + " does not reference an existing car at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                    }
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "The car index is expected to be an integer at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                                }
                            }
                            else
                            {
                                // default
                                if (Lines.Length == 1 && Encoding.Equals(Encoding.Unicode))
                                {
                                    /*
                                     * If only one line, there's a good possibility that our file is NOT Unicode at all
                                     * and that the misdetection has turned it into garbage
                                     *
                                     * Try again with ASCII instead
                                     */
                                    ParseExtensionsConfig(TrainPath, Encoding.GetEncoding(1252), ref CarObjects, ref BogieObjects, Train, LoadObjects);
                                    return;
                                }
                                Interface.AddMessage(MessageType.Error, false, "Invalid statement " + Lines[i] + " encountered at line " + (i + 1).ToString(Culture) + " in file " + FileName);
                            }
                            break;
                        }
                    }
                }

                // check for car objects and reverse if necessary
                int carObjects = 0;
                for (int i = 0; i < Train.Cars.Length; i++)
                {
                    if (CarObjects[i] != null)
                    {
                        carObjects++;
                        if (CarObjectsReversed[i] && LoadObjects)
                        {
                            {
                                // reverse axle positions
                                double temp = Train.Cars[i].FrontAxle.Position;
                                Train.Cars[i].FrontAxle.Position = -Train.Cars[i].RearAxle.Position;
                                Train.Cars[i].RearAxle.Position  = -temp;
                            }
                            if (CarObjects[i] is StaticObject)
                            {
                                StaticObject obj = (StaticObject)CarObjects[i];
                                obj.ApplyScale(-1.0, 1.0, -1.0);
                            }
                            else if (CarObjects[i] is ObjectManager.AnimatedObjectCollection)
                            {
                                ObjectManager.AnimatedObjectCollection obj = (ObjectManager.AnimatedObjectCollection)CarObjects[i];
                                for (int j = 0; j < obj.Objects.Length; j++)
                                {
                                    for (int h = 0; h < obj.Objects[j].States.Length; h++)
                                    {
                                        if (obj.Objects[j].States[h].Object == null)
                                        {
                                            continue;                                             //object failed to load?
                                        }
                                        obj.Objects[j].States[h].Object.ApplyScale(-1.0, 1.0, -1.0);
                                        obj.Objects[j].States[h].Position.X *= -1.0;
                                        obj.Objects[j].States[h].Position.Z *= -1.0;
                                    }
                                    obj.Objects[j].TranslateXDirection.X *= -1.0;
                                    obj.Objects[j].TranslateXDirection.Z *= -1.0;
                                    obj.Objects[j].TranslateYDirection.X *= -1.0;
                                    obj.Objects[j].TranslateYDirection.Z *= -1.0;
                                    obj.Objects[j].TranslateZDirection.X *= -1.0;
                                    obj.Objects[j].TranslateZDirection.Z *= -1.0;
                                }
                            }
                            else
                            {
                                throw new NotImplementedException();
                            }
                        }
                    }
                }

                //Check for bogie objects and reverse if necessary.....
                int bogieObjects = 0;
                for (int i = 0; i < Train.Cars.Length * 2; i++)
                {
                    bool IsOdd    = (i % 2 != 0);
                    int  CarIndex = i / 2;
                    if (BogieObjects[i] != null)
                    {
                        bogieObjects++;
                        if (BogieObjectsReversed[i] && LoadObjects)
                        {
                            {
                                // reverse axle positions
                                if (IsOdd)
                                {
                                    double temp = Train.Cars[CarIndex].FrontBogie.FrontAxle.Position;
                                    Train.Cars[CarIndex].FrontBogie.FrontAxle.Position = -Train.Cars[CarIndex].FrontBogie.RearAxle.Position;
                                    Train.Cars[CarIndex].FrontBogie.RearAxle.Position  = -temp;
                                }
                                else
                                {
                                    double temp = Train.Cars[CarIndex].RearBogie.FrontAxle.Position;
                                    Train.Cars[CarIndex].RearBogie.FrontAxle.Position = -Train.Cars[CarIndex].RearBogie.RearAxle.Position;
                                    Train.Cars[CarIndex].RearBogie.RearAxle.Position  = -temp;
                                }
                            }
                            if (BogieObjects[i] is StaticObject)
                            {
                                StaticObject obj = (StaticObject)BogieObjects[i];
                                obj.ApplyScale(-1.0, 1.0, -1.0);
                            }
                            else if (BogieObjects[i] is ObjectManager.AnimatedObjectCollection)
                            {
                                ObjectManager.AnimatedObjectCollection obj = (ObjectManager.AnimatedObjectCollection)BogieObjects[i];
                                for (int j = 0; j < obj.Objects.Length; j++)
                                {
                                    for (int h = 0; h < obj.Objects[j].States.Length; h++)
                                    {
                                        if (obj.Objects[j].States[h].Object == null)
                                        {
                                            continue;                                             //object failed to load?
                                        }
                                        obj.Objects[j].States[h].Object.ApplyScale(-1.0, 1.0, -1.0);
                                        obj.Objects[j].States[h].Position.X *= -1.0;
                                        obj.Objects[j].States[h].Position.Z *= -1.0;
                                    }
                                    obj.Objects[j].TranslateXDirection.X *= -1.0;
                                    obj.Objects[j].TranslateXDirection.Z *= -1.0;
                                    obj.Objects[j].TranslateYDirection.X *= -1.0;
                                    obj.Objects[j].TranslateYDirection.Z *= -1.0;
                                    obj.Objects[j].TranslateZDirection.X *= -1.0;
                                    obj.Objects[j].TranslateZDirection.Z *= -1.0;
                                }
                            }
                            else
                            {
                                throw new NotImplementedException();
                            }
                        }
                    }
                }

                if (carObjects > 0 & carObjects < Train.Cars.Length)
                {
                    Interface.AddMessage(MessageType.Warning, false, "An incomplete set of exterior objects was provided in file " + FileName);
                }

                if (bogieObjects > 0 & bogieObjects < Train.Cars.Length * 2)
                {
                    Interface.AddMessage(MessageType.Warning, false, "An incomplete set of bogie objects was provided in file " + FileName);
                }
            }
        }
Example #14
0
 /// <summary>Plays a car sound.</summary>
 /// <param name="sound">The car sound.</param>
 /// <param name="pitch">The pitch change factor.</param>
 /// <param name="volume">The volume change factor.</param>
 /// <param name="train">The train the sound is attached to.</param>
 /// <param name="car">The car in the train the sound is attached to.</param>
 /// <param name="looped">Whether to play the sound in a loop.</param>
 /// <returns>The sound source.</returns>
 internal static void PlayCarSound(TrainManager.CarSound sound, double pitch, double volume, TrainManager.Train train, int car, bool looped)
 {
     if (sound.Buffer == null)
     {
         return;
     }
     if (train == null)
     {
         throw new InvalidDataException("A train and car must be specified");
     }
     sound.Source = PlaySound(sound.Buffer, pitch, volume, sound.Position, train, car, looped);
 }
Example #15
0
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (TriggerType == EventTriggerType.TrainFront)
     {
         if (Direction < 0)
         {
             Train.StationFrontCar = false;
             if (Train.Handles.Reverser.Actual == TrainManager.ReverserPosition.Forwards && Train.Handles.Power.Driver != 0 && !Game.MinimalisticSimulation && StationIndex == Train.Station)
             {
                 //Our reverser and power are in F, but we are rolling backwards
                 //Leave the station index alone, and we won't trigger again when we actually move forwards
                 return;
             }
             Train.Station = -1;
         }
         else if (Direction > 0)
         {
             if (Train.Station == StationIndex || Train.NextStopSkipped != TrainManager.StopSkipMode.None)
             {
                 return;
             }
             Train.Station         = StationIndex;
             Train.StationFrontCar = true;
             Train.StationState    = TrainManager.TrainStopState.Pending;
             Train.LastStation     = this.StationIndex;
         }
     }
     else if (TriggerType == EventTriggerType.RearCarRearAxle)
     {
         if (Direction < 0)
         {
             Train.StationRearCar = false;
         }
         else
         {
             Train.StationRearCar = true;
         }
     }
 }
Example #16
0
        /// <summary>Updates the specified signal section</summary>
        /// <param name="SectionIndex">The index of the section to update</param>
        internal static void UpdateSection(int SectionIndex)
        {
            if (SectionIndex >= Sections.Length || Sections == null)
            {
                return;
            }
            // preparations
            int  zeroaspect;
            bool settored = false;

            if (Sections[SectionIndex].Type == SectionType.ValueBased)
            {
                // value-based
                zeroaspect = 0;
                for (int i = 1; i < Sections[SectionIndex].Aspects.Length; i++)
                {
                    if (Sections[SectionIndex].Aspects[i].Number < Sections[SectionIndex].Aspects[zeroaspect].Number)
                    {
                        zeroaspect = i;
                    }
                }
            }
            else
            {
                // index-based
                zeroaspect = 0;
            }
            // hold station departure signal at red
            int d = Sections[SectionIndex].StationIndex;

            if (d >= 0)
            {
                // look for train in previous blocks
                int l = Sections[SectionIndex].PreviousSection;
                TrainManager.Train train = null;
                while (true)
                {
                    if (l >= 0)
                    {
                        train = Sections[l].GetFirstTrain(false);
                        if (train != null)
                        {
                            break;
                        }
                        l = Sections[l].PreviousSection;
                    }
                    else
                    {
                        break;
                    }
                }
                if (train == null)
                {
                    double b = -double.MaxValue;
                    for (int i = 0; i < TrainManager.Trains.Length; i++)
                    {
                        if (TrainManager.Trains[i].State == TrainManager.TrainState.Available)
                        {
                            if (TrainManager.Trains[i].TimetableDelta > b)
                            {
                                b     = TrainManager.Trains[i].TimetableDelta;
                                train = TrainManager.Trains[i];
                            }
                        }
                    }
                }
                // set to red where applicable
                if (train != null)
                {
                    if (!Sections[SectionIndex].TrainReachedStopPoint)
                    {
                        if (train.Station == d)
                        {
                            int c = GetStopIndex(d, train.Cars.Length);
                            if (c >= 0)
                            {
                                double p0 = train.Cars[0].FrontAxle.Follower.TrackPosition - train.Cars[0].FrontAxle.Position + 0.5 * train.Cars[0].Length;
                                double p1 = Stations[d].Stops[c].TrackPosition - Stations[d].Stops[c].BackwardTolerance;
                                if (p0 >= p1)
                                {
                                    Sections[SectionIndex].TrainReachedStopPoint = true;
                                }
                            }
                            else
                            {
                                Sections[SectionIndex].TrainReachedStopPoint = true;
                            }
                        }
                    }
                    double t = -15.0;
                    if (Stations[d].DepartureTime >= 0.0)
                    {
                        t = Stations[d].DepartureTime - 15.0;
                    }
                    else if (Stations[d].ArrivalTime >= 0.0)
                    {
                        t = Stations[d].ArrivalTime;
                    }
                    if (train == TrainManager.PlayerTrain & Stations[d].StationType != StationType.Normal & Stations[d].DepartureTime < 0.0)
                    {
                        settored = true;
                    }
                    else if (t >= 0.0 & SecondsSinceMidnight < t - train.TimetableDelta)
                    {
                        settored = true;
                    }
                    else if (!Sections[SectionIndex].TrainReachedStopPoint)
                    {
                        settored = true;
                    }
                }
                else if (Stations[d].StationType != StationType.Normal)
                {
                    settored = true;
                }
            }
            // train in block
            if (!Sections[SectionIndex].IsFree())
            {
                settored = true;
            }
            // free sections
            int newaspect = -1;

            if (settored)
            {
                Sections[SectionIndex].FreeSections = 0;
                newaspect = zeroaspect;
            }
            else
            {
                int n = Sections[SectionIndex].NextSection;
                if (n >= 0)
                {
                    if (Sections[n].FreeSections == -1)
                    {
                        Sections[SectionIndex].FreeSections = -1;
                    }
                    else
                    {
                        Sections[SectionIndex].FreeSections = Sections[n].FreeSections + 1;
                    }
                }
                else
                {
                    Sections[SectionIndex].FreeSections = -1;
                }
            }
            // change aspect
            if (newaspect == -1)
            {
                if (Sections[SectionIndex].Type == SectionType.ValueBased)
                {
                    // value-based
                    int n = Sections[SectionIndex].NextSection;
                    int a = Sections[SectionIndex].Aspects[Sections[SectionIndex].Aspects.Length - 1].Number;
                    if (n >= 0 && Sections[n].CurrentAspect >= 0)
                    {
                        a = Sections[n].Aspects[Sections[n].CurrentAspect].Number;
                    }
                    for (int i = Sections[SectionIndex].Aspects.Length - 1; i >= 0; i--)
                    {
                        if (Sections[SectionIndex].Aspects[i].Number > a)
                        {
                            newaspect = i;
                        }
                    }
                    if (newaspect == -1)
                    {
                        newaspect = Sections[SectionIndex].Aspects.Length - 1;
                    }
                }
                else
                {
                    // index-based
                    if (Sections[SectionIndex].FreeSections >= 0 & Sections[SectionIndex].FreeSections < Sections[SectionIndex].Aspects.Length)
                    {
                        newaspect = Sections[SectionIndex].FreeSections;
                    }
                    else
                    {
                        newaspect = Sections[SectionIndex].Aspects.Length - 1;
                    }
                }
            }
            // apply new aspect
            Sections[SectionIndex].CurrentAspect = newaspect;
            // update previous section
            if (Sections[SectionIndex].PreviousSection >= 0)
            {
                UpdateSection(Sections[SectionIndex].PreviousSection);
            }
        }
Example #17
0
 internal static void PlaySound(ref int SoundSourceIndex, int SoundBufferIndex, TrainManager.Train Train, int CarIndex, World.Vector3D Position, Importance Important, bool Looped, double Pitch, double Gain)
 {
     PlaySound(ref SoundSourceIndex, true, SoundBufferIndex, Train, CarIndex, Position, Important, Looped, Pitch, Gain);
 }
Example #18
0
 /// <summary>Plays a sound.</summary>
 /// <param name="buffer">The sound buffer.</param>
 /// <param name="pitch">The pitch change factor.</param>
 /// <param name="volume">The volume change factor.</param>
 /// <param name="position">The position. If a train and car are specified, the position is relative to the car, otherwise absolute.</param>
 /// <param name="train">The train the sound is attached to, or a null reference.</param>
 /// <param name="car">The car in the train the sound is attached to.</param>
 /// <param name="looped">Whether to play the sound in a loop.</param>
 /// <returns>The sound source.</returns>
 internal static SoundSource PlaySound(SoundBuffer buffer, double pitch, double volume, OpenBveApi.Math.Vector3D position, TrainManager.Train train, int car, bool looped)
 {
     if (Sources.Length == SourceCount)
     {
         Array.Resize <SoundSource>(ref Sources, Sources.Length << 1);
     }
     Sources[SourceCount] = new SoundSource(buffer, buffer.Radius, pitch, volume, position, train, car, looped);
     SourceCount++;
     return(Sources[SourceCount - 1]);
 }
Example #19
0
 private static void PlaySound(ref int SoundSourceIndex, bool ReturnHandle, int SoundBufferIndex, TrainManager.Train Train, int CarIndex, World.Vector3D Position, Importance Important, bool Looped, double Pitch, double Gain)
 {
     if (OpenAlContext != ContextHandle.Zero)
     {
         if (Game.MinimalisticSimulation & Important == Importance.DontCare | SoundBufferIndex == -1)
         {
             return;
         }
         if (SoundSourceIndex >= 0)
         {
             StopSound(ref SoundSourceIndex);
         }
         int i;
         for (i = 0; i < SoundSources.Length; i++)
         {
             if (SoundSources[i] == null)
             {
                 break;
             }
         }
         if (i >= SoundSources.Length)
         {
             Array.Resize <SoundSource>(ref SoundSources, SoundSources.Length << 1);
         }
         SoundSources[i]                   = new SoundSource();
         SoundSources[i].Position          = Position;
         SoundSources[i].OpenAlPosition    = new float[] { 0.0f, 0.0f, 0.0f };
         SoundSources[i].OpenAlVelocity    = new float[] { 0.0f, 0.0f, 0.0f };
         SoundSources[i].SoundBufferIndex  = SoundBufferIndex;
         SoundSources[i].Radius            = SoundBuffers[SoundBufferIndex].Radius;
         SoundSources[i].Pitch             = (float)Pitch;
         SoundSources[i].Gain              = (float)Gain;
         SoundSources[i].Looped            = Looped;
         SoundSources[i].Suppressed        = true;
         SoundSources[i].FinishedPlaying   = false;
         SoundSources[i].Train             = Train;
         SoundSources[i].CarIndex          = CarIndex;
         SoundSources[i].OpenAlSourceIndex = new OpenAlIndex(0, false);
         SoundSources[i].HasHandle         = ReturnHandle;
         SoundSourceIndex                  = i;
     }
 }
#pragma warning restore 0649

            public 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 + Camera.CurrentAlignment.Position.Z - Backgrounds.BackgroundImageDistance - World.ExtraViewingDistance;
                double       tb          = World.CameraTrackFollower.TrackPosition + Camera.CurrentAlignment.Position.Z + Backgrounds.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 == 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;
                                }
                            }
                        }
                        if (Visible)
                        {
                            //Calculate the distance travelled
                            double delta = UpdateTrackFollowerScript(false, train, train == null ? 0 : train.DriverCar, SectionIndex, TrackPosition, Position, true, timeDelta);
                            //Update the front and rear axle track followers
                            FrontAxleFollower.Update((TrackPosition + FrontAxlePosition) + delta, true, true);
                            RearAxleFollower.Update((TrackPosition + RearAxlePosition) + delta, true, true);
                            //Update the base object position
                            FrontAxleFollower.UpdateWorldCoordinates(false);
                            RearAxleFollower.UpdateWorldCoordinates(false);
                            UpdateObjectPosition();
                        }
                        //Update the actual animated object- This must be done last in case the user has used Translation or Rotation
                        Object.Update(false, train, train == null ? 0 : train.DriverCar, SectionIndex, FrontAxleFollower.TrackPosition, FrontAxleFollower.WorldPosition, Direction, Up, Side, false, true, true, timeDelta, true);
                    }
                    else
                    {
                        Object.SecondsSinceLastUpdate += TimeElapsed;
                    }
                    if (!Visible)
                    {
                        Renderer.ShowObject(Object.ObjectIndex, ObjectType.Dynamic);
                        Visible = true;
                    }
                }
                else
                {
                    Object.SecondsSinceLastUpdate += TimeElapsed;
                    if (Visible)
                    {
                        Renderer.HideObject(ref ObjectManager.Objects[Object.ObjectIndex]);
                        Visible = false;
                    }
                }
            }
Example #21
0
        private void ApplyTrain()
        {
            lock (Program.LockObj)
            {
                Program.TrainManager.Trains = new TrainBase[] { };
                if (checkBoxEnableTrain.Checked)
                {
                    Array.Resize(ref Program.TrainManager.Trains, 1);
                    TrainManager.Train Train = new TrainManager.Train
                    {
                        State = TrainState.Available
                    };
                    Array.Resize(ref Train.Cars, (int)numericUpDownCars.Value);
                    for (int i = 0; i < Train.Cars.Length; i++)
                    {
                        Train.Cars[i] = new CarBase(Train, i);
                        Train.Cars[i].CurrentSpeed = (int)numericUpDownSpeed.Value / 3.6;
                        Train.Cars[i].Specs        = new CarPhysics
                        {
                            PerceivedSpeed = (int)numericUpDownSpeed.Value / 3.6,
                            Acceleration   = (int)numericUpDownAccel.Value / 3.6
                        };
                        if (checkBoxAirBrake.Checked)
                        {
                            Train.Cars[i].CarBrake = new AutomaticAirBrake(EletropneumaticBrakeType.None, Train.Handles.EmergencyBrake, Train.Handles.Reverser, true, 0.0, 0.0, new AccelerationCurve[] {});
                        }
                        else
                        {
                            Train.Cars[i].CarBrake = new ElectromagneticStraightAirBrake(EletropneumaticBrakeType.None, Train.Handles.EmergencyBrake, Train.Handles.Reverser, true, 0.0, 0.0, new AccelerationCurve[] {});
                        }
                        //At the minute, Object Viewer uses dummy brake systems
                        Train.Cars[i].CarBrake.mainReservoir   = new MainReservoir((int)numericUpDownMain.Value * 1000);
                        Train.Cars[i].CarBrake.brakePipe       = new BrakePipe((int)numericUpDownPipe.Value * 1000);
                        Train.Cars[i].CarBrake.brakeCylinder   = new BrakeCylinder((int)numericUpDownCylinder.Value * 1000);
                        Train.Cars[i].CarBrake.straightAirPipe = new StraightAirPipe((int)numericUpDownAirPipe.Value * 1000);

                        Train.Cars[i].Doors[0] = new Door(-1, 1000, 0)
                        {
                            State           = (double)numericUpDownLeft.Value,
                            AnticipatedOpen = checkBoxLeftTarget.Checked
                        };
                        Train.Cars[i].Doors[1] = new Door(1, 1000, 0)
                        {
                            State           = (double)numericUpDownRight.Value,
                            AnticipatedOpen = checkBoxRightTarget.Checked
                        };
                    }

                    Train.Handles.Reverser.Driver = (ReverserPosition)numericUpDownReverser.Value;
                    Train.Handles.Reverser.Actual = (ReverserPosition)numericUpDownReverser.Value;
                    if ((int)numericUpDownPowerNotches.Value != Train.Handles.Power.MaximumNotch)
                    {
                        Train.Handles.Power = new PowerHandle((int)numericUpDownPowerNotches.Value, (int)numericUpDownPowerNotches.Value, new double[] {}, new double[] {}, Train);
                    }
                    Train.Handles.Power.Driver = (int)numericUpDownPowerNotch.Value;
                    if (checkBoxAirBrake.Checked)
                    {
                        Train.Handles.Brake.Driver = (int)numericUpDownBrakeNotch.Value;
                    }
                    else
                    {
                        if ((int)numericUpDownBrakeNotches.Value != Train.Handles.Brake.MaximumNotch)
                        {
                            Train.Handles.Brake = new BrakeHandle((int)numericUpDownBrakeNotches.Value, (int)numericUpDownBrakeNotches.Value, null, new double[] {}, new double[] {}, Train);
                        }
                        Train.Handles.Brake.Driver = (int)numericUpDownBrakeNotch.Value;
                        Train.Handles.HasHoldBrake = checkBoxHoldBrake.Checked;
                        if (checkBoxHoldBrake.Checked)
                        {
                            Train.Handles.HoldBrake.Driver = checkBoxSetHoldBrake.Checked;
                        }
                    }
                    Train.Handles.EmergencyBrake.Driver = checkBoxSetEmergency.Checked;
                    Train.Specs.HasConstSpeed           = checkBoxConstSpeed.Checked;
                    if (checkBoxConstSpeed.Checked)
                    {
                        Train.Specs.CurrentConstSpeed = checkBoxSetConstSpeed.Checked;
                    }

                    Train.SafetySystemPlugin = checkBoxEnablePlugin.Checked;
                    if (checkBoxEnablePlugin.Checked && PluginStates.Count != 0)
                    {
                        PluginManager.CurrentPlugin.Panel = new int[PluginStates.Max(value => value.Number) + 1];
                        foreach (PluginState state in PluginStates)
                        {
                            PluginManager.CurrentPlugin.Panel[state.Number] = state.State;
                        }
                    }
                    else
                    {
                        PluginManager.CurrentPlugin.Panel = new int[] { };
                    }

                    Program.TrainManager.Trains[0] = Train;
                }
            }
        }
Example #22
0
        /// <summary>Loads the sound set for a BVE2 based train</summary>
        /// <param name="train">The train</param>
        /// <param name="trainFolder">The absolute on-disk path to the train's folder</param>
        internal static void Parse(string trainFolder, TrainManager.Train train)
        {
            // set sound positions and radii
            Vector3 front  = new Vector3(0.0, 0.0, 0.5 * train.Cars[train.DriverCar].Length);
            Vector3 center = new Vector3(0.0, 0.0, 0.0);
            Vector3 left   = new Vector3(-1.3, 0.0, 0.0);
            Vector3 right  = new Vector3(1.3, 0.0, 0.0);
            Vector3 cab    = new Vector3(-train.Cars[train.DriverCar].Driver.X, train.Cars[train.DriverCar].Driver.Y, train.Cars[train.DriverCar].Driver.Z - 0.5);
            Vector3 panel  = new Vector3(train.Cars[train.DriverCar].Driver.X, train.Cars[train.DriverCar].Driver.Y, train.Cars[train.DriverCar].Driver.Z + 1.0);

            train.InitializeCarSounds();
            // load sounds for driver's car
            train.Cars[train.DriverCar].Sounds.Adjust                 = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Adjust.wav"), panel, SoundCfgParser.tinyRadius);
            train.Cars[train.DriverCar].Sounds.Brake                  = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Brake.wav"), center, SoundCfgParser.smallRadius);
            train.Cars[train.DriverCar].Sounds.Halt                   = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Halt.wav"), cab, SoundCfgParser.tinyRadius);
            train.Cars[train.DriverCar].Sounds.Horns[0].LoopSound     = Sounds.SoundBuffer.TryToLoad(OpenBveApi.Path.CombineFile(trainFolder, "Klaxon0.wav"), SoundCfgParser.smallRadius);
            train.Cars[train.DriverCar].Sounds.Horns[0].Loop          = false;
            train.Cars[train.DriverCar].Sounds.Horns[0].SoundPosition = front;
            if (train.Cars[train.DriverCar].Sounds.Horns[0].LoopSound == null)
            {
                train.Cars[train.DriverCar].Sounds.Horns[0].LoopSound = Sounds.SoundBuffer.TryToLoad(OpenBveApi.Path.CombineFile(trainFolder, "Klaxon.wav"), SoundCfgParser.largeRadius);
            }
            train.Cars[train.DriverCar].Sounds.Horns[1].LoopSound     = Sounds.SoundBuffer.TryToLoad(OpenBveApi.Path.CombineFile(trainFolder, "Klaxon1.wav"), SoundCfgParser.largeRadius);
            train.Cars[train.DriverCar].Sounds.Horns[1].Loop          = false;
            train.Cars[train.DriverCar].Sounds.Horns[1].SoundPosition = front;
            train.Cars[train.DriverCar].Sounds.Horns[2].LoopSound     = Sounds.SoundBuffer.TryToLoad(OpenBveApi.Path.CombineFile(trainFolder, "Klaxon2.wav"), SoundCfgParser.mediumRadius);
            train.Cars[train.DriverCar].Sounds.Horns[2].Loop          = true;
            train.Cars[train.DriverCar].Sounds.Horns[2].SoundPosition = front;
            train.Cars[train.DriverCar].Sounds.PilotLampOn            = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Leave.wav"), cab, SoundCfgParser.tinyRadius);
            train.Cars[train.DriverCar].Sounds.PilotLampOff           = TrainManager.CarSound.Empty;
            // load sounds for all cars
            for (int i = 0; i < train.Cars.Length; i++)
            {
                Vector3 frontaxle = new Vector3(0.0, 0.0, train.Cars[i].FrontAxle.Position);
                Vector3 rearaxle  = new Vector3(0.0, 0.0, train.Cars[i].RearAxle.Position);
                train.Cars[i].Sounds.Air     = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Air.wav"), center, SoundCfgParser.smallRadius);
                train.Cars[i].Sounds.AirHigh = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "AirHigh.wav"), center, SoundCfgParser.smallRadius);
                train.Cars[i].Sounds.AirZero = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "AirZero.wav"), center, SoundCfgParser.smallRadius);
                if (train.Cars[i].Specs.AirBrake.Type == TrainManager.AirBrakeType.Main)
                {
                    train.Cars[i].Sounds.CpEnd   = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "CpEnd.wav"), center, SoundCfgParser.mediumRadius);
                    train.Cars[i].Sounds.CpLoop  = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "CpLoop.wav"), center, SoundCfgParser.mediumRadius);
                    train.Cars[i].Sounds.CpStart = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "CpStart.wav"), center, SoundCfgParser.mediumRadius);
                }
                train.Cars[i].Sounds.BreakerResume            = TrainManager.CarSound.Empty;
                train.Cars[i].Sounds.BreakerResumeOrInterrupt = TrainManager.CarSound.Empty;
                train.Cars[i].Sounds.BreakerResumed           = false;
                train.Cars[i].Sounds.DoorCloseL = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorClsL.wav"), left, SoundCfgParser.smallRadius);
                train.Cars[i].Sounds.DoorCloseR = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorClsR.wav"), right, SoundCfgParser.smallRadius);
                if (train.Cars[i].Sounds.DoorCloseL.Buffer == null)
                {
                    train.Cars[i].Sounds.DoorCloseL = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorCls.wav"), left, SoundCfgParser.smallRadius);
                }
                if (train.Cars[i].Sounds.DoorCloseR.Buffer == null)
                {
                    train.Cars[i].Sounds.DoorCloseR = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorCls.wav"), right, SoundCfgParser.smallRadius);
                }
                train.Cars[i].Sounds.DoorOpenL = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorOpnL.wav"), left, SoundCfgParser.smallRadius);
                train.Cars[i].Sounds.DoorOpenR = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorOpnR.wav"), right, SoundCfgParser.smallRadius);
                if (train.Cars[i].Sounds.DoorOpenL.Buffer == null)
                {
                    train.Cars[i].Sounds.DoorOpenL = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorOpn.wav"), left, SoundCfgParser.smallRadius);
                }
                if (train.Cars[i].Sounds.DoorOpenR.Buffer == null)
                {
                    train.Cars[i].Sounds.DoorOpenR = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "DoorOpn.wav"), right, SoundCfgParser.smallRadius);
                }
                train.Cars[i].Sounds.EmrBrake       = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "EmrBrake.wav"), center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.Flange         = SoundCfgParser.TryLoadSoundArray(trainFolder, "Flange", ".wav", center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.FlangeVolume   = new double[train.Cars[i].Sounds.Flange.Length];
                train.Cars[i].Sounds.Loop           = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Loop.wav"), center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.PointFrontAxle = new TrainManager.CarSound[]
                {
                    new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Point.wav"), frontaxle, SoundCfgParser.smallRadius)
                };
                train.Cars[i].Sounds.PointRearAxle = new TrainManager.CarSound[]
                {
                    new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Point.wav"), rearaxle, SoundCfgParser.smallRadius)
                };
                train.Cars[i].Sounds.Rub       = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Rub.wav"), center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.Run       = SoundCfgParser.TryLoadSoundArray(trainFolder, "Run", ".wav", center, SoundCfgParser.mediumRadius);
                train.Cars[i].Sounds.RunVolume = new double[train.Cars[i].Sounds.Run.Length];
                train.Cars[i].Sounds.SpringL   = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "SpringL.wav"), left, SoundCfgParser.smallRadius);
                train.Cars[i].Sounds.SpringR   = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "SpringR.wav"), right, SoundCfgParser.smallRadius);
                // motor sound
                if (train.Cars[i].Specs.IsMotorCar)
                {
                    System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
                    train.Cars[i].Sounds.Motor.Position = center;
                    for (int j = 0; j < train.Cars[i].Sounds.Motor.Tables.Length; j++)
                    {
                        for (int k = 0; k < train.Cars[i].Sounds.Motor.Tables[j].Entries.Length; k++)
                        {
                            int idx = train.Cars[i].Sounds.Motor.Tables[j].Entries[k].SoundIndex;
                            if (idx >= 0)
                            {
                                TrainManager.CarSound snd = new TrainManager.CarSound(OpenBveApi.Path.CombineFile(trainFolder, "Motor" + idx.ToString(Culture) + ".wav"), center, SoundCfgParser.mediumRadius);
                                train.Cars[i].Sounds.Motor.Tables[j].Entries[k].Buffer = snd.Buffer;
                            }
                        }
                    }
                }
            }
        }
Example #23
0
        private formTrain()
        {
            InitializeComponent();

            checkBoxEnableTrain.Checked = Program.TrainManager.Trains.Length != 0;
            tabControlSettings.Enabled  = checkBoxEnableTrain.Checked;

            labelEmergency.Enabled         = false;
            numericUpDownEmergency.Enabled = false;
            checkBoxSetHoldBrake.Enabled   = false;
            checkBoxSetConstSpeed.Enabled  = false;
            TrainManager.Train Train = Program.TrainManager.Trains[0] as TrainManager.Train;
            if (checkBoxEnableTrain.Checked)
            {
                numericUpDownCars.Value  = Train.Cars.Length;
                numericUpDownSpeed.Value = (decimal)(Train.Cars[0].CurrentSpeed * 3.6);
                numericUpDownAccel.Value = (decimal)(Train.Cars[0].Specs.MotorAcceleration * 3.6);

                numericUpDownMain.Value     = (decimal)(Train.Cars[0].CarBrake.mainReservoir.CurrentPressure / 1000.0);
                numericUpDownPipe.Value     = (decimal)(Train.Cars[0].CarBrake.brakePipe.CurrentPressure / 1000.0);
                numericUpDownCylinder.Value = (decimal)(Train.Cars[0].CarBrake.brakeCylinder.CurrentPressure / 1000.0);
                numericUpDownAirPipe.Value  = (decimal)(Train.Cars[0].CarBrake.straightAirPipe.CurrentPressure / 1000.0);

                numericUpDownLeft.Value     = (decimal)Train.Cars[0].Doors[0].State;
                numericUpDownRight.Value    = (decimal)Train.Cars[0].Doors[1].State;
                checkBoxLeftTarget.Checked  = Train.Cars[0].Doors[0].AnticipatedOpen;
                checkBoxRightTarget.Checked = Train.Cars[0].Doors[1].AnticipatedOpen;

                numericUpDownReverser.Value     = (decimal)Train.Handles.Reverser.Driver;
                numericUpDownPowerNotch.Value   = Train.Handles.Power.Driver;
                numericUpDownPowerNotches.Value = Train.Handles.Power.MaximumNotch;
                checkBoxAirBrake.Checked        = Train.Cars[0].CarBrake is AutomaticAirBrake;
                if (checkBoxAirBrake.Checked)
                {
                    numericUpDownBrakeNotch.Value     = (int)Train.Handles.Brake.Driver;
                    numericUpDownBrakeNotch.Maximum   = 2;
                    numericUpDownBrakeNotches.Value   = 2;
                    numericUpDownBrakeNotches.Enabled = false;
                    checkBoxHoldBrake.Enabled         = false;
                }
                else
                {
                    numericUpDownBrakeNotch.Value   = Train.Handles.Brake.Driver;
                    numericUpDownBrakeNotches.Value = Train.Handles.Brake.MaximumNotch;
                    checkBoxHoldBrake.Checked       = Train.Handles.HasHoldBrake;
                    if (checkBoxHoldBrake.Checked)
                    {
                        checkBoxSetHoldBrake.Enabled = true;
                        checkBoxSetHoldBrake.Checked = Train.Handles.HoldBrake.Driver;
                    }
                }
                checkBoxSetEmergency.Checked = Train.Handles.EmergencyBrake.Driver;
                checkBoxConstSpeed.Checked   = Train.Specs.HasConstSpeed;
                if (checkBoxConstSpeed.Checked)
                {
                    checkBoxSetConstSpeed.Enabled = true;
                    checkBoxSetConstSpeed.Checked = Train.Specs.CurrentConstSpeed;
                }

                checkBoxEnablePlugin.Checked = Train.SafetySystemPlugin;
            }
            panelPlugin.Enabled         = checkBoxEnablePlugin.Checked;
            buttonRemove.Enabled        = false;
            labelNumber.Enabled         = false;
            numericUpDownNumber.Enabled = false;
            labelState.Enabled          = false;
            numericUpDownState.Enabled  = false;
            PluginStates = new List <PluginState>();
            for (int i = 0; i < PluginManager.CurrentPlugin.Panel.Length; i++)
            {
                if (PluginManager.CurrentPlugin.Panel[i] != 0)
                {
                    PluginStates.Add(new PluginState(i, PluginManager.CurrentPlugin.Panel[i]));
                }
            }
            ListPluginStates();
        }
Example #24
0
        internal static void Parse(string fileName, ref TrainManager.Train Train, ref TrainManager.Car car, bool isDriverCar)
        {
            //3D center of the car
            Vector3 center = Vector3.Zero;
            //Positioned to the left of the car, but centered Y & Z
            Vector3 left = new Vector3(-1.3, 0.0, 0.0);
            //Positioned to the right of the car, but centered Y & Z
            Vector3 right = new Vector3(1.3, 0.0, 0.0);
            //Positioned at the front of the car, centered X and Y
            Vector3 front = new Vector3(0.0, 0.0, 0.5 * car.Length);
            //Positioned at the position of the panel / 3D cab (Remember that the panel is just an object in the world...)
            Vector3 panel = new Vector3(car.Driver.X, car.Driver.Y, car.Driver.Z + 1.0);



            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the marker's XML file
            currentXML.Load(fileName);
            currentPath = System.IO.Path.GetDirectoryName(fileName);
            if (currentXML.DocumentElement != null)
            {
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CarSounds");
                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    Interface.AddMessage(MessageType.Error, false, "No car sound nodes defined in XML file " + fileName);
                    //If we have no appropriate nodes specified, return false and fallback to loading the legacy Sound.cfg file
                    throw new Exception("Empty sound.xml file");
                }
                foreach (XmlNode n in DocumentNodes)
                {
                    if (n.ChildNodes.OfType <XmlElement>().Any())
                    {
                        foreach (XmlNode c in n.ChildNodes)
                        {
                            switch (c.Name.ToLowerInvariant())
                            {
                            case "ats":
                            case "plugin":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of plugin sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                ParseArrayNode(c, out car.Sounds.Plugin, center, SoundCfgParser.mediumRadius);
                                break;

                            case "brake":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of brake sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "releasehigh":
                                        //Release brakes from high pressure
                                        ParseNode(cc, out car.CarBrake.AirHigh, center, SoundCfgParser.smallRadius);
                                        break;

                                    case "release":
                                        //Release brakes from normal pressure
                                        ParseNode(cc, out car.CarBrake.Air, center, SoundCfgParser.smallRadius);
                                        break;

                                    case "releasefull":
                                        //Release brakes from full pressure
                                        ParseNode(cc, out car.CarBrake.AirZero, center, SoundCfgParser.smallRadius);
                                        break;

                                    case "emergency":
                                        //Apply EB
                                        ParseNode(cc, out Train.Handles.EmergencyBrake.ApplicationSound, center, SoundCfgParser.smallRadius);
                                        break;

                                    case "emergencyrelease":
                                        //Release EB
                                        ParseNode(cc, out Train.Handles.EmergencyBrake.ReleaseSound, center, SoundCfgParser.smallRadius);
                                        break;

                                    case "application":
                                        //Standard application
                                        ParseNode(cc, out car.Sounds.Brake, center, SoundCfgParser.smallRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "brakehandle":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of brake handle sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "apply":
                                        ParseNode(cc, out Train.Handles.Brake.Increase, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "applyfast":
                                        ParseNode(cc, out Train.Handles.Brake.IncreaseFast, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "release":
                                        ParseNode(cc, out Train.Handles.Brake.Decrease, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "releasefast":
                                        ParseNode(cc, out Train.Handles.Brake.DecreaseFast, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "min":
                                    case "minimum":
                                        ParseNode(cc, out Train.Handles.Brake.Min, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "max":
                                    case "maximum":
                                        ParseNode(cc, out Train.Handles.Brake.Max, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "breaker":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of breaker sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "on":
                                        ParseNode(cc, out car.Sounds.BreakerResume, panel, SoundCfgParser.smallRadius);
                                        break;

                                    case "off":
                                        ParseNode(cc, out car.Sounds.BreakerResumeOrInterrupt, panel, SoundCfgParser.smallRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "buzzer":
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                ParseNode(c, out Train.SafetySystems.StationAdjust.AdjustAlarm, panel, SoundCfgParser.tinyRadius);
                                break;

                            case "compressor":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of compressor sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (car.CarBrake.brakeType != BrakeType.Main)
                                {
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "attack":
                                    case "start":
                                        //Compressor starting sound
                                        ParseNode(cc, out car.CarBrake.airCompressor.StartSound, center, SoundCfgParser.mediumRadius);
                                        break;

                                    case "loop":
                                        //Compressor loop sound
                                        ParseNode(cc, out car.CarBrake.airCompressor.LoopSound, center, SoundCfgParser.mediumRadius);
                                        break;

                                    case "release":
                                    case "stop":
                                    case "end":
                                        //Compressor end sound
                                        ParseNode(cc, out car.CarBrake.airCompressor.EndSound, center, SoundCfgParser.mediumRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "door":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of door sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "openleft":
                                    case "leftopen":
                                        ParseNode(cc, out car.Doors[0].OpenSound, left, SoundCfgParser.smallRadius);
                                        break;

                                    case "openright":
                                    case "rightopen":
                                        ParseNode(cc, out car.Doors[1].OpenSound, right, SoundCfgParser.smallRadius);
                                        break;

                                    case "closeleft":
                                    case "leftclose":
                                        ParseNode(cc, out car.Doors[0].CloseSound, left, SoundCfgParser.smallRadius);
                                        break;

                                    case "closeright":
                                    case "rightclose":
                                        ParseNode(cc, out car.Doors[1].CloseSound, right, SoundCfgParser.smallRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "flange":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of flange sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                ParseArrayNode(c, out car.Sounds.Flange, center, SoundCfgParser.mediumRadius);
                                break;

                            case "horn":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of horn sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "primary":
                                        //Primary horn
                                        ParseHornNode(cc, out car.Horns[0], front, SoundCfgParser.largeRadius);
                                        break;

                                    case "secondary":
                                        //Secondary horn
                                        ParseHornNode(cc, out car.Horns[1], front, SoundCfgParser.largeRadius);
                                        break;

                                    case "music":
                                        //Music horn
                                        ParseHornNode(cc, out car.Horns[2], front, SoundCfgParser.largeRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "loop":
                            case "noise":
                                ParseNode(c, out car.Sounds.Loop, center, SoundCfgParser.mediumRadius);
                                break;

                            case "mastercontroller":
                            case "powerhandle":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of power handle sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "up":
                                    case "increase":
                                        ParseNode(cc, out Train.Handles.Power.Increase, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "upfast":
                                    case "increasefast":
                                        ParseNode(cc, out Train.Handles.Power.IncreaseFast, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "down":
                                    case "decrease":
                                        ParseNode(cc, out Train.Handles.Power.Decrease, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "downfast":
                                    case "decreasefast":
                                        ParseNode(cc, out Train.Handles.Power.DecreaseFast, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "min":
                                    case "minimum":
                                        ParseNode(cc, out Train.Handles.Power.Min, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "max":
                                    case "maximum":
                                        ParseNode(cc, out Train.Handles.Power.Max, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "motor":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, string.Format("An empty list of motor sounds was defined in in XML file {0}", fileName));
                                    break;
                                }
                                if (!car.Specs.IsMotorCar)
                                {
                                    break;
                                }
                                ParseMotorSoundTableNode(c, ref car.Sounds.Motor.Tables, center, SoundCfgParser.mediumRadius);
                                break;

                            case "pilotlamp":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of pilot-lamp sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "on":
                                        ParseNode(cc, out Train.SafetySystems.PilotLamp.OnSound, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "off":
                                        ParseNode(cc, out Train.SafetySystems.PilotLamp.OffSound, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "pointfrontaxle":
                            case "switchfrontaxle":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of point front axle sounds was defined in in XML file " + fileName);
                                    break;
                                }

                                CarSound[] frontAxlePointSounds;
                                ParseArrayNode(c, out frontAxlePointSounds, new Vector3(0.0, 0.0, car.FrontAxle.Position), SoundCfgParser.smallRadius);
                                car.FrontAxle.PointSounds = frontAxlePointSounds;
                                break;

                            case "pointrearaxle":
                            case "switchrearaxle":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of point rear axle sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                CarSound[] rearAxlePointSounds;
                                ParseArrayNode(c, out rearAxlePointSounds, new Vector3(0.0, 0.0, car.FrontAxle.Position), SoundCfgParser.smallRadius);
                                car.RearAxle.PointSounds = rearAxlePointSounds;
                                break;

                            case "reverser":
                            case "reverserhandle":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of reverser sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "on":
                                        ParseNode(cc, out Train.Handles.Reverser.EngageSound, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    case "off":
                                        ParseNode(cc, out Train.Handles.Reverser.ReleaseSound, panel, SoundCfgParser.tinyRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "run":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of run sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                ParseArrayNode(c, out car.Sounds.Run, center, SoundCfgParser.mediumRadius);
                                break;

                            case "shoe":
                            case "rub":
                                ParseNode(c, out car.CarBrake.Rub, center, SoundCfgParser.mediumRadius);
                                break;

                            case "suspension":
                            case "spring":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of suspension sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "left":
                                        //Left suspension springs
                                        ParseNode(cc, out car.Sounds.SpringL, left, SoundCfgParser.smallRadius);
                                        break;

                                    case "right":
                                        //right suspension springs
                                        ParseNode(cc, out car.Sounds.SpringR, right, SoundCfgParser.smallRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "requeststop":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of request stop sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "stop":
                                        ParseNode(cc, out car.Sounds.RequestStop[0], center, SoundCfgParser.smallRadius);
                                        break;

                                    case "pass":
                                        ParseNode(cc, out car.Sounds.RequestStop[1], center, SoundCfgParser.smallRadius);
                                        break;

                                    case "ignored":
                                        ParseNode(cc, out car.Sounds.RequestStop[2], center, SoundCfgParser.smallRadius);
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, false, "Declaration " + cc.Name + " is unsupported in a " + c.Name + " node.");
                                        break;
                                    }
                                }
                                break;

                            case "touch":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false, "An empty list of touch sounds was defined in in XML file " + fileName);
                                    break;
                                }
                                if (!isDriverCar)
                                {
                                    break;
                                }
                                ParseArrayNode(c, out car.Sounds.Touch, center, SoundCfgParser.mediumRadius);
                                break;
                            }
                        }
                    }
                }
                car.Sounds.RunVolume    = new double[car.Sounds.Run.Length];
                car.Sounds.FlangeVolume = new double[car.Sounds.Flange.Length];
            }
        }
Example #25
0
 internal override void Trigger(int Direction, EventTriggerType TriggerType, TrainManager.Train Train, int CarIndex)
 {
     if (Train == TrainManager.PlayerTrain & TriggerType == EventTriggerType.FrontCarFrontAxle)
     {
         if (this.Message != null)
         {
             if (Direction < 0)
             {
                 if (this.Message.Trains != null && !this.Message.Trains.Contains(new System.IO.DirectoryInfo(Game.RouteInformation.TrainFolder).Name))
                 {
                     //Our train is NOT in the list of trains which this message triggers for
                     return;
                 }
                 MessageManager.AddMessage(this.Message);
             }
             else if (Direction > 0)
             {
                 this.Message.QueueForRemoval = true;
             }
         }
     }
 }