public void MoveGroupOutTheWay(Group group, Vector2 movementDirection, GridRestriction gridRestriction)
        {
            if (group.IgnoreMoveGroupOutTheWay || group.Path != null)
            {
                return;
            }

            //Find the largest density of the groups on the map
            var centroid  = GetCentroid();
            var direction = movementDirection - centroid;

            //default will size of the vector will be 2
            direction.Normalize();
            direction *= 2;
            var destination = group.Center + direction;
            var startGrid   = GameManager.Instance.WorldToGrid(group.Center);
            var endGrid     = GameManager.Instance.WorldToGrid(destination);
            var grid        = GameManager.Instance.GridMap;

            //if()
            //var path = Pathfinder.FindPath(startGrid, endGrid, grid, true);
            Stack <Node> path = null;

            //if centroid method fails move to an empty cell
            if (path == null)
            {
                var neighbours = group.GetNeighbouringCells();
                var startNode  = GameManager.Instance.GridMap[startGrid.x][startGrid.y];

                foreach (var neighbour in neighbours)
                {
                    var potentialPath = GetPathInDirection(startNode, neighbour, group, GetVisitedMap(), gridRestriction);

                    if (potentialPath != null)
                    {
                        group.Path = potentialPath;
                        break;
                    }
                }
            }
            else
            {
                group.Path = new Path(path);
            }

            MakeWayForGroup(group, gridRestriction);
        }
        public void SetDestination(Vector2 destination, Group group, GridRestriction gridRestriction = null)
        {
            //First find path from the center to the destination
            //Assumption is that all of the agents in groups are friendly npcs
            var start = GameManager.Instance.WorldToGrid(group.Center);

            var          end             = GameManager.Instance.WorldToGrid(destination);
            var          destinationNode = GameManager.Instance.GridMap[end.x][end.y];
            var          startNode       = GameManager.Instance.GridMap[start.x][start.y];
            Path         path            = null;
            Stack <Node> potentialPath   = null;

            //If the destination is already in a path of some other group change your final destination
            if (OtherGroupIsOnWayTo(destinationNode, group))
            {
                path = GetPathInDirection(startNode, destinationNode, group, GetVisitedMap(), gridRestriction);
            }

            if (path == null)
            {
                potentialPath = Pathfinder.FindPath(start, end, GameManager.Instance.GridMap, true);
            }

            //Debug.Log($"Group {groupName} Start {start} End {end}");

            if (path == null && potentialPath == null)
            {
                Debug.LogWarning("Path does not exist");
                return;
            }

            path       = path ?? new Path(potentialPath);
            group.Path = path;

            MakeWayForGroup(group, gridRestriction);
        }
        private void MakeWayForGroup(Group group, GridRestriction gridRestriction)
        {
            if (group.Path == null)
            {
                return;
            }

            foreach (var kvp in _groups)
            {
                var otherGroup = kvp.Value;

                if (group != otherGroup)
                {
                    var intersectionNode = group.FindIntersection(otherGroup);

                    if (intersectionNode != null)
                    {
                        group.IgnoreMoveGroupOutTheWay = true;
                        MoveGroupOutTheWay(otherGroup, group.Path.GetMovementDirection(), gridRestriction);
                        group.IgnoreMoveGroupOutTheWay = false;
                    }
                }
            }
        }
        public Path GetPathInDirection(Node fromNode, Node toNode, Group group, bool[][] visitedMap, GridRestriction gridRestriction = null)
        {
            Path path  = null;
            var  queue = new Queue <Node>();

            queue.Enqueue(toNode);

            while (queue.Any())
            {
                //If path found stop search
                if (path != null)
                {
                    break;
                }

                var node = queue.Dequeue();

                //If already visited the node skip to the next one
                if (visitedMap[node.GridPosition.x][node.GridPosition.y])
                {
                    continue;
                }


                if (node.IsPlayerWalkable && !Intersects(group, node))
                {
                    var potentialPath = Pathfinder.FindPath(fromNode.GridPosition, node.GridPosition,
                                                            GameManager.Instance.GridMap, true);

                    if (potentialPath != null && (gridRestriction == null || gridRestriction.IsValid(node)))
                    {
                        path = new Path(potentialPath);
                    }
                }

                visitedMap[node.GridPosition.x][node.GridPosition.y] = true;

                var neighbours = node.GetWalkableNeighbours();

                foreach (var neighbour in neighbours)
                {
                    queue.Enqueue(neighbour);
                }
            }

            return(path);
        }