TryParseTime() static private method

static private TryParseTime ( string Expression, double &Value ) : bool
Expression string
Value double
return bool
示例#1
0
        /// <summary>Parses any command-line arguments passed to the main program</summary>
        /// <param name="Arguments">A string array of arguments</param>
        /// <param name="Result">The main dialog result (Used to launch)</param>
        internal static void ParseArguments(string[] Arguments, ref formMain.MainDialogResult Result)
        {
            if (Arguments.Length == 0)
            {
                return;
            }
            for (int i = 0; i < Arguments.Length; i++)
            {
                int equals = Arguments[i].IndexOf('=');
                if (equals >= 0)
                {
                    string key   = Arguments[i].Substring(0, equals).Trim(new char[] { }).ToLowerInvariant();
                    string value = Arguments[i].Substring(equals + 1).Trim(new char[] { });
                    switch (key)
                    {
                    case "/route":
                        Result.RouteFile     = value;
                        Result.RouteEncoding = TextEncoding.GetSystemEncodingFromFile(Result.RouteFile);
                        break;

                    case "/train":
                        Result.TrainFolder   = value;
                        Result.TrainEncoding = TextEncoding.GetSystemEncodingFromFile(Result.TrainFolder, "train.txt");
                        break;

                    case "/station":
                        Result.InitialStation = value;
                        break;

                    case "/time":
                        Interface.TryParseTime(value, out Result.StartTime);
                        break;

                    case "/ai":
                        if (value.ToLowerInvariant() == "true" || value.ToLowerInvariant() == "1")
                        {
                            Result.AIDriver = true;
                        }
                        break;

                    case "/fullscreen":
                        if (value.ToLowerInvariant() == "true" || value.ToLowerInvariant() == "1")
                        {
                            Result.FullScreen = true;
                        }
                        break;

                    case "/width":
                        NumberFormats.TryParseIntVb6(value, out Result.Width);
                        break;

                    case "/height":
                        NumberFormats.TryParseIntVb6(value, out Result.Height);
                        break;
                    }
                }
            }
        }
        /// <summary>
        /// Function to parse TFO definition
        /// </summary>
        /// <param name="FileName">The filename of the containing XML file</param>
        /// <param name="SectionElement">The XElement to parse</param>
        /// <param name="Train">The track following object to parse this node into</param>
        private static void ParseDefinitionNode(string FileName, XElement SectionElement, TrackFollowingObject Train)
        {
            string Section = SectionElement.Name.LocalName;

            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.Any() && !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.Any() && !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.Any() && !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.Any() && !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;

                default:
                    Interface.AddMessage(MessageType.Warning, false, $"Unsupported key {Key} encountered in {Section} at line {LineNumber.ToString(culture)} in {FileName}");
                    break;
                }
            }
        }
        /// <summary>
        /// Function to parse the contents of TravelStopData class
        /// </summary>
        /// <param name="FileName">The filename of the containing XML file</param>
        /// <param name="SectionElement">The XElement to parse</param>
        /// <returns>An instance of the new TravelStopData class with the parse result applied</returns>
        private static TravelStopData ParseTravelStopNode(string FileName, XElement SectionElement)
        {
            string Section = SectionElement.Name.LocalName;

            TravelStopData Data = new TravelStopData();

            ParseTravelDataNode(FileName, SectionElement, Data);

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

                switch (Key.ToLowerInvariant())
                {
                case "stoptime":
                    if (Value.Any() && !Interface.TryParseTime(Value, out Data.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.Any() && !NumberFormats.TryParseIntVb6(Value, out Door))
                        {
                            Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}");
                        }
                        break;
                    }

                    Data.OpenLeftDoors  = Door < 0.0 | DoorBoth;
                    Data.OpenRightDoors = Door > 0.0 | DoorBoth;
                }
                break;

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

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

                    default:
                        if (Value.Any() && (!NumberFormats.TryParseIntVb6(Value, out d) || !Enum.IsDefined(typeof(TravelDirection), d)))
                        {
                            Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}");
                            d = 1;
                        }
                        break;
                    }

                    Data.Direction = (TravelDirection)d;
                }
                break;

                case "decelerate":
                case "position":
                case "stopposition":
                case "accelerate":
                case "targetspeed":
                case "rail":
                    // Already parsed
                    break;

                default:
                    Interface.AddMessage(MessageType.Warning, false, $"Unsupported key {Key} encountered in {Section} at line {LineNumber.ToString(culture)} in {FileName}");
                    break;
                }
            }

            return(Data);
        }
        public static bool ReadMarkerXML(string fileName, ref CsvRwRouteParser.Marker marker)
        {
            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the marker's XML file
            currentXML.Load(fileName);
            string Path = System.IO.Path.GetDirectoryName(fileName);

            if (currentXML.DocumentElement != null)
            {
                bool        iM            = false;
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/TextMarker");

                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/ImageMarker");
                    iM            = true;
                }
                if (DocumentNodes == null || DocumentNodes.Count == 0)
                {
                    Interface.AddMessage(MessageType.Error, false, "No marker nodes defined in XML file " + fileName);
                    return(false);
                }
                //marker = new CsvRwRouteParser.Marker();
                foreach (XmlNode n in DocumentNodes)
                {
                    if (n.ChildNodes.OfType <XmlElement>().Any())
                    {
                        bool     EarlyDefined = false, LateDefined = false;
                        string   EarlyText = null, Text = null, LateText = null;
                        string[] Trains = null;
                        Texture  EarlyTexture = null, Texture = null, LateTexture = null;
                        double   EarlyTime = 0.0, LateTime = 0.0, TimeOut = Double.PositiveInfinity, EndingPosition = Double.PositiveInfinity;
                        OpenBveApi.Colors.MessageColor EarlyColor = MessageColor.White, OnTimeColor = MessageColor.White, LateColor = MessageColor.White;
                        foreach (XmlNode c in n.ChildNodes)
                        {
                            switch (c.Name.ToLowerInvariant())
                            {
                            case "early":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false,
                                                         "No paramaters defined for the early message in " + fileName);
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        EarlyText = cc.InnerText;
                                        break;

                                    case "texture":
                                    case "image":
                                        string f;
                                        try
                                        {
                                            f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        }
                                        catch
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "MessageEarlyTexture path was malformed in file " + fileName);
                                            break;
                                        }
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Program.CurrentHost.RegisterTexture(f, new TextureParameters(null, null), out EarlyTexture))
                                            {
                                                Interface.AddMessage(MessageType.Error, false, "Loading MessageEarlyTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "MessageEarlyTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "time":
                                        if (!Interface.TryParseTime(cc.InnerText, out EarlyTime))
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "Early message time invalid in " + fileName);
                                        }
                                        EarlyDefined = true;
                                        break;

                                    case "color":
                                        EarlyColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "ontime":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false,
                                                         "No paramaters defined for the on-time message in " + fileName);
                                }
                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        Text = cc.InnerText;
                                        break;

                                    case "texture":
                                    case "image":
                                        string f;
                                        try
                                        {
                                            f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        }
                                        catch
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "MessageTexture path was malformed in file " + fileName);
                                            break;
                                        }
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Program.CurrentHost.RegisterTexture(f, new TextureParameters(null, null), out Texture))
                                            {
                                                Interface.AddMessage(MessageType.Error, false, "Loading MessageTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "MessageTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "color":
                                        OnTimeColor = ParseColor(cc.InnerText, fileName);
                                        break;

                                    case "time":
                                        Interface.AddMessage(MessageType.Error, false, "OnTime should not contain a TIME declaration in " + fileName);
                                        break;
                                    }
                                }
                                break;

                            case "late":
                                if (!c.ChildNodes.OfType <XmlElement>().Any())
                                {
                                    Interface.AddMessage(MessageType.Error, false,
                                                         "No paramaters defined for the late message in " + fileName);
                                }

                                foreach (XmlNode cc in c.ChildNodes)
                                {
                                    switch (cc.Name.ToLowerInvariant())
                                    {
                                    case "text":
                                        LateText = cc.InnerText;
                                        break;

                                    case "texture":
                                    case "image":
                                        string f;
                                        try
                                        {
                                            f = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                        }
                                        catch
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "MessageLateTexture path was malformed in file " + fileName);
                                            break;
                                        }
                                        if (System.IO.File.Exists(f))
                                        {
                                            if (!Program.CurrentHost.RegisterTexture(f, new TextureParameters(null, null), out LateTexture))
                                            {
                                                Interface.AddMessage(MessageType.Error, false, "Loading MessageLateTexture " + f + " failed.");
                                            }
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "MessageLateTexture " + f + " does not exist.");
                                        }
                                        break;

                                    case "time":
                                        if (!Interface.TryParseTime(cc.InnerText, out LateTime))
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "Early message time invalid in " + fileName);
                                        }
                                        LateDefined = true;
                                        break;

                                    case "color":
                                        LateColor = ParseColor(cc.InnerText, fileName);
                                        break;
                                    }
                                }
                                break;

                            case "timeout":
                                if (!NumberFormats.TryParseDouble(c.InnerText, new[] { 1.0 }, out TimeOut))
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Marker timeout invalid in " + fileName);
                                }
                                break;

                            case "distance":
                                if (!NumberFormats.TryParseDouble(c.InnerText, new[] { 1.0 }, out EndingPosition))
                                {
                                    Interface.AddMessage(MessageType.Error, false, "Marker distance invalid in " + fileName);
                                }
                                break;

                            case "trains":
                                Trains = c.InnerText.Split(';');
                                break;
                            }
                        }
                        //Check this marker is valid
                        if (TimeOut == Double.PositiveInfinity && EndingPosition == Double.PositiveInfinity)
                        {
                            Interface.AddMessage(MessageType.Error, false, "No marker timeout or distance defined in marker XML " + fileName);
                            return(false);
                        }
                        if (EndingPosition != Double.PositiveInfinity)
                        {
                            if (Math.Abs(EndingPosition) == EndingPosition)
                            {
                                //Positive
                                marker.EndingPosition = marker.StartingPosition + EndingPosition;
                            }
                            else
                            {
                                //Negative
                                marker.EndingPosition    = marker.StartingPosition;
                                marker.StartingPosition -= EndingPosition;
                            }
                        }
                        TextureMessage t = new TextureMessage();
                        GeneralMessage m = new GeneralMessage();
                        //Add variants

                        if (EarlyDefined)
                        {
                            if (iM)
                            {
                                if (EarlyTexture != null)
                                {
                                    t.MessageEarlyTime    = EarlyTime;
                                    t.MessageEarlyTexture = EarlyTexture;
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                            else
                            {
                                if (EarlyText != null)
                                {
                                    m.MessageEarlyTime  = EarlyTime;
                                    m.MessageEarlyText  = EarlyText;
                                    m.MessageEarlyColor = EarlyColor;
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                        }
                        if (LateDefined)
                        {
                            if (iM)
                            {
                                if (LateTexture != null)
                                {
                                    t.MessageLateTime    = LateTime;
                                    t.MessageLateTexture = LateTexture;
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Warning, false, "A late time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                            else
                            {
                                if (LateText != null)
                                {
                                    m.MessageLateTime  = LateTime;
                                    m.MessageLateText  = LateText;
                                    m.MessageLateColor = LateColor;
                                }
                                else
                                {
                                    Interface.AddMessage(MessageType.Warning, false, "An early time was defined, but no message was specified in MarkerXML " + fileName);
                                }
                            }
                        }
                        //Final on-time message
                        if (iM)
                        {
                            t.Trains = Trains;
                            if (Texture != null)
                            {
                                t.MessageOnTimeTexture = Texture;
                            }
                        }
                        else
                        {
                            m.Trains = Trains;
                            if (Text != null)
                            {
                                m.MessageOnTimeText = Text;
                                m.Color             = OnTimeColor;
                            }
                        }
                        if (iM)
                        {
                            marker.Message = t;
                        }
                        else
                        {
                            marker.Message = m;
                        }
                    }
                }
            }
            return(true);
        }
示例#5
0
        /// <summary>Parses any command-line arguments passed to the main program</summary>
        /// <param name="Arguments">A string array of arguments</param>
        /// <param name="Result">The main dialog result (Used to launch)</param>
        internal static void ParseArguments(string[] Arguments, ref formMain.MainDialogResult Result)
        {
            if (Arguments.Length == 0)
            {
                return;
            }
            for (int i = 0; i < Arguments.Length; i++)
            {
                int equals = Arguments[i].IndexOf('=');
                if (@equals >= 0)
                {
                    string key   = Arguments[i].Substring(0, @equals).Trim().ToLowerInvariant();
                    string value = Arguments[i].Substring(@equals + 1).Trim();
                    switch (key)
                    {
                    case "/route":
                        Result.RouteFile = value;
                        switch (TextEncoding.GetEncodingFromFile(Result.RouteFile))
                        {
                        case TextEncoding.Encoding.Utf7:
                            Result.RouteEncoding = System.Text.Encoding.UTF7;
                            break;

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

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

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

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

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

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

                        case TextEncoding.Encoding.Windows1252:
                            Result.RouteEncoding = System.Text.Encoding.GetEncoding(1252);
                            break;

                        case TextEncoding.Encoding.Big5:
                            Result.RouteEncoding = System.Text.Encoding.GetEncoding(950);
                            break;

                        default:
                            Result.RouteEncoding = Encoding.Default;
                            break;
                        }
                        break;

                    case "/train":
                        Result.TrainFolder = value;
                        switch (TextEncoding.GetEncodingFromFile(Result.TrainFolder, "train.txt"))
                        {
                        case TextEncoding.Encoding.Utf8:
                            Result.TrainEncoding = System.Text.Encoding.UTF8;
                            break;

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

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

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

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

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

                        case TextEncoding.Encoding.Windows1252:
                            Result.TrainEncoding = System.Text.Encoding.GetEncoding(1252);
                            break;

                        case TextEncoding.Encoding.Big5:
                            Result.TrainEncoding = System.Text.Encoding.GetEncoding(950);
                            break;

                        default:
                            Result.TrainEncoding = Encoding.Default;
                            break;
                        }
                        break;

                    case "/station":
                        Result.InitialStation = value;
                        break;

                    case "/time":
                        Interface.TryParseTime(value, out Result.StartTime);
                        break;

                    case "/ai":
                        if (value.ToLowerInvariant() == "true" || value.ToLowerInvariant() == "1")
                        {
                            Result.AIDriver = true;
                        }
                        break;

                    case "/fullscreen":
                        if (value.ToLowerInvariant() == "true" || value.ToLowerInvariant() == "1")
                        {
                            Result.FullScreen = true;
                        }
                        break;

                    case "/width":
                        NumberFormats.TryParseIntVb6(value, out Result.Width);
                        break;

                    case "/height":
                        NumberFormats.TryParseIntVb6(value, out Result.Height);
                        break;
                    }
                }
            }
        }
示例#6
0
        //Parses an XML dynamic lighting definition
        public static bool ReadLightingXML(string fileName)
        {
            //Prep
            Renderer.LightDefinitions = new Renderer.LightDefinition[0];
            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the object's XML file
            try
            {
                currentXML.Load(fileName);
            }
            catch
            {
                return(false);
            }

            bool defined = false;

            //Check for null
            if (currentXML.DocumentElement != null)
            {
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/Brightness");
                //Check this file actually contains OpenBVE light definition nodes
                if (DocumentNodes != null)
                {
                    foreach (XmlNode n in DocumentNodes)
                    {
                        Renderer.LightDefinition currentLight = new Renderer.LightDefinition();
                        if (n.ChildNodes.OfType <XmlElement>().Any())
                        {
                            bool   tf = false, al = false, dl = false, ld = false, cb = false;
                            string ts = null;
                            foreach (XmlNode c in n.ChildNodes)
                            {
                                string[] Arguments = c.InnerText.Split(',');
                                switch (c.Name.ToLowerInvariant())
                                {
                                case "cablighting":
                                    double b;
                                    if (NumberFormats.TryParseDoubleVb6(Arguments[0].Trim(), out b))
                                    {
                                        cb = true;
                                    }
                                    if (b > 255 || b < 0)
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " is not a valid brightness value in file " + fileName);
                                        currentLight.CabBrightness = 255;
                                        break;
                                    }
                                    currentLight.CabBrightness = b;
                                    break;

                                case "time":
                                    double t;
                                    if (Interface.TryParseTime(Arguments[0].Trim(), out t))
                                    {
                                        currentLight.Time = (int)t;
                                        tf = true;
                                        //Keep back for error report later
                                        ts = Arguments[0];
                                    }
                                    else
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid time in file " + fileName);
                                    }
                                    break;

                                case "ambientlight":
                                    if (Arguments.Length == 3)
                                    {
                                        double R, G, B;
                                        if (NumberFormats.TryParseDoubleVb6(Arguments[0].Trim(), out R) && NumberFormats.TryParseDoubleVb6(Arguments[1].Trim(), out G) && NumberFormats.TryParseDoubleVb6(Arguments[2].Trim(), out B))
                                        {
                                            currentLight.AmbientColor = new Color24((byte)R, (byte)G, (byte)B);
                                            al = true;
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid color in file " + fileName);
                                        }
                                    }
                                    else
                                    {
                                        if (Arguments.Length == 1)
                                        {
                                            if (Color24.TryParseHexColor(Arguments[0], out currentLight.DiffuseColor))
                                            {
                                                al = true;
                                                break;
                                            }
                                        }
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not contain three arguments in file " + fileName);
                                    }
                                    break;

                                case "directionallight":
                                    if (Arguments.Length == 3)
                                    {
                                        double R, G, B;
                                        if (NumberFormats.TryParseDoubleVb6(Arguments[0].Trim(), out R) && NumberFormats.TryParseDoubleVb6(Arguments[1].Trim(), out G) && NumberFormats.TryParseDoubleVb6(Arguments[2].Trim(), out B))
                                        {
                                            currentLight.DiffuseColor = new Color24((byte)R, (byte)G, (byte)B);
                                            dl = true;
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid color in file " + fileName);
                                        }
                                    }
                                    else
                                    {
                                        if (Arguments.Length == 1)
                                        {
                                            if (Color24.TryParseHexColor(Arguments[0], out currentLight.DiffuseColor))
                                            {
                                                dl = true;
                                                break;
                                            }
                                        }
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not contain three arguments in file " + fileName);
                                    }
                                    break;

                                case "cartesianlightdirection":
                                case "lightdirection":
                                    if (Arguments.Length == 3)
                                    {
                                        double X, Y, Z;
                                        if (NumberFormats.TryParseDoubleVb6(Arguments[0].Trim(), out X) && NumberFormats.TryParseDoubleVb6(Arguments[1].Trim(), out Y) && NumberFormats.TryParseDoubleVb6(Arguments[2].Trim(), out Z))
                                        {
                                            currentLight.LightPosition = new Vector3(X, Y, Z);
                                            ld = true;
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid direction in file " + fileName);
                                        }
                                    }
                                    else
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not contain three arguments in file " + fileName);
                                    }
                                    break;

                                case "sphericallightdirection":
                                    if (Arguments.Length == 2)
                                    {
                                        double theta, phi;
                                        if (NumberFormats.TryParseDoubleVb6(Arguments[0].Trim(), out theta) && NumberFormats.TryParseDoubleVb6(Arguments[1].Trim(), out phi))
                                        {
                                            currentLight.LightPosition = new Vector3(Math.Cos(theta) * Math.Sin(phi), -Math.Sin(theta), Math.Cos(theta) * Math.Cos(phi));
                                            ld = true;
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid direction in file " + fileName);
                                        }
                                    }
                                    else
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not contain two arguments in file " + fileName);
                                    }
                                    break;
                                }
                            }
                            //We want to be able to add a completely default light element,  but not one that's not been defined in the XML properly
                            if (tf || al || ld || dl || cb)
                            {
                                //HACK: No way to break out of the first loop and continue with the second, so we've got to use a variable
                                bool Break = false;
                                int  l     = Renderer.LightDefinitions.Length;
                                for (int i = 0; i > l; i++)
                                {
                                    if (Renderer.LightDefinitions[i].Time == currentLight.Time)
                                    {
                                        Break = true;
                                        if (ts == null)
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "Multiple undefined times were encountered in file " + fileName);
                                        }
                                        else
                                        {
                                            Interface.AddMessage(MessageType.Error, false, "Duplicate time found: " + ts + " in file " + fileName);
                                        }
                                        break;
                                    }
                                }
                                if (Break)
                                {
                                    continue;
                                }
                                //We've got there, so now figure out where to add the new light into our list of light definitions
                                int t = 0;
                                if (l == 1)
                                {
                                    t = currentLight.Time > Renderer.LightDefinitions[0].Time ? 1 : 0;
                                }
                                else if (l > 1)
                                {
                                    for (int i = 1; i < l; i++)
                                    {
                                        t = i + 1;
                                        if (currentLight.Time > Renderer.LightDefinitions[i - 1].Time && currentLight.Time < Renderer.LightDefinitions[i].Time)
                                        {
                                            break;
                                        }
                                    }
                                }
                                //Resize array
                                defined = true;
                                Array.Resize(ref Renderer.LightDefinitions, l + 1);
                                if (t == l)
                                {
                                    //Straight insert at the end of the array
                                    Renderer.LightDefinitions[l] = currentLight;
                                }
                                else
                                {
                                    for (int u = t; u < l; u++)
                                    {
                                        //Otherwise, shift all elements to compensate
                                        Renderer.LightDefinitions[u + 1] = Renderer.LightDefinitions[u];
                                    }
                                    Renderer.LightDefinitions[t] = currentLight;
                                }
                            }
                        }
                    }
                }
            }
            //We couldn't find any valid XML, so return false
            return(defined);
        }
示例#7
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);
        }
示例#8
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;
                }
            }
        }
示例#9
0
        //Parses an XML background definition
        public static BackgroundHandle ReadBackgroundXML(string fileName)
        {
            List <StaticBackground> Backgrounds = new List <StaticBackground>();
            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the object's XML file
            currentXML.Load(fileName);
            string Path = System.IO.Path.GetDirectoryName(fileName);

            double[] UnitOfLength = { 1.0 };
            //Check for null
            if (currentXML.DocumentElement != null)
            {
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/Background");
                //Check this file actually contains OpenBVE light definition nodes
                if (DocumentNodes != null)
                {
                    foreach (XmlNode n in DocumentNodes)
                    {
                        if (n.ChildNodes.OfType <XmlElement>().Any())
                        {
                            double DisplayTime = -1;
                            //The time to transition between backgrounds in seconds
                            double TransitionTime = 0.8;
                            //The texture to use (if static)
                            Texture t = null;
                            //The object to use (if object based)
                            StaticObject o = null;
                            //The transition mode between backgrounds
                            BackgroundTransitionMode mode = BackgroundTransitionMode.FadeIn;
                            //The number of times the texture is repeated around the viewing frustrum (if appropriate)
                            double repetitions = 6;
                            foreach (XmlNode c in n.ChildNodes)
                            {
                                string[] Arguments = c.InnerText.Split(',');
                                switch (c.Name.ToLowerInvariant())
                                {
                                case "mode":
                                    switch (c.InnerText.ToLowerInvariant())
                                    {
                                    case "fadein":
                                        mode = BackgroundTransitionMode.FadeIn;
                                        break;

                                    case "fadeout":
                                        mode = BackgroundTransitionMode.FadeOut;
                                        break;

                                    case "none":
                                        mode = BackgroundTransitionMode.None;
                                        break;

                                    default:
                                        Interface.AddMessage(MessageType.Error, true, c.InnerText + "is not a valid background fade mode in file " + fileName);
                                        break;
                                    }
                                    break;

                                case "object":
                                    string f;
                                    try
                                    {
                                        f = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(fileName), c.InnerText);
                                    }
                                    catch
                                    {
                                        Interface.AddMessage(MessageType.Error, true, "BackgroundObject FileName is malformed in file " + fileName);
                                        break;
                                    }
                                    if (!System.IO.File.Exists(f))
                                    {
                                        Interface.AddMessage(MessageType.Error, true, "FileName " + f + " not found in file " + fileName);
                                    }
                                    else
                                    {
                                        UnifiedObject b = ObjectManager.LoadObject(f, System.Text.Encoding.Default, false);
                                        o = (StaticObject)b;
                                    }
                                    break;

                                case "repetitions":
                                    if (!NumberFormats.TryParseDoubleVb6(Arguments[0], UnitOfLength, out repetitions))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid number of repetitions in " + fileName);
                                    }
                                    break;

                                case "texture":
                                    string file;
                                    try
                                    {
                                        file = OpenBveApi.Path.CombineFile(Path, c.InnerText);
                                    }
                                    catch
                                    {
                                        Interface.AddMessage(MessageType.Error, true, "BackgroundTexture FileName is malformed in file " + fileName);
                                        break;
                                    }
                                    if (!System.IO.File.Exists(file))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, "The background texture file " + c.InnerText + " does not exist in " + fileName);
                                    }
                                    else
                                    {
                                        Program.CurrentHost.RegisterTexture(file, new TextureParameters(null, null), out t);
                                    }
                                    break;

                                case "time":
                                    if (!Interface.TryParseTime(Arguments[0].Trim(), out DisplayTime))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " does not parse to a valid time in file " + fileName);
                                    }
                                    break;

                                case "transitiontime":
                                    if (!NumberFormats.TryParseDoubleVb6(Arguments[0], UnitOfLength, out TransitionTime))
                                    {
                                        Interface.AddMessage(MessageType.Error, false, c.InnerText + " is not a valid background transition time in " + fileName);
                                    }
                                    break;
                                }
                            }
                            //Create background if texture is not null
                            if (t != null && o == null)
                            {
                                Backgrounds.Add(new StaticBackground(t, repetitions, false, TransitionTime, mode, DisplayTime));
                            }
                            if (t == null && o != null)
                            {
                                //All other parameters are ignored if an object has been defined
                                //TODO: Error message stating they have been ignored
                                return(new BackgroundObject(o));
                            }
                        }
                    }
                    if (Backgrounds.Count == 1)
                    {
                        return(Backgrounds[0]);
                    }
                    if (Backgrounds.Count > 1)
                    {
                        //Sort list- Not worried about when they start or end, so use simple LINQ
                        Backgrounds = Backgrounds.OrderBy(o => o.Time).ToList();
                        //If more than 2 backgrounds, convert to array and return a new dynamic background
                        return(new DynamicBackground(Backgrounds.ToArray()));
                    }
                }
            }
            //We couldn't find any valid XML, so return false
            throw new InvalidDataException();
        }
示例#10
0
        public static Game.Station ReadStationXML(string fileName, bool PreviewOnly, Textures.Texture[] daytimeTimetableTextures, Textures.Texture[] nighttimeTimetableTextures, int CurrentStation, ref bool passAlarm, ref CsvRwRouteParser.StopRequest stopRequest)
        {
            Game.Station station = new Game.Station
            {
                Stops = new Game.StationStop[] { }
            };
            stopRequest.Early              = new TrackManager.RequestStop();
            stopRequest.OnTime             = new TrackManager.RequestStop();
            stopRequest.Late               = new TrackManager.RequestStop();
            stopRequest.OnTime.Probability = 75;
            //The current XML file to load
            XmlDocument currentXML = new XmlDocument();

            //Load the object's XML file
            currentXML.Load(fileName);
            string Path = System.IO.Path.GetDirectoryName(fileName);

            //Check for null
            if (currentXML.DocumentElement != null)
            {
                XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/Station");
                //Check this file actually contains OpenBVE light definition nodes
                if (DocumentNodes != null)
                {
                    foreach (XmlNode n in DocumentNodes)
                    {
                        if (n.ChildNodes.OfType <XmlElement>().Any())
                        {
                            foreach (XmlNode c in n.ChildNodes)
                            {
                                //string[] Arguments = c.InnerText.Split(',');
                                switch (c.Name.ToLowerInvariant())
                                {
                                case "name":
                                    if (!string.IsNullOrEmpty(c.InnerText))
                                    {
                                        station.Name = c.InnerText;
                                    }
                                    else
                                    {
                                        Interface.AddMessage(Interface.MessageType.Error, false, "Station name was empty in XML file " + fileName);
                                    }
                                    break;

                                case "arrivaltime":
                                    if (!string.IsNullOrEmpty(c.InnerText))
                                    {
                                        if (!Interface.TryParseTime(c.InnerText, out station.ArrivalTime))
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Station arrival time was invalid in XML file " + fileName);
                                        }
                                    }
                                    break;

                                case "departuretime":
                                    if (!string.IsNullOrEmpty(c.InnerText))
                                    {
                                        if (!Interface.TryParseTime(c.InnerText, out station.DepartureTime))
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Station arrival time was invalid in XML file " + fileName);
                                        }
                                    }
                                    break;

                                case "type":
                                    switch (c.InnerText.ToLowerInvariant())
                                    {
                                    case "c":
                                    case "changeends":
                                        station.Type = StationType.ChangeEnds;
                                        break;

                                    case "t":
                                    case "terminal":
                                        station.Type = StationType.Terminal;
                                        break;

                                    default:
                                        station.Type = StationType.Normal;
                                        break;
                                    }
                                    break;

                                case "passalarm":
                                    if (!string.IsNullOrEmpty(c.InnerText))
                                    {
                                        if (c.InnerText.ToLowerInvariant() == "1" || c.InnerText.ToLowerInvariant() == "true")
                                        {
                                            passAlarm = true;
                                        }
                                        else
                                        {
                                            passAlarm = false;
                                        }
                                    }
                                    break;

                                case "doors":
                                    int  door     = 0;
                                    bool doorboth = false;
                                    if (!string.IsNullOrEmpty(c.InnerText))
                                    {
                                        switch (c.InnerText.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 (!NumberFormats.TryParseIntVb6(c.InnerText, out door))
                                            {
                                                Interface.AddMessage(Interface.MessageType.Error, false, "Door side was invalid in XML file " + fileName);
                                                door = 0;
                                            }
                                            break;
                                        }
                                    }
                                    station.OpenLeftDoors  = door < 0.0 | doorboth;
                                    station.OpenRightDoors = door > 0.0 | doorboth;
                                    break;

                                case "forcedredsignal":
                                    if (!string.IsNullOrEmpty(c.InnerText))
                                    {
                                        if (c.InnerText.ToLowerInvariant() == "1" || c.InnerText.ToLowerInvariant() == "true")
                                        {
                                            station.ForceStopSignal = true;
                                        }
                                        else
                                        {
                                            station.ForceStopSignal = false;
                                        }
                                    }
                                    break;

                                case "system":
                                    switch (c.InnerText.ToLowerInvariant())
                                    {
                                    case "0":
                                    case "ATS":
                                        station.SafetySystem = Game.SafetySystem.Ats;
                                        break;

                                    case "1":
                                    case "ATC":
                                        station.SafetySystem = Game.SafetySystem.Atc;
                                        break;

                                    default:
                                        Interface.AddMessage(Interface.MessageType.Error, false, "An invalid station safety system was specified in XML file " + fileName);
                                        station.SafetySystem = Game.SafetySystem.Ats;
                                        break;
                                    }
                                    break;

                                case "arrivalsound":
                                    string arrSound  = string.Empty;
                                    double arrRadius = 30.0;
                                    if (!c.ChildNodes.OfType <XmlElement>().Any())
                                    {
                                        foreach (XmlNode cc in c.ChildNodes)
                                        {
                                            switch (c.Name.ToLowerInvariant())
                                            {
                                            case "filename":
                                                try
                                                {
                                                    arrSound = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                                }
                                                catch
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Arrival sound filename is invalid in XML file " + fileName);
                                                }
                                                break;

                                            case "radius":
                                                if (!double.TryParse(cc.InnerText, out arrRadius))
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Arrival sound radius was invalid in XML file " + fileName);
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        try
                                        {
                                            arrSound = OpenBveApi.Path.CombineFile(Path, c.InnerText);
                                        }
                                        catch
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Arrival sound filename is invalid in XML file " + fileName);
                                        }
                                    }
                                    if (File.Exists(arrSound))
                                    {
                                        station.ArrivalSoundBuffer = Sounds.RegisterBuffer(arrSound, arrRadius);
                                    }
                                    else
                                    {
                                        Interface.AddMessage(Interface.MessageType.Error, false, "Arrival sound file does not exist in XML file " + fileName);
                                    }
                                    break;

                                case "stopduration":
                                    double stopDuration;
                                    if (!double.TryParse(c.InnerText, out stopDuration))
                                    {
                                        Interface.AddMessage(Interface.MessageType.Error, false, "Stop duration is invalid in XML file " + fileName);
                                    }
                                    else
                                    {
                                        if (stopDuration < 5.0)
                                        {
                                            stopDuration = 5.0;
                                        }
                                        station.StopTime = stopDuration;
                                    }
                                    break;

                                case "passengerratio":
                                    double ratio;
                                    if (!double.TryParse(c.InnerText, out ratio))
                                    {
                                        Interface.AddMessage(Interface.MessageType.Error, false, "Passenger ratio is invalid in XML file " + fileName);
                                    }
                                    else
                                    {
                                        if (ratio < 0.0)
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Passenger ratio must be non-negative in XML file " + fileName);
                                            ratio = 100.0;
                                        }
                                        station.PassengerRatio = ratio * 0.01;
                                    }
                                    break;

                                case "departuresound":
                                    string depSound  = string.Empty;
                                    double depRadius = 30.0;
                                    if (!c.ChildNodes.OfType <XmlElement>().Any())
                                    {
                                        foreach (XmlNode cc in c.ChildNodes)
                                        {
                                            switch (c.Name.ToLowerInvariant())
                                            {
                                            case "filename":
                                                try
                                                {
                                                    depSound = OpenBveApi.Path.CombineFile(Path, cc.InnerText);
                                                }
                                                catch
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Departure sound filename is invalid in XML file " + fileName);
                                                }
                                                break;

                                            case "radius":
                                                if (!double.TryParse(cc.InnerText, out depRadius))
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Departure sound radius was invalid in XML file " + fileName);
                                                }
                                                break;
                                            }
                                        }
                                    }
                                    else
                                    {
                                        try
                                        {
                                            depSound = OpenBveApi.Path.CombineFile(Path, c.InnerText);
                                        }
                                        catch
                                        {
                                            Interface.AddMessage(Interface.MessageType.Error, false, "Departure sound filename is invalid in XML file " + fileName);
                                        }
                                    }
                                    if (File.Exists(depSound))
                                    {
                                        station.DepartureSoundBuffer = Sounds.RegisterBuffer(depSound, depRadius);
                                    }
                                    else
                                    {
                                        Interface.AddMessage(Interface.MessageType.Error, false, "Departure sound file does not exist in XML file " + fileName);
                                    }
                                    break;

                                case "timetableindex":
                                    if (!PreviewOnly)
                                    {
                                        int ttidx = -1;
                                        if (!string.IsNullOrEmpty(c.InnerText))
                                        {
                                            if (NumberFormats.TryParseIntVb6(c.InnerText, out ttidx))
                                            {
                                                if (ttidx < 0)
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Timetable index must be non-negative in XML file " + fileName);
                                                    ttidx = -1;
                                                }
                                                else if (ttidx >= daytimeTimetableTextures.Length & ttidx >= nighttimeTimetableTextures.Length)
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Timetable index references a non-loaded texture in XML file " + fileName);
                                                    ttidx = -1;
                                                }
                                                station.TimetableDaytimeTexture   = ttidx >= 0 & ttidx < daytimeTimetableTextures.Length ? daytimeTimetableTextures[ttidx] : null;
                                                station.TimetableNighttimeTexture = ttidx >= 0 & ttidx < nighttimeTimetableTextures.Length ? nighttimeTimetableTextures[ttidx] : null;
                                                break;
                                            }
                                        }
                                        if (ttidx == -1)
                                        {
                                            if (CurrentStation > 0)
                                            {
                                                station.TimetableDaytimeTexture   = Game.Stations[CurrentStation - 1].TimetableDaytimeTexture;
                                                station.TimetableNighttimeTexture = Game.Stations[CurrentStation - 1].TimetableNighttimeTexture;
                                            }
                                            else if (daytimeTimetableTextures.Length > 0 & nighttimeTimetableTextures.Length > 0)
                                            {
                                                station.TimetableDaytimeTexture   = daytimeTimetableTextures[0];
                                                station.TimetableNighttimeTexture = nighttimeTimetableTextures[0];
                                            }
                                        }
                                    }
                                    break;

                                case "requeststop":
                                    station.Type     = StationType.RequestStop;
                                    station.StopMode = StationStopMode.AllRequestStop;
                                    foreach (XmlNode cc in c.ChildNodes)
                                    {
                                        switch (cc.Name.ToLowerInvariant())
                                        {
                                        case "aibehaviour":
                                            switch (cc.InnerText.ToLowerInvariant())
                                            {
                                            case "fullspeed":
                                            case "0":
                                                //With this set, the AI driver will not attempt to brake, but pass through at linespeed
                                                stopRequest.FullSpeed = true;
                                                break;

                                            case "normalbrake":
                                            case "1":
                                                //With this set, the AI driver breaks to a near stop whilst passing through the station
                                                stopRequest.FullSpeed = false;
                                                break;
                                            }
                                            break;

                                        case "playeronly":
                                            station.StopMode = StationStopMode.PlayerRequestStop;
                                            break;

                                        case "distance":
                                            if (!string.IsNullOrEmpty(cc.InnerText))
                                            {
                                                double d;
                                                if (!NumberFormats.TryParseDoubleVb6(cc.InnerText, out d))
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Request stop distance is invalid in XML file " + fileName);
                                                    break;
                                                }
                                                stopRequest.TrackPosition -= Math.Abs(d);
                                            }
                                            break;

                                        case "earlytime":
                                            if (!string.IsNullOrEmpty(cc.InnerText))
                                            {
                                                if (!Interface.TryParseTime(cc.InnerText, out stopRequest.Early.Time))
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Request stop early time was invalid in XML file " + fileName);
                                                }
                                            }
                                            break;

                                        case "latetime":
                                            if (!string.IsNullOrEmpty(cc.InnerText))
                                            {
                                                if (!Interface.TryParseTime(cc.InnerText, out stopRequest.Late.Time))
                                                {
                                                    Interface.AddMessage(Interface.MessageType.Error, false, "Request stop late time was invalid in XML file " + fileName);
                                                }
                                            }
                                            break;

                                        case "stopmessage":
                                            if (cc.ChildNodes.OfType <XmlElement>().Any())
                                            {
                                                foreach (XmlNode cd in cc.ChildNodes)
                                                {
                                                    switch (cd.Name.ToLowerInvariant())
                                                    {
                                                    case "early":
                                                        if (!string.IsNullOrEmpty(cd.InnerText))
                                                        {
                                                            stopRequest.Early.StopMessage = cd.InnerText;
                                                        }
                                                        break;

                                                    case "ontime":
                                                        if (!string.IsNullOrEmpty(cd.InnerText))
                                                        {
                                                            stopRequest.OnTime.StopMessage = cd.InnerText;
                                                        }
                                                        break;

                                                    case "late":
                                                        if (!string.IsNullOrEmpty(cd.InnerText))
                                                        {
                                                            stopRequest.Late.StopMessage = cd.InnerText;
                                                        }
                                                        break;

                                                    case "#text":
                                                        stopRequest.Early.StopMessage  = cc.InnerText;
                                                        stopRequest.OnTime.StopMessage = cc.InnerText;
                                                        stopRequest.Late.StopMessage   = cc.InnerText;
                                                        break;
                                                    }
                                                }
                                            }
                                            break;

                                        case "passmessage":
                                            if (cc.ChildNodes.OfType <XmlElement>().Any())
                                            {
                                                foreach (XmlNode cd in cc.ChildNodes)
                                                {
                                                    switch (cd.Name.ToLowerInvariant())
                                                    {
                                                    case "early":
                                                        if (!string.IsNullOrEmpty(cd.InnerText))
                                                        {
                                                            stopRequest.Early.PassMessage = cd.InnerText;
                                                        }
                                                        break;

                                                    case "ontime":
                                                        if (!string.IsNullOrEmpty(cd.InnerText))
                                                        {
                                                            stopRequest.OnTime.PassMessage = cd.InnerText;
                                                        }
                                                        break;

                                                    case "late":
                                                        if (!string.IsNullOrEmpty(cd.InnerText))
                                                        {
                                                            stopRequest.Late.PassMessage = cd.InnerText;
                                                        }
                                                        break;

                                                    case "#text":
                                                        stopRequest.Early.PassMessage  = cc.InnerText;
                                                        stopRequest.OnTime.PassMessage = cc.InnerText;
                                                        stopRequest.Late.PassMessage   = cc.InnerText;
                                                        break;
                                                    }
                                                }
                                            }
                                            break;

                                        case "probability":
                                            foreach (XmlNode cd in cc.ChildNodes)
                                            {
                                                switch (cd.Name.ToLowerInvariant())
                                                {
                                                case "early":
                                                    if (!string.IsNullOrEmpty(cd.InnerText))
                                                    {
                                                        if (!NumberFormats.TryParseIntVb6(cd.InnerText, out stopRequest.Early.Probability))
                                                        {
                                                            Interface.AddMessage(Interface.MessageType.Error, false, "Request stop early probability was invalid in XML file " + fileName);
                                                        }
                                                    }
                                                    break;

                                                case "ontime":
                                                    if (!string.IsNullOrEmpty(cd.InnerText))
                                                    {
                                                        if (!NumberFormats.TryParseIntVb6(cd.InnerText, out stopRequest.OnTime.Probability))
                                                        {
                                                            Interface.AddMessage(Interface.MessageType.Error, false, "Request stop ontime probability was invalid in XML file " + fileName);
                                                        }
                                                    }
                                                    break;

                                                case "late":
                                                    if (!string.IsNullOrEmpty(cd.InnerText))
                                                    {
                                                        if (!NumberFormats.TryParseIntVb6(cd.InnerText, out stopRequest.OnTime.Probability))
                                                        {
                                                            Interface.AddMessage(Interface.MessageType.Error, false, "Request stop late probability was invalid in XML file " + fileName);
                                                        }
                                                    }
                                                    break;

                                                case "#text":
                                                    if (!NumberFormats.TryParseIntVb6(cd.InnerText, out stopRequest.OnTime.Probability))
                                                    {
                                                        Interface.AddMessage(Interface.MessageType.Error, false, "Request stop probability was invalid in XML file " + fileName);
                                                    }
                                                    break;
                                                }
                                            }

                                            break;

                                        case "maxcars":
                                            if (!NumberFormats.TryParseIntVb6(cc.InnerText, out stopRequest.MaxNumberOfCars))
                                            {
                                                Interface.AddMessage(Interface.MessageType.Error, false, "Request stop maximum cars was invalid in XML file " + fileName);
                                            }
                                            break;
                                        }
                                    }

                                    break;
                                }
                            }
                        }
                    }
                    return(station);
                }
            }
            //We couldn't find any valid XML, so return false
            throw new InvalidDataException();
        }