Single tap pickers for improvements and promotion (#765)

* single tap picker (improvements, policies and promotions), tbd: split button

* improvement and promotion pickers: using split buttons featuring a question mark. allows single-tap choice.

* improvement picker and promotion picker: show "pick now" to the right of the button
This commit is contained in:
sulai 2019-05-20 19:38:50 +02:00 committed by Yair Morgenstern
parent bec3c2a224
commit f905fa8068
6 changed files with 121 additions and 53 deletions

View File

@ -799,7 +799,7 @@
Portuguese:"recursos e melhorias" Portuguese:"recursos e melhorias"
Japanese:"リソースと改善" Japanese:"リソースと改善"
} }
"Check for idle units":{ "Check for idle units":{
Italian:"Controlla unità inutilizzate" Italian:"Controlla unità inutilizzate"
Simplified_Chinese:"查看未行动单位" Simplified_Chinese:"查看未行动单位"
@ -875,7 +875,7 @@
Dutch:"Voor [amount] gold kopen" Dutch:"Voor [amount] gold kopen"
Spanish:"Comprar por [amount] de oro" Spanish:"Comprar por [amount] de oro"
Simplified_Chinese:"购买花费[amount]金钱" Simplified_Chinese:"购买花费[amount]金钱"
Portuguese:"Comprar por [amount] ouro" Portuguese:"Comprar por [amount] ouro"
Japanese:"[amount]ゴールドで購入する" Japanese:"[amount]ゴールドで購入する"
} }
@ -938,6 +938,10 @@
Portuguese:"Escolha uma melhoria" Portuguese:"Escolha uma melhoria"
} }
"Pick now!": {
German: "Jetzt wählen!"
}
"Build [building]":{ // eg Build Granary "Build [building]":{ // eg Build Granary
Italian:"Costruisci [building]" Italian:"Costruisci [building]"
Russian:"Строить [building]" Russian:"Строить [building]"
@ -1486,7 +1490,7 @@
French:"[percentage] de défense" French:"[percentage] de défense"
} }
///////// Unit uniques ///////// Unit uniques
// - - - NOTE: These need to be moved to the "Units,Promotions" translation file, in their respective places! - - - // - - - NOTE: These need to be moved to the "Units,Promotions" translation file, in their respective places! - - -
@ -1590,7 +1594,7 @@
// for unit action button // for unit action button
"Discover Technology":{ "Discover Technology":{
Romanian:"Descoperă tehnologie" Romanian:"Descoperă tehnologie"
Spanish:"Descubrir Tecnologia" Spanish:"Descubrir Tecnologia"
Simplified_Chinese:"发现科技" Simplified_Chinese:"发现科技"
@ -1661,7 +1665,7 @@
Simplified_Chinese:"[policyBranch]政策分支解锁!" Simplified_Chinese:"[policyBranch]政策分支解锁!"
Portuguese:"[policyBranch] foi desbloqueado(a)" Portuguese:"[policyBranch] foi desbloqueado(a)"
German:"[policyBranch] Grundsatzzweig wurde freigeschaltet" German:"[policyBranch] Grundsatzzweig wurde freigeschaltet"
} }
////// Trade ////// Trade
@ -2091,7 +2095,7 @@
"+1 Gold from each Trade Route, Oil resources provide double quantity":{ "+1 Gold from each Trade Route, Oil resources provide double quantity":{
Italian:"+1 Oro da ogni rotta commerciale, e doppia quantità da ogni risorsa di Petrolio" Italian:"+1 Oro da ogni rotta commerciale, e doppia quantità da ogni risorsa di Petrolio"
Simplified_Chinese:"每条贸易路线+1金钱石油储量加倍" Simplified_Chinese:"每条贸易路线+1金钱石油储量加倍"
Portuguese:"1 ouro adicional de rotas comerciais e recursos de petróleo geram o dobro" // óleo could mean normal kitchen oil and even fuel from sugar cane Portuguese:"1 ouro adicional de rotas comerciais e recursos de petróleo geram o dobro" // óleo could mean normal kitchen oil and even fuel from sugar cane
} }
"America":{ "America":{
@ -2273,7 +2277,7 @@
Italian:"+50% durata delle Età dell'Oro, durante le quali le unità ricevono +1 Movimento e +10% Forza." Italian:"+50% durata delle Età dell'Oro, durante le quali le unità ricevono +1 Movimento e +10% Forza."
Portuguese:"Idades douradas duram 50% mais, unidades recebem 1 movimento a mais e um bonus de +10% em força de combate." Portuguese:"Idades douradas duram 50% mais, unidades recebem 1 movimento a mais e um bonus de +10% em força de combate."
} }
*/ */
"Uniques":{ // unit uniques, displayed on the new game screen when choosing a civ "Uniques":{ // unit uniques, displayed on the new game screen when choosing a civ
@ -2618,7 +2622,7 @@
Simplified_Chinese:"我们的关系:" Simplified_Chinese:"我们的关系:"
Portuguese:"Nossas relações" Portuguese:"Nossas relações"
} }
"We have encountered the City-State of [name]!":{ // e.g. the Cultured city state of Vienna "We have encountered the City-State of [name]!":{ // e.g. the Cultured city state of Vienna
Italian:"Abbiamo incontrato la Citta-Stato di [name]!" Italian:"Abbiamo incontrato la Citta-Stato di [name]!"
Portuguese:"Nós encontramos a cidade-estado de [name]" Portuguese:"Nós encontramos a cidade-estado de [name]"
@ -2762,11 +2766,11 @@
Simplified_Chinese:"开放的边界促进了彼此的了解,让我们的人民心心相通!" Simplified_Chinese:"开放的边界促进了彼此的了解,让我们的人民心心相通!"
Portuguese:"Nossa fronteiras abertas nos fizeram mais próximos." Portuguese:"Nossa fronteiras abertas nos fizeram mais próximos."
} }
"Your so-called 'friendship' is worth nothing.":{ // When we have a decleration of friendship to someone and we declare war on them "Your so-called 'friendship' is worth nothing.":{ // When we have a decleration of friendship to someone and we declare war on them
Italian:"La tua cosiddetta 'amicizia' non vale nulla!" Italian:"La tua cosiddetta 'amicizia' non vale nulla!"
Portuguese:"Sua chamada 'amizade' não vale nada." Portuguese:"Sua chamada 'amizade' não vale nada."
} }
@ -2868,7 +2872,7 @@
Portuguese:"De outros" Portuguese:"De outros"
Simplified_Chinese:"其他" Simplified_Chinese:"其他"
Portuguese:"Outros" Portuguese:"Outros"
} }
"Population":{ "Population":{
Italian:"Popolazione" Italian:"Popolazione"
@ -2991,7 +2995,7 @@
German:"Nächstgelegene Stadt" German:"Nächstgelegene Stadt"
} }
"Go to unit":{ "Go to unit":{
Italian:"Vai a unità" Italian:"Vai a unità"
Simplified_Chinese:"跳转至所在地图位置" Simplified_Chinese:"跳转至所在地图位置"
Portuguese:"Ir para a unidade" Portuguese:"Ir para a unidade"
@ -3111,8 +3115,8 @@
French:"Détruiser [civName]" French:"Détruiser [civName]"
Russian:"Уничтожить [civName]" Russian:"Уничтожить [civName]"
Simplified_Chinese:"摧毁[civName]文明" Simplified_Chinese:"摧毁[civName]文明"
Portuguese:"Destruir [civName]" //what's the context? as in it being a question, or a pre-requisite for conquest victory? Portuguese:"Destruir [civName]" //what's the context? as in it being a question, or a pre-requisite for conquest victory?
} }
////// Civilopedia texts ////// Civilopedia texts

View File

@ -1,16 +1,14 @@
package com.unciv.ui.pickerscreens package com.unciv.ui.pickerscreens
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Button import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.*
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup import com.badlogic.gdx.utils.Align
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
import com.unciv.models.gamebasics.tile.TileImprovement import com.unciv.models.gamebasics.tile.TileImprovement
import com.unciv.models.gamebasics.tr import com.unciv.models.gamebasics.tr
import com.unciv.ui.utils.ImageGetter import com.unciv.ui.utils.*
import com.unciv.ui.utils.onClick
import com.unciv.ui.utils.setFontColor
class ImprovementPickerScreen(tileInfo: TileInfo, onAccept: ()->Unit) : PickerScreen() { class ImprovementPickerScreen(tileInfo: TileInfo, onAccept: ()->Unit) : PickerScreen() {
private var selectedImprovement: TileImprovement? = null private var selectedImprovement: TileImprovement? = null
@ -19,13 +17,19 @@ class ImprovementPickerScreen(tileInfo: TileInfo, onAccept: ()->Unit) : PickerSc
val currentPlayerCiv = game.gameInfo.getCurrentPlayerCivilization() val currentPlayerCiv = game.gameInfo.getCurrentPlayerCivilization()
setDefaultCloseAction() setDefaultCloseAction()
fun accept(improvement: TileImprovement?) {
if (improvement != null) {
tileInfo.startWorkingOnImprovement(improvement, currentPlayerCiv)
if (tileInfo.civilianUnit != null) tileInfo.civilianUnit!!.action = null // this is to "wake up" the worker if it's sleeping
onAccept()
game.setWorldScreen()
dispose()
}
}
rightSideButton.setText("Pick improvement".tr()) rightSideButton.setText("Pick improvement".tr())
rightSideButton.onClick { rightSideButton.onClick {
tileInfo.startWorkingOnImprovement(selectedImprovement!!, currentPlayerCiv) accept(selectedImprovement)
if(tileInfo.civilianUnit!=null) tileInfo.civilianUnit!!.action=null // this is to "wake up" the worker if it's sleeping
onAccept()
game.setWorldScreen()
dispose()
} }
val regularImprovements = VerticalGroup() val regularImprovements = VerticalGroup()
@ -36,21 +40,37 @@ class ImprovementPickerScreen(tileInfo: TileInfo, onAccept: ()->Unit) : PickerSc
if(improvement.name == tileInfo.improvement) continue if(improvement.name == tileInfo.improvement) continue
if(improvement.name==tileInfo.improvementInProgress) continue if(improvement.name==tileInfo.improvementInProgress) continue
val improvementButton = Button(skin) val group = Table()
if(improvement.name.startsWith("Remove")) val image = if(improvement.name.startsWith("Remove"))
improvementButton.add(ImageGetter.getImage("OtherIcons/Stop.png")).size(30f).pad(10f) ImageGetter.getImage("OtherIcons/Stop.png")
else improvementButton.add(ImageGetter.getImprovementIcon(improvement.name,30f)).pad(10f) else
ImageGetter.getImprovementIcon(improvement.name,30f)
improvementButton.add(Label(improvement.name.tr() + " - " + improvement.getTurnsToBuild(currentPlayerCiv) + " {turns}".tr(),skin) group.add(image).size(30f).pad(10f)
group.add(Label(improvement.name.tr() + " - " + improvement.getTurnsToBuild(currentPlayerCiv) + " {turns}".tr(),skin)
.setFontColor(Color.WHITE)).pad(10f) .setFontColor(Color.WHITE)).pad(10f)
improvementButton.onClick { group.touchable = Touchable.enabled
selectedImprovement = improvement group.onClick {
pick(improvement.name) selectedImprovement = improvement
descriptionLabel.setText(improvement.description) pick(improvement.name)
} descriptionLabel.setText(improvement.description)
}
val pickNow = Label("Pick now!", skin)
pickNow.touchable = Touchable.enabled
pickNow.onClick {
accept(improvement)
}
val improvementButton = Button(skin)
improvementButton.add(group).padRight(10f).fillY()
improvementButton.addSeparatorVertical()
improvementButton.add(pickNow).padLeft(10f).fill()
regularImprovements.addActor(improvementButton) regularImprovements.addActor(improvementButton)
} }
topTable.add(regularImprovements) topTable.add(regularImprovements)
} }

View File

@ -18,20 +18,19 @@ open class PickerScreen : CameraStageBaseScreen() {
protected var scrollPane: ScrollPane protected var scrollPane: ScrollPane
init { init {
bottomTable.add(closeButton).width(stage.width / 4) bottomTable.add(closeButton).pad(10f)
descriptionLabel = "".toLabel() descriptionLabel = "".toLabel()
descriptionLabel.setWrap(true) descriptionLabel.setWrap(true)
val labelScroll = ScrollPane(descriptionLabel) val labelScroll = ScrollPane(descriptionLabel)
bottomTable.add(labelScroll).pad(5f).width(stage.width / 2) bottomTable.add(labelScroll).pad(5f).fill().expand()
rightSideButton = TextButton("", skin) rightSideButton = TextButton("", skin)
rightSideButton.disable() rightSideButton.disable()
rightSideGroup.addActor(rightSideButton) rightSideGroup.addActor(rightSideButton)
bottomTable.add(rightSideGroup).width(stage.width / 4) bottomTable.add(rightSideGroup).pad(10f).right()
bottomTable.height = stage.height * (1 - screenSplit) bottomTable.height = stage.height * (1 - screenSplit)
bottomTable.align(Align.center)
topTable = Table() topTable = Table()
scrollPane = ScrollPane(topTable) scrollPane = ScrollPane(topTable)

View File

@ -33,7 +33,13 @@ class PolicyPickerScreen(internal val civInfo: CivilizationInfo) : PickerScreen(
civInfo.policies.adopt(pickedPolicy!!) civInfo.policies.adopt(pickedPolicy!!)
// If we've moved to another screen in the meantime (great person pick, victory screen) ignore this // If we've moved to another screen in the meantime (great person pick, victory screen) ignore this
if(game.screen is PolicyPickerScreen) game.screen = PolicyPickerScreen(civInfo) if(game.screen is PolicyPickerScreen){
// update policies
// game.screen = PolicyPickerScreen(civInfo)
game.setWorldScreen()
dispose()
}
} }

View File

@ -1,8 +1,12 @@
package com.unciv.ui.pickerscreens package com.unciv.ui.pickerscreens
import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.Touchable
import com.badlogic.gdx.scenes.scene2d.ui.Button import com.badlogic.gdx.scenes.scene2d.ui.Button
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup
import com.badlogic.gdx.utils.Align
import com.unciv.UnCivGame import com.unciv.UnCivGame
import com.unciv.logic.map.MapUnit import com.unciv.logic.map.MapUnit
import com.unciv.models.gamebasics.GameBasics import com.unciv.models.gamebasics.GameBasics
@ -18,16 +22,22 @@ class PromotionPickerScreen(mapUnit: MapUnit) : PickerScreen() {
init { init {
onBackButtonClicked { UnCivGame.Current.setWorldScreen() } onBackButtonClicked { UnCivGame.Current.setWorldScreen() }
setDefaultCloseAction() setDefaultCloseAction()
rightSideButton.setText("Pick promotion".tr())
rightSideButton.onClick("promote") { fun accept(promotion: Promotion?) {
mapUnit.promotions.addPromotion(selectedPromotion!!.name) mapUnit.promotions.addPromotion(promotion!!.name)
if(mapUnit.promotions.canBePromoted()) game.screen = PromotionPickerScreen(mapUnit) if(mapUnit.promotions.canBePromoted()) game.screen = PromotionPickerScreen(mapUnit)
else game.setWorldScreen() else game.setWorldScreen()
dispose() dispose()
} }
rightSideButton.setText("Pick promotion".tr())
rightSideButton.onClick("promote") {
accept(selectedPromotion)
}
val availablePromotionsGroup = VerticalGroup() val availablePromotionsGroup = VerticalGroup()
availablePromotionsGroup.space(10f) availablePromotionsGroup.space(10f)
val unitType = mapUnit.type val unitType = mapUnit.type
val promotionsForUnitType = GameBasics.UnitPromotions.values.filter { it.unitTypes.contains(unitType.toString()) } val promotionsForUnitType = GameBasics.UnitPromotions.values.filter { it.unitTypes.contains(unitType.toString()) }
val unitAvailablePromotions = mapUnit.promotions.getAvailablePromotions() val unitAvailablePromotions = mapUnit.promotions.getAvailablePromotions()
@ -36,15 +46,15 @@ class PromotionPickerScreen(mapUnit: MapUnit) : PickerScreen() {
if(promotion.name=="Heal Instantly" && mapUnit.health==100) continue if(promotion.name=="Heal Instantly" && mapUnit.health==100) continue
val isPromotionAvailable = promotion in unitAvailablePromotions val isPromotionAvailable = promotion in unitAvailablePromotions
val unitHasPromotion = mapUnit.promotions.promotions.contains(promotion.name) val unitHasPromotion = mapUnit.promotions.promotions.contains(promotion.name)
val promotionButton = Button(skin)
if(!isPromotionAvailable) promotionButton.color = Color.GRAY val group = Table()
promotionButton.add(ImageGetter.getPromotionIcon(promotion.name)).size(30f).pad(10f)
promotionButton.add(promotion.name.toLabel()
.setFontColor(Color.WHITE)).pad(10f)
if(unitHasPromotion) promotionButton.color = Color.GREEN
promotionButton.onClick { group.add(ImageGetter.getPromotionIcon(promotion.name)).size(30f).pad(10f)
group.add(promotion.name.toLabel()
.setFontColor(Color.WHITE)).pad(10f).padRight(20f)
group.touchable = Touchable.enabled
group.onClick {
selectedPromotion = promotion selectedPromotion = promotion
rightSideButton.setText(promotion.name.tr()) rightSideButton.setText(promotion.name.tr())
if(isPromotionAvailable && !unitHasPromotion) rightSideButton.enable() if(isPromotionAvailable && !unitHasPromotion) rightSideButton.enable()
@ -55,14 +65,37 @@ class PromotionPickerScreen(mapUnit: MapUnit) : PickerScreen() {
if(promotion.prerequisites.isNotEmpty()) { if(promotion.prerequisites.isNotEmpty()) {
val prerequisitesString:ArrayList<String> = arrayListOf() val prerequisitesString:ArrayList<String> = arrayListOf()
for (i in promotion.prerequisites.filter { promotionsForUnitType.any { promotion -> promotion.name==it } }){ for (i in promotion.prerequisites.filter { promotionsForUnitType.any { promotion -> promotion.name==it } }){
prerequisitesString.add(i.tr()) prerequisitesString.add(i.tr())
} }
descriptionText +="\n{Requires}: ".tr()+prerequisitesString.joinToString(" OR ".tr()) descriptionText +="\n{Requires}: ".tr()+prerequisitesString.joinToString(" OR ".tr())
} }
descriptionLabel.setText(descriptionText) descriptionLabel.setText(descriptionText)
} }
val pickNow = Label("Pick now!", skin)
pickNow.touchable = Touchable.enabled
pickNow.setAlignment(Align.center)
pickNow.onClick {
accept(promotion)
}
val promotionButton = Button(skin)
promotionButton.add(group).fillY()
if(isPromotionAvailable) {
promotionButton.addSeparatorVertical()
promotionButton.add(pickNow).padLeft(10f).fillY()
}
else {
group.touchable = Touchable.disabled
promotionButton.disable()
}
if(unitHasPromotion) promotionButton.color = Color.GREEN
availablePromotionsGroup.addActor(promotionButton) availablePromotionsGroup.addActor(promotionButton)
} }
topTable.add(availablePromotionsGroup) topTable.add(availablePromotionsGroup)
} }

View File

@ -163,6 +163,12 @@ fun Table.addSeparator(): Cell<Image> {
return cell return cell
} }
fun Table.addSeparatorVertical(): Cell<Image> {
val image = ImageGetter.getWhiteDot()
val cell = add(image).width(2f).fillY()
return cell
}
/** /**
* Solves concurrent modification problems - everyone who had a reference to the previous arrayList can keep using it because it hasn't changed * Solves concurrent modification problems - everyone who had a reference to the previous arrayList can keep using it because it hasn't changed
*/ */