コード例 #1
0
ファイル: PathNodeList.cs プロジェクト: caleb-dp/Phoenix
        //---------------------------------------------------------------------------------------------

        public void NormalizeReferences(PathNodeList originalList)
        {
            for (int i = 0; i < this.Count; i++)
            {
                PathNode originalFound = originalList.FindNode(this[i].X, this[i].Y);
                if (originalFound != null)
                {
                    this[i] = originalFound;
                }
            }
        }
コード例 #2
0
ファイル: PathNodeList.cs プロジェクト: caleb-dp/Phoenix
        //---------------------------------------------------------------------------------------------

        public void MergeIdent(PathNodeList possibleList)
        {
            int count = this.Count;

            for (int i = count - 1; i >= 0; i--)
            {
                PathNode findNode = possibleList.FindNode(this[i].X, this[i].Y);
                if (findNode != null)
                {
                    this.RemoveAt(i);
                }
            }
        }
コード例 #3
0
ファイル: PathNodeList.cs プロジェクト: caleb-dp/Phoenix
        //---------------------------------------------------------------------------------------------

        public void MergePossible(PathNodeList possibleList)
        {
            int count = this.Count;

            for (int i = count - 1; i >= 0; i--)
            {
                PathNode findNode = possibleList.FindNode(this[i].X, this[i].Y);
                if (findNode == null || findNode.Walkable.HasValue && !findNode.Walkable.Value)
                {
                    this.RemoveAt(i);
                }
            }
        }
コード例 #4
0
ファイル: PathNodeList.cs プロジェクト: caleb-dp/Phoenix
        //---------------------------------------------------------------------------------------------

        public PathNodeList FromPositionCollection(List <UOPositionBase> positions)
        {
            PathNodeList list = new PathNodeList();

            foreach (UOPositionBase position in positions)
            {
                PathNode node = new PathNode();
                node.X        = position.X.GetValueOrDefault();
                node.Y        = position.Y.GetValueOrDefault();
                node.Walkable = position.IsSepable;
                if (!list.ContainsNode(node))
                {
                    list.Add(node);
                }
            }
            return(list);
        }
コード例 #5
0
ファイル: PathBuilder.cs プロジェクト: caleb-dp/Phoenix
        //---------------------------------------------------------------------------------------------

        public PathNodeList FindAdjacentNodes(PathNode node)
        {
            PathNodeList list    = new PathNodeList();
            PathNode     adjNode = new PathNode()
            {
                X = (ushort)(node.X), Y = (ushort)(node.Y + 1)
            };                                                                             //0

            list.Add(adjNode);
            adjNode = new PathNode()
            {
                X = (ushort)(node.X + 1), Y = (ushort)(node.Y + 1), DiagonalToParent = true
            };                                                                                                 //45
            list.Add(adjNode);
            adjNode = new PathNode()
            {
                X = (ushort)(node.X + 1), Y = (ushort)(node.Y)
            };                                                                    //90
            list.Add(adjNode);
            adjNode = new PathNode()
            {
                X = (ushort)(node.X + 1), Y = (ushort)(node.Y - 1), DiagonalToParent = true
            };                                                                                                 //135
            list.Add(adjNode);
            adjNode = new PathNode()
            {
                X = (ushort)(node.X), Y = (ushort)(node.Y - 1)
            };                                                                    //180
            list.Add(adjNode);
            adjNode = new PathNode()
            {
                X = (ushort)(node.X - 1), Y = (ushort)(node.Y - 1), DiagonalToParent = true
            };                                                                                                 //225
            list.Add(adjNode);
            adjNode = new PathNode()
            {
                X = (ushort)(node.X - 1), Y = (ushort)(node.Y)
            };                                                                    //270
            list.Add(adjNode);
            adjNode = new PathNode()
            {
                X = (ushort)(node.X - 1), Y = (ushort)(node.Y + 1), DiagonalToParent = true
            };                                                                                                 //315
            list.Add(adjNode);
            return(list);
        }
コード例 #6
0
ファイル: PathBuilder.cs プロジェクト: caleb-dp/Phoenix
        //---------------------------------------------------------------------------------------------

        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.OpenNodes != null)
                {
                    this.OpenNodes.Dispose();
                    this.OpenNodes = null;
                }

                if (this.CloseNodes != null)
                {
                    this.CloseNodes.Dispose();
                    this.CloseNodes = null;
                }
            }
        }
コード例 #7
0
ファイル: PathNodeList.cs プロジェクト: caleb-dp/Phoenix
        //---------------------------------------------------------------------------------------------

        public void RemoveDiagonalCorners(PathNode parent, PathBuilder builder)
        {
            int count = this.Count;

            for (int i = count - 1; i >= 0; i--)
            {
                PathNode current = this[i];
                if (current.DiagonalToParent)
                {
                    PathNodeList currentAdje = builder.FindAdjacentNodes(current);
                    currentAdje.MergePossible(this);
                    if (currentAdje.Count == 1 || currentAdje.Count == 0)
                    {
                        this.RemoveAt(i);
                    }
                }
            }
        }
コード例 #8
0
ファイル: PathBuilder.cs プロジェクト: caleb-dp/Phoenix
 public PathBuilder(PathNodeList possibleNodes)
 {
     PossibleNodes = possibleNodes;
 }
コード例 #9
0
ファイル: PathBuilder.cs プロジェクト: caleb-dp/Phoenix
        //---------------------------------------------------------------------------------------------

        public PathBuilder()
        {
            PossibleNodes = new PathNodeList();
        }
コード例 #10
0
ファイル: PathBuilder.cs プロジェクト: caleb-dp/Phoenix
        public bool ComputePath(PathNode start, PathNode end, int fromDistance)
        {
            OpenNodes  = new PathNodeList();
            CloseNodes = new PathNodeList();
            PathNode current = start;

            start.G = 0;
            start.H = ComputeH(start, end);

            if (!OpenNodes.ContainsNode(start))
            {
                OpenNodes.Add(start);
            }

            bool finish = false;
            bool result = false;

            if (!this.PossibleNodes.ContainsNode(start))
            {
                this.PossibleNodes.Add(start);
            }

            if (!this.PossibleNodes.ContainsNode(end))
            {
                this.PossibleNodes.Add(end);
            }

            while (!finish && Searchs < 10000)
            {
                Searchs++;
                OpenNodes.Remove(current);
                if (!CloseNodes.ContainsNode(current))
                {
                    CloseNodes.Add(current);
                }

                PathNodeList searchNodes = FindAdjacentNodes(current);

                foreach (PathNode node in searchNodes)
                {
                    if (!this.PossibleNodes.ContainsNode(node))
                    {
                        this.PossibleNodes.Add(node);
                    }
                }

                searchNodes.MergePossible(this.PossibleNodes);
                searchNodes.RemoveDiagonalCorners(current, this);

                if (searchNodes.Count > 0)
                {
                    searchNodes.MergeIdent(CloseNodes);
                }
                else
                {
                    PathNodeList adjNodes = FindAdjacentNodes(current);
                    foreach (PathNode adj in adjNodes)
                    {
                        PathNode sNode = this.PossibleNodes.FindNode(adj.X, adj.Y);
                        if (sNode == null)
                        {
                            sNode = adj;
                            this.PossibleNodes.Add(sNode);
                        }
                        sNode.Walkable = null;

                        searchNodes.Add(sNode);
                    }
                    searchNodes.RemoveDiagonalCorners(current, this);
                }

                searchNodes.NormalizeReferences(OpenNodes);

                PathNode bestNode = null;
                foreach (PathNode searchNode in searchNodes)
                {
                    if (!OpenNodes.ContainsNode(searchNode))
                    {
                        searchNode.Parent = current;
                        searchNode.H      = ComputeH(searchNode, end);
                        searchNode.G      = ComputeG(searchNode.Parent, searchNode);
                        OpenNodes.Add(searchNode);
                    }
                    else if (searchNode.G > (current.G + (searchNode.DiagonalToParent ? 14 : 10)))
                    {
                        searchNode.Parent = current;
                        searchNode.H      = ComputeH(searchNode, end);
                        searchNode.G      = ComputeG(searchNode.Parent, searchNode);
                    }
                }

                foreach (PathNode openNode in OpenNodes)
                {
                    if (bestNode == null || (openNode.F < bestNode.F))
                    {
                        bestNode = openNode;
                    }
                }

                if (bestNode == null)
                {
                    finish = true;
                }
                else if (bestNode.H == (fromDistance * 10))
                {
                    OpenNodes.Remove(bestNode);
                    if (!CloseNodes.ContainsNode(bestNode))
                    {
                        CloseNodes.Add(bestNode);
                    }

                    bestNode.Finish = true;
                    result          = true;
                    finish          = true;
                }

                current = bestNode;
            }
            return(result);
        }
コード例 #11
0
        //---------------------------------------------------------------------------------------------

        private bool TryGoTo(ushort x, ushort y, int fromDistance, int tries, PathNodeList localList)
        {
            IUOPosition destination = this.CreatePositionInstance(x, y, 0);

            if (localList == null)
            {
                localList = new PathNodeList();
            }
            if (EnableLog)
            {
                Game.PrintMessage("TryGoTo : " + x + ", " + y + " - " + tries);
            }

            if (this.ActualPosition.Equals(destination) || Robot.GetRelativeVectorLength(this.ActualPosition, destination) <= fromDistance)
            {
                if (EnableLog)
                {
                    Game.PrintMessage("TryGoTo OK - 1: " + x + ", " + y);
                }

                return(true);
            }

            PathNode start = new PathNode()
            {
                X = World.Player.X, Y = World.Player.Y
            };
            PathNode end = new PathNode()
            {
                X = x, Y = y
            };


            if (tries > 0)
            {
                using (PathBuilder builder = new PathBuilder(UseCachedPathList ? this.PossibleNodes : localList))
                {
                    if (builder.ComputePath(start, end, fromDistance))
                    {
                        PathNodeList computedPath = new PathNodeList();
                        computedPath.AddRange(builder.ComputedPathNodes);
                        computedPath.Reverse();

                        if (EnableLog)
                        {
                            Game.PrintMessage("TryGoTo Found: " + x + ", " + y + " / " + builder.Searchs);
                        }

                        int step = 0;
                        foreach (PathNode node in computedPath)
                        {
                            step++;
                            IUOPosition  pos  = this.CreatePositionInstance(node.X, node.Y, x);
                            GotoStepArgs args = new GotoStepArgs(pos, tries, fromDistance);
                            if (this.BeforeMove != null)
                            {
                                this.BeforeMove(this, args);
                            }

                            bool moveFail = false;

                            if (args.Abort)
                            {
                                Game.PrintMessage("TryGoTo Abort " + destination);
                                return(false);
                            }

                            if (args.IvalidDestination)
                            {
                                if (EnableLog)
                                {
                                    Game.PrintMessage("Path IvalidDestination: " + this.ActualPosition.ToString() + " to " + node.ToString());
                                }
                                moveFail = true;
                            }
                            else
                            {
                                if (!this.Move(GetMovementDirection(this.GetAngle(pos))))
                                {
                                    if (!this.Move(GetMovementDirection(this.GetAngle(pos))))
                                    {
                                        moveFail = true;
                                    }
                                }
                            }

                            if (moveFail)
                            {
                                if (EnableLog)
                                {
                                    Game.PrintMessage("PathFail: " + this.ActualPosition.ToString() + " to " + node.ToString());
                                }

                                PathNode findNode = builder.PossibleNodes.FindNode(node.X, node.Y);
                                if (findNode != null && !findNode.Walkable.HasValue)
                                {
                                    findNode.Walkable = false;
                                }

                                return(TryGoTo(x, y, fromDistance, --tries, localList));
                            }

                            if (this.AfterMoveSuccess != null)
                            {
                                this.AfterMoveSuccess(this, new GotoStepArgs(pos, tries, fromDistance));
                            }

                            if (args.Abort)
                            {
                                return(false);
                            }
                        }

                        //            09:44 Phoenix: TryGoTo: 1380, 2706 - 459
                        //09:44 Phoenix: Compute Path FAIL: 1380,2707 to 1380,2706
                        //09:44 Phoenix: TryGoTo END: 1380, 2706

                        if (this.ActualPosition.Equals(destination) || Robot.GetRelativeVectorLength(this.ActualPosition, destination) <= fromDistance)
                        {
                            if (EnableLog)
                            {
                                Game.PrintMessage("TryGoTo OK - 2: " + x + ", " + y);
                            }

                            this.OnGoToSuccess(this, EventArgs.Empty);
                            return(true);
                        }
                        else
                        {
                            return(TryGoTo(x, y, fromDistance, --tries, localList));
                        }
                    }
                    else
                    {
                        if (EnableLog)
                        {
                            Game.PrintMessage("Compute Path FAIL - Restart: " + start.ToString() + " to " + end.ToString());
                        }

                        return(TryGoTo(x, y, fromDistance, --tries, null));
                    }
                }
            }


            if (EnableLog)
            {
                Game.PrintMessage("TryGoTo END: " + x + ", " + y);
            }

            return(false);
        }