Esempio n. 1
0
    public override IEnumerator FindPath(Vector2 start, Vector2 target, bool debug)
    {
        Node startNode  = grid.GetNodeFromWorldPostion(start);
        Node targetNode = grid.GetNodeFromWorldPostion(target);

        path = ReconstructPath(startNode, debug);

        List <Node> openSet   = new List <Node>();
        List <Node> closedSet = new List <Node>();

        startNode.gCost = 0;
        startNode.fCost = grid.GetDistance(startNode, targetNode);
        openSet.Add(startNode);
        if (debug)
        {
            tiles[startNode.x, startNode.y].SetDebugColor(Color.cyan);
        }
        yield return(new WaitForSeconds(thinkTimeStep));

        while (openSet.Count > 0)
        {
            Node currentNode = openSet[0];

            for (int i = 1; i < openSet.Count; i++)
            {
                if (currentNode.fCost > openSet[i].fCost)
                {
                    currentNode = openSet[i];
                }
            }

            if (currentNode == targetNode)
            {
                path = ReconstructPath(currentNode, debug);
                break;
            }

            openSet.Remove(currentNode);
            closedSet.Add(currentNode);
            if (debug)
            {
                tiles[currentNode.x, currentNode.y].SetDebugColor(Color.yellow);
            }
            yield return(new WaitForSeconds(thinkTimeStep));

            foreach (Node neighbor in grid.GetNodeNeighbors4(currentNode))
            {
                if (closedSet.Contains(neighbor))
                {
                    continue;
                }

                float newNeighborGCost = currentNode.gCost + (grid.GetDistance(currentNode, neighbor) * (currentNode.travelCost + neighbor.travelCost) / 2);
                if (newNeighborGCost < neighbor.gCost || !openSet.Contains(neighbor))
                {
                    neighbor.previousNode = currentNode;
                    neighbor.gCost        = newNeighborGCost;
                    neighbor.fCost        = newNeighborGCost + grid.GetDistance(neighbor, targetNode);

                    if (!openSet.Contains(neighbor))
                    {
                        openSet.Add(neighbor);
                        if (debug)
                        {
                            tiles[neighbor.x, neighbor.y].SetDebugColor(Color.cyan);
                        }
                        yield return(new WaitForSeconds(thinkTimeStep));
                    }
                }
            }
        }
        yield return(null);
    }
Esempio n. 2
0
    //this formation makes a number of attacks against the tagret formation, possibly damaging it
    public void MeleeAttack(Formation target)
    {
        if (!(pathGrid.GetDistance(transform.position, target.transform.position) <= meleeWeapon.GetRange()))
        {
            Debug.Log("Target out of range");
            return;
        }
        else if (hasAttacked)
        {
            Debug.Log("This Formation has already attacked");
            return;
        }

        //the number of attacks this formation will make
        int numAttackers;

        int targetRemainingFrontage = Mathf.Min(target.frontage, target.currentTroops);

        //if the target is wider or equal width, make attacks equal to frontage
        if (targetRemainingFrontage >= frontage)
        {
            numAttackers = frontage;
        }
        //if this formation is wider by more than 1, make attacks equal to frontage + 4
        else if (frontage > targetRemainingFrontage + 1)
        {
            numAttackers = (targetRemainingFrontage + 2);
        }
        //if this formation is wider by 1, make attacks equal to frontage + 2
        else
        {
            numAttackers = targetRemainingFrontage + 1;
        }

        //multiply the number of melee attackers by the number of ranks that can reach
        numAttackers *= meleeWeapon.GetReach();

        //if there are more attacks than troops remaining, reduce number of attacks to troops remaining
        if (numAttackers > currentTroops)
        {
            numAttackers = currentTroops;
        }

        //calculate what kind of facing is being attacked, front, front-flank, rear, or rear-flank
        int facingType = Mathf.Min(Mathf.Abs(target.facing - facing), 6 - Mathf.Abs(target.facing - facing));

        //if facingType = 0, their facing is the same, so it's a rear attack
        //if facingType = 1, it's a rear-flank
        //if facingType = 2, it's a front flank
        //if facingType = 3, they are directly opposite each other so it's a frontal attack

        int bonusAttack = 0;

        //apply bonuses based on facing
        //flanking attacks on a hex grid result in less troops being able to attack, but gaining a bonus to hit
        if (facingType == 2) //front-flank
        {
            numAttackers = (int)Mathf.Round(0.75f * numAttackers);
            bonusAttack  = 2;
            Debug.Log("Front-Flank Attack");
        }
        else if (facingType == 1) //rear-flank
        {
            numAttackers = (int)Mathf.Round(0.75f * numAttackers);
            bonusAttack  = 4;
            Debug.Log("Rear-Flank Attack");
        }
        else if (facingType == 0) //rear
        {
            bonusAttack = 6;
            Debug.Log("Rear Attack");
        }

        //for each attack, attack, check if a character has died and apply the resulting effects
        for (int attacks = 0; attacks < numAttackers; attacks++)
        {
            troop.Attack(target.troop, meleeWeapon, bonusAttack);
            //if the target troop dies, reset their health and increment the casualties
            if (!target.troop.IsAlive())
            {
                target.troop.ResetHealth();
                target.casualties++;
            }
        }

        SetHasAttacked(true);
    }