Ranged enemy units don't move towards their targets

Cities under attack now switch to training combat units
This commit is contained in:
Yair Morgenstern 2018-04-23 18:58:19 +03:00
parent 7ff81ac901
commit fe09351db7

View File

@ -3,6 +3,7 @@ package com.unciv.logic
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.battle.Battle import com.unciv.logic.battle.Battle
import com.unciv.logic.battle.MapUnitCombatant import com.unciv.logic.battle.MapUnitCombatant
import com.unciv.logic.city.CityInfo
import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.civilization.CivilizationInfo
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
@ -14,12 +15,13 @@ import com.unciv.ui.worldscreen.unit.UnitActions
class Automation { class Automation {
private fun findTileToWork(currentTile: TileInfo, civInfo: CivilizationInfo): TileInfo { private fun findTileToWork(currentTile: TileInfo, civInfo: CivilizationInfo): TileInfo {
val selectedTile = currentTile.tileMap.getTilesInDistance(currentTile.position, 4) val selectedTile = currentTile.tileMap.getTilesInDistance(currentTile.position, 4)
.filter { (it.unit==null || it==currentTile ) .filter {
(it.unit == null || it == currentTile)
&& it.improvement == null && it.improvement == null
&& it.canBuildImprovement(chooseImprovement(it),civInfo) } && it.canBuildImprovement(chooseImprovement(it), civInfo)
}
.maxBy { getPriority(it, civInfo) } .maxBy { getPriority(it, civInfo) }
if (selectedTile != null && getPriority(selectedTile, civInfo) > 1) return selectedTile if (selectedTile != null && getPriority(selectedTile, civInfo) > 1) return selectedTile
else return currentTile else return currentTile
@ -35,22 +37,18 @@ class Automation{
} }
private fun chooseImprovement(tile: TileInfo): TileImprovement { private fun chooseImprovement(tile: TileInfo): TileImprovement {
return GameBasics.TileImprovements[chooseImprovementString(tile)]!! val improvementString = when {
tile.improvementInProgress != null -> tile.improvementInProgress
tile.terrainFeature == "Forest" -> "Lumber mill"
tile.terrainFeature == "Jungle" -> "Trading post"
tile.terrainFeature == "Marsh" -> "Remove Marsh"
tile.resource != null -> tile.tileResource.improvement
tile.baseTerrain == "Hill" -> "Mine"
tile.baseTerrain == "Grassland" || tile.baseTerrain == "Desert" || tile.baseTerrain == "Plains" -> "Farm"
tile.baseTerrain == "Tundra" -> "Trading post"
else -> null
} }
return GameBasics.TileImprovements[improvementString]!!
private fun chooseImprovementString(tile: TileInfo): String? {
when {
tile.improvementInProgress != null -> return tile.improvementInProgress
tile.terrainFeature == "Forest" -> return "Lumber mill"
tile.terrainFeature == "Jungle" -> return "Trading post"
tile.terrainFeature == "Marsh" -> return "Remove Marsh"
tile.resource != null -> return tile.tileResource.improvement
tile.baseTerrain == "Hill" -> return "Mine"
tile.baseTerrain == "Grassland" || tile.baseTerrain == "Desert" || tile.baseTerrain == "Plains" -> return "Farm"
tile.baseTerrain == "Tundra" -> return "Trading post"
else -> return null
}
} }
fun automateWorkerAction(unit: MapUnit) { fun automateWorkerAction(unit: MapUnit) {
@ -76,16 +74,29 @@ class Automation{
civInfo.tech.techsResearched.add(techToResearch!!.name) civInfo.tech.techsResearched.add(techToResearch!!.name)
} }
for (city in civInfo.cities) {
if (city.health < city.getMaxHealth()) trainCombatUnit(city)
}
for (unit in civInfo.getCivUnits()) { for (unit in civInfo.getCivUnits()) {
automateUnitMoves(unit)
}
}
private fun trainCombatUnit(city: CityInfo) {
city.cityConstructions.currentConstruction = "Archer" // when we have more units then we'll see.
}
fun automateUnitMoves(unit: MapUnit) {
if (unit.name == "Settler") { if (unit.name == "Settler") {
UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen!!).first { it.name == "Found city" }.action() UnitActions().getUnitActions(unit, UnCivGame.Current.worldScreen!!).first { it.name == "Found city" }.action()
continue return
} }
if (unit.name == "Worker") { if (unit.name == "Worker") {
Automation().automateWorkerAction(unit) Automation().automateWorkerAction(unit)
continue return
} }
@ -112,12 +123,12 @@ class Automation{
if (unit.health < 50) { if (unit.health < 50) {
healUnit() healUnit()
continue return
} // do nothing but heal } // do nothing but heal
// if there is an attackable unit in the vicinity, attack! // if there is an attackable unit in the vicinity, attack!
val attackableTiles = civInfo.getViewableTiles() val attackableTiles = unit.civInfo.getViewableTiles()
.filter { it.unit != null && it.unit!!.owner != civInfo.civName && !it.isCityCenter }.toHashSet() .filter { it.unit != null && it.unit!!.owner != unit.civInfo.civName && !it.isCityCenter }.toHashSet()
val distanceToTiles = unit.getDistanceToTiles() val distanceToTiles = unit.getDistanceToTiles()
val unitTileToAttack = distanceToTiles.keys.firstOrNull { attackableTiles.contains(it) } val unitTileToAttack = distanceToTiles.keys.firstOrNull { attackableTiles.contains(it) }
@ -127,46 +138,44 @@ class Automation{
unitToAttack.civInfo.addNotification("Our " + unitToAttack.name + " was destroyed by an enemy " + unit.name + "!", unitTileToAttack.position) unitToAttack.civInfo.addNotification("Our " + unitToAttack.name + " was destroyed by an enemy " + unit.name + "!", unitTileToAttack.position)
unitTileToAttack.unit = null unitTileToAttack.unit = null
unit.headTowards(unitTileToAttack.position) unit.headTowards(unitTileToAttack.position)
continue return
} }
val damageToAttacker = Battle(civInfo.gameInfo).calculateDamageToAttacker(MapUnitCombatant(unit), MapUnitCombatant(unitToAttack)) val damageToAttacker = Battle(unit.civInfo.gameInfo).calculateDamageToAttacker(MapUnitCombatant(unit), MapUnitCombatant(unitToAttack))
if (damageToAttacker < unit.health) { // don't attack if we'll die from the attack if (damageToAttacker < unit.health) { // don't attack if we'll die from the attack
if(unit.getBaseUnit().unitType == UnitType.Melee)
unit.headTowards(unitTileToAttack.position) unit.headTowards(unitTileToAttack.position)
Battle(civInfo.gameInfo).attack(MapUnitCombatant(unit), MapUnitCombatant(unitToAttack)) Battle(unit.civInfo.gameInfo).attack(MapUnitCombatant(unit), MapUnitCombatant(unitToAttack))
continue return
} }
} }
if (unit.health < 80) { if (unit.health < 80) {
healUnit() healUnit()
continue return
} // do nothing but heal until 80 health } // do nothing but heal until 80 health
// else, if there is a reachable spot from which we can attack this turn // else, if there is a reachable spot from which we can attack this turn
// (say we're an archer and there's a unit 3 tiles away), go there and attack // (say we're an archer and there's a unit 3 tiles away), go there and attack
// todo // todo
// else, find the closest enemy unit that we know of within 5 spaces and advance towards it // else, find the closest enemy unit that we know of within 5 spaces and advance towards it
val closestUnit = civInfo.gameInfo.tileMap.getTilesInDistance(unit.getTile().position, 5) val closestUnit = unit.civInfo.gameInfo.tileMap.getTilesInDistance(unit.getTile().position, 5)
.firstOrNull { attackableTiles.contains(it) } .firstOrNull { attackableTiles.contains(it) }
if (closestUnit != null) { if (closestUnit != null) {
unit.headTowards(closestUnit.position) unit.headTowards(closestUnit.position)
continue return
} }
if (unit.health < 100) { if (unit.health < 100) {
healUnit() healUnit()
continue return
} }
// else, go to a random space // else, go to a random space
unit.moveToTile(distanceToTiles.keys.filter { it.unit == null }.toList().getRandom()) unit.moveToTile(distanceToTiles.keys.filter { it.unit == null }.toList().getRandom())
} }
} }
}