@@ -50,7 +50,7 @@ class WorkerAutomation(
50
50
private val bestRoadAvailable: RoadStatus =
51
51
cloningSource?.bestRoadAvailable ? :
52
52
// 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
54
54
|| UncivGame .Current .settings.autoPlay.isAutoPlayingAndFullAI()))
55
55
RoadStatus .None
56
56
else civInfo.tech.getBestRoadAvailable()
@@ -163,9 +163,12 @@ class WorkerAutomation(
163
163
return
164
164
}
165
165
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
+ }
169
172
}
170
173
171
174
if (currentTile.improvementInProgress != null ) return // we're working!
@@ -180,7 +183,7 @@ class WorkerAutomation(
180
183
val citiesToNumberOfUnimprovedTiles = HashMap <String , Int >()
181
184
for (city in unit.civ.cities) {
182
185
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 )) }
184
187
}
185
188
186
189
val mostUndevelopedCity = unit.civ.cities.asSequence()
@@ -302,7 +305,7 @@ class WorkerAutomation(
302
305
303
306
// These are the expensive calculations (tileCanBeImproved, canReach), so we only apply these filters after everything else it done.
304
307
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 )) }
306
309
? : return currentTile
307
310
308
311
// Note: workableTiles is a Sequence, and we oiginally used workableTiles.contains for the second
@@ -311,7 +314,7 @@ class WorkerAutomation(
311
314
// currentTile is always the very first entry of the _unsorted_ Sequence - if it is still
312
315
// contained at all and not dropped by the filters - which is the point here.
313
316
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
315
318
|| workableTilesCenterFirst.firstOrNull() != currentTile // current tile is unworkable by city
316
319
|| getPriority(selectedTile) > getPriority(currentTile)) // current tile is less important
317
320
selectedTile
@@ -323,45 +326,62 @@ class WorkerAutomation(
323
326
* (but does not check whether the ruleset contains any unit capable of it)
324
327
*/
325
328
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 ? {
326
333
// todo This is wrong but works for Alpha Frontier, because the unit has both:
327
334
// 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
329
336
// 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
332
339
333
340
val city = tile.getCity()
334
341
if (city == null || city.civ != civInfo)
335
- return false
342
+ return null
336
343
337
344
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
341
349
342
350
// If the tile is a junk improvement or a fort placed in a bad location.
343
351
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()))
346
354
347
355
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
351
360
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)
357
370
&& ! 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
361
371
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
363
382
}
364
383
384
+
365
385
/* *
366
386
* Calculate a priority for improving a tile
367
387
*/
@@ -384,6 +404,8 @@ class WorkerAutomation(
384
404
* Determine the improvement appropriate to a given tile and worker
385
405
*/
386
406
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!! ]
387
409
388
410
val potentialTileImprovements = ruleSet.tileImprovements.filter {
389
411
unit.canBuildImprovement(it.value, tile)
@@ -421,7 +443,6 @@ class WorkerAutomation(
421
443
422
444
// After gathering all the data, we conduct the hierarchy in one place
423
445
val improvementString = when {
424
- tile.improvementInProgress != null -> tile.improvementInProgress!!
425
446
improvementStringForResource != null -> if (improvementStringForResource== tile.improvement) null else improvementStringForResource
426
447
// if this is a resource that HAS an improvement, but this unit can't build it, don't waste your time
427
448
tile.resource != null && tile.tileResource.getImprovements().any() -> return null
0 commit comments