Embarked units at sea which need to heal now go find land to heal on, and don't stay stuck in the same place

This commit is contained in:
Yair Morgenstern 2019-07-08 19:29:12 +03:00
parent 9559894a86
commit 9ad7b976d5
3 changed files with 29 additions and 5 deletions

View file

@ -21,8 +21,8 @@ android {
applicationId "com.unciv.app"
minSdkVersion 14
targetSdkVersion 28
versionCode 269
versionName "2.17.14"
versionCode 270
versionName "2.17.15"
}
// Had to add this crap for Travis to build, it wanted to sign the app

View file

@ -110,12 +110,21 @@ class UnitAutomation{
fun tryHealUnit(unit: MapUnit, unitDistanceToTiles: HashMap<TileInfo, Float>):Boolean {
val tilesInDistance = unitDistanceToTiles.keys.filter { unit.canMoveTo(it) }
if(unitDistanceToTiles.isEmpty()) return true // can't move, so...
val unitTile = unit.getTile()
if (tryPillageImprovement(unit, unitDistanceToTiles)) return true
val tilesByHealingRate = tilesInDistance.groupBy { unit.rankTileForHealing(it) }
if(tilesByHealingRate.isEmpty()) return false
if(tilesByHealingRate.keys.none { it!=0 }){// We can't heal here at all! We're probably embarked
val reachableCityTile = unit.civInfo.cities.map { it.getCenterTile() }
.sortedBy { it.arialDistanceTo(unit.currentTile) }
.firstOrNull{unit.movementAlgs().canReach(it)}
if(reachableCityTile!=null) unit.movementAlgs().headTowards(reachableCityTile)
else wander(unit,unitDistanceToTiles)
return true
}
val bestTilesForHealing = tilesByHealingRate.maxBy { it.key }!!.value
// within the tiles with best healing rate, we'll prefer one which has defensive bonuses
@ -276,13 +285,27 @@ class UnitAutomation{
val reachableTilesNotInBombardRange = unitDistanceToTiles.keys.filter { it !in tilesInBombardRange }
val canMoveIntoBombardRange = tilesInBombardRange.any { unitDistanceToTiles.containsKey(it)}
if(!canMoveIntoBombardRange) // no need to worry, keep going as the movement alg. says
unit.movementAlgs().headTowards(closestReachableEnemyCity)
val suitableGatheringGroundTiles = closestReachableEnemyCity.getTilesAtDistance(4)
.union(closestReachableEnemyCity.getTilesAtDistance(3))
.filter { it.isLand }
val closestReachableLandingGroundTile = suitableGatheringGroundTiles
.sortedBy { it.arialDistanceTo(unit.currentTile) }
.firstOrNull { unit.movementAlgs().canReach(it) }
// don't head straight to the city, try to head to landing grounds -
// this is against tha AI's brilliant plan of having everyone embarked and attacking via sea when unnecessary.
val tileToHeadTo = if(closestReachableLandingGroundTile!=null) closestReachableLandingGroundTile
else closestReachableEnemyCity
if(tileToHeadTo !in tilesInBombardRange) // no need to worry, keep going as the movement alg. says
unit.movementAlgs().headTowards(tileToHeadTo)
else{
if(unit.getRange()>2){ // should never be in a bombardable position
val tilesCanAttackFromButNotInBombardRange =
reachableTilesNotInBombardRange.filter{it.arialDistanceTo(closestReachableEnemyCity) <= unit.getRange()}
// move into position far away enough that the bombard doesn't hurt
if(tilesCanAttackFromButNotInBombardRange.any())
unit.movementAlgs().headTowards(tilesCanAttackFromButNotInBombardRange.minBy { unitDistanceToTiles[it]!! }!!)

View file

@ -407,6 +407,7 @@ class MapUnit {
fun rankTileForHealing(tileInfo:TileInfo): Int {
return when{
tileInfo.isWater && type.isLandUnit() -> 0 // Can't heal in water!
tileInfo.getOwner() == null -> 10 // no man's land (neutral)
tileInfo.isCityCenter() -> 20
!civInfo.isAtWarWith(tileInfo.getOwner()!!) -> 15 // home or allied territory