Ejemplo n.º 1
0
        private void ParsePanelAnimatedNode(XElement Element, string FileName, string TrainPath, TrainBase Train, int Car, CarSection CarSection, int GroupIndex)
        {
            System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;

            int    currentSectionElement   = 0;
            int    numberOfSectionElements = Element.Elements().Count();
            double invfac = numberOfSectionElements == 0 ? 1.0 : 1.0 / (double)numberOfSectionElements;

            foreach (XElement SectionElement in Element.Elements())
            {
                Plugin.CurrentProgress = Plugin.CurrentProgress + invfac * (double)currentSectionElement;
                if ((currentSectionElement & 4) == 0)
                {
                    System.Threading.Thread.Sleep(1);
                    if (Plugin.Cancel)
                    {
                        return;
                    }
                }

                string Section = SectionElement.Name.LocalName;

                switch (SectionElement.Name.LocalName.ToLowerInvariant())
                {
                case "group":
                    if (GroupIndex == 0)
                    {
                        int n = 0;

                        foreach (XElement KeyNode in SectionElement.Elements())
                        {
                            string Key        = KeyNode.Name.LocalName;
                            string Value      = KeyNode.Value;
                            int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                            switch (Key.ToLowerInvariant())
                            {
                            case "number":
                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out n))
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;
                            }
                        }

                        if (n + 1 >= CarSection.Groups.Length)
                        {
                            Array.Resize(ref CarSection.Groups, n + 2);
                            CarSection.Groups[n + 1] = new ElementsGroup(ObjectType.Overlay);
                        }

                        ParsePanelAnimatedNode(SectionElement, FileName, TrainPath, Train, Car, CarSection, n + 1);
                    }
                    break;

                case "touch":
                    if (GroupIndex > 0)
                    {
                        Vector3             Position       = Vector3.Zero;
                        Vector3             Size           = Vector3.Zero;
                        int                 JumpScreen     = GroupIndex - 1;
                        List <int>          SoundIndices   = new List <int>();
                        List <CommandEntry> CommandEntries = new List <CommandEntry>();
                        CommandEntry        CommandEntry   = new CommandEntry();

                        foreach (XElement KeyNode in SectionElement.Elements())
                        {
                            string Key        = KeyNode.Name.LocalName;
                            string Value      = KeyNode.Value;
                            int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                            switch (Key.ToLowerInvariant())
                            {
                            case "position":
                                if (!Vector3.TryParse(KeyNode.Value, ',', out Position))
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, "Position is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;

                            case "size":
                                if (!Vector3.TryParse(KeyNode.Value, ',', out Size))
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, "Size is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;

                            case "jumpscreen":
                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out JumpScreen))
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;

                            case "soundindex":
                                if (Value.Length != 0)
                                {
                                    int SoundIndex;

                                    if (!NumberFormats.TryParseIntVb6(Value, out SoundIndex))
                                    {
                                        Plugin.currentHost.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                    }

                                    SoundIndices.Add(SoundIndex);
                                }
                                break;

                            case "command":
                            {
                                if (!CommandEntries.Contains(CommandEntry))
                                {
                                    CommandEntries.Add(CommandEntry);
                                }

                                if (string.Compare(Value, "N/A", StringComparison.InvariantCultureIgnoreCase) == 0)
                                {
                                    break;
                                }

                                int i;
                                for (i = 0; i < Translations.CommandInfos.Length; i++)
                                {
                                    if (string.Compare(Value, Translations.CommandInfos[i].Name, StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        break;
                                    }
                                }
                                if (i == Translations.CommandInfos.Length || Translations.CommandInfos[i].Type != Translations.CommandType.Digital)
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                else
                                {
                                    CommandEntry.Command = Translations.CommandInfos[i].Command;
                                }
                            }
                            break;

                            case "commandoption":
                                if (!CommandEntries.Contains(CommandEntry))
                                {
                                    CommandEntries.Add(CommandEntry);
                                }

                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out CommandEntry.Option))
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;

                            case "soundentries":
                                if (!KeyNode.HasElements)
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, $"An empty list of touch sound indices was defined at line {((IXmlLineInfo)KeyNode).LineNumber} in XML file {FileName}");
                                    break;
                                }

                                ParseTouchSoundEntryNode(FileName, KeyNode, SoundIndices);
                                break;

                            case "commandentries":
                                if (!KeyNode.HasElements)
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, $"An empty list of touch commands was defined at line {((IXmlLineInfo)KeyNode).LineNumber} in XML file {FileName}");
                                    break;
                                }

                                ParseTouchCommandEntryNode(FileName, KeyNode, CommandEntries);
                                break;
                            }
                        }
                        CreateTouchElement(CarSection.Groups[GroupIndex], Position, Size, JumpScreen, SoundIndices.ToArray(), CommandEntries.ToArray());
                    }
                    break;

                case "include":
                {
                    foreach (XElement KeyNode in SectionElement.Elements())
                    {
                        string Key        = KeyNode.Name.LocalName;
                        string Value      = KeyNode.Value;
                        int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                        switch (Key.ToLowerInvariant())
                        {
                        case "filename":
                        {
                            string File = OpenBveApi.Path.CombineFile(TrainPath, Value);
                            if (System.IO.File.Exists(File))
                            {
                                System.Text.Encoding e = TextEncoding.GetSystemEncodingFromFile(File);
                                UnifiedObject        currentObject;
                                Plugin.currentHost.LoadObject(File, e, out currentObject);
                                var a = currentObject as AnimatedObjectCollection;
                                if (a != null)
                                {
                                    for (int i = 0; i < a.Objects.Length; i++)
                                    {
                                        Plugin.currentHost.CreateDynamicObject(ref a.Objects[i].internalObject);
                                    }
                                    CarSection.Groups[GroupIndex].Elements = a.Objects;
                                }
                                else
                                {
                                    Plugin.currentHost.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                            }
                        }
                        break;
                        }
                    }
                }
                break;
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>Parses a base track following object node</summary>
        /// <param name="Element">The XElement to parse</param>
        /// <param name="FileName">The filename of the containing XML file</param>
        /// <param name="Path">The path of the containing XML file</param>
        /// <param name="Train">The track following object to parse this node into</param>
        private static void ParseTrackFollowingObjectNode(XElement Element, string FileName, string Path, string ObjectPath, TrainManager.TrackFollowingObject Train)
        {
            System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;
            string TrainDirectory       = string.Empty;
            bool   consistReversed      = false;
            List <Game.TravelData> Data = new List <Game.TravelData>();

            foreach (XElement SectionElement in Element.Elements())
            {
                string Section = SectionElement.Name.LocalName;

                switch (SectionElement.Name.LocalName.ToLowerInvariant())
                {
                case "stops":
                    ParseStopNode(SectionElement, FileName, Data);
                    break;

                case "train":
                    foreach (XElement KeyNode in SectionElement.Elements())
                    {
                        string Key        = KeyNode.Name.LocalName;
                        string Value      = KeyNode.Value;
                        int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                        switch (Key.ToLowerInvariant())
                        {
                        case "directory":
                        {
                            string trainDirectory = OpenBveApi.Path.CombineDirectory(Path, Value);
                            if (!System.IO.Directory.Exists(trainDirectory))
                            {
                                trainDirectory = OpenBveApi.Path.CombineFile(Program.FileSystem.InitialTrainFolder, Value);
                            }
                            if (!System.IO.Directory.Exists(trainDirectory))
                            {
                                trainDirectory = OpenBveApi.Path.CombineFile(Program.FileSystem.TrainInstallationDirectory, Value);
                            }
                            if (!System.IO.Directory.Exists(trainDirectory))
                            {
                                trainDirectory = OpenBveApi.Path.CombineFile(ObjectPath, Value);
                            }

                            if (!System.IO.Directory.Exists(trainDirectory))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Directory was not found in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            else
                            {
                                TrainDirectory = trainDirectory;
                            }
                        }
                        break;

                        case "reversed":
                            int n;
                            NumberFormats.TryParseIntVb6(Value, out n);
                            if (n == 1 || Value.ToLowerInvariant() == "true")
                            {
                                consistReversed = true;
                            }
                            break;
                        }
                    }
                    break;

                case "definition":
                    foreach (XElement KeyNode in SectionElement.Elements())
                    {
                        string Key        = KeyNode.Name.LocalName;
                        string Value      = KeyNode.Value;
                        int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                        switch (Key.ToLowerInvariant())
                        {
                        case "appearancetime":
                            if (Value.Length != 0 && !Interface.TryParseTime(Value, out Train.AppearanceTime))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;

                        case "appearancestartposition":
                            if (Value.Length != 0 && !NumberFormats.TryParseDoubleVb6(Value, out Train.AppearanceStartPosition))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;

                        case "appearanceendposition":
                            if (Value.Length != 0 && !NumberFormats.TryParseDoubleVb6(Value, out Train.AppearanceEndPosition))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;

                        case "leavetime":
                            if (Value.Length != 0 && !Interface.TryParseTime(Value, out Train.LeaveTime))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;
                        }
                    }
                    break;
                }
            }

            if (!Data.Any() || string.IsNullOrEmpty(TrainDirectory))
            {
                return;
            }

            /*
             * First check for a train.ai file- Functionally identical, but allows for differently configured AI
             * trains not to show up as driveable
             */
            string TrainData = OpenBveApi.Path.CombineFile(TrainDirectory, "train.ai");

            if (!System.IO.File.Exists(TrainData))
            {
                // Check for the standard driveable train.dat
                TrainData = OpenBveApi.Path.CombineFile(TrainDirectory, "train.dat");
            }
            string ExteriorFile = OpenBveApi.Path.CombineFile(TrainDirectory, "extensions.cfg");

            if (!System.IO.File.Exists(TrainData) || !System.IO.File.Exists(ExteriorFile))
            {
                Interface.AddMessage(MessageType.Error, true, "The supplied train folder in TrackFollowingObject " + FileName + " did not contain a complete set of data.");
                return;
            }
            TrainDatParser.ParseTrainData(TrainData, TextEncoding.GetSystemEncodingFromFile(TrainData), Train);
            SoundCfgParser.ParseSoundConfig(TrainDirectory, Train);
            Train.AI = new Game.TrackFollowingObjectAI(Train, Data);

            UnifiedObject[] CarObjects     = new UnifiedObject[Train.Cars.Length];
            UnifiedObject[] BogieObjects   = new UnifiedObject[Train.Cars.Length * 2];
            UnifiedObject[] CouplerObjects = new UnifiedObject[Train.Cars.Length - 1];
            ExtensionsCfgParser.ParseExtensionsConfig(System.IO.Path.GetDirectoryName(ExteriorFile), TextEncoding.GetSystemEncodingFromFile(ExteriorFile), ref CarObjects, ref BogieObjects, ref CouplerObjects, Train, true);

            int currentBogieObject = 0;

            for (int i = 0; i < Train.Cars.Length; i++)
            {
                if (CarObjects[i] == null)
                {
                    // load default exterior object
                    string       file = OpenBveApi.Path.CombineFile(Program.FileSystem.GetDataFolder("Compatibility"), "exterior.csv");
                    StaticObject so   = ObjectManager.LoadStaticObject(file, System.Text.Encoding.UTF8, false);
                    if (so == null)
                    {
                        CarObjects[i] = null;
                    }
                    else
                    {
                        double sx = Train.Cars[i].Width;
                        double sy = Train.Cars[i].Height;
                        double sz = Train.Cars[i].Length;
                        so.ApplyScale(sx, sy, sz);
                        CarObjects[i] = so;
                    }
                }
                if (CarObjects[i] != null)
                {
                    // add object
                    Train.Cars[i].LoadCarSections(CarObjects[i]);
                }

                //Load bogie objects
                if (BogieObjects[currentBogieObject] != null)
                {
                    Train.Cars[i].FrontBogie.LoadCarSections(BogieObjects[currentBogieObject]);
                }
                currentBogieObject++;
                if (BogieObjects[currentBogieObject] != null)
                {
                    Train.Cars[i].RearBogie.LoadCarSections(BogieObjects[currentBogieObject]);
                }
                currentBogieObject++;
            }

            // door open/close speed
            foreach (var Car in Train.Cars)
            {
                if (Car.Specs.DoorOpenFrequency <= 0.0)
                {
                    if (Car.Doors[0].OpenSound.Buffer != null & Car.Doors[1].OpenSound.Buffer != null)
                    {
                        Program.Sounds.LoadBuffer(Car.Doors[0].OpenSound.Buffer);
                        Program.Sounds.LoadBuffer(Car.Doors[1].OpenSound.Buffer);
                        double a = Car.Doors[0].OpenSound.Buffer.Duration;
                        double b = Car.Doors[1].OpenSound.Buffer.Duration;
                        Car.Specs.DoorOpenFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8;
                    }
                    else if (Car.Doors[0].OpenSound.Buffer != null)
                    {
                        Program.Sounds.LoadBuffer(Car.Doors[0].OpenSound.Buffer);
                        double a = Car.Doors[0].OpenSound.Buffer.Duration;
                        Car.Specs.DoorOpenFrequency = a > 0.0 ? 1.0 / a : 0.8;
                    }
                    else if (Car.Doors[1].OpenSound.Buffer != null)
                    {
                        Program.Sounds.LoadBuffer(Car.Doors[0].OpenSound.Buffer);
                        double b = Car.Doors[1].OpenSound.Buffer.Duration;
                        Car.Specs.DoorOpenFrequency = b > 0.0 ? 1.0 / b : 0.8;
                    }
                    else
                    {
                        Car.Specs.DoorOpenFrequency = 0.8;
                    }
                }
                if (Car.Specs.DoorCloseFrequency <= 0.0)
                {
                    if (Car.Doors[0].CloseSound.Buffer != null & Car.Doors[1].CloseSound.Buffer != null)
                    {
                        Program.Sounds.LoadBuffer(Car.Doors[0].CloseSound.Buffer);
                        Program.Sounds.LoadBuffer(Car.Doors[1].CloseSound.Buffer);
                        double a = Car.Doors[0].CloseSound.Buffer.Duration;
                        double b = Car.Doors[1].CloseSound.Buffer.Duration;
                        Car.Specs.DoorCloseFrequency = a + b > 0.0 ? 2.0 / (a + b) : 0.8;
                    }
                    else if (Car.Doors[0].CloseSound.Buffer != null)
                    {
                        Program.Sounds.LoadBuffer(Car.Doors[0].CloseSound.Buffer);
                        double a = Car.Doors[0].CloseSound.Buffer.Duration;
                        Car.Specs.DoorCloseFrequency = a > 0.0 ? 1.0 / a : 0.8;
                    }
                    else if (Car.Doors[1].CloseSound.Buffer != null)
                    {
                        Program.Sounds.LoadBuffer(Car.Doors[0].CloseSound.Buffer);
                        double b = Car.Doors[1].CloseSound.Buffer.Duration;
                        Car.Specs.DoorCloseFrequency = b > 0.0 ? 1.0 / b : 0.8;
                    }
                    else
                    {
                        Car.Specs.DoorCloseFrequency = 0.8;
                    }
                }
                const double f = 0.015;
                const double g = 2.75;
                Car.Specs.DoorOpenPitch       = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5)));
                Car.Specs.DoorClosePitch      = Math.Exp(f * Math.Tan(g * (Program.RandomNumberGenerator.NextDouble() - 0.5)));
                Car.Specs.DoorOpenFrequency  /= Car.Specs.DoorOpenPitch;
                Car.Specs.DoorCloseFrequency /= Car.Specs.DoorClosePitch;

                /*
                 * Remove the following two lines, then the pitch at which doors play
                 * takes their randomized opening and closing times into account.
                 * */
                Car.Specs.DoorOpenPitch  = 1.0;
                Car.Specs.DoorClosePitch = 1.0;
            }

            foreach (var Car in Train.Cars)
            {
                Car.FrontAxle.Follower.TrackIndex            = Data[0].RailIndex;
                Car.RearAxle.Follower.TrackIndex             = Data[0].RailIndex;
                Car.FrontBogie.FrontAxle.Follower.TrackIndex = Data[0].RailIndex;
                Car.FrontBogie.RearAxle.Follower.TrackIndex  = Data[0].RailIndex;
                Car.RearBogie.FrontAxle.Follower.TrackIndex  = Data[0].RailIndex;
                Car.RearBogie.RearAxle.Follower.TrackIndex   = Data[0].RailIndex;
            }

            if (consistReversed)
            {
                Train.Reverse();
            }
            Train.PlaceCars(Data[0].StopPosition);
        }
Ejemplo n.º 3
0
        private static void ParsePanelAnimatedNode(XElement Element, string FileName, string TrainPath, TrainManager.Train Train, int Car, TrainManager.CarSection CarSection, int GroupIndex)
        {
            System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;

            int    currentSectionElement   = 0;
            int    numberOfSectionElements = Element.Elements().Count();
            double invfac = numberOfSectionElements == 0 ? Loading.TrainProgressCurrentWeight : Loading.TrainProgressCurrentWeight / (double)numberOfSectionElements;

            foreach (XElement SectionElement in Element.Elements())
            {
                Loading.TrainProgress = Loading.TrainProgressCurrentSum + invfac * (double)currentSectionElement;
                if ((currentSectionElement & 4) == 0)
                {
                    System.Threading.Thread.Sleep(1);
                    if (Loading.Cancel)
                    {
                        return;
                    }
                }

                string Section = SectionElement.Name.LocalName;

                switch (SectionElement.Name.LocalName.ToLowerInvariant())
                {
                case "group":
                    if (GroupIndex == 0)
                    {
                        int n = 0;

                        foreach (XElement KeyNode in SectionElement.Elements())
                        {
                            string Key        = KeyNode.Name.LocalName;
                            string Value      = KeyNode.Value;
                            int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                            switch (Key.ToLowerInvariant())
                            {
                            case "number":
                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out n))
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;
                            }
                        }

                        if (n + 1 >= CarSection.Groups.Length)
                        {
                            Array.Resize(ref CarSection.Groups, n + 2);
                            CarSection.Groups[n + 1] = new TrainManager.ElementsGroup
                            {
                                Elements = new ObjectManager.AnimatedObject[] { },
                                Overlay  = true
                            };
                        }

                        ParsePanelAnimatedNode(SectionElement, FileName, TrainPath, Train, Car, CarSection, n + 1);
                    }
                    break;

                case "touch":
                    if (GroupIndex > 0)
                    {
                        Vector3 Position             = Vector3.Zero;
                        Vector3 Size                 = Vector3.Zero;
                        int     JumpScreen           = GroupIndex - 1;
                        int     SoundIndex           = -1;
                        Translations.Command Command = Translations.Command.None;
                        int CommandOption            = 0;

                        foreach (XElement KeyNode in SectionElement.Elements())
                        {
                            string Key        = KeyNode.Name.LocalName;
                            string Value      = KeyNode.Value;
                            int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                            switch (Key.ToLowerInvariant())
                            {
                            case "position":
                            {
                                string[] s = Value.Split(',');
                                if (s.Length == 3)
                                {
                                    if (s[0].Length != 0 && !NumberFormats.TryParseDoubleVb6(s[0], out Position.X))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "X is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                    }
                                    if (s[1].Length != 0 && !NumberFormats.TryParseDoubleVb6(s[1], out Position.Y))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "Y is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                    }
                                    if (s[2].Length != 0 && !NumberFormats.TryParseDoubleVb6(s[2], out Position.Z))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "Z is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                    }
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Three arguments are expected in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                            }
                            break;

                            case "size":
                            {
                                string[] s = Value.Split(',');
                                if (s.Length == 3)
                                {
                                    if (s[0].Length != 0 && !NumberFormats.TryParseDoubleVb6(s[0], out Size.X))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "X is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                    }
                                    if (s[1].Length != 0 && !NumberFormats.TryParseDoubleVb6(s[1], out Size.Y))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "Y is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                    }
                                    if (s[2].Length != 0 && !NumberFormats.TryParseDoubleVb6(s[2], out Size.Z))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "Z is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                    }
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Three arguments are expected in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                            }
                            break;

                            case "jumpscreen":
                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out JumpScreen))
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;

                            case "soundindex":
                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out SoundIndex))
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;

                            case "command":
                            {
                                int i;
                                for (i = 0; i < Translations.CommandInfos.Length; i++)
                                {
                                    if (string.Compare(Value, Translations.CommandInfos[i].Name, StringComparison.OrdinalIgnoreCase) == 0)
                                    {
                                        break;
                                    }
                                }
                                if (i == Translations.CommandInfos.Length || Translations.CommandInfos[i].Type != Translations.CommandType.Digital)
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                else
                                {
                                    Command = Translations.CommandInfos[i].Command;
                                }
                            }
                            break;

                            case "commandoption":
                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out CommandOption))
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;
                            }
                        }
                        CreateTouchElement(CarSection.Groups[GroupIndex], Position, Size, JumpScreen, SoundIndex, Command, CommandOption);
                    }
                    break;

                case "include":
                {
                    foreach (XElement KeyNode in SectionElement.Elements())
                    {
                        string Key        = KeyNode.Name.LocalName;
                        string Value      = KeyNode.Value;
                        int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                        switch (Key.ToLowerInvariant())
                        {
                        case "filename":
                        {
                            string File = OpenBveApi.Path.CombineFile(TrainPath, Value);
                            if (System.IO.File.Exists(File))
                            {
                                System.Text.Encoding e = TextEncoding.GetSystemEncodingFromFile(File);
                                ObjectManager.AnimatedObjectCollection a = AnimatedObjectParser.ReadObject(File, e);
                                if (a != null)
                                {
                                    for (int i = 0; i < a.Objects.Length; i++)
                                    {
                                        a.Objects[i].ObjectIndex = ObjectManager.CreateDynamicObject();
                                    }
                                    CarSection.Groups[GroupIndex].Elements = a.Objects;
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                            }
                        }
                        break;
                        }
                    }
                }
                break;
                }
            }
        }
Ejemplo n.º 4
0
        /// <summary>Parses a train travel stop node</summary>
        /// <param name="Element">The XElement to parse</param>
        /// <param name="FileName">The filename of the containing XML file</param>
        /// <param name="Data">The list of travel data to add this to</param>
        private static void ParseStopNode(XElement Element, string FileName, List <Game.TravelData> Data)
        {
            System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture;

            foreach (XElement SectionElement in Element.Elements())
            {
                string Section = SectionElement.Name.LocalName;

                switch (SectionElement.Name.LocalName.ToLowerInvariant())
                {
                case "stop":
                {
                    Game.TravelData NewData     = new Game.TravelData();
                    double          Decelerate  = 0.0;
                    double          Accelerate  = 0.0;
                    double          TargetSpeed = 0.0;

                    foreach (XElement KeyNode in SectionElement.Elements())
                    {
                        string Key        = KeyNode.Name.LocalName;
                        string Value      = KeyNode.Value;
                        int    LineNumber = ((IXmlLineInfo)KeyNode).LineNumber;

                        switch (Key.ToLowerInvariant())
                        {
                        case "decelerate":
                            if (Value.Length != 0 && !NumberFormats.TryParseDoubleVb6(Value, out Decelerate))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;

                        case "stopposition":
                            if (Value.Length != 0 && !NumberFormats.TryParseDoubleVb6(Value, out NewData.StopPosition))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;

                        case "stoptime":
                            if (Value.Length != 0 && !Interface.TryParseTime(Value, out NewData.StopTime))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;

                        case "doors":
                        {
                            int  door     = 0;
                            bool doorboth = false;

                            switch (Value.ToLowerInvariant())
                            {
                            case "l":
                            case "left":
                                door = -1;
                                break;

                            case "r":
                            case "right":
                                door = 1;
                                break;

                            case "n":
                            case "none":
                            case "neither":
                                door = 0;
                                break;

                            case "b":
                            case "both":
                                doorboth = true;
                                break;

                            default:
                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out door))
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                    door = 0;
                                }
                                break;
                            }

                            NewData.OpenLeftDoors  = door < 0.0 | doorboth;
                            NewData.OpenRightDoors = door > 0.0 | doorboth;
                        }
                        break;

                        case "accelerate":
                            if (Value.Length != 0 && !NumberFormats.TryParseDoubleVb6(Value, out Accelerate))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;

                        case "targetspeed":
                            if (Value.Length != 0 && !NumberFormats.TryParseDoubleVb6(Value, out TargetSpeed))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;

                        case "direction":
                        {
                            int d = 0;
                            switch (Value.ToLowerInvariant())
                            {
                            case "f":
                                d = 1;
                                break;

                            case "r":
                                d = -1;
                                break;

                            default:
                                if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out d))
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                                }
                                break;
                            }
                            if (d == 1 || d == -1)
                            {
                                NewData.Direction = (Game.TravelDirection)d;
                            }
                        }
                        break;

                        case "rail":
                            if (Value.Length != 0 && !NumberFormats.TryParseIntVb6(Value, out NewData.RailIndex))
                            {
                                Interface.AddMessage(MessageType.Error, false, "Value is invalid in " + Key + " in " + Section + " at line " + LineNumber.ToString(Culture) + " in " + FileName);
                            }
                            break;
                        }
                    }

                    NewData.Decelerate  = Decelerate / 3.6;
                    NewData.Accelerate  = Accelerate / 3.6;
                    NewData.TargetSpeed = TargetSpeed / 3.6;
                    Data.Add(NewData);
                }
                break;
                }
            }
        }