Пример #1
0
        /// <summary>Loads a list of compatibility signal objects</summary>
        /// <param name="currentHost">The host application interface</param>
        /// <param name="fileName">The file name of the object list</param>
        /// <param name="objects">The returned array of speed limits</param>
        /// <param name="signalPost">Sets the default signal post</param>
        /// <param name="speedLimits">The array of signal speed limits</param>
        /// <returns>An array of compatability signal objects</returns>
        public static void ReadCompatibilitySignalXML(HostInterface currentHost, string fileName, out CompatibilitySignalObject[] objects, out UnifiedObject signalPost, out double[] speedLimits)
        {
            signalPost = new StaticObject(currentHost);
            objects    = new CompatibilitySignalObject[9];
            //Default Japanese speed limits converted to m/s
            speedLimits = new[] { 0.0, 6.94444444444444, 15.2777777777778, 20.8333333333333, double.PositiveInfinity, double.PositiveInfinity };
            XmlDocument currentXML = new XmlDocument();

            currentXML.Load(fileName);
            string currentPath = System.IO.Path.GetDirectoryName(fileName);

            if (currentXML.DocumentElement != null)
            {
                XmlNode node = currentXML.SelectSingleNode("/openBVE/CompatibilitySignals/SignalSetName");
                if (node != null)
                {
                    currentHost.AddMessage(MessageType.Information, false, "INFO: Using the " + node.InnerText + " compatibility signal set.");
                }
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CompatibilitySignals/Signal");
                if (DocumentNodes != null)
                {
                    int index = 0;
                    foreach (XmlNode nn in DocumentNodes)
                    {
                        List <StaticObject> objectList = new List <StaticObject>();
                        List <int>          aspectList = new List <int>();
                        try
                        {
                            if (nn.HasChildNodes)
                            {
                                foreach (XmlNode n in nn.ChildNodes)
                                {
                                    if (n.Name != "Aspect")
                                    {
                                        continue;
                                    }

                                    int aspect = 0;
                                    if (!NumberFormats.TryParseIntVb6(n.Attributes["Number"].Value, out aspect))
                                    {
                                        currentHost.AddMessage(MessageType.Error, true, "Invalid aspect number " + aspect + " in the signal object list in the compatability signal file " + fileName);
                                        continue;
                                    }

                                    aspectList.Add(aspect);

                                    StaticObject staticObject = new StaticObject(currentHost);
                                    if (n.InnerText.ToLowerInvariant() != "null")
                                    {
                                        string objectFile = Path.CombineFile(currentPath, n.InnerText);
                                        if (File.Exists(objectFile))
                                        {
                                            currentHost.LoadStaticObject(objectFile, Encoding.UTF8, false, out staticObject);
                                        }
                                        else
                                        {
                                            currentHost.AddMessage(MessageType.Error, true, "Compatibility signal file " + objectFile + " not found in " + fileName);
                                        }
                                    }
                                    objectList.Add(staticObject);
                                }
                            }
                        }
                        catch
                        {
                            currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName);
                        }
                        objects[index] = new CompatibilitySignalObject(aspectList.ToArray(), objectList.ToArray());
                        index++;
                    }
                }

                string signalPostFile = Path.CombineFile(currentPath, "Japanese\\signal_post.csv");                 //default plain post
                try
                {
                    node = currentXML.SelectSingleNode("/openBVE/CompatibilitySignals/SignalPost");
                    if (node != null)
                    {
                        string newFile = Path.CombineFile(currentPath, node.InnerText);
                        if (System.IO.File.Exists(newFile))
                        {
                            signalPostFile = newFile;
                        }
                    }
                    currentHost.LoadObject(signalPostFile, Encoding.UTF8, out signalPost);
                }
                catch
                {
                    currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName);
                }

                DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CompatibilitySignals/SpeedLimits");
                if (DocumentNodes != null)
                {
                    foreach (XmlNode nn in DocumentNodes)
                    {
                        try
                        {
                            if (nn.HasChildNodes)
                            {
                                foreach (XmlNode n in nn.ChildNodes)
                                {
                                    if (n.Name != "Aspect")
                                    {
                                        continue;
                                    }

                                    int aspect = 0;
                                    if (n.Attributes != null)
                                    {
                                        if (!NumberFormats.TryParseIntVb6(n.Attributes["Number"].Value, out aspect))
                                        {
                                            currentHost.AddMessage(MessageType.Error, true, "Invalid aspect number " + aspect + " in the speed limit list in the compatability signal file " + fileName);
                                            continue;
                                        }
                                    }

                                    if (aspect <= speedLimits.Length)
                                    {
                                        int l = speedLimits.Length;
                                        Array.Resize(ref speedLimits, aspect + 1);
                                        for (int i = l; i < speedLimits.Length; i++)
                                        {
                                            speedLimits[i] = double.PositiveInfinity;
                                        }

                                        if (!NumberFormats.TryParseDoubleVb6(n.InnerText, out speedLimits[aspect]))
                                        {
                                            speedLimits[aspect] = double.MaxValue;
                                            if (n.InnerText.ToLowerInvariant() != "unlimited")
                                            {
                                                currentHost.AddMessage(MessageType.Error, true, "Invalid speed limit provided for aspect " + aspect + " in the compatability signal file " + fileName);
                                            }
                                        }
                                        else
                                        {
                                            //convert to m/s as that's what we use internally
                                            speedLimits[aspect] *= 0.277777777777778;
                                        }
                                    }
                                }
                            }
                        }
                        catch
                        {
                            currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName);
                        }
                    }
                }
            }
        }
Пример #2
0
        public override bool LoadTrain(Encoding Encoding, string trainPath, ref AbstractTrain train, ref Control[] currentControls)
        {
            CurrentControls = currentControls;
            TrainBase currentTrain = train as TrainBase;

            if (currentTrain == null)
            {
                currentHost.ReportProblem(ProblemType.InvalidData, "Train was not valid");
                return(false);
            }

            if (currentTrain.State == TrainState.Bogus)
            {
                // bogus train
                string TrainData = Path.CombineFile(FileSystem.GetDataFolder("Compatibility", "PreTrain"), "train.dat");
                TrainDatParser.Parse(TrainData, Encoding.UTF8, currentTrain);
                Thread.Sleep(1);
                if (Cancel)
                {
                    return(false);
                }
            }
            else
            {
                currentTrain.TrainFolder = trainPath;
                // real train
                if (currentTrain.IsPlayerTrain)
                {
                    FileSystem.AppendToLogFile("Loading player train: " + currentTrain.TrainFolder);
                }
                else
                {
                    FileSystem.AppendToLogFile("Loading AI train: " + currentTrain.TrainFolder);
                }

                string TrainData = Path.CombineFile(currentTrain.TrainFolder, "train.dat");
                TrainDatParser.Parse(TrainData, Encoding, currentTrain);
                Thread.Sleep(1);
                if (Cancel)
                {
                    return(false);
                }
                SoundCfgParser.ParseSoundConfig(currentTrain);
                Thread.Sleep(1);
                if (Cancel)
                {
                    return(false);
                }
                // door open/close speed
                for (int i = 0; i < currentTrain.Cars.Length; i++)
                {
                    currentTrain.Cars[i].DetermineDoorClosingSpeed();
                }
            }
            // add panel section
            if (currentTrain.IsPlayerTrain)
            {
                ParsePanelConfig(currentTrain, Encoding);
                Thread.Sleep(1); if (Cancel)
                {
                    return(false);
                }
                FileSystem.AppendToLogFile("Train panel loaded sucessfully.");
            }
            // add exterior section
            if (currentTrain.State != TrainState.Bogus)
            {
                bool[]          VisibleFromInterior = new bool[currentTrain.Cars.Length];
                UnifiedObject[] CarObjects          = new UnifiedObject[currentTrain.Cars.Length];
                UnifiedObject[] BogieObjects        = new UnifiedObject[currentTrain.Cars.Length * 2];
                UnifiedObject[] CouplerObjects      = new UnifiedObject[currentTrain.Cars.Length];

                string tXml = Path.CombineFile(currentTrain.TrainFolder, "train.xml");
                if (File.Exists(tXml))
                {
                    TrainXmlParser.Parse(tXml, currentTrain, ref CarObjects, ref BogieObjects, ref CouplerObjects, ref VisibleFromInterior);
                }
                else
                {
                    ExtensionsCfgParser.ParseExtensionsConfig(currentTrain.TrainFolder, Encoding, ref CarObjects, ref BogieObjects, ref CouplerObjects, ref VisibleFromInterior, currentTrain);
                }

                currentTrain.CameraCar = currentTrain.DriverCar;
                Thread.Sleep(1);
                if (Cancel)
                {
                    return(false);
                }
                //Stores the current array index of the bogie object to add
                //Required as there are two bogies per car, and we're using a simple linear array....
                int currentBogieObject = 0;
                for (int i = 0; i < currentTrain.Cars.Length; i++)
                {
                    if (CarObjects[i] == null)
                    {
                        // load default exterior object
                        string       file = Path.CombineFile(FileSystem.GetDataFolder("Compatibility"), "exterior.csv");
                        StaticObject so;
                        currentHost.LoadStaticObject(file, Encoding.UTF8, false, out so);
                        if (so == null)
                        {
                            CarObjects[i] = null;
                        }
                        else
                        {
                            StaticObject c = (StaticObject)so.Clone();                              //Clone as otherwise the cached object doesn't scale right
                            c.ApplyScale(currentTrain.Cars[i].Width, currentTrain.Cars[i].Height, currentTrain.Cars[i].Length);
                            CarObjects[i] = c;
                        }
                    }

                    if (CarObjects[i] != null)
                    {
                        // add object
                        currentTrain.Cars[i].LoadCarSections(CarObjects[i], VisibleFromInterior[i]);
                    }

                    if (CouplerObjects[i] != null)
                    {
                        currentTrain.Cars[i].Coupler.LoadCarSections(CouplerObjects[i], VisibleFromInterior[i]);
                    }

                    //Load bogie objects
                    if (BogieObjects[currentBogieObject] != null)
                    {
                        currentTrain.Cars[i].FrontBogie.LoadCarSections(BogieObjects[currentBogieObject], VisibleFromInterior[i]);
                    }

                    currentBogieObject++;
                    if (BogieObjects[currentBogieObject] != null)
                    {
                        currentTrain.Cars[i].RearBogie.LoadCarSections(BogieObjects[currentBogieObject], VisibleFromInterior[i]);
                    }

                    currentBogieObject++;
                }
            }
            // place cars
            currentTrain.PlaceCars(0.0);
            currentControls = CurrentControls;
            return(true);
        }