public MSTSData(string mstsPath, string Route) { MstsPath = mstsPath; RoutePath = Route; TRK = new RouteFile(MSTS.MSTSPath.GetTRKFileName(RoutePath)); string routePath = Path.Combine(Route, TRK.Tr_RouteFile.FileName); TDB = new TrackDatabaseFile(RoutePath + @"\" + TRK.Tr_RouteFile.FileName + ".tdb"); string ORfilepath = System.IO.Path.Combine(RoutePath, "OpenRails"); if (File.Exists(ORfilepath + @"\sigcfg.dat")) { SIGCFG = new SignalConfigurationFile(ORfilepath + @"\sigcfg.dat", true); } else { SIGCFG = new SignalConfigurationFile(RoutePath + @"\sigcfg.dat", false); } if (Directory.Exists(MstsPath + @"\GLOBAL") && File.Exists(MstsPath + @"\GLOBAL\TSECTION.DAT")) { TSectionDat = new TrackSectionsFile(MstsPath + @"\GLOBAL\TSECTION.DAT"); } else { TSectionDat = new TrackSectionsFile(RoutePath + @"\GLOBAL\TSECTION.DAT"); } if (File.Exists(RoutePath + @"\TSECTION.DAT")) { TSectionDat.AddRouteTSectionDatFile(RoutePath + @"\TSECTION.DAT"); } Signals = new AESignals(this, SIGCFG); }
public MSTSBase(TrackDatabaseFile TDB) { double minTileX = double.PositiveInfinity; double minTileY = double.PositiveInfinity; TrackNode[] nodes = TDB.TrackDB.TrackNodes; for (int nodeIdx = 0; nodeIdx < nodes.Length; nodeIdx++) { if (nodes[nodeIdx] == null) { continue; } TrackNode currNode = nodes[nodeIdx]; if (currNode.TrVectorNode != null && currNode.TrVectorNode.TrVectorSections != null) { if (currNode.TrVectorNode.TrVectorSections.Length > 1) { foreach (TrPin pin in currNode.TrPins) { if (minTileX > nodes[pin.Link].UiD.TileX) { minTileX = nodes[pin.Link].UiD.TileX; } if (minTileY > nodes[pin.Link].UiD.TileZ) { minTileY = nodes[pin.Link].UiD.TileZ; } } } else { TrVectorSection s; s = currNode.TrVectorNode.TrVectorSections[0]; if (minTileX > s.TileX) { minTileX = s.TileX; } if (minTileY > s.TileZ) { minTileY = s.TileZ; } } } else if (currNode.TrJunctionNode != null) { if (minTileX > currNode.UiD.TileX) { minTileX = currNode.UiD.TileX; } if (minTileY > currNode.UiD.TileZ) { minTileY = currNode.UiD.TileZ; } } } TileX = minTileX; TileY = minTileY; }
public void SetTraveller(TrackSectionsFile TSectionDat, TrackDatabaseFile TDB) { TrackNode[] TrackNodes = TDB.TrackDB.TrackNodes; traveller = new AETraveller(TSectionDat, TDB); foreach (var item in routeItems) { if (item.GetType() == typeof(StationItem)) { ((StationItem)item).setTraveller(traveller); } } }
/// <summary> /// Returns the index of the vector node connection this path node to the (given) nextNode. /// </summary> public int FindTVNIndex(AIPathNode nextNode, TrackDatabaseFile TDB, TrackSectionsFile tsectiondat) { int junctionIndexThis = JunctionIndex; int junctionIndexNext = nextNode.JunctionIndex; // if this is no junction, try to find the TVN index if (junctionIndexThis < 0) { try { return(findTrackNodeIndex(TDB, tsectiondat, this)); } catch { junctionIndexThis = FindJunctionOrEndIndex(this.Location, TDB.TrackDB, false); } } // this is a junction; if the next node is no junction, try that one. if (junctionIndexNext < 0) { try { return(findTrackNodeIndex(TDB, tsectiondat, nextNode)); } catch { junctionIndexNext = FindJunctionOrEndIndex(nextNode.Location, TDB.TrackDB, false); } } //both this node and the next node are junctions: find the vector node connecting them. for (int i = 0; i < TDB.TrackDB.TrackNodes.Count(); i++) { TrackNode tn = TDB.TrackDB.TrackNodes[i]; if (tn == null || tn.TrVectorNode == null) { continue; } if (tn.TrPins[0].Link == junctionIndexThis && tn.TrPins[1].Link == junctionIndexNext) { return(i); } if (tn.TrPins[1].Link == junctionIndexThis && tn.TrPins[0].Link == junctionIndexNext) { return(i); } } return(-1); }
/// <summary> /// /// </summary> /// <param name="sideItem"></param> /// <param name="signal"></param> public AESignalItem(SignalItem item, AESignalObject signal, TrackDatabaseFile TDB) { typeItem = (int)TypeItem.SIGNAL_ITEM; Item = item; Signal = signal; sigFonction = new List <MstsSignalFunction>(); foreach (var sig in Signal.SignalHeads) { sigFonction.Add(sig.sigFunction); } hasDir = false; Location.X = item.TileX * 2048 + item.X; Location.Y = item.TileZ * 2048 + item.Z; try { associateNode = TDB.TrackDB.TrackNodes[signal.trackNode]; Vector2 v2; if (associateNode.TrVectorNode != null) { associateNodeIdx = (int)associateNode.Index; var ts = associateNode.TrVectorNode.TrVectorSections[0]; v2 = new Vector2(ts.TileX * 2048 + ts.X, ts.TileZ * 2048 + ts.Z); } else if (associateNode.TrJunctionNode != null) { associateNodeIdx = associateNode.TrJunctionNode.Idx; var ts = associateNode.UiD; v2 = new Vector2(ts.TileX * 2048 + ts.X, ts.TileZ * 2048 + ts.Z); } else { throw new Exception(); } var v1 = new Vector2(Location.X, Location.Y); var v3 = v1 - v2; v3.Normalize(); v2 = v1 - Vector2.Multiply(v3, signal.direction == 0 ? 12f : -12f); //v2 = v1 - Vector2.Multiply(v3, 12f); Dir.X = (float)v2.X; Dir.Y = (float)v2.Y; //v2 = v1 - Vector2.Multiply(v3, signal.direction == 0 ? 1.5f : -1.5f);//shift signal along the dir for 2m, so signals will not be overlapped v2 = v1 - Vector2.Multiply(v3, 1.5f); Location.X = (float)v2.X; Location.Y = (float)v2.Y; hasDir = true; } catch { } }
internal async Task LoadTrackData(bool?useMetricUnits, CancellationToken cancellationToken) { List <Task> loadTasks = new List <Task>(); FolderStructure.ContentFolder.RouteFolder routeFolder = FolderStructure.Route(routePath); RouteFile routeFile = new RouteFile(routeFolder.TrackFileName); RouteName = routeFile.Route.Name; UseMetricUnits = useMetricUnits.GetValueOrDefault(routeFile.Route.MilepostUnitsMetric); loadTasks.Add(Task.Run(() => { string tdbFile = routeFolder.TrackDatabaseFile(routeFile); if (!File.Exists(tdbFile)) { Trace.TraceError($"Track Database File not found in {tdbFile}"); return; } TrackDB = new TrackDatabaseFile(tdbFile).TrackDB; }, cancellationToken)); loadTasks.Add(Task.Run(() => { TrackSections = new TrackSectionsFile(routeFolder.TrackSectionFile); if (File.Exists(routeFolder.RouteTrackSectionFile)) { TrackSections.AddRouteTSectionDatFile(routeFolder.RouteTrackSectionFile); } }, cancellationToken)); loadTasks.Add(Task.Run(() => { string rdbFile = routeFolder.RoadTrackDatabaseFile(routeFile); if (!File.Exists(rdbFile)) { Trace.TraceError($"Road Database File not found in {rdbFile}"); return; } RoadTrackDB = new RoadDatabaseFile(rdbFile).RoadTrackDB; }, cancellationToken)); loadTasks.Add(Task.Run(() => SignalConfig = new SignalConfigurationFile(routeFolder.SignalConfigurationFile, routeFolder.ORSignalConfigFile), cancellationToken)); await Task.WhenAll(loadTasks).ConfigureAwait(false); }
// restore game state public AIPath(TrackDatabaseFile TDB, TrackSectionsFile tsectiondat, BinaryReader inf) { pathName = inf.ReadString(); TrackDB = TDB.TrackDB; TSectionDat = tsectiondat; int n = inf.ReadInt32(); for (int i = 0; i < n; i++) { Nodes.Add(new AIPathNode(inf)); } for (int i = 0; i < n; i++) { Nodes[i].NextMainNode = ReadNode(inf); Nodes[i].NextSidingNode = ReadNode(inf); } FirstNode = Nodes[0]; //LastVisitedNode = ReadNode(inf); }
public void reduce(TrackDatabaseFile TDB) { TrackNode[] nodes = TDB.TrackDB.TrackNodes; for (int nodeIdx = 0; nodeIdx < nodes.Length; nodeIdx++) { if (nodes[nodeIdx] == null) { continue; } ((TrackNode)TDB.TrackDB.TrackNodes[nodeIdx]).reduce(TileX, TileY); } if (TDB.TrackDB.TrItemTable == null) { return; } foreach (var item in TDB.TrackDB.TrItemTable) { item.TileX -= (int)TileX; item.TileZ -= (int)TileY; } }
/// <summary> /// Try to find the tracknode corresponding to the given node's location. /// This will raise an exception if it cannot be found /// </summary> /// <param name="TDB"></param> /// <param name="tsectiondat"></param> /// <param name="node"></param> /// <returns>The track node index that has been found (or an exception)</returns> private static int findTrackNodeIndex(TrackDatabaseFile TDB, TrackSectionsFile tsectiondat, AIPathNode node) { Traveller traveller = new Traveller(tsectiondat, TDB.TrackDB.TrackNodes, node.Location); return(traveller.TrackNodeIndex); }
public string pathName; //name of the path to be able to print it. /// <summary> /// Creates an AIPath from PAT file information. /// First creates all the nodes and then links them together into a main list /// with optional parallel siding list. /// </summary> public AIPath(TrackDatabaseFile TDB, TrackSectionsFile tsectiondat, string filePath, bool isTimetableMode) { PathFile patFile = new PathFile(filePath); pathName = patFile.Name; TrackDB = TDB.TrackDB; TSectionDat = tsectiondat; bool fatalerror = false; if (patFile.PathNodes.Count <= 0) { fatalerror = true; Nodes = null; return; } foreach (PathNode tpn in patFile.PathNodes) { Nodes.Add(new AIPathNode(tpn, patFile.DataPoints[(int)tpn.PathDataPoint], TrackDB, isTimetableMode)); } FirstNode = Nodes[0]; //LastVisitedNode = FirstNode; // Connect the various nodes to each other for (int i = 0; i < Nodes.Count; i++) { AIPathNode node = Nodes[i]; node.Index = i; PathNode tpn = patFile.PathNodes[i]; // find TVNindex to next main node. if (tpn.HasNextMainNode) { node.NextMainNode = Nodes[(int)tpn.NextMainNode]; node.NextMainTVNIndex = node.FindTVNIndex(node.NextMainNode, TDB, tsectiondat, i == 0 ? -1 : Nodes[i - 1].NextMainTVNIndex); if (node.JunctionIndex >= 0) { node.IsFacingPoint = TestFacingPoint(node.JunctionIndex, node.NextMainTVNIndex); } if (node.NextMainTVNIndex < 0) { node.NextMainNode = null; Trace.TraceWarning("Cannot find main track for node {1} in path {0}", filePath, i); fatalerror = true; } } // find TVNindex to next siding node if (tpn.HasNextSidingNode) { node.NextSidingNode = Nodes[(int)tpn.NextSidingNode]; node.NextSidingTVNIndex = node.FindTVNIndex(node.NextSidingNode, TDB, tsectiondat, i == 0 ? -1 : Nodes[i - 1].NextMainTVNIndex); if (node.JunctionIndex >= 0) { node.IsFacingPoint = TestFacingPoint(node.JunctionIndex, node.NextSidingTVNIndex); } if (node.NextSidingTVNIndex < 0) { node.NextSidingNode = null; Trace.TraceWarning("Cannot find siding track for node {1} in path {0}", filePath, i); fatalerror = true; } } if (node.NextMainNode != null && node.NextSidingNode != null) { node.Type = AIPathNodeType.SidingStart; } } FindSidingEnds(); if (fatalerror) { Nodes = null; // invalid path - do not return any nodes } }
/// <summary> /// Returns the index of the vector node connection this path node to the (given) nextNode. /// </summary> public int FindTVNIndex(AIPathNode nextNode, TrackDatabaseFile TDB, TrackSectionsFile tsectiondat, int previousNextMainTVNIndex) { int junctionIndexThis = JunctionIndex; int junctionIndexNext = nextNode.JunctionIndex; // if this is no junction, try to find the TVN index if (junctionIndexThis < 0) { try { return(findTrackNodeIndex(TDB, tsectiondat, this)); } catch { junctionIndexThis = FindJunctionOrEndIndex(this.Location, TDB.TrackDB, false); } } // this is a junction; if the next node is no junction, try that one. if (junctionIndexNext < 0) { try { return(findTrackNodeIndex(TDB, tsectiondat, nextNode)); } catch { junctionIndexNext = FindJunctionOrEndIndex(nextNode.Location, TDB.TrackDB, false); } } //both this node and the next node are junctions: find the vector node connecting them. var iCand = -1; for (int i = 0; i < TDB.TrackDB.TrackNodes.Count(); i++) { if (!(TDB.TrackDB.TrackNodes[i] is TrackVectorNode tn)) { continue; } if (tn.TrackPins[0].Link == junctionIndexThis && tn.TrackPins[1].Link == junctionIndexNext) { iCand = i; if (i != previousNextMainTVNIndex) { break; } Trace.TraceInformation("Managing rocket loop at trackNode {0}", iCand); } else if (tn.TrackPins[1].Link == junctionIndexThis && tn.TrackPins[0].Link == junctionIndexNext) { iCand = i; if (i != previousNextMainTVNIndex) { break; } Trace.TraceInformation("Managing rocket loop at trackNode {0}", iCand); } } return(iCand); }
/// <summary> /// Try to load the file. /// Possibly this might raise an exception. That exception is not caught here /// </summary> /// <param name="file">The file that needs to be loaded</param> public override void TryLoading(string file) { loadedFile = file; TDBfile = new TrackDatabaseFile(file); }
public string pathName; //name of the path to be able to print it. /// <summary> /// Creates an AIPath from PAT file information. /// First creates all the nodes and then links them together into a main list /// with optional parallel siding list. /// </summary> #if ACTIVITY_EDITOR public AIPath(TrackDatabaseFile TDB, TrackSectionsFile tsectiondat, string filePath, bool isTimetableMode, ORRouteConfig orRouteConf)