diff --git a/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt b/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt index 2c575910a5..12fa87a87c 100644 --- a/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt +++ b/core/src/com/unciv/logic/automation/SpecificUnitAutomation.kt @@ -170,16 +170,42 @@ class SpecificUnitAutomation{ if(enemyAirUnitsInRange.isNotEmpty()) return // we need to be on standby in case they attack if(UnitAutomation().tryAttackNearbyEnemy(unit)) return - val reachableCities = tilesInRange + val immediatelyReachableCities = tilesInRange .filter { it.isCityCenter() && it.getOwner()==unit.civInfo && unit.movement.canMoveTo(it)} - for(city in reachableCities){ + for(city in immediatelyReachableCities){ if(city.getTilesInDistance(unit.getRange()) .any { UnitAutomation().containsAttackableEnemy(it,MapUnitCombatant(unit)) }) { unit.movement.moveToTile(city) return } } + + val pathsToCities = unit.movement.getArialPathsToCities() + if(pathsToCities.size==1) return // can't actually move anywhere else + + val citiesByNearbyAirUnits = pathsToCities.keys + .groupBy { it.getTilesInDistance(unit.getRange()) + .count{it.airUnits.size>0 && it.airUnits.first().civInfo.isAtWarWith(unit.civInfo)} } + + if(citiesByNearbyAirUnits.keys.any { it!=0 }){ + val citiesWithMostNeedOfAirUnits = citiesByNearbyAirUnits.maxBy { it.key }!!.value + val chosenCity = citiesWithMostNeedOfAirUnits.minBy { pathsToCities[it]!!.size }!! // city with min path = least turns to get there + val firstStepInPath = pathsToCities[chosenCity]!!.first() + unit.movement.moveToTile(firstStepInPath) + return + } + + // no city needs fighters to defend, so let's attack stuff from the closest possible location + val citiesThatCanAttackFrom = pathsToCities.keys + .filter { it.getTilesInDistance(unit.getRange()) + .any { UnitAutomation().containsAttackableEnemy(it,MapUnitCombatant(unit)) } } + if(citiesThatCanAttackFrom.isEmpty()) return + + val closestCityThatCanAttackFrom = citiesThatCanAttackFrom.minBy { pathsToCities[it]!!.size }!! + val firstStepInPath = pathsToCities[closestCityThatCanAttackFrom]!!.first() + unit.movement.moveToTile(firstStepInPath) + } } \ No newline at end of file diff --git a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt index aab5b2714c..f6078f7774 100644 --- a/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt +++ b/core/src/com/unciv/logic/map/UnitMovementAlgorithms.kt @@ -311,11 +311,12 @@ class UnitMovementAlgorithms(val unit:MapUnit) { fun getDistanceToTiles() = getDistanceToTilesWithinTurn(unit.currentTile.position,unit.currentMovement) - fun getArialMovementBfsTree(startingTile: TileInfo): HashMap { + fun getArialPathsToCities(): HashMap> { var tilesToCheck = ArrayList() /** each tile reached points to its parent tile, where we got to it from */ val tilesReached = HashMap() + val startingTile = unit.currentTile tilesToCheck.add(startingTile) tilesReached[startingTile] = startingTile @@ -333,6 +334,19 @@ class UnitMovementAlgorithms(val unit:MapUnit) { } tilesToCheck=newTilesToCheck } - return tilesReached + + val pathsToCities = HashMap>() + + for(city in tilesReached.keys){ + val path = ArrayList() + var currentCity = city + while(currentCity!=startingTile){ // we don't add the "starting tile" to the arraylist + path.add(currentCity) + currentCity = tilesReached[currentCity]!! // go to parent + } + path.reverse() + pathsToCities[city] = path + } + return pathsToCities } } \ No newline at end of file