예제 #1
0
        /// <summary>
        /// Find all nodes that are the end of a siding (so where main path and siding path come together again)
        /// </summary>
        private void FindSidingEnds()
        {
            Dictionary <int, AIPathNode> lastUse = new Dictionary <int, AIPathNode>();

            for (AIPathNode node1 = FirstNode; node1 != null; node1 = node1.NextMainNode)
            {
                if (node1.JunctionIndex >= 0)
                {
                    lastUse[node1.JunctionIndex] = node1;
                }
                AIPathNode node2 = node1.NextSidingNode;
                while (node2 != null && node2.NextSidingNode != null)
                {
                    if (node2.JunctionIndex >= 0)
                    {
                        lastUse[node2.JunctionIndex] = node2;
                    }
                    node2 = node2.NextSidingNode;
                }
                if (node2 != null)
                {
                    node2.Type = AIPathNodeType.SidingEnd;
                }
            }
            //foreach (KeyValuePair<int, AIPathNode> kvp in lastUse)
            //    kvp.Value.IsLastSwitchUse = true;
        }
예제 #2
0
 public static void WriteNode(BinaryWriter outf, AIPathNode node)
 {
     if (node == null)
     {
         outf.Write((int)-1);
     }
     else
     {
         outf.Write(node.Index);
     }
 }
예제 #3
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);
        }
예제 #4
0
        /// <summary>
        /// Constructor from other AIPathNode
        /// </summary>
        /// <param name="otherNode"></param>

        public AIPathNode(AIPathNode otherNode)
        {
            ID                 = otherNode.ID;
            Index              = otherNode.Index;
            Type               = otherNode.Type;
            WaitTimeS          = otherNode.WaitTimeS;
            WaitUntil          = otherNode.WaitUntil;
            NCars              = otherNode.NCars;
            NextMainNode       = null; // set after completion of copying to get correct reference
            NextSidingNode     = null; // set after completion of copying to get correct reference
            NextMainTVNIndex   = otherNode.NextMainTVNIndex;
            NextSidingTVNIndex = otherNode.NextSidingTVNIndex;
            Location           = otherNode.Location;
            JunctionIndex      = otherNode.JunctionIndex;
            IsFacingPoint      = otherNode.IsFacingPoint;
            IsVisited          = otherNode.IsVisited;
        }
예제 #5
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);
        }
예제 #6
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;
        }
예제 #7
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);
        }
예제 #8
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
            }
        }
예제 #9
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);
        }