From ecd6cd92a4d4995df9822509d635c1cb1d4f4e8e Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Tue, 17 Aug 2021 13:00:01 +0200 Subject: [PATCH] City screen purchasable constructions prettier (#4822) * City screen purchasable constructions prettier * City screen purchasable constructions prettier - patch1 * City screen purchasable constructions prettier - mad modder edition --- .../jsons/Civ V - Vanilla/Buildings.json | 5 +- .../com/unciv/logic/city/CityConstructions.kt | 20 ++++--- core/src/com/unciv/models/ruleset/Building.kt | 52 +++++++++---------- .../com/unciv/models/ruleset/unit/BaseUnit.kt | 4 +- core/src/com/unciv/models/stats/Stat.kt | 23 ++++---- .../ui/cityscreen/ConstructionInfoTable.kt | 3 +- 6 files changed, 60 insertions(+), 47 deletions(-) diff --git a/android/assets/jsons/Civ V - Vanilla/Buildings.json b/android/assets/jsons/Civ V - Vanilla/Buildings.json index f7d472202c..6bc756742f 100644 --- a/android/assets/jsons/Civ V - Vanilla/Buildings.json +++ b/android/assets/jsons/Civ V - Vanilla/Buildings.json @@ -1132,8 +1132,9 @@ "cost": 0, "culture": 2, "faith": 2, - "uniques": ["[+1 Culture, +1 Faith] from [Wine] tiles [in this city]", "Hidden when religion is disabled", - "[+1 Culture, +1 Faith] from [Incense] tiles [in this city]","Unbuildable"] + "uniques": ["[+1 Culture, +1 Faith] from [Wine] tiles [in this city]", + "[+1 Culture, +1 Faith] from [Incense] tiles [in this city]", + "Unbuildable", "Hidden when religion is disabled"] }, { "name": "Mosque", diff --git a/core/src/com/unciv/logic/city/CityConstructions.kt b/core/src/com/unciv/logic/city/CityConstructions.kt index 4bc61abc9e..7849b2662a 100644 --- a/core/src/com/unciv/logic/city/CityConstructions.kt +++ b/core/src/com/unciv/logic/city/CityConstructions.kt @@ -153,16 +153,24 @@ class CityConstructions { } - /** @constructionName needs to be a non-perpetual construction, else a cost of -1 is inferred */ + /** @constructionName needs to be a non-perpetual construction, else an empty string is returned */ internal fun getTurnsToConstructionString(constructionName: String, useStoredProduction:Boolean = true): String { val construction = getConstruction(constructionName) - val cost = - if (construction is INonPerpetualConstruction) construction.getProductionCost(cityInfo.civInfo) - else -1 // This could _should_ never be reached + if (construction !is INonPerpetualConstruction) return "" // shouldn't happen + val cost = construction.getProductionCost(cityInfo.civInfo) val turnsToConstruction = turnsToConstruction(constructionName, useStoredProduction) val currentProgress = if (useStoredProduction) getWorkDone(constructionName) else 0 - if (currentProgress == 0) return "\n$cost${Fonts.production} $turnsToConstruction${Fonts.turn}" - else return "\n$currentProgress/$cost${Fonts.production}\n$turnsToConstruction${Fonts.turn}" + val lines = ArrayList() + val buildable = construction.uniques.none{ it == "Unbuildable" } + if (buildable) + lines += (if (currentProgress == 0) "" else "$currentProgress/") + + "$cost${Fonts.production} $turnsToConstruction${Fonts.turn}" + val otherStats = Stat.values().filter { + (it != Stat.Gold || !buildable) && // Don't show rush cost for consistency + construction.canBePurchasedWithStat(cityInfo, it) + }.joinToString(" / ") { "${construction.getStatBuyCost(cityInfo, it)}${it.character}" } + if (otherStats.isNotEmpty()) lines += otherStats + return lines.joinToString("\n", "\n") } // This function appears unused, can it be removed? diff --git a/core/src/com/unciv/models/ruleset/Building.kt b/core/src/com/unciv/models/ruleset/Building.kt index 43391daf6a..1ab4fbf0f7 100644 --- a/core/src/com/unciv/models/ruleset/Building.kt +++ b/core/src/com/unciv/models/ruleset/Building.kt @@ -86,7 +86,7 @@ class Building : NamedStats(), INonPerpetualConstruction, ICivilopediaText { infoList += "Requires worked [" + requiredNearbyImprovedResources!!.joinToString("/") { it.tr() } + "] near city" if (uniques.isNotEmpty()) { if (replacementTextForUniques != "") infoList += replacementTextForUniques - else infoList += getUniquesStrings() + else infoList += getUniquesStringsWithoutDisablers() } if (cityStrength != 0) infoList += "{City strength} +$cityStrength" if (cityHealth != 0) infoList += "{City health} +$cityHealth" @@ -113,48 +113,46 @@ class Building : NamedStats(), INonPerpetualConstruction, ICivilopediaText { if (value.size == 1) value[0] else value.joinToString { it.tr() } )) } + private fun getUniquesStringsWithoutDisablers() = getUniquesStrings() + .filterNot { it.startsWith("Hidden ") && it.endsWith(" disabled") || it == "Unbuildable" } + /** used in CityScreen (CityInfoTable and ConstructionInfoTable) */ fun getDescription(cityInfo: CityInfo?, ruleset: Ruleset): String { val stats = getStats(cityInfo) - val stringBuilder = StringBuilder() - if (uniqueTo != null) stringBuilder.appendLine("Unique to [$uniqueTo], replaces [$replaces]".tr()) - if (isWonder) stringBuilder.appendLine("Wonder".tr()) - if (isNationalWonder) stringBuilder.appendLine("National Wonder".tr()) + val lines = ArrayList() + if (uniqueTo != null) lines += "Unique to [$uniqueTo], replaces [$replaces]" + if (isWonder) lines += "Wonder" + if (isNationalWonder) lines += "National Wonder" for ((resource, amount) in getResourceRequirements()) { - if (amount == 1) stringBuilder.appendLine("Consumes 1 [$resource]".tr()) // For now, to keep the existing translations - else stringBuilder.appendLine("Consumes [$amount] [$resource]".tr()) + lines += if (amount == 1) "Consumes 1 [$resource]" // For now, to keep the existing translations + else "Consumes [$amount] [$resource]" } if (providesFreeBuilding != null) - stringBuilder.appendLine("Provides a free [$providesFreeBuilding] in the city".tr()) + lines += "Provides a free [$providesFreeBuilding] in the city" if (uniques.isNotEmpty()) { - if (replacementTextForUniques != "") stringBuilder.appendLine(replacementTextForUniques) - else stringBuilder.appendLine(getUniquesStrings().map { it.tr() }.joinToString("\n")) + if (replacementTextForUniques != "") lines += replacementTextForUniques + else lines += getUniquesStringsWithoutDisablers() } if (!stats.isEmpty()) - stringBuilder.appendLine(stats.toString()) + lines += stats.toString() - val percentStats = getStatPercentageBonuses(cityInfo) - if (percentStats.production != 0f) stringBuilder.append("+" + percentStats.production.toInt() + "% {Production}\n".tr()) - if (percentStats.gold != 0f) stringBuilder.append("+" + percentStats.gold.toInt() + "% {Gold}\n".tr()) - if (percentStats.science != 0f) stringBuilder.append("+" + percentStats.science.toInt() + "% {Science}\r\n".tr()) - if (percentStats.food != 0f) stringBuilder.append("+" + percentStats.food.toInt() + "% {Food}\n".tr()) - if (percentStats.culture != 0f) stringBuilder.append("+" + percentStats.culture.toInt() + "% {Culture}\r\n".tr()) + for ((stat, value) in getStatPercentageBonuses(cityInfo).toHashMap()) + if (value != 0f) lines += "+${value.toInt()}% {${stat.name}}\n" - for((greatPersonName, value) in greatPersonPoints) - stringBuilder.appendLine("+$value "+"[$greatPersonName] points".tr()) + for ((greatPersonName, value) in greatPersonPoints) + lines += "+$value " + "[$greatPersonName] points".tr() for ((specialistName, amount) in newSpecialists()) - stringBuilder.appendLine("+$amount " + "[$specialistName] slots".tr()) + lines += "+$amount " + "[$specialistName] slots".tr() if (requiredNearbyImprovedResources != null) - stringBuilder.appendLine(("Requires worked [" + requiredNearbyImprovedResources!!.joinToString("/") { it.tr() } + "] near city").tr()) + lines += "Requires worked [" + requiredNearbyImprovedResources!!.joinToString("/") { it.tr() } + "] near city" - if (cityStrength != 0) stringBuilder.appendLine("{City strength} +".tr() + cityStrength) - if (cityHealth != 0) stringBuilder.appendLine("{City health} +".tr() + cityHealth) - if (xpForNewUnits != 0) stringBuilder.appendLine("+$xpForNewUnits {XP for new units}".tr()) - if (maintenance != 0) - stringBuilder.appendLine("{Maintenance cost}: $maintenance {Gold}".tr()) - return stringBuilder.toString().trim() + if (cityStrength != 0) lines += "{City strength} +$cityStrength" + if (cityHealth != 0) lines += "{City health} +$cityHealth" + if (xpForNewUnits != 0) lines += "+$xpForNewUnits {XP for new units}" + if (maintenance != 0) lines += "{Maintenance cost}: $maintenance {Gold}" + return lines.joinToString("\n") { it.tr() }.trim() } fun getStats(city: CityInfo?): Stats { diff --git a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt index d3f4cd51f7..d3d6da72df 100644 --- a/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt +++ b/core/src/com/unciv/models/ruleset/unit/BaseUnit.kt @@ -88,7 +88,9 @@ class BaseUnit : INamed, INonPerpetualConstruction, ICivilopediaText { lines += "$strengthLine$movement${Fonts.movement}" if (replacementTextForUniques != "") lines += replacementTextForUniques - else for (unique in uniques) + else for (unique in uniques.filterNot { + it.startsWith("Hidden ") && it.endsWith(" disabled") || it == "Unbuildable" + }) lines += unique.tr() if (promotions.isNotEmpty()) { diff --git a/core/src/com/unciv/models/stats/Stat.kt b/core/src/com/unciv/models/stats/Stat.kt index 7c8b0c39d3..2746c7e7dd 100644 --- a/core/src/com/unciv/models/stats/Stat.kt +++ b/core/src/com/unciv/models/stats/Stat.kt @@ -2,13 +2,18 @@ package com.unciv.models.stats import com.unciv.logic.civilization.NotificationIcon import com.unciv.models.UncivSound +import com.unciv.ui.utils.Fonts -enum class Stat(val notificationIcon: String, val purchaseSound: UncivSound) { - Production(NotificationIcon.Production, UncivSound.Click), - Food(NotificationIcon.Food, UncivSound.Click), - Gold(NotificationIcon.Gold, UncivSound.Coin), - Science(NotificationIcon.Science, UncivSound.Chimes), - Culture(NotificationIcon.Culture, UncivSound.Paper), - Happiness(NotificationIcon.Happiness, UncivSound.Click), - Faith(NotificationIcon.Faith, UncivSound.Choir); -} \ No newline at end of file +enum class Stat( + val notificationIcon: String, + val purchaseSound: UncivSound, + val character: Char +) { + Production(NotificationIcon.Production, UncivSound.Click, Fonts.production), + Food(NotificationIcon.Food, UncivSound.Click, Fonts.food), + Gold(NotificationIcon.Gold, UncivSound.Coin, Fonts.gold), + Science(NotificationIcon.Science, UncivSound.Chimes, Fonts.science), + Culture(NotificationIcon.Culture, UncivSound.Paper, Fonts.culture), + Happiness(NotificationIcon.Happiness, UncivSound.Click, Fonts.happiness), + Faith(NotificationIcon.Faith, UncivSound.Choir, Fonts.faith); +} diff --git a/core/src/com/unciv/ui/cityscreen/ConstructionInfoTable.kt b/core/src/com/unciv/ui/cityscreen/ConstructionInfoTable.kt index 9cf879a1cf..ff7e31edc9 100644 --- a/core/src/com/unciv/ui/cityscreen/ConstructionInfoTable.kt +++ b/core/src/com/unciv/ui/cityscreen/ConstructionInfoTable.kt @@ -44,7 +44,6 @@ class ConstructionInfoTable(val city: CityInfo): Table() { //val selectedConstructionTable = Table() selectedConstructionTable.run { - background = ImageGetter.getBackground(ImageGetter.getBlue().lerp(Color.BLACK, 0.5f)) pad(10f) add(ImageGetter.getConstructionImage(construction.name).surroundWithCircle(50f)) @@ -59,7 +58,7 @@ class ConstructionInfoTable(val city: CityInfo): Table() { add(buildingText.toLabel()).row() val (description, link) = when (construction) { - is BaseUnit -> construction.getDescription() to "Unit/${construction.name}" + is BaseUnit -> construction.getDescription() to construction.makeLink() is Building -> construction.getDescription(city, city.getRuleset()) to construction.makeLink() is PerpetualConstruction -> construction.description.replace("[rate]", "[${construction.getConversionRate(city)}]") to "" else -> "" to "" // Should never happen