Esempio n. 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);
                        }
                    }
                }
            }
        }
Esempio n. 2
0
        /// <summary>Attempts to load and parse the current train's panel configuration file.</summary>
        /// <param name="Train">The train</param>
        /// <param name="Encoding">The selected train encoding</param>
        internal void ParsePanelConfig(TrainBase Train, Encoding Encoding)
        {
            Train.Cars[Train.DriverCar].CarSections    = new CarSection[1];
            Train.Cars[Train.DriverCar].CarSections[0] = new CarSection(currentHost, ObjectType.Overlay, true);
            string File = Path.CombineFile(Train.TrainFolder, "panel.xml");

            if (!System.IO.File.Exists(File))
            {
                //Try animated variant too
                File = Path.CombineFile(Train.TrainFolder, "panel.animated.xml");
            }

            if (System.IO.File.Exists(File))
            {
                FileSystem.AppendToLogFile("Loading train panel: " + File);
                try
                {
                    /*
                     * First load the XML. We use this to determine
                     * whether this is a 2D or a 3D animated panel
                     */
                    XDocument CurrentXML = XDocument.Load(File, LoadOptions.SetLineInfo);

                    // Check for null
                    if (CurrentXML.Root != null)
                    {
                        IEnumerable <XElement> DocumentElements = CurrentXML.Root.Elements("PanelAnimated");
                        if (DocumentElements.Any())
                        {
                            PanelAnimatedXmlParser.ParsePanelAnimatedXml(System.IO.Path.GetFileName(File), Train, Train.DriverCar);
                            if (Train.Cars[Train.DriverCar].CameraRestrictionMode != CameraRestrictionMode.Restricted3D)
                            {
                                Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.NotAvailable;
                            }
                            return;
                        }

                        DocumentElements = CurrentXML.Root.Elements("Panel");
                        if (DocumentElements.Any())
                        {
                            PanelXmlParser.ParsePanelXml(System.IO.Path.GetFileName(File), Train, Train.DriverCar);
                            Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.On;
                            Renderer.Camera.CurrentRestriction = CameraRestrictionMode.On;
                            return;
                        }
                    }
                }
                catch
                {
                    var currentError = Translations.GetInterfaceString("errors_critical_file");
                    currentError = currentError.Replace("[file]", "panel.xml");
                    currentHost.ReportProblem(ProblemType.InvalidData, currentError);
                    Cancel = true;
                    return;
                }

                currentHost.AddMessage(MessageType.Error, false, "The panel.xml file " + File + " failed to load. Falling back to legacy panel.");
            }
            else
            {
                File = Path.CombineFile(Train.TrainFolder, "panel.animated");
                if (System.IO.File.Exists(File))
                {
                    FileSystem.AppendToLogFile("Loading train panel: " + File);
                    if (System.IO.File.Exists(Path.CombineFile(Train.TrainFolder, "panel2.cfg")) || System.IO.File.Exists(Path.CombineFile(Train.TrainFolder, "panel.cfg")))
                    {
                        FileSystem.AppendToLogFile("INFO: This train contains both a 2D and a 3D panel. The 3D panel will always take precedence");
                    }

                    UnifiedObject currentObject;
                    currentHost.LoadObject(File, Encoding, out currentObject);
                    var a = currentObject as AnimatedObjectCollection;
                    if (a != null)
                    {
                        //HACK: If a == null , loading our animated object completely failed (Missing objects?). Fallback to trying the panel2.cfg
                        try
                        {
                            for (int i = 0; i < a.Objects.Length; i++)
                            {
                                currentHost.CreateDynamicObject(ref a.Objects[i].internalObject);
                            }

                            Train.Cars[Train.DriverCar].CarSections[0].Groups[0].Elements = a.Objects;
                            if (Train.Cars[Train.DriverCar].CameraRestrictionMode != CameraRestrictionMode.Restricted3D)
                            {
                                Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.NotAvailable;
                                Renderer.Camera.CurrentRestriction = CameraRestrictionMode.NotAvailable;
                            }

                            return;
                        }
                        catch
                        {
                            var currentError = Translations.GetInterfaceString("errors_critical_file");
                            currentError = currentError.Replace("[file]", "panel.animated");
                            currentHost.ReportProblem(ProblemType.InvalidData, currentError);
                            Cancel = true;
                            return;
                        }
                    }

                    currentHost.AddMessage(MessageType.Error, false, "The panel.animated file " + File + " failed to load. Falling back to 2D panel.");
                }
            }

            var Panel2 = false;

            try
            {
                File = Path.CombineFile(Train.TrainFolder, "panel2.cfg");
                if (System.IO.File.Exists(File))
                {
                    FileSystem.AppendToLogFile("Loading train panel: " + File);
                    Panel2 = true;
                    Panel2CfgParser.ParsePanel2Config("panel2.cfg", Train.TrainFolder, Train.Cars[Train.DriverCar]);
                    Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.On;
                    Renderer.Camera.CurrentRestriction = CameraRestrictionMode.On;
                }
                else
                {
                    File = Path.CombineFile(Train.TrainFolder, "panel.cfg");
                    if (System.IO.File.Exists(File))
                    {
                        FileSystem.AppendToLogFile("Loading train panel: " + File);
                        PanelCfgParser.ParsePanelConfig(Train.TrainFolder, Encoding, Train.Cars[Train.DriverCar]);
                        Train.Cars[Train.DriverCar].CameraRestrictionMode = CameraRestrictionMode.On;
                        Renderer.Camera.CurrentRestriction = CameraRestrictionMode.On;
                    }
                    else
                    {
                        Renderer.Camera.CurrentRestriction = CameraRestrictionMode.NotAvailable;
                    }
                }
            }
            catch
            {
                var currentError = Translations.GetInterfaceString("errors_critical_file");
                currentError = currentError.Replace("[file]", Panel2 ? "panel2.cfg" : "panel.cfg");
                currentHost.ReportProblem(ProblemType.InvalidData, currentError);
                Cancel = true;
            }
        }