/// <summary>Loads a list of compatibility signal objects</summary> /// <param name="currentHost">The host application interface</param> /// <param name="fileName">The file name of the object list</param> /// <param name="objects">The returned array of speed limits</param> /// <param name="signalPost">Sets the default signal post</param> /// <param name="speedLimits">The array of signal speed limits</param> /// <returns>An array of compatability signal objects</returns> public static void ReadCompatibilitySignalXML(HostInterface currentHost, string fileName, out CompatibilitySignalObject[] objects, out UnifiedObject signalPost, out double[] speedLimits) { signalPost = new StaticObject(currentHost); objects = new CompatibilitySignalObject[9]; //Default Japanese speed limits converted to m/s speedLimits = new[] { 0.0, 6.94444444444444, 15.2777777777778, 20.8333333333333, double.PositiveInfinity, double.PositiveInfinity }; XmlDocument currentXML = new XmlDocument(); currentXML.Load(fileName); string currentPath = System.IO.Path.GetDirectoryName(fileName); if (currentXML.DocumentElement != null) { XmlNode node = currentXML.SelectSingleNode("/openBVE/CompatibilitySignals/SignalSetName"); if (node != null) { currentHost.AddMessage(MessageType.Information, false, "INFO: Using the " + node.InnerText + " compatibility signal set."); } XmlNodeList DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CompatibilitySignals/Signal"); if (DocumentNodes != null) { int index = 0; foreach (XmlNode nn in DocumentNodes) { List <StaticObject> objectList = new List <StaticObject>(); List <int> aspectList = new List <int>(); try { if (nn.HasChildNodes) { foreach (XmlNode n in nn.ChildNodes) { if (n.Name != "Aspect") { continue; } int aspect = 0; if (!NumberFormats.TryParseIntVb6(n.Attributes["Number"].Value, out aspect)) { currentHost.AddMessage(MessageType.Error, true, "Invalid aspect number " + aspect + " in the signal object list in the compatability signal file " + fileName); continue; } aspectList.Add(aspect); StaticObject staticObject = new StaticObject(currentHost); if (n.InnerText.ToLowerInvariant() != "null") { string objectFile = Path.CombineFile(currentPath, n.InnerText); if (File.Exists(objectFile)) { currentHost.LoadStaticObject(objectFile, Encoding.UTF8, false, out staticObject); } else { currentHost.AddMessage(MessageType.Error, true, "Compatibility signal file " + objectFile + " not found in " + fileName); } } objectList.Add(staticObject); } } } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } objects[index] = new CompatibilitySignalObject(aspectList.ToArray(), objectList.ToArray()); index++; } } string signalPostFile = Path.CombineFile(currentPath, "Japanese\\signal_post.csv"); //default plain post try { node = currentXML.SelectSingleNode("/openBVE/CompatibilitySignals/SignalPost"); if (node != null) { string newFile = Path.CombineFile(currentPath, node.InnerText); if (System.IO.File.Exists(newFile)) { signalPostFile = newFile; } } currentHost.LoadObject(signalPostFile, Encoding.UTF8, out signalPost); } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } DocumentNodes = currentXML.DocumentElement.SelectNodes("/openBVE/CompatibilitySignals/SpeedLimits"); if (DocumentNodes != null) { foreach (XmlNode nn in DocumentNodes) { try { if (nn.HasChildNodes) { foreach (XmlNode n in nn.ChildNodes) { if (n.Name != "Aspect") { continue; } int aspect = 0; if (n.Attributes != null) { if (!NumberFormats.TryParseIntVb6(n.Attributes["Number"].Value, out aspect)) { currentHost.AddMessage(MessageType.Error, true, "Invalid aspect number " + aspect + " in the speed limit list in the compatability signal file " + fileName); continue; } } if (aspect <= speedLimits.Length) { int l = speedLimits.Length; Array.Resize(ref speedLimits, aspect + 1); for (int i = l; i < speedLimits.Length; i++) { speedLimits[i] = double.PositiveInfinity; } if (!NumberFormats.TryParseDoubleVb6(n.InnerText, out speedLimits[aspect])) { speedLimits[aspect] = double.MaxValue; if (n.InnerText.ToLowerInvariant() != "unlimited") { currentHost.AddMessage(MessageType.Error, true, "Invalid speed limit provided for aspect " + aspect + " in the compatability signal file " + fileName); } } else { //convert to m/s as that's what we use internally speedLimits[aspect] *= 0.277777777777778; } } } } } catch { currentHost.AddMessage(MessageType.Error, true, "An unexpected error was encountered whilst processing the compatability signal file " + fileName); } } } } }
public override bool LoadTrain(Encoding Encoding, string trainPath, ref AbstractTrain train, ref Control[] currentControls) { CurrentControls = currentControls; TrainBase currentTrain = train as TrainBase; if (currentTrain == null) { currentHost.ReportProblem(ProblemType.InvalidData, "Train was not valid"); return(false); } if (currentTrain.State == TrainState.Bogus) { // bogus train string TrainData = Path.CombineFile(FileSystem.GetDataFolder("Compatibility", "PreTrain"), "train.dat"); TrainDatParser.Parse(TrainData, Encoding.UTF8, currentTrain); Thread.Sleep(1); if (Cancel) { return(false); } } else { currentTrain.TrainFolder = trainPath; // real train if (currentTrain.IsPlayerTrain) { FileSystem.AppendToLogFile("Loading player train: " + currentTrain.TrainFolder); } else { FileSystem.AppendToLogFile("Loading AI train: " + currentTrain.TrainFolder); } string TrainData = Path.CombineFile(currentTrain.TrainFolder, "train.dat"); TrainDatParser.Parse(TrainData, Encoding, currentTrain); Thread.Sleep(1); if (Cancel) { return(false); } SoundCfgParser.ParseSoundConfig(currentTrain); Thread.Sleep(1); if (Cancel) { return(false); } // door open/close speed for (int i = 0; i < currentTrain.Cars.Length; i++) { currentTrain.Cars[i].DetermineDoorClosingSpeed(); } } // add panel section if (currentTrain.IsPlayerTrain) { ParsePanelConfig(currentTrain, Encoding); Thread.Sleep(1); if (Cancel) { return(false); } FileSystem.AppendToLogFile("Train panel loaded sucessfully."); } // add exterior section if (currentTrain.State != TrainState.Bogus) { bool[] VisibleFromInterior = new bool[currentTrain.Cars.Length]; UnifiedObject[] CarObjects = new UnifiedObject[currentTrain.Cars.Length]; UnifiedObject[] BogieObjects = new UnifiedObject[currentTrain.Cars.Length * 2]; UnifiedObject[] CouplerObjects = new UnifiedObject[currentTrain.Cars.Length]; string tXml = Path.CombineFile(currentTrain.TrainFolder, "train.xml"); if (File.Exists(tXml)) { TrainXmlParser.Parse(tXml, currentTrain, ref CarObjects, ref BogieObjects, ref CouplerObjects, ref VisibleFromInterior); } else { ExtensionsCfgParser.ParseExtensionsConfig(currentTrain.TrainFolder, Encoding, ref CarObjects, ref BogieObjects, ref CouplerObjects, ref VisibleFromInterior, currentTrain); } currentTrain.CameraCar = currentTrain.DriverCar; Thread.Sleep(1); if (Cancel) { return(false); } //Stores the current array index of the bogie object to add //Required as there are two bogies per car, and we're using a simple linear array.... int currentBogieObject = 0; for (int i = 0; i < currentTrain.Cars.Length; i++) { if (CarObjects[i] == null) { // load default exterior object string file = Path.CombineFile(FileSystem.GetDataFolder("Compatibility"), "exterior.csv"); StaticObject so; currentHost.LoadStaticObject(file, Encoding.UTF8, false, out so); if (so == null) { CarObjects[i] = null; } else { StaticObject c = (StaticObject)so.Clone(); //Clone as otherwise the cached object doesn't scale right c.ApplyScale(currentTrain.Cars[i].Width, currentTrain.Cars[i].Height, currentTrain.Cars[i].Length); CarObjects[i] = c; } } if (CarObjects[i] != null) { // add object currentTrain.Cars[i].LoadCarSections(CarObjects[i], VisibleFromInterior[i]); } if (CouplerObjects[i] != null) { currentTrain.Cars[i].Coupler.LoadCarSections(CouplerObjects[i], VisibleFromInterior[i]); } //Load bogie objects if (BogieObjects[currentBogieObject] != null) { currentTrain.Cars[i].FrontBogie.LoadCarSections(BogieObjects[currentBogieObject], VisibleFromInterior[i]); } currentBogieObject++; if (BogieObjects[currentBogieObject] != null) { currentTrain.Cars[i].RearBogie.LoadCarSections(BogieObjects[currentBogieObject], VisibleFromInterior[i]); } currentBogieObject++; } } // place cars currentTrain.PlaceCars(0.0); currentControls = CurrentControls; return(true); }