private FormatBase GetNumberFormat(string format, object value) { FormatBase expectedFormat = NumberFormats.Where(f => f.Format == "G").ToList().FirstOrDefault(); if (!string.IsNullOrEmpty(format)) { string leader = format[0].ToString(); NumberFormat n = NumberFormats.Where(f => f.Format == leader).ToList().FirstOrDefault() as NumberFormat; if (n != null) { string decimalPlaces = format.Substring(1); if (!string.IsNullOrEmpty(decimalPlaces)) { int num; if (Int32.TryParse(decimalPlaces, out num)) { n.DecimalPlaces = num; } } expectedFormat = n; } else { DateFormat d = NumberFormats.Where(f => f.Name == "Date").FirstOrDefault() as DateFormat; if (d.IsDateFormat(format, value)) { expectedFormat = d; } } } return(expectedFormat); }
/// <summary>Parses an XML motor table node</summary> /// <param name="node">The node</param> /// <param name="Tables">The motor sound tables to assign this node's contents to</param> /// <param name="Position">The default sound position</param> /// <param name="Radius">The default sound radius</param> private static void ParseMotorSoundTableNode(XmlNode node, ref TrainManager.MotorSoundTable[] Tables, Vector3 Position, double Radius) { foreach (XmlNode c in node.ChildNodes) { int idx; if (!NumberFormats.TryParseIntVb6(c.Name, out idx)) { continue; } for (int i = 0; i < Tables.Length; i++) { Tables[i].Buffer = null; Tables[i].Source = null; for (int j = 0; j > Tables[i].Entries.Length; j++) { if (idx == Tables[i].Entries[j].SoundIndex) { ParseNode(c, out Tables[i].Entries[j].Buffer, ref Position, Radius); } } } } }
/// ----------------------------------------------------------------------------------------------- /// <summary> /// Overload 2: Constructor, Initialize all fields /// </summary> /// <param name="boundColumnName">string</param> /// <param name="userDefinedColumnName">string</param> /// <param name="numberFormat"></param> /// <param name="horizontalAlignment"></param> /// <param name="showField">bool</param> /// <param name="fieldOrder">int?</param> /// <param name="userDefinedNumberFormat">string</param> /// ----------------------------------------------------------------------------------------------- public Column( string boundColumnName, string userDefinedColumnName, NumberFormats numberFormat = NumberFormats.General, HorizontalAlignmentValues horizontalAlignment = HorizontalAlignmentValues.Center, bool showField = true, int?fieldOrder = null, string userDefinedNumberFormat = null) { try { BoundColumnName = boundColumnName; UserDefinedColumnName = userDefinedColumnName; NumberFormat = numberFormat; HorizontalAlignment = horizontalAlignment; ShowField = showField; FieldOrder = fieldOrder; UserDefinedNumberFormat = userDefinedNumberFormat; } catch (Exception ex) { Log.Error("SpreadsheetLightWrapper.Export.Models.Column.Contructor:Overload 2 -> " + ex.Message + ": " + ex); } }
/// <summary>Converts a RW formatted expression to CSV format</summary> /// <param name="Section">The current section</param> /// <param name="SectionAlwaysPrefix">Whether the section prefix should always be applied</param> internal void ConvertRwToCsv(string Section, bool SectionAlwaysPrefix) { int Equals = Text.IndexOf('='); if (Equals >= 0) { // handle RW cycle syntax string t = Text.Substring(0, Equals); if (Section.ToLowerInvariant() == "cycle" & SectionAlwaysPrefix) { double b; if (NumberFormats.TryParseDoubleVb6(t, out b)) { t = ".Ground(" + b + ")"; } } else if (Section.ToLowerInvariant() == "signal" & SectionAlwaysPrefix) { double b; if (NumberFormats.TryParseDoubleVb6(t, out b)) { t = ".Void(" + b + ")"; } } // convert RW style into CSV style Text = t + " " + Text.Substring(Equals + 1); } }
/// <summary> /// Function to parse the contents of TravelData class /// </summary> /// <param name="FileName">The filename of the containing XML file</param> /// <param name="SectionElement">The XElement to parse</param> /// <param name="Data">Travel data to which the parse results apply</param> private static void ParseTravelDataNode(string FileName, XElement SectionElement, TravelData Data) { string Section = SectionElement.Name.LocalName; double Decelerate = 0.0; double Accelerate = 0.0; double TargetSpeed = 0.0; foreach (XElement KeyNode in SectionElement.Elements()) { string Key = KeyNode.Name.LocalName; string Value = KeyNode.Value; int LineNumber = ((IXmlLineInfo)KeyNode).LineNumber; switch (Key.ToLowerInvariant()) { case "decelerate": if (Value.Any() && !NumberFormats.TryParseDoubleVb6(Value, out Decelerate) || Decelerate < 0.0) { Interface.AddMessage(MessageType.Error, false, $"Value is expected to be a non-negative floating-point number in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "position": case "stopposition": if (Value.Any() && !NumberFormats.TryParseDoubleVb6(Value, out Data.Position)) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "accelerate": if (Value.Any() && !NumberFormats.TryParseDoubleVb6(Value, out Accelerate) || Accelerate < 0.0) { Interface.AddMessage(MessageType.Error, false, $"Value is expected to be a non-negative floating-point number in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "targetspeed": if (Value.Any() && !NumberFormats.TryParseDoubleVb6(Value, out TargetSpeed) || TargetSpeed < 0.0) { Interface.AddMessage(MessageType.Error, false, $"Value is expected to be a non-negative floating-point number in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "rail": if (Value.Any() && !NumberFormats.TryParseIntVb6(Value, out Data.RailIndex) || Data.RailIndex < 0) { Interface.AddMessage(MessageType.Error, false, $"Value is expected to be a non-negative integer number in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); Data.RailIndex = 0; } break; } } Data.Decelerate = -Decelerate / 3.6; Data.Accelerate = Accelerate / 3.6; Data.TargetSpeed = TargetSpeed / 3.6; }
private static void ParseNode(string basePath, XElement parentNode, SoundElement element) { foreach (XElement childNode in parentNode.Elements()) { switch (childNode.Name.LocalName.ToLowerInvariant()) { case "filename": if (!childNode.Value.Any() || Path.ContainsInvalidChars(childNode.Value)) { Interface.AddMessage(MessageType.Error, false, $"FileName {childNode.Value} contains illegal characters or is empty in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber}."); return; } element.FilePath = Path.CombineFile(basePath, childNode.Value); break; case "position": string[] Arguments = childNode.Value.Split(','); double x = 0.0, y = 0.0, z = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[0], out x)) { Interface.AddMessage(MessageType.Error, false, $"Sound radius X {Arguments[0]} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber} is invalid."); x = 0.0; } if (Arguments.Length >= 2 && Arguments[1].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[1], out y)) { Interface.AddMessage(MessageType.Error, false, $"Sound radius Y {Arguments[1]} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber} is invalid."); y = 0.0; } if (Arguments.Length >= 3 && Arguments[2].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[2], out z)) { Interface.AddMessage(MessageType.Error, false, $"Sound radius Z {Arguments[2]} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber} is invalid."); z = 0.0; } element.PositionX = x; element.PositionY = y; element.PositionZ = z; element.DefinedPosition = true; break; case "radius": double radius; if (!NumberFormats.TryParseDoubleVb6(childNode.Value, out radius)) { Interface.AddMessage(MessageType.Error, false, $"The sound radius {childNode.Value} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber} is invalid."); } element.Radius = radius; element.DefinedRadius = true; break; } } }
/// <summary>Parses any command-line arguments passed to the main program</summary> /// <param name="Arguments">A string array of arguments</param> /// <param name="Result">The main dialog result (Used to launch)</param> internal static void ParseArguments(string[] Arguments, ref formMain.MainDialogResult Result) { if (Arguments.Length == 0) { return; } for (int i = 0; i < Arguments.Length; i++) { int equals = Arguments[i].IndexOf('='); if (equals >= 0) { string key = Arguments[i].Substring(0, equals).Trim(new char[] { }).ToLowerInvariant(); string value = Arguments[i].Substring(equals + 1).Trim(new char[] { }); switch (key) { case "/route": Result.RouteFile = value; Result.RouteEncoding = TextEncoding.GetSystemEncodingFromFile(Result.RouteFile); break; case "/train": Result.TrainFolder = value; Result.TrainEncoding = TextEncoding.GetSystemEncodingFromFile(Result.TrainFolder, "train.txt"); break; case "/station": Result.InitialStation = value; break; case "/time": Interface.TryParseTime(value, out Result.StartTime); break; case "/ai": if (value.ToLowerInvariant() == "true" || value.ToLowerInvariant() == "1") { Result.AIDriver = true; } break; case "/fullscreen": if (value.ToLowerInvariant() == "true" || value.ToLowerInvariant() == "1") { Result.FullScreen = true; } break; case "/width": NumberFormats.TryParseIntVb6(value, out Result.Width); break; case "/height": NumberFormats.TryParseIntVb6(value, out Result.Height); break; } } } }
/// ----------------------------------------------------------------------------------------------- /// <summary> /// Set the numeric format of the cell text value from a predetermined /// list of formats enumerated in the NumberFormats Enum. /// If format is "User-Defined" then add a valid Excel Number Format in "userDefinedExcelFormat" /// </summary> /// <param name="format">NumberFormats</param> /// <param name="style">ref SLStyle</param> /// <param name="userDefinedNumberFormat">string</param> /// ----------------------------------------------------------------------------------------------- private void SetNumberFormat(NumberFormats format, ref SLStyle style, string userDefinedNumberFormat = null) { try { style.FormatCode = format == NumberFormats.UserDefined ? userDefinedNumberFormat : GetAttribute(format); } catch (Exception ex) { Log.Error("SpreadsheetLightWrapper.Export.Exporter.SetNumberFormat -> " + ex.Message + ": " + ex); } }
/// ----------------------------------------------------------------------------------------------- /// <summary> /// Overload 2: Overrides the default bound column names with custom ones and determines the formatting, /// visibility and order. /// ** Note: If none are added then the column names from the dataset table will be used and /// there will no formatting. /// <para /> /// "boundColumnName" string: Bound column name /// <para /> /// "userDefinedColumnName" string: Custom column name /// <para /> /// "numberFormat" NumberFormats: Column format /// <para /> /// "horizontalAlignment" HorizontalAlignmentValues: Column horizontalAlignment /// <para /> /// "showField" bool: Show/Hide column /// <para /> /// "fieldOrder" int: Set the order of the field /// <para /> /// "userDefinedNumberFormat" string: User-defined excel format /// * Must be populated when "numberFormat" is set to "User-Defined" /// </summary> /// <param name="boundColumnName">string: Bound column name</param> /// <param name="userDefinedColumnName">string: User-Defined column name</param> /// <param name="numberFormat">string: Column number format</param> /// <param name="horizontalAlignment">string: Column horizontalAlignment</param> /// <param name="showField">bool: Show/Hide column</param> /// <param name="fieldOrder">int: Set the order of the field</param> /// <param name="userDefinedNumberFormat">string</param> /// ----------------------------------------------------------------------------------------------- public void SetUserDefinedColumnNames( string boundColumnName, string userDefinedColumnName, NumberFormats numberFormat, HorizontalAlignmentValues horizontalAlignment, bool showField, int?fieldOrder, string userDefinedNumberFormat = null) { try { if (UserDefinedColumns.Any(x => x.BoundColumnName == boundColumnName)) { UserDefinedColumns.RemoveAt(UserDefinedColumns.FindIndex(x => x.BoundColumnName == boundColumnName)); UserDefinedColumns.Add(new Column { BoundColumnName = boundColumnName, UserDefinedColumnName = userDefinedColumnName, NumberFormat = numberFormat, HorizontalAlignment = horizontalAlignment, ShowField = showField, FieldOrder = fieldOrder, UserDefinedNumberFormat = userDefinedNumberFormat }); } else { UserDefinedColumns.Add(new Column { BoundColumnName = boundColumnName, UserDefinedColumnName = userDefinedColumnName, NumberFormat = numberFormat, HorizontalAlignment = horizontalAlignment, ShowField = showField, FieldOrder = fieldOrder, UserDefinedNumberFormat = userDefinedNumberFormat }); } } catch (Exception ex) { Log.Error( "SpreadsheetLightWrapper.Export.Models.ChildSetting.SetUserDefinedColumnNames:Overload 2 -> " + ex.Message + ": " + ex); } }
/// <summary> /// Function to parse TFO definition /// </summary> /// <param name="FileName">The filename of the containing XML file</param> /// <param name="SectionElement">The XElement to parse</param> /// <param name="Train">The track following object to parse this node into</param> private static void ParseDefinitionNode(string FileName, XElement SectionElement, TrackFollowingObject Train) { string Section = SectionElement.Name.LocalName; foreach (XElement KeyNode in SectionElement.Elements()) { string Key = KeyNode.Name.LocalName; string Value = KeyNode.Value; int LineNumber = ((IXmlLineInfo)KeyNode).LineNumber; switch (Key.ToLowerInvariant()) { case "appearancetime": if (Value.Any() && !Interface.TryParseTime(Value, out Train.AppearanceTime)) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "appearancestartposition": if (Value.Any() && !NumberFormats.TryParseDoubleVb6(Value, out Train.AppearanceStartPosition)) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "appearanceendposition": if (Value.Any() && !NumberFormats.TryParseDoubleVb6(Value, out Train.AppearanceEndPosition)) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "leavetime": if (Value.Any() && !Interface.TryParseTime(Value, out Train.LeaveTime)) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; default: Interface.AddMessage(MessageType.Warning, false, $"Unsupported key {Key} encountered in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); break; } } }
private int[] FindIndices(ref string Command, Expression Expression) { int[] commandIndices = { 0, 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(";", StringComparison.Ordinal); if (h >= 0) { string a = Indices.Substring(0, h).TrimEnd(); string b = Indices.Substring(h + 1).TrimStart(); if (a.Length > 0 && !NumberFormats.TryParseIntVb6(a, out commandIndices[0])) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Invalid first index appeared at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File + "."); Command = null; } if (b.Length > 0 && !NumberFormats.TryParseIntVb6(b, out commandIndices[1])) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Invalid second index appeared at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File + "."); Command = null; } } else { if (Indices.Length > 0 && !NumberFormats.TryParseIntVb6(Indices, out commandIndices[0])) { if (Indices.ToLowerInvariant() != "c" || Command.ToLowerInvariant() != "route.comment") { // (C) used in route comment to represent copyright symbol, so not an error Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Invalid index appeared at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File + "."); Command = null; } } } break; } } } return(commandIndices); }
/// <summary>Parses an XML motor table node</summary> /// <param name="node">The node</param> /// <param name="Tables">The motor sound tables to assign this node's contents to</param> /// <param name="Position">The default sound position</param> /// <param name="Radius">The default sound radius</param> private void ParseMotorSoundTableNode(XmlNode node, ref BVEMotorSoundTable[] Tables, Vector3 Position, double Radius) { foreach (XmlNode c in node.ChildNodes) { int idx = -1; if (c.Name.ToLowerInvariant() != "sound") { Plugin.currentHost.AddMessage(MessageType.Error, false, "Invalid array node " + c.Name + " in XML node " + node.Name); } else { for (int i = 0; i < c.ChildNodes.Count; i++) { if (c.ChildNodes[i].Name.ToLowerInvariant() == "index") { if (!NumberFormats.TryParseIntVb6(c.ChildNodes[i].InnerText.ToLowerInvariant(), out idx)) { Plugin.currentHost.AddMessage(MessageType.Error, false, "Invalid array index " + c.Name + " in XML node " + node.Name); return; } break; } } if (idx >= 0) { for (int i = 0; i < Tables.Length; i++) { Tables[i].Buffer = null; Tables[i].Source = null; for (int j = 0; j < Tables[i].Entries.Length; j++) { if (idx == Tables[i].Entries[j].SoundIndex) { ParseNode(c, out Tables[i].Entries[j].Buffer, ref Position, Radius); } } } } else { Plugin.currentHost.AddMessage(MessageType.Error, false, "Invalid array index " + c.Name + " in XML node " + node.Name); } } } }
/// ----------------------------------------------------------------------------------------------- /// <summary> /// Gets the Format String attribute from the Enum Value /// </summary> /// <param name="format">NumberFormats</param> /// <returns>string</returns> /// ----------------------------------------------------------------------------------------------- private string GetAttribute(NumberFormats format) { try { var type = format.GetType(); var fi = type.GetField(format.ToString()); var formatString = fi.GetCustomAttributes(typeof(FormatString), false) as FormatString[]; if (formatString != null) { return(formatString[0].Value); } } catch (Exception ex) { Log.Error("SpreadsheetLightWrapper.Export.Exporter.GetAttribute -> " + ex.Message + ": " + ex); } return(null); }
private static string GetNumberFormatString(NumberFormats format, bool useTS, int dec, int exp) { switch (format) { case NumberFormats.WholeNumber: return(useTS ? "#,##0" : "0"); case NumberFormats.DecimalNumber: return((useTS ? "#,##0" : "0") + (dec > 0 ? ("." + new string('0', dec)) : "")); case NumberFormats.Currency: return("$ " + GetNumberFormatString(NumberFormats.DecimalNumber, useTS, dec, exp)); case NumberFormats.Percentage: return(GetNumberFormatString(NumberFormats.DecimalNumber, useTS, dec, exp) + " %"); case NumberFormats.Scientific: return(GetNumberFormatString(NumberFormats.DecimalNumber, useTS, dec, exp) + "E+" + new string('0', exp)); default: return(""); } }
public static IEnumerator LerpAmount(this Text text, string format, NumberFormats.Format numberType, UInt128 to, float duration) { NumberFormats.TryParse(text.text.ToLower().Replace(",", "").Replace("$", "").Replace("x", ""), numberType, out UInt128 from); var start = DateTime.UtcNow; for (;;) { var elapsed = (float)(DateTime.UtcNow - start).TotalSeconds; var percent = Curve.Evaluate(elapsed / duration); var normed = UInt128.Lerp(from, to, percent); text.SetAmount(format, numberType, normed); if (elapsed >= duration) { yield break; } yield return(null); } }
public static void Main(string[] args) { Simple.Run(); MultipleSheet.Run(); NumberFormats.Run(); ColumnFormatting.Run(); RowFormatting.Run(); Alignment.Run(); Border.Run(); DataValidation.Run(); RightToLeft.Run(); Zip64Small.Run(); SheetProtection.Run(); Large.Run(); StyledLarge.Run(); StyledLargeCreateStyles.Run(); Zip64Huge.Run(); }
/// <summary>Parses an XML node containing a list of sounds into a car sound array</summary> /// <param name="node">The node to parse</param> /// <param name="Sounds">The car sound array</param> /// <param name="Position">The default position of the sound (May be overriden by any node)</param> /// <param name="Radius">The default radius of the sound (May be overriden by any node)</param> private void ParseDictionaryNode(XmlNode node, out Dictionary <int, CarSound> Sounds, Vector3 Position, double Radius) { Sounds = new Dictionary <int, CarSound>(); foreach (XmlNode c in node.ChildNodes) { int idx = -1; if (c.Name.ToLowerInvariant() != "sound") { Plugin.currentHost.AddMessage(MessageType.Error, false, "Invalid array node " + c.Name + " in XML node " + node.Name); } else { for (int i = 0; i < c.ChildNodes.Count; i++) { if (c.ChildNodes[i].Name.ToLowerInvariant() == "index") { if (!NumberFormats.TryParseIntVb6(c.ChildNodes[i].InnerText.ToLowerInvariant(), out idx)) { Plugin.currentHost.AddMessage(MessageType.Error, false, "Invalid array index " + c.Name + " in XML node " + node.Name); return; } break; } } if (idx >= 0) { CarSound sound; ParseNode(c, out sound, Position, Radius); if (Sounds.ContainsKey(idx)) { Sounds[idx] = sound; } else { Sounds.Add(idx, sound); } } else { Plugin.currentHost.AddMessage(MessageType.Error, false, "Invalid array index " + c.Name + " in XML node " + node.Name); } } } }
/// <summary> /// Function to parse the contents of TravelPointData class /// </summary> /// <param name="FileName">The filename of the containing XML file</param> /// <param name="SectionElement">The XElement to parse</param> /// <returns>An instance of the new TravelPointData class with the parse result applied</returns> private static TravelPointData ParseTravelPointNode(string FileName, XElement SectionElement) { string Section = SectionElement.Name.LocalName; TravelPointData Data = new TravelPointData(); ParseTravelDataNode(FileName, SectionElement, Data); double PassingSpeed = 0.0; foreach (XElement KeyNode in SectionElement.Elements()) { string Key = KeyNode.Name.LocalName; string Value = KeyNode.Value; int LineNumber = ((IXmlLineInfo)KeyNode).LineNumber; switch (Key.ToLowerInvariant()) { case "passingspeed": if (Value.Any() && !NumberFormats.TryParseDoubleVb6(Value, out PassingSpeed) || PassingSpeed < 0.0) { Interface.AddMessage(MessageType.Error, false, $"Value is expected to be a non-negative floating-point number in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "decelerate": case "position": case "stopposition": case "accelerate": case "targetspeed": case "rail": // Already parsed break; default: Interface.AddMessage(MessageType.Warning, false, $"Unsupported key {Key} encountered in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); break; } } Data.PassingSpeed = PassingSpeed / 3.6; return(Data); }
public int GetColumnStyle(string dataFormat) { var numberFormat = new NumberFormat { FormatCode = dataFormat, Id = 164 + NumberFormats.Count // custom number formats start from numFmtId=164 }; var cellFormat = new CellFormat { FormatId = numberFormat.Id, Id = CellFormats.Count }; NumberFormats.Add(numberFormat); CellFormats.Add(cellFormat); return(cellFormat.Id); }
public string FormatValue(double value, NumberFormats format) { try { switch (format) { case NumberFormats.CURRENCY: return(String.Format("Currency formatting: {0:C}", value)); case NumberFormats.DECIMAL: return(String.Format("DECIMAL formatting:{0:D15}", value)); case NumberFormats.EXPONENTIAL: return(String.Format("EXPONENTIAL formatting:{0:E}", value)); case NumberFormats.FIXED_POINT: return(String.Format("FIXED_POINT formatting:{0:F3}", value)); case NumberFormats.HEX: return(String.Format("HEX formatting: {0:X}", (int)value)); case NumberFormats.GENERALS: return(String.Format("GENERALS formatting: {0:G}", value)); case NumberFormats.INT: default: return(String.Format("All formats: Currency:{0:C}\nDecimal:{0:D15}\nEXP:{0:E}\nFixed_point:{0:F3}\nHEX:{0:X}\nGeneral:{0:G}\nDefault:{0:n}", (int)value)); } } catch (FormatException nfe) { //throw new FormatException("My Invalid format"); return(nfe.Message); } }
private static void ParseArrayNode <T>(string basePath, XElement parentNode, ICollection <SoundElement> elements) where T : SoundElement <int>, new() { foreach (XElement childNode in parentNode.Elements()) { if (childNode.Name.LocalName.ToLowerInvariant() != "sound") { Interface.AddMessage(MessageType.Error, false, $"Invalid array node {childNode.Name.LocalName} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber}"); } else { int idx; XElement indexNode = childNode.Element("Index"); if (indexNode == null) { Interface.AddMessage(MessageType.Error, false, $"Invalid array index {childNode.Name.LocalName} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber}"); return; } if (!NumberFormats.TryParseIntVb6(indexNode.Value, out idx)) { Interface.AddMessage(MessageType.Error, false, $"Invalid array index {childNode.Name.LocalName} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber}"); return; } if (idx >= 0) { T element = new T { Key = idx }; ParseNode(basePath, childNode, element); elements.Add(element); } else { Interface.AddMessage(MessageType.Error, false, $"Invalid array index {childNode.Name.LocalName} in XML node {parentNode.Name.LocalName} at line {((IXmlLineInfo)indexNode).LineNumber}"); } } } }
/// <summary>Parses an XML node containing a list of sounds into a car sound array</summary> /// <param name="node">The node to parse</param> /// <param name="Sounds">The car sound array</param> /// <param name="Position">The default position of the sound (May be overriden by any node)</param> /// <param name="Radius">The default radius of the sound (May be overriden by any node)</param> private static void ParseArrayNode(XmlNode node, out TrainManager.CarSound[] Sounds, Vector3 Position, double Radius) { Sounds = new TrainManager.CarSound[0]; foreach (XmlNode c in node.ChildNodes) { int idx = -1; if (c.Name.ToLowerInvariant() != "sound") { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid array node " + c.Name + " in XML node " + node.Name); } else { for (int i = 0; i < c.ChildNodes.Count; i++) { if (c.ChildNodes[i].Name.ToLowerInvariant() == "index") { if (!NumberFormats.TryParseIntVb6(c.ChildNodes[i].InnerText.ToLowerInvariant(), out idx)) { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid array index " + c.Name + " in XML node " + node.Name); return; } break; } } if (idx >= 0) { int l = Sounds.Length; Array.Resize(ref Sounds, idx + 1); while (l < Sounds.Length) { Sounds[l] = TrainManager.CarSound.Empty; l++; } ParseNode(c, out Sounds[idx], Position, Radius); } else { Interface.AddMessage(Interface.MessageType.Error, false, "Invalid array index " + c.Name + " in XML node " + node.Name); } } } }
private static void ParseTouchSoundEntryNode(string fileName, XElement parent, ICollection <int> indices) { foreach (XElement childNode in parent.Elements()) { if (childNode.Name.LocalName.ToLowerInvariant() != "entry") { Plugin.currentHost.AddMessage(MessageType.Error, false, $"Invalid entry node {childNode.Name.LocalName} in XML node {parent.Name.LocalName} at line {((IXmlLineInfo)childNode).LineNumber}"); } else { System.Globalization.CultureInfo culture = System.Globalization.CultureInfo.InvariantCulture; string section = childNode.Name.LocalName; foreach (XElement keyNode in childNode.Elements()) { string key = keyNode.Name.LocalName; string value = keyNode.Value; int lineNumber = ((IXmlLineInfo)keyNode).LineNumber; switch (keyNode.Name.LocalName.ToLowerInvariant()) { case "index": if (value.Any()) { int index; if (!NumberFormats.TryParseIntVb6(value, out index)) { Plugin.currentHost.AddMessage(MessageType.Error, false, $"value is invalid in {key} in {section} at line {lineNumber.ToString(culture)} in {fileName}"); } indices.Add(index); } break; } } } } }
/// <summary>Parses an XML node containing a list of sounds into a car sound array</summary> /// <param name="node">The node to parse</param> /// <param name="Sounds">The car sound array</param> /// <param name="Position">The default position of the sound (May be overriden by any node)</param> /// <param name="Radius">The default radius of the sound (May be overriden by any node)</param> private static void ParseArrayNode(XmlNode node, out CarSound[] Sounds, Vector3 Position, double Radius) { Sounds = new CarSound[0]; foreach (XmlNode c in node.ChildNodes) { int idx = -1; if (c.Name.ToLowerInvariant() == "sound") { for (int i = 0; i < c.ChildNodes.Count; i++) { if (c.ChildNodes[i].Name.ToLowerInvariant() == "index") { if (!NumberFormats.TryParseIntVb6(c.ChildNodes[i].InnerText.ToLowerInvariant(), out idx)) { return; } break; } } if (idx >= 0) { int l = Sounds.Length; Array.Resize(ref Sounds, idx + 1); while (l < Sounds.Length) { Sounds[l] = new CarSound(); l++; } ParseNode(c, out Sounds[idx], Position, Radius); } } } }
/// <summary> /// Function to parse the contents of TravelStopData class /// </summary> /// <param name="FileName">The filename of the containing XML file</param> /// <param name="SectionElement">The XElement to parse</param> /// <returns>An instance of the new TravelStopData class with the parse result applied</returns> private static TravelStopData ParseTravelStopNode(string FileName, XElement SectionElement) { string Section = SectionElement.Name.LocalName; TravelStopData Data = new TravelStopData(); ParseTravelDataNode(FileName, SectionElement, Data); foreach (XElement KeyNode in SectionElement.Elements()) { string Key = KeyNode.Name.LocalName; string Value = KeyNode.Value; int LineNumber = ((IXmlLineInfo)KeyNode).LineNumber; switch (Key.ToLowerInvariant()) { case "stoptime": if (Value.Any() && !Interface.TryParseTime(Value, out Data.StopTime)) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; case "doors": { int Door = 0; bool DoorBoth = false; switch (Value.ToLowerInvariant()) { case "l": case "left": Door = -1; break; case "r": case "right": Door = 1; break; case "n": case "none": case "neither": Door = 0; break; case "b": case "both": DoorBoth = true; break; default: if (Value.Any() && !NumberFormats.TryParseIntVb6(Value, out Door)) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } break; } Data.OpenLeftDoors = Door < 0.0 | DoorBoth; Data.OpenRightDoors = Door > 0.0 | DoorBoth; } break; case "direction": { int d = 0; switch (Value.ToLowerInvariant()) { case "f": d = 1; break; case "r": d = -1; break; default: if (Value.Any() && (!NumberFormats.TryParseIntVb6(Value, out d) || !Enum.IsDefined(typeof(TravelDirection), d))) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); d = 1; } break; } Data.Direction = (TravelDirection)d; } break; case "decelerate": case "position": case "stopposition": case "accelerate": case "targetspeed": case "rail": // Already parsed break; default: Interface.AddMessage(MessageType.Warning, false, $"Unsupported key {Key} encountered in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); break; } } return(Data); }
public string FormatValue(double value, NumberFormats format) { try { switch (format) { case NumberFormats.CURRENCY: return String.Format("Currency formatting: {0:C}", value); case NumberFormats.DECIMAL: return String.Format("DECIMAL formatting:{0:D15}", value); case NumberFormats.EXPONENTIAL: return String.Format("EXPONENTIAL formatting:{0:E}", value); case NumberFormats.FIXED_POINT: return String.Format("FIXED_POINT formatting:{0:F3}", value); case NumberFormats.HEX: return String.Format("HEX formatting: {0:X}", (int)value); case NumberFormats.GENERALS: return String.Format("GENERALS formatting: {0:G}", value); case NumberFormats.INT: default: return String.Format("All formats: Currency:{0:C}\nDecimal:{0:D15}\nEXP:{0:E}\nFixed_point:{0:F3}\nHEX:{0:X}\nGeneral:{0:G}\nDefault:{0:n}", (int)value); } } catch (FormatException nfe) { //throw new FormatException("My Invalid format"); return nfe.Message; } }
/// <summary> /// Function to parse train definition /// </summary> /// <param name="ObjectPath">Absolute path to the object folder of route data</param> /// <param name="FileName">The filename of the containing XML file</param> /// <param name="SectionElement">The XElement to parse</param> /// <param name="TrainDirectory">Absolute path to the train directory</param> /// <param name="ConsistReversed">Whether to reverse the train composition.</param> private static void ParseTrainNode(string ObjectPath, string FileName, XElement SectionElement, ref string TrainDirectory, ref bool ConsistReversed) { string Section = SectionElement.Name.LocalName; foreach (XElement KeyNode in SectionElement.Elements()) { string Key = KeyNode.Name.LocalName; string Value = KeyNode.Value; int LineNumber = ((IXmlLineInfo)KeyNode).LineNumber; switch (Key.ToLowerInvariant()) { case "directory": { string TmpPath = OpenBveApi.Path.CombineDirectory(System.IO.Path.GetDirectoryName(FileName), Value); if (!Directory.Exists(TmpPath)) { TmpPath = OpenBveApi.Path.CombineFile(Program.FileSystem.InitialTrainFolder, Value); } if (!Directory.Exists(TmpPath)) { TmpPath = OpenBveApi.Path.CombineFile(Program.FileSystem.TrainInstallationDirectory, Value); } if (!Directory.Exists(TmpPath)) { TmpPath = OpenBveApi.Path.CombineFile(ObjectPath, Value); } if (!Directory.Exists(TmpPath)) { Interface.AddMessage(MessageType.Error, false, $"Directory was not found in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } else { TrainDirectory = TmpPath; } } break; case "reversed": if (Value.Any()) { switch (Value.ToLowerInvariant()) { case "true": ConsistReversed = true; break; case "false": ConsistReversed = false; break; default: { int n; if (!NumberFormats.TryParseIntVb6(Value, out n)) { Interface.AddMessage(MessageType.Error, false, $"Value is invalid in {Key} in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); } else { ConsistReversed = Convert.ToBoolean(n); } } break; } } break; default: Interface.AddMessage(MessageType.Warning, false, $"Unsupported key {Key} encountered in {Section} at line {LineNumber.ToString(culture)} in {FileName}"); break; } } }
/// <summary>Separates an expression into it's consituent command and arguments</summary> /// <param name="Command">The command</param> /// <param name="ArgumentSequence">The sequence of arguments contained within the expression</param> /// <param name="Culture">The current culture</param> /// <param name="RaiseErrors">Whether errors should be raised at this point</param> /// <param name="IsRw">Whether this is a RW format file</param> /// <param name="CurrentSection">The current section being processed</param> internal void SeparateCommandsAndArguments(out string Command, out string ArgumentSequence, System.Globalization.CultureInfo Culture, bool RaiseErrors, bool IsRw, string CurrentSection) { bool openingerror = false, closingerror = false; int i, fcb = 0; if (Interface.CurrentOptions.EnableBveTsHacks) { if (Text.StartsWith("Train. ", StringComparison.InvariantCultureIgnoreCase)) { //HACK: Some Chinese routes seem to have used a space between Train. and the rest of the command //e.g. Taipei Metro. BVE4/ 2 accept this...... Text = "Train." + Text.Substring(7, Text.Length - 7); } else if (Text.StartsWith("Texture. Background", StringComparison.InvariantCultureIgnoreCase)) { //Same hack as above, found in Minobu route for BVE2 Text = "Texture.Background" + Text.Substring(19, Text.Length - 19); } else if (Text.EndsWith(")height(0)", StringComparison.InvariantCultureIgnoreCase)) { //Heavy Coal original RW- Fix starting station Text = Text.Substring(0, Text.Length - 9); } if (IsRw && CurrentSection.ToLowerInvariant() == "track") { //Removes misplaced track position indicies from the end of a command in the Track section int idx = Text.LastIndexOf(')'); if (idx != -1 && idx != Text.Length) { double d; string s = this.Text.Substring(idx + 1, this.Text.Length - idx - 1).Trim(new char[] { }); if (NumberFormats.TryParseDoubleVb6(s, out d)) { this.Text = this.Text.Substring(0, idx).Trim(new char[] { }); } } } if (IsRw && this.Text.EndsWith("))")) { int openingBrackets = Text.Count(x => x == '('); int closingBrackets = Text.Count(x => x == ')'); //Remove obviously wrong double-ending brackets if (closingBrackets == openingBrackets + 1 && this.Text.EndsWith("))")) { this.Text = this.Text.Substring(0, this.Text.Length - 1); } } if (Text.StartsWith("route.comment", StringComparison.InvariantCultureIgnoreCase) && Text.IndexOf("(C)", StringComparison.InvariantCultureIgnoreCase) != -1) { //Some BVE4 routes use this instead of the copyright symbol Text = Text.Replace("(C)", "©"); Text = Text.Replace("(c)", "©"); } } for (i = 0; i < Text.Length; i++) { if (Text[i] == '(') { bool found = false; bool stationName = false; bool replaced = false; i++; while (i < Text.Length) { if (Text[i] == ',' || Text[i] == ';') { //Only check parenthesis in the station name field- The comma and semi-colon are the argument separators stationName = true; } if (Text[i] == '(') { if (RaiseErrors & !openingerror) { if (stationName) { Interface.AddMessage(MessageType.Error, false, "Invalid opening parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); openingerror = true; } else { Text = Text.Remove(i, 1).Insert(i, "["); replaced = true; } } } else if (Text[i] == ')') { if (stationName == false && i != Text.Length && replaced == true) { Text = Text.Remove(i, 1).Insert(i, "]"); continue; } found = true; fcb = i; break; } i++; } if (!found) { if (RaiseErrors & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Missing closing parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); closingerror = true; } Text += ")"; } } else if (Text[i] == ')') { if (RaiseErrors & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Invalid closing parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); closingerror = true; } } else if (char.IsWhiteSpace(Text[i])) { if (i >= Text.Length - 1 || !char.IsWhiteSpace(Text[i + 1])) { break; } } } if (fcb != 0 && fcb < Text.Length - 1) { if (!Char.IsWhiteSpace(Text[fcb + 1]) && Text[fcb + 1] != '.' && Text[fcb + 1] != ';') { Text = Text.Insert(fcb + 1, " "); i = fcb; } } if (i < Text.Length) { // white space was found outside of parentheses string a = Text.Substring(0, i); if (a.IndexOf('(') >= 0 & a.IndexOf(')') >= 0) { // indices found not separated from the command by spaces Command = Text.Substring(0, i).TrimEnd(new char[] { }); ArgumentSequence = Text.Substring(i + 1).TrimStart(new char[] { }); if (ArgumentSequence.StartsWith("(") & ArgumentSequence.EndsWith(")")) { // arguments are enclosed by parentheses ArgumentSequence = ArgumentSequence.Substring(1, ArgumentSequence.Length - 2).Trim(new char[] { }); } else if (ArgumentSequence.StartsWith("(")) { // only opening parenthesis found if (RaiseErrors & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Missing closing parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); } ArgumentSequence = ArgumentSequence.Substring(1).TrimStart(new char[] { }); } } else { // no indices found before the space if (i < Text.Length - 1 && Text[i + 1] == '(') { // opening parenthesis follows the space int j = Text.IndexOf(')', i + 1); if (j > i + 1) { // closing parenthesis found if (j == Text.Length - 1) { // only closing parenthesis found at the end of the expression Command = Text.Substring(0, i).TrimEnd(new char[] { }); ArgumentSequence = Text.Substring(i + 2, j - i - 2).Trim(new char[] { }); } else { // detect border between indices and arguments bool found = false; Command = null; ArgumentSequence = null; for (int k = j + 1; k < Text.Length; k++) { if (char.IsWhiteSpace(Text[k])) { Command = Text.Substring(0, k).TrimEnd(new char[] { }); ArgumentSequence = Text.Substring(k + 1).TrimStart(new char[] { }); found = true; break; } else if (Text[k] == '(') { Command = Text.Substring(0, k).TrimEnd(new char[] { }); ArgumentSequence = Text.Substring(k).TrimStart(new char[] { }); found = true; break; } } if (!found) { if (RaiseErrors & !openingerror & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Invalid syntax encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); openingerror = true; closingerror = true; } Command = Text; ArgumentSequence = ""; } if (ArgumentSequence.StartsWith("(") & ArgumentSequence.EndsWith(")")) { // arguments are enclosed by parentheses ArgumentSequence = ArgumentSequence.Substring(1, ArgumentSequence.Length - 2).Trim(new char[] { }); } else if (ArgumentSequence.StartsWith("(")) { // only opening parenthesis found if (RaiseErrors & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Missing closing parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); } ArgumentSequence = ArgumentSequence.Substring(1).TrimStart(new char[] { }); } } } else { // no closing parenthesis found if (RaiseErrors & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Missing closing parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); } Command = Text.Substring(0, i).TrimEnd(new char[] { }); ArgumentSequence = Text.Substring(i + 2).TrimStart(new char[] { }); } } else { // no index possible Command = Text.Substring(0, i).TrimEnd(new char[] { }); ArgumentSequence = Text.Substring(i + 1).TrimStart(new char[] { }); if (ArgumentSequence.StartsWith("(") & ArgumentSequence.EndsWith(")")) { // arguments are enclosed by parentheses ArgumentSequence = ArgumentSequence.Substring(1, ArgumentSequence.Length - 2).Trim(new char[] { }); } else if (ArgumentSequence.StartsWith("(")) { // only opening parenthesis found if (RaiseErrors & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Missing closing parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); } ArgumentSequence = ArgumentSequence.Substring(1).TrimStart(new char[] { }); } } } } else { // no single space found if (Text.EndsWith(")")) { i = Text.LastIndexOf('('); if (i >= 0) { Command = Text.Substring(0, i).TrimEnd(new char[] { }); ArgumentSequence = Text.Substring(i + 1, Text.Length - i - 2).Trim(new char[] { }); } else { Command = Text; ArgumentSequence = ""; } } else { i = Text.IndexOf('('); if (i >= 0) { if (RaiseErrors & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Missing closing parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); } Command = Text.Substring(0, i).TrimEnd(new char[] { }); ArgumentSequence = Text.Substring(i + 1).TrimStart(new char[] { }); } else { if (RaiseErrors) { i = Text.IndexOf(')'); if (i >= 0 & !closingerror) { Interface.AddMessage(MessageType.Error, false, "Invalid closing parenthesis encountered at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); } } Command = Text; ArgumentSequence = ""; } } } // invalid trailing characters if (Command.EndsWith(";")) { if (RaiseErrors) { Interface.AddMessage(MessageType.Error, false, "Invalid trailing semicolon encountered in " + Command + " at line " + Line.ToString(Culture) + ", column " + Column.ToString(Culture) + " in file " + File); } while (Command.EndsWith(";")) { Command = Command.Substring(0, Command.Length - 1); } } }
internal static void ParsePatchNode(XmlNode node, ref Dictionary <string, RoutefilePatch> routeFixes) { RoutefilePatch currentPatch = new RoutefilePatch(); string currentHash = string.Empty; foreach (XmlElement childNode in node.ChildNodes.OfType <XmlElement>()) { string t; switch (childNode.Name) { case "Hash": currentHash = childNode.InnerText; break; case "FileName": currentPatch.FileName = childNode.InnerText; break; case "LineEndingFix": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.LineEndingFix = true; } else { currentPatch.LineEndingFix = false; } break; case "IgnorePitchRoll": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.IgnorePitchRoll = true; } else { currentPatch.IgnorePitchRoll = false; } break; case "LogMessage": currentPatch.LogMessage = childNode.InnerText; break; case "CylinderHack": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.CylinderHack = true; } else { currentPatch.CylinderHack = false; } break; case "Expression": t = childNode.Attributes["Number"].InnerText; int expressionNumber; if (NumberFormats.TryParseIntVb6(t, out expressionNumber)) { currentPatch.ExpressionFixes.Add(expressionNumber, childNode.InnerText); } break; case "XParser": switch (childNode.InnerText.ToLowerInvariant()) { case "original": currentPatch.XParser = XParsers.Original; break; case "new": currentPatch.XParser = XParsers.NewXParser; break; case "assimp": currentPatch.XParser = XParsers.Assimp; break; } break; case "DummyRailTypes": string[] splitString = childNode.InnerText.Split(','); for (int i = 0; i < splitString.Length; i++) { int rt; if (NumberFormats.TryParseIntVb6(splitString[i], out rt)) { currentPatch.DummyRailTypes.Add(rt); } } break; case "DummyGroundTypes": splitString = childNode.InnerText.Split(','); for (int i = 0; i < splitString.Length; i++) { int gt; if (NumberFormats.TryParseIntVb6(splitString[i], out gt)) { currentPatch.DummyGroundTypes.Add(gt); } } break; case "Derailments": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "0" || t == "false") { currentPatch.Derailments = false; } else { currentPatch.Derailments = true; } break; case "Toppling": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "0" || t == "false") { currentPatch.Derailments = false; } else { currentPatch.Derailments = true; } break; case "SignalSet": string signalFile = Path.CombineFile(Plugin.FileSystem.GetDataFolder("Compatibility\\Signals"), childNode.InnerText.Trim()); if (File.Exists(signalFile)) { currentPatch.CompatibilitySignalSet = signalFile; } break; case "AccurateObjectDisposal": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.AccurateObjectDisposal = true; } else { currentPatch.AccurateObjectDisposal = false; } break; case "SplitLineHack": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.SplitLineHack = true; } else { currentPatch.SplitLineHack = false; } break; case "AllowTrackPositionArguments": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.AllowTrackPositionArguments = true; } else { currentPatch.AllowTrackPositionArguments = false; } break; case "DisableSemiTransparentFaces": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.DisableSemiTransparentFaces = true; } else { currentPatch.DisableSemiTransparentFaces = false; } break; case "ReducedColorTransparency": t = childNode.InnerText.Trim().ToLowerInvariant(); if (t == "1" || t == "true") { currentPatch.ReducedColorTransparency = true; } else { currentPatch.ReducedColorTransparency = false; } break; } } if (!routeFixes.ContainsKey(currentHash)) { routeFixes.Add(currentHash, currentPatch); } else { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "The RoutePatches database contains a duplicate entry with hash " + currentHash); } }
private void ParseTrainCommand(TrainCommand Command, string[] Arguments, int Index, Expression Expression, ref RouteData Data, bool PreviewOnly) { switch (Command) { case TrainCommand.Interval: { if (!PreviewOnly) { List <double> intervals = new List <double>(); for (int k = 0; k < Arguments.Length; k++) { double o; if (!NumberFormats.TryParseDoubleVb6(Arguments[k], out o)) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Interval " + k.ToString(Culture) + " is invalid in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); continue; } if (o == 0) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Interval " + k.ToString(Culture) + " must be non-zero in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); continue; } if (o > 43200 && Plugin.CurrentOptions.EnableBveTsHacks) { //Southern Blighton- Treston park has a runinterval of well over 24 hours, and there are likely others //Discard this Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Interval " + k.ToString(Culture) + " is greater than 12 hours in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); continue; } if (o < 120 && Plugin.CurrentOptions.EnableBveTsHacks) { /* * An AI train follows the same schedule / rules as the player train * ==> * x Waiting time before departure at the first station (30s to 1min is 'normal') * x Time to accelerate to linespeed * x Time to clear (as a minimum) the protecting signal on station exit * * When the runinterval is below ~2minutes, on large numbers of routes, this * shows up as a train overlapping the player train (bad....) */ o = 120; } intervals.Add(o); } intervals.Sort(); if (intervals.Count > 0) { CurrentRoute.PrecedingTrainTimeDeltas = intervals.ToArray(); } } } break; case TrainCommand.Velocity: { if (!PreviewOnly) { double limit = 0.0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseDoubleVb6(Arguments[0], out limit)) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Speed is invalid in Train.Velocity at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); limit = 0.0; } Plugin.CurrentOptions.PrecedingTrainSpeedLimit = limit <= 0.0 ? double.PositiveInfinity : Data.UnitOfSpeed * limit; } } break; case TrainCommand.Folder: case TrainCommand.File: { if (PreviewOnly) { if (Arguments.Length < 1) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, Command + " is expected to have one argument 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, "FolderName contains illegal characters in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { Plugin.CurrentOptions.TrainName = Arguments[0]; } } } } break; case TrainCommand.Run: case TrainCommand.Rail: { if (!PreviewOnly) { if (Index < 0) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "RailTypeIndex is out of range in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { int val = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseIntVb6(Arguments[0], out val)) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "RunSoundIndex is invalid in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); val = 0; } if (val < 0) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "RunSoundIndex is expected to be non-negative in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); val = 0; } if (Index >= Data.Structure.Run.Length) { Array.Resize(ref Data.Structure.Run, Index + 1); } Data.Structure.Run[Index] = val; } } } break; case TrainCommand.Flange: { if (!PreviewOnly) { if (Index < 0) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "RailTypeIndex is out of range in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { int val = 0; if (Arguments.Length >= 1 && Arguments[0].Length > 0 && !NumberFormats.TryParseIntVb6(Arguments[0], out val)) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "FlangeSoundIndex is invalid in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); val = 0; } if (val < 0) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "FlangeSoundIndex expected to be non-negative in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); val = 0; } if (Index >= Data.Structure.Flange.Length) { Array.Resize(ref Data.Structure.Flange, Index + 1); } Data.Structure.Flange[Index] = val; } } } break; case TrainCommand.TimetableDay: { if (!PreviewOnly) { if (Index < 0) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "TimetableIndex is expected to be non-negative 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.Error, false, Command + " is expected to have one argument 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, "FileName " + Arguments[0] + " contains illegal characters in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { while (Index >= Data.TimetableDaytime.Length) { int n = Data.TimetableDaytime.Length; Array.Resize(ref Data.TimetableDaytime, n << 1); for (int i = n; i < Data.TimetableDaytime.Length; i++) { Data.TimetableDaytime[i] = null; } } string f = string.Empty; if (!string.IsNullOrEmpty(TrainPath)) { f = Path.CombineFile(TrainPath, Arguments[0]); } if (!System.IO.File.Exists(f)) { f = Path.CombineFile(ObjectPath, Arguments[0]); } if (System.IO.File.Exists(f)) { Plugin.CurrentHost.RegisterTexture(f, new TextureParameters(null, null), out Data.TimetableDaytime[Index]); } else { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "DaytimeTimetable " + Index + " with FileName " + Arguments[0] + " was not found in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } } } } } break; case TrainCommand.TimetableNight: { if (!PreviewOnly) { if (Index < 0) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "TimetableIndex is expected to be non-negative 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.Error, false, Command + " is expected to have one argument 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, "FileName " + Arguments[0] + " contains illegal characters in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { while (Index >= Data.TimetableNighttime.Length) { int n = Data.TimetableNighttime.Length; Array.Resize(ref Data.TimetableNighttime, n << 1); for (int i = n; i < Data.TimetableNighttime.Length; i++) { Data.TimetableNighttime[i] = null; } } string f = string.Empty; if (!string.IsNullOrEmpty(TrainPath)) { f = Path.CombineFile(TrainPath, Arguments[0]); } if (!System.IO.File.Exists(f)) { f = Path.CombineFile(ObjectPath, Arguments[0]); } if (System.IO.File.Exists(f)) { Plugin.CurrentHost.RegisterTexture(f, new TextureParameters(null, null), out Data.TimetableNighttime[Index]); } else { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "DaytimeTimetable " + Index + " with FileName " + Arguments[0] + " was not found in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } } } } } break; case TrainCommand.Destination: { if (!PreviewOnly) { if (Arguments.Length < 1) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, Command + " is expected to have one argument at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } else { if (!NumberFormats.TryParseIntVb6(Arguments[0], out Plugin.CurrentOptions.InitialDestination)) { Plugin.CurrentHost.AddMessage(MessageType.Error, false, "Destination is expected to be an Integer in " + Command + " at line " + Expression.Line.ToString(Culture) + ", column " + Expression.Column.ToString(Culture) + " in file " + Expression.File); } } } } break; } }
internal static void Process(Form form) { mainForm = form; if (!System.IO.File.Exists(FileName)) { MessageBox.Show("The selected folder does not contain a valid train.dat \r\n Please retry.", "CarXML Convertor", MessageBoxButtons.OK, MessageBoxIcon.Information); } string[] Lines = System.IO.File.ReadAllLines(FileName); for (int i = 0; i < Lines.Length; i++) { int n = 0; switch (Lines[i].ToLowerInvariant()) { case "#cockpit": case "#cab": i++; while (i < Lines.Length && !Lines[i].StartsWith("#", StringComparison.Ordinal)) { double a; if (NumberFormats.TryParseDoubleVb6(Lines[i], out a)) { switch (n) { case 0: ConvertSoundCfg.DriverPosition.X = 0.001 * a; break; case 1: ConvertSoundCfg.DriverPosition.Y = 0.001 * a; break; case 2: ConvertSoundCfg.DriverPosition.Z = 0.001 * a; break; case 3: DriverCar = (int)Math.Round(a); break; } } i++; n++; } i--; break; case "#car": i++; while (i < Lines.Length && !Lines[i].StartsWith("#", StringComparison.Ordinal)) { double a; if (NumberFormats.TryParseDoubleVb6(Lines[i], out a)) { switch (n) { case 0: if (!(a <= 0.0)) { MotorCarMass = a * 1000.0; } break; case 1: if (!(a <= 0.0)) { NumberOfMotorCars = (int)Math.Round(a); } break; case 2: if (!(a <= 0.0)) { TrailerCarMass = a * 1000.0; } break; case 3: if (!(a <= 0.0)) { NumberOfTrailerCars = (int)Math.Round(a); } break; case 4: if (!(a <= 0.0)) { CarLength = a; } break; case 5: FrontCarIsMotorCar = a == 1.0; break; case 6: if (!(a <= 0.0)) { CarWidth = a; } break; case 7: if (!(a <= 0.0)) { CarHeight = a; } break; } } i++; n++; } i--; break; default: { i++; while (i < Lines.Length && !Lines[i].StartsWith("#", StringComparison.Ordinal)) { i++; n++; } i--; } break; } } NumberOfCars = NumberOfMotorCars + NumberOfTrailerCars; MotorCars = new bool[NumberOfCars]; if (NumberOfMotorCars == 1) { if (FrontCarIsMotorCar | NumberOfTrailerCars == 0) { MotorCars[0] = true; } else { MotorCars[NumberOfCars - 1] = true; } } else if (NumberOfMotorCars == 2) { if (FrontCarIsMotorCar | NumberOfTrailerCars == 0) { MotorCars[0] = true; MotorCars[NumberOfCars - 1] = true; } else if (NumberOfTrailerCars == 1) { MotorCars[1] = true; MotorCars[2] = true; } else { int i = (int)Math.Ceiling(0.25 * (double)(NumberOfCars - 1)); int j = (int)Math.Floor(0.75 * (double)(NumberOfCars - 1)); MotorCars[i] = true; MotorCars[j] = true; } } else if (NumberOfMotorCars > 0) { if (FrontCarIsMotorCar) { MotorCars[0] = true; double t = 1.0 + (double)NumberOfTrailerCars / (double)(NumberOfMotorCars - 1); double r = 0.0; double x = 0.0; while (true) { double y = x + t - r; x = Math.Ceiling(y); r = x - y; int i = (int)x; if (i >= NumberOfCars) { break; } MotorCars[i] = true; } } else { MotorCars[1] = true; double t = 1.0 + (double)(NumberOfTrailerCars - 1) / (double)(NumberOfMotorCars - 1); double r = 0.0; double x = 1.0; while (true) { double y = x + t - r; x = Math.Ceiling(y); r = x - y; int i = (int)x; if (i >= NumberOfCars) { break; } MotorCars[i] = true; } } } }
/// <summary> /// Formats a number for output. /// </summary> /// <example> /// <code> /// using Mezzocode.Halide3; /// ... /// string result = h3Text.FormatNumber(value, h3Text.NumberFormats.Currency); /// </code> /// </example> /// <param name="value">Numeric value to format.</param> /// <param name="format">Enumeration with preset number formats.</param> /// <returns>String with the formatted number.</returns> public static String FormatNumber(string value, NumberFormats format) { Int64 newValue = Convert.ToInt64(value); return FormatNumber(newValue, format); }
/// <summary> /// Formats a number for output. /// </summary> /// <example> /// <code> /// using Mezzocode.Halide3; /// ... /// string result = h3Text.FormatNumber(value, h3Text.NumberFormats.Currency); /// </code> /// </example> /// <param name="value">Numeric value to format.</param> /// <param name="format">Enumeration with preset number formats.</param> /// <returns>String with the formatted number.</returns> public static String FormatNumber(Int64 value, NumberFormats format) { string retVal = value.ToString(); switch (format) { case NumberFormats.Currency: retVal = value.ToString("c"); break; case NumberFormats.DiskStorage: // KILOBYTE if (value < 1048576) { float newVal = (float)value / 1024; retVal = (newVal.ToString("#,##0")) + "kb"; } // MEGABYTES if (value >= 1048576 && value < 1073741824) { float newVal = (float)(value / 1024) / 1024; retVal = (newVal.ToString("#,##0.0")) + "mb"; } // GIGABYTES if (value >= 1073741824 && value < 1099511627776) { float newVal = (float)((value / 1024) / 1024) / 1024; retVal = (newVal.ToString("#,##0.0")) + "gb"; } // TERABYTES if (value >= 1099511627776 && value < 1125899906842624) { float newVal = (float)(((value / 1024) / 1024) / 1024) / 1024; retVal = (newVal.ToString("#,##0.0")) + "tb"; } // PETABYTES if (value >= 1125899906842624 && value < 1152921504606846976) { float newVal = (float)((((value / 1024) / 1024) / 1024) / 1024) / 1024; retVal = (newVal.ToString("#,##0.0")) + "pb"; } break; } return retVal; }