//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; }
//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); }