Example #1
0
        public override bool Equals(object other)
        {
            if (!(other is VectorXZ))
            {
                return(false);
            }
            VectorXZ vectorXZ = (VectorXZ)other;

            if (this.x != vectorXZ.x)
            {
                return(false);
            }
            return(this.z == vectorXZ.z);
        }
        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;
        }
        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;
        }
        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);
                    }
                }
            }
        }
Example #5
0
        private bool DrawAccessibility(IGrid grid, Cell start, Cell end, Color lineColor)
        {
            var matrix = grid.cellMatrix;
            var cellSize = grid.cellSize;

            VectorXZ[] directions = new[] { new VectorXZ(-1, 0), new VectorXZ(-1, 1), new VectorXZ(0, 1), new VectorXZ(1, 1) };
            var heightAdj = new Vector3(0.0f, 0.05f, 0.0f);

            for (int x = start.matrixPosX; x <= end.matrixPosX; x++)
            {
                for (int z = start.matrixPosZ; z <= end.matrixPosZ; z++)
                {
                    var c = matrix[x, z];
                    if (c == null)
                    {
                        return false;
                    }

                    if (!c.isWalkable(this.modelAttributes))
                    {
                        Gizmos.color = this.obstacleColor;
                        Gizmos.DrawCube(c.position, new Vector3(cellSize, 0.05f, cellSize));
                        continue;
                    }

                    var curPos = new VectorXZ(x, z);
                    for (int i = 0; i < 4; i++)
                    {
                        var checkPos = curPos + directions[i];
                        var other = matrix[checkPos.x, checkPos.z];

                        if (other != null)
                        {
                            if (!other.isWalkable(this.modelAttributes))
                            {
                                continue;
                            }

                            //Determine top and bottom, with bottom winning over top if equal so to speak, due to cross height.
                            var topPos = c;
                            var bottomPos = other;
                            if (topPos.position.y <= bottomPos.position.y)
                            {
                                topPos = bottomPos;
                                bottomPos = c;
                            }

                            var topDown = bottomPos.isWalkableFrom(topPos, _modelProps);
                            var downTop = topPos.isWalkableFrom(bottomPos, _modelProps);

                            if (topDown && downTop)
                            {
                                Gizmos.color = lineColor;
                            }
                            else if (topDown)
                            {
                                Gizmos.color = this.descentOnlyColor;
                            }
                            else if (downTop)
                            {
                                Gizmos.color = this.ascentOnlyColor;
                            }
                            else
                            {
                                continue;
                            }

                            Gizmos.DrawLine(c.position + heightAdj, other.position + heightAdj);
                        }
                    } /* end for each selected neighbour */
                }
            }

            return true;
        }
Example #6
0
 Cell IGridCell.GetNeighbour(VectorXZ offset)
 {
     return null;
 }
Example #7
0
 /// <summary>
 /// Gets the neighbour at the specified matrix offset.
 /// </summary>
 /// <param name="offset">The offset.</param>
 /// <returns>
 /// The neighbour cell or null
 /// </returns>
 public Cell GetNeighbour(VectorXZ offset)
 {
     return GetNeighbour(offset.x, offset.z);
 }