mirror of
https://github.com/yairm210/Unciv.git
synced 2025-09-30 07:21:34 -04:00
Refactor: Change UncivGame.worldScreen and UncivGame.gameInfo to be of nullable type (#7114)
* Refactor: Make Popups work on Stages instead of BaseScreens * Refactor: Change UncivGame.worldScreen and UncivGame.gameInfo to be of nullable type * Fix "Resume" game loading not fully handling exceptions * Fix one missed refactoring * Refactor: remove useless postRunnable
This commit is contained in:
parent
72b197fdc3
commit
9008d242a3
@ -70,13 +70,13 @@ open class AndroidLauncher : AndroidApplication() {
|
|||||||
|
|
||||||
override fun onPause() {
|
override fun onPause() {
|
||||||
if (UncivGame.isCurrentInitialized()
|
if (UncivGame.isCurrentInitialized()
|
||||||
&& UncivGame.Current.isGameInfoInitialized()
|
&& UncivGame.Current.gameInfo != null
|
||||||
&& UncivGame.Current.settings.multiplayer.turnCheckerEnabled
|
&& UncivGame.Current.settings.multiplayer.turnCheckerEnabled
|
||||||
&& UncivGame.Current.gameSaver.getMultiplayerSaves().any()
|
&& UncivGame.Current.gameSaver.getMultiplayerSaves().any()
|
||||||
) {
|
) {
|
||||||
MultiplayerTurnCheckWorker.startTurnChecker(
|
MultiplayerTurnCheckWorker.startTurnChecker(
|
||||||
applicationContext, UncivGame.Current.gameSaver,
|
applicationContext, UncivGame.Current.gameSaver,
|
||||||
UncivGame.Current.gameInfo, UncivGame.Current.settings.multiplayer
|
UncivGame.Current.gameInfo!!, UncivGame.Current.settings.multiplayer
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
super.onPause()
|
super.onPause()
|
||||||
|
@ -198,7 +198,7 @@ class MainMenuScreen: BaseScreen() {
|
|||||||
|
|
||||||
|
|
||||||
private fun resumeGame() {
|
private fun resumeGame() {
|
||||||
val curWorldScreen = game.getWorldScreenOrNull()
|
val curWorldScreen = game.worldScreen
|
||||||
if (curWorldScreen != null) {
|
if (curWorldScreen != null) {
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
curWorldScreen.popups.filterIsInstance(WorldScreenMenuPopup::class.java).forEach(Popup::close)
|
curWorldScreen.popups.filterIsInstance(WorldScreenMenuPopup::class.java).forEach(Popup::close)
|
||||||
|
@ -4,6 +4,7 @@ import com.badlogic.gdx.Application
|
|||||||
import com.badlogic.gdx.Game
|
import com.badlogic.gdx.Game
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
import com.badlogic.gdx.Input
|
import com.badlogic.gdx.Input
|
||||||
|
import com.badlogic.gdx.Screen
|
||||||
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
import com.badlogic.gdx.scenes.scene2d.actions.Actions
|
||||||
import com.badlogic.gdx.utils.Align
|
import com.badlogic.gdx.utils.Align
|
||||||
import com.unciv.logic.GameInfo
|
import com.unciv.logic.GameInfo
|
||||||
@ -22,13 +23,13 @@ import com.unciv.ui.audio.SoundPlayer
|
|||||||
import com.unciv.ui.crashhandling.closeExecutors
|
import com.unciv.ui.crashhandling.closeExecutors
|
||||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||||
|
import com.unciv.ui.crashhandling.wrapCrashHandlingUnit
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.multiplayer.LoadDeepLinkScreen
|
import com.unciv.ui.multiplayer.LoadDeepLinkScreen
|
||||||
import com.unciv.ui.multiplayer.MultiplayerHelpers
|
import com.unciv.ui.multiplayer.MultiplayerHelpers
|
||||||
import com.unciv.ui.popup.Popup
|
import com.unciv.ui.popup.Popup
|
||||||
import com.unciv.ui.utils.BaseScreen
|
import com.unciv.ui.utils.BaseScreen
|
||||||
import com.unciv.ui.utils.extensions.center
|
import com.unciv.ui.utils.extensions.center
|
||||||
import com.unciv.ui.crashhandling.wrapCrashHandlingUnit
|
|
||||||
import com.unciv.ui.worldscreen.PlayerReadyScreen
|
import com.unciv.ui.worldscreen.PlayerReadyScreen
|
||||||
import com.unciv.ui.worldscreen.WorldScreen
|
import com.unciv.ui.worldscreen.WorldScreen
|
||||||
import com.unciv.utils.debug
|
import com.unciv.utils.debug
|
||||||
@ -49,8 +50,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
private val audioExceptionHelper = parameters.audioExceptionHelper
|
private val audioExceptionHelper = parameters.audioExceptionHelper
|
||||||
|
|
||||||
var deepLinkedMultiplayerGame: String? = null
|
var deepLinkedMultiplayerGame: String? = null
|
||||||
lateinit var gameInfo: GameInfo
|
var gameInfo: GameInfo? = null
|
||||||
fun isGameInfoInitialized() = this::gameInfo.isInitialized
|
|
||||||
lateinit var settings: GameSettings
|
lateinit var settings: GameSettings
|
||||||
lateinit var musicController: MusicController
|
lateinit var musicController: MusicController
|
||||||
lateinit var onlineMultiplayer: OnlineMultiplayer
|
lateinit var onlineMultiplayer: OnlineMultiplayer
|
||||||
@ -70,9 +70,8 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
*/
|
*/
|
||||||
var simulateUntilTurnForDebug: Int = 0
|
var simulateUntilTurnForDebug: Int = 0
|
||||||
|
|
||||||
lateinit var worldScreen: WorldScreen
|
var worldScreen: WorldScreen? = null
|
||||||
private set
|
private set
|
||||||
fun getWorldScreenOrNull() = if (this::worldScreen.isInitialized) worldScreen else null
|
|
||||||
|
|
||||||
var isInitialized = false
|
var isInitialized = false
|
||||||
|
|
||||||
@ -105,7 +104,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
* - Font (hence Fonts.resetFont() inside setSkin())
|
* - Font (hence Fonts.resetFont() inside setSkin())
|
||||||
*/
|
*/
|
||||||
settings = gameSaver.getGeneralSettings() // needed for the screen
|
settings = gameSaver.getGeneralSettings() // needed for the screen
|
||||||
screen = LoadingScreen() // NOT dependent on any atlas or skin
|
setScreen(LoadingScreen()) // NOT dependent on any atlas or skin
|
||||||
GameSounds.init()
|
GameSounds.init()
|
||||||
musicController = MusicController() // early, but at this point does only copy volume from settings
|
musicController = MusicController() // early, but at this point does only copy volume from settings
|
||||||
audioExceptionHelper?.installHooks(
|
audioExceptionHelper?.installHooks(
|
||||||
@ -152,49 +151,66 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun loadGame(gameInfo: GameInfo) {
|
fun loadGame(gameInfo: GameInfo): WorldScreen {
|
||||||
this.gameInfo = gameInfo
|
this.gameInfo = gameInfo
|
||||||
ImageGetter.setNewRuleset(gameInfo.ruleSet)
|
ImageGetter.setNewRuleset(gameInfo.ruleSet)
|
||||||
// Clone the mod list and add the base ruleset to it
|
// Clone the mod list and add the base ruleset to it
|
||||||
val fullModList = gameInfo.gameParameters.getModsAndBaseRuleset()
|
val fullModList = gameInfo.gameParameters.getModsAndBaseRuleset()
|
||||||
musicController.setModList(fullModList)
|
musicController.setModList(fullModList)
|
||||||
Gdx.input.inputProcessor = null // Since we will set the world screen when we're ready,
|
Gdx.input.inputProcessor = null // Since we will set the world screen when we're ready,
|
||||||
if (gameInfo.civilizations.count { it.playerType == PlayerType.Human } > 1 && !gameInfo.gameParameters.isOnlineMultiplayer)
|
val worldScreen = WorldScreen(gameInfo, gameInfo.getPlayerToViewAs())
|
||||||
setScreen(PlayerReadyScreen(gameInfo, gameInfo.getPlayerToViewAs()))
|
val newScreen = if (gameInfo.civilizations.count { it.playerType == PlayerType.Human } > 1 && !gameInfo.gameParameters.isOnlineMultiplayer)
|
||||||
|
PlayerReadyScreen(worldScreen)
|
||||||
else {
|
else {
|
||||||
resetToWorldScreen(WorldScreen(gameInfo, gameInfo.getPlayerToViewAs()))
|
worldScreen
|
||||||
}
|
}
|
||||||
}
|
setScreen(newScreen)
|
||||||
|
return worldScreen
|
||||||
fun setScreen(screen: BaseScreen) {
|
|
||||||
val oldScreen = getScreen()
|
|
||||||
Gdx.input.inputProcessor = screen.stage
|
|
||||||
super.setScreen(screen)
|
|
||||||
if (oldScreen != getWorldScreenOrNull()) oldScreen.dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If called with null [newWorldScreen], disposes of the current screen and sets it to the current stored world screen.
|
* Sets the screen of the game and automatically disposes the old screen as long as it isn't the world screen.
|
||||||
* If the current screen is already the world screen, the only thing that happens is that the world screen updates.
|
*
|
||||||
|
* @param screen must be a subclass of [BaseScreen].
|
||||||
*/
|
*/
|
||||||
fun resetToWorldScreen(newWorldScreen: WorldScreen? = null) {
|
override fun setScreen(screen: Screen) {
|
||||||
if (newWorldScreen != null) {
|
if (screen !is BaseScreen) throw IllegalArgumentException("Call to setScreen with screen that does not inherit BaseScreen: " + screen.javaClass.simpleName)
|
||||||
debug("Reset to new WorldScreen, gameId: %s, turn: %s, curCiv: %s",
|
setScreen(screen)
|
||||||
newWorldScreen.gameInfo.gameId, newWorldScreen.gameInfo.turns, newWorldScreen.gameInfo.currentPlayer)
|
|
||||||
val oldWorldScreen = getWorldScreenOrNull()
|
|
||||||
worldScreen = newWorldScreen
|
|
||||||
// setScreen disposes the current screen, but the old world screen is not the current screen, so need to dispose here
|
|
||||||
if (screen != oldWorldScreen) {
|
|
||||||
oldWorldScreen?.dispose()
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
val oldWorldScreen = getWorldScreenOrNull()!!
|
override fun getScreen(): BaseScreen? {
|
||||||
debug("Reset to old WorldScreen, gameId: %s, turn: %s, curCiv: %s",
|
val curScreen = super.getScreen()
|
||||||
oldWorldScreen.gameInfo.gameId, oldWorldScreen.gameInfo.turns, oldWorldScreen.gameInfo.currentPlayer)
|
return if (curScreen == null) { null } else { curScreen as BaseScreen }
|
||||||
}
|
}
|
||||||
setScreen(worldScreen)
|
|
||||||
worldScreen.shouldUpdate = true // This can set the screen to the policy picker or tech picker screen, so the input processor must come before
|
/** Sets the screen of the game and automatically [disposes][Screen.dispose] the old screen as long as it isn't the world screen. */
|
||||||
|
fun setScreen(newScreen: BaseScreen) {
|
||||||
|
if (newScreen is WorldScreen) {
|
||||||
|
debug(
|
||||||
|
"Setting new world screen: gameId: %s, turn: %s, curCiv: %s",
|
||||||
|
newScreen.gameInfo.gameId, newScreen.gameInfo.turns, newScreen.gameInfo.currentPlayer
|
||||||
|
)
|
||||||
|
if (newScreen != worldScreen) worldScreen?.dispose()
|
||||||
|
worldScreen = newScreen
|
||||||
|
newScreen.shouldUpdate = true
|
||||||
Gdx.graphics.requestRendering()
|
Gdx.graphics.requestRendering()
|
||||||
|
} else {
|
||||||
|
debug("Setting new screen: %s", newScreen)
|
||||||
|
}
|
||||||
|
|
||||||
|
val oldScreen = screen
|
||||||
|
Gdx.input.inputProcessor = newScreen.stage
|
||||||
|
super.setScreen(newScreen) // This can set the screen to the policy picker or tech picker screen, so the input processor must be set before
|
||||||
|
if (oldScreen !is WorldScreen) { // we want to keep the world screen around, because it's expensive to re-create it
|
||||||
|
oldScreen?.dispose()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Resets the game to the stored world screen and automatically [disposes][Screen.dispose] the old screen.
|
||||||
|
*/
|
||||||
|
fun resetToWorldScreen() {
|
||||||
|
setScreen(worldScreen!!)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun tryLoadDeepLinkedGame() = launchCrashHandling("LoadDeepLinkedGame") {
|
private fun tryLoadDeepLinkedGame() = launchCrashHandling("LoadDeepLinkedGame") {
|
||||||
@ -233,7 +249,8 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun pause() {
|
override fun pause() {
|
||||||
if (isGameInfoInitialized()) gameSaver.autoSave(this.gameInfo)
|
val curGameInfo = gameInfo
|
||||||
|
if (curGameInfo != null) gameSaver.autoSave(curGameInfo)
|
||||||
musicController.pause()
|
musicController.pause()
|
||||||
super.pause()
|
super.pause()
|
||||||
}
|
}
|
||||||
@ -252,14 +269,15 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
if (::musicController.isInitialized) musicController.gracefulShutdown() // Do allow fade-out
|
if (::musicController.isInitialized) musicController.gracefulShutdown() // Do allow fade-out
|
||||||
closeExecutors()
|
closeExecutors()
|
||||||
|
|
||||||
if (isGameInfoInitialized()) {
|
val curGameInfo = gameInfo
|
||||||
|
if (curGameInfo != null) {
|
||||||
val autoSaveJob = gameSaver.autoSaveJob
|
val autoSaveJob = gameSaver.autoSaveJob
|
||||||
if (autoSaveJob != null && autoSaveJob.isActive) {
|
if (autoSaveJob != null && autoSaveJob.isActive) {
|
||||||
// auto save is already in progress (e.g. started by onPause() event)
|
// auto save is already in progress (e.g. started by onPause() event)
|
||||||
// let's allow it to finish and do not try to autosave second time
|
// let's allow it to finish and do not try to autosave second time
|
||||||
autoSaveJob.join()
|
autoSaveJob.join()
|
||||||
} else {
|
} else {
|
||||||
gameSaver.autoSaveSingleThreaded(gameInfo) // NO new thread
|
gameSaver.autoSaveSingleThreaded(curGameInfo) // NO new thread
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings.save()
|
settings.save()
|
||||||
@ -277,10 +295,15 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Returns the [worldScreen] if it is the currently active screen of the game */
|
||||||
|
fun getWorldScreenIfActive(): WorldScreen? {
|
||||||
|
return if (screen == worldScreen) worldScreen else null
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
lateinit var Current: UncivGame
|
lateinit var Current: UncivGame
|
||||||
fun isCurrentInitialized() = this::Current.isInitialized
|
fun isCurrentInitialized() = this::Current.isInitialized
|
||||||
fun isCurrentGame(gameId: String): Boolean = isCurrentInitialized() && Current.isGameInfoInitialized() && Current.gameInfo.gameId == gameId
|
fun isCurrentGame(gameId: String): Boolean = isCurrentInitialized() && Current.gameInfo != null && Current.gameInfo!!.gameId == gameId
|
||||||
fun isDeepLinkedGameLoading() = isCurrentInitialized() && Current.deepLinkedMultiplayerGame != null
|
fun isDeepLinkedGameLoading() = isCurrentInitialized() && Current.deepLinkedMultiplayerGame != null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,7 +208,7 @@ object Battle {
|
|||||||
|
|
||||||
// CS friendship from killing barbarians
|
// CS friendship from killing barbarians
|
||||||
if (defeatedUnit.matchesCategory("Barbarian") && defeatedUnit.matchesCategory("Military") && civUnit.getCivInfo().isMajorCiv()) {
|
if (defeatedUnit.matchesCategory("Barbarian") && defeatedUnit.matchesCategory("Military") && civUnit.getCivInfo().isMajorCiv()) {
|
||||||
for (cityState in UncivGame.Current.gameInfo.getAliveCityStates()) {
|
for (cityState in UncivGame.Current.gameInfo!!.getAliveCityStates()) {
|
||||||
if (civUnit.getCivInfo().knows(cityState) && defeatedUnit.unit.threatensCiv(cityState)) {
|
if (civUnit.getCivInfo().knows(cityState) && defeatedUnit.unit.threatensCiv(cityState)) {
|
||||||
cityState.cityStateFunctions.threateningBarbarianKilledBy(civUnit.getCivInfo())
|
cityState.cityStateFunctions.threateningBarbarianKilledBy(civUnit.getCivInfo())
|
||||||
}
|
}
|
||||||
@ -216,7 +216,7 @@ object Battle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CS war with major pseudo-quest
|
// CS war with major pseudo-quest
|
||||||
for (cityState in UncivGame.Current.gameInfo.getAliveCityStates()) {
|
for (cityState in UncivGame.Current.gameInfo!!.getAliveCityStates()) {
|
||||||
cityState.questManager.militaryUnitKilledBy(civUnit.getCivInfo(), defeatedUnit.getCivInfo())
|
cityState.questManager.militaryUnitKilledBy(civUnit.getCivInfo(), defeatedUnit.getCivInfo())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -663,8 +663,8 @@ class CityConstructions {
|
|||||||
cityInfo.cityStats.update()
|
cityInfo.cityStats.update()
|
||||||
cityInfo.civInfo.updateDetailedCivResources()
|
cityInfo.civInfo.updateDetailedCivResources()
|
||||||
// If bought the worldscreen will not have been marked to update, and the new improvement won't show until later...
|
// If bought the worldscreen will not have been marked to update, and the new improvement won't show until later...
|
||||||
if (UncivGame.isCurrentInitialized())
|
if (UncivGame.isCurrentInitialized() && UncivGame.Current.worldScreen != null)
|
||||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
UncivGame.Current.worldScreen!!.shouldUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Support for [UniqueType.CreatesOneImprovement]:
|
/** Support for [UniqueType.CreatesOneImprovement]:
|
||||||
|
@ -155,8 +155,10 @@ class CityInfoConquestFunctions(val city: CityInfo){
|
|||||||
city.isPuppet = false
|
city.isPuppet = false
|
||||||
city.cityConstructions.inProgressConstructions.clear() // undo all progress of the previous civ on units etc.
|
city.cityConstructions.inProgressConstructions.clear() // undo all progress of the previous civ on units etc.
|
||||||
city.cityStats.update()
|
city.cityStats.update()
|
||||||
if (!UncivGame.Current.consoleMode)
|
val worldScreen = UncivGame.Current.worldScreen
|
||||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
if (!UncivGame.Current.consoleMode && worldScreen != null) {
|
||||||
|
worldScreen.shouldUpdate = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun diplomaticRepercussionsForConqueringCity(oldCiv: CivilizationInfo, conqueringCiv: CivilizationInfo) {
|
private fun diplomaticRepercussionsForConqueringCity(oldCiv: CivilizationInfo, conqueringCiv: CivilizationInfo) {
|
||||||
|
@ -62,8 +62,11 @@ class CivilizationInfo {
|
|||||||
/** Returns an instance of WorkerAutomation valid for the duration of the current turn
|
/** Returns an instance of WorkerAutomation valid for the duration of the current turn
|
||||||
* This instance carries cached data common for all Workers of this civ */
|
* This instance carries cached data common for all Workers of this civ */
|
||||||
fun getWorkerAutomation(): WorkerAutomation {
|
fun getWorkerAutomation(): WorkerAutomation {
|
||||||
val currentTurn = if (UncivGame.Current.isInitialized && UncivGame.Current.isGameInfoInitialized())
|
val currentTurn = if (UncivGame.Current.isInitialized && UncivGame.Current.gameInfo != null) {
|
||||||
UncivGame.Current.gameInfo.turns else 0
|
UncivGame.Current.gameInfo!!.turns
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
if (workerAutomationCache == null || workerAutomationCache!!.cachedForTurn != currentTurn)
|
if (workerAutomationCache == null || workerAutomationCache!!.cachedForTurn != currentTurn)
|
||||||
workerAutomationCache = WorkerAutomation(this, currentTurn)
|
workerAutomationCache = WorkerAutomation(this, currentTurn)
|
||||||
return workerAutomationCache!!
|
return workerAutomationCache!!
|
||||||
|
@ -919,11 +919,11 @@ class AssignedQuest(val questName: String = "",
|
|||||||
when (questName) {
|
when (questName) {
|
||||||
QuestName.ClearBarbarianCamp.value -> {
|
QuestName.ClearBarbarianCamp.value -> {
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
game.worldScreen.mapHolder.setCenterPosition(Vector2(data1.toFloat(), data2.toFloat()), selectUnit = false)
|
game.worldScreen!!.mapHolder.setCenterPosition(Vector2(data1.toFloat(), data2.toFloat()), selectUnit = false)
|
||||||
}
|
}
|
||||||
QuestName.Route.value -> {
|
QuestName.Route.value -> {
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
game.worldScreen.mapHolder.setCenterPosition(gameInfo.getCivilization(assigner).getCapital()!!.location, selectUnit = false)
|
game.worldScreen!!.mapHolder.setCenterPosition(gameInfo.getCivilization(assigner).getCapital()!!.location, selectUnit = false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -67,8 +67,9 @@ class OnlineMultiplayer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun getCurrentGame(): OnlineMultiplayerGame? {
|
private fun getCurrentGame(): OnlineMultiplayerGame? {
|
||||||
if (UncivGame.isCurrentInitialized() && UncivGame.Current.isGameInfoInitialized()) {
|
val gameInfo = UncivGame.Current.gameInfo
|
||||||
return getGameByGameId(UncivGame.Current.gameInfo.gameId)
|
if (gameInfo != null) {
|
||||||
|
return getGameByGameId(gameInfo.gameId)
|
||||||
} else {
|
} else {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ data class TradeOffer(val name: String, val type: TradeType, var amount: Int = 1
|
|||||||
name: String,
|
name: String,
|
||||||
type: TradeType,
|
type: TradeType,
|
||||||
amount: Int = 1,
|
amount: Int = 1,
|
||||||
gameSpeed: GameSpeed = UncivGame.Current.gameInfo.gameParameters.gameSpeed
|
gameSpeed: GameSpeed = UncivGame.Current.gameInfo!!.gameParameters.gameSpeed
|
||||||
) : this(name, type, amount, duration = -1) {
|
) : this(name, type, amount, duration = -1) {
|
||||||
duration = when {
|
duration = when {
|
||||||
type.isImmediate -> -1 // -1 for offers that are immediate (e.g. gold transfer)
|
type.isImmediate -> -1 // -1 for offers that are immediate (e.g. gold transfer)
|
||||||
@ -36,7 +36,7 @@ data class TradeOffer(val name: String, val type: TradeType, var amount: Int = 1
|
|||||||
var offerText = when(type){
|
var offerText = when(type){
|
||||||
TradeType.WarDeclaration -> "Declare war on [$name]"
|
TradeType.WarDeclaration -> "Declare war on [$name]"
|
||||||
TradeType.Introduction -> "Introduction to [$name]"
|
TradeType.Introduction -> "Introduction to [$name]"
|
||||||
TradeType.City -> UncivGame.Current.gameInfo.getCities().firstOrNull{ it.id == name }?.name ?: "Non-existent city"
|
TradeType.City -> UncivGame.Current.gameInfo!!.getCities().firstOrNull{ it.id == name }?.name ?: "Non-existent city"
|
||||||
else -> name
|
else -> name
|
||||||
}.tr()
|
}.tr()
|
||||||
|
|
||||||
|
@ -47,8 +47,9 @@ class Belief() : RulesetObject() {
|
|||||||
// private but potentially reusable, therefore not folded into getCivilopediaTextMatching
|
// private but potentially reusable, therefore not folded into getCivilopediaTextMatching
|
||||||
private fun getBeliefsMatching(name: String, ruleset: Ruleset): Sequence<Belief> {
|
private fun getBeliefsMatching(name: String, ruleset: Ruleset): Sequence<Belief> {
|
||||||
if (!UncivGame.isCurrentInitialized()) return sequenceOf()
|
if (!UncivGame.isCurrentInitialized()) return sequenceOf()
|
||||||
if (!UncivGame.Current.isGameInfoInitialized()) return sequenceOf()
|
val gameInfo = UncivGame.Current.gameInfo
|
||||||
if (!UncivGame.Current.gameInfo.isReligionEnabled()) return sequenceOf()
|
if (gameInfo == null) return sequenceOf()
|
||||||
|
if (!gameInfo.isReligionEnabled()) return sequenceOf()
|
||||||
return ruleset.beliefs.asSequence().map { it.value }
|
return ruleset.beliefs.asSequence().map { it.value }
|
||||||
.filter { belief -> belief.uniqueObjects.any { unique -> unique.params.any { it == name } }
|
.filter { belief -> belief.uniqueObjects.any { unique -> unique.params.any { it == name } }
|
||||||
}
|
}
|
||||||
|
@ -137,10 +137,11 @@ class Nation : RulesetObject() {
|
|||||||
|
|
||||||
textList += FormattedLine("{Type}: {$cityStateType}", header = 4, color = cityStateType!!.color)
|
textList += FormattedLine("{Type}: {$cityStateType}", header = 4, color = cityStateType!!.color)
|
||||||
|
|
||||||
val era = if (UncivGame.isCurrentInitialized() && UncivGame.Current.isGameInfoInitialized())
|
val era = if (UncivGame.isCurrentInitialized() && UncivGame.Current.gameInfo != null) {
|
||||||
UncivGame.Current.gameInfo.currentPlayerCiv.getEra()
|
UncivGame.Current.gameInfo!!.currentPlayerCiv.getEra()
|
||||||
else
|
} else {
|
||||||
ruleset.eras.values.first()
|
ruleset.eras.values.first()
|
||||||
|
}
|
||||||
var showResources = false
|
var showResources = false
|
||||||
|
|
||||||
val friendBonus = era.friendBonus[cityStateType!!.name]
|
val friendBonus = era.friendBonus[cityStateType!!.name]
|
||||||
@ -185,7 +186,7 @@ class Nation : RulesetObject() {
|
|||||||
when {
|
when {
|
||||||
building.uniqueTo != name -> continue
|
building.uniqueTo != name -> continue
|
||||||
building.hasUnique(UniqueType.HiddenFromCivilopedia) -> continue
|
building.hasUnique(UniqueType.HiddenFromCivilopedia) -> continue
|
||||||
UncivGame.Current.isGameInfoInitialized() && !UncivGame.Current.gameInfo.isReligionEnabled() && building.hasUnique(UniqueType.HiddenWithoutReligion) -> continue // This seems consistent with existing behaviour of CivilopediaScreen's init.<locals>.shouldBeDisplayed(), and Technology().getEnabledUnits(). Otherwise there are broken links in the Civilopedia (E.G. to "Pyramid" and "Shrine", from "The Maya").
|
UncivGame.Current.gameInfo != null && !UncivGame.Current.gameInfo!!.isReligionEnabled() && building.hasUnique(UniqueType.HiddenWithoutReligion) -> continue // This seems consistent with existing behaviour of CivilopediaScreen's init.<locals>.shouldBeDisplayed(), and Technology().getEnabledUnits(). Otherwise there are broken links in the Civilopedia (E.G. to "Pyramid" and "Shrine", from "The Maya").
|
||||||
}
|
}
|
||||||
yield(FormattedLine("{${building.name}} -", link=building.makeLink()))
|
yield(FormattedLine("{${building.name}} -", link=building.makeLink()))
|
||||||
if (building.replaces != null && ruleset.buildings.containsKey(building.replaces!!)) {
|
if (building.replaces != null && ruleset.buildings.containsKey(building.replaces!!)) {
|
||||||
|
@ -51,7 +51,7 @@ class Technology: RulesetObject() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val viewingCiv = UncivGame.Current.worldScreen.viewingCiv
|
val viewingCiv = UncivGame.Current.worldScreen!!.viewingCiv
|
||||||
val enabledUnits = getEnabledUnits(ruleset, viewingCiv)
|
val enabledUnits = getEnabledUnits(ruleset, viewingCiv)
|
||||||
if (enabledUnits.any()) {
|
if (enabledUnits.any()) {
|
||||||
lineList += "{Units enabled}: "
|
lineList += "{Units enabled}: "
|
||||||
@ -225,7 +225,7 @@ class Technology: RulesetObject() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val viewingCiv = UncivGame.Current.getWorldScreenOrNull()?.viewingCiv
|
val viewingCiv = UncivGame.Current.worldScreen?.viewingCiv
|
||||||
val enabledUnits = getEnabledUnits(ruleset, viewingCiv)
|
val enabledUnits = getEnabledUnits(ruleset, viewingCiv)
|
||||||
if (enabledUnits.any()) {
|
if (enabledUnits.any()) {
|
||||||
lineList += FormattedLine()
|
lineList += FormattedLine()
|
||||||
|
@ -176,9 +176,9 @@ class TileImprovement : RulesetStatsObject() {
|
|||||||
if (isAncientRuinsEquivalent() && ruleset.ruinRewards.isNotEmpty()) {
|
if (isAncientRuinsEquivalent() && ruleset.ruinRewards.isNotEmpty()) {
|
||||||
val difficulty: String
|
val difficulty: String
|
||||||
val religionEnabled: Boolean
|
val religionEnabled: Boolean
|
||||||
if (UncivGame.isCurrentInitialized() && UncivGame.Current.isGameInfoInitialized()) {
|
if (UncivGame.isCurrentInitialized() && UncivGame.Current.gameInfo != null) {
|
||||||
difficulty = UncivGame.Current.gameInfo.gameParameters.difficulty
|
difficulty = UncivGame.Current.gameInfo!!.gameParameters.difficulty
|
||||||
religionEnabled = UncivGame.Current.gameInfo.isReligionEnabled()
|
religionEnabled = UncivGame.Current.gameInfo!!.isReligionEnabled()
|
||||||
} else {
|
} else {
|
||||||
difficulty = "Prince" // most factors == 1
|
difficulty = "Prince" // most factors == 1
|
||||||
religionEnabled = true
|
religionEnabled = true
|
||||||
|
@ -38,7 +38,7 @@ class Simulation(
|
|||||||
for (civ in civilizations) {
|
for (civ in civilizations) {
|
||||||
this.winRate[civ] = MutableInt(0)
|
this.winRate[civ] = MutableInt(0)
|
||||||
winRateByVictory[civ] = mutableMapOf()
|
winRateByVictory[civ] = mutableMapOf()
|
||||||
for (victory in UncivGame.Current.gameInfo.ruleSet.victories.keys)
|
for (victory in UncivGame.Current.gameInfo!!.ruleSet.victories.keys)
|
||||||
winRateByVictory[civ]!![victory] = MutableInt(0)
|
winRateByVictory[civ]!![victory] = MutableInt(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,7 +121,7 @@ class Simulation(
|
|||||||
outString += "\n$civ:\n"
|
outString += "\n$civ:\n"
|
||||||
val wins = winRate[civ]!!.value * 100 / max(steps.size, 1)
|
val wins = winRate[civ]!!.value * 100 / max(steps.size, 1)
|
||||||
outString += "$wins% total win rate \n"
|
outString += "$wins% total win rate \n"
|
||||||
for (victory in UncivGame.Current.gameInfo.ruleSet.victories.keys) {
|
for (victory in UncivGame.Current.gameInfo!!.ruleSet.victories.keys) {
|
||||||
val winsVictory = winRateByVictory[civ]!![victory]!!.value * 100 / max(winRate[civ]!!.value, 1)
|
val winsVictory = winRateByVictory[civ]!![victory]!!.value * 100 / max(winRate[civ]!!.value, 1)
|
||||||
outString += "$victory: $winsVictory% "
|
outString += "$victory: $winsVictory% "
|
||||||
}
|
}
|
||||||
|
@ -250,21 +250,27 @@ object TranslationActiveModsCache {
|
|||||||
}
|
}
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private fun getCurrentHash() = UncivGame.Current.run {
|
private fun getCurrentHash(): Int {
|
||||||
if (isGameInfoInitialized())
|
val gameInfo = UncivGame.Current.gameInfo
|
||||||
|
return if (gameInfo != null) {
|
||||||
gameInfo.gameParameters.mods.hashCode() + gameInfo.gameParameters.baseRuleset.hashCode() * 31
|
gameInfo.gameParameters.mods.hashCode() + gameInfo.gameParameters.baseRuleset.hashCode() * 31
|
||||||
else translations.translationActiveMods.hashCode() * 31 * 31
|
} else {
|
||||||
|
UncivGame.Current.translations.translationActiveMods.hashCode() * 31 * 31
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getCurrentSet() = UncivGame.Current.run {
|
private fun getCurrentSet(): LinkedHashSet<String> {
|
||||||
if (isGameInfoInitialized()) {
|
val gameInfo = UncivGame.Current.gameInfo
|
||||||
|
return if (gameInfo != null) {
|
||||||
val par = gameInfo.gameParameters
|
val par = gameInfo.gameParameters
|
||||||
// This is equivalent to (par.mods + par.baseRuleset) without the cast down to `Set`
|
// This is equivalent to (par.mods + par.baseRuleset) without the cast down to `Set`
|
||||||
LinkedHashSet<String>(par.mods.size + 1).apply {
|
LinkedHashSet<String>(par.mods.size + 1).apply {
|
||||||
addAll(par.mods)
|
addAll(par.mods)
|
||||||
add(par.baseRuleset)
|
add(par.baseRuleset)
|
||||||
}
|
}
|
||||||
} else translations.translationActiveMods
|
} else {
|
||||||
|
UncivGame.Current.translations.translationActiveMods
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,6 +49,5 @@ class LanguagePickerScreen : PickerScreen() {
|
|||||||
|
|
||||||
game.translations.tryReadTranslationForCurrentLanguage()
|
game.translations.tryReadTranslationForCurrentLanguage()
|
||||||
game.setScreen(MainMenuScreen())
|
game.setScreen(MainMenuScreen())
|
||||||
dispose()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,8 @@ object SoundPlayer {
|
|||||||
val game = UncivGame.Current
|
val game = UncivGame.Current
|
||||||
|
|
||||||
// Get a hash covering all mods - quickly, so don't map, cast or copy the Set types
|
// Get a hash covering all mods - quickly, so don't map, cast or copy the Set types
|
||||||
val hash1 = if (game.isGameInfoInitialized()) game.gameInfo.ruleSet.mods.hashCode() else 0
|
val gameInfo = game.gameInfo
|
||||||
|
val hash1 = if (gameInfo != null) gameInfo.ruleSet.mods.hashCode() else 0
|
||||||
val newHash = hash1.xor(game.settings.visualMods.hashCode())
|
val newHash = hash1.xor(game.settings.visualMods.hashCode())
|
||||||
|
|
||||||
// If hash the same, leave the cache as is
|
// If hash the same, leave the cache as is
|
||||||
@ -91,8 +92,10 @@ object SoundPlayer {
|
|||||||
// audiovisual mods after game mods but before built-in sounds
|
// audiovisual mods after game mods but before built-in sounds
|
||||||
// (these can already be available when game.gameInfo is not)
|
// (these can already be available when game.gameInfo is not)
|
||||||
val modList: MutableSet<String> = mutableSetOf()
|
val modList: MutableSet<String> = mutableSetOf()
|
||||||
if (game.isGameInfoInitialized())
|
val gameInfo = game.gameInfo
|
||||||
modList.addAll(game.gameInfo.ruleSet.mods) // Sounds from game mods
|
if (gameInfo != null) {
|
||||||
|
modList.addAll(gameInfo.ruleSet.mods) // Sounds from game mods
|
||||||
|
}
|
||||||
modList.addAll(game.settings.visualMods)
|
modList.addAll(game.settings.visualMods)
|
||||||
|
|
||||||
// Translate the basic mod list into relative folder names so only sounds/name.ext needs
|
// Translate the basic mod list into relative folder names so only sounds/name.ext needs
|
||||||
|
@ -516,10 +516,9 @@ class CityConstructionsTable(private val cityScreen: CityScreen) {
|
|||||||
"Would you like to purchase [${construction.name}] for [$constructionBuyCost] [${stat.character}]?".tr()
|
"Would you like to purchase [${construction.name}] for [$constructionBuyCost] [${stat.character}]?".tr()
|
||||||
YesNoPopup(
|
YesNoPopup(
|
||||||
purchasePrompt,
|
purchasePrompt,
|
||||||
action = { purchaseConstruction(construction, stat, tile) },
|
|
||||||
screen = cityScreen,
|
screen = cityScreen,
|
||||||
restoreDefault = { cityScreen.update() }
|
restoreDefault = { cityScreen.update() }
|
||||||
).open()
|
) { purchaseConstruction(construction, stat, tile) }.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This tests whether the buy button should be _shown_ */
|
/** This tests whether the buy button should be _shown_ */
|
||||||
|
@ -138,17 +138,17 @@ class CityInfoTable(private val cityScreen: CityScreen) : Table(BaseScreen.skin)
|
|||||||
cityScreen.closeAllPopups()
|
cityScreen.closeAllPopups()
|
||||||
|
|
||||||
YesNoPopup("Are you sure you want to sell this [${building.name}]?".tr(),
|
YesNoPopup("Are you sure you want to sell this [${building.name}]?".tr(),
|
||||||
{
|
cityScreen, {
|
||||||
|
cityScreen.update()
|
||||||
|
}
|
||||||
|
) {
|
||||||
cityScreen.city.sellBuilding(building.name)
|
cityScreen.city.sellBuilding(building.name)
|
||||||
cityScreen.update()
|
cityScreen.update()
|
||||||
}, cityScreen,
|
}.open()
|
||||||
{
|
|
||||||
cityScreen.update()
|
|
||||||
}).open()
|
|
||||||
}
|
}
|
||||||
if (cityScreen.city.hasSoldBuildingThisTurn && !cityScreen.city.civInfo.gameInfo.gameParameters.godMode
|
if (cityScreen.city.hasSoldBuildingThisTurn && !cityScreen.city.civInfo.gameInfo.gameParameters.godMode
|
||||||
|| cityScreen.city.isPuppet
|
|| cityScreen.city.isPuppet
|
||||||
|| !UncivGame.Current.worldScreen.isPlayersTurn || !cityScreen.canChangeState)
|
|| !UncivGame.Current.worldScreen!!.isPlayersTurn || !cityScreen.canChangeState)
|
||||||
sellBuildingButton.disable()
|
sellBuildingButton.disable()
|
||||||
}
|
}
|
||||||
it.addSeparator()
|
it.addSeparator()
|
||||||
|
@ -81,7 +81,7 @@ class CityReligionInfoTable(
|
|||||||
icon.onClick {
|
icon.onClick {
|
||||||
val newScreen = if (religion == iconName)
|
val newScreen = if (religion == iconName)
|
||||||
EmpireOverviewScreen(civInfo, EmpireOverviewCategories.Religion.name, religion)
|
EmpireOverviewScreen(civInfo, EmpireOverviewCategories.Religion.name, religion)
|
||||||
else CivilopediaScreen(gameInfo.ruleSet, UncivGame.Current.screen as BaseScreen, CivilopediaCategories.Belief, religion )
|
else CivilopediaScreen(gameInfo.ruleSet, UncivGame.Current.screen!!, CivilopediaCategories.Belief, religion )
|
||||||
UncivGame.Current.setScreen(newScreen)
|
UncivGame.Current.setScreen(newScreen)
|
||||||
}
|
}
|
||||||
return icon
|
return icon
|
||||||
|
@ -41,7 +41,7 @@ class CityScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Toggles or adds/removes all state changing buttons */
|
/** Toggles or adds/removes all state changing buttons */
|
||||||
val canChangeState = UncivGame.Current.worldScreen.canChangeState
|
val canChangeState = UncivGame.Current.worldScreen!!.canChangeState
|
||||||
|
|
||||||
/** Toggle between Constructions and cityInfo (buildings, specialists etc. */
|
/** Toggle between Constructions and cityInfo (buildings, specialists etc. */
|
||||||
var showConstructionsTable = true
|
var showConstructionsTable = true
|
||||||
@ -402,8 +402,8 @@ class CityScreen(
|
|||||||
|
|
||||||
fun exit() {
|
fun exit() {
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
game.worldScreen.mapHolder.setCenterPosition(city.location)
|
game.worldScreen!!.mapHolder.setCenterPosition(city.location)
|
||||||
game.worldScreen.bottomUnitTable.selectUnit()
|
game.worldScreen!!.bottomUnitTable.selectUnit()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun page(delta: Int) {
|
fun page(delta: Int) {
|
||||||
|
@ -112,15 +112,14 @@ class CityScreenTileTable(private val cityScreen: CityScreen): Table() {
|
|||||||
"Would you like to purchase [Tile] for [$goldCostOfTile] [${Stat.Gold.character}]?".tr()
|
"Would you like to purchase [Tile] for [$goldCostOfTile] [${Stat.Gold.character}]?".tr()
|
||||||
YesNoPopup(
|
YesNoPopup(
|
||||||
purchasePrompt,
|
purchasePrompt,
|
||||||
action = {
|
screen = cityScreen,
|
||||||
|
restoreDefault = { cityScreen.update() }
|
||||||
|
) {
|
||||||
SoundPlayer.play(UncivSound.Coin)
|
SoundPlayer.play(UncivSound.Coin)
|
||||||
city.expansion.buyTile(selectedTile)
|
city.expansion.buyTile(selectedTile)
|
||||||
// preselect the next tile on city screen rebuild so bulk buying can go faster
|
// preselect the next tile on city screen rebuild so bulk buying can go faster
|
||||||
UncivGame.Current.setScreen(CityScreen(city, initSelectedTile = city.expansion.chooseNewTileToOwn()))
|
UncivGame.Current.setScreen(CityScreen(city, initSelectedTile = city.expansion.chooseNewTileToOwn()))
|
||||||
},
|
}.open()
|
||||||
screen = cityScreen,
|
|
||||||
restoreDefault = { cityScreen.update() }
|
|
||||||
).open()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** This tests whether the buy button should be _shown_ */
|
/** This tests whether the buy button should be _shown_ */
|
||||||
|
@ -81,7 +81,7 @@ class SpecialistAllocationTable(val cityScreen: CityScreen) : Table(BaseScreen.s
|
|||||||
cityInfo.cityStats.update()
|
cityInfo.cityStats.update()
|
||||||
cityScreen.update()
|
cityScreen.update()
|
||||||
}
|
}
|
||||||
if (cityInfo.population.getFreePopulation() == 0 || !UncivGame.Current.worldScreen.isPlayersTurn)
|
if (cityInfo.population.getFreePopulation() == 0 || !UncivGame.Current.worldScreen!!.isPlayersTurn)
|
||||||
assignButton.clear()
|
assignButton.clear()
|
||||||
return assignButton
|
return assignButton
|
||||||
}
|
}
|
||||||
@ -98,7 +98,7 @@ class SpecialistAllocationTable(val cityScreen: CityScreen) : Table(BaseScreen.s
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (assignedSpecialists <= 0 || cityInfo.isPuppet) unassignButton.isVisible = false
|
if (assignedSpecialists <= 0 || cityInfo.isPuppet) unassignButton.isVisible = false
|
||||||
if (!UncivGame.Current.worldScreen.isPlayersTurn) unassignButton.clear()
|
if (!UncivGame.Current.worldScreen!!.isPlayersTurn) unassignButton.clear()
|
||||||
return unassignButton
|
return unassignButton
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,10 +183,9 @@ class CivilopediaScreen(
|
|||||||
val imageSize = 50f
|
val imageSize = 50f
|
||||||
onBackButtonClicked { game.setScreen(previousScreen) }
|
onBackButtonClicked { game.setScreen(previousScreen) }
|
||||||
|
|
||||||
val religionEnabled = if (game.isGameInfoInitialized()) game.gameInfo.isReligionEnabled()
|
val curGameInfo = game.gameInfo
|
||||||
else ruleset.beliefs.isNotEmpty()
|
val religionEnabled = if (curGameInfo != null) curGameInfo.isReligionEnabled() else ruleset.beliefs.isNotEmpty()
|
||||||
val victoryTypes = if (game.isGameInfoInitialized()) game.gameInfo.gameParameters.victoryTypes
|
val victoryTypes = if (curGameInfo != null) curGameInfo.gameParameters.victoryTypes else emptyList()
|
||||||
else listOf()
|
|
||||||
|
|
||||||
fun shouldBeDisplayed(obj: IHasUniques): Boolean {
|
fun shouldBeDisplayed(obj: IHasUniques): Boolean {
|
||||||
return when {
|
return when {
|
||||||
@ -254,7 +253,6 @@ class CivilopediaScreen(
|
|||||||
val goToGameButton = Constants.close.toTextButton()
|
val goToGameButton = Constants.close.toTextButton()
|
||||||
goToGameButton.onClick {
|
goToGameButton.onClick {
|
||||||
game.setScreen(previousScreen)
|
game.setScreen(previousScreen)
|
||||||
dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val topTable = Table()
|
val topTable = Table()
|
||||||
|
@ -164,10 +164,13 @@ class FormattedLine (
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
private fun getCurrentRuleset() = when {
|
private fun getCurrentRuleset(): Ruleset {
|
||||||
|
val gameInfo = UncivGame.Current.gameInfo
|
||||||
|
return when {
|
||||||
!UncivGame.isCurrentInitialized() -> Ruleset()
|
!UncivGame.isCurrentInitialized() -> Ruleset()
|
||||||
!UncivGame.Current.isGameInfoInitialized() -> RulesetCache[BaseRuleset.Civ_V_Vanilla.fullName]!!
|
gameInfo == null -> RulesetCache[BaseRuleset.Civ_V_Vanilla.fullName]!!
|
||||||
else -> UncivGame.Current.gameInfo.ruleSet
|
else -> gameInfo.ruleSet
|
||||||
|
}
|
||||||
}
|
}
|
||||||
private fun initNamesCategoryMap(ruleSet: Ruleset): HashMap<String, CivilopediaCategories> {
|
private fun initNamesCategoryMap(ruleSet: Ruleset): HashMap<String, CivilopediaCategories> {
|
||||||
//val startTime = System.nanoTime()
|
//val startTime = System.nanoTime()
|
||||||
|
@ -47,7 +47,7 @@ class CrashScreen(val exception: Throwable): BaseScreen() {
|
|||||||
|
|
||||||
/** Qualified class name of the game screen that was active at the construction of this instance, or an error note. */
|
/** Qualified class name of the game screen that was active at the construction of this instance, or an error note. */
|
||||||
private val lastScreenType = try {
|
private val lastScreenType = try {
|
||||||
UncivGame.Current.screen::class.qualifiedName.toString()
|
UncivGame.Current.screen!!::class.qualifiedName.toString()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
"Could not get screen type: $e"
|
"Could not get screen type: $e"
|
||||||
}
|
}
|
||||||
@ -58,11 +58,11 @@ class CrashScreen(val exception: Throwable): BaseScreen() {
|
|||||||
|
|
||||||
/** @return The last active save game serialized as a compressed string if any, or an informational note otherwise. */
|
/** @return The last active save game serialized as a compressed string if any, or an informational note otherwise. */
|
||||||
private fun tryGetSaveGame(): String {
|
private fun tryGetSaveGame(): String {
|
||||||
if (!UncivGame.isCurrentInitialized() || !UncivGame.Current.isGameInfoInitialized())
|
if (!UncivGame.isCurrentInitialized() || UncivGame.Current.gameInfo == null)
|
||||||
return ""
|
return ""
|
||||||
return "\n**Save Data:**\n<details><summary>Show Saved Game</summary>\n\n```\n" +
|
return "\n**Save Data:**\n<details><summary>Show Saved Game</summary>\n\n```\n" +
|
||||||
try {
|
try {
|
||||||
GameSaver.gameInfoToString(UncivGame.Current.gameInfo, forceZip = true)
|
GameSaver.gameInfoToString(UncivGame.Current.gameInfo!!, forceZip = true)
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
"No save data: $e" // In theory .toString() could still error here.
|
"No save data: $e" // In theory .toString() could still error here.
|
||||||
} + "\n```\n</details>\n"
|
} + "\n```\n</details>\n"
|
||||||
@ -70,11 +70,11 @@ class CrashScreen(val exception: Throwable): BaseScreen() {
|
|||||||
|
|
||||||
/** @return Mods from the last active save game if any, or an informational note otherwise. */
|
/** @return Mods from the last active save game if any, or an informational note otherwise. */
|
||||||
private fun tryGetSaveMods(): String {
|
private fun tryGetSaveMods(): String {
|
||||||
if (!UncivGame.isCurrentInitialized() || !UncivGame.Current.isGameInfoInitialized())
|
if (!UncivGame.isCurrentInitialized() || UncivGame.Current.gameInfo == null)
|
||||||
return ""
|
return ""
|
||||||
return "\n**Save Mods:**\n```\n" +
|
return "\n**Save Mods:**\n```\n" +
|
||||||
try { // Also from old CrashController().buildReport(), also could still error at .toString().
|
try { // Also from old CrashController().buildReport(), also could still error at .toString().
|
||||||
LinkedHashSet(UncivGame.Current.gameInfo.gameParameters.getModsAndBaseRuleset()).toString()
|
LinkedHashSet(UncivGame.Current.gameInfo!!.gameParameters.getModsAndBaseRuleset()).toString()
|
||||||
} catch (e: Throwable) {
|
} catch (e: Throwable) {
|
||||||
"No mod data: $e"
|
"No mod data: $e"
|
||||||
} + "\n```\n"
|
} + "\n```\n"
|
||||||
|
@ -62,10 +62,10 @@ class MapEditorLoadTab(
|
|||||||
|
|
||||||
private fun deleteHandler() {
|
private fun deleteHandler() {
|
||||||
if (chosenMap == null) return
|
if (chosenMap == null) return
|
||||||
YesNoPopup("Are you sure you want to delete this map?", {
|
YesNoPopup("Are you sure you want to delete this map?", editorScreen) {
|
||||||
chosenMap!!.delete()
|
chosenMap!!.delete()
|
||||||
mapFiles.update()
|
mapFiles.update()
|
||||||
}, editorScreen).open()
|
}.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun activated(index: Int, caption: String, pager: TabbedPager) {
|
override fun activated(index: Int, caption: String, pager: TabbedPager) {
|
||||||
|
@ -131,7 +131,7 @@ class MapEditorModsTab(
|
|||||||
add(inc.toLabel()).row()
|
add(inc.toLabel()).row()
|
||||||
}
|
}
|
||||||
add(ScrollPane(incompatibilityTable)).colspan(2)
|
add(ScrollPane(incompatibilityTable)).colspan(2)
|
||||||
.maxHeight(screen.stage.height * 0.8f).row()
|
.maxHeight(stage.height * 0.8f).row()
|
||||||
addGoodSizedLabel("Change map to fit selected ruleset?", 24).colspan(2).row()
|
addGoodSizedLabel("Change map to fit selected ruleset?", 24).colspan(2).row()
|
||||||
addButtonInRow(Constants.yes, 'y') {
|
addButtonInRow(Constants.yes, 'y') {
|
||||||
onOK()
|
onOK()
|
||||||
|
@ -78,10 +78,10 @@ class MapEditorSaveTab(
|
|||||||
|
|
||||||
private fun deleteHandler() {
|
private fun deleteHandler() {
|
||||||
if (chosenMap == null) return
|
if (chosenMap == null) return
|
||||||
YesNoPopup("Are you sure you want to delete this map?", {
|
YesNoPopup("Are you sure you want to delete this map?", editorScreen) {
|
||||||
chosenMap!!.delete()
|
chosenMap!!.delete()
|
||||||
mapFiles.update()
|
mapFiles.update()
|
||||||
}, editorScreen).open()
|
}.open()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun activated(index: Int, caption: String, pager: TabbedPager) {
|
override fun activated(index: Int, caption: String, pager: TabbedPager) {
|
||||||
|
@ -191,9 +191,9 @@ class MapEditorScreen(map: TileMap? = null): BaseScreen() {
|
|||||||
|
|
||||||
fun askIfDirty(question: String, action: ()->Unit) {
|
fun askIfDirty(question: String, action: ()->Unit) {
|
||||||
if (!isDirty) return action()
|
if (!isDirty) return action()
|
||||||
YesNoPopup(question, action, screen = this, restoreDefault = {
|
YesNoPopup(question, screen = this, restoreDefault = {
|
||||||
keyPressDispatcher[KeyCharAndCode.BACK] = this::closeEditor
|
keyPressDispatcher[KeyCharAndCode.BACK] = this::closeEditor
|
||||||
}).open()
|
}, action).open()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun hideSelection() {
|
fun hideSelection() {
|
||||||
|
@ -40,11 +40,11 @@ class EditFriendScreen(selectedFriend: FriendList.Friend, backScreen: ViewFriend
|
|||||||
topTable.add(gameIDTable).padBottom(30f).row()
|
topTable.add(gameIDTable).padBottom(30f).row()
|
||||||
|
|
||||||
deleteFriendButton.onClick {
|
deleteFriendButton.onClick {
|
||||||
val askPopup = YesNoPopup("Are you sure you want to delete this friend?", {
|
val askPopup = YesNoPopup("Are you sure you want to delete this friend?", this) {
|
||||||
friendlist.delete(selectedFriend)
|
friendlist.delete(selectedFriend)
|
||||||
backScreen.game.setScreen(backScreen)
|
backScreen.game.setScreen(backScreen)
|
||||||
backScreen.refreshFriendsList()
|
backScreen.refreshFriendsList()
|
||||||
}, this)
|
}
|
||||||
askPopup.open()
|
askPopup.open()
|
||||||
}.apply { color = Color.RED }
|
}.apply { color = Color.RED }
|
||||||
topTable.add(deleteFriendButton)
|
topTable.add(deleteFriendButton)
|
||||||
|
@ -27,22 +27,22 @@ class EditMultiplayerGameInfoScreen(val multiplayerGame: OnlineMultiplayerGame,
|
|||||||
|
|
||||||
val deleteButton = "Delete save".toTextButton()
|
val deleteButton = "Delete save".toTextButton()
|
||||||
deleteButton.onClick {
|
deleteButton.onClick {
|
||||||
val askPopup = YesNoPopup("Are you sure you want to delete this map?", {
|
val askPopup = YesNoPopup("Are you sure you want to delete this map?", this) {
|
||||||
try {
|
try {
|
||||||
game.onlineMultiplayer.deleteGame(multiplayerGame)
|
game.onlineMultiplayer.deleteGame(multiplayerGame)
|
||||||
game.setScreen(backScreen)
|
game.setScreen(backScreen)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
ToastPopup("Could not delete game!", this)
|
ToastPopup("Could not delete game!", this)
|
||||||
}
|
}
|
||||||
}, this)
|
}
|
||||||
askPopup.open()
|
askPopup.open()
|
||||||
}.apply { color = Color.RED }
|
}.apply { color = Color.RED }
|
||||||
|
|
||||||
val giveUpButton = "Resign".toTextButton()
|
val giveUpButton = "Resign".toTextButton()
|
||||||
giveUpButton.onClick {
|
giveUpButton.onClick {
|
||||||
val askPopup = YesNoPopup("Are you sure you want to resign?", {
|
val askPopup = YesNoPopup("Are you sure you want to resign?", this) {
|
||||||
resign(multiplayerGame, backScreen)
|
resign(multiplayerGame, backScreen)
|
||||||
}, this)
|
}
|
||||||
askPopup.open()
|
askPopup.open()
|
||||||
}
|
}
|
||||||
giveUpButton.apply { color = Color.RED }
|
giveUpButton.apply { color = Color.RED }
|
||||||
|
@ -36,6 +36,7 @@ import com.unciv.ui.utils.extensions.onClick
|
|||||||
import com.unciv.ui.utils.extensions.pad
|
import com.unciv.ui.utils.extensions.pad
|
||||||
import com.unciv.ui.utils.extensions.toLabel
|
import com.unciv.ui.utils.extensions.toLabel
|
||||||
import com.unciv.ui.utils.extensions.toTextButton
|
import com.unciv.ui.utils.extensions.toTextButton
|
||||||
|
import com.unciv.utils.Log
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
import com.unciv.ui.utils.AutoScrollPane as ScrollPane
|
||||||
@ -74,9 +75,9 @@ class NewGameScreen(
|
|||||||
val resetToDefaultsButton = "Reset to defaults".toTextButton()
|
val resetToDefaultsButton = "Reset to defaults".toTextButton()
|
||||||
rightSideGroup.addActorAt(0, resetToDefaultsButton)
|
rightSideGroup.addActorAt(0, resetToDefaultsButton)
|
||||||
resetToDefaultsButton.onClick {
|
resetToDefaultsButton.onClick {
|
||||||
YesNoPopup("Are you sure you want to reset all game options to defaults?", {
|
YesNoPopup("Are you sure you want to reset all game options to defaults?", this) {
|
||||||
game.setScreen(NewGameScreen(previousScreen, GameSetupInfo()))
|
game.setScreen(NewGameScreen(previousScreen, GameSetupInfo()))
|
||||||
}, this).open(true)
|
}.open(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +156,7 @@ class NewGameScreen(
|
|||||||
val message = mapSize.fixUndesiredSizes(gameSetupInfo.mapParameters.worldWrap)
|
val message = mapSize.fixUndesiredSizes(gameSetupInfo.mapParameters.worldWrap)
|
||||||
if (message != null) {
|
if (message != null) {
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
ToastPopup( message, UncivGame.Current.screen as BaseScreen, 4000 )
|
ToastPopup( message, UncivGame.Current.screen!!, 4000 )
|
||||||
with (mapOptionsTable.generatedMapOptionsTable) {
|
with (mapOptionsTable.generatedMapOptionsTable) {
|
||||||
customMapSizeRadius.text = mapSize.radius.toString()
|
customMapSizeRadius.text = mapSize.radius.toString()
|
||||||
customMapWidth.text = mapSize.width.toString()
|
customMapWidth.text = mapSize.width.toString()
|
||||||
@ -275,6 +276,7 @@ class NewGameScreen(
|
|||||||
rightSideButton.setText("Start game!".tr())
|
rightSideButton.setText("Start game!".tr())
|
||||||
return
|
return
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
|
Log.error("Error while creating game", ex)
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
popup.reuseWith("Could not upload game!", true)
|
popup.reuseWith("Could not upload game!", true)
|
||||||
}
|
}
|
||||||
@ -286,13 +288,12 @@ class NewGameScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
game.loadGame(newGame)
|
val worldScreen = game.loadGame(newGame)
|
||||||
previousScreen.dispose()
|
|
||||||
if (newGame.gameParameters.isOnlineMultiplayer) {
|
if (newGame.gameParameters.isOnlineMultiplayer) {
|
||||||
// Save gameId to clipboard because you have to do it anyway.
|
// Save gameId to clipboard because you have to do it anyway.
|
||||||
Gdx.app.clipboard.contents = newGame.gameId
|
Gdx.app.clipboard.contents = newGame.gameId
|
||||||
// Popup to notify the User that the gameID got copied to the clipboard
|
// Popup to notify the User that the gameID got copied to the clipboard
|
||||||
ToastPopup("Game ID copied to clipboard!".tr(), game.worldScreen, 2500)
|
ToastPopup("Game ID copied to clipboard!".tr(), worldScreen, 2500)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -344,7 +344,7 @@ private class NationPickerPopup(
|
|||||||
private val ruleset = previousScreen.ruleset
|
private val ruleset = previousScreen.ruleset
|
||||||
// This Popup's body has two halves of same size, either side by side or arranged vertically
|
// This Popup's body has two halves of same size, either side by side or arranged vertically
|
||||||
// depending on screen proportions - determine height for one of those
|
// depending on screen proportions - determine height for one of those
|
||||||
private val partHeight = screen.stage.height * (if (screen.isNarrowerThan4to3()) 0.45f else 0.8f)
|
private val partHeight = stage.height * (if (stage.isNarrowerThan4to3()) 0.45f else 0.8f)
|
||||||
private val civBlocksWidth = playerPicker.civBlocksWidth
|
private val civBlocksWidth = playerPicker.civBlocksWidth
|
||||||
private val nationListTable = Table()
|
private val nationListTable = Table()
|
||||||
private val nationListScroll = ScrollPane(nationListTable)
|
private val nationListScroll = ScrollPane(nationListTable)
|
||||||
@ -356,7 +356,7 @@ private class NationPickerPopup(
|
|||||||
nationListScroll.setOverscroll(false, false)
|
nationListScroll.setOverscroll(false, false)
|
||||||
add(nationListScroll).size( civBlocksWidth + 10f, partHeight )
|
add(nationListScroll).size( civBlocksWidth + 10f, partHeight )
|
||||||
// +10, because the nation table has a 5f pad, for a total of +10f
|
// +10, because the nation table has a 5f pad, for a total of +10f
|
||||||
if (screen.isNarrowerThan4to3()) row()
|
if (stage.isNarrowerThan4to3()) row()
|
||||||
nationDetailsScroll.setOverscroll(false, false)
|
nationDetailsScroll.setOverscroll(false, false)
|
||||||
add(nationDetailsScroll).size(civBlocksWidth + 10f, partHeight) // Same here, see above
|
add(nationDetailsScroll).size(civBlocksWidth + 10f, partHeight) // Same here, see above
|
||||||
|
|
||||||
|
@ -9,6 +9,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Cell
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.badlogic.gdx.utils.Array
|
import com.badlogic.gdx.utils.Array
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.models.metadata.GameSettings
|
import com.unciv.models.metadata.GameSettings
|
||||||
import com.unciv.models.translations.TranslationFileWriter
|
import com.unciv.models.translations.TranslationFileWriter
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
@ -48,12 +49,12 @@ fun advancedTab(
|
|||||||
|
|
||||||
addMaxZoomSlider(this, settings)
|
addMaxZoomSlider(this, settings)
|
||||||
|
|
||||||
val screen = optionsPopup.screen
|
val helper = UncivGame.Current.platformSpecificHelper
|
||||||
if (screen.game.platformSpecificHelper != null && Gdx.app.type == Application.ApplicationType.Android) {
|
if (helper != null && Gdx.app.type == Application.ApplicationType.Android) {
|
||||||
optionsPopup.addCheckbox(this, "Enable portrait orientation", settings.allowAndroidPortrait) {
|
optionsPopup.addCheckbox(this, "Enable portrait orientation", settings.allowAndroidPortrait) {
|
||||||
settings.allowAndroidPortrait = it
|
settings.allowAndroidPortrait = it
|
||||||
// Note the following might close the options screen indirectly and delayed
|
// Note the following might close the options screen indirectly and delayed
|
||||||
screen.game.platformSpecificHelper.allowPortrait(it)
|
helper.allowPortrait(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,7 +62,7 @@ fun advancedTab(
|
|||||||
|
|
||||||
addTranslationGeneration(this, optionsPopup)
|
addTranslationGeneration(this, optionsPopup)
|
||||||
|
|
||||||
addSetUserId(this, settings, screen)
|
addSetUserId(this, settings)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addAutosaveTurnsSelectBox(table: Table, settings: GameSettings) {
|
private fun addAutosaveTurnsSelectBox(table: Table, settings: GameSettings) {
|
||||||
@ -161,22 +162,18 @@ private fun addTranslationGeneration(table: Table, optionsPopup: OptionsPopup) {
|
|||||||
table.add(generateTranslationsButton).colspan(2).row()
|
table.add(generateTranslationsButton).colspan(2).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addSetUserId(table: Table, settings: GameSettings, screen: BaseScreen) {
|
private fun addSetUserId(table: Table, settings: GameSettings) {
|
||||||
val idSetLabel = "".toLabel()
|
val idSetLabel = "".toLabel()
|
||||||
val takeUserIdFromClipboardButton = "Take user ID from clipboard".toTextButton()
|
val takeUserIdFromClipboardButton = "Take user ID from clipboard".toTextButton()
|
||||||
.onClick {
|
.onClick {
|
||||||
try {
|
try {
|
||||||
val clipboardContents = Gdx.app.clipboard.contents.trim()
|
val clipboardContents = Gdx.app.clipboard.contents.trim()
|
||||||
UUID.fromString(clipboardContents)
|
UUID.fromString(clipboardContents)
|
||||||
YesNoPopup(
|
YesNoPopup("Doing this will reset your current user ID to the clipboard contents - are you sure?",table.stage) {
|
||||||
"Doing this will reset your current user ID to the clipboard contents - are you sure?",
|
|
||||||
{
|
|
||||||
settings.multiplayer.userId = clipboardContents
|
settings.multiplayer.userId = clipboardContents
|
||||||
settings.save()
|
settings.save()
|
||||||
idSetLabel.setFontColor(Color.WHITE).setText("ID successfully set!".tr())
|
idSetLabel.setFontColor(Color.WHITE).setText("ID successfully set!".tr())
|
||||||
},
|
}.open(true)
|
||||||
screen
|
|
||||||
).open(true)
|
|
||||||
idSetLabel.isVisible = true
|
idSetLabel.isVisible = true
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
idSetLabel.isVisible = true
|
idSetLabel.isVisible = true
|
||||||
|
@ -19,6 +19,8 @@ fun debugTab() = Table(BaseScreen.skin).apply {
|
|||||||
defaults().pad(5f)
|
defaults().pad(5f)
|
||||||
val game = UncivGame.Current
|
val game = UncivGame.Current
|
||||||
|
|
||||||
|
val worldScreen = game.worldScreen
|
||||||
|
if (worldScreen != null) {
|
||||||
val simulateButton = "Simulate until turn:".toTextButton()
|
val simulateButton = "Simulate until turn:".toTextButton()
|
||||||
val simulateTextField = TextField(game.simulateUntilTurnForDebug.toString(), BaseScreen.skin)
|
val simulateTextField = TextField(game.simulateUntilTurnForDebug.toString(), BaseScreen.skin)
|
||||||
val invalidInputLabel = "This is not a valid integer!".toLabel().also { it.isVisible = false }
|
val invalidInputLabel = "This is not a valid integer!".toLabel().also { it.isVisible = false }
|
||||||
@ -30,11 +32,12 @@ fun debugTab() = Table(BaseScreen.skin).apply {
|
|||||||
}
|
}
|
||||||
game.simulateUntilTurnForDebug = simulateUntilTurns
|
game.simulateUntilTurnForDebug = simulateUntilTurns
|
||||||
invalidInputLabel.isVisible = false
|
invalidInputLabel.isVisible = false
|
||||||
game.worldScreen.nextTurn()
|
worldScreen.nextTurn()
|
||||||
}
|
}
|
||||||
add(simulateButton)
|
add(simulateButton)
|
||||||
add(simulateTextField).row()
|
add(simulateTextField).row()
|
||||||
add(invalidInputLabel).colspan(2).row()
|
add(invalidInputLabel).colspan(2).row()
|
||||||
|
}
|
||||||
|
|
||||||
add("Supercharged".toCheckBox(game.superchargedForDebug) {
|
add("Supercharged".toCheckBox(game.superchargedForDebug) {
|
||||||
game.superchargedForDebug = it
|
game.superchargedForDebug = it
|
||||||
@ -42,9 +45,10 @@ fun debugTab() = Table(BaseScreen.skin).apply {
|
|||||||
add("View entire map".toCheckBox(game.viewEntireMapForDebug) {
|
add("View entire map".toCheckBox(game.viewEntireMapForDebug) {
|
||||||
game.viewEntireMapForDebug = it
|
game.viewEntireMapForDebug = it
|
||||||
}).colspan(2).row()
|
}).colspan(2).row()
|
||||||
if (game.isGameInfoInitialized()) {
|
val curGameInfo = game.gameInfo
|
||||||
add("God mode (current game)".toCheckBox(game.gameInfo.gameParameters.godMode) {
|
if (curGameInfo != null) {
|
||||||
game.gameInfo.gameParameters.godMode = it
|
add("God mode (current game)".toCheckBox(curGameInfo.gameParameters.godMode) {
|
||||||
|
curGameInfo.gameParameters.godMode = it
|
||||||
}).colspan(2).row()
|
}).colspan(2).row()
|
||||||
}
|
}
|
||||||
add("Save games compressed".toCheckBox(GameSaver.saveZipped) {
|
add("Save games compressed".toCheckBox(GameSaver.saveZipped) {
|
||||||
@ -73,25 +77,25 @@ fun debugTab() = Table(BaseScreen.skin).apply {
|
|||||||
|
|
||||||
val unlockTechsButton = "Unlock all techs".toTextButton()
|
val unlockTechsButton = "Unlock all techs".toTextButton()
|
||||||
unlockTechsButton.onClick {
|
unlockTechsButton.onClick {
|
||||||
if (!game.isGameInfoInitialized())
|
if (curGameInfo == null)
|
||||||
return@onClick
|
return@onClick
|
||||||
for (tech in game.gameInfo.ruleSet.technologies.keys) {
|
for (tech in curGameInfo.ruleSet.technologies.keys) {
|
||||||
if (tech !in game.gameInfo.getCurrentPlayerCivilization().tech.techsResearched) {
|
if (tech !in curGameInfo.getCurrentPlayerCivilization().tech.techsResearched) {
|
||||||
game.gameInfo.getCurrentPlayerCivilization().tech.addTechnology(tech)
|
curGameInfo.getCurrentPlayerCivilization().tech.addTechnology(tech)
|
||||||
game.gameInfo.getCurrentPlayerCivilization().popupAlerts.removeLastOrNull()
|
curGameInfo.getCurrentPlayerCivilization().popupAlerts.removeLastOrNull()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
game.gameInfo.getCurrentPlayerCivilization().updateSightAndResources()
|
curGameInfo.getCurrentPlayerCivilization().updateSightAndResources()
|
||||||
game.worldScreen.shouldUpdate = true
|
if (worldScreen != null) worldScreen.shouldUpdate = true
|
||||||
}
|
}
|
||||||
add(unlockTechsButton).colspan(2).row()
|
add(unlockTechsButton).colspan(2).row()
|
||||||
|
|
||||||
val giveResourcesButton = "Get all strategic resources".toTextButton()
|
val giveResourcesButton = "Get all strategic resources".toTextButton()
|
||||||
giveResourcesButton.onClick {
|
giveResourcesButton.onClick {
|
||||||
if (!game.isGameInfoInitialized())
|
if (curGameInfo == null)
|
||||||
return@onClick
|
return@onClick
|
||||||
val ownedTiles = game.gameInfo.tileMap.values.asSequence().filter { it.getOwner() == game.gameInfo.getCurrentPlayerCivilization() }
|
val ownedTiles = curGameInfo.tileMap.values.asSequence().filter { it.getOwner() == curGameInfo.getCurrentPlayerCivilization() }
|
||||||
val resourceTypes = game.gameInfo.ruleSet.tileResources.values.asSequence().filter { it.resourceType == ResourceType.Strategic }
|
val resourceTypes = curGameInfo.ruleSet.tileResources.values.asSequence().filter { it.resourceType == ResourceType.Strategic }
|
||||||
for ((tile, resource) in ownedTiles zip resourceTypes) {
|
for ((tile, resource) in ownedTiles zip resourceTypes) {
|
||||||
tile.resource = resource.name
|
tile.resource = resource.name
|
||||||
tile.resourceAmount = 999
|
tile.resourceAmount = 999
|
||||||
@ -99,8 +103,8 @@ fun debugTab() = Table(BaseScreen.skin).apply {
|
|||||||
// If this becomes a problem, check if such an improvement exists and otherwise plop down a great improvement or so
|
// If this becomes a problem, check if such an improvement exists and otherwise plop down a great improvement or so
|
||||||
tile.improvement = resource.getImprovements().first()
|
tile.improvement = resource.getImprovements().first()
|
||||||
}
|
}
|
||||||
game.gameInfo.getCurrentPlayerCivilization().updateSightAndResources()
|
curGameInfo.getCurrentPlayerCivilization().updateSightAndResources()
|
||||||
game.worldScreen.shouldUpdate = true
|
if (worldScreen != null) worldScreen.shouldUpdate = true
|
||||||
}
|
}
|
||||||
add(giveResourcesButton).colspan(2).row()
|
add(giveResourcesButton).colspan(2).row()
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import com.badlogic.gdx.graphics.Color
|
|||||||
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.badlogic.gdx.utils.Array
|
import com.badlogic.gdx.utils.Array
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.models.metadata.GameSettings
|
import com.unciv.models.metadata.GameSettings
|
||||||
import com.unciv.models.tilesets.TileSetCache
|
import com.unciv.models.tilesets.TileSetCache
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
@ -41,7 +42,7 @@ fun displayTab(
|
|||||||
optionsPopup.addCheckbox(this, "Experimental Demographics scoreboard", settings.useDemographics, true) { settings.useDemographics = it }
|
optionsPopup.addCheckbox(this, "Experimental Demographics scoreboard", settings.useDemographics, true) { settings.useDemographics = it }
|
||||||
optionsPopup.addCheckbox(this, "Show zoom buttons in world screen", settings.showZoomButtons, true) { settings.showZoomButtons = it }
|
optionsPopup.addCheckbox(this, "Show zoom buttons in world screen", settings.showZoomButtons, true) { settings.showZoomButtons = it }
|
||||||
|
|
||||||
addMinimapSizeSlider(this, settings, optionsPopup.screen, optionsPopup.selectBoxMinWidth)
|
addMinimapSizeSlider(this, settings, optionsPopup.selectBoxMinWidth)
|
||||||
|
|
||||||
addResolutionSelectBox(this, settings, optionsPopup.selectBoxMinWidth, onResolutionChange)
|
addResolutionSelectBox(this, settings, optionsPopup.selectBoxMinWidth, onResolutionChange)
|
||||||
|
|
||||||
@ -62,7 +63,7 @@ fun displayTab(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addMinimapSizeSlider(table: Table, settings: GameSettings, screen: BaseScreen, selectBoxMinWidth: Float) {
|
private fun addMinimapSizeSlider(table: Table, settings: GameSettings, selectBoxMinWidth: Float) {
|
||||||
table.add("Show minimap".toLabel()).left().fillX()
|
table.add("Show minimap".toLabel()).left().fillX()
|
||||||
|
|
||||||
// The meaning of the values needs a formula to be synchronized between here and
|
// The meaning of the values needs a formula to be synchronized between here and
|
||||||
@ -88,8 +89,9 @@ private fun addMinimapSizeSlider(table: Table, settings: GameSettings, screen: B
|
|||||||
settings.minimapSize = size
|
settings.minimapSize = size
|
||||||
}
|
}
|
||||||
settings.save()
|
settings.save()
|
||||||
if (screen is WorldScreen)
|
val worldScreen = UncivGame.Current.getWorldScreenIfActive()
|
||||||
screen.shouldUpdate = true
|
if (worldScreen != null)
|
||||||
|
worldScreen.shouldUpdate = true
|
||||||
}
|
}
|
||||||
table.add(minimapSlider).minWidth(selectBoxMinWidth).pad(10f).row()
|
table.add(minimapSlider).minWidth(selectBoxMinWidth).pad(10f).row()
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.unciv.ui.options
|
package com.unciv.ui.options
|
||||||
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.civilization.PlayerType
|
import com.unciv.logic.civilization.PlayerType
|
||||||
import com.unciv.ui.utils.BaseScreen
|
import com.unciv.ui.utils.BaseScreen
|
||||||
import com.unciv.ui.worldscreen.WorldScreen
|
import com.unciv.ui.worldscreen.WorldScreen
|
||||||
@ -12,16 +13,16 @@ fun gameplayTab(
|
|||||||
defaults().pad(5f)
|
defaults().pad(5f)
|
||||||
|
|
||||||
val settings = optionsPopup.settings
|
val settings = optionsPopup.settings
|
||||||
val screen = optionsPopup.screen
|
|
||||||
|
|
||||||
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, "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, "Auto-assign city production", settings.autoAssignCityProduction, true) {
|
optionsPopup.addCheckbox(this, "Auto-assign city production", settings.autoAssignCityProduction, true) { shouldAutoAssignCityProduction ->
|
||||||
settings.autoAssignCityProduction = it
|
settings.autoAssignCityProduction = shouldAutoAssignCityProduction
|
||||||
if (it && screen is WorldScreen &&
|
val worldScreen = UncivGame.Current.getWorldScreenIfActive()
|
||||||
screen.viewingCiv.isCurrentPlayer() && screen.viewingCiv.playerType == PlayerType.Human
|
if (shouldAutoAssignCityProduction && worldScreen != null &&
|
||||||
|
worldScreen.viewingCiv.isCurrentPlayer() && worldScreen.viewingCiv.playerType == PlayerType.Human
|
||||||
) {
|
) {
|
||||||
screen.gameInfo.currentPlayerCiv.cities.forEach { city ->
|
worldScreen.gameInfo.currentPlayerCiv.cities.forEach { city ->
|
||||||
city.cityConstructions.chooseNextConstruction()
|
city.cityConstructions.chooseNextConstruction()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.unciv.ui.options
|
package com.unciv.ui.options
|
||||||
|
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.ui.utils.BaseScreen
|
import com.unciv.ui.utils.BaseScreen
|
||||||
import com.unciv.ui.utils.LanguageTable.Companion.addLanguageTables
|
import com.unciv.ui.utils.LanguageTable.Companion.addLanguageTables
|
||||||
import com.unciv.ui.utils.extensions.onClick
|
import com.unciv.ui.utils.extensions.onClick
|
||||||
@ -17,7 +18,7 @@ fun languageTab(
|
|||||||
fun selectLanguage() {
|
fun selectLanguage() {
|
||||||
settings.language = chosenLanguage
|
settings.language = chosenLanguage
|
||||||
settings.updateLocaleFromLanguage()
|
settings.updateLocaleFromLanguage()
|
||||||
optionsPopup.screen.game.translations.tryReadTranslationForCurrentLanguage()
|
UncivGame.Current.translations.tryReadTranslationForCurrentLanguage()
|
||||||
onLanguageSelected()
|
onLanguageSelected()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,7 +12,6 @@ import com.unciv.models.metadata.GameSetting
|
|||||||
import com.unciv.models.metadata.GameSettings
|
import com.unciv.models.metadata.GameSettings
|
||||||
import com.unciv.models.ruleset.Ruleset
|
import com.unciv.models.ruleset.Ruleset
|
||||||
import com.unciv.models.ruleset.RulesetCache
|
import com.unciv.models.ruleset.RulesetCache
|
||||||
import com.unciv.models.translations.tr
|
|
||||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||||
import com.unciv.ui.popup.Popup
|
import com.unciv.ui.popup.Popup
|
||||||
@ -145,8 +144,7 @@ private fun addMultiplayerServerOptions(
|
|||||||
settings.save()
|
settings.save()
|
||||||
}
|
}
|
||||||
|
|
||||||
val screen = optionsPopup.screen
|
serverIpTable.add(multiplayerServerTextField).minWidth(optionsPopup.stageToShowOn.width / 2).growX()
|
||||||
serverIpTable.add(multiplayerServerTextField).minWidth(screen.stage.width / 2).growX()
|
|
||||||
tab.add(serverIpTable).colspan(2).fillX().row()
|
tab.add(serverIpTable).colspan(2).fillX().row()
|
||||||
|
|
||||||
tab.add("Reset to Dropbox".toTextButton().onClick {
|
tab.add("Reset to Dropbox".toTextButton().onClick {
|
||||||
@ -156,7 +154,7 @@ private fun addMultiplayerServerOptions(
|
|||||||
}).colspan(2).row()
|
}).colspan(2).row()
|
||||||
|
|
||||||
tab.add(connectionToServerButton.onClick {
|
tab.add(connectionToServerButton.onClick {
|
||||||
val popup = Popup(screen).apply {
|
val popup = Popup(optionsPopup.stage).apply {
|
||||||
addGoodSizedLabel("Awaiting response...").row()
|
addGoodSizedLabel("Awaiting response...").row()
|
||||||
}
|
}
|
||||||
popup.open(true)
|
popup.open(true)
|
||||||
|
@ -8,6 +8,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table
|
|||||||
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
|
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener
|
||||||
import com.badlogic.gdx.utils.Array
|
import com.badlogic.gdx.utils.Array
|
||||||
import com.unciv.MainMenuScreen
|
import com.unciv.MainMenuScreen
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.logic.event.EventBus
|
import com.unciv.logic.event.EventBus
|
||||||
import com.unciv.models.UncivSound
|
import com.unciv.models.UncivSound
|
||||||
import com.unciv.models.metadata.BaseRuleset
|
import com.unciv.models.metadata.BaseRuleset
|
||||||
@ -133,20 +134,20 @@ class OptionsPopup(
|
|||||||
/** Reload this Popup after major changes (resolution, tileset, language, font) */
|
/** Reload this Popup after major changes (resolution, tileset, language, font) */
|
||||||
private fun reloadWorldAndOptions() {
|
private fun reloadWorldAndOptions() {
|
||||||
settings.save()
|
settings.save()
|
||||||
if (screen is WorldScreen) {
|
val worldScreen = UncivGame.Current.getWorldScreenIfActive()
|
||||||
screen.game.resetToWorldScreen(WorldScreen(screen.gameInfo, screen.viewingCiv))
|
if (worldScreen != null) {
|
||||||
} else if (screen is MainMenuScreen) {
|
val newWorldScreen = WorldScreen(worldScreen.gameInfo, worldScreen.viewingCiv)
|
||||||
screen.game.setScreen(MainMenuScreen())
|
worldScreen.game.setScreen(newWorldScreen)
|
||||||
|
newWorldScreen.openOptionsPopup(tabs.activePage)
|
||||||
}
|
}
|
||||||
(screen.game.screen as BaseScreen).openOptionsPopup(tabs.activePage)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun addCheckbox(table: Table, text: String, initialState: Boolean, updateWorld: Boolean = false, action: ((Boolean) -> Unit)) {
|
fun addCheckbox(table: Table, text: String, initialState: Boolean, updateWorld: Boolean = false, action: ((Boolean) -> Unit)) {
|
||||||
val checkbox = text.toCheckBox(initialState) {
|
val checkbox = text.toCheckBox(initialState) {
|
||||||
action(it)
|
action(it)
|
||||||
settings.save()
|
settings.save()
|
||||||
if (updateWorld && screen is WorldScreen)
|
val worldScreen = UncivGame.Current.getWorldScreenIfActive()
|
||||||
screen.shouldUpdate = true
|
if (updateWorld && worldScreen != null) worldScreen.shouldUpdate = true
|
||||||
}
|
}
|
||||||
table.add(checkbox).colspan(2).left().row()
|
table.add(checkbox).colspan(2).left().row()
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ package com.unciv.ui.options
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
|
import com.unciv.UncivGame
|
||||||
import com.unciv.models.UncivSound
|
import com.unciv.models.UncivSound
|
||||||
import com.unciv.models.metadata.GameSettings
|
import com.unciv.models.metadata.GameSettings
|
||||||
import com.unciv.models.translations.tr
|
import com.unciv.models.translations.tr
|
||||||
|
import com.unciv.ui.audio.MusicController
|
||||||
import com.unciv.ui.audio.MusicTrackChooserFlags
|
import com.unciv.ui.audio.MusicTrackChooserFlags
|
||||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||||
@ -24,17 +26,17 @@ fun soundTab(
|
|||||||
defaults().pad(5f)
|
defaults().pad(5f)
|
||||||
|
|
||||||
val settings = optionsPopup.settings
|
val settings = optionsPopup.settings
|
||||||
val screen = optionsPopup.screen
|
val music = UncivGame.Current.musicController
|
||||||
|
|
||||||
addSoundEffectsVolumeSlider(this, settings)
|
addSoundEffectsVolumeSlider(this, settings)
|
||||||
|
|
||||||
if (screen.game.musicController.isMusicAvailable()) {
|
if (UncivGame.Current.musicController.isMusicAvailable()) {
|
||||||
addMusicVolumeSlider(this, settings, screen)
|
addMusicVolumeSlider(this, settings, music)
|
||||||
addMusicPauseSlider(this, settings, screen)
|
addMusicPauseSlider(this, settings, music)
|
||||||
addMusicCurrentlyPlaying(this, screen)
|
addMusicCurrentlyPlaying(this, music)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!screen.game.musicController.isDefaultFileAvailable())
|
if (!UncivGame.Current.musicController.isDefaultFileAvailable())
|
||||||
addDownloadMusic(this, optionsPopup)
|
addDownloadMusic(this, optionsPopup)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,11 +54,10 @@ private fun addDownloadMusic(table: Table, optionsPopup: OptionsPopup) {
|
|||||||
// So the whole game doesn't get stuck while downloading the file
|
// So the whole game doesn't get stuck while downloading the file
|
||||||
launchCrashHandling("MusicDownload") {
|
launchCrashHandling("MusicDownload") {
|
||||||
try {
|
try {
|
||||||
val screen = optionsPopup.screen
|
UncivGame.Current.musicController.downloadDefaultFile()
|
||||||
screen.game.musicController.downloadDefaultFile()
|
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
optionsPopup.tabs.replacePage("Sound", soundTab(optionsPopup))
|
optionsPopup.tabs.replacePage("Sound", soundTab(optionsPopup))
|
||||||
screen.game.musicController.chooseTrack(flags = MusicTrackChooserFlags.setPlayDefault)
|
UncivGame.Current.musicController.chooseTrack(flags = MusicTrackChooserFlags.setPlayDefault)
|
||||||
}
|
}
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
@ -83,7 +84,7 @@ private fun addSoundEffectsVolumeSlider(table: Table, settings: GameSettings) {
|
|||||||
table.add(soundEffectsVolumeSlider).pad(5f).row()
|
table.add(soundEffectsVolumeSlider).pad(5f).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addMusicVolumeSlider(table: Table, settings: GameSettings, screen: BaseScreen) {
|
private fun addMusicVolumeSlider(table: Table, settings: GameSettings, music: MusicController) {
|
||||||
table.add("Music volume".tr()).left().fillX()
|
table.add("Music volume".tr()).left().fillX()
|
||||||
|
|
||||||
val musicVolumeSlider = UncivSlider(
|
val musicVolumeSlider = UncivSlider(
|
||||||
@ -95,7 +96,6 @@ private fun addMusicVolumeSlider(table: Table, settings: GameSettings, screen: B
|
|||||||
settings.musicVolume = it
|
settings.musicVolume = it
|
||||||
settings.save()
|
settings.save()
|
||||||
|
|
||||||
val music = screen.game.musicController
|
|
||||||
music.setVolume(it)
|
music.setVolume(it)
|
||||||
if (!music.isPlaying())
|
if (!music.isPlaying())
|
||||||
music.chooseTrack(flags = MusicTrackChooserFlags.setPlayDefault)
|
music.chooseTrack(flags = MusicTrackChooserFlags.setPlayDefault)
|
||||||
@ -103,9 +103,7 @@ private fun addMusicVolumeSlider(table: Table, settings: GameSettings, screen: B
|
|||||||
table.add(musicVolumeSlider).pad(5f).row()
|
table.add(musicVolumeSlider).pad(5f).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addMusicPauseSlider(table: Table, settings: GameSettings, screen: BaseScreen) {
|
private fun addMusicPauseSlider(table: Table, settings: GameSettings, music: MusicController) {
|
||||||
val music = screen.game.musicController
|
|
||||||
|
|
||||||
// map to/from 0-1-2..10-12-14..30-35-40..60-75-90-105-120
|
// map to/from 0-1-2..10-12-14..30-35-40..60-75-90-105-120
|
||||||
fun posToLength(pos: Float): Float = when (pos) {
|
fun posToLength(pos: Float): Float = when (pos) {
|
||||||
in 0f..10f -> pos
|
in 0f..10f -> pos
|
||||||
@ -141,16 +139,16 @@ private fun addMusicPauseSlider(table: Table, settings: GameSettings, screen: Ba
|
|||||||
table.add(pauseLengthSlider).pad(5f).row()
|
table.add(pauseLengthSlider).pad(5f).row()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addMusicCurrentlyPlaying(table: Table, screen: BaseScreen) {
|
private fun addMusicCurrentlyPlaying(table: Table, music: MusicController) {
|
||||||
val label = WrappableLabel("", table.width - 10f, Color(-0x2f5001), 16)
|
val label = WrappableLabel("", table.width - 10f, Color(-0x2f5001), 16)
|
||||||
label.wrap = true
|
label.wrap = true
|
||||||
table.add(label).padTop(20f).colspan(2).fillX().row()
|
table.add(label).padTop(20f).colspan(2).fillX().row()
|
||||||
screen.game.musicController.onChange {
|
music.onChange {
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
label.setText("Currently playing: [$it]".tr())
|
label.setText("Currently playing: [$it]".tr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
label.onClick(UncivSound.Silent) {
|
label.onClick(UncivSound.Silent) {
|
||||||
screen.game.musicController.chooseTrack(flags = MusicTrackChooserFlags.none)
|
music.chooseTrack(flags = MusicTrackChooserFlags.none)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,6 @@ class DiplomacyOverviewTab (
|
|||||||
table.touchable = Touchable.enabled
|
table.touchable = Touchable.enabled
|
||||||
table.onClick {
|
table.onClick {
|
||||||
if (civInfo.isDefeated() || viewingPlayer.isSpectator() || civInfo == viewingPlayer) return@onClick
|
if (civInfo.isDefeated() || viewingPlayer.isSpectator() || civInfo == viewingPlayer) return@onClick
|
||||||
overviewScreen.dispose()
|
|
||||||
UncivGame.Current.setScreen(DiplomacyScreen(viewingPlayer, civInfo))
|
UncivGame.Current.setScreen(DiplomacyScreen(viewingPlayer, civInfo))
|
||||||
}
|
}
|
||||||
return table
|
return table
|
||||||
|
@ -138,7 +138,7 @@ class StatsOverviewTab(
|
|||||||
for (city in viewingPlayer.cities) { city.cityStats.update() }
|
for (city in viewingPlayer.cities) { city.cityStats.update() }
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
slider.isDisabled = !UncivGame.Current.worldScreen.canChangeState
|
slider.isDisabled = !UncivGame.Current.worldScreen!!.canChangeState
|
||||||
|
|
||||||
sliderTable.add(slider).padTop(15f)
|
sliderTable.add(slider).padTop(15f)
|
||||||
add(sliderTable).colspan(2)
|
add(sliderTable).colspan(2)
|
||||||
|
@ -78,7 +78,7 @@ class UnitOverviewTab(
|
|||||||
private fun showWorldScreenAt(position: Vector2, unit: MapUnit?) {
|
private fun showWorldScreenAt(position: Vector2, unit: MapUnit?) {
|
||||||
val game = overviewScreen.game
|
val game = overviewScreen.game
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
game.worldScreen.mapHolder.setCenterPosition(position, forceSelectUnit = unit)
|
game.worldScreen!!.mapHolder.setCenterPosition(position, forceSelectUnit = unit)
|
||||||
}
|
}
|
||||||
private fun showWorldScreenAt(unit: MapUnit) = showWorldScreenAt(unit.currentTile.position, unit)
|
private fun showWorldScreenAt(unit: MapUnit) = showWorldScreenAt(unit.currentTile.position, unit)
|
||||||
private fun showWorldScreenAt(tile: TileInfo) = showWorldScreenAt(tile.position, null)
|
private fun showWorldScreenAt(tile: TileInfo) = showWorldScreenAt(tile.position, null)
|
||||||
@ -190,7 +190,7 @@ class UnitOverviewTab(
|
|||||||
if (unit.promotions.canBePromoted())
|
if (unit.promotions.canBePromoted())
|
||||||
promotionsTable.add(
|
promotionsTable.add(
|
||||||
ImageGetter.getImage("OtherIcons/Star").apply {
|
ImageGetter.getImage("OtherIcons/Star").apply {
|
||||||
color = if (game.worldScreen.canChangeState && unit.currentMovement > 0f && unit.attacksThisTurn == 0)
|
color = if (game.worldScreen!!.canChangeState && unit.currentMovement > 0f && unit.attacksThisTurn == 0)
|
||||||
Color.GOLDENROD
|
Color.GOLDENROD
|
||||||
else Color.GOLDENROD.darken(0.25f)
|
else Color.GOLDENROD.darken(0.25f)
|
||||||
}
|
}
|
||||||
@ -198,7 +198,6 @@ class UnitOverviewTab(
|
|||||||
promotionsTable.onClick {
|
promotionsTable.onClick {
|
||||||
if (unit.promotions.canBePromoted() || unit.promotions.promotions.isNotEmpty()) {
|
if (unit.promotions.canBePromoted() || unit.promotions.promotions.isNotEmpty()) {
|
||||||
game.setScreen(PromotionPickerScreen(unit))
|
game.setScreen(PromotionPickerScreen(unit))
|
||||||
overviewScreen.dispose()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add(promotionsTable)
|
add(promotionsTable)
|
||||||
|
@ -238,8 +238,11 @@ class WonderOverviewTab(
|
|||||||
val locationLabel = locationText.toLabel()
|
val locationLabel = locationText.toLabel()
|
||||||
if (wonder.location != null)
|
if (wonder.location != null)
|
||||||
locationLabel.onClick{
|
locationLabel.onClick{
|
||||||
|
val worldScreen = UncivGame.Current.worldScreen
|
||||||
|
if (worldScreen != null) {
|
||||||
UncivGame.Current.resetToWorldScreen()
|
UncivGame.Current.resetToWorldScreen()
|
||||||
UncivGame.Current.worldScreen.mapHolder.setCenterPosition(wonder.location.position)
|
worldScreen.mapHolder.setCenterPosition(wonder.location.position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
add(locationLabel).fillY()
|
add(locationLabel).fillY()
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,6 @@ class ImprovementPickerScreen(
|
|||||||
onAccept()
|
onAccept()
|
||||||
}
|
}
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
@ -87,7 +87,6 @@ class ModManagementScreen(
|
|||||||
game.settings.tileSet = tileSets.first()
|
game.settings.tileSet = tileSets.first()
|
||||||
}
|
}
|
||||||
game.setScreen(MainMenuScreen())
|
game.setScreen(MainMenuScreen())
|
||||||
dispose()
|
|
||||||
}
|
}
|
||||||
closeButton.onClick(closeAction)
|
closeButton.onClick(closeAction)
|
||||||
onBackButtonClicked(closeAction)
|
onBackButtonClicked(closeAction)
|
||||||
@ -581,7 +580,6 @@ class ModManagementScreen(
|
|||||||
override fun resize(width: Int, height: Int) {
|
override fun resize(width: Int, height: Int) {
|
||||||
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
|
if (stage.viewport.screenWidth != width || stage.viewport.screenHeight != height) {
|
||||||
game.setScreen(ModManagementScreen(installedModInfo, onlineModInfo))
|
game.setScreen(ModManagementScreen(installedModInfo, onlineModInfo))
|
||||||
dispose() // interrupt background loader - sorry, the resized new screen won't continue
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class PickerPane(
|
|||||||
|
|
||||||
/** Sets the text of the [rightSideButton] and enables it if it's the player's turn */
|
/** Sets the text of the [rightSideButton] and enables it if it's the player's turn */
|
||||||
fun pick(rightButtonText: String) {
|
fun pick(rightButtonText: String) {
|
||||||
if (UncivGame.Current.worldScreen.isPlayersTurn) rightSideButton.enable()
|
if (UncivGame.Current.worldScreen!!.isPlayersTurn) rightSideButton.enable()
|
||||||
rightSideButton.setText(rightButtonText)
|
rightSideButton.setText(rightButtonText)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,6 @@ open class PickerScreen(disableScroll: Boolean = false) : BaseScreen() {
|
|||||||
val closeAction = {
|
val closeAction = {
|
||||||
if (previousScreen != null) game.setScreen(previousScreen)
|
if (previousScreen != null) game.setScreen(previousScreen)
|
||||||
else game.resetToWorldScreen()
|
else game.resetToWorldScreen()
|
||||||
dispose()
|
|
||||||
}
|
}
|
||||||
pickerPane.closeButton.onClick(closeAction)
|
pickerPane.closeButton.onClick(closeAction)
|
||||||
onBackButtonClicked(closeAction)
|
onBackButtonClicked(closeAction)
|
||||||
|
@ -58,7 +58,6 @@ class PolicyPickerScreen(val worldScreen: WorldScreen, civInfo: CivilizationInfo
|
|||||||
// 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 || !policies.canAdoptPolicy()) {
|
if (game.screen !is PolicyPickerScreen || !policies.canAdoptPolicy()) {
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
dispose()
|
|
||||||
} else {
|
} else {
|
||||||
val policyScreen = PolicyPickerScreen(worldScreen)
|
val policyScreen = PolicyPickerScreen(worldScreen)
|
||||||
policyScreen.scrollPane.scrollPercentX = scrollPane.scrollPercentX
|
policyScreen.scrollPane.scrollPercentX = scrollPane.scrollPercentX
|
||||||
|
@ -30,8 +30,6 @@ class PromotionPickerScreen(val unit: MapUnit) : PickerScreen() {
|
|||||||
game.setScreen(PromotionPickerScreen(unit).setScrollY(scrollPane.scrollY))
|
game.setScreen(PromotionPickerScreen(unit).setScrollY(scrollPane.scrollY))
|
||||||
else
|
else
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
dispose()
|
|
||||||
game.worldScreen.shouldUpdate = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -43,7 +41,7 @@ class PromotionPickerScreen(val unit: MapUnit) : PickerScreen() {
|
|||||||
acceptPromotion(selectedPromotion)
|
acceptPromotion(selectedPromotion)
|
||||||
}
|
}
|
||||||
val canBePromoted = unit.promotions.canBePromoted()
|
val canBePromoted = unit.promotions.canBePromoted()
|
||||||
val canChangeState = game.worldScreen.canChangeState
|
val canChangeState = game.worldScreen!!.canChangeState
|
||||||
val canPromoteNow = canBePromoted && canChangeState
|
val canPromoteNow = canBePromoted && canChangeState
|
||||||
&& unit.currentMovement > 0 && unit.attacksThisTurn == 0
|
&& unit.currentMovement > 0 && unit.attacksThisTurn == 0
|
||||||
rightSideButton.isEnabled = canPromoteNow
|
rightSideButton.isEnabled = canPromoteNow
|
||||||
|
@ -67,7 +67,6 @@ abstract class ReligionPickerScreenCommon(
|
|||||||
rightSideButton.onClick(UncivSound.Choir) {
|
rightSideButton.onClick(UncivSound.Choir) {
|
||||||
choosingCiv.religionManager.action()
|
choosingCiv.religionManager.action()
|
||||||
UncivGame.Current.resetToWorldScreen()
|
UncivGame.Current.resetToWorldScreen()
|
||||||
dispose()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,8 +88,6 @@ class TechPickerScreen(
|
|||||||
game.settings.addCompletedTutorialTask("Pick technology")
|
game.settings.addCompletedTutorialTask("Pick technology")
|
||||||
|
|
||||||
game.resetToWorldScreen()
|
game.resetToWorldScreen()
|
||||||
game.worldScreen.shouldUpdate = true
|
|
||||||
dispose()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// per default show current/recent technology,
|
// per default show current/recent technology,
|
||||||
@ -265,7 +263,7 @@ class TechPickerScreen(
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!UncivGame.Current.worldScreen.canChangeState) {
|
if (!UncivGame.Current.worldScreen!!.canChangeState) {
|
||||||
rightSideButton.disable()
|
rightSideButton.disable()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package com.unciv.ui.popup
|
|||||||
|
|
||||||
import com.badlogic.gdx.graphics.Color
|
import com.badlogic.gdx.graphics.Color
|
||||||
import com.badlogic.gdx.scenes.scene2d.Actor
|
import com.badlogic.gdx.scenes.scene2d.Actor
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
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.Cell
|
import com.badlogic.gdx.scenes.scene2d.ui.Cell
|
||||||
@ -27,7 +28,12 @@ import com.unciv.ui.utils.extensions.toTextButton
|
|||||||
* Base class for all Popups, i.e. Tables that get rendered in the middle of a screen and on top of everything else
|
* Base class for all Popups, i.e. Tables that get rendered in the middle of a screen and on top of everything else
|
||||||
*/
|
*/
|
||||||
@Suppress("MemberVisibilityCanBePrivate")
|
@Suppress("MemberVisibilityCanBePrivate")
|
||||||
open class Popup(val screen: BaseScreen): Table(BaseScreen.skin) {
|
open class Popup(
|
||||||
|
val stageToShowOn: Stage
|
||||||
|
): Table(BaseScreen.skin) {
|
||||||
|
|
||||||
|
constructor(screen: BaseScreen) : this(screen.stage)
|
||||||
|
|
||||||
// This exists to differentiate the actual popup (the inner table)
|
// This exists to differentiate the actual popup (the inner table)
|
||||||
// from the 'screen blocking' part of the popup (which covers the entire screen)
|
// from the 'screen blocking' part of the popup (which covers the entire screen)
|
||||||
val innerTable = Table(BaseScreen.skin)
|
val innerTable = Table(BaseScreen.skin)
|
||||||
@ -38,11 +44,15 @@ open class Popup(val screen: BaseScreen): Table(BaseScreen.skin) {
|
|||||||
*/
|
*/
|
||||||
val keyPressDispatcher = KeyPressDispatcher(this.javaClass.simpleName)
|
val keyPressDispatcher = KeyPressDispatcher(this.javaClass.simpleName)
|
||||||
|
|
||||||
|
val closeListeners = mutableListOf<() -> Unit>()
|
||||||
|
|
||||||
|
val scrollPane: AutoScrollPane
|
||||||
|
|
||||||
init {
|
init {
|
||||||
// Set actor name for debugging
|
// Set actor name for debugging
|
||||||
name = javaClass.simpleName
|
name = javaClass.simpleName
|
||||||
|
|
||||||
val scrollPane = AutoScrollPane(innerTable, BaseScreen.skin)
|
scrollPane = AutoScrollPane(innerTable, BaseScreen.skin)
|
||||||
|
|
||||||
background = ImageGetter.getBackground(Color.GRAY.cpy().apply { a=.5f })
|
background = ImageGetter.getBackground(Color.GRAY.cpy().apply { a=.5f })
|
||||||
innerTable.background = ImageGetter.getBackground(ImageGetter.getBlue().darken(0.5f))
|
innerTable.background = ImageGetter.getBackground(ImageGetter.getBlue().darken(0.5f))
|
||||||
@ -61,11 +71,11 @@ open class Popup(val screen: BaseScreen): Table(BaseScreen.skin) {
|
|||||||
* closed. Use [force] = true if you want to open this popup above the other one anyway.
|
* closed. Use [force] = true if you want to open this popup above the other one anyway.
|
||||||
*/
|
*/
|
||||||
fun open(force: Boolean = false) {
|
fun open(force: Boolean = false) {
|
||||||
screen.stage.addActor(this)
|
stageToShowOn.addActor(this)
|
||||||
innerTable.pack()
|
innerTable.pack()
|
||||||
pack()
|
pack()
|
||||||
center(screen.stage)
|
center(stageToShowOn)
|
||||||
if (force || !screen.hasOpenPopups()) {
|
if (force || !stageToShowOn.hasOpenPopups()) {
|
||||||
show()
|
show()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,18 +83,19 @@ open class Popup(val screen: BaseScreen): Table(BaseScreen.skin) {
|
|||||||
/** Subroutine for [open] handles only visibility and [keyPressDispatcher] */
|
/** Subroutine for [open] handles only visibility and [keyPressDispatcher] */
|
||||||
private fun show() {
|
private fun show() {
|
||||||
this.isVisible = true
|
this.isVisible = true
|
||||||
val currentCount = screen.countOpenPopups()
|
val currentCount = stageToShowOn.countOpenPopups()
|
||||||
// the lambda is for stacked key dispatcher precedence:
|
// the lambda is for stacked key dispatcher precedence:
|
||||||
keyPressDispatcher.install(screen.stage) { screen.countOpenPopups() > currentCount }
|
keyPressDispatcher.install(stageToShowOn) { stageToShowOn.countOpenPopups() > currentCount }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Close this popup and - if any other popups are pending - display the next one.
|
* Close this popup and - if any other popups are pending - display the next one.
|
||||||
*/
|
*/
|
||||||
open fun close() {
|
open fun close() {
|
||||||
|
for (listener in closeListeners) listener()
|
||||||
keyPressDispatcher.uninstall()
|
keyPressDispatcher.uninstall()
|
||||||
remove()
|
remove()
|
||||||
val nextPopup = screen.stage.actors.firstOrNull { it is Popup }
|
val nextPopup = stageToShowOn.actors.firstOrNull { it is Popup }
|
||||||
if (nextPopup != null) (nextPopup as Popup).show()
|
if (nextPopup != null) (nextPopup as Popup).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +115,7 @@ open class Popup(val screen: BaseScreen): Table(BaseScreen.skin) {
|
|||||||
val label = text.toLabel(fontSize = size)
|
val label = text.toLabel(fontSize = size)
|
||||||
label.wrap = true
|
label.wrap = true
|
||||||
label.setAlignment(Align.center)
|
label.setAlignment(Align.center)
|
||||||
return add(label).width(screen.stage.width / 2)
|
return add(label).width(stageToShowOn.width / 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -219,9 +230,9 @@ open class Popup(val screen: BaseScreen): Table(BaseScreen.skin) {
|
|||||||
* [FocusListener][com.badlogic.gdx.scenes.scene2d.utils.FocusListener] cancels the event.
|
* [FocusListener][com.badlogic.gdx.scenes.scene2d.utils.FocusListener] cancels the event.
|
||||||
*/
|
*/
|
||||||
var keyboardFocus: Actor?
|
var keyboardFocus: Actor?
|
||||||
get() = screen.stage.keyboardFocus
|
get() = stageToShowOn.keyboardFocus
|
||||||
set(value) {
|
set(value) {
|
||||||
if (screen.stage.setKeyboardFocus(value))
|
if (stageToShowOn.setKeyboardFocus(value))
|
||||||
(value as? TextField)?.selectAll()
|
(value as? TextField)?.selectAll()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -230,25 +241,22 @@ open class Popup(val screen: BaseScreen): Table(BaseScreen.skin) {
|
|||||||
* Checks if there are visible [Popup]s.
|
* Checks if there are visible [Popup]s.
|
||||||
* @return `true` if any were found.
|
* @return `true` if any were found.
|
||||||
*/
|
*/
|
||||||
fun BaseScreen.hasOpenPopups(): Boolean = stage.actors.any { it is Popup && it.isVisible }
|
fun BaseScreen.hasOpenPopups(): Boolean = stage.hasOpenPopups()
|
||||||
|
private fun Stage.hasOpenPopups(): Boolean = actors.any { it is Popup && it.isVisible }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Counts number of visible[Popup]s.
|
* Counts number of visible[Popup]s.
|
||||||
*
|
*
|
||||||
* Used for key dispatcher precedence.
|
* Used for key dispatcher precedence.
|
||||||
*/
|
*/
|
||||||
fun BaseScreen.countOpenPopups() = stage.actors.count { it is Popup && it.isVisible }
|
private fun Stage.countOpenPopups() = actors.count { it is Popup && it.isVisible }
|
||||||
|
|
||||||
/** Closes all [Popup]s. */
|
/** Closes all [Popup]s. */
|
||||||
fun BaseScreen.closeAllPopups() = popups.forEach { it.close() }
|
fun BaseScreen.closeAllPopups() = stage.popups.forEach { it.close() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Closes the topmost visible [Popup].
|
|
||||||
* @return The [name][Popup.name] of the closed [Popup] if any popup was closed and if it had a name.
|
|
||||||
*/
|
|
||||||
fun BaseScreen.closeOneVisiblePopup() = popups.lastOrNull { it.isVisible }?.apply { close() }?.name
|
|
||||||
|
|
||||||
/** @return A [List] of currently active or pending [Popup] screens. */
|
/** @return A [List] of currently active or pending [Popup] screens. */
|
||||||
val BaseScreen.popups: List<Popup>
|
val BaseScreen.popups
|
||||||
get() = stage.actors.filterIsInstance<Popup>()
|
get() = stage.popups
|
||||||
|
private val Stage.popups: List<Popup>
|
||||||
|
get() = actors.filterIsInstance<Popup>()
|
||||||
|
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.unciv.ui.popup
|
package com.unciv.ui.popup
|
||||||
|
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||||
import com.unciv.ui.utils.BaseScreen
|
import com.unciv.ui.utils.BaseScreen
|
||||||
@ -10,7 +11,10 @@ import kotlinx.coroutines.delay
|
|||||||
* This is an unobtrusive popup which will close itself after a given amount of time.
|
* This is an unobtrusive popup which will close itself after a given amount of time.
|
||||||
* Default time is two seconds (in milliseconds)
|
* Default time is two seconds (in milliseconds)
|
||||||
*/
|
*/
|
||||||
class ToastPopup (message: String, screen: BaseScreen, val time: Long = 2000) : Popup(screen){
|
class ToastPopup (message: String, stage: Stage, val time: Long = 2000) : Popup(stage){
|
||||||
|
|
||||||
|
constructor(message: String, screen: BaseScreen, time: Long = 2000) : this(message, screen.stage, time)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
//Make this popup unobtrusive
|
//Make this popup unobtrusive
|
||||||
setFillParent(false)
|
setFillParent(false)
|
||||||
@ -20,7 +24,7 @@ class ToastPopup (message: String, screen: BaseScreen, val time: Long = 2000) :
|
|||||||
open()
|
open()
|
||||||
//move it to the top so its not in the middle of the screen
|
//move it to the top so its not in the middle of the screen
|
||||||
//have to be done after open() because open() centers the popup
|
//have to be done after open() because open() centers the popup
|
||||||
y = screen.stage.height - (height + 20f)
|
y = stage.height - (height + 20f)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun startTimer(){
|
private fun startTimer(){
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package com.unciv.ui.popup
|
package com.unciv.ui.popup
|
||||||
|
|
||||||
import com.badlogic.gdx.Gdx
|
import com.badlogic.gdx.Gdx
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||||
import com.badlogic.gdx.utils.Align
|
import com.badlogic.gdx.utils.Align
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
@ -16,10 +17,17 @@ import com.unciv.ui.utils.extensions.toLabel
|
|||||||
*/
|
*/
|
||||||
open class YesNoPopup(
|
open class YesNoPopup(
|
||||||
question: String,
|
question: String,
|
||||||
action: ()->Unit,
|
stage: Stage,
|
||||||
screen: BaseScreen = UncivGame.Current.worldScreen,
|
restoreDefault: () -> Unit = {},
|
||||||
restoreDefault: ()->Unit = {}
|
action: () -> Unit
|
||||||
) : Popup(screen) {
|
) : Popup(stage) {
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
question: String,
|
||||||
|
screen: BaseScreen,
|
||||||
|
restoreDefault: () -> Unit = {},
|
||||||
|
action: () -> Unit
|
||||||
|
) : this(question, screen.stage, restoreDefault, action)
|
||||||
|
|
||||||
/** The [Label][com.badlogic.gdx.scenes.scene2d.ui.Label] created for parameter `question` for optional layout tweaking */
|
/** The [Label][com.badlogic.gdx.scenes.scene2d.ui.Label] created for parameter `question` for optional layout tweaking */
|
||||||
private val promptLabel = question.toLabel()
|
private val promptLabel = question.toLabel()
|
||||||
@ -34,12 +42,11 @@ open class YesNoPopup (
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Shortcut to open a [YesNoPopup] with the exit game question */
|
/** Shortcut to open a [YesNoPopup] with the exit game question */
|
||||||
class ExitGamePopup(screen: BaseScreen, force: Boolean = false)
|
class ExitGamePopup(screen: BaseScreen, force: Boolean = false) : YesNoPopup(
|
||||||
: YesNoPopup(
|
|
||||||
question = "Do you want to exit the game?",
|
question = "Do you want to exit the game?",
|
||||||
action = { Gdx.app.exit() },
|
|
||||||
screen = screen,
|
screen = screen,
|
||||||
restoreDefault = { screen.game.musicController.resume() }
|
restoreDefault = { screen.game.musicController.resume() },
|
||||||
|
action = { Gdx.app.exit() }
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
screen.game.musicController.pause()
|
screen.game.musicController.pause()
|
||||||
|
@ -6,9 +6,11 @@ import com.unciv.UncivGame
|
|||||||
import com.unciv.logic.GameInfo
|
import com.unciv.logic.GameInfo
|
||||||
import com.unciv.ui.crashhandling.launchCrashHandling
|
import com.unciv.ui.crashhandling.launchCrashHandling
|
||||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||||
|
import com.unciv.ui.multiplayer.MultiplayerHelpers
|
||||||
import com.unciv.ui.popup.Popup
|
import com.unciv.ui.popup.Popup
|
||||||
import com.unciv.ui.popup.ToastPopup
|
import com.unciv.ui.popup.ToastPopup
|
||||||
import com.unciv.ui.worldscreen.WorldScreen
|
import com.unciv.ui.worldscreen.WorldScreen
|
||||||
|
import com.unciv.utils.Log
|
||||||
|
|
||||||
|
|
||||||
//todo reduce code duplication
|
//todo reduce code duplication
|
||||||
@ -70,6 +72,7 @@ object QuickSave {
|
|||||||
outOfMemory()
|
outOfMemory()
|
||||||
return@launchCrashHandling
|
return@launchCrashHandling
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
|
Log.error("Could not autoload game", ex)
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
loadingPopup.close()
|
loadingPopup.close()
|
||||||
ToastPopup("Cannot resume game!", screen)
|
ToastPopup("Cannot resume game!", screen)
|
||||||
@ -82,6 +85,13 @@ object QuickSave {
|
|||||||
screen.game.onlineMultiplayer.loadGame(savedGame)
|
screen.game.onlineMultiplayer.loadGame(savedGame)
|
||||||
} catch (oom: OutOfMemoryError) {
|
} catch (oom: OutOfMemoryError) {
|
||||||
outOfMemory()
|
outOfMemory()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
val message = MultiplayerHelpers.getLoadExceptionMessage(ex)
|
||||||
|
Log.error("Could not autoload game", ex)
|
||||||
|
postCrashHandlingRunnable {
|
||||||
|
loadingPopup.close()
|
||||||
|
ToastPopup(message, screen)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
postCrashHandlingRunnable { /// ... and load it into the screen on main thread for GL context
|
postCrashHandlingRunnable { /// ... and load it into the screen on main thread for GL context
|
||||||
@ -89,6 +99,10 @@ object QuickSave {
|
|||||||
screen.game.loadGame(savedGame)
|
screen.game.loadGame(savedGame)
|
||||||
} catch (oom: OutOfMemoryError) {
|
} catch (oom: OutOfMemoryError) {
|
||||||
outOfMemory()
|
outOfMemory()
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
Log.error("Could not autoload game", ex)
|
||||||
|
loadingPopup.close()
|
||||||
|
ToastPopup("Cannot resume game!", screen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ class SaveGameScreen(val gameInfo: GameInfo) : LoadOrSaveScreen("Current saves")
|
|||||||
rightSideButton.setText("Save game".tr())
|
rightSideButton.setText("Save game".tr())
|
||||||
val saveAction = {
|
val saveAction = {
|
||||||
if (game.gameSaver.getSave(gameNameTextField.text).exists())
|
if (game.gameSaver.getSave(gameNameTextField.text).exists())
|
||||||
YesNoPopup("Overwrite existing file?", { saveGame() }, this).open()
|
YesNoPopup("Overwrite existing file?", this) { saveGame() }.open()
|
||||||
else saveGame()
|
else saveGame()
|
||||||
}
|
}
|
||||||
rightSideButton.onClick(saveAction)
|
rightSideButton.onClick(saveAction)
|
||||||
|
@ -172,7 +172,7 @@ class TileGroupIcons(val tileGroup: TileGroup) {
|
|||||||
val shouldDisplayResource =
|
val shouldDisplayResource =
|
||||||
if (tileGroup.showEntireMap) showResourcesAndImprovements
|
if (tileGroup.showEntireMap) showResourcesAndImprovements
|
||||||
else showResourcesAndImprovements
|
else showResourcesAndImprovements
|
||||||
&& tileGroup.tileInfo.hasViewableResource(UncivGame.Current.worldScreen.viewingCiv)
|
&& tileGroup.tileInfo.hasViewableResource(UncivGame.Current.worldScreen!!.viewingCiv)
|
||||||
tileGroup.resourceImage!!.isVisible = shouldDisplayResource
|
tileGroup.resourceImage!!.isVisible = shouldDisplayResource
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,7 @@ class DiplomacyScreen(
|
|||||||
private val rightSideTable = Table()
|
private val rightSideTable = Table()
|
||||||
private val closeButton = Constants.close.toTextButton()
|
private val closeButton = Constants.close.toTextButton()
|
||||||
|
|
||||||
private fun isNotPlayersTurn() = !UncivGame.Current.worldScreen.canChangeState
|
private fun isNotPlayersTurn() = !UncivGame.Current.worldScreen!!.canChangeState
|
||||||
|
|
||||||
init {
|
init {
|
||||||
onBackButtonClicked { UncivGame.Current.resetToWorldScreen() }
|
onBackButtonClicked { UncivGame.Current.resetToWorldScreen() }
|
||||||
@ -205,7 +205,7 @@ class DiplomacyScreen(
|
|||||||
wrapper.addTooltip(name, 18f)
|
wrapper.addTooltip(name, 18f)
|
||||||
wrapper.onClick {
|
wrapper.onClick {
|
||||||
val pedia = CivilopediaScreen(
|
val pedia = CivilopediaScreen(
|
||||||
UncivGame.Current.gameInfo.ruleSet,
|
UncivGame.Current.gameInfo!!.ruleSet,
|
||||||
this,
|
this,
|
||||||
link = "Resource/$name"
|
link = "Resource/$name"
|
||||||
)
|
)
|
||||||
@ -389,11 +389,11 @@ class DiplomacyScreen(
|
|||||||
private fun getRevokeProtectionButton(otherCiv: CivilizationInfo): TextButton {
|
private fun getRevokeProtectionButton(otherCiv: CivilizationInfo): TextButton {
|
||||||
val revokeProtectionButton = "Revoke Protection".toTextButton()
|
val revokeProtectionButton = "Revoke Protection".toTextButton()
|
||||||
revokeProtectionButton.onClick {
|
revokeProtectionButton.onClick {
|
||||||
YesNoPopup("Revoke protection for [${otherCiv.civName}]?", {
|
YesNoPopup("Revoke protection for [${otherCiv.civName}]?", this) {
|
||||||
otherCiv.removeProtectorCiv(viewingCiv)
|
otherCiv.removeProtectorCiv(viewingCiv)
|
||||||
updateLeftSideTable(otherCiv)
|
updateLeftSideTable(otherCiv)
|
||||||
updateRightSide(otherCiv)
|
updateRightSide(otherCiv)
|
||||||
}, this).open()
|
}.open()
|
||||||
}
|
}
|
||||||
if (isNotPlayersTurn() || !otherCiv.otherCivCanWithdrawProtection(viewingCiv)) revokeProtectionButton.disable()
|
if (isNotPlayersTurn() || !otherCiv.otherCivCanWithdrawProtection(viewingCiv)) revokeProtectionButton.disable()
|
||||||
return revokeProtectionButton
|
return revokeProtectionButton
|
||||||
@ -402,11 +402,11 @@ class DiplomacyScreen(
|
|||||||
private fun getPledgeToProtectButton(otherCiv: CivilizationInfo): TextButton {
|
private fun getPledgeToProtectButton(otherCiv: CivilizationInfo): TextButton {
|
||||||
val protectionButton = "Pledge to protect".toTextButton()
|
val protectionButton = "Pledge to protect".toTextButton()
|
||||||
protectionButton.onClick {
|
protectionButton.onClick {
|
||||||
YesNoPopup("Declare Protection of [${otherCiv.civName}]?", {
|
YesNoPopup("Declare Protection of [${otherCiv.civName}]?", this) {
|
||||||
otherCiv.addProtectorCiv(viewingCiv)
|
otherCiv.addProtectorCiv(viewingCiv)
|
||||||
updateLeftSideTable(otherCiv)
|
updateLeftSideTable(otherCiv)
|
||||||
updateRightSide(otherCiv)
|
updateRightSide(otherCiv)
|
||||||
}, this).open()
|
}.open()
|
||||||
}
|
}
|
||||||
if (isNotPlayersTurn() || !otherCiv.otherCivCanPledgeProtection(viewingCiv)) protectionButton.disable()
|
if (isNotPlayersTurn() || !otherCiv.otherCivCanPledgeProtection(viewingCiv)) protectionButton.disable()
|
||||||
return protectionButton
|
return protectionButton
|
||||||
@ -418,7 +418,7 @@ class DiplomacyScreen(
|
|||||||
): TextButton {
|
): TextButton {
|
||||||
val peaceButton = "Negotiate Peace".toTextButton()
|
val peaceButton = "Negotiate Peace".toTextButton()
|
||||||
peaceButton.onClick {
|
peaceButton.onClick {
|
||||||
YesNoPopup("Peace with [${otherCiv.civName}]?", {
|
YesNoPopup("Peace with [${otherCiv.civName}]?", this) {
|
||||||
val tradeLogic = TradeLogic(viewingCiv, otherCiv)
|
val tradeLogic = TradeLogic(viewingCiv, otherCiv)
|
||||||
tradeLogic.currentTrade.ourOffers.add(
|
tradeLogic.currentTrade.ourOffers.add(
|
||||||
TradeOffer(
|
TradeOffer(
|
||||||
@ -435,7 +435,7 @@ class DiplomacyScreen(
|
|||||||
tradeLogic.acceptTrade()
|
tradeLogic.acceptTrade()
|
||||||
updateLeftSideTable(otherCiv)
|
updateLeftSideTable(otherCiv)
|
||||||
updateRightSide(otherCiv)
|
updateRightSide(otherCiv)
|
||||||
}, this).open()
|
}.open()
|
||||||
}
|
}
|
||||||
val cityStatesAlly = otherCiv.getAllyCiv()
|
val cityStatesAlly = otherCiv.getAllyCiv()
|
||||||
val atWarWithItsAlly = viewingCiv.getKnownCivs()
|
val atWarWithItsAlly = viewingCiv.getKnownCivs()
|
||||||
@ -761,11 +761,11 @@ class DiplomacyScreen(
|
|||||||
): TextButton {
|
): TextButton {
|
||||||
val denounceButton = "Denounce ([30] turns)".toTextButton()
|
val denounceButton = "Denounce ([30] turns)".toTextButton()
|
||||||
denounceButton.onClick {
|
denounceButton.onClick {
|
||||||
YesNoPopup("Denounce [${otherCiv.civName}]?", {
|
YesNoPopup("Denounce [${otherCiv.civName}]?", this) {
|
||||||
diplomacyManager.denounce()
|
diplomacyManager.denounce()
|
||||||
updateLeftSideTable(otherCiv)
|
updateLeftSideTable(otherCiv)
|
||||||
setRightSideFlavorText(otherCiv, "We will remember this.", "Very well.")
|
setRightSideFlavorText(otherCiv, "We will remember this.", "Very well.")
|
||||||
}, this).open()
|
}.open()
|
||||||
}
|
}
|
||||||
if (isNotPlayersTurn()) denounceButton.disable()
|
if (isNotPlayersTurn()) denounceButton.disable()
|
||||||
return denounceButton
|
return denounceButton
|
||||||
@ -956,12 +956,12 @@ class DiplomacyScreen(
|
|||||||
declareWarButton.setText(declareWarButton.text.toString() + " ($turnsToPeaceTreaty${Fonts.turn})")
|
declareWarButton.setText(declareWarButton.text.toString() + " ($turnsToPeaceTreaty${Fonts.turn})")
|
||||||
}
|
}
|
||||||
declareWarButton.onClick {
|
declareWarButton.onClick {
|
||||||
YesNoPopup("Declare war on [${otherCiv.civName}]?", {
|
YesNoPopup("Declare war on [${otherCiv.civName}]?", this) {
|
||||||
diplomacyManager.declareWar()
|
diplomacyManager.declareWar()
|
||||||
setRightSideFlavorText(otherCiv, otherCiv.nation.attacked, "Very well.")
|
setRightSideFlavorText(otherCiv, otherCiv.nation.attacked, "Very well.")
|
||||||
updateLeftSideTable(otherCiv)
|
updateLeftSideTable(otherCiv)
|
||||||
UncivGame.Current.musicController.chooseTrack(otherCiv.civName, MusicMood.War, MusicTrackChooserFlags.setSpecific)
|
UncivGame.Current.musicController.chooseTrack(otherCiv.civName, MusicMood.War, MusicTrackChooserFlags.setSpecific)
|
||||||
}, this).open()
|
}.open()
|
||||||
}
|
}
|
||||||
if (isNotPlayersTurn()) declareWarButton.disable()
|
if (isNotPlayersTurn()) declareWarButton.disable()
|
||||||
return declareWarButton
|
return declareWarButton
|
||||||
@ -996,8 +996,11 @@ class DiplomacyScreen(
|
|||||||
private fun getGoToOnMapButton(civilization: CivilizationInfo): TextButton {
|
private fun getGoToOnMapButton(civilization: CivilizationInfo): TextButton {
|
||||||
val goToOnMapButton = "Go to on map".toTextButton()
|
val goToOnMapButton = "Go to on map".toTextButton()
|
||||||
goToOnMapButton.onClick {
|
goToOnMapButton.onClick {
|
||||||
|
val worldScreen = UncivGame.Current.worldScreen
|
||||||
|
if (worldScreen != null) {
|
||||||
UncivGame.Current.resetToWorldScreen()
|
UncivGame.Current.resetToWorldScreen()
|
||||||
UncivGame.Current.worldScreen.mapHolder.setCenterPosition(civilization.getCapital()!!.location, selectUnit = false)
|
worldScreen.mapHolder.setCenterPosition(civilization.getCapital()!!.location, selectUnit = false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return goToOnMapButton
|
return goToOnMapButton
|
||||||
}
|
}
|
||||||
|
@ -92,7 +92,7 @@ class OffersListScroll(
|
|||||||
Luxury_Resource, Strategic_Resource ->
|
Luxury_Resource, Strategic_Resource ->
|
||||||
ImageGetter.getResourceImage(offer.name, 30f)
|
ImageGetter.getResourceImage(offer.name, 30f)
|
||||||
WarDeclaration ->
|
WarDeclaration ->
|
||||||
ImageGetter.getNationIndicator(UncivGame.Current.gameInfo.ruleSet.nations[offer.name]!!, 30f)
|
ImageGetter.getNationIndicator(UncivGame.Current.gameInfo!!.ruleSet.nations[offer.name]!!, 30f)
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
val tradeButton = IconTextButton(tradeLabel, tradeIcon).apply {
|
val tradeButton = IconTextButton(tradeLabel, tradeIcon).apply {
|
||||||
|
@ -7,16 +7,22 @@ import com.badlogic.gdx.graphics.GL20
|
|||||||
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
import com.badlogic.gdx.graphics.g2d.BitmapFont
|
||||||
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
import com.badlogic.gdx.graphics.g2d.SpriteBatch
|
||||||
import com.badlogic.gdx.scenes.scene2d.Stage
|
import com.badlogic.gdx.scenes.scene2d.Stage
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.*
|
import com.badlogic.gdx.scenes.scene2d.ui.CheckBox
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Label
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.Skin
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
|
||||||
|
import com.badlogic.gdx.scenes.scene2d.ui.TextField
|
||||||
import com.badlogic.gdx.scenes.scene2d.utils.Drawable
|
import com.badlogic.gdx.scenes.scene2d.utils.Drawable
|
||||||
import com.badlogic.gdx.utils.viewport.ExtendViewport
|
import com.badlogic.gdx.utils.viewport.ExtendViewport
|
||||||
import com.unciv.UncivGame
|
import com.unciv.UncivGame
|
||||||
import com.unciv.models.Tutorial
|
import com.unciv.models.Tutorial
|
||||||
import com.unciv.ui.UncivStage
|
import com.unciv.ui.UncivStage
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
|
import com.unciv.ui.options.OptionsPopup
|
||||||
import com.unciv.ui.popup.hasOpenPopups
|
import com.unciv.ui.popup.hasOpenPopups
|
||||||
import com.unciv.ui.tutorials.TutorialController
|
import com.unciv.ui.tutorials.TutorialController
|
||||||
import com.unciv.ui.options.OptionsPopup
|
import com.unciv.ui.utils.extensions.isNarrowerThan4to3
|
||||||
|
|
||||||
abstract class BaseScreen : Screen {
|
abstract class BaseScreen : Screen {
|
||||||
|
|
||||||
@ -122,7 +128,7 @@ abstract class BaseScreen : Screen {
|
|||||||
fun isCrampedPortrait() = isPortrait() &&
|
fun isCrampedPortrait() = isPortrait() &&
|
||||||
game.settings.resolution.split("x").map { it.toInt() }.last() <= 700
|
game.settings.resolution.split("x").map { it.toInt() }.last() <= 700
|
||||||
/** @return `true` if the screen is narrower than 4:3 landscape */
|
/** @return `true` if the screen is narrower than 4:3 landscape */
|
||||||
fun isNarrowerThan4to3() = stage.viewport.screenHeight * 4 > stage.viewport.screenWidth * 3
|
fun isNarrowerThan4to3() = stage.isNarrowerThan4to3()
|
||||||
|
|
||||||
fun openOptionsPopup(startingPage: Int = OptionsPopup.defaultPage, onClose: () -> Unit = {}) {
|
fun openOptionsPopup(startingPage: Int = OptionsPopup.defaultPage, onClose: () -> Unit = {}) {
|
||||||
OptionsPopup(this, startingPage, onClose).open(force = true)
|
OptionsPopup(this, startingPage, onClose).open(force = true)
|
||||||
|
@ -289,7 +289,7 @@ open class TabbedPager(
|
|||||||
//region Initialization
|
//region Initialization
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val screen = (if (UncivGame.isCurrentInitialized()) UncivGame.Current.screen else null) as? BaseScreen
|
val screen = (if (UncivGame.isCurrentInitialized()) UncivGame.Current.screen else null)
|
||||||
val (screenWidth, screenHeight) = (screen?.stage?.run { width to height }) ?: (Float.MAX_VALUE to Float.MAX_VALUE)
|
val (screenWidth, screenHeight) = (screen?.stage?.run { width to height }) ?: (Float.MAX_VALUE to Float.MAX_VALUE)
|
||||||
dimW = DimensionMeasurement.from(minimumWidth, maximumWidth, screenWidth)
|
dimW = DimensionMeasurement.from(minimumWidth, maximumWidth, screenWidth)
|
||||||
dimH = DimensionMeasurement.from(minimumHeight, maximumHeight, screenHeight)
|
dimH = DimensionMeasurement.from(minimumHeight, maximumHeight, screenHeight)
|
||||||
@ -601,7 +601,7 @@ open class TabbedPager(
|
|||||||
if (!UncivGame.isCurrentInitialized() || askPasswordLock || deferredSecretPages.isEmpty()) return
|
if (!UncivGame.isCurrentInitialized() || askPasswordLock || deferredSecretPages.isEmpty()) return
|
||||||
askPasswordLock = true // race condition: Popup closes _first_, then deferredSecretPages is emptied -> parent shows and calls us again
|
askPasswordLock = true // race condition: Popup closes _first_, then deferredSecretPages is emptied -> parent shows and calls us again
|
||||||
|
|
||||||
PassPopup(UncivGame.Current.screen as BaseScreen, {
|
PassPopup(UncivGame.Current.screen!!, {
|
||||||
addDeferredSecrets()
|
addDeferredSecrets()
|
||||||
}, {
|
}, {
|
||||||
deferredSecretPages.clear()
|
deferredSecretPages.clear()
|
||||||
|
@ -229,3 +229,6 @@ fun WidgetGroup.packIfNeeded(): WidgetGroup {
|
|||||||
if (needsLayout()) pack()
|
if (needsLayout()) pack()
|
||||||
return this
|
return this
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** @return `true` if the screen is narrower than 4:3 landscape */
|
||||||
|
fun Stage.isNarrowerThan4to3() = viewport.screenHeight * 4 > viewport.screenWidth * 3
|
||||||
|
@ -3,25 +3,24 @@ package com.unciv.ui.worldscreen
|
|||||||
import com.badlogic.gdx.scenes.scene2d.Touchable
|
import com.badlogic.gdx.scenes.scene2d.Touchable
|
||||||
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
import com.badlogic.gdx.scenes.scene2d.ui.Table
|
||||||
import com.unciv.Constants
|
import com.unciv.Constants
|
||||||
import com.unciv.logic.GameInfo
|
|
||||||
import com.unciv.logic.civilization.CivilizationInfo
|
|
||||||
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
import com.unciv.ui.crashhandling.postCrashHandlingRunnable
|
||||||
import com.unciv.ui.images.ImageGetter
|
import com.unciv.ui.images.ImageGetter
|
||||||
import com.unciv.ui.utils.BaseScreen
|
import com.unciv.ui.utils.BaseScreen
|
||||||
import com.unciv.ui.utils.extensions.onClick
|
import com.unciv.ui.utils.extensions.onClick
|
||||||
import com.unciv.ui.utils.extensions.toLabel
|
import com.unciv.ui.utils.extensions.toLabel
|
||||||
|
|
||||||
class PlayerReadyScreen(gameInfo: GameInfo, currentPlayerCiv: CivilizationInfo) : BaseScreen(){
|
class PlayerReadyScreen(worldScreen: WorldScreen) : BaseScreen() {
|
||||||
init {
|
init {
|
||||||
val table = Table()
|
val table = Table()
|
||||||
table.touchable = Touchable.enabled
|
table.touchable = Touchable.enabled
|
||||||
table.background= ImageGetter.getBackground(currentPlayerCiv.nation.getOuterColor())
|
val curCiv = worldScreen.viewingCiv
|
||||||
|
table.background = ImageGetter.getBackground(curCiv.nation.getOuterColor())
|
||||||
|
|
||||||
table.add("[$currentPlayerCiv] ready?".toLabel(currentPlayerCiv.nation.getInnerColor(), Constants.headingFontSize))
|
table.add("[$curCiv] ready?".toLabel(curCiv.nation.getInnerColor(), Constants.headingFontSize))
|
||||||
|
|
||||||
table.onClick {
|
table.onClick {
|
||||||
postCrashHandlingRunnable { // To avoid ANRs on Android when the creation of the worldscreen takes more than 500ms
|
postCrashHandlingRunnable { // To avoid ANRs on Android when the creation of the worldscreen takes more than 500ms
|
||||||
game.resetToWorldScreen(WorldScreen(gameInfo, currentPlayerCiv))
|
game.setScreen(worldScreen)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
table.setFillParent(true)
|
table.setFillParent(true)
|
||||||
|
@ -216,7 +216,7 @@ class WorldMapHolder(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun onTileRightClicked(unit: MapUnit, tile: TileInfo) {
|
private fun onTileRightClicked(unit: MapUnit, tile: TileInfo) {
|
||||||
if (UncivGame.Current.gameInfo.currentPlayerCiv.isSpectator()) {
|
if (UncivGame.Current.gameInfo!!.currentPlayerCiv.isSpectator()) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
removeUnitActionOverlay()
|
removeUnitActionOverlay()
|
||||||
|
@ -336,7 +336,7 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
debug("loadLatestMultiplayerState current game: gameId: %s, turn: %s, curCiv: %s",
|
debug("loadLatestMultiplayerState current game: gameId: %s, turn: %s, curCiv: %s",
|
||||||
game.worldScreen.gameInfo.gameId, game.worldScreen.gameInfo.turns, game.worldScreen.gameInfo.currentPlayer)
|
gameInfo.gameId, gameInfo.turns, gameInfo.currentPlayer)
|
||||||
val latestGame = game.onlineMultiplayer.downloadGame(gameInfo.gameId)
|
val latestGame = game.onlineMultiplayer.downloadGame(gameInfo.gameId)
|
||||||
debug("loadLatestMultiplayerState downloaded game: gameId: %s, turn: %s, curCiv: %s",
|
debug("loadLatestMultiplayerState downloaded game: gameId: %s, turn: %s, curCiv: %s",
|
||||||
latestGame.gameId, latestGame.turns, latestGame.currentPlayer)
|
latestGame.gameId, latestGame.turns, latestGame.currentPlayer)
|
||||||
@ -345,8 +345,8 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
|
|||||||
}
|
}
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
loadingGamePopup.close()
|
loadingGamePopup.close()
|
||||||
if (game.gameInfo.gameId == gameInfo.gameId) { // game could've been changed during download
|
if (game.gameInfo!!.gameId == gameInfo.gameId) { // game could've been changed during download
|
||||||
createNewWorldScreen(latestGame)
|
game.setScreen(createNewWorldScreen(latestGame))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
@ -602,7 +602,7 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createNewWorldScreen(gameInfo: GameInfo, resize:Boolean=false) {
|
private fun createNewWorldScreen(gameInfo: GameInfo, resize:Boolean=false): WorldScreen {
|
||||||
|
|
||||||
game.gameInfo = gameInfo
|
game.gameInfo = gameInfo
|
||||||
val newWorldScreen = WorldScreen(gameInfo, gameInfo.getPlayerToViewAs())
|
val newWorldScreen = WorldScreen(gameInfo, gameInfo.getPlayerToViewAs())
|
||||||
@ -621,7 +621,7 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
|
|||||||
newWorldScreen.selectedCiv = gameInfo.getCivilization(selectedCiv.civName)
|
newWorldScreen.selectedCiv = gameInfo.getCivilization(selectedCiv.civName)
|
||||||
newWorldScreen.fogOfWar = fogOfWar
|
newWorldScreen.fogOfWar = fogOfWar
|
||||||
|
|
||||||
game.resetToWorldScreen(newWorldScreen)
|
return newWorldScreen
|
||||||
}
|
}
|
||||||
|
|
||||||
fun nextTurn() {
|
fun nextTurn() {
|
||||||
@ -669,16 +669,15 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
|
|||||||
// create a new WorldScreen to show the new stuff we've changed, and switch out the current screen.
|
// create a new WorldScreen to show the new stuff we've changed, and switch out the current screen.
|
||||||
// do this on main thread - it's the only one that has a GL context to create images from
|
// do this on main thread - it's the only one that has a GL context to create images from
|
||||||
postCrashHandlingRunnable {
|
postCrashHandlingRunnable {
|
||||||
|
val newWorldScreen = createNewWorldScreen(gameInfoClone)
|
||||||
if (gameInfoClone.currentPlayerCiv.civName != viewingCiv.civName
|
if (gameInfoClone.currentPlayerCiv.civName != viewingCiv.civName
|
||||||
&& !gameInfoClone.gameParameters.isOnlineMultiplayer)
|
&& !gameInfoClone.gameParameters.isOnlineMultiplayer) {
|
||||||
game.setScreen(PlayerReadyScreen(gameInfoClone, gameInfoClone.getCurrentPlayerCivilization()))
|
game.setScreen(PlayerReadyScreen(newWorldScreen))
|
||||||
else {
|
} else {
|
||||||
createNewWorldScreen(gameInfoClone)
|
game.setScreen(newWorldScreen)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shouldAutoSave) {
|
if (shouldAutoSave) {
|
||||||
val newWorldScreen = this@WorldScreen.game.worldScreen
|
|
||||||
newWorldScreen.waitingForAutosave = true
|
newWorldScreen.waitingForAutosave = true
|
||||||
newWorldScreen.shouldUpdate = true
|
newWorldScreen.shouldUpdate = true
|
||||||
game.gameSaver.autoSave(gameInfoClone) {
|
game.gameSaver.autoSave(gameInfoClone) {
|
||||||
@ -821,7 +820,7 @@ class WorldScreen(val gameInfo: GameInfo, val viewingCiv:CivilizationInfo) : Bas
|
|||||||
nextTurn()
|
nextTurn()
|
||||||
}
|
}
|
||||||
if (game.settings.confirmNextTurn) {
|
if (game.settings.confirmNextTurn) {
|
||||||
YesNoPopup("Confirm next turn", action, this).open()
|
YesNoPopup("Confirm next turn", this, action = action).open()
|
||||||
} else {
|
} else {
|
||||||
action()
|
action()
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@ class TileInfoTable(private val viewingCiv :CivilizationInfo) : Table(BaseScreen
|
|||||||
if (tile != null && (UncivGame.Current.viewEntireMapForDebug || viewingCiv.exploredTiles.contains(tile.position)) ) {
|
if (tile != null && (UncivGame.Current.viewEntireMapForDebug || viewingCiv.exploredTiles.contains(tile.position)) ) {
|
||||||
add(getStatsTable(tile))
|
add(getStatsTable(tile))
|
||||||
add( MarkupRenderer.render(tile.toMarkup(viewingCiv), padding = 0f, iconDisplay = IconDisplay.None) {
|
add( MarkupRenderer.render(tile.toMarkup(viewingCiv), padding = 0f, iconDisplay = IconDisplay.None) {
|
||||||
UncivGame.Current.setScreen(CivilopediaScreen(viewingCiv.gameInfo.ruleSet, UncivGame.Current.worldScreen, link = it))
|
UncivGame.Current.setScreen(CivilopediaScreen(viewingCiv.gameInfo.ruleSet, UncivGame.Current.worldScreen!!, link = it))
|
||||||
} ).pad(5f).row()
|
} ).pad(5f).row()
|
||||||
if (UncivGame.Current.viewEntireMapForDebug)
|
if (UncivGame.Current.viewEntireMapForDebug)
|
||||||
add(tile.position.run { "(${x.toInt()},${y.toInt()})" }.toLabel()).colspan(2).pad(5f)
|
add(tile.position.run { "(${x.toInt()},${y.toInt()})" }.toLabel()).colspan(2).pad(5f)
|
||||||
|
@ -42,7 +42,7 @@ class MapOverlayToggleButton(
|
|||||||
/** Toggle overlay. Called on click. */
|
/** Toggle overlay. Called on click. */
|
||||||
fun toggle() {
|
fun toggle() {
|
||||||
setter(!getter())
|
setter(!getter())
|
||||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
UncivGame.Current.worldScreen!!.shouldUpdate = true
|
||||||
// Setting worldScreen.shouldUpdate implicitly causes this.update() to be called by the WorldScreen on the next update.
|
// Setting worldScreen.shouldUpdate implicitly causes this.update() to be called by the WorldScreen on the next update.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -127,7 +127,7 @@ object UnitActions {
|
|||||||
val disbandText = if (unit.currentTile.getOwner() == unit.civInfo)
|
val disbandText = if (unit.currentTile.getOwner() == unit.civInfo)
|
||||||
"Disband this unit for [${unit.baseUnit.getDisbandGold(unit.civInfo)}] gold?".tr()
|
"Disband this unit for [${unit.baseUnit.getDisbandGold(unit.civInfo)}] gold?".tr()
|
||||||
else "Do you really want to disband this unit?".tr()
|
else "Do you really want to disband this unit?".tr()
|
||||||
YesNoPopup(disbandText, { unit.disband(); worldScreen.shouldUpdate = true }).open()
|
YesNoPopup(disbandText, UncivGame.Current.worldScreen!!) { unit.disband(); worldScreen.shouldUpdate = true }.open()
|
||||||
}
|
}
|
||||||
}.takeIf { unit.currentMovement > 0 })
|
}.takeIf { unit.currentMovement > 0 })
|
||||||
}
|
}
|
||||||
@ -187,7 +187,7 @@ object UnitActions {
|
|||||||
if (tile.ruleset.tileImprovements.containsKey("City center"))
|
if (tile.ruleset.tileImprovements.containsKey("City center"))
|
||||||
tile.improvement = "City center"
|
tile.improvement = "City center"
|
||||||
unit.destroy()
|
unit.destroy()
|
||||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
UncivGame.Current.worldScreen!!.shouldUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unit.civInfo.playerType == PlayerType.AI)
|
if (unit.civInfo.playerType == PlayerType.AI)
|
||||||
@ -204,7 +204,7 @@ object UnitActions {
|
|||||||
else {
|
else {
|
||||||
// ask if we would be breaking a promise
|
// ask if we would be breaking a promise
|
||||||
val text = "Do you want to break your promise to [$leaders]?"
|
val text = "Do you want to break your promise to [$leaders]?"
|
||||||
YesNoPopup(text, foundAction, UncivGame.Current.worldScreen).open(force = true)
|
YesNoPopup(text, UncivGame.Current.worldScreen!!, action = foundAction).open(force = true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
@ -275,7 +275,7 @@ object UnitActions {
|
|||||||
else actionList += UnitAction(type = UnitActionType.Pillage) {
|
else actionList += UnitAction(type = UnitActionType.Pillage) {
|
||||||
if (!worldScreen.hasOpenPopups()) {
|
if (!worldScreen.hasOpenPopups()) {
|
||||||
val pillageText = "Are you sure you want to pillage this [${unit.currentTile.improvement}]?"
|
val pillageText = "Are you sure you want to pillage this [${unit.currentTile.improvement}]?"
|
||||||
YesNoPopup(pillageText, { (pillageAction.action)(); worldScreen.shouldUpdate = true }).open()
|
YesNoPopup(pillageText, UncivGame.Current.worldScreen!!) { (pillageAction.action)(); worldScreen.shouldUpdate = true }.open()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -853,7 +853,7 @@ object UnitActions {
|
|||||||
unit.destroy() // City states dont get GPs
|
unit.destroy() // City states dont get GPs
|
||||||
else
|
else
|
||||||
unit.gift(recipient)
|
unit.gift(recipient)
|
||||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
UncivGame.Current.worldScreen!!.shouldUpdate = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return UnitAction(UnitActionType.GiftUnit, action = giftAction)
|
return UnitAction(UnitActionType.GiftUnit, action = giftAction)
|
||||||
|
@ -39,7 +39,7 @@ class UnitActionsTable(val worldScreen: WorldScreen) : Table() {
|
|||||||
actionButton.pack()
|
actionButton.pack()
|
||||||
val action = {
|
val action = {
|
||||||
unitAction.action?.invoke()
|
unitAction.action?.invoke()
|
||||||
UncivGame.Current.worldScreen.shouldUpdate = true
|
UncivGame.Current.worldScreen!!.shouldUpdate = true
|
||||||
}
|
}
|
||||||
if (unitAction.action == null) actionButton.disable()
|
if (unitAction.action == null) actionButton.disable()
|
||||||
else {
|
else {
|
||||||
|
@ -87,6 +87,7 @@ internal object DesktopLauncher {
|
|||||||
try {
|
try {
|
||||||
updateRpc(game)
|
updateRpc(game)
|
||||||
} catch (ex: Exception) {
|
} catch (ex: Exception) {
|
||||||
|
debug("Exception while updating Discord Rich Presence", ex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ex: Throwable) {
|
} catch (ex: Throwable) {
|
||||||
@ -98,10 +99,15 @@ internal object DesktopLauncher {
|
|||||||
private fun updateRpc(game: UncivGame) {
|
private fun updateRpc(game: UncivGame) {
|
||||||
if (!game.isInitialized) return
|
if (!game.isInitialized) return
|
||||||
val presence = DiscordRichPresence()
|
val presence = DiscordRichPresence()
|
||||||
val currentPlayerCiv = game.gameInfo.getCurrentPlayerCivilization()
|
|
||||||
presence.details = "${currentPlayerCiv.nation.leaderName} of ${currentPlayerCiv.nation.name}"
|
|
||||||
presence.largeImageKey = "logo" // The actual image is uploaded to the discord app / applications webpage
|
presence.largeImageKey = "logo" // The actual image is uploaded to the discord app / applications webpage
|
||||||
|
|
||||||
|
val gameInfo = game.gameInfo
|
||||||
|
if (gameInfo != null) {
|
||||||
|
val currentPlayerCiv = gameInfo.getCurrentPlayerCivilization()
|
||||||
|
presence.details = "${currentPlayerCiv.nation.leaderName} of ${currentPlayerCiv.nation.name}"
|
||||||
presence.largeImageText = "Turn" + " " + currentPlayerCiv.gameInfo.turns
|
presence.largeImageText = "Turn" + " " + currentPlayerCiv.gameInfo.turns
|
||||||
|
}
|
||||||
|
|
||||||
DiscordRPC.INSTANCE.Discord_UpdatePresence(presence)
|
DiscordRPC.INSTANCE.Discord_UpdatePresence(presence)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user