///two towers attack stuff
    public bool CanTwoAttack(TowerBehavior destination, TowerBehavior attackingTower, TowerBehavior queueTower,
                             float attackPercentage, out float queuePercent)
    {
        queuePercent = 0;
        if (queueTower.StationedUnits <= 0)
        {
            return(false);
        }


        int unitsLeft;

        int numOriginalAttacking = Mathf.CeilToInt(attackingTower.StationedUnits * attackPercentage);
        int maxAdditionAttackers = queueTower.StationedUnits;

        if (SimulateAttackUtil.SimulateAttack((numOriginalAttacking + maxAdditionAttackers),
                                              destination, attackingTower.Faction, out unitsLeft) == false)
        {
            //incase for overload attack
            maxAdditionAttackers -= unitsLeft - 1;
            queuePercent          = AIConstants.RoundPercentToClosestOption((float)maxAdditionAttackers / (float)queueTower.StationedUnits);
            return(false);
        }

        maxAdditionAttackers -= unitsLeft - 1;
        queuePercent          = AIConstants.RoundPercentToClosestOption((float)maxAdditionAttackers / (float)queueTower.StationedUnits);

        if (SimulateAttackUtil.DistanceCheck(queueTower, destination) == false)
        {
            return(false);
        }


        return(true);
    }
    private bool HaveEnoughSoldiers(TowerBehavior AI, TowerBehavior destination, ref float percent)
    {
        //if the Ai doesn't have more units than the destination in general
        //then we can't take over the tower so there is no need to do more calculations
        if (AI.StationedUnits <= destination.StationedUnits)
        {
            percent = AIConstants.RoundPercentToClosestOption(((float)AI.StationedUnits / (float)AI.StationedUnits));
            return(false);
        }

        int AIunits = AI.StationedUnits;

        //how many Units are left after the attack
        int AIunitsLeft;

        //did the "attack" succeed?
        if (SimulateAttackUtil.SimulateAttack(AIunits, destination, AI.Faction, out AIunitsLeft) == false)
        {
            percent = AIConstants.RoundPercentToClosestOption((float)AIunits / (float)AI.StationedUnits);
            return(false);
        }


        AIunits -= AIunitsLeft;
        AIunits += 1;
        percent  = AIConstants.RoundPercentToClosestOption((float)AIunits / (float)AI.StationedUnits);
        return(true);
    }
    //This is the function the AI calls to see if it should attack the chosen tower
    public bool ShouldAIAttack(TowerBehavior AI, TowerBehavior destination, out float percentage,
                               out AIConstants.ReasonFailed reason)
    {
        float chanceToAttackAnyway = AIGameStateManager.PercentToAttackAnyway;

        //setting our out variables(must be garunteed set before the function returns)
        reason     = AIConstants.ReasonFailed.None;
        percentage = 0;

        if (AI.StationedUnits <= 0)
        {
            //percentage is already set to zero
            reason = AIConstants.ReasonFailed.NotEnoughtoSend;
            return(false);
        }

        //random chance to attack anyway
        int randomNum = Random.Range(0, 101);

        if (randomNum <= chanceToAttackAnyway)
        {
            percentage = AIConstants.RoundPercentToClosestOption(((float)AI.StationedUnits / (float)AI.StationedUnits));
            return(true);
        }

        else
        {
            bool cantravel    = SimulateAttackUtil.DistanceCheck(AI, destination);
            bool enoughtUnits = HaveEnoughSoldiers(AI, destination, ref percentage);
            //if distance is ever a factor, than the we don't need to adjust the percentage
            if (enoughtUnits == false && cantravel == false)
            {
                reason = AIConstants.ReasonFailed.Both;
                return(false);
            }
            else if (enoughtUnits == false)
            {
                reason = AIConstants.ReasonFailed.Units;
                return(false);
            }

            else if (cantravel == false)
            {
                reason = AIConstants.ReasonFailed.Distance;
                return(false);
            }
        }


        return(true);
    }
Exemplo n.º 4
0
    private void Defend(MovedUnitsInfo info, int enemyUnitsLeft)
    {
        //if none of the towers are able to make the distance to the AI.
        List <AIBehavior> friendlyTowers = closestFriendlyTowers(info.To);

        //Check if we even have towers to use to defend
        if (friendlyTowers == null || friendlyTowers.Count == 0)
        {
            return;
        }

        Dictionary <AIBehavior, int> helpDefending = new Dictionary <AIBehavior, int>();
        int totalDefendingUnits    = info.To.StationedUnits;
        int numUnitsNeededToDefend = SimulateAttackUtil.NumUnitsNeededToDefend(info.To, info.FromFaction, info.NumberOfUnits);

        for (int i = 0; i < (maxNumberTowersCanDefend <= friendlyTowers.Count ? maxNumberTowersCanDefend : friendlyTowers.Count); i++)
        {
            int additionalUnits = friendlyTowers[0].myTower.StationedUnits;
            //even though this has some extra steps for if condition is equal
            //but figured it would be better than writing out another if statement
            if (totalDefendingUnits + additionalUnits >= numUnitsNeededToDefend)
            {
                additionalUnits -= ((totalDefendingUnits + additionalUnits) - numUnitsNeededToDefend);
                helpDefending.Add(friendlyTowers[i], additionalUnits);
                totalDefendingUnits += additionalUnits;
                break;
            }
            else
            {
                helpDefending.Add(friendlyTowers[i], additionalUnits);
                totalDefendingUnits += additionalUnits;
            }
        }

        if (totalDefendingUnits >= numUnitsNeededToDefend && helpDefending.Count > 0)
        {
            foreach (KeyValuePair <AIBehavior, int> pair in helpDefending)
            {
                pair.Key.SetMyTimer(AIController.GetTimer());
                //find the percent of Soldiers we are attacking
                float percent = AIConstants.RoundPercentToClosestOption((float)pair.Value / (float)pair.Key.myTower.StationedUnits);

                //we don't really need to do anything with the bool from this, it will defend as intended or nothing will happen
                //we don't need to do anything if the start attack fails
                pair.Key.StartAttack(info.To, percent, 1f);
            }
        }
    }