mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-12 00:39:56 +07:00
Next-Turn Progressbar (#9409)
* Next-Turn Progressbar * Next-Turn Progressbar - doc * NextTurnProgress: Rethink max on first turn
This commit is contained in:
@ -34,6 +34,7 @@ import com.unciv.models.ruleset.nation.Difficulty
|
|||||||
import com.unciv.models.ruleset.unique.UniqueType
|
import com.unciv.models.ruleset.unique.UniqueType
|
||||||
import com.unciv.ui.audio.MusicMood
|
import com.unciv.ui.audio.MusicMood
|
||||||
import com.unciv.ui.audio.MusicTrackChooserFlags
|
import com.unciv.ui.audio.MusicTrackChooserFlags
|
||||||
|
import com.unciv.ui.screens.worldscreen.status.NextTurnProgress
|
||||||
import com.unciv.utils.DebugUtils
|
import com.unciv.utils.DebugUtils
|
||||||
import com.unciv.utils.debug
|
import com.unciv.utils.debug
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
@ -277,7 +278,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
|||||||
fun isSimulation(): Boolean = turns < DebugUtils.SIMULATE_UNTIL_TURN
|
fun isSimulation(): Boolean = turns < DebugUtils.SIMULATE_UNTIL_TURN
|
||||||
|| turns < simulateMaxTurns && simulateUntilWin
|
|| turns < simulateMaxTurns && simulateUntilWin
|
||||||
|
|
||||||
fun nextTurn() {
|
fun nextTurn(progressBar: NextTurnProgress? = null) {
|
||||||
|
|
||||||
var player = currentPlayerCiv
|
var player = currentPlayerCiv
|
||||||
var playerIndex = civilizations.indexOf(player)
|
var playerIndex = civilizations.indexOf(player)
|
||||||
@ -299,7 +300,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
|||||||
// would skip a turn if an AI civ calls nextTurn
|
// would skip a turn if an AI civ calls nextTurn
|
||||||
// this happens when resigning a multiplayer game)
|
// this happens when resigning a multiplayer game)
|
||||||
if (player.isHuman()) {
|
if (player.isHuman()) {
|
||||||
TurnManager(player).endTurn()
|
TurnManager(player).endTurn(progressBar)
|
||||||
setNextPlayer()
|
setNextPlayer()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -314,7 +315,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
|||||||
{
|
{
|
||||||
|
|
||||||
// Starting preparations
|
// Starting preparations
|
||||||
TurnManager(player).startTurn()
|
TurnManager(player).startTurn(progressBar)
|
||||||
|
|
||||||
// Automation done here
|
// Automation done here
|
||||||
TurnManager(player).automateTurn()
|
TurnManager(player).automateTurn()
|
||||||
@ -326,7 +327,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Clean up
|
// Clean up
|
||||||
TurnManager(player).endTurn()
|
TurnManager(player).endTurn(progressBar)
|
||||||
|
|
||||||
// To the next player
|
// To the next player
|
||||||
setNextPlayer()
|
setNextPlayer()
|
||||||
@ -341,7 +342,7 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
|||||||
currentPlayerCiv = getCivilization(currentPlayer)
|
currentPlayerCiv = getCivilization(currentPlayer)
|
||||||
|
|
||||||
// Starting his turn
|
// Starting his turn
|
||||||
TurnManager(player).startTurn()
|
TurnManager(player).startTurn(progressBar)
|
||||||
|
|
||||||
// No popups for spectators
|
// No popups for spectators
|
||||||
if (currentPlayerCiv.isSpectator())
|
if (currentPlayerCiv.isSpectator())
|
||||||
|
@ -19,6 +19,7 @@ import com.unciv.models.ruleset.unique.UniqueType
|
|||||||
import com.unciv.models.ruleset.unique.endTurn
|
import com.unciv.models.ruleset.unique.endTurn
|
||||||
import com.unciv.models.stats.Stats
|
import com.unciv.models.stats.Stats
|
||||||
import com.unciv.ui.components.MayaCalendar
|
import com.unciv.ui.components.MayaCalendar
|
||||||
|
import com.unciv.ui.screens.worldscreen.status.NextTurnProgress
|
||||||
import com.unciv.utils.Log
|
import com.unciv.utils.Log
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
@ -27,7 +28,7 @@ import kotlin.random.Random
|
|||||||
class TurnManager(val civInfo: Civilization) {
|
class TurnManager(val civInfo: Civilization) {
|
||||||
|
|
||||||
|
|
||||||
fun startTurn() {
|
fun startTurn(progressBar: NextTurnProgress? = null) {
|
||||||
if (civInfo.isSpectator()) return
|
if (civInfo.isSpectator()) return
|
||||||
|
|
||||||
if (civInfo.isMajorCiv() && civInfo.isAlive()) {
|
if (civInfo.isMajorCiv() && civInfo.isAlive()) {
|
||||||
@ -66,7 +67,10 @@ class TurnManager(val civInfo: Civilization) {
|
|||||||
civInfo.cache.updateCitiesConnectedToCapital()
|
civInfo.cache.updateCitiesConnectedToCapital()
|
||||||
startTurnFlags()
|
startTurnFlags()
|
||||||
updateRevolts()
|
updateRevolts()
|
||||||
for (city in civInfo.cities) CityTurnManager(city).startTurn() // Most expensive part of startTurn
|
for (city in civInfo.cities) {
|
||||||
|
progressBar?.increment()
|
||||||
|
CityTurnManager(city).startTurn() // Most expensive part of startTurn
|
||||||
|
}
|
||||||
|
|
||||||
for (unit in civInfo.units.getCivUnits()) UnitTurnManager(unit).startTurn()
|
for (unit in civInfo.units.getCivUnits()) UnitTurnManager(unit).startTurn()
|
||||||
|
|
||||||
@ -218,7 +222,7 @@ class TurnManager(val civInfo: Civilization) {
|
|||||||
((4 + Random.Default.nextInt(3)) * max(civInfo.gameInfo.speed.modifier, 1f)).toInt()
|
((4 + Random.Default.nextInt(3)) * max(civInfo.gameInfo.speed.modifier, 1f)).toInt()
|
||||||
|
|
||||||
|
|
||||||
fun endTurn() {
|
fun endTurn(progressBar: NextTurnProgress? = null) {
|
||||||
val notificationsLog = civInfo.notificationsLog
|
val notificationsLog = civInfo.notificationsLog
|
||||||
val notificationsThisTurn = Civilization.NotificationsLog(civInfo.gameInfo.turns)
|
val notificationsThisTurn = Civilization.NotificationsLog(civInfo.gameInfo.turns)
|
||||||
notificationsThisTurn.notifications.addAll(civInfo.notifications)
|
notificationsThisTurn.notifications.addAll(civInfo.notifications)
|
||||||
@ -278,8 +282,10 @@ class TurnManager(val civInfo: Civilization) {
|
|||||||
|
|
||||||
// To handle tile's owner issue (#8246), we need to run cities being razed first.
|
// To handle tile's owner issue (#8246), we need to run cities being razed first.
|
||||||
// a city can be removed while iterating (if it's being razed) so we need to iterate over a copy - sorting does one
|
// a city can be removed while iterating (if it's being razed) so we need to iterate over a copy - sorting does one
|
||||||
for (city in civInfo.cities.sortedByDescending { it.isBeingRazed })
|
for (city in civInfo.cities.sortedByDescending { it.isBeingRazed }) {
|
||||||
|
progressBar?.increment()
|
||||||
CityTurnManager(city).endTurn()
|
CityTurnManager(city).endTurn()
|
||||||
|
}
|
||||||
|
|
||||||
civInfo.temporaryUniques.endTurn()
|
civInfo.temporaryUniques.endTurn()
|
||||||
|
|
||||||
|
@ -57,6 +57,7 @@ import com.unciv.ui.screens.worldscreen.bottombar.TileInfoTable
|
|||||||
import com.unciv.ui.screens.worldscreen.minimap.MinimapHolder
|
import com.unciv.ui.screens.worldscreen.minimap.MinimapHolder
|
||||||
import com.unciv.ui.screens.worldscreen.status.MultiplayerStatusButton
|
import com.unciv.ui.screens.worldscreen.status.MultiplayerStatusButton
|
||||||
import com.unciv.ui.screens.worldscreen.status.NextTurnButton
|
import com.unciv.ui.screens.worldscreen.status.NextTurnButton
|
||||||
|
import com.unciv.ui.screens.worldscreen.status.NextTurnProgress
|
||||||
import com.unciv.ui.screens.worldscreen.status.StatusButtons
|
import com.unciv.ui.screens.worldscreen.status.StatusButtons
|
||||||
import com.unciv.ui.screens.worldscreen.unit.UnitTable
|
import com.unciv.ui.screens.worldscreen.unit.UnitTable
|
||||||
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsTable
|
import com.unciv.ui.screens.worldscreen.unit.actions.UnitActionsTable
|
||||||
@ -557,6 +558,8 @@ class WorldScreen(
|
|||||||
fun nextTurn() {
|
fun nextTurn() {
|
||||||
isPlayersTurn = false
|
isPlayersTurn = false
|
||||||
shouldUpdate = true
|
shouldUpdate = true
|
||||||
|
val progressBar = NextTurnProgress(nextTurnButton)
|
||||||
|
progressBar.start(this)
|
||||||
|
|
||||||
// on a separate thread so the user can explore their world while we're passing the turn
|
// on a separate thread so the user can explore their world while we're passing the turn
|
||||||
nextTurnUpdateJob = Concurrency.runOnNonDaemonThreadPool("NextTurn") {
|
nextTurnUpdateJob = Concurrency.runOnNonDaemonThreadPool("NextTurn") {
|
||||||
@ -566,7 +569,9 @@ class WorldScreen(
|
|||||||
val gameInfoClone = originalGameInfo.clone()
|
val gameInfoClone = originalGameInfo.clone()
|
||||||
gameInfoClone.setTransients() // this can get expensive on large games, not the clone itself
|
gameInfoClone.setTransients() // this can get expensive on large games, not the clone itself
|
||||||
|
|
||||||
gameInfoClone.nextTurn()
|
progressBar.increment()
|
||||||
|
|
||||||
|
gameInfoClone.nextTurn(progressBar)
|
||||||
|
|
||||||
if (originalGameInfo.gameParameters.isOnlineMultiplayer) {
|
if (originalGameInfo.gameParameters.isOnlineMultiplayer) {
|
||||||
try {
|
try {
|
||||||
@ -617,6 +622,8 @@ class WorldScreen(
|
|||||||
gameInfoClone.isUpToDate = true
|
gameInfoClone.isUpToDate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
progressBar.increment()
|
||||||
|
|
||||||
startNewScreenJob(gameInfoClone)
|
startNewScreenJob(gameInfoClone)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -713,7 +720,7 @@ class WorldScreen(
|
|||||||
displayTutorial(TutorialTrigger.LuxuryResource) { resources.any { it.resource.resourceType == ResourceType.Luxury } }
|
displayTutorial(TutorialTrigger.LuxuryResource) { resources.any { it.resource.resourceType == ResourceType.Luxury } }
|
||||||
displayTutorial(TutorialTrigger.StrategicResource) { resources.any { it.resource.resourceType == ResourceType.Strategic } }
|
displayTutorial(TutorialTrigger.StrategicResource) { resources.any { it.resource.resourceType == ResourceType.Strategic } }
|
||||||
displayTutorial(TutorialTrigger.EnemyCity) {
|
displayTutorial(TutorialTrigger.EnemyCity) {
|
||||||
viewingCiv.getKnownCivs().asSequence().filter { viewingCiv.isAtWarWith(it) }
|
viewingCiv.getKnownCivs().filter { viewingCiv.isAtWarWith(it) }
|
||||||
.flatMap { it.cities.asSequence() }.any { viewingCiv.hasExplored(it.getCenterTile()) }
|
.flatMap { it.cities.asSequence() }.any { viewingCiv.hasExplored(it.getCenterTile()) }
|
||||||
}
|
}
|
||||||
displayTutorial(TutorialTrigger.ApolloProgram) { viewingCiv.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts) }
|
displayTutorial(TutorialTrigger.ApolloProgram) { viewingCiv.hasUnique(UniqueType.EnablesConstructionOfSpaceshipParts) }
|
||||||
|
@ -27,7 +27,7 @@ import com.unciv.utils.Concurrency
|
|||||||
import com.unciv.utils.launchOnGLThread
|
import com.unciv.utils.launchOnGLThread
|
||||||
|
|
||||||
class NextTurnButton : IconTextButton("", null, 30) {
|
class NextTurnButton : IconTextButton("", null, 30) {
|
||||||
private var nextTurnAction = NextTurnAction("", Color.BLACK) {}
|
private var nextTurnAction = NextTurnAction.Default
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// label.setFontSize(30)
|
// label.setFontSize(30)
|
||||||
@ -41,29 +41,31 @@ class NextTurnButton : IconTextButton("", null, 30) {
|
|||||||
|
|
||||||
fun update(worldScreen: WorldScreen) {
|
fun update(worldScreen: WorldScreen) {
|
||||||
nextTurnAction = getNextTurnAction(worldScreen)
|
nextTurnAction = getNextTurnAction(worldScreen)
|
||||||
|
updateButton(nextTurnAction)
|
||||||
|
|
||||||
|
isEnabled = !worldScreen.hasOpenPopups() && worldScreen.isPlayersTurn
|
||||||
|
&& !worldScreen.waitingForAutosave && !worldScreen.isNextTurnUpdateRunning()
|
||||||
|
}
|
||||||
|
internal fun updateButton(nextTurnAction: NextTurnAction) {
|
||||||
label.setText(nextTurnAction.text.tr())
|
label.setText(nextTurnAction.text.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) })
|
||||||
else
|
else
|
||||||
iconCell.clearActor()
|
iconCell.clearActor()
|
||||||
pack()
|
pack()
|
||||||
|
|
||||||
isEnabled = !worldScreen.hasOpenPopups() && worldScreen.isPlayersTurn
|
|
||||||
&& !worldScreen.waitingForAutosave && !worldScreen.isNextTurnUpdateRunning()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private fun getNextTurnAction(worldScreen: WorldScreen): NextTurnAction {
|
private fun getNextTurnAction(worldScreen: WorldScreen): NextTurnAction {
|
||||||
return when {
|
return when {
|
||||||
worldScreen.isNextTurnUpdateRunning() ->
|
worldScreen.isNextTurnUpdateRunning() ->
|
||||||
NextTurnAction("Working...", Color.GRAY, "NotificationIcons/Working") {}
|
NextTurnAction.Working
|
||||||
!worldScreen.isPlayersTurn && worldScreen.gameInfo.gameParameters.isOnlineMultiplayer ->
|
!worldScreen.isPlayersTurn && worldScreen.gameInfo.gameParameters.isOnlineMultiplayer ->
|
||||||
NextTurnAction("Waiting for [${worldScreen.gameInfo.currentPlayerCiv}]...", Color.GRAY,
|
NextTurnAction("Waiting for [${worldScreen.gameInfo.currentPlayerCiv}]...", Color.GRAY,
|
||||||
"NotificationIcons/Waiting") {}
|
"NotificationIcons/Waiting") {}
|
||||||
!worldScreen.isPlayersTurn && !worldScreen.gameInfo.gameParameters.isOnlineMultiplayer ->
|
!worldScreen.isPlayersTurn && !worldScreen.gameInfo.gameParameters.isOnlineMultiplayer ->
|
||||||
NextTurnAction("Waiting for other players...",Color.GRAY,
|
NextTurnAction.Waiting
|
||||||
"NotificationIcons/Waiting") {}
|
|
||||||
|
|
||||||
worldScreen.viewingCiv.cities.any {
|
worldScreen.viewingCiv.cities.any {
|
||||||
!it.isPuppet &&
|
!it.isPuppet &&
|
||||||
@ -185,7 +187,12 @@ class NextTurnButton : IconTextButton("", null, 30) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class NextTurnAction(val text: String, val color: Color, val icon: String? = null, val action: () -> Unit)
|
class NextTurnAction(val text: String, val color: Color, val icon: String? = null, val action: () -> Unit) {
|
||||||
|
companion object Prefabs {
|
||||||
|
val Default = NextTurnAction("", Color.BLACK) {}
|
||||||
|
val Working = NextTurnAction("Working...", Color.GRAY, "NotificationIcons/Working") {}
|
||||||
|
val Waiting = NextTurnAction("Waiting for other players...",Color.GRAY, "NotificationIcons/Waiting") {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
package com.unciv.ui.screens.worldscreen.status
|
||||||
|
|
||||||
|
import com.badlogic.gdx.graphics.Color
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
|
import com.unciv.GUI
|
||||||
|
import com.unciv.models.metadata.GameParameters
|
||||||
|
import com.unciv.ui.components.extensions.disable
|
||||||
|
import com.unciv.ui.images.ImageGetter
|
||||||
|
import com.unciv.ui.screens.basescreen.BaseScreen
|
||||||
|
import com.unciv.ui.screens.worldscreen.WorldScreen
|
||||||
|
import com.unciv.utils.Concurrency
|
||||||
|
import com.unciv.utils.Log
|
||||||
|
|
||||||
|
class NextTurnProgress(
|
||||||
|
// nullable so we can free the reference once the ProgressBar is shown
|
||||||
|
private var nextTurnButton: NextTurnButton?
|
||||||
|
) : Table() {
|
||||||
|
companion object {
|
||||||
|
/** Background tint will be color of the right (shrinking) part of the bar - UI mods can override this */
|
||||||
|
private val defaultRightColor = Color(0x600000ff)
|
||||||
|
/** Minimum Height of the bar if the moddable background has no minHeight */
|
||||||
|
private const val defaultBarHeight = 4f
|
||||||
|
/** Distance from bottom of NextTurnButton */
|
||||||
|
private const val barYPos = 1f
|
||||||
|
/** Bar width is NextTurnButton.width minus background ninepatch's declared outer widths minus this */
|
||||||
|
private const val removeHorizontalPad = 25f
|
||||||
|
/** Speed of fading the bar in when it starts being rendered */
|
||||||
|
private const val fadeInDuration = 1f
|
||||||
|
}
|
||||||
|
|
||||||
|
private var progress = -1
|
||||||
|
private var progressMax = 0
|
||||||
|
private var isDirty = false
|
||||||
|
private var barWidth = 0f
|
||||||
|
|
||||||
|
// Since we do UI update coroutine-decoupled there's a potential race conditon where the worldScreen
|
||||||
|
// gets replaced, and a pending update comes too late. To prevent re-showing when it's outdated we
|
||||||
|
// keep a hash in lieu of a weak reference - a normal reference might keep an outdated WorldScreen from
|
||||||
|
// being garbage collected, and java.lang.ref.WeakReference.refersTo requires a language level 16 opt-in.
|
||||||
|
private var worldScreenHash = 0
|
||||||
|
|
||||||
|
init {
|
||||||
|
background = BaseScreen.skinStrings.getUiBackground("WorldScreen/NextTurn/ProgressBar", tintColor = defaultRightColor)
|
||||||
|
val leftColor = BaseScreen.skinStrings.getUIColor("WorldScreen/NextTurn/ProgressColor", Color.FOREST)
|
||||||
|
add(ImageGetter.getDot(leftColor)) // active bar part
|
||||||
|
add() // Empty cell for the remainder portion of the bar
|
||||||
|
}
|
||||||
|
|
||||||
|
fun start(worldScreen: WorldScreen) {
|
||||||
|
progress = 0
|
||||||
|
val game = worldScreen.gameInfo
|
||||||
|
worldScreenHash = worldScreen.hashCode()
|
||||||
|
|
||||||
|
fun GameParameters.isRandomNumberOfCivs() = randomNumberOfPlayers || randomNumberOfCityStates
|
||||||
|
fun GameParameters.minNumberOfCivs() =
|
||||||
|
(if (randomNumberOfPlayers) minNumberOfPlayers else players.size) +
|
||||||
|
(if (randomNumberOfCityStates) minNumberOfCityStates else numberOfCityStates)
|
||||||
|
|
||||||
|
progressMax = 3 + // one extra step after clone and just before new worldscreen, 1 extra so it's never 100%
|
||||||
|
when {
|
||||||
|
// Later turns = two steps per city (startTurn and endTurn)
|
||||||
|
// Note we ignore cities being founded or destroyed - after turn 0 that proportion
|
||||||
|
// should be small, so the bar may clamp at max for a short while;
|
||||||
|
// or the new WordScreen starts before it's full. Far simpler code this way.
|
||||||
|
game.turns > 0 -> game.getCities().count() * 2
|
||||||
|
// If we shouldn't disclose how many civs there are to Mr. Eagle Eye counting steps:
|
||||||
|
game.gameParameters.isRandomNumberOfCivs() -> game.gameParameters.minNumberOfCivs()
|
||||||
|
// One step per expected city to be founded (they get an endTurn, no startTurn)
|
||||||
|
else -> game.civilizations.count { it.isMajorCiv() && it.isAI() || it.isCityState() }
|
||||||
|
}
|
||||||
|
|
||||||
|
startUpdateProgress()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun increment() {
|
||||||
|
progress++
|
||||||
|
startUpdateProgress()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun startUpdateProgress() {
|
||||||
|
isDirty = true
|
||||||
|
Concurrency.runOnGLThread {
|
||||||
|
updateProgress()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun updateProgress() {
|
||||||
|
if (!isDirty) return
|
||||||
|
isDirty = false
|
||||||
|
|
||||||
|
val currentWorldScreenHash = GUI.getWorldScreenIfActive()?.hashCode() ?: -1
|
||||||
|
if (progressMax == 0 || currentWorldScreenHash != worldScreenHash) {
|
||||||
|
remove()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// On first update the button text is not yet updated. To stabilize geometry, do it now
|
||||||
|
if (progress == 0) nextTurnButton?.apply {
|
||||||
|
disable()
|
||||||
|
updateButton(NextTurnAction.Working)
|
||||||
|
barWidth = width - removeHorizontalPad -
|
||||||
|
(background.leftWidth + background.rightWidth) // "cut off" the rounded parts of the button
|
||||||
|
this@NextTurnProgress.setPosition((width - barWidth) / 2, barYPos)
|
||||||
|
}
|
||||||
|
|
||||||
|
val cellWidth = barWidth * progress.coerceAtMost(progressMax) / progressMax
|
||||||
|
val cellHeight = background.minHeight.coerceAtLeast(defaultBarHeight)
|
||||||
|
cells[0].actor.setSize(cellWidth, cellHeight)
|
||||||
|
cells[1].width(barWidth - cellWidth) // Necessary - Table has a quirk so a simple fillX() won't shrink
|
||||||
|
setSize(barWidth, defaultBarHeight)
|
||||||
|
|
||||||
|
if (parent == null) {
|
||||||
|
color.a = 0f
|
||||||
|
nextTurnButton?.addActor(this)
|
||||||
|
addAction(Actions.fadeIn(fadeInDuration)) // Also helps hide the jerkiness when many cities are founded on turn 0
|
||||||
|
nextTurnButton = null // Release reference as early as possible
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -21,14 +21,15 @@ class UiElementDocsWriter {
|
|||||||
|
|
||||||
val elements = mutableListOf<String>()
|
val elements = mutableListOf<String>()
|
||||||
val backgroundRegex = Regex("""getUiBackground\((\X*?)"(?<path>.*)"[ ,\n\r]*((BaseScreen\.)?skinStrings\.(?<default>.*)Shape)?\X*?\)""")
|
val backgroundRegex = Regex("""getUiBackground\((\X*?)"(?<path>.*)"[ ,\n\r]*((BaseScreen\.)?skinStrings\.(?<default>.*)Shape)?\X*?\)""")
|
||||||
|
@Suppress("RegExpRepeatedSpace") // IDE doesn't know about commented RegExes
|
||||||
val colorRegex = Regex("""
|
val colorRegex = Regex("""
|
||||||
getUIColor\s*\(\s* # function call, whitespace around opening round bracket optional. All \s also allow line breaks!
|
getUIColor\s*\(\s* # function call, whitespace around opening round bracket optional. All \s also allow line breaks!
|
||||||
"(?<path>[^"]*)"\s* # captures "path", anything between double-quotes, not allowing for embedded quotes
|
"(?<path>[^"]*)"\s* # captures "path", anything between double-quotes, not allowing for embedded quotes
|
||||||
(?:,\s* # group for optional default parameter
|
(?:,\s* # group for optional default parameter
|
||||||
(?:default\s*=\s*)? # allow for named parameter
|
(?:default\s*=\s*)? # allow for named parameter
|
||||||
(?:Colors\s*\(|colorFromRGB\s*\(|Color\.) # recognize only Color constructor, colorFromRGB helper, or Color.* constants as argument
|
(?:Color\s*\(|colorFromRGB\s*\(|Color\.) # recognize only Color constructor, colorFromRGB helper, or Color.* constants as argument
|
||||||
(?<default>[^)]*) # capture "default" up until a closing round bracket
|
(?<default>[^)]*) # capture "default" up until a closing round bracket
|
||||||
)\s*\) # ends default parameter group and checks closing round bracket of the getUIColor call
|
)?\s*\) # ends default parameter group and checks closing round bracket of the getUIColor call
|
||||||
""", RegexOption.COMMENTS)
|
""", RegexOption.COMMENTS)
|
||||||
|
|
||||||
for (file in srcFile.walk()) {
|
for (file in srcFile.walk()) {
|
||||||
|
@ -107,6 +107,8 @@ These shapes are used all over Unciv and can be replaced to make a lot of UI ele
|
|||||||
| WorldScreen/CityButton/ | InfluenceBar | null | |
|
| WorldScreen/CityButton/ | InfluenceBar | null | |
|
||||||
| WorldScreen/Minimap/ | Background | null | |
|
| WorldScreen/Minimap/ | Background | null | |
|
||||||
| WorldScreen/Minimap/ | Border | null | |
|
| WorldScreen/Minimap/ | Border | null | |
|
||||||
|
| WorldScreen/NextTurn/ | ProgressBar | null | |
|
||||||
|
| WorldScreen/NextTurn/ | ProgressColor | FOREST | |
|
||||||
| WorldScreen/TopBar/ | LeftAttachment | roundedEdgeRectangle | |
|
| WorldScreen/TopBar/ | LeftAttachment | roundedEdgeRectangle | |
|
||||||
| WorldScreen/TopBar/ | ResourceTable | null | |
|
| WorldScreen/TopBar/ | ResourceTable | null | |
|
||||||
| WorldScreen/TopBar/ | RightAttachment | roundedEdgeRectangle | |
|
| WorldScreen/TopBar/ | RightAttachment | roundedEdgeRectangle | |
|
||||||
|
Reference in New Issue
Block a user