mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-27 22:06:05 -04:00
Removed ALL hardcoded decisions in worker AI - we're now fully moddable! (#6003)
I tested this out with RekMOD, 150 simulated turns, to see if this was working. Not only did I discover that workers were squatting on Antiquity Sites since they had resource improvements that they couldn't build, I also discovered something much worse. Even after fixing that, most cities were woefully underimproved. Turns out, the construction automation would limit worker construction to a measly *3 workers* even for a *10 city* civ! After removing this limitation and making civs aim for a 1:1 ratio between cities and workers, everything started looking much, much better. I'm not sure what the exact effect on the AI will be but I'm _sure_ that this leads to a major improvement. More improved tiles means more stats means more everything.
This commit is contained in:
parent
feb9b19d11
commit
080fc245d8
@ -168,12 +168,9 @@ class ConstructionAutomation(val cityConstructions: CityConstructions){
|
||||
&& it.isBuildable(cityConstructions)
|
||||
&& Automation.allowSpendingResource(civInfo, it) }
|
||||
if (workerEquivalents.isEmpty()) return // for mods with no worker units
|
||||
if (civInfo.getIdleUnits().any { it.isAutomated() && it.hasUniqueToBuildImprovements })
|
||||
return // If we have automated workers who have no work to do then it's silly to construct new workers.
|
||||
|
||||
val citiesCountedTowardsWorkers = min(5, cities) // above 5 cities, extra cities won't make us want more workers
|
||||
if (workers < citiesCountedTowardsWorkers * 0.6f && civUnits.none { it.hasUniqueToBuildImprovements && it.isIdle() }) {
|
||||
var modifier = citiesCountedTowardsWorkers / (workers + 0.1f)
|
||||
if (workers < cities) {
|
||||
var modifier = cities / (workers + 0.1f) // The worse our worker to city ratio is, the more desperate we are
|
||||
if (!cityIsOverAverageProduction) modifier /= 5 // higher production cities will deal with this
|
||||
addChoice(relativeCostEffectiveness, workerEquivalents.minByOrNull { it.cost }!!.name, modifier)
|
||||
}
|
||||
|
@ -333,15 +333,21 @@ class WorkerAutomation(
|
||||
private fun chooseImprovement(unit: MapUnit, tile: TileInfo): TileImprovement? {
|
||||
|
||||
// turnsToBuild is what defines them as buildable
|
||||
val tileImprovements = ruleSet.tileImprovements.filter {
|
||||
it.value.turnsToBuild != 0 && tile.canImprovementBeBuiltHere(it.value, tile.hasViewableResource(civInfo)) }
|
||||
val uniqueImprovement = tileImprovements.values
|
||||
.firstOrNull { it.uniqueTo == civInfo.civName }
|
||||
val potentialTileImprovements = ruleSet.tileImprovements.filter {
|
||||
unit.canBuildImprovement(it.value, tile)
|
||||
&& tile.canImprovementBeBuiltHere(it.value, tile.hasViewableResource(civInfo))
|
||||
&& (it.value.uniqueTo == null || it.value.uniqueTo == unit.civInfo.civName)
|
||||
}
|
||||
if (potentialTileImprovements.isEmpty()) return null
|
||||
|
||||
val currentlyBuildableImprovements = tileImprovements.values.filter { tile.canBuildImprovement(it, civInfo) }
|
||||
val bestBuildableImprovement = currentlyBuildableImprovements.map { Pair(it, Automation.rankStatsValue(it, civInfo)) }
|
||||
.filter { it.second > 0f }
|
||||
.maxByOrNull { it.second }?.first
|
||||
val uniqueImprovement = potentialTileImprovements.values.asSequence()
|
||||
.filter { it.uniqueTo == civInfo.civName }
|
||||
.maxByOrNull { Automation.rankStatsValue(it, unit.civInfo) }
|
||||
|
||||
val bestBuildableImprovement = potentialTileImprovements.values.asSequence()
|
||||
.map { Pair(it, Automation.rankStatsValue(it, civInfo)) }
|
||||
.filter { it.second > 0f }
|
||||
.maxByOrNull { it.second }?.first
|
||||
|
||||
val lastTerrain = tile.getLastTerrain()
|
||||
|
||||
@ -358,7 +364,12 @@ class WorkerAutomation(
|
||||
|
||||
val improvementString = when {
|
||||
tile.improvementInProgress != null -> tile.improvementInProgress!!
|
||||
improvementStringForResource != null && tileImprovements.containsKey(improvementStringForResource) -> improvementStringForResource
|
||||
improvementStringForResource != null -> {
|
||||
if (potentialTileImprovements.containsKey(improvementStringForResource))
|
||||
improvementStringForResource
|
||||
// if this is a resource that HAS an improvement, but this unit can't build it, don't waste your time
|
||||
else return null
|
||||
}
|
||||
tile.containsGreatImprovement() -> return null
|
||||
tile.containsUnfinishedGreatImprovement() -> return null
|
||||
|
||||
@ -367,20 +378,12 @@ class WorkerAutomation(
|
||||
!civInfo.isPlayerCivilization() && evaluateFortPlacement(tile, civInfo,false) -> Constants.fort
|
||||
// I think we can assume that the unique improvement is better
|
||||
uniqueImprovement != null && tile.canBuildImprovement(uniqueImprovement, civInfo)
|
||||
&& unit.canBuildImprovement(uniqueImprovement, tile) ->
|
||||
uniqueImprovement.name
|
||||
-> uniqueImprovement.name
|
||||
|
||||
lastTerrain.let {
|
||||
isUnbuildableAndRemovable(it) &&
|
||||
(Automation.rankStatsValue(it, civInfo) < 0 || it.hasUnique(UniqueType.NullifyYields) )
|
||||
} -> Constants.remove + lastTerrain.name
|
||||
tile.terrainFeatures.contains(Constants.jungle) -> Constants.tradingPost
|
||||
tile.terrainFeatures.contains("Oasis") -> return null
|
||||
tile.terrainFeatures.contains(Constants.forest) && tileImprovements.containsKey("Lumber mill") -> "Lumber mill"
|
||||
tile.isHill() && tileImprovements.containsKey("Mine") -> "Mine"
|
||||
tile.baseTerrain in listOf(Constants.grassland, Constants.desert, Constants.plains)
|
||||
&& tileImprovements.containsKey("Farm") -> "Farm"
|
||||
tile.isAdjacentToFreshwater && tileImprovements.containsKey("Farm") -> "Farm"
|
||||
|
||||
bestBuildableImprovement != null -> bestBuildableImprovement.name
|
||||
else -> return null
|
||||
|
@ -1115,8 +1115,9 @@ class MapUnit {
|
||||
&& improvement.name != Constants.cancelImprovementOrder
|
||||
&& tile.improvementInProgress != improvement.name
|
||||
) return false
|
||||
val matchingUniques = getMatchingUniques(UniqueType.BuildImprovements)
|
||||
return matchingUniques.any { improvement.matchesFilter(it.params[0]) || tile.matchesTerrainFilter(it.params[0]) }
|
||||
|
||||
return getMatchingUniques(UniqueType.BuildImprovements)
|
||||
.any { improvement.matchesFilter(it.params[0]) || tile.matchesTerrainFilter(it.params[0]) }
|
||||
}
|
||||
|
||||
fun getReligionDisplayName(): String? {
|
||||
|
Loading…
x
Reference in New Issue
Block a user