示例#1
0
 /// <summary>
 /// Constructor that immediately sets the closest item (and distance)
 /// </summary>
 /// <param name="tn">Tracknode that will be stored as closest item</param>
 /// <param name="tsectionDat">The track section Dat file that we can use to calculate the distance to the track</param>
 public CloseToMouseTrack(TrackSectionsFile tsectionDat, TrackNode tn)
 {
     this.tsectionDat = tsectionDat;
     sortedTrackCandidates = new SortedList<double, TrackCandidate>(new ReverseDoubleComparer());
     sortedTrackCandidates.Add(0, new TrackCandidate(tn, null, 0, 0));
     realDistancesAreCalculated = true; // we do not want to calculate distance if we override the highlight
 }
示例#2
0
        /// <summary>
        /// Creates an trainpath from PAT file information.
        /// First creates all the nodes and then links them together into a main list
        /// with optional parallel siding list.
        /// </summary>
        /// <param name="trackDB"></param>
        /// <param name="tsectionDat"></param>
        /// <param name="filePath">file name including path of the .pat file</param>
        public Trainpath(TrackDB trackDB, TrackSectionsFile tsectionDat, string filePath)
            : this(trackDB, tsectionDat)
        {
            this.FilePath = filePath;

            PathFile patFile = new PathFile(filePath);

            if (PatFileIsIncomplete(patFile))
            {
                MessageBox.Show("The .pat file is somehow incomplete. Cannot load the path.",
                                "Trackviewer Path Editor", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return;
            }

            PathId    = patFile.PathID;
            PathName  = patFile.Name;
            PathStart = patFile.Start;
            PathEnd   = patFile.End;
            PathFlags = patFile.Flags;

            List <TrainpathNode> Nodes = new List <TrainpathNode>();

            CreateNodes(patFile, Nodes);

            LinkNodes(patFile, Nodes);
            SetFacingPoints(Nodes);

            FindSidingEnds();
            FindNodeOrientations();
            FindWronglyOrientedLinks();
            DetermineIfBroken();
        }
示例#3
0
 /// <summary>
 /// Constructor
 /// </summary>
 public DrawPath (TrackDB trackDB, TrackSectionsFile tsectionDat)
 {
     this.trackDB = trackDB;
     this.tsectionDat = tsectionDat;
     this.colorSchemeMain = DrawColors.colorsPathMain;
     this.colorSchemeSiding = DrawColors.colorsPathSiding;
 }
示例#4
0
        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);
        }
示例#5
0
        int currentIndexUnmodified; // The index of the last saved path.

        #endregion

        /// <summary>
        /// Basic constructor creating an empty path, but storing track database and track section data
        /// </summary>
        /// <param name="trackDB"></param>
        /// <param name="tsectionDat"></param>
        public Trainpath(TrackDB trackDB, TrackSectionsFile tsectionDat)
        {
            this.trackDB     = trackDB;
            this.tsectionDat = tsectionDat;
            trainPaths       = new List <TrainPathData>();
            trainPaths.Add(new TrainPathData());
        }
示例#6
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="routeData">The data needed for the route</param>
        public TrackItemManager(ORTS.TrackViewer.Drawing.RouteData routeData)
        {
            this.trackDB     = routeData.TrackDB;
            this.tsectionDat = routeData.TsectionDat;

            cachedItems = new Dictionary <TrackNode, IEnumerable <ChartableTrackItem> >();
        }
示例#7
0
 /// <summary>
 /// Constructor
 /// </summary>
 public DrawPath(TrackDB trackDB, TrackSectionsFile tsectionDat)
 {
     this.trackDB           = trackDB;
     this.tsectionDat       = tsectionDat;
     this.ColorSchemeMain   = DrawColors.colorsPathMain;
     this.ColorSchemeSiding = DrawColors.colorsPathSiding;
     this.ColorSchemeLast   = DrawColors.ShadeColor(DrawColors.otherPathsReferenceColor, 0, 1);
 }
示例#8
0
 public TrackContent(TrackDB trackDB, RoadTrackDB roadTrackDB, TrackSectionsFile trackSections, SignalConfigurationFile signalConfig, bool metricUnits)
 {
     this.trackDB      = trackDB;
     this.roadTrackDB  = roadTrackDB;
     trackSectionsFile = trackSections;
     UseMetricUnits    = metricUnits;
     SignalConfigFile  = signalConfig;
 }
示例#9
0
 /// <summary>
 /// Creates a single trainpathNode and initializes everything that do not depend on other nodes.
 /// The trainpath constructor will initialize the rest.
 /// </summary>
 protected TrainpathNode(TrackPDP pdp, TrackDB trackDB, TrackSectionsFile tsectionDat)
     : this(trackDB, tsectionDat)
 {
     Location = new WorldLocation(pdp.TileX, pdp.TileZ, pdp.X, pdp.Y, pdp.Z);
     if (pdp.IsInvalid) // not a valid point
     {
         this.SetBroken(NodeStatus.SetAsInvalid);
     }
 }
示例#10
0
 /// <summary>
 /// basic constructor, in case node is not created from PAT file, and only some parts are needed
 /// </summary>
 protected TrainpathNode(TrackDB trackDB, TrackSectionsFile tsectionDat)
 {
     this.TrackDB       = trackDB;
     this.TsectionDat   = tsectionDat;
     HasSidingPath      = false;
     NextMainTvnIndex   = 0;
     NextSidingTvnIndex = 0;
     NodeType           = TrainpathNodeType.Other;
 }
示例#11
0
 /// <summary>
 /// Creates a single trainpathNode and initializes everything that do not depend on other nodes.
 /// The trainpath constructor will initialize the rest.
 /// </summary>
 protected TrainpathNode(PathDataPoint pdp, TrackDB trackDB, TrackSectionsFile tsectionDat)
     : this(trackDB, tsectionDat)
 {
     Location = pdp.Location;
     if (pdp.IsInvalid) // not a valid point
     {
         this.SetBroken(NodeStatus.SetAsInvalid);
     }
 }
示例#12
0
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="routeData">The data needed for the route</param>
        public TrackItemManager(ORTS.TrackViewer.Drawing.RouteData routeData)
        {
            this.trackDB     = routeData.TrackDB;
            this.tsectionDat = routeData.TsectionDat;

            cachedItems = new Dictionary <TrackNode, IEnumerable <ChartableTrackItem> >();

            supportedTrackTypes = new HashSet <TrItem.trItemType> {
                TrItem.trItemType.trPLATFORM,
                TrItem.trItemType.trSPEEDPOST,
            };
        }
 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);
         }
     }
 }
示例#14
0
        public async Task Initialize()
        {
            List <Task> initializer = new List <Task>
            {
                Task.Run(async() => await InitializeTrackSegments().ConfigureAwait(false))
            };

            await Task.WhenAll(initializer).ConfigureAwait(false);

            trackDB           = null;
            roadTrackDB       = null;
            trackSectionsFile = null;
        }
示例#15
0
 /// <summary>
 /// Find the angle that the signal needs to be drawn at
 /// </summary>
 /// <param name="tsectionDat">Database with track sections</param>
 /// <param name="trackDB">Database with tracks</param>
 /// <param name="tn">TrackNode on which the signal actually is</param>
 public void FindAngle(TrackSectionsFile tsectionDat, TrackDB trackDB, TrackNode tn)
 {
     this.angle = 0;
     try
     {
         Traveller signalTraveller = new Traveller(tsectionDat, trackDB.TrackNodes, tn,
                                                   this.WorldLocation.TileX, this.WorldLocation.TileZ,
                                                   this.WorldLocation.Location.X, this.WorldLocation.Location.Z,
                                                   this.direction);
         this.angle = signalTraveller.RotY;
     }
     catch { }
 }
示例#16
0
        /// <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);
        }
示例#17
0
        /// <summary>
        /// Find the angle that the signal needs to be drawn at
        /// </summary>
        /// <param name="tsectionDat">Database with track sections</param>
        /// <param name="trackDB">Database with tracks</param>
        /// <param name="tn">TrackNode on which the signal actually is</param>
        public void FindAngle(TrackSectionsFile tsectionDat, TrackDB trackDB, TrackVectorNode tn)
        {
            this.angle = 0;
            try
            {
                Traveller signalTraveller = new Traveller(tsectionDat, trackDB.TrackNodes, tn, WorldLocation, this.direction);
                this.angle = signalTraveller.RotY;

                // Shift signal a little bit to be able to distinguish backfacing from normal facing
                Microsoft.Xna.Framework.Vector3 shiftedLocation = this.WorldLocation.Location +
                                                                  0.0001f * new Microsoft.Xna.Framework.Vector3((float)Math.Cos(this.angle), 0f, -(float)Math.Sin(this.angle));
                this.WorldLocation = new WorldLocation(this.WorldLocation.TileX, this.WorldLocation.TileZ, shiftedLocation);
            }
            catch { }
        }
示例#18
0
        /// <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)
        {
            string subdirname = Path.GetFileName(Path.GetDirectoryName(file));

            if (subdirname.Equals("openrails", System.StringComparison.OrdinalIgnoreCase))
            {
                //todo Need good examples for this. Might not actually be found via SIMIS header
                //Also not clear if this needs a global tracksection or not
                _ = new TrackSectionsFile(file);
            }
            else
            {
                globalTsection.AddRouteTSectionDatFile(file);
            }
        }
示例#19
0
        /// <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)
        {
            var subdirname = Path.GetFileName(Path.GetDirectoryName(file)).ToLowerInvariant();

            if (subdirname == "openrails")
            {
                //todo Need good examples for this. Might not actually be found via SIMIS header
                //Also not clear if this needs a global tracksection or not
                var TSectionDat = new TrackSectionsFile(file);
            }
            else
            {
                _globalTsection.AddRouteTSectionDatFile(file);
            }
        }
示例#20
0
        /// <summary>
        /// Constructor
        /// </summary>
        public DrawMultiplePaths(RouteData routeData, Collection <Path> paths)
        {
            this.trackDB       = routeData.TrackDB;
            this.tsectionDat   = routeData.TsectionDat;
            fullPathNames      = new Dictionary <string, string>();
            loadedPaths        = new Dictionary <string, Trainpath>();
            selectedTrainpaths = new List <Trainpath>();
            drawPaths          = new Dictionary <Trainpath, DrawPath>();

            foreach (Path path in paths)
            {
                string pathName = ORTS.TrackViewer.UserInterface.MenuControl.MakePathMenyEntryName(path);
                fullPathNames[pathName] = path.FilePath;
            }
        }
示例#21
0
        /// <summary>
        /// Constructor based on PAT file information.
        /// </summary>
        /// <param name="tpn">TrPathNode from .pat file</param>
        /// <param name="pdp">TrackPDP from .pat file</param>
        /// <param name="trackDB"></param>
        /// <param name="tsectionDat"></param>
        public TrainpathVectorNode(TrPathNode tpn, TrackPDP pdp, TrackDB trackDB, TrackSectionsFile tsectionDat)
            : base(pdp, trackDB, tsectionDat)
        {
            try
            {
                Traveller traveller = new Traveller(tsectionDat, trackDB.TrackNodes, this.Location);
                CopyDataFromTraveller(traveller);
            }
            catch
            {
                SetBroken(NodeStatus.NotOnTrack);
            }

            ForwardOriented = true; // only initial setting

            InterpretPathNodeFlags(tpn);
        }
示例#22
0
        /// <summary>
        /// base constructor that only stores the information of the tracks.
        /// </summary>
        /// <param name="routeData">The route information that contains track data base and track section data</param>
        /// <param name="drawTrackDB">The drawn tracks to know about where the mouse is</param>
        private PathEditor(RouteData routeData, DrawTrackDB drawTrackDB)
        {
            this.drawTrackDB = drawTrackDB;
            this.trackDB     = routeData.TrackDB;
            this.tsectionDat = routeData.TsectionDat;

            TrackExtensions.Initialize(trackDB.TrackNodes, tsectionDat); // we might be calling this more than once, but so be it.

            enableMouseUpdate = true;

            drawPath = new DrawPath(trackDB, tsectionDat);

            CreateNonMenuActions();
            CreateDirectActions();
            CreateContextMenuEntries();
            CreateContextMenu();
        }
示例#23
0
        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);
        }
示例#24
0
        /// <summary>
        /// Find the indices we need to use for TrPins in the various junction nodes in case we want to use either main
        /// or siding path. That information is available in the trackshapes in the tsectionDat.
        /// </summary>
        /// <param name="trackNodesIn">The tracknodes</param>
        /// <param name="tsectionDatIn">Track section Data</param>
        public static void Initialize(TrackNode[] trackNodesIn, TrackSectionsFile tsectionDatIn)
        {
            trackNodes  = trackNodesIn;
            tsectionDat = tsectionDatIn;

            mainRouteIndex   = new uint[trackNodes.Length];
            sidingRouteIndex = new uint[trackNodes.Length];
            for (int tni = 0; tni < trackNodes.Length; tni++)
            {
                TrackNode tn = trackNodes[tni];
                if (tn == null)
                {
                    continue;
                }
                if (tn.TrJunctionNode == null)
                {
                    continue;
                }
                uint mainRoute = 0;

                uint trackShapeIndex = tn.TrJunctionNode.ShapeIndex;
                try
                {
                    TrackShape trackShape = tsectionDat.TrackShapes.Get(trackShapeIndex);
                    mainRoute = trackShape.MainRoute;
                }
                catch (System.IO.InvalidDataException exception)
                {
                    exception.ToString();
                }

                mainRouteIndex[tni] = tn.Inpins + mainRoute;
                if (mainRoute == 0)
                {   // sidingRouteIndex is simply the next
                    sidingRouteIndex[tni] = tn.Inpins + 1;
                }
                else
                {   // sidingRouteIndex is the first
                    sidingRouteIndex[tni] = tn.Inpins;
                }
            }
        }
示例#25
0
        // 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);
        }
示例#26
0
        /// <summary>
        /// constructor out of other path
        /// </summary>
        /// <param name="otherPath"></param>

        public AIPath(AIPath otherPath)
        {
            TrackDB     = otherPath.TrackDB;;
            TSectionDat = otherPath.TSectionDat;
            FirstNode   = new AIPathNode(otherPath.FirstNode);
            foreach (AIPathNode otherNode in otherPath.Nodes)
            {
                Nodes.Add(new AIPathNode(otherNode));
            }

            // set correct node references

            for (int iNode = 0; iNode <= otherPath.Nodes.Count - 1; iNode++)
            {
                AIPathNode otherNode = otherPath.Nodes[iNode];
                if (otherNode.NextMainNode != null)
                {
                    Nodes[iNode].NextMainNode = Nodes[otherNode.NextMainNode.Index];
                }

                if (otherNode.NextSidingNode != null)
                {
                    Nodes[iNode].NextSidingNode = Nodes[otherNode.NextSidingNode.Index];
                }
            }

            if (otherPath.FirstNode.NextMainNode != null)
            {
                FirstNode.NextMainNode = Nodes[otherPath.FirstNode.NextMainNode.Index];
            }
            if (otherPath.FirstNode.NextSidingNode != null)
            {
                FirstNode.NextSidingNode = Nodes[otherPath.FirstNode.NextSidingNode.Index];
            }

            pathName = otherPath.pathName;
        }
示例#27
0
 /// <summary>
 /// Constructor giving the information this loaded depends on
 /// </summary>
 /// <param name="globalTsection">The global Tsection that is used as a base</param>
 public TSectionLoader(TrackSectionsFile globalTsection) : this()
 {
     this.globalTsection = globalTsection;
 }
示例#28
0
        /// <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);
        }
示例#29
0
        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
            }
        }
示例#30
0
        /// <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);
        }