void MoveUnitToTileInstant(UnitTB unit, Tile tile) { List <Tile> path = AStar.SearchToOccupiedTile(unit.occupiedTile, tile); //make sure the target tile is not occupied if (path.Count > 0) { if (path[path.Count - 1].unit != null) { path.RemoveAt(path.Count - 1); } } //make sure the unit doesnt move beyond the allowed range while (path.Count > Mathf.Max(1, unit.GetMoveRange() + 1)) { path.RemoveAt(path.Count - 1); } if (path.Count > 0) { Tile destinationTile = path[path.Count - 1]; unit.occupiedTile.unit = null; unit.occupiedTile = destinationTile; destinationTile.unit = unit; unit.thisT.position = destinationTile.pos; } unitInAction = false; }
void DrawSelectedUnit(UnitTB unit) { GUIStyle style = new GUIStyle(); style.fontSize = 20; style.fontStyle = FontStyle.Bold; style.normal.textColor = UI.colorH; style.alignment = TextAnchor.UpperCenter; int winWidth = 300; int winHeight = 550; int startX = Screen.width / 2 - 350; int startY = Screen.height / 2 - winHeight / 2; for (int i = 0; i < 3; i++) { GUI.Box(new Rect(startX, startY, winWidth, winHeight), ""); } startX += 15; winWidth -= 30; GUI.Label(new Rect(startX, startY + 10, winWidth, winHeight), unit.unitName, style); GUI.Label(new Rect(startX, startY + 12, winWidth, winHeight), "_________________________________________________", style); startY += 40; GUI.DrawTexture(new Rect(startX + 10, startY, 60, 60), texBar); GUI.DrawTexture(new Rect(startX + 13, startY + 3, 54, 54), unit.icon); style.alignment = TextAnchor.UpperLeft; style.fontSize = 16; GUI.Label(new Rect(startX + 80, startY + 10, winWidth - 80, winHeight), "Hit Point:\nAction Point:", style); style.alignment = TextAnchor.UpperRight; GUI.Label(new Rect(startX + 80, startY + 10, winWidth - 80, winHeight), unit.fullHP + "\n" + unit.fullAP, style); startY += 70; if (infoTab == _InfoTab.General) { style.alignment = TextAnchor.UpperCenter; style.wordWrap = true; style.normal.textColor = UI.colorN; GUI.Label(new Rect(startX, startY, winWidth, 100), unit.desp, style); } else { string offText = ""; string offVText = ""; if (unit.attackMode == _AttackMode.Hybrid) { offText = "Damage (melee/range):\nHit (melee/range):\nCritical (melee/range):\nAttack Range"; offVText += unit.GetMeleeDamageMin() + "-" + unit.GetMeleeDamageMax() + "/" + unit.GetRangeDamageMin() + "-" + unit.GetRangeDamageMax() + "\n"; offVText += (unit.GetMeleeAttack() * 100).ToString("f0") + "/" + (unit.GetRangeAttack() * 100).ToString("f0") + "%" + "\n"; offVText += (unit.GetMeleeCritical() * 100).ToString("f0") + "/" + (unit.GetRangeCritical() * 100).ToString("f0") + "%" + "\n"; offVText += unit.GetAttackRangeMax().ToString("f0") + "\n"; } else { offText = "Attack Damage:\nHit Chance:\nCritical Hit Chance:\nAttack Range:"; } if (unit.attackMode == _AttackMode.Melee) { offVText += unit.GetMeleeDamageMin() + "-" + unit.GetMeleeDamageMax() + "\n"; offVText += (unit.GetMeleeAttack() * 100).ToString("f0") + "%" + "\n"; offVText += (unit.GetMeleeCritical() * 100).ToString("f0") + "%" + "\n"; offVText += unit.GetAttackRangeMax().ToString("f0") + "\n"; } else if (unit.attackMode == _AttackMode.Range) { offVText += unit.GetRangeDamageMin() + "-" + unit.GetRangeDamageMax() + "\n"; offVText += (unit.GetRangeAttack() * 100).ToString("f0") + "%" + "\n"; offVText += (unit.GetRangeCritical() * 100).ToString("f0") + "%" + "\n"; int dist = unit.GetAttackRangeMin(); if (dist <= 0) { offVText += unit.GetAttackRangeMax().ToString("f0") + "\n"; } else { offVText += unit.GetRangeDamageMin() + "-" + unit.GetRangeDamageMax() + "\n"; } } string defText = "Armour:\nDodge Chance:\nCritical Immunity:"; string miscText = "Mobility:\nSpeed:\nAbilities:"; string defVText = ""; defVText += unit.GetDmgReduc().ToString("f0") + "\n"; defVText += (unit.GetDefend() * 100).ToString("f0") + "%" + "\n"; defVText += (unit.GetCritDef() * 100).ToString("f0") + "%" + "\n"; string miscVText = ""; miscVText += unit.GetMoveRange().ToString("f0") + "\n"; miscVText += unit.GetTurnPriority().ToString("f0") + "\n"; style.alignment = TextAnchor.UpperLeft; style.fontSize = 16; style.normal.textColor = UI.colorH; GUI.Label(new Rect(startX, startY, winWidth, winHeight), "Offense:", style); style.fontSize = 12; style.normal.textColor = UI.colorN; GUI.Label(new Rect(startX, startY + 18, winWidth, winHeight), offText, style); style.alignment = TextAnchor.UpperRight; GUI.Label(new Rect(startX, startY + 18, winWidth, winHeight), offVText, style); startY += 90; style.alignment = TextAnchor.UpperLeft; style.fontSize = 16; style.normal.textColor = UI.colorH; GUI.Label(new Rect(startX, startY, winWidth, winHeight), "Defense:", style); style.fontSize = 12; style.normal.textColor = UI.colorN; GUI.Label(new Rect(startX, startY + 18, winWidth, winHeight), defText, style); style.alignment = TextAnchor.UpperRight; GUI.Label(new Rect(startX, startY + 18, winWidth, winHeight), defVText, style); startY += 75; style.alignment = TextAnchor.UpperLeft; style.fontSize = 16; style.normal.textColor = UI.colorH; GUI.Label(new Rect(startX, startY, winWidth, winHeight), "Misc:", style); style.fontSize = 12; style.normal.textColor = UI.colorN; GUI.Label(new Rect(startX, startY + 18, winWidth, winHeight), miscText, style); style.alignment = TextAnchor.UpperRight; GUI.Label(new Rect(startX, startY + 18, winWidth, winHeight), miscVText, style); startY += 65; List <int> abilityIDList = unit.abilityIDList; for (int i = 0; i < abilityIDList.Count; i++) { foreach (UnitAbility uAB in unitAbilityList) { if (uAB.ID == abilityIDList[i]) { GUI.DrawTexture(new Rect(15 + startX + i * 35, startY, 31, 31), texBar); GUI.DrawTexture(new Rect(15 + startX + i * 35 + 2, startY + 2, 27, 27), uAB.icon); GUIContent cont = new GUIContent("", uAB.ID.ToString()); GUI.Label(new Rect(15 + startX + i * 35, startY + 3, 25, 25), cont); } } } startY += 40; if (GUI.tooltip != "") { int ID = int.Parse(GUI.tooltip); foreach (UnitAbility uAB in unitAbilityList) { if (uAB.ID == ID) { style.alignment = TextAnchor.UpperCenter; style.wordWrap = true; GUI.Label(new Rect(startX + 3, startY + 3, winWidth, 50), uAB.desp.ToString()); } } } } string buttonText = "Less Details"; if (infoTab == _InfoTab.General) { buttonText = "More Details"; } bool switchFlag = GUI.Button(new Rect(startX + winWidth / 2 - 60, Screen.height / 2 + winHeight / 2 - 40, 120, 30), buttonText, UI.buttonStyle); if (switchFlag) { if (infoTab == _InfoTab.General) { infoTab = _InfoTab.Stats; } else { infoTab = _InfoTab.General; } } }
//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; }
void MoveUnitToTileInstant(UnitTB unit, Tile tile) { List<Tile> path=AStar.SearchToOccupiedTile(unit.occupiedTile, tile); //make sure the target tile is not occupied if(path.Count>0){ if(path[path.Count-1].unit!=null) path.RemoveAt(path.Count-1); } //make sure the unit doesnt move beyond the allowed range while(path.Count>Mathf.Max(1, unit.GetMoveRange()+1)){ path.RemoveAt(path.Count-1); } if(path.Count>0){ Tile destinationTile=path[path.Count-1]; unit.occupiedTile.unit=null; unit.occupiedTile=destinationTile; destinationTile.unit=unit; unit.thisT.position=destinationTile.pos; } unitInAction=false; }
void DrawSelectedUnit(UnitTB unit) { GUIStyle style=new GUIStyle(); style.fontSize=20; style.fontStyle=FontStyle.Bold; style.normal.textColor=UI.colorH; style.alignment=TextAnchor.UpperCenter; int winWidth=300; int winHeight=550; int startX=Screen.width/2-350; int startY=Screen.height/2-winHeight/2; for(int i=0; i<3; i++) GUI.Box(new Rect(startX, startY, winWidth, winHeight), ""); startX+=15; winWidth-=30; GUI.Label(new Rect(startX, startY+10, winWidth, winHeight), unit.unitName, style); GUI.Label(new Rect(startX, startY+12, winWidth, winHeight), "_________________________________________________", style); startY+=40; GUI.DrawTexture(new Rect(startX+10, startY, 60, 60), texBar); GUI.DrawTexture(new Rect(startX+13, startY+3, 54, 54), unit.icon); style.alignment=TextAnchor.UpperLeft; style.fontSize=16; GUI.Label(new Rect(startX+80, startY+10, winWidth-80, winHeight), "Hit Point:\nAction Point:", style); style.alignment=TextAnchor.UpperRight; GUI.Label(new Rect(startX+80, startY+10, winWidth-80, winHeight), unit.fullHP+"\n"+unit.fullAP, style); startY+=70; if(infoTab==_InfoTab.General){ style.alignment=TextAnchor.UpperCenter; style.wordWrap=true; style.normal.textColor=UI.colorN; GUI.Label(new Rect(startX, startY, winWidth, 100), unit.desp, style); } else{ string offText=""; string offVText=""; if(unit.attackMode==_AttackMode.Hybrid){ offText="Damage (melee/range):\nHit (melee/range):\nCritical (melee/range):\nAttack Range"; offVText+=unit.GetMeleeDamageMin()+"-"+unit.GetMeleeDamageMax()+"/"+unit.GetRangeDamageMin()+"-"+unit.GetRangeDamageMax()+"\n"; offVText+=(unit.GetMeleeAttack()*100).ToString("f0")+"/"+(unit.GetRangeAttack()*100).ToString("f0")+"%"+"\n"; offVText+=(unit.GetMeleeCritical()*100).ToString("f0")+"/"+(unit.GetRangeCritical()*100).ToString("f0")+"%"+"\n"; offVText+=unit.GetAttackRangeMax().ToString("f0")+"\n"; } else{ offText="Attack Damage:\nHit Chance:\nCritical Hit Chance:\nAttack Range:"; } if(unit.attackMode==_AttackMode.Melee){ offVText+=unit.GetMeleeDamageMin()+"-"+unit.GetMeleeDamageMax()+"\n"; offVText+=(unit.GetMeleeAttack()*100).ToString("f0")+"%"+"\n"; offVText+=(unit.GetMeleeCritical()*100).ToString("f0")+"%"+"\n"; offVText+=unit.GetAttackRangeMax().ToString("f0")+"\n"; } else if(unit.attackMode==_AttackMode.Range){ offVText+=unit.GetRangeDamageMin()+"-"+unit.GetRangeDamageMax()+"\n"; offVText+=(unit.GetRangeAttack()*100).ToString("f0")+"%"+"\n"; offVText+=(unit.GetRangeCritical()*100).ToString("f0")+"%"+"\n"; int dist=unit.GetAttackRangeMin(); if(dist<=0) offVText+=unit.GetAttackRangeMax().ToString("f0")+"\n"; else offVText+=unit.GetRangeDamageMin()+"-"+unit.GetRangeDamageMax()+"\n"; } string defText="Armour:\nDodge Chance:\nCritical Immunity:"; string miscText="Mobility:\nSpeed:\nAbilities:"; string defVText=""; defVText+=unit.GetDmgReduc().ToString("f0")+"\n"; defVText+=(unit.GetDefend()*100).ToString("f0")+"%"+"\n"; defVText+=(unit.GetCritDef()*100).ToString("f0")+"%"+"\n"; string miscVText=""; miscVText+=unit.GetMoveRange().ToString("f0")+"\n"; miscVText+=unit.GetTurnPriority().ToString("f0")+"\n"; style.alignment=TextAnchor.UpperLeft; style.fontSize=16; style.normal.textColor=UI.colorH; GUI.Label(new Rect(startX, startY, winWidth, winHeight), "Offense:", style); style.fontSize=12; style.normal.textColor=UI.colorN; GUI.Label(new Rect(startX, startY+18, winWidth, winHeight), offText, style); style.alignment=TextAnchor.UpperRight; GUI.Label(new Rect(startX, startY+18, winWidth, winHeight), offVText, style); startY+=90; style.alignment=TextAnchor.UpperLeft; style.fontSize=16; style.normal.textColor=UI.colorH; GUI.Label(new Rect(startX, startY, winWidth, winHeight), "Defense:", style); style.fontSize=12; style.normal.textColor=UI.colorN; GUI.Label(new Rect(startX, startY+18, winWidth, winHeight), defText, style); style.alignment=TextAnchor.UpperRight; GUI.Label(new Rect(startX, startY+18, winWidth, winHeight), defVText, style); startY+=75; style.alignment=TextAnchor.UpperLeft; style.fontSize=16; style.normal.textColor=UI.colorH; GUI.Label(new Rect(startX, startY, winWidth, winHeight), "Misc:", style); style.fontSize=12; style.normal.textColor=UI.colorN; GUI.Label(new Rect(startX, startY+18, winWidth, winHeight), miscText, style); style.alignment=TextAnchor.UpperRight; GUI.Label(new Rect(startX, startY+18, winWidth, winHeight), miscVText, style); startY+=65; List<int> abilityIDList=unit.abilityIDList; for(int i=0; i<abilityIDList.Count; i++){ foreach(UnitAbility uAB in unitAbilityList){ if(uAB.ID==abilityIDList[i]){ GUI.DrawTexture(new Rect(15+startX+i*35, startY, 31, 31), texBar); GUI.DrawTexture(new Rect(15+startX+i*35+2, startY+2, 27, 27), uAB.icon); GUIContent cont=new GUIContent("", uAB.ID.ToString()); GUI.Label(new Rect(15+startX+i*35, startY+3, 25, 25), cont); } } } startY+=40; if(GUI.tooltip!=""){ int ID=int.Parse(GUI.tooltip); foreach(UnitAbility uAB in unitAbilityList){ if(uAB.ID==ID){ style.alignment=TextAnchor.UpperCenter; style.wordWrap=true; GUI.Label(new Rect(startX+3, startY+3, winWidth, 50), uAB.desp.ToString()); } } } } string buttonText="Less Details"; if(infoTab==_InfoTab.General) buttonText="More Details"; bool switchFlag=GUI.Button(new Rect(startX+winWidth/2-60, Screen.height/2+winHeight/2-40, 120, 30), buttonText, UI.buttonStyle); if(switchFlag){ if(infoTab==_InfoTab.General) infoTab=_InfoTab.Stats; else infoTab=_InfoTab.General; } }
//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); }