@@ -50,7 +50,7 @@ class WorkerAutomation(
5050 private val bestRoadAvailable: RoadStatus =
5151 cloningSource?.bestRoadAvailable ? :
5252 // Player can choose not to auto-build roads & railroads.
53- if (civInfo.isHuman() && (! UncivGame .Current .settings.autoBuildingRoads
53+ if (civInfo.isHuman() && (! UncivGame .Current .settings.autoBuildingRoads
5454 || UncivGame .Current .settings.autoPlay.isAutoPlayingAndFullAI()))
5555 RoadStatus .None
5656 else civInfo.tech.getBestRoadAvailable()
@@ -163,9 +163,12 @@ class WorkerAutomation(
163163 return
164164 }
165165
166- if (currentTile.improvementInProgress == null && tileCanBeImproved(unit, currentTile)) {
167- debug(" WorkerAutomation: ${unit.label()} -> start improving $currentTile " )
168- return currentTile.startWorkingOnImprovement(chooseImprovement(unit, currentTile)!! , civInfo, unit)
166+ if (currentTile.improvementInProgress == null ) {
167+ val newImprovement = getImprovementToImprove(unit, currentTile)
168+ if (newImprovement != null ) {
169+ debug(" WorkerAutomation: ${unit.label()} -> start improving $currentTile " )
170+ return currentTile.startWorkingOnImprovement(newImprovement, civInfo, unit)
171+ }
169172 }
170173
171174 if (currentTile.improvementInProgress != null ) return // we're working!
@@ -180,7 +183,7 @@ class WorkerAutomation(
180183 val citiesToNumberOfUnimprovedTiles = HashMap <String , Int >()
181184 for (city in unit.civ.cities) {
182185 citiesToNumberOfUnimprovedTiles[city.id] = city.getTiles()
183- .count { it.isLand && it.civilianUnit == null && (tileCanBeImproved(unit, it ) || it.isPillaged( )) }
186+ .count { it.isLand && it.civilianUnit == null && (it.isPillaged( ) || tileCanBeImproved(unit, it )) }
184187 }
185188
186189 val mostUndevelopedCity = unit.civ.cities.asSequence()
@@ -302,7 +305,7 @@ class WorkerAutomation(
302305
303306 // These are the expensive calculations (tileCanBeImproved, canReach), so we only apply these filters after everything else it done.
304307 val selectedTile = workableTilesPrioritized
305- .firstOrNull { unit.movement.canReach(it) && (tileCanBeImproved(unit, it ) || it.isPillaged( )) }
308+ .firstOrNull { unit.movement.canReach(it) && (it.isPillaged( ) || tileCanBeImproved(unit, it )) }
306309 ? : return currentTile
307310
308311 // Note: workableTiles is a Sequence, and we oiginally used workableTiles.contains for the second
@@ -311,7 +314,7 @@ class WorkerAutomation(
311314 // currentTile is always the very first entry of the _unsorted_ Sequence - if it is still
312315 // contained at all and not dropped by the filters - which is the point here.
313316 return if ( currentTile == selectedTile // No choice
314- || (! tileCanBeImproved(unit, currentTile) && ! currentTile.isPillaged( )) // current tile is unimprovable
317+ || (! currentTile.isPillaged( ) && ! tileCanBeImproved(unit, currentTile )) // current tile is unimprovable
315318 || workableTilesCenterFirst.firstOrNull() != currentTile // current tile is unworkable by city
316319 || getPriority(selectedTile) > getPriority(currentTile)) // current tile is less important
317320 selectedTile
@@ -323,45 +326,62 @@ class WorkerAutomation(
323326 * (but does not check whether the ruleset contains any unit capable of it)
324327 */
325328 private fun tileCanBeImproved (unit : MapUnit , tile : Tile ): Boolean {
329+ return getImprovementToImprove(unit, tile) != null
330+ }
331+
332+ private fun getImprovementToImprove (unit : MapUnit , tile : Tile ): TileImprovement ? {
326333 // todo This is wrong but works for Alpha Frontier, because the unit has both:
327334 // It should test for the build over time ability, but this tests the create and die ability
328- if (! tile.isLand && ! unit.cache.hasUniqueToCreateWaterImprovements) return false
335+ if (! tile.isLand && ! unit.cache.hasUniqueToCreateWaterImprovements) return null
329336 // Allow outlandish mods having non-road improvements on Mountains
330- if (tile.isImpassible() && ! unit.cache.canPassThroughImpassableTiles) return false
331- if (tile.isCityCenter()) return false
337+ if (tile.isImpassible() && ! unit.cache.canPassThroughImpassableTiles) return null
338+ if (tile.isCityCenter()) return null
332339
333340 val city = tile.getCity()
334341 if (city == null || city.civ != civInfo)
335- return false
342+ return null
336343
337344 if (! city.tilesInRange.contains(tile)
338- && ! tile.hasViewableResource(civInfo)
339- && civInfo.cities.none { it.getCenterTile().aerialDistanceTo(tile) <= 3 })
340- return false // unworkable tile
345+ && ! tile.hasViewableResource(civInfo)
346+ && civInfo.cities.none { it.getCenterTile().aerialDistanceTo(tile) <= 3 }
347+ )
348+ return null // unworkable tile
341349
342350 // If the tile is a junk improvement or a fort placed in a bad location.
343351 val junkImprovement = tile.getTileImprovement()?.hasUnique(UniqueType .AutomatedWorkersWillReplace ) == true
344- || (tile.improvement == Constants .fort && ! evaluateFortSuroundings(tile, false )
345- && (! civInfo.isHuman() || UncivGame .Current .settings.autoPlay.isAutoPlayingAndFullAI()))
352+ || (tile.improvement == Constants .fort && ! evaluateFortSuroundings(tile, false )
353+ && (! civInfo.isHuman() || UncivGame .Current .settings.autoPlay.isAutoPlayingAndFullAI()))
346354
347355 if (tile.improvement != null && ! junkImprovement
348- && ! UncivGame .Current .settings.automatedWorkersReplaceImprovements
349- && unit.civ.isHuman() && ! UncivGame .Current .settings.autoPlay.isAutoPlayingAndFullAI())
350- return false
356+ && ! UncivGame .Current .settings.automatedWorkersReplaceImprovements
357+ && unit.civ.isHuman() && ! UncivGame .Current .settings.autoPlay.isAutoPlayingAndFullAI()
358+ )
359+ return null
351360
352- if (tile.improvement == null || junkImprovement) {
353- if (tile.improvementInProgress != null && unit.canBuildImprovement(tile.getTileImprovementInProgress()!! , tile)) return true
354- val chosenImprovement = chooseImprovement(unit, tile)
355- if (chosenImprovement != null && tile.improvementFunctions.canBuildImprovement(chosenImprovement, civInfo) && unit.canBuildImprovement(chosenImprovement, tile)) return true
356- } else if (! tile.containsGreatImprovement() && tile.hasViewableResource(civInfo)
361+ val anyImprovementIsOk = tile.improvement == null || junkImprovement
362+
363+ if (anyImprovementIsOk
364+ && tile.improvementInProgress != null
365+ && unit.canBuildImprovement(tile.getTileImprovementInProgress()!! , tile))
366+ return tile.getTileImprovementInProgress()!!
367+
368+ val isResourceTileWithoutResourceProvider = ! tile.containsGreatImprovement()
369+ && tile.hasViewableResource(civInfo)
357370 && ! tile.tileResource.isImprovedBy(tile.improvement!! )
358- && (chooseImprovement(unit, tile) // if the chosen improvement is not null and buildable
359- .let { it != null && tile.improvementFunctions.canBuildImprovement(it, civInfo) && unit.canBuildImprovement(it, tile)}))
360- return true
361371
362- return false // couldn't find anything to construct here
372+ if (anyImprovementIsOk || isResourceTileWithoutResourceProvider) {
373+ val chosenImprovement = chooseImprovement(unit, tile)
374+ if (chosenImprovement != null
375+ && tile.improvementFunctions.canBuildImprovement(chosenImprovement, civInfo)
376+ && unit.canBuildImprovement(chosenImprovement, tile)
377+ )
378+ return chosenImprovement
379+ }
380+
381+ return null // couldn't find anything to construct here
363382 }
364383
384+
365385 /* *
366386 * Calculate a priority for improving a tile
367387 */
@@ -384,6 +404,8 @@ class WorkerAutomation(
384404 * Determine the improvement appropriate to a given tile and worker
385405 */
386406 private fun chooseImprovement (unit : MapUnit , tile : Tile ): TileImprovement ? {
407+ // You can keep working on half-built improvements, even if they're unique to another civ
408+ if (tile.improvementInProgress != null ) return ruleSet.tileImprovements[tile.improvementInProgress!! ]
387409
388410 val potentialTileImprovements = ruleSet.tileImprovements.filter {
389411 unit.canBuildImprovement(it.value, tile)
@@ -421,7 +443,6 @@ class WorkerAutomation(
421443
422444 // After gathering all the data, we conduct the hierarchy in one place
423445 val improvementString = when {
424- tile.improvementInProgress != null -> tile.improvementInProgress!!
425446 improvementStringForResource != null -> if (improvementStringForResource== tile.improvement) null else improvementStringForResource
426447 // if this is a resource that HAS an improvement, but this unit can't build it, don't waste your time
427448 tile.resource != null && tile.tileResource.getImprovements().any() -> return null
0 commit comments