コード例 #1
0
        private IPathNode Jump(IPathNode current, VectorXZ direction)
        {
            var next = current.GetNeighbour(direction.x, direction.z);

            if (next == null || !next.IsWalkableFromWithClearance(current, _unitProps))
            {
                return(null);
            }

            if (next == this.goal)
            {
                return(next);
            }

            if (HasForcedNeighbour(next, direction))
            {
                return(next);
            }

            if (direction.x != 0 && direction.z != 0)
            {
                if (Jump(next, new VectorXZ(direction.x, 0)) != null || Jump(next, new VectorXZ(0, direction.z)) != null)
                {
                    return(next);
                }

                //If both or either neighbours (depending on cut corner setting) in a diagonal move are blocked, the diagonal neighbour is not reachable since the passage is blocked
                var n1 = next.GetNeighbour(direction.x, 0);
                var n2 = next.GetNeighbour(0, direction.z);

                bool jumpOn = _cutCorners ? ((n1 != null && n1.IsWalkableFromWithClearance(current, _unitProps)) || (n2 != null && n2.IsWalkableFromWithClearance(current, _unitProps))) : ((n1 != null && n1.IsWalkableFromWithClearance(current, _unitProps)) && (n2 != null && n2.IsWalkableFromWithClearance(current, _unitProps)));
                if (jumpOn)
                {
                    return(Jump(next, direction));
                }
            }
            else
            {
                return(Jump(next, direction));
            }

            return(null);
        }
コード例 #2
0
        private IPathNode Jump(IPathNode current, VectorXZ direction)
        {
            var next = current.GetNeighbour(direction.x, direction.z);

            if (next == null || !next.isWalkableFrom(current, _unitProps))
            {
                return null;
            }

            if (next == this.goal)
            {
                return next;
            }

            if (HasForcedNeighbour(next, direction))
            {
                return next;
            }

            if (direction.x != 0 && direction.z != 0)
            {
                if (Jump(next, new VectorXZ(direction.x, 0)) != null || Jump(next, new VectorXZ(0, direction.z)) != null)
                {
                    return next;
                }

                //If both or either neighbours (depending on cut corner setting) in a diagonal move are blocked, the diagonal neighbour is not reachable since the passage is blocked
                var n1 = next.GetNeighbour(direction.x, 0);
                var n2 = next.GetNeighbour(0, direction.z);

                bool jumpOn = _cutCorners ? ((n1 != null && n1.isWalkableFrom(current, _unitProps)) || (n2 != null && n2.isWalkableFrom(current, _unitProps))) : ((n1 != null && n1.isWalkableFrom(current, _unitProps)) && (n2 != null && n2.isWalkableFrom(current, _unitProps)));
                if (jumpOn)
                {
                    return Jump(next, direction);
                }
            }
            else
            {
                return Jump(next, direction);
            }

            return null;
        }
コード例 #3
0
        private bool HasForcedNeighbour(IPathNode current, VectorXZ direction)
        {
            if (current.hasVirtualNeighbour)
            {
                return true;
            }

            bool hasForced = false;

            if (direction.x != 0)
            {
                if (direction.z != 0)
                {
                    if (_cutCorners)
                    {
                        var nLeft = current.GetNeighbour(-direction.x, 0);
                        if (nLeft != null && !nLeft.isWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(-direction.x, direction.z);
                            hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                        }

                        var nDown = current.GetNeighbour(0, -direction.z);
                        if (nDown != null && !nDown.isWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(direction.x, -direction.z);
                            hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                        }
                    }
                    else
                    {
                        return false;
                    }
                }
                else
                {
                    if (_cutCorners)
                    {
                        var nUp = current.GetNeighbour(0, 1);
                        if (nUp != null && !nUp.isWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(direction.x, 1);
                            hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                        }

                        var nDown = current.GetNeighbour(0, -1);
                        if (nDown != null && !nDown.isWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(direction.x, -1);
                            hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                        }
                    }
                    else
                    {
                        var nUpBack = current.GetNeighbour(-direction.x, 1);
                        if (nUpBack != null && !nUpBack.isWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(0, 1);
                            hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                        }

                        var nDownBack = current.GetNeighbour(-direction.x, -1);
                        if (nDownBack != null && !nDownBack.isWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(0, -1);
                            hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                        }
                    }
                }
            }
            else
            {
                if (_cutCorners)
                {
                    var nLeft = current.GetNeighbour(-1, 0);
                    if (nLeft != null && !nLeft.isWalkableFromAllDirections(_unitProps))
                    {
                        var fn = current.GetNeighbour(-1, direction.z);
                        hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                    }

                    var nRight = current.GetNeighbour(1, 0);
                    if (nRight != null && !nRight.isWalkableFromAllDirections(_unitProps))
                    {
                        var fn = current.GetNeighbour(1, direction.z);
                        hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                    }
                }
                else
                {
                    var nLeftDown = current.GetNeighbour(-1, -direction.z);
                    if (nLeftDown != null && !nLeftDown.isWalkableFromAllDirections(_unitProps))
                    {
                        var fn = current.GetNeighbour(-1, 0);
                        hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                    }

                    var nRightDown = current.GetNeighbour(1, -direction.z);
                    if (nRightDown != null && !nRightDown.isWalkableFromAllDirections(_unitProps))
                    {
                        var fn = current.GetNeighbour(1, 0);
                        hasForced |= (fn != null && fn.isWalkableFrom(current, _unitProps));
                    }
                }
            }

            return hasForced;
        }
コード例 #4
0
        private void PruneNeighbours(IPathNode current, VectorXZ direction)
        {
            if (direction.x != 0)
            {
                if (direction.z != 0)
                {
                    //Natural neighbours
                    var nTop = current.TryGetWalkableNeighbour(0, direction.z, _unitProps, _neighbours);
                    var nRight = current.TryGetWalkableNeighbour(direction.x, 0, _unitProps, _neighbours);

                    if (_cutCorners)
                    {
                        if (nTop || nRight)
                        {
                            current.TryGetWalkableNeighbour(direction.x, direction.z, _unitProps, _neighbours);
                        }

                        //Forced neighbours? The left/down is as seen from a normal view of the grid, i.e. not seen from the direction of movement (well direction left corner diagonal)
                        var nLeft = current.GetNeighbour(-direction.x, 0);
                        if (nLeft != null && !nLeft.isWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(-direction.x, direction.z, _unitProps, _neighbours);
                        }

                        var nDown = current.GetNeighbour(0, -direction.z);
                        if (nDown != null && !nDown.isWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(direction.x, -direction.z, _unitProps, _neighbours);
                        }
                    }
                    else
                    {
                        if (nTop && nRight)
                        {
                            current.TryGetWalkableNeighbour(direction.x, direction.z, _unitProps, _neighbours);
                        }
                    }
                }
                else
                {
                    //Natural neighbour
                    current.TryGetWalkableNeighbour(direction.x, 0, _unitProps, _neighbours);

                    //Forced neighbours?
                    if (_cutCorners)
                    {
                        var nUp = current.GetNeighbour(0, 1);
                        if (nUp != null && !nUp.isWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(direction.x, 1, _unitProps, _neighbours);
                        }

                        var nDown = current.GetNeighbour(0, -1);
                        if (nDown != null && !nDown.isWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(direction.x, -1, _unitProps, _neighbours);
                        }
                    }
                    else
                    {
                        var nUpBack = current.GetNeighbour(-direction.x, 1);
                        if (nUpBack != null && !nUpBack.isWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(0, 1, _unitProps, _neighbours);
                            current.TryGetWalkableNeighbour(direction.x, 1, _unitProps, _neighbours);
                        }

                        var nDownBack = current.GetNeighbour(-direction.x, -1);
                        if (nDownBack != null && !nDownBack.isWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(0, -1, _unitProps, _neighbours);
                            current.TryGetWalkableNeighbour(direction.x, -1, _unitProps, _neighbours);
                        }
                    }
                }
            }
            else
            {
                //Portals return Vector3.zero as the direction, and for those we need to start over on the new grid.
                if (direction.z == 0)
                {
                    current.GetWalkableNeighbours(_neighbours, _unitProps, _cutCorners, false);
                    return;
                }

                //Natural neighbour
                current.TryGetWalkableNeighbour(0, direction.z, _unitProps, _neighbours);

                //Forced neighbours? The left/right is as seen from a normal view of the grid, i.e. not seen from the direction of movement (well direction bottom up)
                if (_cutCorners)
                {
                    var nLeft = current.GetNeighbour(-1, 0);
                    if (nLeft != null && !nLeft.isWalkableFromAllDirections(_unitProps))
                    {
                        current.TryGetWalkableNeighbour(-1, direction.z, _unitProps, _neighbours);
                    }

                    var nRight = current.GetNeighbour(1, 0);
                    if (nRight != null && !nRight.isWalkableFromAllDirections(_unitProps))
                    {
                        current.TryGetWalkableNeighbour(1, direction.z, _unitProps, _neighbours);
                    }
                }
                else
                {
                    var nLeftDown = current.GetNeighbour(-1, -direction.z);
                    if (nLeftDown != null && !nLeftDown.isWalkableFromAllDirections(_unitProps))
                    {
                        current.TryGetWalkableNeighbour(-1, 0, _unitProps, _neighbours);
                        current.TryGetWalkableNeighbour(-1, direction.z, _unitProps, _neighbours);
                    }

                    var nRightDown = current.GetNeighbour(1, -direction.z);
                    if (nRightDown != null && !nRightDown.isWalkableFromAllDirections(_unitProps))
                    {
                        current.TryGetWalkableNeighbour(1, 0, _unitProps, _neighbours);
                        current.TryGetWalkableNeighbour(1, direction.z, _unitProps, _neighbours);
                    }
                }
            }
        }
コード例 #5
0
        private void PruneNeighbours(IPathNode current, VectorXZ direction)
        {
            if (direction.x != 0)
            {
                if (direction.z != 0)
                {
                    //Natural neighbours
                    var nTop   = current.TryGetWalkableNeighbour(0, direction.z, _unitProps, _neighbours);
                    var nRight = current.TryGetWalkableNeighbour(direction.x, 0, _unitProps, _neighbours);

                    if (_cutCorners)
                    {
                        if (nTop || nRight)
                        {
                            current.TryGetWalkableNeighbour(direction.x, direction.z, _unitProps, _neighbours);
                        }

                        //Forced neighbours? The left/down is as seen from a normal view of the grid, i.e. not seen from the direction of movement (well direction left corner diagonal)
                        var nLeft = current.GetNeighbour(-direction.x, 0);
                        if (nLeft != null && !nLeft.IsWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(-direction.x, direction.z, _unitProps, _neighbours);
                        }

                        var nDown = current.GetNeighbour(0, -direction.z);
                        if (nDown != null && !nDown.IsWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(direction.x, -direction.z, _unitProps, _neighbours);
                        }
                    }
                    else
                    {
                        if (nTop && nRight)
                        {
                            current.TryGetWalkableNeighbour(direction.x, direction.z, _unitProps, _neighbours);
                        }
                    }
                }
                else
                {
                    //Natural neighbour
                    current.TryGetWalkableNeighbour(direction.x, 0, _unitProps, _neighbours);

                    //Forced neighbours?
                    if (_cutCorners)
                    {
                        var nUp = current.GetNeighbour(0, 1);
                        if (nUp != null && !nUp.IsWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(direction.x, 1, _unitProps, _neighbours);
                        }

                        var nDown = current.GetNeighbour(0, -1);
                        if (nDown != null && !nDown.IsWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(direction.x, -1, _unitProps, _neighbours);
                        }
                    }
                    else
                    {
                        var nUpBack = current.GetNeighbour(-direction.x, 1);
                        if (nUpBack != null && !nUpBack.IsWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(0, 1, _unitProps, _neighbours);
                            current.TryGetWalkableNeighbour(direction.x, 1, _unitProps, _neighbours);
                        }

                        var nDownBack = current.GetNeighbour(-direction.x, -1);
                        if (nDownBack != null && !nDownBack.IsWalkableFromAllDirections(_unitProps))
                        {
                            current.TryGetWalkableNeighbour(0, -1, _unitProps, _neighbours);
                            current.TryGetWalkableNeighbour(direction.x, -1, _unitProps, _neighbours);
                        }
                    }
                }
            }
            else
            {
                //Portals return Vector3.zero as the direction, and for those we need to start over on the new grid.
                if (direction.z == 0)
                {
                    current.GetWalkableNeighbours(_neighbours, _unitProps, _cutCorners, false);
                    return;
                }

                //Natural neighbour
                current.TryGetWalkableNeighbour(0, direction.z, _unitProps, _neighbours);

                //Forced neighbours? The left/right is as seen from a normal view of the grid, i.e. not seen from the direction of movement (well direction bottom up)
                if (_cutCorners)
                {
                    var nLeft = current.GetNeighbour(-1, 0);
                    if (nLeft != null && !nLeft.IsWalkableFromAllDirections(_unitProps))
                    {
                        current.TryGetWalkableNeighbour(-1, direction.z, _unitProps, _neighbours);
                    }

                    var nRight = current.GetNeighbour(1, 0);
                    if (nRight != null && !nRight.IsWalkableFromAllDirections(_unitProps))
                    {
                        current.TryGetWalkableNeighbour(1, direction.z, _unitProps, _neighbours);
                    }
                }
                else
                {
                    var nLeftDown = current.GetNeighbour(-1, -direction.z);
                    if (nLeftDown != null && !nLeftDown.IsWalkableFromAllDirections(_unitProps))
                    {
                        current.TryGetWalkableNeighbour(-1, 0, _unitProps, _neighbours);
                        current.TryGetWalkableNeighbour(-1, direction.z, _unitProps, _neighbours);
                    }

                    var nRightDown = current.GetNeighbour(1, -direction.z);
                    if (nRightDown != null && !nRightDown.IsWalkableFromAllDirections(_unitProps))
                    {
                        current.TryGetWalkableNeighbour(1, 0, _unitProps, _neighbours);
                        current.TryGetWalkableNeighbour(1, direction.z, _unitProps, _neighbours);
                    }
                }
            }
        }
コード例 #6
0
        private bool HasForcedNeighbour(IPathNode current, VectorXZ direction)
        {
            if (current.hasVirtualNeighbour)
            {
                return(true);
            }

            bool hasForced = false;

            if (direction.x != 0)
            {
                if (direction.z != 0)
                {
                    if (_cutCorners)
                    {
                        var nLeft = current.GetNeighbour(-direction.x, 0);
                        if (nLeft != null && !nLeft.IsWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(-direction.x, direction.z);
                            hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                        }

                        var nDown = current.GetNeighbour(0, -direction.z);
                        if (nDown != null && !nDown.IsWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(direction.x, -direction.z);
                            hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                else
                {
                    if (_cutCorners)
                    {
                        var nUp = current.GetNeighbour(0, 1);
                        if (nUp != null && !nUp.IsWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(direction.x, 1);
                            hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                        }

                        var nDown = current.GetNeighbour(0, -1);
                        if (nDown != null && !nDown.IsWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(direction.x, -1);
                            hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                        }
                    }
                    else
                    {
                        var nUpBack = current.GetNeighbour(-direction.x, 1);
                        if (nUpBack != null && !nUpBack.IsWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(0, 1);
                            hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                        }

                        var nDownBack = current.GetNeighbour(-direction.x, -1);
                        if (nDownBack != null && !nDownBack.IsWalkableFromAllDirections(_unitProps))
                        {
                            var fn = current.GetNeighbour(0, -1);
                            hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                        }
                    }
                }
            }
            else
            {
                if (_cutCorners)
                {
                    var nLeft = current.GetNeighbour(-1, 0);
                    if (nLeft != null && !nLeft.IsWalkableFromAllDirections(_unitProps))
                    {
                        var fn = current.GetNeighbour(-1, direction.z);
                        hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                    }

                    var nRight = current.GetNeighbour(1, 0);
                    if (nRight != null && !nRight.IsWalkableFromAllDirections(_unitProps))
                    {
                        var fn = current.GetNeighbour(1, direction.z);
                        hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                    }
                }
                else
                {
                    var nLeftDown = current.GetNeighbour(-1, -direction.z);
                    if (nLeftDown != null && !nLeftDown.IsWalkableFromAllDirections(_unitProps))
                    {
                        var fn = current.GetNeighbour(-1, 0);
                        hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                    }

                    var nRightDown = current.GetNeighbour(1, -direction.z);
                    if (nRightDown != null && !nRightDown.IsWalkableFromAllDirections(_unitProps))
                    {
                        var fn = current.GetNeighbour(1, 0);
                        hasForced |= (fn != null && fn.IsWalkableFromWithClearance(current, _unitProps));
                    }
                }
            }

            return(hasForced);
        }