diff --git a/core/src/com/unciv/logic/automation/Automation.kt b/core/src/com/unciv/logic/automation/Automation.kt index fce19bc48a..d84f818a70 100644 --- a/core/src/com/unciv/logic/automation/Automation.kt +++ b/core/src/com/unciv/logic/automation/Automation.kt @@ -46,13 +46,11 @@ object Automation { if (specialist) { // If you have the Food Bonus, count as 1 extra food production (base is 2food) - for (unique in localUniqueCache.get(UniqueType.FoodConsumptionBySpecialists.name, - city.getMatchingUniques(UniqueType.FoodConsumptionBySpecialists))) + for (unique in localUniqueCache.forCityGetMatchingUniques(city, UniqueType.FoodConsumptionBySpecialists)) if (city.matchesFilter(unique.params[1])) yieldStats.food -= (unique.params[0].toFloat() / 100f) * 2f // base 2 food per Pop // Specialist Happiness Percentage Change 0f-1f - for (unique in localUniqueCache.get(UniqueType.UnhappinessFromPopulationTypePercentageChange.name, - city.getMatchingUniques(UniqueType.UnhappinessFromPopulationTypePercentageChange))) + for (unique in localUniqueCache.forCityGetMatchingUniques(city, UniqueType.UnhappinessFromPopulationTypePercentageChange)) if (city.matchesFilter(unique.params[2]) && unique.params[1] == "Specialists") yieldStats.happiness -= (unique.params[0].toFloat() / 100f) // relative val is negative, make positive if (city.civ.getHappiness() < 0) yieldStats.happiness *= 2 // double weight for unhappy civilization diff --git a/core/src/com/unciv/logic/city/CityStats.kt b/core/src/com/unciv/logic/city/CityStats.kt index 89d4085b7e..fa1599f6f5 100644 --- a/core/src/com/unciv/logic/city/CityStats.kt +++ b/core/src/com/unciv/logic/city/CityStats.kt @@ -182,10 +182,10 @@ class CityStats(val city: City) { val specialist = city.getRuleset().specialists[specialistName] ?: return Stats() val stats = specialist.cloneStats() - for (unique in localUniqueCache.get(UniqueType.StatsFromSpecialist.name, city.getMatchingUniques(UniqueType.StatsFromSpecialist))) + for (unique in localUniqueCache.forCityGetMatchingUniques(city, UniqueType.StatsFromSpecialist)) if (city.matchesFilter(unique.params[1])) stats.add(unique.stats) - for (unique in localUniqueCache.get(UniqueType.StatsFromObject.name, city.civ.getMatchingUniques(UniqueType.StatsFromObject))) + for (unique in localUniqueCache.forCityGetMatchingUniques(city, UniqueType.StatsFromObject)) if (unique.params[1] == specialistName) stats.add(unique.stats) return stats diff --git a/core/src/com/unciv/logic/map/tile/TileStatFunctions.kt b/core/src/com/unciv/logic/map/tile/TileStatFunctions.kt index e3c2432b64..0c4108af77 100644 --- a/core/src/com/unciv/logic/map/tile/TileStatFunctions.kt +++ b/core/src/com/unciv/logic/map/tile/TileStatFunctions.kt @@ -13,7 +13,10 @@ import com.unciv.ui.components.extensions.toPercent class TileStatFunctions(val tile: Tile) { - fun getTileStats(observingCiv: Civilization?): Stats = getTileStats(tile.getCity(), observingCiv) + fun getTileStats( + observingCiv: Civilization?, + localUniqueCache: LocalUniqueCache = LocalUniqueCache(false) + ): Stats = getTileStats(tile.getCity(), observingCiv, localUniqueCache) fun getTileStats(city: City?, observingCiv: Civilization?, localUniqueCache: LocalUniqueCache = LocalUniqueCache(false) @@ -24,19 +27,21 @@ class TileStatFunctions(val tile: Tile) { val stateForConditionals = StateForConditionals(civInfo = observingCiv, city = city, tile = tile) if (city != null) { - var tileUniques = city.getMatchingUniques(UniqueType.StatsFromTiles, StateForConditionals.IgnoreConditionals) - .filter { city.matchesFilter(it.params[2]) } - tileUniques += city.getMatchingUniques(UniqueType.StatsFromObject, StateForConditionals.IgnoreConditionals) - for (unique in localUniqueCache.get("StatsFromTilesAndObjects", tileUniques)) { + var tileUniques = + localUniqueCache.forCityGetMatchingUniques( + city, UniqueType.StatsFromTiles, StateForConditionals.IgnoreConditionals) + .filter { city.matchesFilter(it.params[2]) } + tileUniques += localUniqueCache.forCityGetMatchingUniques( + city, UniqueType.StatsFromObject, StateForConditionals.IgnoreConditionals) + for (unique in tileUniques) { if (!unique.conditionalsApply(stateForConditionals)) continue val tileType = unique.params[1] if (!tile.matchesTerrainFilter(tileType, observingCiv)) continue stats.add(unique.stats) } - for (unique in localUniqueCache.get("StatsFromTilesWithout", - city.getMatchingUniques(UniqueType.StatsFromTilesWithout, StateForConditionals.IgnoreConditionals)) - ) { + for (unique in localUniqueCache.forCityGetMatchingUniques( + city, UniqueType.StatsFromTilesWithout, StateForConditionals.IgnoreConditionals)) { if ( unique.conditionalsApply(stateForConditionals) && tile.matchesTerrainFilter(unique.params[1]) && @@ -109,19 +114,19 @@ class TileStatFunctions(val tile: Tile) { if (city != null) { // Since the tile changes every time, we cache all uniques, and filter by conditional state only when iterating - val cachedStatPercentFromObjectUniques = uniqueCache.get(UniqueType.StatPercentFromObject.name, - city.getMatchingUniques(UniqueType.StatPercentFromObject, StateForConditionals.IgnoreConditionals)) + val cachedStatPercentFromObjectCityUniques = uniqueCache.forCityGetMatchingUniques( + city, UniqueType.StatPercentFromObject, StateForConditionals.IgnoreConditionals) - for (unique in cachedStatPercentFromObjectUniques) { + for (unique in cachedStatPercentFromObjectCityUniques) { if (!unique.conditionalsApply(stateForConditionals)) continue val tileFilter = unique.params[2] if (tile.matchesTerrainFilter(tileFilter, observingCiv)) stats[Stat.valueOf(unique.params[1])] += unique.params[0].toFloat() } - val cachedAllStatPercentFromObjectUniques = uniqueCache.get(UniqueType.AllStatsPercentFromObject.name, - city.getMatchingUniques(UniqueType.AllStatsPercentFromObject, StateForConditionals.IgnoreConditionals)) - for (unique in cachedAllStatPercentFromObjectUniques) { + val cachedAllStatPercentFromObjectCityUniques = uniqueCache.forCityGetMatchingUniques( + city, UniqueType.AllStatsPercentFromObject, StateForConditionals.IgnoreConditionals) + for (unique in cachedAllStatPercentFromObjectCityUniques) { if (!unique.conditionalsApply(stateForConditionals)) continue val tileFilter = unique.params[1] if (!tile.matchesTerrainFilter(tileFilter, observingCiv)) continue @@ -131,13 +136,17 @@ class TileStatFunctions(val tile: Tile) { } } else if (observingCiv != null) { - for (unique in observingCiv.getMatchingUniques(UniqueType.StatPercentFromObject, stateForConditionals)) { + val cachedStatPercentFromObjectCivUniques = uniqueCache.forCivGetMatchingUniques( + observingCiv, UniqueType.StatPercentFromObject, stateForConditionals) + for (unique in cachedStatPercentFromObjectCivUniques) { val tileFilter = unique.params[2] if (tile.matchesTerrainFilter(tileFilter, observingCiv)) stats[Stat.valueOf(unique.params[1])] += unique.params[0].toFloat() } - for (unique in observingCiv.getMatchingUniques(UniqueType.AllStatsPercentFromObject, stateForConditionals)) { + val cachedAllStatPercentFromObjectCivUniques = uniqueCache.forCivGetMatchingUniques( + observingCiv, UniqueType.AllStatsPercentFromObject, stateForConditionals) + for (unique in cachedAllStatPercentFromObjectCivUniques) { val tileFilter = unique.params[1] if (!tile.matchesTerrainFilter(tileFilter, observingCiv)) continue val statPercentage = unique.params[0].toFloat() @@ -222,7 +231,7 @@ class TileStatFunctions(val tile: Tile) { improvement: TileImprovement, city: City, conditionalState: StateForConditionals, - cityUniqueCache: LocalUniqueCache + uniqueCache: LocalUniqueCache ): Stats { val stats = Stats() @@ -231,9 +240,8 @@ class TileStatFunctions(val tile: Tile) { // therefore if we want the cache to be useful it needs to hold the pre-filtered uniques, // and then for each improvement we'll filter the uniques locally. // This is still a MASSIVE save of RAM! - val tileUniques = cityUniqueCache.get(UniqueType.StatsFromTiles.name, - city.getMatchingUniques(UniqueType.StatsFromTiles, StateForConditionals.IgnoreConditionals) - .filter { city.matchesFilter(it.params[2]) }) // These are the uniques for all improvements for this city, + val tileUniques = uniqueCache.forCityGetMatchingUniques(city, UniqueType.StatsFromTiles, StateForConditionals.IgnoreConditionals) + .filter { city.matchesFilter(it.params[2]) } // These are the uniques for all improvements for this city, .filter { it.conditionalsApply(conditionalState) } // ...and this is those with applicable conditions val improvementUniques = improvement.getMatchingUniques(UniqueType.ImprovementStatsOnTile, conditionalState) @@ -250,9 +258,11 @@ class TileStatFunctions(val tile: Tile) { fun statsFromObject() { // Same as above - cache holds unfiltered uniques for the city, while we use only the filtered ones - val uniques = cityUniqueCache.get(UniqueType.StatsFromObject.name, - city.getMatchingUniques(UniqueType.StatsFromObject, StateForConditionals.IgnoreConditionals)) - .filter { it.conditionalsApply(conditionalState) } + val uniques = uniqueCache.forCityGetMatchingUniques( + city, + UniqueType.StatsFromObject, + StateForConditionals.IgnoreConditionals + ).filter { it.conditionalsApply(conditionalState) } for (unique in uniques) { if (improvement.matchesFilter(unique.params[1])) { stats.add(unique.stats) @@ -280,9 +290,11 @@ class TileStatFunctions(val tile: Tile) { if (city != null) { // As above, since the conditional is tile-dependant, // we save uniques in the cache without conditional filtering, and use only filtered ones - val allStatPercentUniques = cityUniqueCache.get(UniqueType.AllStatsPercentFromObject.name, - city.getMatchingUniques(UniqueType.AllStatsPercentFromObject, StateForConditionals.IgnoreConditionals)) - .filter { it.conditionalsApply(conditionalState) } + val allStatPercentUniques = cityUniqueCache.forCityGetMatchingUniques( + city, + UniqueType.AllStatsPercentFromObject, + StateForConditionals.IgnoreConditionals + ).filter { it.conditionalsApply(conditionalState) } for (unique in allStatPercentUniques) { if (!improvement.matchesFilter(unique.params[1])) continue for (stat in Stat.values()) { @@ -291,9 +303,11 @@ class TileStatFunctions(val tile: Tile) { } // Same trick different unique - not sure if worth generalizing this 'late apply' of conditions? - val statPercentUniques = cityUniqueCache.get(UniqueType.StatPercentFromObject.name, - city.getMatchingUniques(UniqueType.StatPercentFromObject, StateForConditionals.IgnoreConditionals)) - .filter { it.conditionalsApply(conditionalState) } + val statPercentUniques = cityUniqueCache.forCityGetMatchingUniques( + city, + UniqueType.StatPercentFromObject, + StateForConditionals.IgnoreConditionals + ).filter { it.conditionalsApply(conditionalState) } for (unique in statPercentUniques) { if (!improvement.matchesFilter(unique.params[2])) continue diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 50283f58e3..e7f0481c29 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -184,7 +184,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { // Calls the clone function of the NamedStats this class is derived from, not a clone function of this class val stats = cloneStats() - for (unique in localUniqueCache.get("StatsFromObject", city.getMatchingUniques(UniqueType.StatsFromObject))) { + for (unique in localUniqueCache.forCityGetMatchingUniques(city, UniqueType.StatsFromObject)) { if (!matchesFilter(unique.params[1])) continue stats.add(unique.stats) } @@ -193,7 +193,7 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { stats.add(unique.stats) if (!isWonder) - for (unique in localUniqueCache.get("StatsFromBuildings", city.getMatchingUniques(UniqueType.StatsFromBuildings))) { + for (unique in localUniqueCache.forCityGetMatchingUniques(city, UniqueType.StatsFromBuildings)) { if (matchesFilter(unique.params[1])) stats.add(unique.stats) } @@ -204,12 +204,12 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { val stats = percentStatBonus?.clone() ?: Stats() val civInfo = city?.civ ?: return stats // initial stats - for (unique in localUniqueCache.get("StatPercentFromObject", civInfo.getMatchingUniques(UniqueType.StatPercentFromObject))) { + for (unique in localUniqueCache.forCivGetMatchingUniques(civInfo, UniqueType.StatPercentFromObject)) { if (matchesFilter(unique.params[2])) stats.add(Stat.valueOf(unique.params[1]), unique.params[0].toFloat()) } - for (unique in localUniqueCache.get("AllStatsPercentFromObject", civInfo.getMatchingUniques(UniqueType.AllStatsPercentFromObject))) { + for (unique in localUniqueCache.forCivGetMatchingUniques(civInfo, UniqueType.AllStatsPercentFromObject)) { if (!matchesFilter(unique.params[1])) continue for (stat in Stat.values()) { stats.add(stat, unique.params[0].toFloat()) diff --git a/core/src/com/unciv/models/ruleset/unique/Unique.kt b/core/src/com/unciv/models/ruleset/unique/Unique.kt index 9a14ccd0c8..cef3cf3dbc 100644 --- a/core/src/com/unciv/models/ruleset/unique/Unique.kt +++ b/core/src/com/unciv/models/ruleset/unique/Unique.kt @@ -301,8 +301,35 @@ class LocalUniqueCache(val cache:Boolean = true) { // This stores sequences *that iterate directly on a list* - that is, pre-resolved private val keyToUniques = HashMap>() + fun forCityGetMatchingUniques( + city: City, + uniqueType: UniqueType, + stateForConditionals: StateForConditionals = StateForConditionals( + city.civ, + city + ) + ): Sequence { + return get( + "city-${city.id}-${uniqueType.name}-${stateForConditionals}", + city.getMatchingUniques(uniqueType, stateForConditionals) + ) + } + + fun forCivGetMatchingUniques( + civ: Civilization, + uniqueType: UniqueType, + stateForConditionals: StateForConditionals = StateForConditionals( + civ + ) + ): Sequence { + return get( + "civ-${civ.civName}-${uniqueType.name}-${stateForConditionals}", + civ.getMatchingUniques(uniqueType, stateForConditionals) + ) + } + /** Get cached results as a sequence */ - fun get(key: String, sequence: Sequence): Sequence { + private fun get(key: String, sequence: Sequence): Sequence { if (!cache) return sequence if (keyToUniques.containsKey(key)) return keyToUniques[key]!! // Iterate the sequence, save actual results as a list, as return a sequence to that diff --git a/core/src/com/unciv/ui/components/tilegroups/CityTileGroup.kt b/core/src/com/unciv/ui/components/tilegroups/CityTileGroup.kt index a5d0ea9fbf..b4ded4b9bf 100644 --- a/core/src/com/unciv/ui/components/tilegroups/CityTileGroup.kt +++ b/core/src/com/unciv/ui/components/tilegroups/CityTileGroup.kt @@ -8,6 +8,7 @@ import com.unciv.UncivGame import com.unciv.logic.city.City import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.tile.Tile +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.models.stats.Stat import com.unciv.ui.images.ImageGetter import com.unciv.ui.components.extensions.addToCenter @@ -31,8 +32,8 @@ class CityTileGroup(val city: City, tile: Tile, tileSetStrings: TileSetStrings) layerMisc.touchable = Touchable.childrenOnly } - override fun update(viewingCiv: Civilization?) { - super.update(city.civ) + override fun update(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { + super.update(city.civ, localUniqueCache) tileState = CityTileState.NONE diff --git a/core/src/com/unciv/ui/components/tilegroups/TileGroup.kt b/core/src/com/unciv/ui/components/tilegroups/TileGroup.kt index fe647b0c73..1e35b69203 100644 --- a/core/src/com/unciv/ui/components/tilegroups/TileGroup.kt +++ b/core/src/com/unciv/ui/components/tilegroups/TileGroup.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.g2d.Batch import com.badlogic.gdx.scenes.scene2d.Group import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.tile.Tile +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.components.tilegroups.layers.TileLayerBorders import com.unciv.ui.components.tilegroups.layers.TileLayerCityButton import com.unciv.ui.components.tilegroups.layers.TileLayerFeatures @@ -74,10 +75,10 @@ open class TileGroup( || viewingCiv.viewableTiles.contains(tile) || viewingCiv.isSpectator() - private fun reset() { + private fun reset(localUniqueCache: LocalUniqueCache) { layerTerrain.reset() layerBorders.reset() - layerMisc.reset() + layerMisc.reset(localUniqueCache) layerOverlay.reset() layerUnitArt.reset() layerUnitFlag.reset() @@ -94,8 +95,9 @@ open class TileGroup( layerCityButton.isVisible = isVisible } - open fun update(viewingCiv: Civilization? = null) { - + open fun update( + viewingCiv: Civilization? = null, + localUniqueCache: LocalUniqueCache = LocalUniqueCache(false)) { layerMisc.removeHexOutline() layerMisc.hideTerrainOverlay() layerOverlay.hideHighlight() @@ -107,7 +109,7 @@ open class TileGroup( // Do not update layers if tile is not explored by viewing player if (viewingCiv != null && !(isForceVisible || viewingCiv.hasExplored(tile))) { - reset() + reset(localUniqueCache) // If tile has explored neighbors - reveal layers partially if (tile.neighbors.none { viewingCiv.hasExplored(it) }) // Else - hide all layers @@ -117,14 +119,14 @@ open class TileGroup( removeMissingModReferences() - layerTerrain.update(viewingCiv) - layerFeatures.update(viewingCiv) - layerBorders.update(viewingCiv) - layerOverlay.update(viewingCiv) - layerMisc.update(viewingCiv) - layerUnitArt.update(viewingCiv) - layerUnitFlag.update(viewingCiv) - layerCityButton.update(viewingCiv) + layerTerrain.update(viewingCiv, localUniqueCache) + layerFeatures.update(viewingCiv, localUniqueCache) + layerBorders.update(viewingCiv, localUniqueCache) + layerOverlay.update(viewingCiv, localUniqueCache) + layerMisc.update(viewingCiv, localUniqueCache) + layerUnitArt.update(viewingCiv, localUniqueCache) + layerUnitFlag.update(viewingCiv, localUniqueCache) + layerCityButton.update(viewingCiv, localUniqueCache) } private fun removeMissingModReferences() { diff --git a/core/src/com/unciv/ui/components/tilegroups/WorldTileGroup.kt b/core/src/com/unciv/ui/components/tilegroups/WorldTileGroup.kt index b06ba2728e..86336f8ca5 100644 --- a/core/src/com/unciv/ui/components/tilegroups/WorldTileGroup.kt +++ b/core/src/com/unciv/ui/components/tilegroups/WorldTileGroup.kt @@ -5,10 +5,10 @@ import com.badlogic.gdx.scenes.scene2d.Touchable import com.unciv.UncivGame import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.tile.Tile +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.images.ImageGetter import com.unciv.ui.components.extensions.center import com.unciv.ui.components.extensions.darken -import com.unciv.ui.screens.worldscreen.WorldScreen class WorldTileGroup(tile: Tile, tileSetStrings: TileSetStrings) @@ -18,8 +18,8 @@ class WorldTileGroup(tile: Tile, tileSetStrings: TileSetStrings) layerMisc.touchable = Touchable.disabled } - override fun update(viewingCiv: Civilization?) { - super.update(viewingCiv) + override fun update(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { + super.update(viewingCiv, localUniqueCache) updateWorkedIcon(viewingCiv!!) } diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayer.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayer.kt index 12a6774b67..fd1a6801c7 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayer.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayer.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.ui.Image import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.tile.Tile +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.models.tilesets.TileSetCache import com.unciv.ui.components.tilegroups.TileGroup import com.unciv.ui.components.tilegroups.TileSetStrings @@ -32,8 +33,10 @@ abstract class TileLayer(val tileGroup: TileGroup, size: Float) : Group() { fun isViewable(viewingCiv: Civilization) = tileGroup.isViewable(viewingCiv) - fun update(viewingCiv: Civilization?) { - doUpdate(viewingCiv) + fun update( + viewingCiv: Civilization?, + localUniqueCache: LocalUniqueCache = LocalUniqueCache(false)) { + doUpdate(viewingCiv, localUniqueCache) determineVisibility() } @@ -41,6 +44,8 @@ abstract class TileLayer(val tileGroup: TileGroup, size: Float) : Group() { isVisible = hasChildren() } - protected abstract fun doUpdate(viewingCiv: Civilization?) + protected abstract fun doUpdate( + viewingCiv: Civilization?, + localUniqueCache: LocalUniqueCache = LocalUniqueCache(false)) } diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerBorders.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerBorders.kt index 0c7c9ce2dd..7764ae7960 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerBorders.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerBorders.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.scenes.scene2d.Actor import com.badlogic.gdx.scenes.scene2d.ui.Image import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.tile.Tile +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.images.ImageGetter import com.unciv.ui.components.tilegroups.TileGroup import kotlin.math.PI @@ -135,7 +136,7 @@ class TileLayerBorders(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, } - override fun doUpdate(viewingCiv: Civilization?) { + override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { updateBorders() } diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerCityButton.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerCityButton.kt index 7532ccb6a8..7cc9e25eb3 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerCityButton.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerCityButton.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.Actor import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.utils.Align import com.unciv.logic.civilization.Civilization +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.components.tilegroups.CityButton import com.unciv.ui.components.tilegroups.TileGroup import com.unciv.ui.components.tilegroups.WorldTileGroup @@ -43,7 +44,7 @@ class TileLayerCityButton(tileGroup: TileGroup, size: Float) : TileLayer(tileGro cityButton?.moveButtonDown() } - override fun doUpdate(viewingCiv: Civilization?) { + override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { if (tileGroup !is WorldTileGroup) return diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerFeatures.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerFeatures.kt index 3f5ec20fad..e6ebe086aa 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerFeatures.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerFeatures.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Image import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.tile.RoadStatus import com.unciv.logic.map.tile.Tile +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.images.ImageGetter import com.unciv.ui.components.tilegroups.TileGroup import kotlin.math.atan2 @@ -69,7 +70,7 @@ class TileLayerFeatures(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup } - override fun doUpdate(viewingCiv: Civilization?) { + override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { updateRoadImages() } diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerMisc.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerMisc.kt index 25bde7d1fe..3e9dd2a85e 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerMisc.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerMisc.kt @@ -13,6 +13,7 @@ import com.unciv.models.helpers.MapArrowType import com.unciv.models.helpers.MiscArrowTypes import com.unciv.models.helpers.TintedMapArrow import com.unciv.models.helpers.UnitMovementMemoryType +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.components.extensions.center import com.unciv.ui.components.extensions.centerX import com.unciv.ui.components.extensions.toLabel @@ -268,7 +269,11 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si } // JN updating display of tile yields - private fun updateYieldIcon(viewingCiv: Civilization?, show: Boolean) { + private fun updateYieldIcon( + viewingCiv: Civilization?, + show: Boolean, + localUniqueCache: LocalUniqueCache + ) { val effectiveVisible = show && !tileGroup.isForMapEditorIcon && // don't have a map to calc yields !(viewingCiv == null && tileGroup.isForceVisible) // main menu background @@ -278,9 +283,9 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si if (effectiveVisible) yields.run { // Update YieldGroup Icon if (tileGroup is CityTileGroup) - setStats(tile().stats.getTileStats(tileGroup.city, viewingCiv)) + setStats(tile().stats.getTileStats(tileGroup.city, viewingCiv, localUniqueCache)) else - setStats(tile().stats.getTileStats(viewingCiv)) + setStats(tile().stats.getTileStats(viewingCiv, localUniqueCache)) toFront() centerX(tileGroup) isVisible = true @@ -345,7 +350,7 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si determineVisibility() } - override fun doUpdate(viewingCiv: Civilization?) { + override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { var showResourcesAndImprovements = true var showTileYields = true @@ -356,7 +361,7 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si } updateImprovementIcon(viewingCiv, showResourcesAndImprovements) - updateYieldIcon(viewingCiv, showTileYields) + updateYieldIcon(viewingCiv, showTileYields, localUniqueCache) updateResourceIcon(viewingCiv, showResourcesAndImprovements) if (tileGroup !is WorldTileGroup || DebugUtils.SHOW_TILE_COORDS) updateStartingLocationIcon(true) @@ -374,9 +379,9 @@ class TileLayerMisc(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, si || terrainOverlay.isVisible } - fun reset() { + fun reset(localUniqueCache: LocalUniqueCache) { updateImprovementIcon(null, false) - updateYieldIcon(null, false) + updateYieldIcon(null, false, localUniqueCache) updateResourceIcon(null, false) updateStartingLocationIcon(false) clearArrows() diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerOverlay.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerOverlay.kt index eef3beadce..497a844399 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerOverlay.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerOverlay.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.Actor import com.unciv.Constants import com.unciv.logic.civilization.Civilization +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.components.tilegroups.TileGroup import com.unciv.ui.images.ImageGetter @@ -79,7 +80,7 @@ class TileLayerOverlay(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, determineVisibility() } - override fun doUpdate(viewingCiv: Civilization?) { + override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { val isViewable = viewingCiv == null || isViewable(viewingCiv) fog.isVisible = !isViewable && !tileGroup.isForceVisible diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt index 8d96fa22e6..b109edb5e6 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerTerrain.kt @@ -6,6 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Image import com.unciv.UncivGame import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.tile.Tile +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.images.ImageGetter import com.unciv.ui.components.tilegroups.TileGroup import com.unciv.ui.screens.basescreen.BaseScreen @@ -194,7 +195,7 @@ class TileLayerTerrain(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, } } - override fun doUpdate(viewingCiv: Civilization?) { + override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { updateTileImage(viewingCiv) updateRivers(tileGroup.tile.hasBottomRightRiver, tileGroup.tile.hasBottomRiver, tileGroup.tile.hasBottomLeftRiver) updateTileColor(viewingCiv) diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerUnitArt.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerUnitArt.kt index c03f71a621..caa455deb4 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerUnitArt.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerUnitArt.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.Group import com.unciv.UncivGame import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.mapunit.MapUnit +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.images.ImageGetter import com.unciv.ui.components.tilegroups.TileGroup @@ -63,7 +64,7 @@ class TileLayerUnitArt(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup, color.a = 0.5f } - override fun doUpdate(viewingCiv: Civilization?) { + override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { val slot1Unit = tileGroup.tile.civilianUnit val slot2Unit = tileGroup.tile.militaryUnit diff --git a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerUnitFlag.kt b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerUnitFlag.kt index f81037ff29..7a4f8a9da4 100644 --- a/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerUnitFlag.kt +++ b/core/src/com/unciv/ui/components/tilegroups/layers/TileLayerUnitFlag.kt @@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.Align import com.unciv.UncivGame import com.unciv.logic.civilization.Civilization import com.unciv.logic.map.mapunit.MapUnit +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.ui.images.ImageGetter import com.unciv.ui.components.tilegroups.TileGroup import com.unciv.ui.screens.basescreen.BaseScreen @@ -133,7 +134,7 @@ class TileLayerUnitFlag(tileGroup: TileGroup, size: Float) : TileLayer(tileGroup } - override fun doUpdate(viewingCiv: Civilization?) { + override fun doUpdate(viewingCiv: Civilization?, localUniqueCache: LocalUniqueCache) { clearSlots() fillSlots(viewingCiv) diff --git a/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt b/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt index c902439da3..f22ae36ead 100644 --- a/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt +++ b/core/src/com/unciv/ui/screens/worldscreen/WorldMapHolder.kt @@ -32,6 +32,7 @@ import com.unciv.logic.map.tile.Tile import com.unciv.models.UncivSound import com.unciv.models.helpers.MapArrowType import com.unciv.models.helpers.MiscArrowTypes +import com.unciv.models.ruleset.unique.LocalUniqueCache import com.unciv.models.ruleset.unique.UniqueType import com.unciv.ui.audio.SoundPlayer import com.unciv.ui.components.KeyCharAndCode @@ -567,8 +568,9 @@ class WorldMapHolder( } // General update of all tiles + val uniqueCache = LocalUniqueCache(true) for (tileGroup in tileGroups.values) - tileGroup.update(viewingCiv) + tileGroup.update(viewingCiv, uniqueCache) // Update tiles according to selected unit/city val unitTable = worldScreen.bottomUnitTable