public override AIState DetermineCombatTarget()
    {
        targetActor      = null;
        distanceToTarget = float.PositiveInfinity;

        MovePointBehavior movePoint = Actor.currentMovePoint;

        CombatSquadBehavior combatSquad = Actor.GetComponent <CombatSquadBehavior>();

        if (combatSquad == null)
        {
            Debug.LogError(string.Format("AI Squad ({0}) does not have a CombatSquadBehavior!", Actor.transform.name));
            Actor.actorHasMovedThisTurn = true;

            return(AIState.PickingSquad);
        }

        int attackRange = combatSquad.Squad.Range;

        // Retrieve a list of nodes in range.
        List <MovePointBehavior> graph = new List <MovePointBehavior>();

        movePoint.BuildGraph(attackRange, 0, grid, ref graph, true);

        // Iterate over the nodes to determine if any node has an enemy.
        foreach (MovePointBehavior node in graph)
        {
            ActorBehavior actorOnNode = gameController.GetActorOnNode(node);

            if (actorOnNode == null || (actorOnNode.theSide != GameControllerBehaviour.UnitSide.player))
            {
                continue;
            }

            beginCombatWithTarget(actorOnNode);

            return(AIState.WaitingForCombat);
        }

        return(AIState.PickingSquad);
    }
    /// <summary>
    /// Determines the target for this squad.
    /// </summary>
    /// <returns>AI state the controller should enter after determining the target.</returns>
    public override AIState DetermineMovePoint()
    {
        targetActor = null;

        MovePointBehavior movePoint = Actor.currentMovePoint;

        // Get a list of spaces that are within attack range (movement + range).
        CombatSquadBehavior combatSquad = Actor.GetComponent <CombatSquadBehavior>();

        if (combatSquad == null)
        {
            Debug.LogError(string.Format("AI Squad ({0}) does not have a CombatSquadBehavior!", Actor.transform.name));
            Actor.actorHasMovedThisTurn = true;

            return(AIState.PickingSquad);
        }

        int attackRange  = combatSquad.Squad.Range;
        int moveDistance = combatSquad.Squad.Speed;

        List <MovePointBehavior> pointsInRange = new List <MovePointBehavior>();

        movePoint.BuildGraph(attackRange + moveDistance, 0, grid, ref pointsInRange, true);

        // Find the closest actor in attack range.
        foreach (MovePointBehavior node in pointsInRange)
        {
            ActorBehavior actorOnNode = gameController.GetActorOnNode(node);

            if (actorOnNode == null || (actorOnNode.theSide != GameControllerBehaviour.UnitSide.player))
            {
                continue;
            }

            // If the distance to the target is less than the distance to the selected target, target it instead.
            float distance = Vector3.Distance(Actor.transform.position, actorOnNode.transform.position);
            if (distance < distanceToTarget)
            {
                targetActor      = actorOnNode;
                distanceToTarget = distance;
            }
        }

        // If a target was found, move toward it.
        if (targetActor != null)
        {
            // Build a path to the actor.
            List <MovePointBehavior> pathList = movePoint.FindPath(targetActor.currentMovePoint, (moveDistance + attackRange), grid, true);

            // Remove the target's move point from the grid.
            pathList.RemoveAt(pathList.Count - 1);

            // Determine the excess items in the path list.
            int excess = pathList.Count - moveDistance;

            if (excess > 0)
            {
                pathList.RemoveRange(pathList.Count - excess, excess);
            }

            if (pathList.Count > 0)
            {
                MovePointBehavior targetPoint = pathList[pathList.Count - 1];

                // Determine the fastest path to the target point.
                pathList = movePoint.FindPath(targetPoint, moveDistance, grid);

                if (pathList != null)
                {
                    Actor.pathList = pathList;
                    Actor.canMove  = true;

                    grid.ignoreList.Remove(movePoint);

                    grid.ignoreList.Add(targetPoint);

                    Actor.actorHasMovedThisTurn = true;

                    return(AIState.WaitingForMove);
                }
            }
            else
            {
                Actor.actorHasMovedThisTurn = true;

                return(AIState.WaitingForMove);
            }
        }
        else
        {
            targetActor      = null;
            distanceToTarget = float.PositiveInfinity;

            // No target was found, so determine the closest target to move towards.
            foreach (ActorBehavior playerSquad in gameController.playerTeam)
            {
                float distance = Vector3.Distance(Actor.transform.position, playerSquad.transform.position);
                if (distance < distanceToTarget)
                {
                    targetActor      = playerSquad;
                    distanceToTarget = distance;
                }
            }

            // Retrieve a list of all nodes within movement range.
            List <MovePointBehavior> nodesInRange = new List <MovePointBehavior>();
            movePoint.BuildGraph(moveDistance, 0, grid, ref nodesInRange);

            // Cast a ray to the target and retrieve the farthest one that is in our movement range.
            Ray ray = new Ray(Actor.transform.position, (targetActor.transform.position - Actor.transform.position).normalized);

            // Perform raycasting and store a list of all objects that have been selected.
            List <RaycastHit> hits = new List <RaycastHit>();
            hits.AddRange(Physics.RaycastAll(ray));

            // Iterate over the selection list to determine if the player has clicked on one of her squads.
            foreach (RaycastHit hitInfo in hits.OrderBy(l => l.distance).Reverse())
            {
                MovePointBehavior hitBehavior = hitInfo.transform.GetComponent <MovePointBehavior>();
                if (hitBehavior == null || !nodesInRange.Contains(hitBehavior))
                {
                    continue;
                }

                // Target node has been found! Find a path to it.
                List <MovePointBehavior> pathList = movePoint.FindPath(hitBehavior, moveDistance, grid);

                if (pathList != null)
                {
                    Actor.pathList = pathList;
                    Actor.canMove  = true;

                    grid.ignoreList.Remove(movePoint);
                    grid.ignoreList.Add(hitBehavior);

                    Actor.actorHasMovedThisTurn = true;

                    return(AIState.WaitingForMove);
                }
            }
        }

        Actor.actorHasMovedThisTurn = true;
        return(AIState.PickingSquad);
    }