diff --git a/core/src/com/unciv/logic/automation/civilization/ReligionAutomation.kt b/core/src/com/unciv/logic/automation/civilization/ReligionAutomation.kt index 56b44f70fe..090f9f7467 100644 --- a/core/src/com/unciv/logic/automation/civilization/ReligionAutomation.kt +++ b/core/src/com/unciv/logic/automation/civilization/ReligionAutomation.kt @@ -127,7 +127,7 @@ object ReligionAutomation { if (validCitiesToBuy.isEmpty()) return val citiesWithBonusCharges = validCitiesToBuy.filter { city -> - city.getLocalMatchingUniques(UniqueType.UnitStartingActions).filter { it.params[2] == Constants.spreadReligion }.any() + city.getMatchingUniques(UniqueType.UnitStartingActions).filter { it.params[2] == Constants.spreadReligion }.any() } val holyCity = validCitiesToBuy.firstOrNull { it.isHolyCityOf(civInfo.religionManager.religion!!.name) } diff --git a/core/src/com/unciv/logic/battle/Battle.kt b/core/src/com/unciv/logic/battle/Battle.kt index 8e0d8e02ed..f766ac7298 100644 --- a/core/src/com/unciv/logic/battle/Battle.kt +++ b/core/src/com/unciv/logic/battle/Battle.kt @@ -232,10 +232,10 @@ object Battle { val cityWithReligion = civUnit.getTile().getTilesInDistance(4).firstOrNull { - it.isCityCenter() && it.getCity()!!.getLocalMatchingUniques(UniqueType.KillUnitPlunderNearCity, stateForConditionals).any() + it.isCityCenter() && it.getCity()!!.getMatchingUniques(UniqueType.KillUnitPlunderNearCity, stateForConditionals).any() }?.getCity() if (cityWithReligion != null) { - bonusUniques.addAll(cityWithReligion.getLocalMatchingUniques(UniqueType.KillUnitPlunderNearCity, stateForConditionals)) + bonusUniques.addAll(cityWithReligion.getMatchingUniques(UniqueType.KillUnitPlunderNearCity, stateForConditionals)) } for (unique in bonusUniques) { diff --git a/core/src/com/unciv/logic/city/City.kt b/core/src/com/unciv/logic/city/City.kt index 936fa94da4..c2978dcff0 100644 --- a/core/src/com/unciv/logic/city/City.kt +++ b/core/src/com/unciv/logic/city/City.kt @@ -264,7 +264,7 @@ class City : IsPartOfGameInfoSerialization { } private fun getCityResourcesFromUniqueBuildings(cityResources: ResourceSupplyList, resourceModifer: HashMap) { - for (unique in getLocalMatchingUniques(UniqueType.ProvidesResources, StateForConditionals(civ, this))) { // E.G "Provides [1] [Iron]" + for (unique in getMatchingUniques(UniqueType.ProvidesResources, StateForConditionals(civ, this))) { // E.G "Provides [1] [Iron]" val resource = getRuleset().tileResources[unique.params[1]] ?: continue cityResources.add( @@ -575,7 +575,6 @@ class City : IsPartOfGameInfoSerialization { return when (filter) { "in this city" -> true // Filtered by the way uniques are found "in all cities" -> true - "in other cities" -> true // Filtered by the way uniques are found "in all coastal cities" -> isCoastal() "in capital" -> isCapital() "in all non-occupied cities" -> !cityStats.hasExtraAnnexUnhappiness() || isPuppet @@ -618,13 +617,14 @@ class City : IsPartOfGameInfoSerialization { uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(civ, this) ): Sequence { - return civ.getMatchingUniques(uniqueType, stateForConditionals, this) + + return civ.getMatchingUniques(uniqueType, stateForConditionals) + getLocalMatchingUniques(uniqueType, stateForConditionals) } - fun getLocalMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(civ, this)): Sequence { + // Uniques special to this city + private fun getLocalMatchingUniques(uniqueType: UniqueType, stateForConditionals: StateForConditionals = StateForConditionals(civ, this)): Sequence { return ( - cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType).filter { !it.isAntiLocalEffect } + cityConstructions.builtBuildingUniqueMap.getUniques(uniqueType).filter { it.isLocalEffect } + religion.getUniques().filter { it.isOfType(uniqueType) } ).filter { it.conditionalsApply(stateForConditionals) @@ -632,6 +632,7 @@ class City : IsPartOfGameInfoSerialization { } + // Uniques coming from this city, but that should be provided globally 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 diff --git a/core/src/com/unciv/logic/city/CityConstructions.kt b/core/src/com/unciv/logic/city/CityConstructions.kt index 00deb192b9..cb601fda26 100644 --- a/core/src/com/unciv/logic/city/CityConstructions.kt +++ b/core/src/com/unciv/logic/city/CityConstructions.kt @@ -506,7 +506,7 @@ class CityConstructions : IsPartOfGameInfoSerialization { } builtBuildingObjects = builtBuildingObjects.withItem(building) builtBuildings.add(buildingName) - + updateUniques() /** Support for [UniqueType.CreatesOneImprovement] */ @@ -578,15 +578,13 @@ class CityConstructions : IsPartOfGameInfoSerialization { fun addFreeBuildings() { // "Gain a free [buildingName] [cityFilter]" - val freeBuildingUniques = city.getLocalMatchingUniques(UniqueType.GainFreeBuildings, StateForConditionals(city.civ, city)) + val freeBuildingUniques = city.getMatchingUniques(UniqueType.GainFreeBuildings, StateForConditionals(city.civ, city)) for (unique in freeBuildingUniques) { val freeBuilding = city.civ.getEquivalentBuilding(unique.params[0]) - val citiesThatApply = when (unique.params[1]) { - "in this city" -> listOf(city) - "in other cities" -> city.civ.cities.filter { it !== city } - else -> city.civ.cities.filter { it.matchesFilter(unique.params[1]) } - } + val citiesThatApply = + if (unique.isLocalEffect) listOf(city) + else city.civ.cities.filter { it.matchesFilter(unique.params[1]) } for (city in citiesThatApply) { if (city.cityConstructions.containsBuildingOrEquivalent(freeBuilding.name)) continue diff --git a/core/src/com/unciv/logic/city/managers/CityReligionManager.kt b/core/src/com/unciv/logic/city/managers/CityReligionManager.kt index 40ca3706d9..6b2da75c78 100644 --- a/core/src/com/unciv/logic/city/managers/CityReligionManager.kt +++ b/core/src/com/unciv/logic/city/managers/CityReligionManager.kt @@ -258,7 +258,7 @@ class CityReligionManager : IsPartOfGameInfoSerialization { private fun getSpreadRange(): Int { var spreadRange = 10 - for (unique in city.getLocalMatchingUniques(UniqueType.ReligionSpreadDistance)) { + for (unique in city.getMatchingUniques(UniqueType.ReligionSpreadDistance)) { spreadRange += unique.params[0].toInt() } @@ -308,7 +308,7 @@ class CityReligionManager : IsPartOfGameInfoSerialization { var pressure = pressureFromAdjacentCities.toFloat() // Follower beliefs of this religion - for (unique in city.getLocalMatchingUniques(UniqueType.NaturalReligionSpreadStrength)) { + for (unique in city.getMatchingUniques(UniqueType.NaturalReligionSpreadStrength)) { if (pressuredCity.matchesFilter(unique.params[1])) pressure *= unique.params[0].toPercent() } diff --git a/core/src/com/unciv/logic/civilization/Civilization.kt b/core/src/com/unciv/logic/civilization/Civilization.kt index bc8cf06b01..65504d8909 100644 --- a/core/src/com/unciv/logic/civilization/Civilization.kt +++ b/core/src/com/unciv/logic/civilization/Civilization.kt @@ -453,12 +453,10 @@ class Civilization : IsPartOfGameInfoSerialization { /** Destined to replace getMatchingUniques, gradually, as we fill the enum */ fun getMatchingUniques( uniqueType: UniqueType, - stateForConditionals: StateForConditionals = StateForConditionals(this), - cityToIgnore: City? = null + stateForConditionals: StateForConditionals = StateForConditionals(this) ): Sequence = sequence { yieldAll(nation.getMatchingUniques(uniqueType, stateForConditionals)) yieldAll(cities.asSequence() - .filter { it != cityToIgnore } .flatMap { city -> city.getMatchingUniquesWithNonLocalEffects(uniqueType, stateForConditionals) } ) yieldAll(policies.policyUniques.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 d84b234039..055e1e9f39 100644 --- a/core/src/com/unciv/models/ruleset/unique/Unique.kt +++ b/core/src/com/unciv/models/ruleset/unique/Unique.kt @@ -38,7 +38,6 @@ class Unique(val text: String, val sourceObjectType: UniqueTarget? = null, val s val allParams = params + conditionals.flatMap { it.params } val isLocalEffect = params.contains("in this city") || conditionals.any { it.type == UniqueType.ConditionalInThisCity } - val isAntiLocalEffect = params.contains("in other cities") || conditionals.any { it.type == UniqueType.ConditionalInOtherCities } fun hasFlag(flag: UniqueFlag) = type != null && type.flags.contains(flag) diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt b/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt index d75d348780..c3d7c42e73 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueTriggerActivation.kt @@ -238,11 +238,9 @@ object UniqueTriggerActivation { } UniqueType.OneTimeGainPopulation -> { - val applicableCities = when (unique.params[1]) { - "in this city" -> sequenceOf(city!!) - "in other cities" -> civInfo.cities.asSequence().filter { it != city } - else -> civInfo.cities.asSequence().filter { it.matchesFilter(unique.params[1]) } - } + val applicableCities = + if (unique.params[1] == "in this city") sequenceOf(city!!) + else civInfo.cities.asSequence().filter { it.matchesFilter(unique.params[1]) } for (applicableCity in applicableCities) { applicableCity.population.addPopulation(unique.params[0].toInt()) } diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 817ffd056a..95264f57cc 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -634,7 +634,6 @@ enum class UniqueType(val text: String, vararg targets: UniqueTarget, val flags: /////// city conditionals ConditionalInThisCity("in this city", UniqueTarget.Conditional), - ConditionalInOtherCities("in other cities", UniqueTarget.Conditional), ConditionalCityWithBuilding("in cities with a [buildingFilter]", UniqueTarget.Conditional), ConditionalCityWithoutBuilding("in cities without a [buildingFilter]", UniqueTarget.Conditional), ConditionalPopulationFilter("in cities with at least [amount] [populationFilter]", UniqueTarget.Conditional),