From 928f0df01f2ef4d5ded470cedfa1d70d3c572eb4 Mon Sep 17 00:00:00 2001 From: Jeremy Woo <71725118+woo1127@users.noreply.github.com> Date: Mon, 18 Mar 2024 05:12:40 +0800 Subject: [PATCH] Added multi filter support for BuildingFilter !! (#11319) * Fixed policies do not grant production bonus to wonders * Added multi-filter and tech filter for buildingFilter * Rectification of the uniques of monument to the gods and marbles * Fixed mod checker issued warnings regarding the techFilter in Unit and Building Filters. * Edit Unique-parameters.md * Undo 'Fixed policies do not grant production bonus to Wonders --- .../assets/jsons/Civ V - Gods & Kings/Beliefs.json | 10 ++-------- .../assets/jsons/Civ V - Gods & Kings/Policies.json | 2 +- .../jsons/Civ V - Gods & Kings/TileResources.json | 11 ++++++----- android/assets/jsons/Civ V - Vanilla/Policies.json | 2 +- .../assets/jsons/Civ V - Vanilla/TileResources.json | 7 ++++--- core/src/com/unciv/logic/GameInfo.kt | 3 +++ core/src/com/unciv/models/ruleset/Building.kt | 11 +++++++---- .../models/ruleset/unique/UniqueParameterType.kt | 5 +++-- docs/Modders/Unique-parameters.md | 12 +++++++----- 9 files changed, 34 insertions(+), 29 deletions(-) diff --git a/android/assets/jsons/Civ V - Gods & Kings/Beliefs.json b/android/assets/jsons/Civ V - Gods & Kings/Beliefs.json index b5ed4cf1a2..ee70169c14 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/Beliefs.json +++ b/android/assets/jsons/Civ V - Gods & Kings/Beliefs.json @@ -75,14 +75,8 @@ { "name": "Monument to the Gods", "type": "Pantheon", - "uniques": ["[+15]% Production when constructing [All] wonders [in cities following this religion]"] - // ToDo: Should only be ancient/classical era wonders, but implementing that is another can of worms - // For that we really should need an era.matchesFilter(), so we could write something like: - //"uniques": ["[+15]% Production when constructing [Ancient era] wonders [in cities following this religion]", - // "[+15]% Production when constructing [Classical era] wonders [in cities following this religion]"] - // For now this feels like overkill, but I'll leave this here for the future - - // Alternatively, we could approximate this with "[+15]% Production when constructing [All] wonders [in all cities] " + "uniques": ["[+15]% Production when constructing [Ancient era] wonders [in cities following this religion]", + "[+15]% Production when constructing [Classical era] wonders [in cities following this religion]"] }, { "name": "One with Nature", diff --git a/android/assets/jsons/Civ V - Gods & Kings/Policies.json b/android/assets/jsons/Civ V - Gods & Kings/Policies.json index c90dcc8b6a..d93be0733b 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/Policies.json +++ b/android/assets/jsons/Civ V - Gods & Kings/Policies.json @@ -84,7 +84,7 @@ "name": "Republic", "uniques": [ "[+1 Production] [in all cities]", - "[+5]% Production when constructing [All] buildings [in all cities]" + "[+5]% Production when constructing [All] buildings [in all cities]", ], "row": 1, "column": 1 diff --git a/android/assets/jsons/Civ V - Gods & Kings/TileResources.json b/android/assets/jsons/Civ V - Gods & Kings/TileResources.json index 5b22cae1eb..d0226667ee 100644 --- a/android/assets/jsons/Civ V - Gods & Kings/TileResources.json +++ b/android/assets/jsons/Civ V - Gods & Kings/TileResources.json @@ -1,4 +1,4 @@ -[ +[ // Bonus resources { "name": "Cattle", @@ -84,7 +84,7 @@ "improvementStats": {"production": 1} }, */ - + // Strategic resources { "name": "Horses", @@ -207,7 +207,7 @@ "majorDepositAmount": {"sparse": 2, "default": 4, "abundant": 4}, "minorDepositAmount": {"sparse": 1, "default": 2, "abundant": 3} }, - + // Luxury resources { "name": "Furs", @@ -371,7 +371,8 @@ "gold": 2, "improvement": "Quarry", "improvementStats": {"production": 1}, - "uniques": ["[+15]% Production when constructing [All] wonders [in all cities]", + "uniques": ["[+15]% Production when constructing [Ancient era] wonders [in this city]", + "[+15]% Production when constructing [Classical era] wonders [in this city]", "Special placement during map generation", "Doesn't generate naturally "] }, @@ -449,7 +450,7 @@ "Doesn't generate naturally ", "Doesn't generate naturally "] }, - /* + /* { "name": "Cocoa", "resourceType": "Luxury", diff --git a/android/assets/jsons/Civ V - Vanilla/Policies.json b/android/assets/jsons/Civ V - Vanilla/Policies.json index 9c99b811d3..3640af692b 100644 --- a/android/assets/jsons/Civ V - Vanilla/Policies.json +++ b/android/assets/jsons/Civ V - Vanilla/Policies.json @@ -103,7 +103,7 @@ "name": "Republic", "uniques": [ "[+1 Production] [in all cities]", - "[+5]% Production when constructing [All] buildings [in all cities]" + "[+5]% Production when constructing [All] buildings [in all cities]", ], "requires": ["Collective Rule"], "row": 2, diff --git a/android/assets/jsons/Civ V - Vanilla/TileResources.json b/android/assets/jsons/Civ V - Vanilla/TileResources.json index 2d958eb7f3..ffb83e6577 100644 --- a/android/assets/jsons/Civ V - Vanilla/TileResources.json +++ b/android/assets/jsons/Civ V - Vanilla/TileResources.json @@ -1,4 +1,4 @@ -[ +[ // Bonus resources { "name": "Cattle", @@ -86,7 +86,7 @@ "improvementStats": {"food": 1} }, */ - + // Strategic resources { "name": "Horses", @@ -384,7 +384,8 @@ "gold": 2, "improvement": "Quarry", "improvementStats": {"production": 1}, - "uniques": ["[+15]% Production when constructing [All] wonders [in all cities]", + "uniques": ["[+15]% Production when constructing [Ancient era] wonders [in this city]", + "[+15]% Production when constructing [Classical era] wonders [in this city]", "Special placement during map generation", "Doesn't generate naturally "] }, diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 24744bc5ab..9c2742ee92 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -621,6 +621,9 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion for (baseUnit in ruleset.units.values) baseUnit.ruleset = ruleset + for (building in ruleset.buildings.values) + building.ruleset = ruleset + // This needs to go before tileMap.setTransients, as units need to access // the nation of their civilization when setting transients for (civInfo in civilizations) civInfo.gameInfo = this diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index aaa0e6e0dd..9d11b71718 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -54,6 +54,8 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { var quote: String = "" var replacementTextForUniques = "" + lateinit var ruleset: Ruleset + override fun getUniqueTarget() = if (isAnyWonder()) UniqueTarget.Wonder else UniqueTarget.Building override fun makeLink() = if (isAnyWonder()) "Wonder/$name" else "Building/$name" @@ -510,14 +512,15 @@ class Building : RulesetStatsObject(), INonPerpetualConstruction { name -> true "Building", "Buildings" -> !isAnyWonder() "Wonder", "Wonders" -> isAnyWonder() - "National Wonder" -> isNationalWonder - "World Wonder" -> isWonder + "National Wonder", "National" -> isNationalWonder + "World Wonder", "World" -> isWonder replaces -> true else -> { if (uniques.contains(filter)) return true + for (requiredTech: String in requiredTechs()) + if (ruleset.technologies[requiredTech]?.matchesFilter(filter) == true) return true val stat = Stat.safeValueOf(filter) - if (stat != null && isStatRelated(stat)) return true - return false + return (stat != null && isStatRelated(stat)) } } } diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt index 8a0ded365e..befc2e2b4c 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt @@ -128,6 +128,7 @@ enum class UniqueParameterType( if (UnitName.getErrorSeverity(parameterText, ruleset) == null) return true if (ruleset.units.values.any { it.uniques.contains(parameterText) }) return true if (UnitTypeFilter.isKnownValue(parameterText, ruleset)) return true + if (TechFilter.isKnownValue(parameterText, ruleset)) return true return false } @@ -145,7 +146,6 @@ enum class UniqueParameterType( override fun isKnownValue(parameterText: String, ruleset: Ruleset): Boolean { if (parameterText in knownValues) return true if (ruleset.unitTypes.containsKey(parameterText)) return true - if (ruleset.eras.containsKey(parameterText)) return true if (ruleset.unitTypes.values.any { it.uniques.contains(parameterText) }) return true return false } @@ -287,7 +287,7 @@ enum class UniqueParameterType( /** Implemented by [Building.matchesFilter][com.unciv.models.ruleset.Building.matchesFilter] */ BuildingFilter("buildingFilter", "Culture") { - private val knownValues = mutableSetOf("Building", "Buildings", "Wonder", "Wonders", "National Wonder", "World Wonder") + private val knownValues = mutableSetOf("Building", "Buildings", "Wonder", "Wonders", "National Wonder", "National", "World Wonder", "World") .apply { addAll(Stat.names()); addAll(Constants.all) } override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): @@ -297,6 +297,7 @@ enum class UniqueParameterType( if (parameterText in knownValues) return true if (BuildingName.getErrorSeverity(parameterText, ruleset) == null) return true if (ruleset.buildings.values.any { it.hasUnique(parameterText) }) return true + if (TechFilter.isKnownValue(parameterText, ruleset)) return true return false } diff --git a/docs/Modders/Unique-parameters.md b/docs/Modders/Unique-parameters.md index 576d40bc5b..47c31a43c2 100644 --- a/docs/Modders/Unique-parameters.md +++ b/docs/Modders/Unique-parameters.md @@ -72,7 +72,7 @@ The following are allowed to be used: - Matching [technologyfilter](#technologyfilter) for the tech this unit requires - e.g. `Modern Era` - Any exact unique the unit has - Any exact unique the unit type has -- Any combination of the above (will match only if all match). The format is `{filter1} {filter2}` and can match any number of filters. For example: ` +- Any combination of the above (will match only if all match). The format is `{filter1} {filter2}` and can match any number of filters. For example: `[{Modern era} {Land}]` units ## mapUnitFilter @@ -93,17 +93,19 @@ Allows to only activate a unique for certain buildings. Allowed options are: - `All` - `Buildings`, `Building` -- `Wonders`, `Wonders` -- `National Wonder` -- `World Wonder` -- All wonders that are not national wonders +- `Wonder`, `Wonders` +- `National Wonder`, `National` +- `World Wonder`, `World` -- All wonders that are not national wonders - building name - The name of the building it replaces (so for example uniques for libraries will apply to paper makers as well) -- an exact unique the building has (e.g.: `spaceship part`) +- Matching [technologyfilter](#technologyfilter) for the tech this building requires - e.g. Modern Era +- An exact unique the building has (e.g.: `spaceship part`) - `Culture`, `Gold`, etc. if the building is `stat-related` for that stat. Stat-related buildings are defined as one of the following: - Provides that stat directly (e.g. +1 Culture) - Provides a percentage bonus for that stat (e.g. +10% Production) - Provides that stat as a bonus for resources (e.g. +1 Food from every Wheat) - Provides that stat per some amount of population (e.g. +1 Science for every 2 population [cityFilter]) +- Any combination of the above (will match only if all match). The format is `{filter1} {filter2}` up to any number of filters. For example `[{Ancient era} {Food}]` buildings. ## cityFilter