diff --git a/android/assets/jsons/translations/German.properties b/android/assets/jsons/translations/German.properties index b50cd0d441..c228efcf37 100644 --- a/android/assets/jsons/translations/German.properties +++ b/android/assets/jsons/translations/German.properties @@ -634,8 +634,8 @@ Raze city = Stadt niederreißen Stop razing city = Niederreißen der Stadt stoppen Buy for [amount] gold = Für [amount] Gold kaufen Buy = Kaufen -Currently you have [amount] gold. = Zur Zeit besitzt du [amount] Gold. -Would you like to purchase [constructionName] for [buildingGoldCost] gold? = [constructionName] für [buildingGoldCost] Gold kaufen? +Currently you have [amount] [stat]. = Zur Zeit besitzt du [amount] [stat]. +Would you like to purchase [constructionName] for [buildingGoldCost] [stat]? = [constructionName] für [buildingGoldCost] [stat] kaufen? No space available to place [unit] near [city] = Kein Platz verfügbar um [unit] nahe [city] zu platzieren Maintenance cost = Wartungskosten Pick construction = Produktion auswählen diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index 95b6bd4a43..24ca4409ba 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -631,8 +631,8 @@ Raze city = Stop razing city = Buy for [amount] gold = Buy = -Currently you have [amount] gold. = -Would you like to purchase [constructionName] for [buildingGoldCost] gold? = +Currently you have [amount] [stat]. = +Would you like to purchase [constructionName] for [buildingGoldCost] [stat]? = No space available to place [unit] near [city] = Maintenance cost = Pick construction = diff --git a/core/src/com/unciv/models/stats/Stat.kt b/core/src/com/unciv/models/stats/Stat.kt index 2746c7e7dd..35202fea13 100644 --- a/core/src/com/unciv/models/stats/Stat.kt +++ b/core/src/com/unciv/models/stats/Stat.kt @@ -16,4 +16,11 @@ enum class Stat( Culture(NotificationIcon.Culture, UncivSound.Paper, Fonts.culture), Happiness(NotificationIcon.Happiness, UncivSound.Click, Fonts.happiness), Faith(NotificationIcon.Faith, UncivSound.Choir, Fonts.faith); + + companion object { + val statsUsableToBuy = listOf(Gold, Food, Science, Culture, Faith) + } } + +// Should the well-known colours for these be needed: +// Production = "#c14d00", Food = "#38ff70", Gold = "#ffeb7f", Science = "#8c9dff", Culture = "#8b60ff", Happiness = "#ffd800", Faith = "#cbdfff" diff --git a/core/src/com/unciv/ui/cityscreen/CityConstructionsTable.kt b/core/src/com/unciv/ui/cityscreen/CityConstructionsTable.kt index a06ebd7c44..176a1cc31f 100644 --- a/core/src/com/unciv/ui/cityscreen/CityConstructionsTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityConstructionsTable.kt @@ -120,28 +120,18 @@ class CityConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBase val city = cityScreen.city val cityConstructions = city.cityConstructions - for (unit in city.getRuleset().units.values.filter { it.shouldBeDisplayed(cityConstructions) }) { - val useStoredProduction = !cityConstructions.isBeingConstructedOrEnqueued(unit.name) - var buttonText = unit.name.tr() + cityConstructions.getTurnsToConstructionString(unit.name, useStoredProduction) - for ((resource, amount) in unit.getResourceRequirements()) { - if (amount == 1) buttonText += "\n" + "Consumes 1 [$resource]".tr() - else buttonText += "\n" + "Consumes [$amount] [$resource]".tr() + val constructionsSequence = city.getRuleset().units.values.asSequence() + + city.getRuleset().buildings.values.asSequence() + for (entry in constructionsSequence.filter { it.shouldBeDisplayed(cityConstructions) }) { + val useStoredProduction = entry is Building || !cityConstructions.isBeingConstructedOrEnqueued(entry.name) + var buttonText = entry.name.tr() + cityConstructions.getTurnsToConstructionString(entry.name, useStoredProduction) + for ((resource, amount) in entry.getResourceRequirements()) { + buttonText += "\n" + (if (amount == 1) "Consumes 1 [$resource]" + else "Consumes [$amount] [$resource]").tr() } - constructionButtonDTOList.add(ConstructionButtonDTO(unit, buttonText, - unit.getRejectionReason(cityConstructions))) - } - - - for (building in city.getRuleset().buildings.values.filter { it.shouldBeDisplayed(cityConstructions) }) { - var buttonText = building.name.tr() + cityConstructions.getTurnsToConstructionString(building.name) - for ((resource, amount) in building.getResourceRequirements()) { - if (amount == 1) buttonText += "\n" + "Consumes 1 [$resource]".tr() - else buttonText += "\n" + "Consumes [$amount] [$resource]".tr() - } - - constructionButtonDTOList.add(ConstructionButtonDTO(building, buttonText, - building.getRejectionReason(cityConstructions))) + constructionButtonDTOList.add(ConstructionButtonDTO(entry, buttonText, + entry.getRejectionReason(cityConstructions))) } for (specialConstruction in PerpetualConstruction.perpetualConstructionsMap.values @@ -376,7 +366,7 @@ class CityConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBase } } - fun purchaseConstruction(construction: INonPerpetualConstruction, stat: Stat = Stat.Gold) { + private fun purchaseConstruction(construction: INonPerpetualConstruction, stat: Stat = Stat.Gold) { val city = cityScreen.city if (!city.cityConstructions.purchaseConstruction(construction.name, selectedQueueEntry, false, stat)) { Popup(cityScreen).apply { @@ -386,7 +376,7 @@ class CityConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBase } return } - if (isSelectedQueueEntry()) { + if (isSelectedQueueEntry() || cityScreen.selectedConstruction?.isBuildable(city.cityConstructions) != true) { selectedQueueEntry = -1 cityScreen.selectedConstruction = null } @@ -394,38 +384,43 @@ class CityConstructionsTable(val cityScreen: CityScreen) : Table(CameraStageBase } private fun getBuyButtons(construction: INonPerpetualConstruction?): List { - return listOf(Stat.Gold, Stat.Faith, Stat.Culture, Stat.Science, Stat.Food) - .mapNotNull { getBuyButton(construction, it) } + return Stat.statsUsableToBuy.mapNotNull { getBuyButton(construction, it) } } private fun getBuyButton(construction: INonPerpetualConstruction?, stat: Stat = Stat.Gold): TextButton? { - if (stat !in listOf(Stat.Gold, Stat.Faith, Stat.Culture, Stat.Science, Stat.Food)) + if (stat !in Stat.statsUsableToBuy || construction == null) return null - val city = cityScreen.city + val city = cityScreen.city val button = "".toTextButton() - if (construction == null || construction is PerpetualConstruction || - (!construction.canBePurchasedWithStat(city, stat) && !city.civInfo.gameInfo.gameParameters.godMode)) { - // fully disable a "buy" button only for "priceless" buildings such as wonders - // for all other cases, the price should be displayed - if (stat == Stat.Gold) { - button.setText("Buy".tr()) - button.disable() - } - else return null + if (!construction.canBePurchasedWithStat(city, stat) && !city.civInfo.gameInfo.gameParameters.godMode) { + // This can't ever be bought with the given currency. + // We want one disabled "buy" button without a price for "priceless" buildings such as wonders + // We don't want such a button when the construction can be bought using a different currency + if (stat != Stat.Gold || construction.canBePurchasedWithAnyStat(city)) + return null + button.setText("Buy".tr()) + button.disable() } else { val constructionBuyCost = construction.getStatBuyCost(city, stat)!! - button.setText("Buy".tr() + " " + constructionBuyCost) - button.add(ImageGetter.getStatIcon(stat.name)).size(20f).padBottom(2f) + button.setText("Buy".tr() + " " + constructionBuyCost + stat.character) button.onClick(stat.purchaseSound) { button.disable() cityScreen.closeAllPopups() - val purchasePrompt = "Currently you have [${city.getStatReserve(stat)}] [${stat.name}].".tr() + "\n" + - "Would you like to purchase [${construction.name}] for [$constructionBuyCost] [${stat.name}]?".tr() - YesNoPopup(purchasePrompt, { purchaseConstruction(construction, stat) }, cityScreen, { cityScreen.update() }).open() + val purchasePrompt = "Currently you have [${city.getStatReserve(stat)}] [${stat.name}].".tr() + "\n\n" + + "Would you like to purchase [${construction.name}] for [$constructionBuyCost] [${stat.character}]?".tr() + YesNoPopup( + purchasePrompt, + action = { purchaseConstruction(construction, stat) }, + screen = cityScreen, + restoreDefault = { cityScreen.update() } + ).apply { + promptLabel.setAlignment(Align.center) + open() + } } if (!cityScreen.canChangeState diff --git a/core/src/com/unciv/ui/cityscreen/CityScreenTileTable.kt b/core/src/com/unciv/ui/cityscreen/CityScreenTileTable.kt index 572ea93681..455c468b07 100644 --- a/core/src/com/unciv/ui/cityscreen/CityScreenTileTable.kt +++ b/core/src/com/unciv/ui/cityscreen/CityScreenTileTable.kt @@ -5,6 +5,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table import com.unciv.UncivGame import com.unciv.logic.map.TileInfo import com.unciv.models.UncivSound +import com.unciv.models.stats.Stat import com.unciv.models.stats.Stats import com.unciv.models.translations.tr import com.unciv.ui.civilopedia.CivilopediaScreen @@ -47,8 +48,8 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() { val buyTileButton = "Buy for [$goldCostOfTile] gold".toTextButton() buyTileButton.onClick(UncivSound.Coin) { - val purchasePrompt = "Currently you have [${city.civInfo.gold}] gold.".tr() + "\n" + - "Would you like to purchase [Tile] for [$goldCostOfTile] gold?".tr() + val purchasePrompt = "Currently you have [${city.civInfo.gold}] [Gold].".tr() + "\n\n" + + "Would you like to purchase [Tile] for [$goldCostOfTile] [${Stat.Gold.character}]?".tr() YesNoPopup(purchasePrompt, { city.expansion.buyTile(selectedTile);UncivGame.Current.setScreen(CityScreen(city)) }, cityScreen).open() } val canPurchase = goldCostOfTile == 0 || city.civInfo.gold >= goldCostOfTile diff --git a/core/src/com/unciv/ui/utils/YesNoPopup.kt b/core/src/com/unciv/ui/utils/YesNoPopup.kt index 312de87a51..89235ea406 100644 --- a/core/src/com/unciv/ui/utils/YesNoPopup.kt +++ b/core/src/com/unciv/ui/utils/YesNoPopup.kt @@ -1,6 +1,7 @@ package com.unciv.ui.utils import com.badlogic.gdx.Gdx +import com.badlogic.gdx.utils.Align import com.unciv.Constants import com.unciv.UncivGame @@ -11,14 +12,18 @@ import com.unciv.UncivGame * @param restoreDefault A lambda to execute when "No" is chosen */ open class YesNoPopup ( - question:String, - action:()->Unit, + question: String, + action: ()->Unit, screen: CameraStageBaseScreen = UncivGame.Current.worldScreen, - restoreDefault:()->Unit = {} + restoreDefault: ()->Unit = {} ) : Popup(screen) { + /** The [Label][com.badlogic.gdx.scenes.scene2d.ui.Label] created for parameter `question` for optional layout tweaking */ + val promptLabel = question.toLabel() + init { - add(question.toLabel()).colspan(2).row() + promptLabel.setAlignment(Align.center) + add(promptLabel).colspan(2).row() addOKButton(Constants.yes, KeyCharAndCode('y'), action) addCloseButton(Constants.no, KeyCharAndCode('n'), restoreDefault) equalizeLastTwoButtonWidths()