Add a filter for religions (#13016)

* Add a filter for religions

* whoops

* Convert if chain to jvm switch statement

* Introduce inverse conditional

* Irrelevant optimization: Checking if it is in the ruleset and returning null it unnecessary with mapNotNull

* Add belief names to filter

* Docs
This commit is contained in:
SeventhM 2025-03-06 10:20:36 -08:00 committed by GitHub
parent 7c8479326c
commit 72418972fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 67 additions and 4 deletions

View File

@ -2,8 +2,11 @@ package com.unciv.models
import com.unciv.logic.GameInfo import com.unciv.logic.GameInfo
import com.unciv.logic.IsPartOfGameInfoSerialization import com.unciv.logic.IsPartOfGameInfoSerialization
import com.unciv.logic.MultiFilter
import com.unciv.logic.civilization.Civilization
import com.unciv.models.ruleset.Belief import com.unciv.models.ruleset.Belief
import com.unciv.models.ruleset.BeliefType import com.unciv.models.ruleset.BeliefType
import com.unciv.models.ruleset.unique.StateForConditionals
import com.unciv.models.ruleset.unique.UniqueMap import com.unciv.models.ruleset.unique.UniqueMap
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.INamed import com.unciv.models.stats.INamed
@ -76,10 +79,7 @@ class Religion() : INamed, IsPartOfGameInfoSerialization {
private fun mapToExistingBeliefs(beliefs: Set<String>): Sequence<Belief> { private fun mapToExistingBeliefs(beliefs: Set<String>): Sequence<Belief> {
val rulesetBeliefs = gameInfo.ruleset.beliefs val rulesetBeliefs = gameInfo.ruleset.beliefs
return beliefs.asSequence().mapNotNull { return beliefs.asSequence().mapNotNull { rulesetBeliefs[it] }
if (it !in rulesetBeliefs) null
else rulesetBeliefs[it]!!
}
} }
fun getBeliefs(beliefType: BeliefType): Sequence<Belief> { fun getBeliefs(beliefType: BeliefType): Sequence<Belief> {
@ -114,6 +114,32 @@ class Religion() : INamed, IsPartOfGameInfoSerialization {
fun getFounder() = gameInfo.getCivilization(foundingCivName) fun getFounder() = gameInfo.getCivilization(foundingCivName)
fun matchesFilter(filter: String, state: StateForConditionals = StateForConditionals.IgnoreConditionals, civ: Civilization? = null): Boolean {
return MultiFilter.multiFilter(filter, { matchesSingleFilter(it, state, civ) })
}
private fun matchesSingleFilter(filter: String, state: StateForConditionals = StateForConditionals.IgnoreConditionals, civ: Civilization? = null): Boolean {
val foundingCiv = getFounder()
when (filter) {
"any" -> return true
"major" -> return isMajorReligion()
"enhanced" -> return isEnhancedReligion()
"your" -> return civ == foundingCiv
"foreign" -> return civ != null && civ != foundingCiv
"enemy" -> {
val known = civ != null && civ.knows(foundingCiv)
return known && civ!!.isAtWarWith(foundingCiv)
}
else -> {
if (filter == name) return true
if (filter in getBeliefs(BeliefType.Any).map { it.name }) return true
if (founderBeliefUniqueMap.hasMatchingUnique(filter, state)) return true
if (followerBeliefUniqueMap.hasMatchingUnique(filter, state)) return true
return false
}
}
}
private fun unlockedBuildingsPurchasable(): List<String> { private fun unlockedBuildingsPurchasable(): List<String> {
return getAllBeliefsOrdered().flatMap { belief -> return getAllBeliefsOrdered().flatMap { belief ->
belief.getMatchingUniques(UniqueType.BuyBuildingsWithStat).map { it.params[0] } + belief.getMatchingUniques(UniqueType.BuyBuildingsWithStat).map { it.params[0] } +

View File

@ -194,6 +194,14 @@ object Conditionals {
UniqueType.ConditionalInThisCity -> state.relevantCity != null UniqueType.ConditionalInThisCity -> state.relevantCity != null
UniqueType.ConditionalCityFilter -> checkOnCity { matchesFilter(conditional.params[0], state.relevantCiv) } UniqueType.ConditionalCityFilter -> checkOnCity { matchesFilter(conditional.params[0], state.relevantCiv) }
UniqueType.ConditionalCityConnected -> checkOnCity { isConnectedToCapital() } UniqueType.ConditionalCityConnected -> checkOnCity { isConnectedToCapital() }
UniqueType.ConditionalCityReligion -> checkOnCity {
religion.getMajorityReligion()
?.matchesFilter(conditional.params[0], state, state.relevantCiv) == true
}
UniqueType.ConditionalCityNotReligion -> checkOnCity {
religion.getMajorityReligion()
?.matchesFilter(conditional.params[0], state, state.relevantCiv) != true
}
UniqueType.ConditionalCityMajorReligion -> checkOnCity { UniqueType.ConditionalCityMajorReligion -> checkOnCity {
religion.getMajorityReligion()?.isMajorReligion() == true } religion.getMajorityReligion()?.isMajorReligion() == true }
UniqueType.ConditionalCityEnhancedReligion -> checkOnCity { UniqueType.ConditionalCityEnhancedReligion -> checkOnCity {

View File

@ -510,6 +510,19 @@ enum class UniqueParameterType(
Belief("belief", "God of War", "The name of any belief") { Belief("belief", "God of War", "The name of any belief") {
override fun getKnownValuesForAutocomplete(ruleset: Ruleset) = ruleset.beliefs.keys override fun getKnownValuesForAutocomplete(ruleset: Ruleset) = ruleset.beliefs.keys
}, },
/**Used by [UniqueType.ConditionalCityReligion]*/
ReligionFilter("religionFilter", "major") {
override val staticKnownValues = setOf("any", "major", "enhanced", "your", "foreign","enemy")
override fun isKnownValue(parameterText: String, ruleset: Ruleset): Boolean {
return when (parameterText) {
in staticKnownValues -> true
in ruleset.religions -> true
in ruleset.beliefs -> true
else -> ruleset.beliefs.values.any { it.hasTagUnique(parameterText) }
}
}
},
/** Used by [UniqueType.FreeExtraBeliefs] and its any variant, see ReligionManager.getBeliefsToChooseAt* functions */ /** Used by [UniqueType.FreeExtraBeliefs] and its any variant, see ReligionManager.getBeliefsToChooseAt* functions */
FoundingOrEnhancing("foundingOrEnhancing", "founding", "`founding` or `enhancing`", "Prophet Action Filters", FoundingOrEnhancing("foundingOrEnhancing", "founding", "`founding` or `enhancing`", "Prophet Action Filters",

View File

@ -742,6 +742,8 @@ enum class UniqueType(
ConditionalInThisCity("in this city", UniqueTarget.Conditional), ConditionalInThisCity("in this city", UniqueTarget.Conditional),
ConditionalCityFilter("in [cityFilter] cities", UniqueTarget.Conditional), ConditionalCityFilter("in [cityFilter] cities", UniqueTarget.Conditional),
ConditionalCityConnected("in cities connected to the capital", UniqueTarget.Conditional), ConditionalCityConnected("in cities connected to the capital", UniqueTarget.Conditional),
ConditionalCityReligion("in cities with a [religionFilter] religion", UniqueTarget.Conditional),
ConditionalCityNotReligion("in cities not following a [religionFilter] religion", UniqueTarget.Conditional),
ConditionalCityMajorReligion("in cities with a major religion", UniqueTarget.Conditional), ConditionalCityMajorReligion("in cities with a major religion", UniqueTarget.Conditional),
ConditionalCityEnhancedReligion("in cities with an enhanced religion", UniqueTarget.Conditional), ConditionalCityEnhancedReligion("in cities with an enhanced religion", UniqueTarget.Conditional),
ConditionalCityThisReligion("in cities following our religion", UniqueTarget.Conditional), ConditionalCityThisReligion("in cities following our religion", UniqueTarget.Conditional),

View File

@ -171,6 +171,20 @@ Allowed values:
- `Followers of the Majority Religion` or `Followers of this Religion`, both of which only apply when this religion is the majority religion in that city - `Followers of the Majority Religion` or `Followers of this Religion`, both of which only apply when this religion is the majority religion in that city
- Specialist names - Specialist names
## religionFilter
For filtering specific relgions
- `any`
- `major`
- `enhanced`
- `your`
- `foriegn`
- `enemy`
- The name of a relgion symbol
- The name of a belief
- A unique of a belief the religion has
## policyFilter ## policyFilter
Allowed values: Allowed values: