//Fancy cooroutines because we need delays for the AI to work public IEnumerator EnemyActions(float delay) { //Play the voice line at the beginning of turn (sass) SoundMan.playEnemyGodTurnStart(); //Updates the order the enemy units move in (no move and attack goes first, followed by move + attack, followed by move no attack) also order by how far away they are updatePriorities(); //Sort by priority BoardMan.enemyUnits.Sort((x, y) => x.MovePriority.CompareTo(y.MovePriority)); //Make sure things dont break if (BoardMan.enemyUnits.Count == 1 && !(BoardMan.enemyUnits[0] as God).isInBattle) { (BoardMan.enemyUnits[0] as God).forcedEnterBattle(); } foreach (Unit enemyUnit in BoardMan.enemyUnits) { Camera.main.GetComponent <CombatCam>().lookAt(enemyUnit.unitGameObject().transform.position); //Logic for units in battle if (enemyUnit.getPos().x != -1 && enemyUnit.getPos().y != -1) { yield return(new WaitForSeconds(delay)); //Show the closest movement tile showClosestTile(enemyUnit); yield return(new WaitForSeconds(delay)); //Find it MapMan.Selected = enemyUnit.unitGameObject(); GameObject closestTile = GameObject.FindGameObjectWithTag("MoveableTile"); //Wait a frame so we can check if we can actually move (or need to) yield return(null); if (closestTile != null) { //Woo for using function we made for testing Camera.main.GetComponent <CombatCam>().lookAt(closestTile.transform.position); closestTile.GetComponent <Movable>().TestClick(); closestTile.GetComponent <Movable>().OnMouseOver(); yield return(new WaitForSeconds(delay)); } //Set us to selected and try to show an attackable tile MapMan.Selected = enemyUnit.unitGameObject(); BoardMan.showAttackable(enemyUnit); yield return(new WaitForSeconds(delay)); //Wait a frame to see if we can attack yield return(null); //Yes this is semi random if there's more than one. Will be based off remaining health in future GameObject AttackableTile = GameObject.FindGameObjectWithTag("AttackableTile"); //Attack if we can, then end turn if (AttackableTile != null) { Camera.main.GetComponent <CombatCam>().lookAt(AttackableTile.transform.position); AttackableTile.GetComponent <Attackable>().TestClick(); AttackableTile.GetComponent <Attackable>().OnMouseOver(); yield return(new WaitForSeconds(delay)); } else { //End turn if we cant attack enemyUnit.EndTurnButton(); } } //Logic for enemy god that is not in battle (using abilities) else { MapMan.Selected = enemyUnit.unitGameObject(); //Check if we can use any abilites List <Ability> useableAbilities = new List <Ability>(); foreach (string ability in (enemyUnit as God).getAbilites()) { Debug.Log(ability); //If we have enough faith to use and ablilty, add it to the list if ((enemyUnit as God).faith >= Ability.LoadAbilityFromName(ability).FaithCost) { useableAbilities.Add(Ability.LoadAbilityFromName(ability)); } } //Chose to use an ability or not based chance weighted by how many abilties we can use float roll = Random.Range(0.0f, 100.0f); Ability abilityToBeUsed = null; if (roll < useableAbilities.Count * 25 || useableAbilities.Count == 4) { //Use system.random to pick a random ability System.Random r = new System.Random(); abilityToBeUsed = useableAbilities[r.Next(useableAbilities.Count)]; } //If we're going to use an abilty if (abilityToBeUsed != null) { //Draw the tiles BoardMan.useAbility(abilityToBeUsed.AbilityName); //Setup lists for tiles and units List <Targetable> validTiles = new List <Targetable>(); List <Unit> parallelTargets = new List <Unit>(); //Wait for tiles to be done drawing while (BoardMan.areAbilityTilesDrawing()) { yield return(new WaitForSeconds(1)); } //If we are using something single target (buff and debuff included) if (abilityToBeUsed.AbiltyType != Ability.ABILITYTYPE.MultiTarget) { foreach (GameObject tile in GameObject.FindGameObjectsWithTag("TargetableTile")) { Targetable tileScript = tile.GetComponent <Targetable>(); tileScript.OnMouseOver(); if (tileScript.valid) { validTiles.Add(tileScript); } } //Make a parallel list of units to valid tiles foreach (Targetable tile in validTiles) { foreach (Unit unit in tile.targets) { if (tile.pos.x == unit.getPos().x&& tile.pos.y == unit.getPos().y) { parallelTargets.Add(unit); } } } } //Avoid calling OnMouseOver for multitarget, so we dont cover the map in AOE shapes else { foreach (GameObject tile in GameObject.FindGameObjectsWithTag("TargetableTile")) { foreach (Unit unit in BoardMan.playerUnits) { if (tile.GetComponent <Targetable>().pos.x == unit.getPos().x&& tile.GetComponent <Targetable>().pos.y == unit.getPos().y) { validTiles.Add(tile.GetComponent <Targetable>()); parallelTargets.Add(unit); } } } } //Pause to the player can see the targeted tiles yield return(new WaitForSeconds(delay)); Targetable target = null; int mostWorshipperCount = 0; int leastWorshipperCount = int.MaxValue; //Do stuff based on ability type switch (abilityToBeUsed.AbiltyType) { case Ability.ABILITYTYPE.SingleTarget: Debug.Log("Using a single target ability!"); //Use single target on weakest unit leastWorshipperCount = int.MaxValue; for (int i = 0; i < parallelTargets.Count; i++) { if (parallelTargets[i].WorshiperCount < leastWorshipperCount) { target = validTiles[i]; } } if (target != null && MapMan.Selected != null) { target.testClick(); target.OnMouseOver(); } else { enemyUnit.EndTurnButton(); } break; case Ability.ABILITYTYPE.MultiTarget: Debug.Log("Using a multi target ability!"); //Use multi target centered on weakest unit leastWorshipperCount = int.MaxValue; for (int i = 0; i < parallelTargets.Count; i++) { if (parallelTargets[i].WorshiperCount < leastWorshipperCount) { target = validTiles[i]; } } target.OnMouseOver(); yield return(new WaitForSeconds(delay)); if (target != null && MapMan.Selected != null) { target.testClick(); target.OnMouseOver(); } else { enemyUnit.EndTurnButton(); } break; case Ability.ABILITYTYPE.Buff: Debug.Log("Using a buff ability!"); //Use buff on healthiest unit mostWorshipperCount = 0; for (int i = 0; i < parallelTargets.Count; i++) { if (parallelTargets[i].WorshiperCount > mostWorshipperCount) { target = validTiles[i]; } } if (target != null && MapMan.Selected != null) { target.testClick(); target.OnMouseOver(); } else { enemyUnit.EndTurnButton(); } break; case Ability.ABILITYTYPE.Debuff: Debug.Log("Using a debuff ability!"); //Use debuff on healthiest unit mostWorshipperCount = 0; for (int i = 0; i < parallelTargets.Count; i++) { if (parallelTargets[i].WorshiperCount > mostWorshipperCount) { target = validTiles[i]; } } if (target != null && MapMan.Selected != null) { target.testClick(); target.OnMouseOver(); } else { enemyUnit.EndTurnButton(); } break; } } //If we're not going to use and ability, end turn else { enemyUnit.EndTurnButton(); } } } }