//LOS and fog of war is not considered //that has already been built into various function called on UnitControl and GridManager public Tile Analyse(UnitTB unit) { //analyse current tile first List <UnitTB> currentHostilesList; if (!GameControlTB.EnableFogOfWar()) { currentHostilesList = UnitControl.GetHostileInRangeFromTile(unit.occupiedTile, unit); } else { currentHostilesList = UnitControl.GetVisibleHostileInRangeFromTile(unit.occupiedTile, unit); } unit.occupiedTile.AIHostileList = currentHostilesList; if (GameControlTB.EnableCover()) { if (currentHostilesList.Count != 0) { int count = 0; for (int n = 0; n < currentHostilesList.Count; n++) { if ((int)unit.occupiedTile.GetCoverType(currentHostilesList[n].thisT.position) > 0) { count += 1; } } if (count == currentHostilesList.Count) { return(unit.occupiedTile); } } } else { if (currentHostilesList.Count != 0) { return(unit.occupiedTile); } } //get all possible target List <UnitTB> allHostiles = new List <UnitTB>(); if (GameControlTB.EnableFogOfWar()) { allHostiles = UnitControl.GetAllHostileWithinFactionSight(unit.factionID); } else { allHostiles = UnitControl.GetAllHostile(unit.factionID); } //if there's no potential target at all if (allHostiles.Count == 0) { if (unit.attackerList.Count > 0) { return(unit.attackerList[0].unit.occupiedTile); } else { //if stance is set to passive, stay put if (aIStance == _AIStance.Passive) { return(unit.occupiedTile); } } } //get all walkable List <Tile> walkableTiles = GridManager.GetWalkableTilesWithinRange(unit.occupiedTile, unit.GetMoveRange()); //get tiles with target in range from the walkables List <Tile> offensiveTiles = new List <Tile>(); for (int i = 0; i < walkableTiles.Count; i++) { walkableTiles[i].AIHostileList = new List <UnitTB>(); bool visibleOnly = GameControlTB.EnableFogOfWar(); List <UnitTB> hostilesList = UnitControl.GetHostileInRangeFromTile(walkableTiles[i], unit, visibleOnly); walkableTiles[i].AIHostileList = hostilesList; if (hostilesList.Count > 0) { offensiveTiles.Add(walkableTiles[i]); } } //cross search any walkables with any tiles with target List <Tile> offensiveWalkableTiles = new List <Tile>(); for (int i = 0; i < offensiveTiles.Count; i++) { if (walkableTiles.Contains(offensiveTiles[i])) { offensiveWalkableTiles.Add(offensiveTiles[i]); } } //if the game uses cover if (GameControlTB.EnableCover()) { //calculating general direction of enemy, to know which direction to take cover from //Vector3 hostileAveragePos=Vector3.zero; //for(int i=0; i<allHostiles.Count; i++){ // hostileAveragePos+=allHostiles[i].occupiedTile.pos; //} //hostileAveragePos/=allHostiles.Count; //get offensive tile with cover from all hostile List <Tile> offensiveTilesWithAllCover = new List <Tile>(); List <Tile> offensiveTilesWithPartialCover = new List <Tile>(); for (int i = 0; i < offensiveWalkableTiles.Count; i++) { Tile tile = offensiveWalkableTiles[i]; int count = 0; for (int n = 0; n < tile.AIHostileList.Count; n++) { if ((int)tile.GetCoverType(tile.AIHostileList[n].thisT.position) > 0) { count += 1; } } if (count == tile.AIHostileList.Count) { offensiveTilesWithAllCover.Add(tile); } else if (count > 0) { offensiveTilesWithPartialCover.Add(tile); } } if (offensiveTilesWithAllCover.Count > 0) { int rand = UnityEngine.Random.Range(0, offensiveTilesWithAllCover.Count); return(offensiveTilesWithAllCover[rand]); } else if (offensiveTilesWithAllCover.Count > 0) { int rand = UnityEngine.Random.Range(0, offensiveTilesWithPartialCover.Count); return(offensiveTilesWithPartialCover[rand]); } //get any tile with possible cover from the walkables List <Tile> walkableTilesWithCover = new List <Tile>(); for (int i = 0; i < walkableTiles.Count; i++) { if (walkableTiles[i].GotCover()) { walkableTilesWithCover.Add(walkableTiles[i]); } } //cross-search offense and walkable tile with cover //to get tiles which offer cover and the unit can attack from List <Tile> offensiveTilesWithCover = new List <Tile>(); for (int i = 0; i < offensiveTiles.Count; i++) { if (walkableTilesWithCover.Contains(offensiveTiles[i])) { offensiveTilesWithCover.Add(offensiveTiles[i]); } } //if there's any tile that offer cover and target at the same time, use the tile if (offensiveTilesWithCover.Count > 0) { int rand = UnityEngine.Random.Range(0, offensiveTilesWithCover.Count); return(offensiveTilesWithCover[rand]); } //if there's no tile that offer cover and target at the same time //just use any walkable tile with cover instead if (walkableTilesWithCover.Count > 0) { int rand = UnityEngine.Random.Range(0, walkableTilesWithCover.Count); return(walkableTilesWithCover[rand]); } } //if cover system is not used, or there's no cover in any walkable tiles //if there's walkable that the unit can attack from, uses that if (offensiveWalkableTiles.Count > 0) { int rand = UnityEngine.Random.Range(0, offensiveWalkableTiles.Count); return(offensiveWalkableTiles[rand]); } //check if the unit has been attacked, if yes, retaliate UnitTB attacker = unit.GetNearestAttacker(); if (attacker != null) { return(attacker.occupiedTile); } //no hostile unit within range if (aIStance == _AIStance.Active || aIStance == _AIStance.Trigger) { //no hostile detected at all, just move randomly if (allHostiles.Count == 0) { if (walkableTiles.Count > 0) { int rand = UnityEngine.Random.Range(0, walkableTiles.Count); return(walkableTiles[rand]); } } //get the nearest target and move towards it else { int nearest = 999999999; int nearestID = 0; for (int i = 0; i < allHostiles.Count; i++) { int dist = GridManager.Distance(unit.occupiedTile, allHostiles[i].occupiedTile); if (dist < nearest) { nearest = dist; nearestID = i; } } return(allHostiles[nearestID].occupiedTile); } } return(null); }