perf: Send current tile stats when choosing improvement, ~6% CPU reduction

This commit is contained in:
yairm210 2024-07-03 23:19:21 +03:00
parent 740f7bdb93
commit 45ec525a47
4 changed files with 21 additions and 10 deletions

View File

@ -17,6 +17,7 @@ import com.unciv.models.ruleset.tile.Terrain
import com.unciv.models.ruleset.tile.TileImprovement import com.unciv.models.ruleset.tile.TileImprovement
import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.models.ruleset.unique.LocalUniqueCache
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stats
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActions import com.unciv.ui.screens.worldscreen.unit.actions.UnitActions
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsFromUniques import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsFromUniques
import com.unciv.utils.debug import com.unciv.utils.debug
@ -141,7 +142,7 @@ class WorkerAutomation(
for (city in unit.civ.cities) { for (city in unit.civ.cities) {
citiesToNumberOfUnimprovedTiles[city.id] = city.getTiles() citiesToNumberOfUnimprovedTiles[city.id] = city.getTiles()
.count { tile -> tile.isLand .count { tile -> tile.isLand
&& tile.getUnits().any { unit -> unit.cache.hasUniqueToBuildImprovements } && tile.getUnits().none { unit -> unit.cache.hasUniqueToBuildImprovements }
&& (tile.isPillaged() || tileHasWorkToDo(tile, unit, localUniqueCache)) } && (tile.isPillaged() || tileHasWorkToDo(tile, unit, localUniqueCache)) }
} }
@ -318,14 +319,15 @@ class WorkerAutomation(
if (tile.improvementInProgress != null) return ruleSet.tileImprovements[tile.improvementInProgress!!] if (tile.improvementInProgress != null) return ruleSet.tileImprovements[tile.improvementInProgress!!]
val potentialTileImprovements = ruleSet.tileImprovements.filter { val potentialTileImprovements = ruleSet.tileImprovements.filter {
unit.canBuildImprovement(it.value, tile) (it.value.uniqueTo == null || it.value.uniqueTo == unit.civ.civName)
&& unit.canBuildImprovement(it.value, tile)
&& tile.improvementFunctions.canBuildImprovement(it.value, civInfo) && tile.improvementFunctions.canBuildImprovement(it.value, civInfo)
&& (it.value.uniqueTo == null || it.value.uniqueTo == unit.civ.civName)
} }
if (potentialTileImprovements.isEmpty()) return null if (potentialTileImprovements.isEmpty()) return null
val currentTileStats = tile.stats.getTileStats(tile.getCity(), civInfo, localUniqueCache)
var bestBuildableImprovement = potentialTileImprovements.values.asSequence() var bestBuildableImprovement = potentialTileImprovements.values.asSequence()
.map { Pair(it, getImprovementRanking(tile, unit, it.name, localUniqueCache)) } .map { Pair(it, getImprovementRanking(tile, unit, it.name, localUniqueCache, currentTileStats)) }
.filter { it.second > 0f } .filter { it.second > 0f }
.maxByOrNull { it.second }?.first .maxByOrNull { it.second }?.first
@ -374,7 +376,8 @@ class WorkerAutomation(
} }
private fun getImprovementRanking(tile: Tile, unit: MapUnit, improvementName: String, private fun getImprovementRanking(tile: Tile, unit: MapUnit, improvementName: String,
localUniqueCache: LocalUniqueCache): Float { localUniqueCache: LocalUniqueCache,
/** Provide for performance */ currentTileStats: Stats? = null): Float {
val improvement = ruleSet.tileImprovements[improvementName]!! val improvement = ruleSet.tileImprovements[improvementName]!!
// Add the value of roads if we want to build it here // Add the value of roads if we want to build it here
@ -396,7 +399,7 @@ class WorkerAutomation(
&& tile.aerialDistanceTo(it.owningCity!!.getCenterTile()) <= civInfo.modConstants.cityWorkRange } )) && tile.aerialDistanceTo(it.owningCity!!.getCenterTile()) <= civInfo.modConstants.cityWorkRange } ))
return 0f return 0f
val stats = tile.stats.getStatDiffForImprovement(improvement, civInfo, tile.getCity(), localUniqueCache) val stats = tile.stats.getStatDiffForImprovement(improvement, civInfo, tile.getCity(), localUniqueCache, currentTileStats)
if (improvementName.startsWith(Constants.remove)) { if (improvementName.startsWith(Constants.remove)) {
// We need to look beyond what we are doing right now and at the final improvement that will be on this tile // We need to look beyond what we are doing right now and at the final improvement that will be on this tile

View File

@ -433,7 +433,11 @@ class Civilization : IsPartOfGameInfoSerialization {
stats.happiness < it != previousHappiness < it // If move from being below them to not, or vice versa stats.happiness < it != previousHappiness < it // If move from being below them to not, or vice versa
}) })
for (city in cities) city.cityStats.update(updateCivStats = false) for (city in cities) city.cityStats.update(updateCivStats = false)
stats.statsForNextTurn = stats.getStatMapForNextTurn().values.reduce { a, b -> a + b } val statMapForNextTurn = stats.getStatMapForNextTurn()
val newStats = Stats()
for (stats in statMapForNextTurn.values) newStats.add(stats)
stats.statsForNextTurn = newStats
} }
fun getHappiness() = stats.happiness fun getHappiness() = stats.happiness

View File

@ -141,7 +141,8 @@ class CivInfoStatsForNextTurn(val civInfo: Civilization) {
} }
fun getUnitSupplyFromCities(): Int { fun getUnitSupplyFromCities(): Int {
return civInfo.cities.size * return civInfo.cities.size *
(civInfo.getDifficulty().unitSupplyPerCity + civInfo.getMatchingUniques(UniqueType.UnitSupplyPerCity).sumOf { it.params[0].toInt() }) (civInfo.getDifficulty().unitSupplyPerCity
+ civInfo.getMatchingUniques(UniqueType.UnitSupplyPerCity).sumOf { it.params[0].toInt() })
} }
fun getUnitSupplyFromPop(): Int { fun getUnitSupplyFromPop(): Int {
var totalSupply = civInfo.cities.sumOf { it.population.population } * civInfo.gameInfo.ruleset.modOptions.constants.unitSupplyPerPopulation var totalSupply = civInfo.cities.sumOf { it.population.population } * civInfo.gameInfo.ruleset.modOptions.constants.unitSupplyPerPopulation

View File

@ -266,9 +266,12 @@ class TileStatFunctions(val tile: Tile) {
improvement: TileImprovement, improvement: TileImprovement,
observingCiv: Civilization, observingCiv: Civilization,
city: City?, city: City?,
cityUniqueCache: LocalUniqueCache = LocalUniqueCache(false)): Stats { cityUniqueCache: LocalUniqueCache = LocalUniqueCache(false),
/** Provide this for performance */
currentTileStats: Stats? = null): Stats {
val currentStats = getTileStats(city, observingCiv, cityUniqueCache) val currentStats = currentTileStats
?: getTileStats(city, observingCiv, cityUniqueCache)
val tileClone = tile.clone() val tileClone = tile.clone()
tileClone.setTerrainTransients() tileClone.setTerrainTransients()