diff --git a/android/assets/jsons/Civ V - Vanilla/Terrains.json b/android/assets/jsons/Civ V - Vanilla/Terrains.json index 24a53db967..5315da0509 100644 --- a/android/assets/jsons/Civ V - Vanilla/Terrains.json +++ b/android/assets/jsons/Civ V - Vanilla/Terrains.json @@ -251,7 +251,7 @@ "impassable": true, "unbuildable": true, "uniques": ["Must be adjacent to [0] [Coast] tiles", - "Grants Rejuvenation (all healing effects doubled) to adjacent military land units for the rest of the game"], + "Grants [Rejuvenation] ([all healing effects doubled]) to adjacent [{Military} {Land}] units for the rest of the game"], "weight": 1 }, { @@ -404,8 +404,8 @@ "impassable": true, "unbuildable": true, "weight": 10 - } - /* + }, +/* // BNW wonders { "name": "King Solomon's Mines", @@ -424,11 +424,10 @@ "type": "NaturalWonder", "food": 6, "occursOn": ["Plains"], - "uniques": ["Must be adjacent to [0] [Coast] tiles"], "turnsInto": "Mountain", "impassable": true, "unbuildable": true, - "uniques": ["Fresh water"], + "uniques": ["Fresh water","Must be adjacent to [0] [Coast] tiles"], "weight": 10 }, { @@ -443,8 +442,8 @@ "uniques": ["Must be adjacent to [0] [Coast] tiles", "Must be adjacent to [2] to [6] [Hill] tiles", "Must be adjacent to [0] to [2] [Mountain] tiles", - "Grants Altitude Training (double movement and +10% Strength in hills) to adjacent land units for the rest of the game"], //ToDo + "Grants [Altitude Training] ([double movement and +10% Strength in hills]) to adjacent [Land] units for the rest of the game"], "weight": 10 } - */ +*/ ] diff --git a/core/src/com/unciv/Constants.kt b/core/src/com/unciv/Constants.kt index 5d413e32c6..03cec9c80b 100644 --- a/core/src/com/unciv/Constants.kt +++ b/core/src/com/unciv/Constants.kt @@ -35,26 +35,6 @@ object Constants { val vegetation = arrayOf(forest, jungle) val sea = arrayOf(ocean, coast) - const val barringerCrater = "Barringer Crater" - const val grandMesa = "Grand Mesa" - const val greatBarrierReef = "Great Barrier Reef" - const val krakatoa = "Krakatoa" - const val mountFuji = "Mount Fuji" - const val oldFaithful = "Old Faithful" - const val rockOfGibraltar = "Rock of Gibraltar" - const val cerroDePotosi = "Cerro de Potosi" - const val elDorado = "El Dorado" - const val fountainOfYouth = "Fountain of Youth" - const val mountKailash = "Mount Kailash" - const val mountSinai = "Mount Sinai" - const val sriPada = "Sri Pada" - const val uluru = "Uluru" - /* - const val kingSolomonsMines = "King Solomon's Mines" //BNW - const val lakeVictoria = "Lake Victoria" //BNW - const val mountKilimanjaro = "Mount Kilimanjaro" //BNW - */ - const val barbarianEncampment = "Barbarian encampment" const val peaceTreaty = "Peace Treaty" diff --git a/core/src/com/unciv/logic/map/MapUnit.kt b/core/src/com/unciv/logic/map/MapUnit.kt index 43e2cd46ca..f45c27ed0b 100644 --- a/core/src/com/unciv/logic/map/MapUnit.kt +++ b/core/src/com/unciv/logic/map/MapUnit.kt @@ -13,6 +13,7 @@ import com.unciv.models.UnitActionType import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.unique.Unique import com.unciv.models.ruleset.tile.TileImprovement +import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.ruleset.unit.UnitType import com.unciv.ui.utils.toPercent @@ -746,12 +747,14 @@ class MapUnit { if (tile.improvement == Constants.barbarianEncampment && !civInfo.isBarbarian()) clearEncampment(tile) - if (!hasUnique("All healing effects doubled") && baseUnit.isLandUnit() && baseUnit.isMilitary()) { - //todo: Grants [promotion] to adjacent [unitFilter] units for the rest of the game - val gainDoubleHealPromotion = tile.neighbors - .any { it.hasUnique("Grants Rejuvenation (all healing effects doubled) to adjacent military land units for the rest of the game") } - if (gainDoubleHealPromotion && civInfo.gameInfo.ruleSet.unitPromotions.containsKey("Rejuvenation")) - promotions.addPromotion("Rejuvenation", true) + val promotionUniques = tile.neighbors + .flatMap { it.getAllTerrains() } + .flatMap { it.getMatchingUniques(UniqueType.TerrainGrantsPromotion) } + for (unique in promotionUniques) { + if (!this.matchesFilter(unique.params[2])) continue + val promotion = unique.params[0] + if (promotion in promotions.promotions) continue + promotions.addPromotion(promotion, true) } updateVisibleTiles() diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt index be0b646335..f2e14bbeb3 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueParameterType.kt @@ -18,6 +18,10 @@ enum class UniqueParameterType(val parameterName:String) { private val knownValues = setOf("Wounded", "Barbarians", "City-State", "Embarked", "Non-City") override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): UniqueType.UniqueComplianceErrorSeverity? { + if ('{' in parameterText) // "{filter} {filter}" for and logic + return parameterText.removePrefix("{").removeSuffix("}").split("} {") + .mapNotNull { getErrorSeverity(it, ruleset) } + .maxByOrNull { it.ordinal } if (parameterText in knownValues) return null return BaseUnitFilter.getErrorSeverity(parameterText, ruleset) } @@ -91,6 +95,18 @@ enum class UniqueParameterType(val parameterName:String) { return UniqueType.UniqueComplianceErrorSeverity.RulesetSpecific } }, + Promotion("promotion") { + override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): + UniqueType.UniqueComplianceErrorSeverity? = when (parameterText) { + in ruleset.unitPromotions -> null + else -> UniqueType.UniqueComplianceErrorSeverity.RulesetSpecific + } + }, + /** Behaves like [Unknown], but states explicitly the parameter is OK and its contents are ignored */ + Comment("comment") { + override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): + UniqueType.UniqueComplianceErrorSeverity? = null + }, Unknown("param") { override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): UniqueType.UniqueComplianceErrorSeverity? { diff --git a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt index 5068526a2d..70870f1269 100644 --- a/core/src/com/unciv/models/ruleset/unique/UniqueType.kt +++ b/core/src/com/unciv/models/ruleset/unique/UniqueType.kt @@ -97,6 +97,8 @@ enum class UniqueType(val text:String, vararg targets: UniqueTarget) { NaturalWonderConvertNeighbors("Neighboring tiles will convert to [baseTerrain]", UniqueTarget.Terrain), NaturalWonderConvertNeighborsExcept("Neighboring tiles except [terrainFilter] will convert to [baseTerrain]", UniqueTarget.Terrain), + TerrainGrantsPromotion("Grants [promotion] ([comment]) to adjacent [mapUnitFilter] units for the rest of the game", UniqueTarget.Terrain), + ///// CONDITIONALS diff --git a/core/src/com/unciv/models/ruleset/unit/Promotion.kt b/core/src/com/unciv/models/ruleset/unit/Promotion.kt index e52702240f..4a7ba632f9 100644 --- a/core/src/com/unciv/models/ruleset/unit/Promotion.kt +++ b/core/src/com/unciv/models/ruleset/unit/Promotion.kt @@ -3,6 +3,7 @@ package com.unciv.models.ruleset.unit import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.RulesetObject import com.unciv.models.ruleset.unique.UniqueTarget +import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.translations.tr import com.unciv.ui.civilopedia.FormattedLine @@ -111,10 +112,8 @@ class Promotion : RulesetObject() { && it.params[2] == name } } + ruleset.terrains.values.filter { - // once that unique is parameterized, this will be the efficient order of checks - terrain -> terrain.uniques.any { - it == "Grants Rejuvenation (all healing effects doubled) to adjacent military land units for the rest of the game" - && name == "Rejuvenation" + terrain -> terrain.uniqueObjects.any { + it.isOfType(UniqueType.TerrainGrantsPromotion) && name == it.params[0] } } if (grantors.isNotEmpty()) {