Show "x units due" on Big Button, setting for cycling units (#12814)

* Show "x units due" on Big Button

* Add setting for cycling with Next unit button (default true)

* Fix template.properties

* Use the term 'idle' when cycling

* Improve code structure

---------

Co-authored-by: M. Rittweger <m.rittweger@mvolution.de>
This commit is contained in:
sulai 2025-01-18 17:54:43 +01:00 committed by GitHub
parent 44fa9bde7d
commit 7e3827bc6e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 51 additions and 8 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 896 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.3 KiB

After

Width:  |  Height:  |  Size: 896 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 907 KiB

After

Width:  |  Height:  |  Size: 906 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 574 KiB

After

Width:  |  Height:  |  Size: 573 KiB

View File

@ -846,6 +846,7 @@ When disabled, saves battery life but certain animations will be suspended =
## Gameplay tab ## Gameplay tab
Gameplay = Gameplay =
Check for idle units = Check for idle units =
'Next unit' button cycles idle units =
Auto Unit Cycle = Auto Unit Cycle =
Move units with a single tap = Move units with a single tap =
Move units with a long tap = Move units with a long tap =
@ -1171,6 +1172,8 @@ Turn =
turns = turns =
turn = turn =
Next unit = Next unit =
[amount] units idle =
[amount] units due =
Fog of War = Fog of War =
Pick a policy = Pick a policy =
Move Spies = Move Spies =

View File

@ -12,7 +12,6 @@ import com.unciv.models.translations.Translations.Companion.getNumberFormatFromL
import com.unciv.ui.components.fonts.FontFamilyData import com.unciv.ui.components.fonts.FontFamilyData
import com.unciv.ui.components.fonts.Fonts import com.unciv.ui.components.fonts.Fonts
import com.unciv.ui.components.input.KeyboardBindings import com.unciv.ui.components.input.KeyboardBindings
import com.unciv.ui.screens.overviewscreen.EmpireOverviewCategories
import com.unciv.ui.screens.worldscreen.NotificationsScroll import com.unciv.ui.screens.worldscreen.NotificationsScroll
import com.unciv.utils.Display import com.unciv.utils.Display
import com.unciv.utils.ScreenOrientation import com.unciv.utils.ScreenOrientation
@ -38,6 +37,7 @@ class GameSettings {
var showSettlersSuggestedCityLocations: Boolean = true var showSettlersSuggestedCityLocations: Boolean = true
var checkForDueUnits: Boolean = true var checkForDueUnits: Boolean = true
var checkForDueUnitsCycles: Boolean = false
var autoUnitCycle: Boolean = true var autoUnitCycle: Boolean = true
var singleTapMove: Boolean = false var singleTapMove: Boolean = false
var longTapMove: Boolean = true var longTapMove: Boolean = true

View File

@ -15,6 +15,7 @@ fun gameplayTab(
val settings = optionsPopup.settings val settings = optionsPopup.settings
optionsPopup.addCheckbox(this, "Check for idle units", settings.checkForDueUnits, true) { settings.checkForDueUnits = it } optionsPopup.addCheckbox(this, "Check for idle units", settings.checkForDueUnits, true) { settings.checkForDueUnits = it }
optionsPopup.addCheckbox(this, "'Next unit' button cycles idle units", settings.checkForDueUnitsCycles, true) { settings.checkForDueUnitsCycles = it }
optionsPopup.addCheckbox(this, "Auto Unit Cycle", settings.autoUnitCycle, true) { settings.autoUnitCycle = it } optionsPopup.addCheckbox(this, "Auto Unit Cycle", settings.autoUnitCycle, true) { settings.autoUnitCycle = it }
optionsPopup.addCheckbox(this, "Move units with a single tap", settings.singleTapMove) { settings.singleTapMove = it } optionsPopup.addCheckbox(this, "Move units with a single tap", settings.singleTapMove) { settings.singleTapMove = it }
optionsPopup.addCheckbox(this, "Move units with a long tap", settings.longTapMove) { settings.longTapMove = it } optionsPopup.addCheckbox(this, "Move units with a long tap", settings.longTapMove) { settings.longTapMove = it }

View File

@ -638,9 +638,9 @@ class WorldScreen(
} }
} }
fun switchToNextUnit() { fun switchToNextUnit(resetDue: Boolean = true) {
// Try to select something new if we already have the next pending unit selected. // Try to select something new if we already have the next pending unit selected.
if (bottomUnitTable.selectedUnit != null) if (bottomUnitTable.selectedUnit != null && resetDue)
bottomUnitTable.selectedUnit!!.due = false bottomUnitTable.selectedUnit!!.due = false
val nextDueUnit = viewingCiv.units.cycleThroughDueUnits(bottomUnitTable.selectedUnit) val nextDueUnit = viewingCiv.units.cycleThroughDueUnits(bottomUnitTable.selectedUnit)
if (nextDueUnit != null) { if (nextDueUnit != null) {

View File

@ -120,7 +120,9 @@ enum class NextTurnAction(protected val text: String, val color: Color) {
override fun isChoice(worldScreen: WorldScreen) = override fun isChoice(worldScreen: WorldScreen) =
worldScreen.viewingCiv.units.shouldGoToDueUnit() worldScreen.viewingCiv.units.shouldGoToDueUnit()
override fun action(worldScreen: WorldScreen) = override fun action(worldScreen: WorldScreen) =
worldScreen.switchToNextUnit() worldScreen.switchToNextUnit(!worldScreen.game.settings.checkForDueUnitsCycles)
override fun getSubText(worldScreen: WorldScreen): String? =
getIdleUnitsText(worldScreen)
}, },
MoveAutomatedUnits("Move automated units", Color.LIGHT_GRAY) { MoveAutomatedUnits("Move automated units", Color.LIGHT_GRAY) {
override fun isChoice(worldScreen: WorldScreen) = override fun isChoice(worldScreen: WorldScreen) =
@ -133,11 +135,14 @@ enum class NextTurnAction(protected val text: String, val color: Color) {
true // When none of the others is active.. true // When none of the others is active..
override fun action(worldScreen: WorldScreen) = override fun action(worldScreen: WorldScreen) =
worldScreen.confirmedNextTurn() worldScreen.confirmedNextTurn()
override fun getSubText(worldScreen: WorldScreen): String? =
getIdleUnitsText(worldScreen)
}, },
; ;
open val icon: String? get() = if (text != "AutoPlay") "NotificationIcons/$name" else "NotificationIcons/Working" open val icon: String? get() = if (text != "AutoPlay") "NotificationIcons/$name" else "NotificationIcons/Working"
open fun getText(worldScreen: WorldScreen) = text open fun getText(worldScreen: WorldScreen) = text
open fun getSubText(worldScreen: WorldScreen): String? = null
abstract fun isChoice(worldScreen: WorldScreen): Boolean abstract fun isChoice(worldScreen: WorldScreen): Boolean
open fun action(worldScreen: WorldScreen) {} open fun action(worldScreen: WorldScreen) {}
@ -200,5 +205,24 @@ enum class NextTurnAction(protected val text: String, val color: Color) {
true, action = ::action).open() true, action = ::action).open()
} else action() } else action()
} }
/**
Show due units in next-unit and next-turn phase, encouraging the player to give order to
idle units.
It also serves to inform new players that the NextUnit-Button cycles units. That's easy
to grasp, because the number doesn't change when repeatedly clicking the button.
We also show due units on the NextTurn button, so players see due units in case the
the NextTurn phase is disabled.
*/
private fun getIdleUnitsText(worldScreen: WorldScreen): String? {
val count = worldScreen.viewingCiv.units.getDueUnits().count()
if (count > 0) {
return if (worldScreen.game.settings.checkForDueUnitsCycles)
"[$count] units idle"
else
"[$count] units due"
}
return null
}
} }
} }

View File

@ -1,5 +1,7 @@
package com.unciv.ui.screens.worldscreen.status package com.unciv.ui.screens.worldscreen.status
import com.badlogic.gdx.scenes.scene2d.ui.Cell
import com.badlogic.gdx.scenes.scene2d.ui.Label
import com.unciv.logic.civilization.managers.TurnManager import com.unciv.logic.civilization.managers.TurnManager
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.components.UncivTooltip.Companion.addTooltip import com.unciv.ui.components.UncivTooltip.Companion.addTooltip
@ -12,21 +14,25 @@ import com.unciv.ui.components.input.onRightClick
import com.unciv.ui.images.IconTextButton import com.unciv.ui.images.IconTextButton
import com.unciv.ui.images.ImageGetter import com.unciv.ui.images.ImageGetter
import com.unciv.ui.popups.hasOpenPopups import com.unciv.ui.popups.hasOpenPopups
import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.ui.screens.worldscreen.WorldScreen import com.unciv.ui.screens.worldscreen.WorldScreen
import com.unciv.ui.screens.worldscreen.status.NextTurnAction.Default
import com.unciv.utils.Concurrency import com.unciv.utils.Concurrency
class NextTurnButton( class NextTurnButton(
private val worldScreen: WorldScreen private val worldScreen: WorldScreen
) : IconTextButton("", null, 30) { ) : IconTextButton("", null, 30) {
private var nextTurnAction = NextTurnAction.Default private var nextTurnAction = Default
private val unitsDueLabel = Label("", BaseScreen.skin)
private val unitsDueCell: Cell<Label>
init { init {
pad(15f) pad(15f)
onActivation { nextTurnAction.action(worldScreen) } onActivation { nextTurnAction.action(worldScreen) }
onRightClick { NextTurnMenu(stage, this, this, worldScreen) } onRightClick { NextTurnMenu(stage, this, this, worldScreen) }
keyShortcuts.add(KeyboardBinding.NextTurn) keyShortcuts.add(KeyboardBinding.NextTurn)
keyShortcuts.add(KeyboardBinding.NextTurnAlternate) keyShortcuts.add(KeyboardBinding.NextTurnAlternate)
// Let unit actions override this for command "Wait". labelCell.row()
keyShortcuts.add(KeyboardBinding.Wait, -99) unitsDueCell = add(unitsDueLabel).padTop(6f).colspan(2).center()
} }
fun update() { fun update() {
@ -52,9 +58,18 @@ class NextTurnButton(
label.setText(nextTurnAction.getText(worldScreen).tr()) label.setText(nextTurnAction.getText(worldScreen).tr())
label.color = nextTurnAction.color label.color = nextTurnAction.color
if (nextTurnAction.icon != null && ImageGetter.imageExists(nextTurnAction.icon!!)) if (nextTurnAction.icon != null && ImageGetter.imageExists(nextTurnAction.icon!!))
iconCell.setActor(ImageGetter.getImage(nextTurnAction.icon).apply { setSize(30f) }) iconCell.setActor(ImageGetter.getImage(nextTurnAction.icon).apply {
setSize(30f)
color = nextTurnAction.color
})
else else
iconCell.clearActor() iconCell.clearActor()
nextTurnAction.getSubText(worldScreen)?.let {
unitsDueLabel.setText(it.tr())
unitsDueCell.setActor(unitsDueLabel)
} ?: unitsDueCell.clearActor()
pack() pack()
} }