From 5d07fd981beaee99aa62d7ee9771754d650bdc7d Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Thu, 23 Feb 2023 21:40:47 +0100 Subject: [PATCH] Allow filters in the ModOptions "ToRemove" lists (#8730) * Allow "*" wildcard in the ModOptions "ToRemove" lists * Allow filters in the ModOptions "ToRemove" lists --- core/src/com/unciv/models/ruleset/Ruleset.kt | 37 ++++++++++++++----- .../com/unciv/models/ruleset/nation/Nation.kt | 12 +++++- .../unciv/models/ruleset/tech/Technology.kt | 10 ++++- docs/Modders/Unique-parameters.md | 23 ++++++++++++ docs/Other/Miscellaneous-JSON-files.md | 30 +++++++-------- 5 files changed, 86 insertions(+), 26 deletions(-) diff --git a/core/src/com/unciv/models/ruleset/Ruleset.kt b/core/src/com/unciv/models/ruleset/Ruleset.kt index f82711a79b..cc689b1787 100644 --- a/core/src/com/unciv/models/ruleset/Ruleset.kt +++ b/core/src/com/unciv/models/ruleset/Ruleset.kt @@ -120,34 +120,53 @@ class Ruleset { fun add(ruleset: Ruleset) { beliefs.putAll(ruleset.beliefs) + ruleset.modOptions.buildingsToRemove + .flatMap { buildingToRemove -> + buildings.filter { it.value.matchesFilter(buildingToRemove) }.keys + }.toSet().forEach { + buildings.remove(it) + } buildings.putAll(ruleset.buildings) - for (buildingToRemove in ruleset.modOptions.buildingsToRemove) buildings.remove( - buildingToRemove - ) difficulties.putAll(ruleset.difficulties) eras.putAll(ruleset.eras) speeds.putAll(ruleset.speeds) globalUniques = GlobalUniques().apply { - uniques.addAll(globalUniques.uniques); uniques.addAll(ruleset.globalUniques.uniques) + uniques.addAll(globalUniques.uniques) + uniques.addAll(ruleset.globalUniques.uniques) } + ruleset.modOptions.nationsToRemove + .flatMap { nationToRemove -> + nations.filter { it.value.matchesFilter(nationToRemove) }.keys + }.toSet().forEach { + nations.remove(it) + } nations.putAll(ruleset.nations) - for (nationToRemove in ruleset.modOptions.nationsToRemove) nations.remove(nationToRemove) policyBranches.putAll(ruleset.policyBranches) policies.putAll(ruleset.policies) quests.putAll(ruleset.quests) religions.addAll(ruleset.religions) ruinRewards.putAll(ruleset.ruinRewards) specialists.putAll(ruleset.specialists) + ruleset.modOptions.techsToRemove + .flatMap { techToRemove -> + technologies.filter { it.value.matchesFilter(techToRemove) }.keys + }.toSet().forEach { + technologies.remove(it) + } technologies.putAll(ruleset.technologies) - for (techToRemove in ruleset.modOptions.techsToRemove) technologies.remove(techToRemove) terrains.putAll(ruleset.terrains) tileImprovements.putAll(ruleset.tileImprovements) tileResources.putAll(ruleset.tileResources) - units.putAll(ruleset.units) unitTypes.putAll(ruleset.unitTypes) victories.putAll(ruleset.victories) cityStateTypes.putAll(ruleset.cityStateTypes) - for (unitToRemove in ruleset.modOptions.unitsToRemove) units.remove(unitToRemove) + ruleset.modOptions.unitsToRemove + .flatMap { unitToRemove -> + units.filter { it.value.matchesFilter(unitToRemove) }.keys + }.toSet().forEach { + units.remove(it) + } + units.putAll(ruleset.units) modOptions.uniques.addAll(ruleset.modOptions.uniques) modOptions.constants.merge(ruleset.modOptions.constants) @@ -565,7 +584,7 @@ object RulesetCache : HashMap() { for (mod in loadedMods.sortedByDescending { it.modOptions.isBaseRuleset }) { if (mod.modOptions.isBaseRuleset) { - // This is so we don't keep using the base ruleset's unqiues *by reference* and add to in ad infinitum + // This is so we don't keep using the base ruleset's uniques *by reference* and add to in ad infinitum newRuleset.modOptions.uniques = ArrayList() newRuleset.modOptions.isBaseRuleset = true } diff --git a/core/src/com/unciv/models/ruleset/nation/Nation.kt b/core/src/com/unciv/models/ruleset/nation/Nation.kt index 4ed10a3634..3dd815786a 100644 --- a/core/src/com/unciv/models/ruleset/nation/Nation.kt +++ b/core/src/com/unciv/models/ruleset/nation/Nation.kt @@ -295,7 +295,17 @@ import kotlin.math.pow } fun getContrastRatio() = getContrastRatio(getInnerColor(), getOuterColor()) -} + + fun matchesFilter(filter: String): Boolean { + return when (filter) { + "All" -> true + name -> true + "Major" -> isMajorCiv() + "CityState" -> isCityState() + else -> uniques.contains(filter) + } + } + } /** All defined by https://www.w3.org/TR/WCAG20/#relativeluminancedef */ diff --git a/core/src/com/unciv/models/ruleset/tech/Technology.kt b/core/src/com/unciv/models/ruleset/tech/Technology.kt index a6bc53a109..d727ba964d 100644 --- a/core/src/com/unciv/models/ruleset/tech/Technology.kt +++ b/core/src/com/unciv/models/ruleset/tech/Technology.kt @@ -1,7 +1,6 @@ package com.unciv.models.ruleset.tech import com.unciv.GUI -import com.unciv.UncivGame import com.unciv.logic.civilization.Civilization import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Ruleset @@ -285,4 +284,13 @@ class Technology: RulesetObject() { return lineList } + + fun matchesFilter(filter: String): Boolean { + return when (filter) { + "All" -> true + name -> true + era() -> true + else -> uniques.contains(filter) + } + } } diff --git a/docs/Modders/Unique-parameters.md b/docs/Modders/Unique-parameters.md index 22b863ee94..1d90a629f7 100644 --- a/docs/Modders/Unique-parameters.md +++ b/docs/Modders/Unique-parameters.md @@ -96,6 +96,18 @@ It can be any value noted in `baseUnitFilter` or one of the following: - `Barbarians`, `Barbarian` - Again, any combination of the above is also allowed, e.g. `[{Wounded} {Water}]` units. +## nationFilter + +At the moment only implemented for [ModOptions.nationsToRemove](../Other/Miscellaneous-JSON-files.md#modoptionsjson). + +Allowed values are: + +- `All` +- `Major` +- `CityState` +- The name of a Nation +- A unique a Nation has (verbatim, no placeholders) + ## populationFilter A filter determining a part of the population of a city. It can be any of the following values: @@ -133,6 +145,17 @@ For example: `+1 Science`. These can be strung together with ", " between them, for example: `+2 Production, +3 Food`. +## technologyFilter + +At the moment only implemented for [ModOptions.techsToRemove](../Other/Miscellaneous-JSON-files.md#modoptionsjson). + +Allowed values are: + +- `All` +- The name of an Era +- The name of a Technology +- A unique a Technology has (verbatim, no placeholders) + ## terrainFilter This indicates the terrain on a single tile. The following values are allowed: diff --git a/docs/Other/Miscellaneous-JSON-files.md b/docs/Other/Miscellaneous-JSON-files.md index 661b788f1b..a0e120d2d9 100644 --- a/docs/Other/Miscellaneous-JSON-files.md +++ b/docs/Other/Miscellaneous-JSON-files.md @@ -108,20 +108,20 @@ This file is a little different: The file can have the following attributes, including the values Unciv sets (no point in a mod author setting those): -| Attribute | Type | Optional | Notes | -| --------- | ---- | -------- | ----- | -| isBaseRuleset | Boolean | false | Differentiates mods that change the vanilla ruleset or replace it | -| maxXPfromBarbarians | Integer | 30 | *Deprecated*, see [constants](#ModConstants) | -| uniques | List | empty | Mod-wide specials, [see here](../Modders/uniques.md#modoptions-uniques) | -| techsToRemove | List | empty | List of [Technologies](Civilization-related-JSON-files.md#techsjson) to remove (isBaseRuleset=false only) | -| buildingsToRemove | List | empty | List of [Buildings or Wonders](Civilization-related-JSON-files.md#buildingsjson) to remove (isBaseRuleset=false only) | -| unitsToRemove | List | empty | List of [Units](Unit-related-JSON-files.md#unitsjson) to remove (isBaseRuleset=false only) | -| nationsToRemove | List | empty | List of [Nations](Civilization-related-JSON-files.md#nationsjson) to remove (isBaseRuleset=false only) | -| lastUpdated | String | empty | Set automatically after download - Last repository update, not necessarily last content change | -| modUrl | String | empty | Set automatically after download - URL of repository | -| author | String | empty | Set automatically after download - Owner of repository | -| modSize | Integer | empty | Set automatically after download - kB in entire repository, not sum of default branch files | -| constants | Object | empty | see [ModConstants](#ModConstants) | +| Attribute | Type | Optional | Notes | +|---------------------|---------|----------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| isBaseRuleset | Boolean | false | Differentiates mods that change the vanilla ruleset or replace it | +| maxXPfromBarbarians | Integer | 30 | *Deprecated*, see [constants](#ModConstants) | +| uniques | List | empty | Mod-wide specials, [see here](../Modders/uniques.md#modoptions-uniques) | +| techsToRemove | List | empty | List of [Technologies](Civilization-related-JSON-files.md#techsjson) or [-filters](../Modders/Unique-parameters.md#technologyfilter) to remove (isBaseRuleset=false only) | +| buildingsToRemove | List | empty | List of [Buildings or Wonders](Civilization-related-JSON-files.md#buildingsjson) or [-filters](../Modders/Unique-parameters.md#buildingfilter) to remove (isBaseRuleset=false only) | +| unitsToRemove | List | empty | List of [Units](Unit-related-JSON-files.md#unitsjson) or [-filters](../Modders/Unique-parameters.md#baseunitfilter) to remove (isBaseRuleset=false only) | +| nationsToRemove | List | empty | List of [Nations](Civilization-related-JSON-files.md#nationsjson) or [-filters](../Modders/Unique-parameters.md#nationfilter) to remove (isBaseRuleset=false only) | +| lastUpdated | String | empty | Set automatically after download - Last repository update, not necessarily last content change | +| modUrl | String | empty | Set automatically after download - URL of repository | +| author | String | empty | Set automatically after download - Owner of repository | +| modSize | Integer | empty | Set automatically after download - kB in entire repository, not sum of default branch files | +| constants | Object | empty | see [ModConstants](#ModConstants) | ### ModConstants @@ -192,7 +192,7 @@ The formula for the gold cost of a unit upgrade is (rounded down to a multiple o ( max((`base` + `perProduction` * (new_unit_cost - old_unit_cost)), 0) * (1 + eraNumber * `eraMultiplier`) * `civModifier` ) ^ `exponent` -With `civModifier` being the multiplicative aggregate of ["\[relativeAmount\]% Gold cost of upgrading"](../uniques.md#global_uniques) uniques that apply. +With `civModifier` being the multiplicative aggregate of ["\[relativeAmount\]% Gold cost of upgrading"](../Modders/uniques.md#global-uniques) uniques that apply. ## VictoryTypes.json