Resolved #3663 - fixed settler automation bug

This commit is contained in:
Yair Morgenstern
2021-03-08 22:05:59 +02:00
parent 7eab616352
commit 87c9729e52
2 changed files with 35 additions and 25 deletions

View File

@ -20,8 +20,10 @@ object SpecificUnitAutomation {
fun automateWorkBoats(unit: MapUnit) {
val closestReachableResource = unit.civInfo.cities.asSequence()
.flatMap { city -> city.getWorkableTiles() }
.filter { hasWorkableSeaResource(it, unit.civInfo)
&& (unit.currentTile == it || unit.movement.canMoveTo(it)) }
.filter {
hasWorkableSeaResource(it, unit.civInfo)
&& (unit.currentTile == it || unit.movement.canMoveTo(it))
}
.sortedBy { it.aerialDistanceTo(unit.currentTile) }
.firstOrNull { unit.movement.canReach(it) }
@ -64,11 +66,12 @@ object SpecificUnitAutomation {
val enemyCities = unit.civInfo.getKnownCivs()
.filter { unit.civInfo.getDiplomacyManager(it).hasModifier(DiplomaticModifiers.StealingTerritory) }
.flatMap { it.cities }.asSequence()
// find the suitable tiles (or their neigbours)
// find the suitable tiles (or their neighbours)
val tileToSteal = enemyCities.flatMap { it.getTiles() } // City tiles
.filter { it.neighbors.any { it.getOwner() != unit.civInfo } } // Edge city tiles
.flatMap { it.neighbors.asSequence() } // Neighbors of edge city tiles
.filter { it in unit.civInfo.viewableTiles // we can see them
.filter {
it in unit.civInfo.viewableTiles // we can see them
&& it.neighbors.any { tile -> tile.getOwner() == unit.civInfo }// they are close to our borders
}
.sortedBy {
@ -78,7 +81,8 @@ object SpecificUnitAutomation {
val owner = it.getOwner()
if (owner != null)
distance - WorkerAutomation(unit).getPriority(it, owner)
else distance }
else distance
}
.firstOrNull { unit.movement.canReach(it) } // canReach is performance-heavy and always a last resort
// if there is a good tile to steal - go there
if (tileToSteal != null) {
@ -95,9 +99,11 @@ object SpecificUnitAutomation {
}
//if no unit to follow, take refuge in city or build citadel there.
val reachableTest : (TileInfo) -> Boolean = {it.civilianUnit == null &&
val reachableTest: (TileInfo) -> Boolean = {
it.civilianUnit == null &&
unit.movement.canMoveTo(it)
&& unit.movement.canReach(it)}
&& unit.movement.canReach(it)
}
val cityToGarrison = unit.civInfo.cities.asSequence().map { it.getCenterTile() }
.sortedBy { it.aerialDistanceTo(unit.currentTile) }
.firstOrNull { reachableTest(it) }
@ -105,8 +111,10 @@ object SpecificUnitAutomation {
if (cityToGarrison != null) {
// try to find a good place for citadel nearby
val potentialTilesNearCity = cityToGarrison.getTilesInDistanceRange(3..4)
val tileForCitadel = potentialTilesNearCity.firstOrNull { reachableTest(it) &&
WorkerAutomation(unit).evaluateFortPlacement(it, unit.civInfo, true) }
val tileForCitadel = potentialTilesNearCity.firstOrNull {
reachableTest(it) &&
WorkerAutomation(unit).evaluateFortPlacement(it, unit.civInfo, true)
}
if (tileForCitadel != null) {
unit.movement.headTowards(tileForCitadel)
if (unit.currentMovement > 0 && unit.currentTile == tileForCitadel)
@ -175,7 +183,10 @@ object SpecificUnitAutomation {
// It's possible that we'll see a tile "over the sea" that's better than the tiles close by, but that's not a reason to abandon the close tiles!
// Also this lead to some routing problems, see https://github.com/yairm210/Unciv/issues/3653
val bestCityLocation: TileInfo? = citiesByRanking.firstOrNull { unit.movement.getShortestPath(it.first).size < 4 }?.first
val bestCityLocation: TileInfo? = citiesByRanking.firstOrNull {
val pathSize = unit.movement.getShortestPath(it.first).size
return@firstOrNull pathSize in 1..3
}?.first
if (bestCityLocation == null) { // We got a badass over here, all tiles within 5 are taken? Screw it, random walk.
if (UnitAutomation.tryExplore(unit)) return // try to find new areas
@ -341,5 +352,4 @@ object SpecificUnitAutomation {
}
return false
}
}

View File

@ -22,7 +22,7 @@ class TileInfoTable(private val viewingCiv :CivilizationInfo) : Table(CameraStag
add(getStatsTable(tile))
add(tile.toString(viewingCiv).toLabel()).colspan(2).pad(10f)
// For debug only!
add(tile.position.toString().toLabel()).colspan(2).pad(10f)
// add(tile.position.toString().toLabel()).colspan(2).pad(10f)
}
pack()