From af9e691102bd09459e2ac03f0fb0285cf5af7a12 Mon Sep 17 00:00:00 2001 From: yairm210 Date: Fri, 17 Sep 2021 10:33:53 +0300 Subject: [PATCH] Ease of deprecation, brought to you by unique types! *Visible*, locatable deprecated uniques! Stated replacement uniques! --- .../assets/jsons/Civ V - Vanilla/Nations.json | 6 +++-- .../jsons/Civ V - Vanilla/Policies.json | 2 +- .../unciv/logic/civilization/CivInfoStats.kt | 17 ++++++++---- core/src/com/unciv/models/ruleset/Unique.kt | 26 ++++++++++++------- 4 files changed, 33 insertions(+), 18 deletions(-) diff --git a/android/assets/jsons/Civ V - Vanilla/Nations.json b/android/assets/jsons/Civ V - Vanilla/Nations.json index 8197a18549..50283ba95e 100644 --- a/android/assets/jsons/Civ V - Vanilla/Nations.json +++ b/android/assets/jsons/Civ V - Vanilla/Nations.json @@ -337,7 +337,8 @@ "outerColor": [150,150,150], "innerColor": [60,60,60], "uniqueName": "Furor Teutonicus", - "uniques": ["67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment", "-[25]% [Land] unit maintenance costs"], + "uniques": ["67% chance to earn 25 Gold and recruit a Barbarian unit from a conquered encampment", + "[-25]% maintenance costs for [Land] units"], "cities": ["Berlin","Hamburg","Munich","Cologne","Frankfurt","Essen","Dortmund","Stuttgart","Düsseldorf","Bremen", "Hannover","Duisburg","Leipzig","Dresden","Bonn","Bochum","Bielefeld","Karlsruhe","Gelsenkirchen","Wiesbaden", "Münster","Rostock","Chemnitz","Braunschweig","Halle","Mönchengladbach","Kiel","Wuppertal","Freiburg","Hagen", @@ -366,7 +367,8 @@ "outerColor": [245,248,185], "innerColor": [18,84,30], "uniqueName": "Barbary Corsairs", - "uniques": ["-[66]% [Water] unit maintenance costs", "50% chance of capturing defeated Barbarian naval units and earning 25 Gold"], + "uniques": ["[-66]% maintenance costs for [Water] units", + "50% chance of capturing defeated Barbarian naval units and earning 25 Gold"], "cities": ["Istanbul","Edirne","Ankara","Bursa","Konya","Samsun","Gaziantep","Diyarbakır","Izmir","Kayseri","Malatya", "Mersin","Antalya","Zonguldak","Denizli","Ordu","Muğla","Eskişehir","Inebolu","Sinop","Adana","Artvin", "Bodrum","Eregli","Silifke","Sivas","Amasya","Marmaris","Trabzon","Erzurum","Urfa","Izmit","Afyonkarahisar", diff --git a/android/assets/jsons/Civ V - Vanilla/Policies.json b/android/assets/jsons/Civ V - Vanilla/Policies.json index 63a3af3c6c..443ff96ac3 100644 --- a/android/assets/jsons/Civ V - Vanilla/Policies.json +++ b/android/assets/jsons/Civ V - Vanilla/Policies.json @@ -367,7 +367,7 @@ { "name": "Autocracy", "era": "Industrial era", - "uniques": ["-[33]% unit upkeep costs", "Upon capturing a city, receive [10] times its [Culture] production as [Culture] immediately", + "uniques": ["[-33]% maintenance costs for [All] units", "Upon capturing a city, receive [10] times its [Culture] production as [Culture] immediately", "Incompatible with [Order]", "Incompatible with [Freedom]"], "policies": [ { diff --git a/core/src/com/unciv/logic/civilization/CivInfoStats.kt b/core/src/com/unciv/logic/civilization/CivInfoStats.kt index ae9f56e089..d3f89c18a1 100644 --- a/core/src/com/unciv/logic/civilization/CivInfoStats.kt +++ b/core/src/com/unciv/logic/civilization/CivInfoStats.kt @@ -37,8 +37,7 @@ class CivInfoStats(val civInfo: CivilizationInfo) { var numberOfUnitsToPayFor = max(0f, unitsToPayFor.count().toFloat() - freeUnits) - - for (unique in civInfo.getMatchingUniques("-[]% [] unit maintenance costs")) { + for (unique in civInfo.getMatchingUniquesByEnum(UniqueType.UnitMaintenanceDiscount)) { val numberOfUnitsWithDiscount = min( numberOfUnitsToPayFor, unitsToPayFor.count { it.matchesFilter(unique.params[1]) }.toFloat() @@ -46,6 +45,17 @@ class CivInfoStats(val civInfo: CivilizationInfo) { numberOfUnitsToPayFor -= numberOfUnitsWithDiscount * unique.params[0].toFloat() / 100f } + for (unique in civInfo.getMatchingUniquesByEnum(UniqueType.DecreasedUnitMaintenanceCostsByFilter)) { + val numberOfUnitsWithDiscount = min( + numberOfUnitsToPayFor, + unitsToPayFor.count { it.matchesFilter(unique.params[1]) }.toFloat() + ) + numberOfUnitsToPayFor -= numberOfUnitsWithDiscount * unique.params[0].toFloat() / 100f + } + for (unique in civInfo.getMatchingUniquesByEnum(UniqueType.DecreasedUnitMaintenanceCostsGlobally)) { + numberOfUnitsToPayFor *= 1f - unique.params[0].toFloat() / 100f + } + val turnLimit = BASE_GAME_DURATION_TURNS * civInfo.gameInfo.gameParameters.gameSpeed.modifier val gameProgress = @@ -55,9 +65,6 @@ class CivInfoStats(val civInfo: CivilizationInfo) { if (!civInfo.isPlayerCivilization()) cost *= civInfo.gameInfo.getDifficulty().aiUnitMaintenanceModifier - for (unique in civInfo.getMatchingUniques("-[]% unit upkeep costs")) { - cost *= 1f - unique.params[0].toFloat() / 100f - } return cost.toInt() } diff --git a/core/src/com/unciv/models/ruleset/Unique.kt b/core/src/com/unciv/models/ruleset/Unique.kt index 982d73ed47..4314ab92d6 100644 --- a/core/src/com/unciv/models/ruleset/Unique.kt +++ b/core/src/com/unciv/models/ruleset/Unique.kt @@ -9,7 +9,7 @@ import com.unciv.models.translations.getPlaceholderText // Eventually we'll merge the translation generation to take this as the source of that enum class UniqueParameterType(val parameterName:String) { Number("amount") { - override fun getErrorType(parameterText: String, ruleset: Ruleset): + override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): UniqueType.UniqueComplianceErrorSeverity? { return if (parameterText.toIntOrNull() == null) UniqueType.UniqueComplianceErrorSeverity.RulesetInvariant else null @@ -17,18 +17,18 @@ enum class UniqueParameterType(val parameterName:String) { }, MapUnitFilter("mapUnitFilter"){ val knownValues = setOf("Wounded", "Barbarians", "City-State", "Embarked", "Non-City") - override fun getErrorType(parameterText: String, ruleset: Ruleset): + override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): UniqueType.UniqueComplianceErrorSeverity? { if (parameterText in knownValues) return null - return BaseUnitFilter.getErrorType(parameterText, ruleset) + return BaseUnitFilter.getErrorSeverity(parameterText, ruleset) } }, BaseUnitFilter("baseUnitFilter"){ // As you can see there is a difference between these and what's in unitTypeStrings (for translation) - // the goal is to unify, but for now this is the "real" list - val knownValues = setOf("Melee", "Ranged", "Civilian", "Military", "Land", "Water", "Air", + val knownValues = setOf("All", "Melee", "Ranged", "Civilian", "Military", "Land", "Water", "Air", "non-air", "Nuclear Weapon", "Great Person", "Religious") - override fun getErrorType(parameterText: String, ruleset: Ruleset): + override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): UniqueType.UniqueComplianceErrorSeverity? { if (parameterText in knownValues) return null if (ruleset.unitTypes.containsKey(parameterText)) return null @@ -41,13 +41,13 @@ enum class UniqueParameterType(val parameterName:String) { } }, Unknown("param") { - override fun getErrorType(parameterText: String, ruleset: Ruleset): + override fun getErrorSeverity(parameterText: String, ruleset: Ruleset): UniqueType.UniqueComplianceErrorSeverity? { return null } }; - abstract fun getErrorType(parameterText:String, ruleset: Ruleset): UniqueType.UniqueComplianceErrorSeverity? + abstract fun getErrorSeverity(parameterText:String, ruleset: Ruleset): UniqueType.UniqueComplianceErrorSeverity? companion object { val unitTypeStrings = hashSetOf( @@ -76,10 +76,16 @@ class UniqueComplianceError( ) -enum class UniqueType(val text:String) { +enum class UniqueType(val text:String, val replacedBy: UniqueType? = null) { ConsumesResources("Consumes [amount] [resource]"), - FreeUnits("[amount] units cost no maintenance"); + FreeUnits("[amount] units cost no maintenance"), + UnitMaintenanceDiscount("[amount]% maintenance costs for [mapUnitFilter] units"), + @Deprecated("As of 3.16.16") + DecreasedUnitMaintenanceCostsByFilter("-[amount]% [mapUnitFilter] unit maintenance costs", UnitMaintenanceDiscount), + @Deprecated("As of 3.16.16") + DecreasedUnitMaintenanceCostsGlobally("-[amount]% unit upkeep costs", UnitMaintenanceDiscount), + ; /** For uniques that have "special" parameters that can accept multiple types, we can override them manually * For 95% of cases, auto-matching is fine. */ @@ -118,7 +124,7 @@ enum class UniqueType(val text:String) { for ((index, param) in unique.params.withIndex()) { val acceptableParamTypes = parameterTypeMap[index] val errorTypesForAcceptableParameters = - acceptableParamTypes.map { it.getErrorType(param, ruleset) } + acceptableParamTypes.map { it.getErrorSeverity(param, ruleset) } if (errorTypesForAcceptableParameters.any { it == null }) continue // This matches one of the types! val leastSevereWarning = errorTypesForAcceptableParameters.maxByOrNull { it!!.ordinal }!!