diff --git a/core/src/com/unciv/logic/city/CityConstructions.kt b/core/src/com/unciv/logic/city/CityConstructions.kt index 30dd5a8070..e417928a5e 100644 --- a/core/src/com/unciv/logic/city/CityConstructions.kt +++ b/core/src/com/unciv/logic/city/CityConstructions.kt @@ -37,6 +37,7 @@ import com.unciv.ui.screens.civilopediascreen.FormattedLine import com.unciv.ui.screens.pickerscreens.PromotionTree import com.unciv.utils.withItem import com.unciv.utils.withoutItem +import yairm210.purity.annotations.Cache import yairm210.purity.annotations.LocalState import yairm210.purity.annotations.Readonly import kotlin.math.ceil @@ -58,6 +59,9 @@ class CityConstructions : IsPartOfGameInfoSerialization { @Transient private var builtBuildingObjects = ArrayList() + + @Transient @Cache + private val containedBuildingFiltersCache = HashMap() @Transient val builtBuildingUniqueMap = UniqueMap() @@ -265,7 +269,10 @@ class CityConstructions : IsPartOfGameInfoSerialization { @Readonly fun getBuiltBuildings(): Sequence = builtBuildingObjects.asSequence() @Readonly fun containsBuildingOrEquivalent(buildingNameOrUnique: String): Boolean = - isBuilt(buildingNameOrUnique) || getBuiltBuildings().any { it.replaces == buildingNameOrUnique || it.hasUnique(buildingNameOrUnique, city.state) } + containedBuildingFiltersCache.getOrPut(buildingNameOrUnique) { + isBuilt(buildingNameOrUnique) + || getBuiltBuildings().any { it.replaces == buildingNameOrUnique || it.hasUnique(buildingNameOrUnique, city.state) } + } @Readonly fun getWorkDone(constructionName: String): Int { @@ -658,6 +665,8 @@ class CityConstructions : IsPartOfGameInfoSerialization { fun updateUniques(onLoadGame: Boolean = false) { builtBuildingUniqueMap.clear() + containedBuildingFiltersCache.clear() + for (building in getBuiltBuildings()) builtBuildingUniqueMap.addUniques(building.uniqueObjects) if (!onLoadGame) { diff --git a/core/src/com/unciv/models/ruleset/unique/Conditionals.kt b/core/src/com/unciv/models/ruleset/unique/Conditionals.kt index 2068316bda..83b855056c 100644 --- a/core/src/com/unciv/models/ruleset/unique/Conditionals.kt +++ b/core/src/com/unciv/models/ruleset/unique/Conditionals.kt @@ -28,7 +28,7 @@ object Conditionals { state: GameContext ): Boolean { - if (conditional.type?.targetTypes?.any { it.modifierType == UniqueTarget.ModifierType.Other } == true) + if (conditional.isOtherModifierType) return true // not a filtering condition, includes e.g. ModifierHiddenFromUsers /** Helper to simplify conditional tests requiring gameInfo */ diff --git a/core/src/com/unciv/models/ruleset/unique/Unique.kt b/core/src/com/unciv/models/ruleset/unique/Unique.kt index 0c9224c9cc..3fd5935efb 100644 --- a/core/src/com/unciv/models/ruleset/unique/Unique.kt +++ b/core/src/com/unciv/models/ruleset/unique/Unique.kt @@ -43,6 +43,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s val allParams = params + modifiers.flatMap { it.params } val isLocalEffect = params.contains("in this city") || hasModifier(UniqueType.ConditionalInThisCity) + val isOtherModifierType = type?.targetTypes?.any { it.modifierType == UniqueTarget.ModifierType.Other } == true @Readonly fun hasFlag(flag: UniqueFlag) = type != null && type.flags.contains(flag) @Readonly fun isHiddenToUsers() = hasFlag(UniqueFlag.HiddenToUsers) || hasModifier(UniqueType.ModifierHiddenFromUsers)