// parse route for data private static void ParseRouteForData(string FileName, bool IsRW, System.Text.Encoding Encoding, Expression[] Expressions, string TrainPath, string ObjectPath, string SoundPath, double[] UnitOfLength, ref RouteData Data, bool PreviewOnly) { System.Globalization.CultureInfo Culture = System.Globalization.CultureInfo.InvariantCulture; string Section = ""; bool SectionAlwaysPrefix = false; int BlockIndex = 0; int BlocksUsed = Data.Blocks.Length; Game.Stations = new Game.Station[] { }; int CurrentStation = -1; int CurrentStop = -1; bool DepartureSignalUsed = false; int CurrentSection = 0; bool ValueBasedSections = false; double progressFactor = Expressions.Length == 0 ? 0.3333 : 0.3333 / (double)Expressions.Length; // process non-track namespaces for (int j = 0; j < Expressions.Length; j++) { Loading.RouteProgress = (double)j * progressFactor; if ((j & 255) == 0) { System.Threading.Thread.Sleep(1); if (Loading.Cancel) return; } if (Expressions[j].Text.StartsWith("[") & Expressions[j].Text.EndsWith("]")) { Section = Expressions[j].Text.Substring(1, Expressions[j].Text.Length - 2).Trim(); if (string.Compare(Section, "object", StringComparison.OrdinalIgnoreCase) == 0) { Section = "Structure"; } else if (string.Compare(Section, "railway", StringComparison.OrdinalIgnoreCase) == 0) { Section = "Track"; } SectionAlwaysPrefix = true; } else { // find equals int Equals = Expressions[j].Text.IndexOf('='); if (Equals >= 0) { // handle RW cycle syntax string t = Expressions[j].Text.Substring(0, Equals); if (Section.ToLowerInvariant() == "cycle" & SectionAlwaysPrefix) { double b; if (Interface.TryParseDoubleVb6(t, out b)) { t = ".Ground(" + t + ")"; } } else if (Section.ToLowerInvariant() == "signal" & SectionAlwaysPrefix) { double b; if (Interface.TryParseDoubleVb6(t, out b)) { t = ".Void(" + t + ")"; } } // convert RW style into CSV style Expressions[j].Text = t + " " + Expressions[j].Text.Substring(Equals + 1); } // separate command and arguments string Command, ArgumentSequence; SeparateCommandsAndArguments(Expressions[j], out Command, out ArgumentSequence, Culture, Expressions[j].File, j, false); // process command double Number; bool NumberCheck = !IsRW || string.Compare(Section, "track", StringComparison.OrdinalIgnoreCase) == 0; if (NumberCheck && Interface.TryParseDouble(Command, UnitOfLength, out Number)) { // track position (ignored) } else { // split arguments string[] Arguments; { int n = 0; for (int k = 0; k < ArgumentSequence.Length; k++) { if (IsRW & ArgumentSequence[k] == ',') { n++; } else if (ArgumentSequence[k] == ';') { n++; } } Arguments = new string[n + 1]; int a = 0, h = 0; for (int k = 0; k < ArgumentSequence.Length; k++) { if (IsRW & ArgumentSequence[k] == ',') { Arguments[h] = ArgumentSequence.Substring(a, k - a).Trim(); a = k + 1; h++; } else if (ArgumentSequence[k] == ';') { Arguments[h] = ArgumentSequence.Substring(a, k - a).Trim(); a = k + 1; h++; } } if (ArgumentSequence.Length - a > 0) { Arguments[h] = ArgumentSequence.Substring(a).Trim(); h++; } Array.Resize<string>(ref Arguments, h); } // preprocess command if (Command.ToLowerInvariant() == "with") { if (Arguments.Length >= 1) { Section = Arguments[0]; SectionAlwaysPrefix = false; } else { Section = ""; SectionAlwaysPrefix = false; } Command = null; } else { if (Command.StartsWith(".")) { Command = Section + Command; } else if (SectionAlwaysPrefix) { Command = Section + "." + Command; } Command = Command.Replace(".Void", ""); if (Command.StartsWith("structure", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 5).TrimEnd(); } else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 5).TrimEnd(); } else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".x", StringComparison.OrdinalIgnoreCase)) { Command = "texture.background.x" + Command.Substring(18, Command.Length - 20).TrimEnd(); } else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".aspect", StringComparison.OrdinalIgnoreCase)) { Command = "texture.background.aspect" + Command.Substring(18, Command.Length - 25).TrimEnd(); } else if (Command.StartsWith("structure.back", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".x", StringComparison.OrdinalIgnoreCase)) { Command = "texture.background.x" + Command.Substring(14, Command.Length - 16).TrimEnd(); } else if (Command.StartsWith("structure.back", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".aspect", StringComparison.OrdinalIgnoreCase)) { Command = "texture.background.aspect" + Command.Substring(14, Command.Length - 21).TrimEnd(); } else if (Command.StartsWith("cycle", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".params", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 7).TrimEnd(); } else if (Command.StartsWith("signal", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 5).TrimEnd(); } else if (Command.StartsWith("train.run", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 4).TrimEnd(); } else if (Command.StartsWith("train.flange", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 4).TrimEnd(); } else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".day.load", StringComparison.OrdinalIgnoreCase)) { Command = "train.timetable.day" + Command.Substring(15, Command.Length - 24).Trim(); } else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".night.load", StringComparison.OrdinalIgnoreCase)) { Command = "train.timetable.night" + Command.Substring(15, Command.Length - 26).Trim(); } else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".day", StringComparison.OrdinalIgnoreCase)) { Command = "train.timetable.day" + Command.Substring(15, Command.Length - 19).Trim(); } else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".night", StringComparison.OrdinalIgnoreCase)) { Command = "train.timetable.night" + Command.Substring(15, Command.Length - 21).Trim(); } else if (Command.StartsWith("route.signal", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 4).TrimEnd(); } } // handle indices int CommandIndex1 = 0, CommandIndex2 = 0; if (Command != null && Command.EndsWith(")")) { for (int k = Command.Length - 2; k >= 0; k--) { if (Command[k] == '(') { string Indices = Command.Substring(k + 1, Command.Length - k - 2).TrimStart(); Command = Command.Substring(0, k).TrimEnd(); int h = Indices.IndexOf(";"); if (h >= 0) { string a = Indices.Substring(0, h).TrimEnd(); string b = Indices.Substring(h + 1).TrimStart(); if (a.Length > 0 && !Interface.TryParseIntVb6(a, out CommandIndex1)) { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid first index appeared at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File + "."); Command = null; break; } else if (b.Length > 0 && !Interface.TryParseIntVb6(b, out CommandIndex2)) { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid second index appeared at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File + "."); Command = null; break; } } else { if (Indices.Length > 0 && !Interface.TryParseIntVb6(Indices, out CommandIndex1)) { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid index appeared at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File + "."); Command = null; break; } } break; } } } // process command if (Command != null && Command.Length != 0) { switch (Command.ToLowerInvariant()) { // options case "options.blocklength": { double length = 25.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], UnitOfLength, out length)) { Interface.AddMessage(Interface.MessageType.Error, false, "Length is invalid in Options.BlockLength at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); length = 25.0; } Data.BlockInterval = length; } break; case "options.unitoflength": case "options.unitofspeed": case "options.objectvisibility": break; case "options.sectionbehavior": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { int a; if (!Interface.TryParseIntVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "Mode is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (a != 0 & a != 1) { Interface.AddMessage(Interface.MessageType.Error, false, "Mode is expected to be either 0 or 1 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { ValueBasedSections = a == 1; } } break; case "options.cantbehavior": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { int a; if (!Interface.TryParseIntVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "Mode is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (a != 0 & a != 1) { Interface.AddMessage(Interface.MessageType.Error, false, "Mode is expected to be either 0 or 1 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.SignedCant = a == 1; } } break; case "options.fogbehavior": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { int a; if (!Interface.TryParseIntVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "Mode is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (a != 0 & a != 1) { Interface.AddMessage(Interface.MessageType.Error, false, "Mode is expected to be either 0 or 1 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.FogTransitionMode = a == 1; } } break; // route case "route.comment": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Game.RouteComment = Arguments[0]; } break; case "route.image": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { string f = OpenBveApi.Path.CombineFile(System.IO.Path.GetDirectoryName(FileName), Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Game.RouteImage = f; } } break; case "route.timetable": if (!PreviewOnly) { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, "" + Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Timetable.DefaultTimetableDescription = Arguments[0]; } } break; case "route.change": if (!PreviewOnly) { int change = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out change)) { Interface.AddMessage(Interface.MessageType.Error, false, "Mode is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); change = 0; } else if (change < -1 | change > 1) { Interface.AddMessage(Interface.MessageType.Error, false, "Mode is expected to be -1, 0 or 1 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); change = 0; } Game.TrainStart = (Game.TrainStartMode)change; } break; case "route.gauge": case "train.gauge": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double a; if (!Interface.TryParseDoubleVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "ValueInMillimeters is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (a <= 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "ValueInMillimeters is expected to be positive in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Game.RouteRailGauge = 0.001 * a; } } break; case "route.signal": if (!PreviewOnly) { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double a; if (!Interface.TryParseDoubleVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "AspectIndex is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (a < 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "Speed is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.SignalSpeeds.Length) { int n = Data.SignalSpeeds.Length; Array.Resize<double>(ref Data.SignalSpeeds, CommandIndex1 + 1); for (int i = n; i < CommandIndex1; i++) { Data.SignalSpeeds[i] = double.PositiveInfinity; } } Data.SignalSpeeds[CommandIndex1] = a * Data.UnitOfSpeed; } } } } break; case "route.runinterval": case "train.interval": { if (!PreviewOnly) { double[] intervals = new double[Arguments.Length]; for (int k = 0; k < Arguments.Length; k++) { if (!Interface.TryParseDoubleVb6(Arguments[k], out intervals[k])) { Interface.AddMessage(Interface.MessageType.Error, false, "Interval" + k.ToString(Culture) + " is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } } Array.Sort<double>(intervals); Game.PrecedingTrainTimeDeltas = intervals; } } break; case "train.velocity": { if (!PreviewOnly) { double limit = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out limit)) { Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in Train.Velocity at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); limit = 0.0; } Game.PrecedingTrainSpeedLimit = limit <= 0.0 ? double.PositiveInfinity : Data.UnitOfSpeed * limit; } } break; case "route.accelerationduetogravity": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double a; if (!Interface.TryParseDoubleVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "Value is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (a <= 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "Value is expected to be positive in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Game.RouteAccelerationDueToGravity = a; } } break; case "route.elevation": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double a; if (!Interface.TryParseDoubleVb6(Arguments[0], UnitOfLength, out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "Height is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Game.RouteInitialElevation = a; } } break; case "route.temperature": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double a; if (!Interface.TryParseDoubleVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "ValueInCelsius is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (a <= -273.15) { Interface.AddMessage(Interface.MessageType.Error, false, "ValueInCelsius is expected to be greater than to -273.15 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Game.RouteInitialAirTemperature = a + 273.15; } } break; case "route.pressure": if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double a; if (!Interface.TryParseDoubleVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "ValueInKPa is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (a <= 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "ValueInKPa is expected to be positive in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Game.RouteInitialAirPressure = 1000.0 * a; } } break; case "route.ambientlight": { int r = 255, g = 255, b = 255; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out r)) { Interface.AddMessage(Interface.MessageType.Error, false, "RedValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (r < 0 | r > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "RedValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); r = r < 0 ? 0 : 255; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out g)) { Interface.AddMessage(Interface.MessageType.Error, false, "GreenValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (g < 0 | g > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "GreenValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); g = g < 0 ? 0 : 255; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out b)) { Interface.AddMessage(Interface.MessageType.Error, false, "BlueValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (b < 0 | b > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "BlueValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); b = b < 0 ? 0 : 255; } Renderer.OptionAmbientColor = new Color24((byte)r, (byte)g, (byte)b); } break; case "route.directionallight": { int r = 255, g = 255, b = 255; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out r)) { Interface.AddMessage(Interface.MessageType.Error, false, "RedValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (r < 0 | r > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "RedValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); r = r < 0 ? 0 : 255; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out g)) { Interface.AddMessage(Interface.MessageType.Error, false, "GreenValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (g < 0 | g > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "GreenValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); g = g < 0 ? 0 : 255; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out b)) { Interface.AddMessage(Interface.MessageType.Error, false, "BlueValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (b < 0 | b > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "BlueValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); b = b < 0 ? 0 : 255; } Renderer.OptionDiffuseColor = new Color24((byte)r, (byte)g, (byte)b); } break; case "route.lightdirection": { double theta = 60.0, phi = -26.565051177078; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out theta)) { Interface.AddMessage(Interface.MessageType.Error, false, "Theta is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], out phi)) { Interface.AddMessage(Interface.MessageType.Error, false, "Phi is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } theta *= 0.0174532925199433; phi *= 0.0174532925199433; double dx = Math.Cos(theta) * Math.Sin(phi); double dy = -Math.Sin(theta); double dz = Math.Cos(theta) * Math.Cos(phi); Renderer.OptionLightPosition = new World.Vector3Df((float)-dx, (float)-dy, (float)-dz); } break; // train case "train.folder": case "train.file": { if (PreviewOnly) { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FolderName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Game.TrainName = Arguments[0]; } } } } break; case "train.run": case "train.rail": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailTypeIndex is out of range in "+Command+" at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { int val = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out val)) { Interface.AddMessage(Interface.MessageType.Error, false, "RunSoundIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); val = 0; } if (val < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RunSoundIndex is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); val = 0; } if (CommandIndex1 >= Data.Structure.Run.Length) { Array.Resize<int>(ref Data.Structure.Run, CommandIndex1 + 1); } Data.Structure.Run[CommandIndex1] = val; } } } break; case "train.flange": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailTypeIndex is out of range in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { int val = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out val)) { Interface.AddMessage(Interface.MessageType.Error, false, "FlangeSoundIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); val = 0; } if (val < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "FlangeSoundIndex expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); val = 0; } if (CommandIndex1 >= Data.Structure.Flange.Length) { Array.Resize<int>(ref Data.Structure.Flange, CommandIndex1 + 1); } Data.Structure.Flange[CommandIndex1] = val; } } } break; case "train.timetable.day": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "TimetableIndex is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { while (CommandIndex1 >= Data.TimetableDaytime.Length) { int n = Data.TimetableDaytime.Length; Array.Resize<Textures.Texture>(ref Data.TimetableDaytime, n << 1); for (int i = n; i < Data.TimetableDaytime.Length; i++) { Data.TimetableDaytime[i] = null; } } string f = OpenBveApi.Path.CombineFile(TrainPath, Arguments[0]); if (!System.IO.File.Exists(f)) { f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); } if (System.IO.File.Exists(f)) { Textures.RegisterTexture(f, out Data.TimetableDaytime[CommandIndex1]); } } } } } break; case "train.timetable.night": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "TimetableIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { while (CommandIndex1 >= Data.TimetableNighttime.Length) { int n = Data.TimetableNighttime.Length; Array.Resize<Textures.Texture>(ref Data.TimetableNighttime, n << 1); for (int i = n; i < Data.TimetableNighttime.Length; i++) { Data.TimetableNighttime[i] = null; } } string f = OpenBveApi.Path.CombineFile(TrainPath, Arguments[0]); if (!System.IO.File.Exists(f)) { f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); } if (System.IO.File.Exists(f)) { Textures.RegisterTexture(f, out Data.TimetableNighttime[CommandIndex1]); } } } } } break; // structure case "structure.rail": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.Rail.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.Rail, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.Rail[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.beacon": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "BeaconStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.Beacon.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.Beacon, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.Beacon[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.pole": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "AdditionalRailsCovered is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (CommandIndex2 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "PoleStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.Poles.Length) { Array.Resize<ObjectManager.UnifiedObject[]>(ref Data.Structure.Poles, CommandIndex1 + 1); } if (Data.Structure.Poles[CommandIndex1] == null) { Data.Structure.Poles[CommandIndex1] = new ObjectManager.UnifiedObject[CommandIndex2 + 1]; } else if (CommandIndex2 >= Data.Structure.Poles[CommandIndex1].Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.Poles[CommandIndex1], CommandIndex2 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.Poles[CommandIndex1][CommandIndex2] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.ground": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "GroundStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.Ground.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.Ground, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.Ground[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.walll": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "WallStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.WallL.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.WallL, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.WallL[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.wallr": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "WallStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.WallR.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.WallR, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.WallR[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.dikel": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "DikeStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.DikeL.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.DikeL, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.DikeL[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.diker": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "DikeStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.DikeR.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.DikeR, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.DikeR[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.forml": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.FormL.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.FormL, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.FormL[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.formr": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.FormR.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.FormR, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.FormR[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; case "structure.formcl": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.FormCL.Length) { Array.Resize<ObjectManager.StaticObject>(ref Data.Structure.FormCL, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.FormCL[CommandIndex1] = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, true, false, false); } } } } } break; case "structure.formcr": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.FormCR.Length) { Array.Resize<ObjectManager.StaticObject>(ref Data.Structure.FormCR, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.FormCR[CommandIndex1] = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, true, false, false); } } } } } break; case "structure.roofl": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 == 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex was omitted or is 0 in " + Command + " argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); CommandIndex1 = 1; } if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is expected to be non-negativ in " + Command + " argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.RoofL.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.RoofL, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.RoofL[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } } break; case "structure.roofr": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 == 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex was omitted or is 0 in " + Command + " argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); CommandIndex1 = 1; } if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is expected to be non-negativ in " + Command + " argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.RoofR.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.RoofR, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.RoofR[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } } break; case "structure.roofcl": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 == 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex was omitted or is 0 in " + Command + " argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); CommandIndex1 = 1; } if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is expected to be non-negativ in " + Command + " argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.RoofCL.Length) { Array.Resize<ObjectManager.StaticObject>(ref Data.Structure.RoofCL, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.RoofCL[CommandIndex1] = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, true, false, false); } } } } } } break; case "structure.roofcr": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 == 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex was omitted or is 0 in " + Command + " argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); CommandIndex1 = 1; } if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is expected to be non-negativ in " + Command + " argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.RoofCR.Length) { Array.Resize<ObjectManager.StaticObject>(ref Data.Structure.RoofCR, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.RoofCR[CommandIndex1] = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, true, false, false); } } } } } } break; case "structure.crackl": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "CrackStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.CrackL.Length) { Array.Resize<ObjectManager.StaticObject>(ref Data.Structure.CrackL, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.CrackL[CommandIndex1] = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, true, false, false); } } } } } break; case "structure.crackr": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "CrackStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.CrackR.Length) { Array.Resize<ObjectManager.StaticObject>(ref Data.Structure.CrackR, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.CrackR[CommandIndex1] = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, true, false, false); } } } } } break; case "structure.freeobj": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "FreeObjStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Structure.FreeObj.Length) { Array.Resize<ObjectManager.UnifiedObject>(ref Data.Structure.FreeObj, CommandIndex1 + 1); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " could not be found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Structure.FreeObj[CommandIndex1] = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); } } } } } break; // signal case "signal": { if (!PreviewOnly) { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have between 1 and 2 arguments at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.SignalData.Length) { Array.Resize<SignalData>(ref Data.SignalData, CommandIndex1 + 1); } if (Arguments[0].EndsWith(".animated", StringComparison.OrdinalIgnoreCase)) { if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "AnimatedObjectFile contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length > 1) { Interface.AddMessage(Interface.MessageType.Warning, false, Command + " is expected to have exactly 1 argument when using animated objects at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "SignalFileWithoutExtension " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { ObjectManager.UnifiedObject Object = ObjectManager.LoadObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); if (Object is ObjectManager.AnimatedObjectCollection) { AnimatedObjectSignalData Signal = new AnimatedObjectSignalData(); Signal.Objects = (ObjectManager.AnimatedObjectCollection)Object; Data.SignalData[CommandIndex1] = Signal; } else { Interface.AddMessage(Interface.MessageType.Error, true, "GlowFileWithoutExtension " + f + " is not a valid animated object in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } } } } else { if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "SignalFileWithoutExtension contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Arguments.Length > 2) { Interface.AddMessage(Interface.MessageType.Warning, false, Command + " is expected to have between 1 and 2 arguments at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } string f = System.IO.Path.Combine(ObjectPath, Arguments[0]); Bve4SignalData Signal = new Bve4SignalData(); Signal.BaseObject = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); Signal.GlowObject = null; string Folder = System.IO.Path.GetDirectoryName(f); if (!System.IO.Directory.Exists(Folder)) { Interface.AddMessage(Interface.MessageType.Error, true, "The folder " + Folder + " could not be found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Signal.SignalTextures = LoadAllTextures(f, false); Signal.GlowTextures = new Textures.Texture[] { }; if (Arguments.Length >= 2 && Arguments[1].Length != 0) { if (Interface.ContainsInvalidPathChars(Arguments[1])) { Interface.AddMessage(Interface.MessageType.Error, false, "GlowFileWithoutExtension contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { f = System.IO.Path.Combine(ObjectPath, Arguments[1]); Signal.GlowObject = ObjectManager.LoadStaticObject(f, Encoding, ObjectManager.ObjectLoadMode.Normal, false, false, false); if (Signal.GlowObject != null) { Signal.GlowTextures = LoadAllTextures(f, true); for (int p = 0; p < Signal.GlowObject.Mesh.Materials.Length; p++) { Signal.GlowObject.Mesh.Materials[p].BlendMode = World.MeshMaterialBlendMode.Additive; Signal.GlowObject.Mesh.Materials[p].GlowAttenuationData = World.GetGlowAttenuationData(200.0, World.GlowAttenuationMode.DivisionExponent4); } } } } Data.SignalData[CommandIndex1] = Signal; } } } } } } break; // texture case "texture.background": case "structure.back": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "BackgroundTextureIndex is expected to be non-negative at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Backgrounds.Length) { int a = Data.Backgrounds.Length; Array.Resize<World.Background>(ref Data.Backgrounds, CommandIndex1 + 1); for (int k = a; k <= CommandIndex1; k++) { Data.Backgrounds[k] = new World.Background(null, 6, false); } } string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Textures.RegisterTexture(f, out Data.Backgrounds[CommandIndex1].Texture); } } } } } break; case "texture.background.x": case "structure.back.x": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "BackgroundTextureIndex is expected to be non-negative at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Backgrounds.Length) { int a = Data.Backgrounds.Length; Array.Resize<World.Background>(ref Data.Backgrounds, CommandIndex1 + 1); for (int k = a; k <= CommandIndex1; k++) { Data.Backgrounds[k] = new World.Background(null, 6, false); } } int x; if (!Interface.TryParseIntVb6(Arguments[0], out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "BackgroundTextureIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (x == 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RepetitionCount is expected to be non-zero in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Backgrounds[CommandIndex1].Repetition = x; } } } } break; case "texture.background.aspect": case "structure.back.aspect": { if (!PreviewOnly) { if (CommandIndex1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "BackgroundTextureIndex is expected to be non-negative at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (CommandIndex1 >= Data.Backgrounds.Length) { int a = Data.Backgrounds.Length; Array.Resize<World.Background>(ref Data.Backgrounds, CommandIndex1 + 1); for (int k = a; k <= CommandIndex1; k++) { Data.Backgrounds[k] = new World.Background(null, 6, false); } } int aspect; if (!Interface.TryParseIntVb6(Arguments[0], out aspect)) { Interface.AddMessage(Interface.MessageType.Error, false, "BackgroundTextureIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (aspect != 0 & aspect != 1) { Interface.AddMessage(Interface.MessageType.Error, false, "Value is expected to be either 0 or 1 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Backgrounds[CommandIndex1].KeepAspectRatio = aspect == 1; } } } } break; // cycle case "cycle.ground": if (!PreviewOnly) { if (CommandIndex1 >= Data.Structure.Cycle.Length) { Array.Resize<int[]>(ref Data.Structure.Cycle, CommandIndex1 + 1); } Data.Structure.Cycle[CommandIndex1] = new int[Arguments.Length]; for (int k = 0; k < Arguments.Length; k++) { int ix = 0; if (Arguments[k].Length > 0 && !Interface.TryParseIntVb6(Arguments[k], out ix)) { Interface.AddMessage(Interface.MessageType.Error, false, "GroundStructureIndex" + (k + 1).ToString(Culture) + " is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); ix = 0; } if (ix < 0 | ix >= Data.Structure.Ground.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "GroundStructureIndex" + (k + 1).ToString(Culture) + " is out of range in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); ix = 0; } Data.Structure.Cycle[CommandIndex1][k] = ix; } } break; } } } } } // process track namespace for (int j = 0; j < Expressions.Length; j++) { Loading.RouteProgress = 0.3333 + (double)j * progressFactor; if ((j & 255) == 0) { System.Threading.Thread.Sleep(1); if (Loading.Cancel) return; } if (Expressions[j].Text.StartsWith("[") & Expressions[j].Text.EndsWith("]")) { Section = Expressions[j].Text.Substring(1, Expressions[j].Text.Length - 2).Trim(); if (string.Compare(Section, "object", StringComparison.OrdinalIgnoreCase) == 0) { Section = "Structure"; } else if (string.Compare(Section, "railway", StringComparison.OrdinalIgnoreCase) == 0) { Section = "Track"; } SectionAlwaysPrefix = true; } else { // find equals int Equals = Expressions[j].Text.IndexOf('='); if (Equals >= 0) { // handle RW cycle syntax string t = Expressions[j].Text.Substring(0, Equals); if (Section.ToLowerInvariant() == "cycle" & SectionAlwaysPrefix) { double b; if (Interface.TryParseDoubleVb6(t, out b)) { t = ".Ground(" + t + ")"; } } else if (Section.ToLowerInvariant() == "signal" & SectionAlwaysPrefix) { double b; if (Interface.TryParseDoubleVb6(t, out b)) { t = ".Void(" + t + ")"; } } // convert RW style into CSV style Expressions[j].Text = t + " " + Expressions[j].Text.Substring(Equals + 1); } // separate command and arguments string Command, ArgumentSequence; SeparateCommandsAndArguments(Expressions[j], out Command, out ArgumentSequence, Culture, Expressions[j].File, j, false); // process command double Number; bool NumberCheck = !IsRW || string.Compare(Section, "track", StringComparison.OrdinalIgnoreCase) == 0; if (NumberCheck && Interface.TryParseDouble(Command, UnitOfLength, out Number)) { // track position if (ArgumentSequence.Length != 0) { Interface.AddMessage(Interface.MessageType.Error, false, "A track position must not contain any arguments at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Number < 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "Negative track position encountered at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.TrackPosition = Number; BlockIndex = (int)Math.Floor(Number / Data.BlockInterval + 0.001); if (Data.FirstUsedBlock == -1) Data.FirstUsedBlock = BlockIndex; CreateMissingBlocks(ref Data, ref BlocksUsed, BlockIndex, PreviewOnly); } } else { // split arguments string[] Arguments; { int n = 0; for (int k = 0; k < ArgumentSequence.Length; k++) { if (IsRW & ArgumentSequence[k] == ',') { n++; } else if (ArgumentSequence[k] == ';') { n++; } } Arguments = new string[n + 1]; int a = 0, h = 0; for (int k = 0; k < ArgumentSequence.Length; k++) { if (IsRW & ArgumentSequence[k] == ',') { Arguments[h] = ArgumentSequence.Substring(a, k - a).Trim(); a = k + 1; h++; } else if (ArgumentSequence[k] == ';') { Arguments[h] = ArgumentSequence.Substring(a, k - a).Trim(); a = k + 1; h++; } } if (ArgumentSequence.Length - a > 0) { Arguments[h] = ArgumentSequence.Substring(a).Trim(); h++; } Array.Resize<string>(ref Arguments, h); } // preprocess command if (Command.ToLowerInvariant() == "with") { if (Arguments.Length >= 1) { Section = Arguments[0]; SectionAlwaysPrefix = false; } else { Section = ""; SectionAlwaysPrefix = false; } Command = null; } else { if (Command.StartsWith(".")) { Command = Section + Command; } else if (SectionAlwaysPrefix) { Command = Section + "." + Command; } Command = Command.Replace(".Void", ""); if (Command.StartsWith("structure", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 5).TrimEnd(); } else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 5).TrimEnd(); } else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".x", StringComparison.OrdinalIgnoreCase)) { Command = "texture.background.x" + Command.Substring(18, Command.Length - 20).TrimEnd(); } else if (Command.StartsWith("texture.background", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".aspect", StringComparison.OrdinalIgnoreCase)) { Command = "texture.background.aspect" + Command.Substring(18, Command.Length - 25).TrimEnd(); } else if (Command.StartsWith("structure.back", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".x", StringComparison.OrdinalIgnoreCase)) { Command = "texture.background.x" + Command.Substring(14, Command.Length - 16).TrimEnd(); } else if (Command.StartsWith("structure.back", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".aspect", StringComparison.OrdinalIgnoreCase)) { Command = "texture.background.aspect" + Command.Substring(14, Command.Length - 21).TrimEnd(); } else if (Command.StartsWith("cycle", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".params", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 7).TrimEnd(); } else if (Command.StartsWith("signal", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".load", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 5).TrimEnd(); } else if (Command.StartsWith("train.run", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 4).TrimEnd(); } else if (Command.StartsWith("train.flange", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 4).TrimEnd(); } else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".day.load", StringComparison.OrdinalIgnoreCase)) { Command = "train.timetable.day" + Command.Substring(15, Command.Length - 24).Trim(); } else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".night.load", StringComparison.OrdinalIgnoreCase)) { Command = "train.timetable.night" + Command.Substring(15, Command.Length - 26).Trim(); } else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".day", StringComparison.OrdinalIgnoreCase)) { Command = "train.timetable.day" + Command.Substring(15, Command.Length - 19).Trim(); } else if (Command.StartsWith("train.timetable", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".night", StringComparison.OrdinalIgnoreCase)) { Command = "train.timetable.night" + Command.Substring(15, Command.Length - 21).Trim(); } else if (Command.StartsWith("route.signal", StringComparison.OrdinalIgnoreCase) & Command.EndsWith(".set", StringComparison.OrdinalIgnoreCase)) { Command = Command.Substring(0, Command.Length - 4).TrimEnd(); } } // handle indices int CommandIndex1 = 0, CommandIndex2 = 0; if (Command != null && Command.EndsWith(")")) { for (int k = Command.Length - 2; k >= 0; k--) { if (Command[k] == '(') { string Indices = Command.Substring(k + 1, Command.Length - k - 2).TrimStart(); Command = Command.Substring(0, k).TrimEnd(); int h = Indices.IndexOf(";"); if (h >= 0) { string a = Indices.Substring(0, h).TrimEnd(); string b = Indices.Substring(h + 1).TrimStart(); if (a.Length > 0 && !Interface.TryParseIntVb6(a, out CommandIndex1)) { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid first index appeared at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File + "."); Command = null; break; } else if (b.Length > 0 && !Interface.TryParseIntVb6(b, out CommandIndex2)) { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid second index appeared at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File + "."); Command = null; break; } } else { if (Indices.Length > 0 && !Interface.TryParseIntVb6(Indices, out CommandIndex1)) { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid index appeared at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File + "."); Command = null; break; } } break; } } } // process command if (Command != null && Command.Length != 0) { switch (Command.ToLowerInvariant()) { // non-track case "options.blocklength": case "options.unitoflength": case "options.unitofspeed": case "options.objectvisibility": case "options.sectionbehavior": case "options.fogbehavior": case "options.cantbehavior": case "route.comment": case "route.image": case "route.timetable": case "route.change": case "route.gauge": case "train.gauge": case "route.signal": case "route.runinterval": case "train.interval": case "route.accelerationduetogravity": case "route.elevation": case "route.temperature": case "route.pressure": case "route.ambientlight": case "route.directionallight": case "route.lightdirection": case "route.developerid": case "train.folder": case "train.file": case "train.run": case "train.rail": case "train.flange": case "train.timetable.day": case "train.timetable.night": case "train.velocity": case "train.acceleration": case "train.station": case "structure.rail": case "structure.beacon": case "structure.pole": case "structure.ground": case "structure.walll": case "structure.wallr": case "structure.dikel": case "structure.diker": case "structure.forml": case "structure.formr": case "structure.formcl": case "structure.formcr": case "structure.roofl": case "structure.roofr": case "structure.roofcl": case "structure.roofcr": case "structure.crackl": case "structure.crackr": case "structure.freeobj": case "signal": case "texture.background": case "structure.back": case "structure.back.x": case "structure.back.aspect": case "texture.background.x": case "texture.background.aspect": case "cycle.ground": break; // track case "track.railstart": case "track.rail": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 1) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be positive in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (string.Compare(Command, "track.railstart", StringComparison.OrdinalIgnoreCase) == 0) { if (idx < Data.Blocks[BlockIndex].Rail.Length && Data.Blocks[BlockIndex].Rail[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is required to reference a non-existing rail in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } } if (Data.Blocks[BlockIndex].Rail.Length <= idx) { Array.Resize<Rail>(ref Data.Blocks[BlockIndex].Rail, idx + 1); } if (Data.Blocks[BlockIndex].Rail[idx].RailStartRefreshed) { Data.Blocks[BlockIndex].Rail[idx].RailEnd = true; } { Data.Blocks[BlockIndex].Rail[idx].RailStart = true; Data.Blocks[BlockIndex].Rail[idx].RailStartRefreshed = true; if (Arguments.Length >= 2) { if (Arguments[1].Length > 0) { double x; if (!Interface.TryParseDoubleVb6(Arguments[1], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } Data.Blocks[BlockIndex].Rail[idx].RailStartX = x; } if (!Data.Blocks[BlockIndex].Rail[idx].RailEnd) { Data.Blocks[BlockIndex].Rail[idx].RailEndX = Data.Blocks[BlockIndex].Rail[idx].RailStartX; } } if (Arguments.Length >= 3) { if (Arguments[2].Length > 0) { double y; if (!Interface.TryParseDoubleVb6(Arguments[2], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } Data.Blocks[BlockIndex].Rail[idx].RailStartY = y; } if (!Data.Blocks[BlockIndex].Rail[idx].RailEnd) { Data.Blocks[BlockIndex].Rail[idx].RailEndY = Data.Blocks[BlockIndex].Rail[idx].RailStartY; } } if (Data.Blocks[BlockIndex].RailType.Length <= idx) { Array.Resize<int>(ref Data.Blocks[BlockIndex].RailType, idx + 1); } if (Arguments.Length >= 4 && Arguments[3].Length != 0) { int sttype; if (!Interface.TryParseIntVb6(Arguments[3], out sttype)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailStructureIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } if (sttype < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailStructureIndex is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (sttype >= Data.Structure.Rail.Length || Data.Structure.Rail[sttype] == null) { Interface.AddMessage(Interface.MessageType.Error, false, "RailStructureIndex references an object not loaded in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Blocks[BlockIndex].RailType[idx] = sttype; } } } } } } break; case "track.railend": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 0 || idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex references a non-existing rail in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Data.Blocks[BlockIndex].RailType.Length <= idx) { Array.Resize<Rail>(ref Data.Blocks[BlockIndex].Rail, idx + 1); } Data.Blocks[BlockIndex].Rail[idx].RailStart = false; Data.Blocks[BlockIndex].Rail[idx].RailStartRefreshed = false; Data.Blocks[BlockIndex].Rail[idx].RailEnd = true; if (Arguments.Length >= 2 && Arguments[1].Length > 0) { double x; if (!Interface.TryParseDoubleVb6(Arguments[1], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } Data.Blocks[BlockIndex].Rail[idx].RailEndX = x; } if (Arguments.Length >= 3 && Arguments[2].Length > 0) { double y; if (!Interface.TryParseDoubleVb6(Arguments[2], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } Data.Blocks[BlockIndex].Rail[idx].RailEndY = y; } } } } break; case "track.railtype": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } int sttype = 0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out sttype)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailStructureIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex could be out of range in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (sttype < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailStructureIndex is expected to be non-negativ in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (sttype >= Data.Structure.Rail.Length || Data.Structure.Rail[sttype] == null) { Interface.AddMessage(Interface.MessageType.Error, false, "RailStructureIndex references an object not loaded in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Data.Blocks[BlockIndex].RailType.Length <= idx) { Array.Resize<int>(ref Data.Blocks[BlockIndex].RailType, idx + 1); } Data.Blocks[BlockIndex].RailType[idx] = sttype; } } } } break; case "track.accuracy": { double r = 2.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out r)) { Interface.AddMessage(Interface.MessageType.Error, false, "Value is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); r = 2.0; } if (r < 0.0) { r = 0.0; } else if (r > 4.0) { r = 4.0; } Data.Blocks[BlockIndex].Accuracy = r; } break; case "track.pitch": { double p = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out p)) { Interface.AddMessage(Interface.MessageType.Error, false, "ValueInPermille is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); p = 0.0; } Data.Blocks[BlockIndex].Pitch = 0.001 * p; } break; case "track.curve": { double radius = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], UnitOfLength, out radius)) { Interface.AddMessage(Interface.MessageType.Error, false, "Radius is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); radius = 0.0; } double cant = 0.0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], out cant)) { Interface.AddMessage(Interface.MessageType.Error, false, "CantInMillimeters is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); cant = 0.0; } else { cant *= 0.001; } if (Data.SignedCant) { if (radius != 0.0) { cant *= (double)Math.Sign(radius); } } else { cant = Math.Abs(cant) * (double)Math.Sign(radius); } Data.Blocks[BlockIndex].CurrentTrackState.CurveRadius = radius; Data.Blocks[BlockIndex].CurrentTrackState.CurveCant = cant; Data.Blocks[BlockIndex].CurrentTrackState.CurveCantTangent = 0.0; } break; case "track.turn": { double s = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out s)) { Interface.AddMessage(Interface.MessageType.Error, false, "Ratio is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); s = 0.0; } Data.Blocks[BlockIndex].Turn = s; } break; case "track.adhesion": { double a = 100.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out a)) { Interface.AddMessage(Interface.MessageType.Error, false, "Value is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); a = 100.0; } if (a < 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "Value is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); a = 100.0; } Data.Blocks[BlockIndex].AdhesionMultiplier = 0.01 * a; } break; case "track.brightness": { if (!PreviewOnly) { float value = 255.0f; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseFloatVb6(Arguments[0], out value)) { Interface.AddMessage(Interface.MessageType.Error, false, "Value is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); value = 255.0f; } value /= 255.0f; if (value < 0.0f) value = 0.0f; if (value > 1.0f) value = 1.0f; int n = Data.Blocks[BlockIndex].Brightness.Length; Array.Resize<Brightness>(ref Data.Blocks[BlockIndex].Brightness, n + 1); Data.Blocks[BlockIndex].Brightness[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Brightness[n].Value = value; } } break; case "track.fog": { if (!PreviewOnly) { double start = 0.0, end = 0.0; int r = 128, g = 128, b = 128; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out start)) { Interface.AddMessage(Interface.MessageType.Error, false, "StartingDistance is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); start = 0.0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], out end)) { Interface.AddMessage(Interface.MessageType.Error, false, "EndingDistance is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); end = 0.0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out r)) { Interface.AddMessage(Interface.MessageType.Error, false, "RedValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); r = 128; } else if (r < 0 | r > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "RedValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); r = r < 0 ? 0 : 255; } if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseIntVb6(Arguments[3], out g)) { Interface.AddMessage(Interface.MessageType.Error, false, "GreenValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); g = 128; } else if (g < 0 | g > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "GreenValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); g = g < 0 ? 0 : 255; } if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !Interface.TryParseIntVb6(Arguments[4], out b)) { Interface.AddMessage(Interface.MessageType.Error, false, "BlueValue is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); b = 128; } else if (b < 0 | b > 255) { Interface.AddMessage(Interface.MessageType.Error, false, "BlueValue is required to be within the range from 0 to 255 in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); b = b < 0 ? 0 : 255; } if (start < end) { Data.Blocks[BlockIndex].Fog.Start = (float)start; Data.Blocks[BlockIndex].Fog.End = (float)end; } else { Data.Blocks[BlockIndex].Fog.Start = Game.NoFogStart; Data.Blocks[BlockIndex].Fog.End = Game.NoFogEnd; } Data.Blocks[BlockIndex].Fog.Color = new Color24((byte)r, (byte)g, (byte)b); Data.Blocks[BlockIndex].FogDefined = true; } } break; case "track.section": case "track.sections": { if (!PreviewOnly) { if (Arguments.Length == 0) { Interface.AddMessage(Interface.MessageType.Error, false, "At least one argument is required in " + Command + "at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { int[] aspects = new int[Arguments.Length]; for (int i = 0; i < Arguments.Length; i++) { if (!Interface.TryParseIntVb6(Arguments[i], out aspects[i])) { Interface.AddMessage(Interface.MessageType.Error, false, "Aspect" + i.ToString(Culture) + " is invalid in " + Command + "at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); aspects[i] = -1; } else if (aspects[i] < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "Aspect" + i.ToString(Culture) + " is expected to be non-negative in " + Command + "at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); aspects[i] = -1; } } bool valueBased = ValueBasedSections | string.Equals(Command, "Track.SectionS", StringComparison.OrdinalIgnoreCase); if (valueBased) { Array.Sort<int>(aspects); } int n = Data.Blocks[BlockIndex].Section.Length; Array.Resize<Section>(ref Data.Blocks[BlockIndex].Section, n + 1); Data.Blocks[BlockIndex].Section[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Section[n].Aspects = aspects; Data.Blocks[BlockIndex].Section[n].Type = valueBased ? Game.SectionType.ValueBased : Game.SectionType.IndexBased; Data.Blocks[BlockIndex].Section[n].DepartureStationIndex = -1; if (CurrentStation >= 0 && Game.Stations[CurrentStation].ForceStopSignal) { if (CurrentStation >= 0 & CurrentStop >= 0 & !DepartureSignalUsed) { Data.Blocks[BlockIndex].Section[n].DepartureStationIndex = CurrentStation; DepartureSignalUsed = true; } } CurrentSection++; } } } break; case "track.sigf": { if (!PreviewOnly) { int objidx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out objidx)) { Interface.AddMessage(Interface.MessageType.Error, false, "SignalIndex is invalid in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); objidx = 0; } if (objidx >= 0 & objidx < Data.SignalData.Length && Data.SignalData[objidx] != null) { int section = 0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out section)) { Interface.AddMessage(Interface.MessageType.Error, false, "Section is invalid in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); section = 0; } double x = 0.0, y = 0.0; if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[2], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[3], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } double yaw = 0.0, pitch = 0.0, roll = 0.0; if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[4], out yaw)) { Interface.AddMessage(Interface.MessageType.Error, false, "Yaw is invalid in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); yaw = 0.0; } if (Arguments.Length >= 6 && Arguments[5].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[5], out pitch)) { Interface.AddMessage(Interface.MessageType.Error, false, "Pitch is invalid in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); pitch = 0.0; } if (Arguments.Length >= 7 && Arguments[6].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[6], out roll)) { Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } int n = Data.Blocks[BlockIndex].Signal.Length; Array.Resize<Signal>(ref Data.Blocks[BlockIndex].Signal, n + 1); Data.Blocks[BlockIndex].Signal[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Signal[n].Section = CurrentSection + section; Data.Blocks[BlockIndex].Signal[n].SignalCompatibilityObjectIndex = -1; Data.Blocks[BlockIndex].Signal[n].SignalObjectIndex = objidx; Data.Blocks[BlockIndex].Signal[n].X = x; Data.Blocks[BlockIndex].Signal[n].Y = y < 0.0 ? 4.8 : y; Data.Blocks[BlockIndex].Signal[n].Yaw = 0.0174532925199433 * yaw; Data.Blocks[BlockIndex].Signal[n].Pitch = 0.0174532925199433 * pitch; Data.Blocks[BlockIndex].Signal[n].Roll = 0.0174532925199433 * roll; Data.Blocks[BlockIndex].Signal[n].ShowObject = true; Data.Blocks[BlockIndex].Signal[n].ShowPost = y < 0.0; Data.Blocks[BlockIndex].Signal[n].GameSignalIndex = -1; } else { Interface.AddMessage(Interface.MessageType.Error, false, "SignalIndex references a signal object not loaded in Track.SigF at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } } } break; case "track.signal": case "track.sig": { if (!PreviewOnly) { int num = -2; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out num)) { Interface.AddMessage(Interface.MessageType.Error, false, "Aspects is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); num = -2; } if (num != -2 & num != 2 & num != 3 & num != -4 & num != 4 & num != -5 & num != 5 & num != 6) { Interface.AddMessage(Interface.MessageType.Error, false, "Aspects has an unsupported value in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); num = num == -3 | num == -6 ? -num : -4; } double x = 0.0, y = 0.0; if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[2], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[3], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } double yaw = 0.0, pitch = 0.0, roll = 0.0; if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[4], out yaw)) { Interface.AddMessage(Interface.MessageType.Error, false, "Yaw is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); yaw = 0.0; } if (Arguments.Length >= 6 && Arguments[5].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[5], out pitch)) { Interface.AddMessage(Interface.MessageType.Error, false, "Pitch is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); pitch = 0.0; } if (Arguments.Length >= 7 && Arguments[6].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[6], out roll)) { Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } int[] aspects; int comp; switch (num) { case 2: aspects = new int[] { 0, 2 }; comp = 0; break; case -2: aspects = new int[] { 0, 4 }; comp = 1; break; case 3: aspects = new int[] { 0, 2, 4 }; comp = 2; break; case 4: aspects = new int[] { 0, 1, 2, 4 }; comp = 3; break; case -4: aspects = new int[] { 0, 2, 3, 4 }; comp = 4; break; case 5: aspects = new int[] { 0, 1, 2, 3, 4 }; comp = 5; break; case -5: aspects = new int[] { 0, 2, 3, 4, 5 }; comp = 6; break; case 6: aspects = new int[] { 0, 1, 2, 3, 4, 5 }; comp = 7; break; default: aspects = new int[] { 0, 2 }; comp = 0; break; } int n = Data.Blocks[BlockIndex].Section.Length; Array.Resize<Section>(ref Data.Blocks[BlockIndex].Section, n + 1); Data.Blocks[BlockIndex].Section[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Section[n].Aspects = aspects; Data.Blocks[BlockIndex].Section[n].DepartureStationIndex = -1; Data.Blocks[BlockIndex].Section[n].Invisible = x == 0.0; Data.Blocks[BlockIndex].Section[n].Type = Game.SectionType.ValueBased; if (CurrentStation >= 0 && Game.Stations[CurrentStation].ForceStopSignal) { if (CurrentStation >= 0 & CurrentStop >= 0 & !DepartureSignalUsed) { Data.Blocks[BlockIndex].Section[n].DepartureStationIndex = CurrentStation; DepartureSignalUsed = true; } } CurrentSection++; n = Data.Blocks[BlockIndex].Signal.Length; Array.Resize<Signal>(ref Data.Blocks[BlockIndex].Signal, n + 1); Data.Blocks[BlockIndex].Signal[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Signal[n].Section = CurrentSection; Data.Blocks[BlockIndex].Signal[n].SignalCompatibilityObjectIndex = comp; Data.Blocks[BlockIndex].Signal[n].SignalObjectIndex = -1; Data.Blocks[BlockIndex].Signal[n].X = x; Data.Blocks[BlockIndex].Signal[n].Y = y < 0.0 ? 4.8 : y; Data.Blocks[BlockIndex].Signal[n].Yaw = 0.0174532925199433 * yaw; Data.Blocks[BlockIndex].Signal[n].Pitch = 0.0174532925199433 * pitch; Data.Blocks[BlockIndex].Signal[n].Roll = 0.0174532925199433 * roll; Data.Blocks[BlockIndex].Signal[n].ShowObject = x != 0.0; Data.Blocks[BlockIndex].Signal[n].ShowPost = x != 0.0 & y < 0.0; Data.Blocks[BlockIndex].Signal[n].GameSignalIndex = -1; } } break; case "track.relay": { if (!PreviewOnly) { double x = 0.0, y = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in Track.Relay at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in Track.Relay at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } double yaw = 0.0, pitch = 0.0, roll = 0.0; if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[2], out yaw)) { Interface.AddMessage(Interface.MessageType.Error, false, "Yaw is invalid in Track.Relay at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); yaw = 0.0; } if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[3], out pitch)) { Interface.AddMessage(Interface.MessageType.Error, false, "Pitch is invalid in Track.Relay at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); pitch = 0.0; } if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[4], out roll)) { Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in Track.Relay at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } int n = Data.Blocks[BlockIndex].Signal.Length; Array.Resize<Signal>(ref Data.Blocks[BlockIndex].Signal, n + 1); Data.Blocks[BlockIndex].Signal[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Signal[n].Section = CurrentSection + 1; Data.Blocks[BlockIndex].Signal[n].SignalCompatibilityObjectIndex = 8; Data.Blocks[BlockIndex].Signal[n].SignalObjectIndex = -1; Data.Blocks[BlockIndex].Signal[n].X = x; Data.Blocks[BlockIndex].Signal[n].Y = y < 0.0 ? 4.8 : y; Data.Blocks[BlockIndex].Signal[n].Yaw = yaw * 0.0174532925199433; Data.Blocks[BlockIndex].Signal[n].Pitch = pitch * 0.0174532925199433; Data.Blocks[BlockIndex].Signal[n].Roll = roll * 0.0174532925199433; Data.Blocks[BlockIndex].Signal[n].ShowObject = x != 0.0; Data.Blocks[BlockIndex].Signal[n].ShowPost = x != 0.0 & y < 0.0; } } break; case "track.beacon": { if (!PreviewOnly) { int type = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out type)) { Interface.AddMessage(Interface.MessageType.Error, false, "Type is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); type = 0; } if (type < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "Type is expected to be non-positive in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { int structure = 0, section = 0, optional = 0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out structure)) { Interface.AddMessage(Interface.MessageType.Error, false, "BeaconStructureIndex is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); structure = 0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out section)) { Interface.AddMessage(Interface.MessageType.Error, false, "Section is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); section = 0; } if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseIntVb6(Arguments[3], out optional)) { Interface.AddMessage(Interface.MessageType.Error, false, "Data is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); optional = 0; } if (structure < -1) { Interface.AddMessage(Interface.MessageType.Error, false, "BeaconStructureIndex is expected to be non-negative or -1 in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); structure = -1; } else if (structure >= 0 && (structure >= Data.Structure.Beacon.Length || Data.Structure.Beacon[structure] == null)) { Interface.AddMessage(Interface.MessageType.Error, false, "BeaconStructureIndex references an object not loaded in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); structure = -1; } if (section == -1) { //section = (int)TrackManager.TransponderSpecialSection.NextRedSection; } else if (section < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "Section is expected to be non-negative or -1 in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); section = CurrentSection + 1; } else { section += CurrentSection; } double x = 0.0, y = 0.0; double yaw = 0.0, pitch = 0.0, roll = 0.0; if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[4], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } if (Arguments.Length >= 6 && Arguments[5].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[5], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } if (Arguments.Length >= 7 && Arguments[6].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[6], out yaw)) { Interface.AddMessage(Interface.MessageType.Error, false, "Yaw is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); yaw = 0.0; } if (Arguments.Length >= 8 && Arguments[7].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[7], out pitch)) { Interface.AddMessage(Interface.MessageType.Error, false, "Pitch is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); pitch = 0.0; } if (Arguments.Length >= 9 && Arguments[8].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[8], out roll)) { Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in Track.Beacon at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } int n = Data.Blocks[BlockIndex].Transponder.Length; Array.Resize<Transponder>(ref Data.Blocks[BlockIndex].Transponder, n + 1); Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Transponder[n].Type = type; Data.Blocks[BlockIndex].Transponder[n].Data = optional; Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = structure; Data.Blocks[BlockIndex].Transponder[n].Section = section; Data.Blocks[BlockIndex].Transponder[n].ShowDefaultObject = false; Data.Blocks[BlockIndex].Transponder[n].X = x; Data.Blocks[BlockIndex].Transponder[n].Y = y; Data.Blocks[BlockIndex].Transponder[n].Yaw = yaw * 0.0174532925199433; Data.Blocks[BlockIndex].Transponder[n].Pitch = pitch * 0.0174532925199433; Data.Blocks[BlockIndex].Transponder[n].Roll = roll * 0.0174532925199433; } } } break; case "track.transponder": case "track.tr": { if (!PreviewOnly) { int type = 0, oversig = 0, work = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out type)) { Interface.AddMessage(Interface.MessageType.Error, false, "Type is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); type = 0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out oversig)) { Interface.AddMessage(Interface.MessageType.Error, false, "Signals is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); oversig = 0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out work)) { Interface.AddMessage(Interface.MessageType.Error, false, "SwitchSystems is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); work = 0; } if (oversig < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "Signals is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); oversig = 0; } double x = 0.0, y = 0.0; if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[3], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[4], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } double yaw = 0.0, pitch = 0.0, roll = 0.0; if (Arguments.Length >= 6 && Arguments[5].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[5], out yaw)) { Interface.AddMessage(Interface.MessageType.Error, false, "Yaw is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); yaw = 0.0; } if (Arguments.Length >= 7 && Arguments[6].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[6], out pitch)) { Interface.AddMessage(Interface.MessageType.Error, false, "Pitch is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); pitch = 0.0; } if (Arguments.Length >= 8 && Arguments[7].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[7], out roll)) { Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } int n = Data.Blocks[BlockIndex].Transponder.Length; Array.Resize<Transponder>(ref Data.Blocks[BlockIndex].Transponder, n + 1); Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Transponder[n].Type = type; Data.Blocks[BlockIndex].Transponder[n].Data = work; Data.Blocks[BlockIndex].Transponder[n].ShowDefaultObject = true; Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; Data.Blocks[BlockIndex].Transponder[n].X = x; Data.Blocks[BlockIndex].Transponder[n].Y = y; Data.Blocks[BlockIndex].Transponder[n].Yaw = yaw * 0.0174532925199433; Data.Blocks[BlockIndex].Transponder[n].Pitch = pitch * 0.0174532925199433; Data.Blocks[BlockIndex].Transponder[n].Roll = roll * 0.0174532925199433; Data.Blocks[BlockIndex].Transponder[n].Section = CurrentSection + oversig + 1; } } break; case "track.atssn": { if (!PreviewOnly) { int n = Data.Blocks[BlockIndex].Transponder.Length; Array.Resize<Transponder>(ref Data.Blocks[BlockIndex].Transponder, n + 1); Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Transponder[n].Type = 0; Data.Blocks[BlockIndex].Transponder[n].Data = 0; Data.Blocks[BlockIndex].Transponder[n].ShowDefaultObject = true; Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; Data.Blocks[BlockIndex].Transponder[n].Section = CurrentSection + 1; } } break; case "track.atsp": { if (!PreviewOnly) { int n = Data.Blocks[BlockIndex].Transponder.Length; Array.Resize<Transponder>(ref Data.Blocks[BlockIndex].Transponder, n + 1); Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Transponder[n].Type = 3; Data.Blocks[BlockIndex].Transponder[n].Data = 0; Data.Blocks[BlockIndex].Transponder[n].ShowDefaultObject = true; Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; Data.Blocks[BlockIndex].Transponder[n].Section = CurrentSection + 1; } } break; case "track.pattern": { if (!PreviewOnly) { int type = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out type)) { Interface.AddMessage(Interface.MessageType.Error, false, "Type is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); type = 0; } double speed = 0.0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], out speed)) { Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); speed = 0.0; } int n = Data.Blocks[BlockIndex].Transponder.Length; Array.Resize<Transponder>(ref Data.Blocks[BlockIndex].Transponder, n + 1); Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; if (type == 0) { Data.Blocks[BlockIndex].Transponder[n].Type = TrackManager.SpecialTransponderTypes.InternalAtsPTemporarySpeedLimit; Data.Blocks[BlockIndex].Transponder[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); } else { Data.Blocks[BlockIndex].Transponder[n].Type = TrackManager.SpecialTransponderTypes.AtsPPermanentSpeedLimit; Data.Blocks[BlockIndex].Transponder[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); } Data.Blocks[BlockIndex].Transponder[n].Section = -1; Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; } } break; case "track.plimit": { if (!PreviewOnly) { double speed = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out speed)) { Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); speed = 0.0; } int n = Data.Blocks[BlockIndex].Transponder.Length; Array.Resize<Transponder>(ref Data.Blocks[BlockIndex].Transponder, n + 1); Data.Blocks[BlockIndex].Transponder[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Transponder[n].Type = TrackManager.SpecialTransponderTypes.AtsPPermanentSpeedLimit; Data.Blocks[BlockIndex].Transponder[n].Data = speed == 0.0 ? int.MaxValue : (int)Math.Round(speed * Data.UnitOfSpeed * 3.6); Data.Blocks[BlockIndex].Transponder[n].Section = -1; Data.Blocks[BlockIndex].Transponder[n].BeaconStructureIndex = -1; } } break; case "track.limit": { double limit = 0.0; int direction = 0, cource = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], out limit)) { Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in Track.Limit at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); limit = 0.0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out direction)) { Interface.AddMessage(Interface.MessageType.Error, false, "Direction is invalid in Track.Limit at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); direction = 0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out cource)) { Interface.AddMessage(Interface.MessageType.Error, false, "Cource is invalid in Track.Limit at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); cource = 0; } int n = Data.Blocks[BlockIndex].Limit.Length; Array.Resize<Limit>(ref Data.Blocks[BlockIndex].Limit, n + 1); Data.Blocks[BlockIndex].Limit[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Limit[n].Speed = limit <= 0.0 ? double.PositiveInfinity : Data.UnitOfSpeed * limit; Data.Blocks[BlockIndex].Limit[n].Direction = direction; Data.Blocks[BlockIndex].Limit[n].Cource = cource; } break; case "track.stop": if (CurrentStation == -1) { Interface.AddMessage(Interface.MessageType.Error, false, "A stop without a station is invalid in Track.Stop at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { int dir = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out dir)) { Interface.AddMessage(Interface.MessageType.Error, false, "Direction is invalid in Track.Stop at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dir = 0; } double backw = 5.0, forw = 5.0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], UnitOfLength, out backw)) { Interface.AddMessage(Interface.MessageType.Error, false, "BackwardTolerance is invalid in Track.Stop at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); backw = 5.0; } else if (backw <= 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "BackwardTolerance is expected to be positive in Track.Stop at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); backw = 5.0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[2], UnitOfLength, out forw)) { Interface.AddMessage(Interface.MessageType.Error, false, "ForwardTolerance is invalid in Track.Stop at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); forw = 5.0; } else if (forw <= 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "ForwardTolerance is expected to be positive in Track.Stop at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); forw = 5.0; } int cars = 0; if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseIntVb6(Arguments[3], out cars)) { Interface.AddMessage(Interface.MessageType.Error, false, "Cars is invalid in Track.Stop at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); cars = 0; } int n = Data.Blocks[BlockIndex].Stop.Length; Array.Resize<Stop>(ref Data.Blocks[BlockIndex].Stop, n + 1); Data.Blocks[BlockIndex].Stop[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Stop[n].Station = CurrentStation; Data.Blocks[BlockIndex].Stop[n].Direction = dir; Data.Blocks[BlockIndex].Stop[n].ForwardTolerance = forw; Data.Blocks[BlockIndex].Stop[n].BackwardTolerance = backw; Data.Blocks[BlockIndex].Stop[n].Cars = cars; CurrentStop = cars; } break; case "track.sta": { CurrentStation++; Array.Resize<Game.Station>(ref Game.Stations, CurrentStation + 1); Game.Stations[CurrentStation].Name = string.Empty; Game.Stations[CurrentStation].StopMode = Game.StationStopMode.AllStop; Game.Stations[CurrentStation].StationType = Game.StationType.Normal; if (Arguments.Length >= 1 && Arguments[0].Length > 0) { Game.Stations[CurrentStation].Name = Arguments[0]; } double arr = -1.0, dep = -1.0; if (Arguments.Length >= 2 && Arguments[1].Length > 0) { if (string.Equals(Arguments[1], "P", StringComparison.OrdinalIgnoreCase) | string.Equals(Arguments[1], "L", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.AllPass; } else if (string.Equals(Arguments[1], "B", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.PlayerPass; } else if (Arguments[1].StartsWith("B:", StringComparison.InvariantCultureIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.PlayerPass; if (!Interface.TryParseTime(Arguments[1].Substring(2).TrimStart(), out arr)) { Interface.AddMessage(Interface.MessageType.Error, false, "ArrivalTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); arr = -1.0; } } else if (string.Equals(Arguments[1], "S", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.PlayerStop; } else if (Arguments[1].StartsWith("S:", StringComparison.InvariantCultureIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.PlayerStop; if (!Interface.TryParseTime(Arguments[1].Substring(2).TrimStart(), out arr)) { Interface.AddMessage(Interface.MessageType.Error, false, "ArrivalTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); arr = -1.0; } } else if (!Interface.TryParseTime(Arguments[1], out arr)) { Interface.AddMessage(Interface.MessageType.Error, false, "ArrivalTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); arr = -1.0; } } if (Arguments.Length >= 3 && Arguments[2].Length > 0) { if (string.Equals(Arguments[2], "T", StringComparison.OrdinalIgnoreCase) | string.Equals(Arguments[2], "=", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StationType = Game.StationType.Terminal; } else if (Arguments[2].StartsWith("T:", StringComparison.InvariantCultureIgnoreCase)) { Game.Stations[CurrentStation].StationType = Game.StationType.Terminal; if (!Interface.TryParseTime(Arguments[2].Substring(2).TrimStart(), out dep)) { Interface.AddMessage(Interface.MessageType.Error, false, "DepartureTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dep = -1.0; } } else if (string.Equals(Arguments[2], "C", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StationType = Game.StationType.ChangeEnds; } else if (Arguments[2].StartsWith("C:", StringComparison.InvariantCultureIgnoreCase)) { Game.Stations[CurrentStation].StationType = Game.StationType.ChangeEnds; if (!Interface.TryParseTime(Arguments[2].Substring(2).TrimStart(), out dep)) { Interface.AddMessage(Interface.MessageType.Error, false, "DepartureTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dep = -1.0; } } else if (!Interface.TryParseTime(Arguments[2], out dep)) { Interface.AddMessage(Interface.MessageType.Error, false, "DepartureTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dep = -1.0; } } int passalarm = 0; if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseIntVb6(Arguments[3], out passalarm)) { Interface.AddMessage(Interface.MessageType.Error, false, "PassAlarm is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); passalarm = 0; } int door = 0; bool doorboth = false; if (Arguments.Length >= 5 && Arguments[4].Length != 0) { switch (Arguments[4].ToUpperInvariant()) { case "L": door = -1; break; case "R": door = 1; break; case "N": door = 0; break; case "B": doorboth = true; break; default: if (!Interface.TryParseIntVb6(Arguments[4], out door)) { Interface.AddMessage(Interface.MessageType.Error, false, "Doors is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); door = 0; } break; } } int stop = 0; if (Arguments.Length >= 6 && Arguments[5].Length > 0 && !Interface.TryParseIntVb6(Arguments[5], out stop)) { Interface.AddMessage(Interface.MessageType.Error, false, "ForcedRedSignal is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); stop = 0; } int device = 0; if (Arguments.Length >= 7 && Arguments[6].Length > 0) { if (string.Compare(Arguments[6], "ats", StringComparison.OrdinalIgnoreCase) == 0) { device = 0; } else if (string.Compare(Arguments[6], "atc", StringComparison.OrdinalIgnoreCase) == 0) { device = 1; } else if (!Interface.TryParseIntVb6(Arguments[6], out device)) { Interface.AddMessage(Interface.MessageType.Error, false, "System is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); device = 0; } if (device != 0 & device != 1) { Interface.AddMessage(Interface.MessageType.Error, false, "System is not supported in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); device = 0; } } Sounds.SoundBuffer arrsnd = null; Sounds.SoundBuffer depsnd = null; if (!PreviewOnly) { if (Arguments.Length >= 8 && Arguments[7].Length > 0) { if (Interface.ContainsInvalidPathChars(Arguments[7])) { Interface.AddMessage(Interface.MessageType.Error, false, "ArrivalSound contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { string f = OpenBveApi.Path.CombineFile(SoundPath, Arguments[7]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "ArrivalSound " + f + " not found in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { const double radius = 30.0; arrsnd = Sounds.RegisterBuffer(f, radius); } } } } double halt = 15.0; if (Arguments.Length >= 9 && Arguments[8].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[8], out halt)) { Interface.AddMessage(Interface.MessageType.Error, false, "StopDuration is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); halt = 15.0; } else if (halt < 5.0) { halt = 5.0; } double jam = 100.0; if (!PreviewOnly) { if (Arguments.Length >= 10 && Arguments[9].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[9], out jam)) { Interface.AddMessage(Interface.MessageType.Error, false, "PassengerRatio is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); jam = 100.0; } else if (jam < 0.0) { Interface.AddMessage(Interface.MessageType.Error, false, "PassengerRatio is expected to be non-negative in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); jam = 100.0; } } if (!PreviewOnly) { if (Arguments.Length >= 11 && Arguments[10].Length > 0) { if (Interface.ContainsInvalidPathChars(Arguments[10])) { Interface.AddMessage(Interface.MessageType.Error, false, "DepartureSound contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { string f = OpenBveApi.Path.CombineFile(SoundPath, Arguments[10]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "DepartureSound " + f + " not found in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { const double radius = 30.0; depsnd = Sounds.RegisterBuffer(f, radius); } } } } int ttidx = -1; Textures.Texture tdt = null, tnt = null; if (!PreviewOnly) { if (Arguments.Length >= 12 && Arguments[11].Length > 0) { if (!Interface.TryParseIntVb6(Arguments[11], out ttidx)) { ttidx = -1; } else { if (ttidx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "TimetableIndex is expected to be non-negative in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); ttidx = -1; } else if (ttidx >= Data.TimetableDaytime.Length & ttidx >= Data.TimetableNighttime.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "TimetableIndex references textures not loaded in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); ttidx = -1; } tdt = ttidx >= 0 & ttidx < Data.TimetableDaytime.Length ? Data.TimetableDaytime[ttidx] : null; tnt = ttidx >= 0 & ttidx < Data.TimetableNighttime.Length ? Data.TimetableNighttime[ttidx] : null; ttidx = 0; } } else { ttidx = -1; } if (ttidx == -1) { if (CurrentStation > 0) { tdt = Game.Stations[CurrentStation - 1].TimetableDaytimeTexture; tnt = Game.Stations[CurrentStation - 1].TimetableNighttimeTexture; } else if (Data.TimetableDaytime.Length > 0 & Data.TimetableNighttime.Length > 0) { tdt = Data.TimetableDaytime[0]; tnt = Data.TimetableNighttime[0]; } else { tdt = null; tnt = null; } } } if (Game.Stations[CurrentStation].Name.Length == 0 & (Game.Stations[CurrentStation].StopMode == Game.StationStopMode.PlayerStop | Game.Stations[CurrentStation].StopMode == Game.StationStopMode.AllStop)) { Game.Stations[CurrentStation].Name = "Station " + (CurrentStation + 1).ToString(Culture) + ")"; } Game.Stations[CurrentStation].ArrivalTime = arr; Game.Stations[CurrentStation].ArrivalSoundBuffer = arrsnd; Game.Stations[CurrentStation].DepartureTime = dep; Game.Stations[CurrentStation].DepartureSoundBuffer = depsnd; Game.Stations[CurrentStation].StopTime = halt; Game.Stations[CurrentStation].ForceStopSignal = stop == 1; Game.Stations[CurrentStation].OpenLeftDoors = door < 0.0 | doorboth; Game.Stations[CurrentStation].OpenRightDoors = door > 0.0 | doorboth; Game.Stations[CurrentStation].SafetySystem = device == 1 ? Game.SafetySystem.Atc : Game.SafetySystem.Ats; Game.Stations[CurrentStation].Stops = new Game.StationStop[] { }; Game.Stations[CurrentStation].PassengerRatio = 0.01 * jam; Game.Stations[CurrentStation].TimetableDaytimeTexture = tdt; Game.Stations[CurrentStation].TimetableNighttimeTexture = tnt; Game.Stations[CurrentStation].DefaultTrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Station = CurrentStation; Data.Blocks[BlockIndex].StationPassAlarm = passalarm == 1; CurrentStop = -1; DepartureSignalUsed = false; } break; case "track.station": { CurrentStation++; Array.Resize<Game.Station>(ref Game.Stations, CurrentStation + 1); Game.Stations[CurrentStation].Name = string.Empty; Game.Stations[CurrentStation].StopMode = Game.StationStopMode.AllStop; Game.Stations[CurrentStation].StationType = Game.StationType.Normal; if (Arguments.Length >= 1 && Arguments[0].Length > 0) { Game.Stations[CurrentStation].Name = Arguments[0]; } double arr = -1.0, dep = -1.0; if (Arguments.Length >= 2 && Arguments[1].Length > 0) { if (string.Equals(Arguments[1], "P", StringComparison.OrdinalIgnoreCase) | string.Equals(Arguments[1], "L", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.AllPass; } else if (string.Equals(Arguments[1], "B", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.PlayerPass; } else if (Arguments[1].StartsWith("B:", StringComparison.InvariantCultureIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.PlayerPass; if (!Interface.TryParseTime(Arguments[1].Substring(2).TrimStart(), out arr)) { Interface.AddMessage(Interface.MessageType.Error, false, "ArrivalTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); arr = -1.0; } } else if (string.Equals(Arguments[1], "S", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.PlayerStop; } else if (Arguments[1].StartsWith("S:", StringComparison.InvariantCultureIgnoreCase)) { Game.Stations[CurrentStation].StopMode = Game.StationStopMode.PlayerStop; if (!Interface.TryParseTime(Arguments[1].Substring(2).TrimStart(), out arr)) { Interface.AddMessage(Interface.MessageType.Error, false, "ArrivalTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); arr = -1.0; } } else if (!Interface.TryParseTime(Arguments[1], out arr)) { Interface.AddMessage(Interface.MessageType.Error, false, "ArrivalTime is invalid in Track.Station at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); arr = -1.0; } } if (Arguments.Length >= 3 && Arguments[2].Length > 0) { if (string.Equals(Arguments[2], "T", StringComparison.OrdinalIgnoreCase) | string.Equals(Arguments[2], "=", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StationType = Game.StationType.Terminal; } else if (Arguments[2].StartsWith("T:", StringComparison.InvariantCultureIgnoreCase)) { Game.Stations[CurrentStation].StationType = Game.StationType.Terminal; if (!Interface.TryParseTime(Arguments[2].Substring(2).TrimStart(), out dep)) { Interface.AddMessage(Interface.MessageType.Error, false, "DepartureTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dep = -1.0; } } else if (string.Equals(Arguments[2], "C", StringComparison.OrdinalIgnoreCase)) { Game.Stations[CurrentStation].StationType = Game.StationType.ChangeEnds; } else if (Arguments[2].StartsWith("C:", StringComparison.InvariantCultureIgnoreCase)) { Game.Stations[CurrentStation].StationType = Game.StationType.ChangeEnds; if (!Interface.TryParseTime(Arguments[2].Substring(2).TrimStart(), out dep)) { Interface.AddMessage(Interface.MessageType.Error, false, "DepartureTime is invalid in Track.Sta at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dep = -1.0; } } else if (!Interface.TryParseTime(Arguments[2], out dep)) { Interface.AddMessage(Interface.MessageType.Error, false, "DepartureTime is invalid in Track.Station at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dep = -1.0; } } int stop = 0; if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseIntVb6(Arguments[3], out stop)) { Interface.AddMessage(Interface.MessageType.Error, false, "ForcedRedSignal is invalid in Track.Station at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); stop = 0; } int device = 0; if (Arguments.Length >= 5 && Arguments[4].Length > 0) { if (string.Compare(Arguments[4], "ats", StringComparison.OrdinalIgnoreCase) == 0) { device = 0; } else if (string.Compare(Arguments[4], "atc", StringComparison.OrdinalIgnoreCase) == 0) { device = 1; } else if (!Interface.TryParseIntVb6(Arguments[4], out device)) { Interface.AddMessage(Interface.MessageType.Error, false, "System is invalid in Track.Station at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); device = 0; } else if (device != 0 & device != 1) { Interface.AddMessage(Interface.MessageType.Error, false, "System is not supported in Track.Station at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); device = 0; } } Sounds.SoundBuffer depsnd = null; if (!PreviewOnly) { if (Arguments.Length >= 6 && Arguments[5].Length != 0) { if (Interface.ContainsInvalidPathChars(Arguments[5])) { Interface.AddMessage(Interface.MessageType.Error, false, "DepartureSound contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { string f = OpenBveApi.Path.CombineFile(SoundPath, Arguments[5]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "DepartureSound " + f + " not found in Track.Station at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { const double radius = 30.0; depsnd = Sounds.RegisterBuffer(f, radius); } } } } if (Game.Stations[CurrentStation].Name.Length == 0 & (Game.Stations[CurrentStation].StopMode == Game.StationStopMode.PlayerStop | Game.Stations[CurrentStation].StopMode == Game.StationStopMode.AllStop)) { Game.Stations[CurrentStation].Name = "Station " + (CurrentStation + 1).ToString(Culture) + ")"; } Game.Stations[CurrentStation].ArrivalTime = arr; Game.Stations[CurrentStation].ArrivalSoundBuffer = null; Game.Stations[CurrentStation].DepartureTime = dep; Game.Stations[CurrentStation].DepartureSoundBuffer = depsnd; Game.Stations[CurrentStation].StopTime = 15.0; Game.Stations[CurrentStation].ForceStopSignal = stop == 1; Game.Stations[CurrentStation].OpenLeftDoors = true; Game.Stations[CurrentStation].OpenRightDoors = true; Game.Stations[CurrentStation].SafetySystem = device == 1 ? Game.SafetySystem.Atc : Game.SafetySystem.Ats; Game.Stations[CurrentStation].Stops = new Game.StationStop[] { }; Game.Stations[CurrentStation].PassengerRatio = 1.0; Game.Stations[CurrentStation].TimetableDaytimeTexture = null; Game.Stations[CurrentStation].TimetableNighttimeTexture = null; Game.Stations[CurrentStation].DefaultTrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].Station = CurrentStation; Data.Blocks[BlockIndex].StationPassAlarm = false; CurrentStop = -1; DepartureSignalUsed = false; } break; case "track.buffer": { if (!PreviewOnly) { int n = Game.BufferTrackPositions.Length; Array.Resize<double>(ref Game.BufferTrackPositions, n + 1); Game.BufferTrackPositions[n] = Data.TrackPosition; } } break; case "track.form": { if (!PreviewOnly) { int idx1 = 0, idx2 = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx1)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex1 is invalid in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx1 = 0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0) { if (string.Compare(Arguments[1], "L", StringComparison.OrdinalIgnoreCase) == 0) { idx2 = Form.SecondaryRailL; } else if (string.Compare(Arguments[1], "R", StringComparison.OrdinalIgnoreCase) == 0) { idx2 = Form.SecondaryRailR; } else if (IsRW && string.Compare(Arguments[1], "9X", StringComparison.OrdinalIgnoreCase) == 0) { idx2 = int.MaxValue; } else if (!Interface.TryParseIntVb6(Arguments[1], out idx2)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex2 is invalid in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx2 = 0; } } if (IsRW) { if (idx2 == int.MaxValue) { idx2 = 9; } else if (idx2 == -9) { idx2 = Form.SecondaryRailL; } else if (idx2 == 9) { idx2 = Form.SecondaryRailR; } } if (idx1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex1 is expected to be non-negative in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (idx2 < 0 & idx2 != Form.SecondaryRailStub & idx2 != Form.SecondaryRailL & idx2 != Form.SecondaryRailR) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex2 is expected to be greater or equal to -2 in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx1 >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx1].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex1 could be out of range in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (idx2 != Form.SecondaryRailStub & idx2 != Form.SecondaryRailL & idx2 != Form.SecondaryRailR && (idx2 >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx2].RailStart)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex2 could be out of range in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } int roof = 0, pf = 0; if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out roof)) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex is invalid in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roof = 0; } if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseIntVb6(Arguments[3], out pf)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex is invalid in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); pf = 0; } if (roof != 0 & (roof < 0 || (roof >= Data.Structure.RoofL.Length || Data.Structure.RoofL[roof] == null) || (roof >= Data.Structure.RoofR.Length || Data.Structure.RoofR[roof] == null))) { Interface.AddMessage(Interface.MessageType.Error, false, "RoofStructureIndex references an object not loaded in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (pf < 0 | (pf >= Data.Structure.FormL.Length || Data.Structure.FormL[pf] == null) & (pf >= Data.Structure.FormR.Length || Data.Structure.FormR[pf] == null)) { Interface.AddMessage(Interface.MessageType.Error, false, "FormStructureIndex references an object not loaded in Track.Form at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } int n = Data.Blocks[BlockIndex].Form.Length; Array.Resize<Form>(ref Data.Blocks[BlockIndex].Form, n + 1); Data.Blocks[BlockIndex].Form[n].PrimaryRail = idx1; Data.Blocks[BlockIndex].Form[n].SecondaryRail = idx2; Data.Blocks[BlockIndex].Form[n].FormType = pf; Data.Blocks[BlockIndex].Form[n].RoofType = roof; } } } } break; case "track.pole": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negative in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex could be out of range in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (idx >= Data.Blocks[BlockIndex].RailPole.Length) { Array.Resize<Pole>(ref Data.Blocks[BlockIndex].RailPole, idx + 1); Data.Blocks[BlockIndex].RailPole[idx].Mode = 0; Data.Blocks[BlockIndex].RailPole[idx].Location = 0; Data.Blocks[BlockIndex].RailPole[idx].Interval = 2.0 * Data.BlockInterval; Data.Blocks[BlockIndex].RailPole[idx].Type = 0; } int typ = Data.Blocks[BlockIndex].RailPole[idx].Mode; int sttype = Data.Blocks[BlockIndex].RailPole[idx].Type; if (Arguments.Length >= 2 && Arguments[1].Length > 0) { if (!Interface.TryParseIntVb6(Arguments[1], out typ)) { Interface.AddMessage(Interface.MessageType.Error, false, "AdditionalRailsCovered is invalid in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); typ = 0; } } if (Arguments.Length >= 3 && Arguments[2].Length > 0) { double loc; if (!Interface.TryParseDoubleVb6(Arguments[2], out loc)) { Interface.AddMessage(Interface.MessageType.Error, false, "Location is invalid in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); loc = 0.0; } Data.Blocks[BlockIndex].RailPole[idx].Location = loc; } if (Arguments.Length >= 4 && Arguments[3].Length > 0) { double dist; if (!Interface.TryParseDoubleVb6(Arguments[3], UnitOfLength, out dist)) { Interface.AddMessage(Interface.MessageType.Error, false, "Interval is invalid in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dist = Data.BlockInterval; } Data.Blocks[BlockIndex].RailPole[idx].Interval = dist; } if (Arguments.Length >= 5 && Arguments[4].Length > 0) { if (!Interface.TryParseIntVb6(Arguments[4], out sttype)) { Interface.AddMessage(Interface.MessageType.Error, false, "PoleStructureIndex is invalid in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } } if (typ < 0 || typ >= Data.Structure.Poles.Length || Data.Structure.Poles[typ] == null) { Interface.AddMessage(Interface.MessageType.Error, false, "PoleStructureIndex references an object not loaded in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (sttype < 0 || sttype >= Data.Structure.Poles[typ].Length || Data.Structure.Poles[typ][sttype] == null) { Interface.AddMessage(Interface.MessageType.Error, false, "PoleStructureIndex references an object not loaded in Track.Pole at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Blocks[BlockIndex].RailPole[idx].Mode = typ; Data.Blocks[BlockIndex].RailPole[idx].Type = sttype; Data.Blocks[BlockIndex].RailPole[idx].Exists = true; } } } } break; case "track.poleend": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in Track.PoleEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 0 | idx >= Data.Blocks[BlockIndex].RailPole.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex does not reference an existing pole in Track.PoleEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx >= Data.Blocks[BlockIndex].Rail.Length || (!Data.Blocks[BlockIndex].Rail[idx].RailStart & !Data.Blocks[BlockIndex].Rail[idx].RailEnd)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex could be out of range in Track.PoleEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } Data.Blocks[BlockIndex].RailPole[idx].Exists = false; } } } break; case "track.wall": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be a non-negative integer in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } int dir = 0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out dir)) { Interface.AddMessage(Interface.MessageType.Error, false, "Direction is invalid in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dir = 0; } int sttype = 0; if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out sttype)) { Interface.AddMessage(Interface.MessageType.Error, false, "WallStructureIndex is invalid in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } if (sttype < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "WallStructureIndex is expected to be a non-negative integer in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } if (dir <= 0 && (sttype >= Data.Structure.WallL.Length || Data.Structure.WallL[sttype] == null) || dir >= 0 && (sttype >= Data.Structure.WallR.Length || Data.Structure.WallR[sttype] == null)) { Interface.AddMessage(Interface.MessageType.Error, false, "WallStructureIndex references an object not loaded in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negative in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex could be out of range in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (idx >= Data.Blocks[BlockIndex].RailWall.Length) { Array.Resize<WallDike>(ref Data.Blocks[BlockIndex].RailWall, idx + 1); } Data.Blocks[BlockIndex].RailWall[idx].Exists = true; Data.Blocks[BlockIndex].RailWall[idx].Type = sttype; Data.Blocks[BlockIndex].RailWall[idx].Direction = dir; } } } } break; case "track.wallend": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in Track.WallEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 0 | idx >= Data.Blocks[BlockIndex].RailWall.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex does not reference an existing wall in Track.WallEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx >= Data.Blocks[BlockIndex].Rail.Length || (!Data.Blocks[BlockIndex].Rail[idx].RailStart & !Data.Blocks[BlockIndex].Rail[idx].RailEnd)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex could be out of range in Track.WallEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } Data.Blocks[BlockIndex].RailWall[idx].Exists = false; } } } break; case "track.dike": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in Track.Dike at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be a non-negative integer in Track.Dike at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } int dir = 0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out dir)) { Interface.AddMessage(Interface.MessageType.Error, false, "Direction is invalid in Track.Dike at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dir = 0; } int sttype = 0; if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out sttype)) { Interface.AddMessage(Interface.MessageType.Error, false, "DikeStructureIndex is invalid in Track.Dike at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } if (sttype < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "DikeStructureIndex is expected to be a non-negative integer in Track.Wall at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } if (dir <= 0 && (sttype >= Data.Structure.DikeL.Length || Data.Structure.DikeL[sttype] == null) || dir >= 0 && (sttype >= Data.Structure.DikeR.Length || Data.Structure.DikeR[sttype] == null)) { Interface.AddMessage(Interface.MessageType.Error, false, "DikeStructureIndex references an object not loaded in Track.Dike at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negative in Track.Dike at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex could be out of range in Track.Dike at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (idx >= Data.Blocks[BlockIndex].RailDike.Length) { Array.Resize<WallDike>(ref Data.Blocks[BlockIndex].RailDike, idx + 1); } Data.Blocks[BlockIndex].RailDike[idx].Exists = true; Data.Blocks[BlockIndex].RailDike[idx].Type = sttype; Data.Blocks[BlockIndex].RailDike[idx].Direction = dir; } } } } break; case "track.dikeend": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in Track.DikeEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 0 | idx >= Data.Blocks[BlockIndex].RailDike.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex does not reference an existing dike in Track.DikeEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx >= Data.Blocks[BlockIndex].Rail.Length || (!Data.Blocks[BlockIndex].Rail[idx].RailStart & !Data.Blocks[BlockIndex].Rail[idx].RailEnd)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex could be out of range in Track.DikeEnd at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } Data.Blocks[BlockIndex].RailDike[idx].Exists = false; } } } break; case "track.marker": { if (!PreviewOnly) { if (Arguments.Length < 1) { Interface.AddMessage(Interface.MessageType.Error, false, "Track.Marker is expected to have at least one argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { string f = OpenBveApi.Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in Track.Marker at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double dist = Data.BlockInterval; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], UnitOfLength, out dist)) { Interface.AddMessage(Interface.MessageType.Error, false, "Distance is invalid in Track.Marker at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); dist = Data.BlockInterval; } double start, end; if (dist < 0.0) { start = Data.TrackPosition; end = Data.TrackPosition - dist; } else { start = Data.TrackPosition - dist; end = Data.TrackPosition; } if (start < 0.0) start = 0.0; if (end < 0.0) end = 0.0; if (end <= start) end = start + 0.01; int n = Data.Markers.Length; Array.Resize<Marker>(ref Data.Markers, n + 1); Data.Markers[n].StartingPosition = start; Data.Markers[n].EndingPosition = end; Textures.RegisterTexture(f, new OpenBveApi.Textures.TextureParameters(null, new Color24(64, 64, 64)), out Data.Markers[n].Texture); } } } } break; case "track.height": { if (!PreviewOnly) { double h = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[0], UnitOfLength, out h)) { Interface.AddMessage(Interface.MessageType.Error, false, "Height is invalid in Track.Height at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); h = 0.0; } Data.Blocks[BlockIndex].Height = IsRW ? h + 0.3 : h; } } break; case "track.ground": { if (!PreviewOnly) { int cytype = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out cytype)) { Interface.AddMessage(Interface.MessageType.Error, false, "CycleIndex is invalid in Track.Ground at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); cytype = 0; } if (cytype < Data.Structure.Cycle.Length && Data.Structure.Cycle[cytype] != null) { Data.Blocks[BlockIndex].Cycle = Data.Structure.Cycle[cytype]; } else { if (cytype >= Data.Structure.Ground.Length || Data.Structure.Ground[cytype] == null) { Interface.AddMessage(Interface.MessageType.Error, false, "CycleIndex references an object not loaded in Track.Ground at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Blocks[BlockIndex].Cycle = new int[] { cytype }; } } } } break; case "track.crack": { if (!PreviewOnly) { int idx1 = 0, idx2 = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx1)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex1 is invalid in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx1 = 0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out idx2)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex2 is invalid in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx2 = 0; } int sttype = 0; if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseIntVb6(Arguments[2], out sttype)) { Interface.AddMessage(Interface.MessageType.Error, false, "CrackStructureIndex is invalid in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } if (sttype < 0 || (sttype >= Data.Structure.CrackL.Length || Data.Structure.CrackL[sttype] == null) || (sttype >= Data.Structure.CrackR.Length || Data.Structure.CrackR[sttype] == null)) { Interface.AddMessage(Interface.MessageType.Error, false, "CrackStructureIndex references an object not loaded in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx1 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex1 is expected to be non-negative in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (idx2 < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex2 is expected to be non-negative in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (idx1 == idx2) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex1 is expected to be unequal to Index2 in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx1 >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx1].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex1 could be out of range in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (idx2 >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx2].RailStart) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex2 could be out of range in Track.Crack at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } int n = Data.Blocks[BlockIndex].Crack.Length; Array.Resize<Crack>(ref Data.Blocks[BlockIndex].Crack, n + 1); Data.Blocks[BlockIndex].Crack[n].PrimaryRail = idx1; Data.Blocks[BlockIndex].Crack[n].SecondaryRail = idx2; Data.Blocks[BlockIndex].Crack[n].Type = sttype; } } } } break; case "track.freeobj": { if (!PreviewOnly) { int idx = 0, sttype = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseIntVb6(Arguments[1], out sttype)) { Interface.AddMessage(Interface.MessageType.Error, false, "FreeObjStructureIndex is invalid in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); sttype = 0; } if (idx < -1) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negative or -1 in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (sttype < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "FreeObjStructureIndex is expected to be non-negative in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (idx >= 0 && (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart)) { Interface.AddMessage(Interface.MessageType.Warning, false, "RailIndex could be out of range in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } if (sttype >= Data.Structure.FreeObj.Length || Data.Structure.FreeObj[sttype] == null || Data.Structure.FreeObj[sttype] == null) { Interface.AddMessage(Interface.MessageType.Error, false, "FreeObjStructureIndex references an object not loaded in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double x = 0.0, y = 0.0; double yaw = 0.0, pitch = 0.0, roll = 0.0; if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[2], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[3], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[4], out yaw)) { Interface.AddMessage(Interface.MessageType.Error, false, "Yaw is invalid in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); yaw = 0.0; } if (Arguments.Length >= 6 && Arguments[5].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[5], out pitch)) { Interface.AddMessage(Interface.MessageType.Error, false, "Pitch is invalid in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); pitch = 0.0; } if (Arguments.Length >= 7 && Arguments[6].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[6], out roll)) { Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in Track.FreeObj at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } if (idx == -1) { int n; n = Data.Blocks[BlockIndex].GroundFreeObj.Length; Array.Resize<FreeObj>(ref Data.Blocks[BlockIndex].GroundFreeObj, n + 1); Data.Blocks[BlockIndex].GroundFreeObj[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].GroundFreeObj[n].Type = sttype; Data.Blocks[BlockIndex].GroundFreeObj[n].X = x; Data.Blocks[BlockIndex].GroundFreeObj[n].Y = y; Data.Blocks[BlockIndex].GroundFreeObj[n].Yaw = yaw * 0.0174532925199433; Data.Blocks[BlockIndex].GroundFreeObj[n].Pitch = pitch * 0.0174532925199433; Data.Blocks[BlockIndex].GroundFreeObj[n].Roll = roll * 0.0174532925199433; } else { if (idx >= Data.Blocks[BlockIndex].RailFreeObj.Length) { Array.Resize<FreeObj[]>(ref Data.Blocks[BlockIndex].RailFreeObj, idx + 1); } int n; if (Data.Blocks[BlockIndex].RailFreeObj[idx] == null) { Data.Blocks[BlockIndex].RailFreeObj[idx] = new FreeObj[1]; n = 0; } else { n = Data.Blocks[BlockIndex].RailFreeObj[idx].Length; Array.Resize<FreeObj>(ref Data.Blocks[BlockIndex].RailFreeObj[idx], n + 1); } Data.Blocks[BlockIndex].RailFreeObj[idx][n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].RailFreeObj[idx][n].Type = sttype; Data.Blocks[BlockIndex].RailFreeObj[idx][n].X = x; Data.Blocks[BlockIndex].RailFreeObj[idx][n].Y = y; Data.Blocks[BlockIndex].RailFreeObj[idx][n].Yaw = yaw * 0.0174532925199433; Data.Blocks[BlockIndex].RailFreeObj[idx][n].Pitch = pitch * 0.0174532925199433; Data.Blocks[BlockIndex].RailFreeObj[idx][n].Roll = roll * 0.0174532925199433; } } } } } break; case "track.back": { if (!PreviewOnly) { int typ = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out typ)) { Interface.AddMessage(Interface.MessageType.Error, false, "BackgroundTextureIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); typ = 0; } if (typ < 0 | typ >= Data.Backgrounds.Length) { Interface.AddMessage(Interface.MessageType.Error, false, "BackgroundTextureIndex references a texture not loaded in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else if (Data.Backgrounds[typ].Texture == null) { Interface.AddMessage(Interface.MessageType.Error, false, "BackgroundTextureIndex has not been loaded via Texture.Background in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { Data.Blocks[BlockIndex].Background = typ; } } } break; case "track.announce": { if (!PreviewOnly) { if (Arguments.Length == 0) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have between 1 and 2 arguments at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { string f = OpenBveApi.Path.CombineFile(SoundPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double speed = 0.0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], out speed)) { Interface.AddMessage(Interface.MessageType.Error, false, "Speed is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); speed = 0.0; } int n = Data.Blocks[BlockIndex].Sound.Length; Array.Resize<Sound>(ref Data.Blocks[BlockIndex].Sound, n + 1); Data.Blocks[BlockIndex].Sound[n].TrackPosition = Data.TrackPosition; const double radius = 15.0; Data.Blocks[BlockIndex].Sound[n].SoundBuffer = Sounds.RegisterBuffer(f, radius); Data.Blocks[BlockIndex].Sound[n].Type = speed == 0.0 ? SoundType.TrainStatic : SoundType.TrainDynamic; Data.Blocks[BlockIndex].Sound[n].Speed = speed * Data.UnitOfSpeed; } } } } } break; case "track.doppler": { if (!PreviewOnly) { if (Arguments.Length == 0) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have between 1 and 3 arguments at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { if (Interface.ContainsInvalidPathChars(Arguments[0])) { Interface.AddMessage(Interface.MessageType.Error, false, "FileName contains illegal characters in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { string f = OpenBveApi.Path.CombineFile(SoundPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Interface.AddMessage(Interface.MessageType.Error, true, "FileName " + f + " not found in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double x = 0.0, y = 0.0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 & !Interface.TryParseDoubleVb6(Arguments[1], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 & !Interface.TryParseDoubleVb6(Arguments[2], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } int n = Data.Blocks[BlockIndex].Sound.Length; Array.Resize<Sound>(ref Data.Blocks[BlockIndex].Sound, n + 1); Data.Blocks[BlockIndex].Sound[n].TrackPosition = Data.TrackPosition; const double radius = 15.0; Data.Blocks[BlockIndex].Sound[n].SoundBuffer = Sounds.RegisterBuffer(f, radius); Data.Blocks[BlockIndex].Sound[n].Type = SoundType.World; Data.Blocks[BlockIndex].Sound[n].X = x; Data.Blocks[BlockIndex].Sound[n].Y = y; Data.Blocks[BlockIndex].Sound[n].Radius = radius; } } } } } break; case "track.pretrain": { if (!PreviewOnly) { if (Arguments.Length == 0) { Interface.AddMessage(Interface.MessageType.Error, false, Command + " is expected to have exactly 1 argument at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } else { double time = 0.0; if (Arguments[0].Length > 0 & !Interface.TryParseTime(Arguments[0], out time)) { Interface.AddMessage(Interface.MessageType.Error, false, "Time is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); time = 0.0; } int n = Game.BogusPretrainInstructions.Length; if (n != 0 && Game.BogusPretrainInstructions[n - 1].Time >= time) { Interface.AddMessage(Interface.MessageType.Error, false, "Time is expected to be in ascending order between successive " + Command + " commands at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } Array.Resize<Game.BogusPretrainInstruction>(ref Game.BogusPretrainInstructions, n + 1); Game.BogusPretrainInstructions[n].TrackPosition = Data.TrackPosition; Game.BogusPretrainInstructions[n].Time = time; } } } break; case "track.pointofinterest": case "track.poi": { if (!PreviewOnly) { int idx = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !Interface.TryParseIntVb6(Arguments[0], out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx < 0) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex is expected to be non-negative in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); idx = 0; } if (idx >= 0 && (idx >= Data.Blocks[BlockIndex].Rail.Length || !Data.Blocks[BlockIndex].Rail[idx].RailStart)) { Interface.AddMessage(Interface.MessageType.Error, false, "RailIndex references a non-existing rail in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); } double x = 0.0, y = 0.0; if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[1], UnitOfLength, out x)) { Interface.AddMessage(Interface.MessageType.Error, false, "X is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); x = 0.0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[2], UnitOfLength, out y)) { Interface.AddMessage(Interface.MessageType.Error, false, "Y is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); y = 0.0; } double yaw = 0.0, pitch = 0.0, roll = 0.0; if (Arguments.Length >= 4 && Arguments[3].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[3], out yaw)) { Interface.AddMessage(Interface.MessageType.Error, false, "Yaw is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); yaw = 0.0; } if (Arguments.Length >= 5 && Arguments[4].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[4], out pitch)) { Interface.AddMessage(Interface.MessageType.Error, false, "Pitch is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); pitch = 0.0; } if (Arguments.Length >= 6 && Arguments[5].Length > 0 && !Interface.TryParseDoubleVb6(Arguments[5], out roll)) { Interface.AddMessage(Interface.MessageType.Error, false, "Roll is invalid in " + Command + " at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); roll = 0.0; } string text = null; if (Arguments.Length >= 7 && Arguments[6].Length != 0) { text = Arguments[6]; } int n = Data.Blocks[BlockIndex].PointsOfInterest.Length; Array.Resize<PointOfInterest>(ref Data.Blocks[BlockIndex].PointsOfInterest, n + 1); Data.Blocks[BlockIndex].PointsOfInterest[n].TrackPosition = Data.TrackPosition; Data.Blocks[BlockIndex].PointsOfInterest[n].RailIndex = idx; Data.Blocks[BlockIndex].PointsOfInterest[n].X = x; Data.Blocks[BlockIndex].PointsOfInterest[n].Y = y; Data.Blocks[BlockIndex].PointsOfInterest[n].Yaw = 0.0174532925199433 * yaw; Data.Blocks[BlockIndex].PointsOfInterest[n].Pitch = 0.0174532925199433 * pitch; Data.Blocks[BlockIndex].PointsOfInterest[n].Roll = 0.0174532925199433 * roll; Data.Blocks[BlockIndex].PointsOfInterest[n].Text = text; } } break; default: Interface.AddMessage(Interface.MessageType.Warning, false, "The command " + Command + " is not supported at line " + Expressions[j].Line.ToString(Culture) + ", column " + Expressions[j].Column.ToString(Culture) + " in file " + Expressions[j].File); break; } } } } } if (!PreviewOnly) { // timetable Timetable.CustomTextures = new Textures.Texture[Data.TimetableDaytime.Length + Data.TimetableNighttime.Length]; int n = 0; for (int i = 0; i < Data.TimetableDaytime.Length; i++) { if (Data.TimetableDaytime[i] != null) { Timetable.CustomTextures[n] = Data.TimetableDaytime[i]; n++; } } for (int i = 0; i < Data.TimetableNighttime.Length; i++) { if (Data.TimetableNighttime[i] != null) { Timetable.CustomTextures[n] = Data.TimetableNighttime[i]; n++; } } Array.Resize<Textures.Texture>(ref Timetable.CustomTextures, n); } // blocks Array.Resize<Block>(ref Data.Blocks, BlocksUsed); }
private void ParseSignalCommand(string Command, string[] Arguments, int Index, Encoding Encoding, Expression Expression, ref RouteData Data, bool PreviewOnly) { switch (Command) { case "signal": if (!PreviewOnly) { if (Arguments.Length < 1) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, Command + " is expected to have between 1 and 2 arguments at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { if (Arguments[0].EndsWith(".animated", StringComparison.OrdinalIgnoreCase)) { if (Path.ContainsInvalidChars(Arguments[0])) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "AnimatedObjectFile contains illegal characters in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { if (Arguments.Length > 1) { Plugin.CurrentHost.AddMessage(MessageType.Warning, false, Command + " is expected to have exactly 1 argument when using animated objects at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } string f = Path.CombineFile(ObjectPath, Arguments[0]); if (!System.IO.File.Exists(f)) { Plugin.CurrentHost.AddMessage(MessageType.Error, true, "SignalFileWithoutExtension " + f + " not found in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { UnifiedObject obj; Plugin.CurrentHost.LoadObject(f, Encoding, out obj); if (obj is AnimatedObjectCollection) { AnimatedObjectSignalData Signal = new AnimatedObjectSignalData(obj); Data.Signals[Index] = Signal; } else { Plugin.CurrentHost.AddMessage(MessageType.Error, true, "GlowFileWithoutExtension " + f + " is not a valid animated object in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } } } } else { if (Path.ContainsInvalidChars(Arguments[0])) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "SignalFileWithoutExtension contains illegal characters in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { if (Arguments.Length > 2) { Plugin.CurrentHost.AddMessage(MessageType.Warning, false, Command + " is expected to have between 1 and 2 arguments at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } string f = Arguments[0]; try { if (!LocateObject(ref f, ObjectPath)) { string testPath = Path.CombineFile(ObjectPath, f); if (Plugin.CurrentHost.DetermineStaticObjectExtension(ref testPath)) { f = testPath; } else { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "SignalFileWithoutExtension does not exist in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); break; } } } catch { //NYCT-1 line has a comment containing SIGNAL, which is then misinterpreted by the parser here //Really needs commenting fixing, rather than hacks like this..... Plugin.CurrentHost.AddMessage(MessageType.Error, false, "SignalFileWithoutExtension does not contain a valid path in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); break; } Bve4SignalData Signal = new Bve4SignalData { BaseObject = LoadStaticObject(f, Encoding, false), GlowObject = null }; string Folder = System.IO.Path.GetDirectoryName(f); if (!System.IO.Directory.Exists(Folder)) { Plugin.CurrentHost.AddMessage(MessageType.Error, true, "The folder " + Folder + " could not be found in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { Signal.SignalTextures = LoadAllTextures(f, false); Signal.GlowTextures = new OpenBveApi.Textures.Texture[] { }; if (Arguments.Length >= 2 && Arguments[1].Length != 0) { if (Path.ContainsInvalidChars(Arguments[1])) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "GlowFileWithoutExtension contains illegal characters in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { f = Arguments[1]; bool glowFileFound = false; if (!System.IO.File.Exists(f) && System.IO.Path.HasExtension(f)) { string ext = System.IO.Path.GetExtension(f); if (Plugin.CurrentHost.SupportedStaticObjectExtensions.Contains(ext.ToLowerInvariant())) { Plugin.CurrentHost.AddMessage(MessageType.Warning, false, "GlowFileWithoutExtension should not supply a file extension in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); f = Path.CombineFile(ObjectPath, f); glowFileFound = true; } else if (Plugin.CurrentHost.SupportedAnimatedObjectExtensions.Contains(ext.ToLowerInvariant())) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "GlowFileWithoutExtension must be a static object in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "GlowFileWithoutExtension is invalid in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } } if (!System.IO.File.Exists(f) && !System.IO.Path.HasExtension(f)) { string testPath = Path.CombineFile(ObjectPath, f); if (Plugin.CurrentHost.DetermineStaticObjectExtension(ref testPath)) { f = testPath; glowFileFound = true; } else { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "GlowFileWithoutExtension does not exist in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); break; } } if (glowFileFound) { Plugin.CurrentHost.LoadStaticObject(f, Encoding, false, out Signal.GlowObject); if (Signal.GlowObject != null) { Signal.GlowTextures = LoadAllTextures(f, true); for (int p = 0; p < Signal.GlowObject.Mesh.Materials.Length; p++) { Signal.GlowObject.Mesh.Materials[p].BlendMode = MeshMaterialBlendMode.Additive; Signal.GlowObject.Mesh.Materials[p].GlowAttenuationData = Glow.GetAttenuationData(200.0, GlowAttenuationMode.DivisionExponent4); } } } } } Data.Signals.Add(Index, Signal); } } } } } break; } }