From 54201c381cb84794d445f7ff79d4943f3b02b0a8 Mon Sep 17 00:00:00 2001 From: SeventhM <127357473+SeventhM@users.noreply.github.com> Date: Sat, 24 Feb 2024 12:38:32 -0800 Subject: [PATCH] Allow conditional timed triggers for unit actions or most other trigger conditionals (#11181) * Allow conditional timed triggers to be visible from all uniqueMaps * Whoops --- core/src/com/unciv/logic/city/City.kt | 17 +++++++++-------- .../unciv/logic/civilization/Civilization.kt | 6 +++++- .../transients/CapitalConnectionsFinder.kt | 4 ++-- core/src/com/unciv/logic/map/tile/Tile.kt | 5 +++-- .../com/unciv/models/ruleset/unique/Unique.kt | 10 +++++----- 5 files changed, 24 insertions(+), 18 deletions(-) diff --git a/core/src/com/unciv/logic/city/City.kt b/core/src/com/unciv/logic/city/City.kt index f43c4af137..1035652231 100644 --- a/core/src/com/unciv/logic/city/City.kt +++ b/core/src/com/unciv/logic/city/City.kt @@ -211,8 +211,8 @@ class City : IsPartOfGameInfoSerialization { fun foodForNextTurn() = cityStats.currentCityStats.food.roundToInt() - fun containsBuildingUnique(uniqueType: UniqueType) = - cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType).any() + fun containsBuildingUnique(uniqueType: UniqueType, state: StateForConditionals = StateForConditionals(this)) = + cityConstructions.builtBuildingUniqueMap.getMatchingUniques(uniqueType, state).any() fun getGreatPersonPercentageBonus() = GreatPersonPointsBreakdown.getGreatPersonPercentageBonus(this) fun getGreatPersonPoints() = GreatPersonPointsBreakdown(this).sum() @@ -479,17 +479,17 @@ class City : IsPartOfGameInfoSerialization { fun getLocalMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(civ, this)): Sequence { return ( cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType).filter { it.isLocalEffect } - + religion.getUniques().filter { it.type == uniqueType } - ).filter { - it.conditionalsApply(stateForConditionals) - } + + religion.getUniques().filter { it.type == uniqueType } + ).filter { + !it.isTimedTriggerable && it.conditionalsApply(stateForConditionals) + } } // Uniques coming from only this city fun getMatchingLocalOnlyUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals): Sequence { val uniques = cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType).filter { it.isLocalEffect } + religion.getUniques().filter { it.type == uniqueType } - return if (uniques.any()) uniques.filter { it.conditionalsApply(stateForConditionals) } + return if (uniques.any()) uniques.filter { !it.isTimedTriggerable && it.conditionalsApply(stateForConditionals) } else uniques } @@ -497,7 +497,8 @@ class City : IsPartOfGameInfoSerialization { fun getMatchingUniquesWithNonLocalEffects(uniqueType: UniqueType, stateForConditionals: StateForConditionals): Sequence { val uniques = cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType) // Memory performance showed that this function was very memory intensive, thus we only create the filter if needed - return if (uniques.any()) uniques.filter { !it.isLocalEffect && it.conditionalsApply(stateForConditionals) } + return if (uniques.any()) uniques.filter { !it.isLocalEffect && !it.isTimedTriggerable + && it.conditionalsApply(stateForConditionals) } else uniques } diff --git a/core/src/com/unciv/logic/civilization/Civilization.kt b/core/src/com/unciv/logic/civilization/Civilization.kt index e9354fcb0b..e64ec02553 100644 --- a/core/src/com/unciv/logic/civilization/Civilization.kt +++ b/core/src/com/unciv/logic/civilization/Civilization.kt @@ -482,7 +482,7 @@ class Civilization : IsPartOfGameInfoSerialization { yieldAll(cityStateFunctions.getUniquesProvidedByCityStates(uniqueType, stateForConditionals)) if (religionManager.religion != null) yieldAll(religionManager.religion!!.getFounderUniques() - .filter { it.type == uniqueType && it.conditionalsApply(stateForConditionals) }) + .filter { !it.isTimedTriggerable && it.type == uniqueType && it.conditionalsApply(stateForConditionals) }) yieldAll(getCivResourceSupply().asSequence() .filter { it.amount > 0 } @@ -500,6 +500,10 @@ class Civilization : IsPartOfGameInfoSerialization { yieldAll(cities.asSequence() .flatMap { city -> city.cityConstructions.builtBuildingUniqueMap.getTriggeredUniques(trigger, stateForConditionals) } ) + if (religionManager.religion != null) + yieldAll(religionManager.religion!!.getFounderUniques() + .filter { unique -> unique.conditionals.any { it.type == trigger } + && unique.conditionalsApply(stateForConditionals) }) yieldAll(policies.policyUniques.getTriggeredUniques(trigger, stateForConditionals)) yieldAll(tech.techUniques.getTriggeredUniques(trigger, stateForConditionals)) yieldAll(getEra().uniqueMap.getTriggeredUniques (trigger, stateForConditionals)) diff --git a/core/src/com/unciv/logic/civilization/transients/CapitalConnectionsFinder.kt b/core/src/com/unciv/logic/civilization/transients/CapitalConnectionsFinder.kt index 06ddd00959..cda976cefa 100644 --- a/core/src/com/unciv/logic/civilization/transients/CapitalConnectionsFinder.kt +++ b/core/src/com/unciv/logic/civilization/transients/CapitalConnectionsFinder.kt @@ -85,8 +85,8 @@ class CapitalConnectionsFinder(private val civInfo: Civilization) { ) } - private fun City.containsHarbor() = - this.cityConstructions.builtBuildingUniqueMap.getUniques(UniqueType.ConnectTradeRoutes).any() + private fun City.containsHarbor() = + this.containsBuildingUnique(UniqueType.ConnectTradeRoutes) private fun check(cityToConnectFrom: City, transportType: String, diff --git a/core/src/com/unciv/logic/map/tile/Tile.kt b/core/src/com/unciv/logic/map/tile/Tile.kt index 663151382e..a7ec11c223 100644 --- a/core/src/com/unciv/logic/map/tile/Tile.kt +++ b/core/src/com/unciv/logic/map/tile/Tile.kt @@ -387,9 +387,10 @@ open class Tile : IsPartOfGameInfoSerialization { fun isRoughTerrain() = allTerrains.any { it.isRough() } /** Checks whether any of the TERRAINS of this tile has a certain unique */ - fun terrainHasUnique(uniqueType: UniqueType) = terrainUniqueMap.getUniques(uniqueType).any() + fun terrainHasUnique(uniqueType: UniqueType, state: StateForConditionals = StateForConditionals(tile = this)) = + terrainUniqueMap.getMatchingUniques(uniqueType, state).any() /** Get all uniques of this type that any TERRAIN on this tile has */ - fun getTerrainMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(tile=this) ): Sequence { + fun getTerrainMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(tile = this) ): Sequence { return terrainUniqueMap.getMatchingUniques(uniqueType, stateForConditionals) } diff --git a/core/src/com/unciv/models/ruleset/unique/Unique.kt b/core/src/com/unciv/models/ruleset/unique/Unique.kt index 87722d69bd..6181a57c49 100644 --- a/core/src/com/unciv/models/ruleset/unique/Unique.kt +++ b/core/src/com/unciv/models/ruleset/unique/Unique.kt @@ -28,10 +28,12 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s } val conditionals: List = text.getConditionals() + val isTimedTriggerable = conditionals.any { it.type == UniqueType.ConditionalTimedUnique } + val isTriggerable = type != null && ( type.targetTypes.contains(UniqueTarget.Triggerable) || type.targetTypes.contains(UniqueTarget.UnitTriggerable) - || conditionals.any { it.type == UniqueType.ConditionalTimedUnique } + || isTimedTriggerable ) /** Includes conditional params */ @@ -59,7 +61,7 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s fun conditionalsApply(state: StateForConditionals = StateForConditionals()): Boolean { if (state.ignoreConditionals) return true // Always allow Timed conditional uniques. They are managed elsewhere - if (conditionals.any { it.type == UniqueType.ConditionalTimedUnique }) return true + if (isTimedTriggerable) return true for (condition in conditionals) { if (!Conditionals.conditionalApplies(this, condition, state)) return false } @@ -209,8 +211,6 @@ class UniqueMap: HashMap>() { /** Adds one [unique] unless it has a ConditionalTimedUnique conditional */ fun addUnique(unique: Unique) { - if (unique.conditionals.any { it.type == UniqueType.ConditionalTimedUnique }) return - val existingArrayList = get(unique.placeholderText) if (existingArrayList != null) existingArrayList.add(unique) else this[unique.placeholderText] = arrayListOf(unique) @@ -228,7 +228,7 @@ class UniqueMap: HashMap>() { fun getUniques(uniqueType: UniqueType) = getUniques(uniqueType.placeholderText) fun getMatchingUniques(uniqueType: UniqueType, state: StateForConditionals) = getUniques(uniqueType) - .filter { it.conditionalsApply(state) } + .filter { it.conditionalsApply(state) && !it.isTimedTriggerable } fun getAllUniques() = this.asSequence().flatMap { it.value.asSequence() }