diff --git a/android/build.gradle b/android/build.gradle index 370b686559..e8865ca573 100644 --- a/android/build.gradle +++ b/android/build.gradle @@ -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 diff --git a/core/src/com/unciv/logic/automation/UnitAutomation.kt b/core/src/com/unciv/logic/automation/UnitAutomation.kt index 6468bdea97..4ef2301e7f 100644 --- a/core/src/com/unciv/logic/automation/UnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/UnitAutomation.kt @@ -110,12 +110,21 @@ class UnitAutomation{ fun tryHealUnit(unit: MapUnit, unitDistanceToTiles: HashMap):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]!! }!!) diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index 74a3bf843f..6dc1cf90a9 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -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