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); }
///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); }
//function is called when the UnitsMoved event is fired private void TowerHasAttack(MovedUnitsInfo attackInfo) { //check to see if the tower being attacked is the AI and the attacking tower is the player if (attackInfo.FromFaction != FactionController.OtherFaction1 && attackInfo.ToFaction == FactionController.OtherFaction1) { //Check if the enemy units can even reach this tower, if (SimulateAttackUtil.DistanceCheck(attackInfo.From, attackInfo.To) == false) { return; } //Check if the enemy units can even take over the tower int EnemyUnitsLeft; if (SimulateAttackUtil.SimulateAttack(attackInfo.NumberOfUnits, attackInfo.To, attackInfo.FromFaction, out EnemyUnitsLeft) == false) { return; } //random check to see if the Ai will defend it float rand = Random.Range(0f, 100f); if (rand <= AIGameStateManager.PercentChanceAIWontDefend) { return; } //if we make it through the check, then Defend Defend(attackInfo, EnemyUnitsLeft); } }
public bool CanOverloadAttack(List <MultiAttackInfo> info) { //at this point it only equals 2 //can the first tower reach the second tower if (SimulateAttackUtil.DistanceCheck(info[0].AI.myTower, info[1].AI.myTower) == false) { return(false); } 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); }
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); } } }
private List <AIBehavior> closestFriendlyTowers(TowerBehavior defendingAI) { //Get the list of current AI Towers List <AIBehavior> AI = AIController.GetAITowers(); //Hashtable for all of the towers SortedDictionary <float, List <AIBehavior> > closestTowers = new SortedDictionary <float, List <AIBehavior> >(); foreach (AIBehavior ai in AI) { if (ai.myTower == defendingAI) { continue; } float distance = Vector3.Distance(defendingAI.transform.position, ai.myTower.transform.position); if (SimulateAttackUtil.DistanceCheck(defendingAI, ai.myTower) == true) { if (!closestTowers.ContainsKey(distance)) { List <AIBehavior> newList = new List <AIBehavior>(); newList.Add(ai); closestTowers.Add(distance, newList); } else { closestTowers[distance].Add(ai); } } } List <AIBehavior> towersToSend = new List <AIBehavior>(); foreach (KeyValuePair <float, List <AIBehavior> > pair in closestTowers) { foreach (AIBehavior ai in pair.Value) { towersToSend.Add(ai); } } return(towersToSend); }