From f7702bd71a84041daab53ee8989dc5f84f1ee4d8 Mon Sep 17 00:00:00 2001 From: SeventhM <127357473+SeventhM@users.noreply.github.com> Date: Tue, 30 Jan 2024 10:06:36 -0800 Subject: [PATCH] Add additional cityFilters (#11047) * Add additional cityFilters * Maybe viewingCiv shouldn't be null * Studio complains it is unnecessary now * I'm doomed to forget imports * Ignore this * typo --- core/src/com/unciv/logic/city/City.kt | 32 +++++++++++------- .../models/ruleset/unique/Conditionals.kt | 10 +++++- .../ruleset/unique/UniqueParameterType.kt | 33 ++++++++++++------- .../unciv/models/ruleset/unique/UniqueType.kt | 5 +++ docs/Modders/Unique-parameters.md | 23 +++++++------ 5 files changed, 68 insertions(+), 35 deletions(-) diff --git a/core/src/com/unciv/logic/city/City.kt b/core/src/com/unciv/logic/city/City.kt index 2dad929e94..602ecc5502 100644 --- a/core/src/com/unciv/logic/city/City.kt +++ b/core/src/com/unciv/logic/city/City.kt @@ -3,6 +3,7 @@ package com.unciv.logic.city import com.badlogic.gdx.math.Vector2 import com.unciv.GUI import com.unciv.logic.IsPartOfGameInfoSerialization +import com.unciv.logic.MultiFilter import com.unciv.logic.city.managers.CityConquestFunctions import com.unciv.logic.city.managers.CityEspionageManager import com.unciv.logic.city.managers.CityExpansionManager @@ -480,17 +481,22 @@ class City : IsPartOfGameInfoSerialization { } /** Implements [UniqueParameterType.CityFilter][com.unciv.models.ruleset.unique.UniqueParameterType.CityFilter] */ - fun matchesFilter(filter: String, viewingCiv: Civilization = civ): Boolean { + fun matchesFilter(filter: String, viewingCiv: Civilization? = civ): Boolean { + return MultiFilter.multiFilter(filter, { matchesSingleFilter(it, viewingCiv) }) + } + + private fun matchesSingleFilter(filter: String, viewingCiv: Civilization? = civ): Boolean { return when (filter) { "in this city" -> true // Filtered by the way uniques are found - "in all cities" -> true - "in all coastal cities" -> isCoastal() - "in capital" -> isCapital() - "in all non-occupied cities" -> !cityStats.hasExtraAnnexUnhappiness() || isPuppet + "in all cities", "All" -> true + "in your cities", "Your" -> viewingCiv == civ + "in all coastal cities", "Coastal" -> isCoastal() + "in capital", "Capital" -> isCapital() + "in all non-occupied cities", "Non-occupied" -> !cityStats.hasExtraAnnexUnhappiness() || isPuppet "in all cities with a world wonder" -> cityConstructions.getBuiltBuildings() .any { it.isWonder } "in all cities connected to capital" -> isConnectedToCapital() - "in all cities with a garrison" -> isGarrisoned() + "in all cities with a garrison", "Garrisoned" -> isGarrisoned() "in all cities in which the majority religion is a major religion" -> religion.getMajorityReligionName() != null && religion.getMajorityReligion()!!.isMajorReligion() @@ -498,18 +504,20 @@ class City : IsPartOfGameInfoSerialization { religion.getMajorityReligionName() != null && religion.getMajorityReligion()!!.isEnhancedReligion() "in non-enemy foreign cities" -> - viewingCiv != civ + viewingCiv != null && viewingCiv != civ && !civ.isAtWarWith(viewingCiv) - "in foreign cities" -> viewingCiv != civ - "in annexed cities" -> foundingCiv != civ.civName && !isPuppet - "in puppeted cities" -> isPuppet - "in holy cities" -> isHolyCity() + "in enemy cities", "Enemy" -> civ.isAtWarWith(viewingCiv ?: civ) + "in foreign cities", "Foreign" -> viewingCiv != null && viewingCiv != civ + "in annexed cities", "Annexed" -> foundingCiv != civ.civName && !isPuppet + "in puppeted cities", "Puppeted" -> isPuppet + "in holy cities", "Holy" -> isHolyCity() "in City-State cities" -> civ.isCityState() // This is only used in communication to the user indicating that only in cities with this // religion a unique is active. However, since religion uniques only come from the city itself, // this will always be true when checked. "in cities following this religion" -> true - else -> false + "in cities following our religion" -> viewingCiv?.religionManager?.religion == religion.getMajorityReligion() + else -> civ.matchesFilter(filter) } } diff --git a/core/src/com/unciv/models/ruleset/unique/Conditionals.kt b/core/src/com/unciv/models/ruleset/unique/Conditionals.kt index 50a8545c8a..63d657a07f 100644 --- a/core/src/com/unciv/models/ruleset/unique/Conditionals.kt +++ b/core/src/com/unciv/models/ruleset/unique/Conditionals.kt @@ -169,7 +169,15 @@ object Conditionals { checkOnGameInfo { getCities().any { it.cityConstructions.containsBuildingOrEquivalent(condition.params[0]) } } // Filtered via city.getMatchingUniques - UniqueType.ConditionalInThisCity -> true + UniqueType.ConditionalInThisCity -> relevantCity != null + UniqueType.ConditionalCityFilter -> checkOnCity { matchesFilter(condition.params[0], relevantCiv) } + UniqueType.ConditionalCityConnected -> checkOnCity { isConnectedToCapital() } + UniqueType.ConditionalCityMajorReligion -> checkOnCity { + religion.getMajorityReligion()?.isMajorReligion() == true } + UniqueType.ConditionalCityEnhancedReligion -> checkOnCity { + religion.getMajorityReligion()?.isEnhancedReligion() == true } + UniqueType.ConditionalCityThisReligion -> checkOnCity { + religion.getMajorityReligion() == relevantCiv?.religionManager?.religion } UniqueType.ConditionalWLTKD -> checkOnCity { isWeLoveTheKingDayActive() } UniqueType.ConditionalCityWithBuilding -> checkOnCity { cityConstructions.containsBuildingOrEquivalent(condition.params[0]) } diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt index b99e54abde..fde3d7c775 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt @@ -236,33 +236,42 @@ enum class UniqueParameterType( /** Implemented by [City.matchesFilter][com.unciv.logic.city.City.matchesFilter] */ CityFilter("cityFilter", "in all cities", null, "City filters") { - private val cityFilterStrings = setOf( + private val knownValues = setOf( "in this city", - "in all cities", - "in all coastal cities", - "in capital", - "in all non-occupied cities", + "in all cities", "All", + "in your cities", "Your", + "in all coastal cities", "Coastal", + "in capital", "Capital", + "in all non-occupied cities", "Non-occupied", "in all cities with a world wonder", "in all cities connected to capital", - "in all cities with a garrison", + "in all cities with a garrison", "Garrisoned", "in all cities in which the majority religion is a major religion", "in all cities in which the majority religion is an enhanced religion", "in non-enemy foreign cities", - "in foreign cities", - "in annexed cities", - "in puppeted cities", - "in holy cities", + "in enemy cities", "Enemy", + "in foreign cities", "Foreign", + "in annexed cities", "Annexed", + "in puppeted cities", "Puppeted", + "in holy cities", "Holy", "in City-State cities", "in cities following this religion", + "in cities following our religion", ) override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): UniqueType.UniqueParameterErrorSeverity? { - if (parameterText in cityFilterStrings) return null + if (parameterText in knownValues) return null return UniqueType.UniqueParameterErrorSeverity.RulesetInvariant } - override fun getTranslationWriterStringsForOutput() = cityFilterStrings + override fun isKnownValue(parameterText: String, ruleset: Ruleset): Boolean { + if (parameterText in knownValues) return true + if (CityFilter.isKnownValue(parameterText, ruleset)) return true + return false + } + + override fun getTranslationWriterStringsForOutput() = knownValues }, /** Used by [BuildingFilter] and e.g. [UniqueType.ConditionalCityWithBuilding] */ diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 9db7f97482..d599e6ef40 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -655,6 +655,11 @@ enum class UniqueType( /////// city conditionals ConditionalInThisCity("in this city", UniqueTarget.Conditional), + ConditionalCityFilter("in [cityFilter] cities", UniqueTarget.Conditional), + ConditionalCityConnected("in cities connected to the capital", UniqueTarget.Conditional), + ConditionalCityMajorReligion("in cities with a major religion", UniqueTarget.Conditional), + ConditionalCityEnhancedReligion("in cities with an enhanced religion", UniqueTarget.Conditional), + ConditionalCityThisReligion("in cities following our religion", 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), diff --git a/docs/Modders/Unique-parameters.md b/docs/Modders/Unique-parameters.md index d7c3ea4fb6..21a06dfe3f 100644 --- a/docs/Modders/Unique-parameters.md +++ b/docs/Modders/Unique-parameters.md @@ -11,7 +11,7 @@ Note that all of these are case-sensitive! ## General Filter Rules -All filters except for `cityFilter` and `populationFilter` accept multiple values in the format: `{A} {B} {C}` etc, meaning "the object must match ALL of these filters" +All filters except for `populationFilter` accept multiple values in the format: `{A} {B} {C}` etc, meaning "the object must match ALL of these filters" > Example: `[{Military} {Water}] units`, `[{Wounded} {Armor}] units`, etc. @@ -111,22 +111,25 @@ cityFilters allow us to choose the range of cities affected by this unique: - `in this city` - `in all cities` -- `in other cities` -- `in all coastal cities` -- `in capital` -- `in all non-occupied cities` - all cities that are not puppets and don't have extra unhappiness from being recently conquered +- `in your cities`, `Your` +- `in all coastal cities`, `Coastal` +- `in capital`, `Capital` +- `in all non-occupied cities`, `Non-occupied` - all cities that are not puppets and don't have extra unhappiness from being recently conquered - `in all cities with a world wonder` - `in all cities connected to capital` -- `in all cities with a garrison` +- `in all cities with a garrison`, `Garrisoned` - `in non-enemy foreign cities` - In all cities owned by civs other than you that you are not at war with -- `in foreign cities` -- `in annexed cities` -- `in puppeted cities` -- `in holy cities` +- `in enemy cities`, `Enemy` +- `in foreign cities`, `Foreign` +- `in annexed cities`, `Annexed` +- `in puppeted cities`, `Puppeted` +- `in holy cities`, `Holy` - `in City-State cities` - `in cities following this religion` - Should only be used in pantheon/follower uniques for religions +- `in cities following our religion` - `in all cities in which the majority religion is a major religion` - `in all cities in which the majority religion is an enhanced religion` +- [civFilter] ## improvementFilter