diff --git a/core/src/com/unciv/UncivGame.kt b/core/src/com/unciv/UncivGame.kt index a1833c9c09..fe336afcd1 100644 --- a/core/src/com/unciv/UncivGame.kt +++ b/core/src/com/unciv/UncivGame.kt @@ -5,7 +5,10 @@ import com.badlogic.gdx.Game import com.badlogic.gdx.Gdx import com.badlogic.gdx.Input import com.badlogic.gdx.audio.Music +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.actions.Actions +import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.utils.Align import com.unciv.logic.GameInfo import com.unciv.logic.GameSaver @@ -16,6 +19,8 @@ import com.unciv.models.metadata.GameSettings import com.unciv.models.ruleset.RulesetCache import com.unciv.models.translations.Translations import com.unciv.ui.LanguagePickerScreen +import com.unciv.ui.newgamescreen.NewGameScreen +import com.unciv.ui.saves.LoadGameScreen import com.unciv.ui.utils.* import com.unciv.ui.worldscreen.WorldScreen import java.util.* @@ -87,32 +92,33 @@ class UncivGame( // This stuff needs to run on the main thread because it needs the GL context Gdx.app.postRunnable { CameraStageBaseScreen.resetFonts() - autoLoadGame() thread(name="Music") { startMusic() } + restoreSize() + setScreen(MenuScreen()) isInitialized = true } } crashController = CrashController.Impl(crashReportSender) } - private fun restoreSize() { + fun restoreSize() { if (!isSizeRestored && Gdx.app.type == Application.ApplicationType.Desktop && settings.windowState.height>39 && settings.windowState.width>39) { isSizeRestored = true Gdx.graphics.setWindowedMode(settings.windowState.width, settings.windowState.height) } } - fun autoLoadGame() { - // IMHO better test for fresh installs than Autosave.exists() - // e.g. should someone delete the settings file only or kill the language picker screen - if (settings.isFreshlyCreated) { - return setScreen(LanguagePickerScreen()) - } - try { - loadGame("Autosave") - } catch (ex: Exception) { // silent fail if we can't read the autosave - startNewGame() - } + + fun loadGame(gameInfo: GameInfo) { + this.gameInfo = gameInfo + ImageGetter.ruleset = gameInfo.ruleSet + ImageGetter.refreshAtlas() + worldScreen = WorldScreen(gameInfo.getPlayerToViewAs()) + setWorldScreen() + } + + fun loadGame(gameName: String) { + loadGame(GameSaver.loadGameByName(gameName)) } fun startMusic() { @@ -132,24 +138,6 @@ class UncivGame( super.setScreen(screen) } - fun loadGame(gameInfo: GameInfo) { - this.gameInfo = gameInfo - ImageGetter.ruleset = gameInfo.ruleSet - ImageGetter.refreshAtlas() - restoreSize() - worldScreen = WorldScreen(gameInfo.getPlayerToViewAs()) - setWorldScreen() - } - - fun loadGame(gameName: String) { - loadGame(GameSaver.loadGameByName(gameName)) - } - - fun startNewGame() { - val newGame = GameStarter.startNewGame(GameParameters().apply { difficulty = "Chieftain" }, MapParameters()) - loadGame(newGame) - } - fun setWorldScreen() { if (screen != null && screen != worldScreen) screen.dispose() setScreen(worldScreen) @@ -163,14 +151,7 @@ class UncivGame( if (!isInitialized) return // The stuff from Create() is still happening, so the main screen will load eventually ImageGetter.refreshAtlas() - // This is to solve a rare problem - - // Sometimes, resume() is called and the gameInfo doesn't have any civilizations. - // Can happen if you resume to the language picker screen for instance. - if (!::gameInfo.isInitialized || gameInfo.civilizations.isEmpty()) - return autoLoadGame() - - if (::worldScreen.isInitialized) worldScreen.dispose() // I hope this will solve some of the many OuOfMemory exceptions... - loadGame(gameInfo) + setScreen(MenuScreen()) } // Maybe this will solve the resume error on chrome OS, issue 322? Worth a shot @@ -210,4 +191,64 @@ class LoadingScreen:CameraStageBaseScreen() { Actions.rotateBy(360f, 0.5f))) stage.addActor(happinessImage) } +} + + +class MenuScreen:CameraStageBaseScreen() { + val autosave = "Autosave" + + fun getTableBlock(text:String): Table { + val table = Table() + table.background = ImageGetter.getBackground(colorFromRGB(11, 135, 133)) + table.add(text.toLabel().setFontSize(30).apply { setAlignment(Align.center) }).pad(40f).width(200f) + table.touchable=Touchable.enabled + table.pack() + return table + } + + init { + if (game.settings.isFreshlyCreated) { + game.setScreen(LanguagePickerScreen(this)) + } else { + val table = Table().apply { defaults().pad(10f) } + val autosaveGame = GameSaver.getSave(autosave, false) + if(autosaveGame.exists()) { + val resumeTable = getTableBlock("Resume") + resumeTable.onClick { autoLoadGame() } + table.add(resumeTable).row() + } + + val quickstartTable = getTableBlock("Quickstart") + quickstartTable.onClick { startNewGame() } + table.add(quickstartTable).row() + + val newGameButton = getTableBlock("Start new game") + newGameButton.onClick { UncivGame.Current.setScreen(NewGameScreen(this)) } + table.add(newGameButton).row() + + if(GameSaver.getSaves(false).any()) { + val loadGameTable = getTableBlock("Load game") + loadGameTable.onClick { UncivGame.Current.setScreen(LoadGameScreen(this)) } + table.add(loadGameTable).row() + } + + table.pack() + table.center(stage) + stage.addActor(table) + } + } + + fun autoLoadGame() { + try { + game.loadGame(autosave) + } catch (ex: Exception) { // silent fail if we can't read the autosave + ResponsePopup("Cannot resume game!", this) + } + } + + fun startNewGame() { + val newGame = GameStarter.startNewGame(GameParameters().apply { difficulty = "Chieftain" }, MapParameters()) + game.loadGame(newGame) + } + } \ No newline at end of file diff --git a/core/src/com/unciv/ui/LanguagePickerScreen.kt b/core/src/com/unciv/ui/LanguagePickerScreen.kt index d206dcfbec..629f0ccf89 100644 --- a/core/src/com/unciv/ui/LanguagePickerScreen.kt +++ b/core/src/com/unciv/ui/LanguagePickerScreen.kt @@ -6,10 +6,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.Table import com.unciv.UncivGame import com.unciv.models.translations.tr import com.unciv.ui.pickerscreens.PickerScreen -import com.unciv.ui.utils.ImageGetter -import com.unciv.ui.utils.enable -import com.unciv.ui.utils.onClick -import com.unciv.ui.utils.toLabel +import com.unciv.ui.utils.* class LanguageTable(val language:String, val percentComplete: Int):Table(){ @@ -35,7 +32,7 @@ class LanguageTable(val language:String, val percentComplete: Int):Table(){ } -class LanguagePickerScreen: PickerScreen(){ +class LanguagePickerScreen(val previousScreen: CameraStageBaseScreen): PickerScreen(){ var chosenLanguage = "English" private val languageTables = ArrayList() @@ -77,13 +74,13 @@ class LanguagePickerScreen: PickerScreen(){ } fun pickLanguage(){ - UncivGame.Current.settings.language = chosenLanguage - UncivGame.Current.settings.isFreshlyCreated = false // mark so the picker isn't called next launch - UncivGame.Current.settings.save() + game.settings.language = chosenLanguage + game.settings.isFreshlyCreated = false // mark so the picker isn't called next launch + game.settings.save() - UncivGame.Current.translations.tryReadTranslationForCurrentLanguage() + game.translations.tryReadTranslationForCurrentLanguage() resetFonts() - UncivGame.Current.startNewGame() + game.setScreen(previousScreen) dispose() } } \ No newline at end of file diff --git a/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt b/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt index 56ea3cb8a4..290a747da0 100644 --- a/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt +++ b/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt @@ -11,6 +11,8 @@ import com.unciv.logic.GameSaver import com.unciv.logic.GameStarter import com.unciv.logic.IdChecker import com.unciv.logic.civilization.PlayerType +import com.unciv.logic.map.MapParameters +import com.unciv.models.metadata.GameParameters import com.unciv.models.ruleset.RulesetCache import com.unciv.models.translations.tr import com.unciv.ui.pickerscreens.PickerScreen @@ -19,14 +21,14 @@ import com.unciv.ui.worldscreen.mainmenu.OnlineMultiplayer import java.util.* import kotlin.concurrent.thread -class NewGameScreen: PickerScreen(){ +class NewGameScreen(previousScreen:CameraStageBaseScreen, currentGame:GameInfo?=null): PickerScreen(){ - val newGameParameters= UncivGame.Current.gameInfo.gameParameters.clone() - val mapParameters = UncivGame.Current.gameInfo.tileMap.mapParameters + val newGameParameters= currentGame?.gameParameters?.clone() ?: GameParameters() + val mapParameters = currentGame?.tileMap?.mapParameters ?: MapParameters() val ruleset = RulesetCache.getComplexRuleset(newGameParameters.mods) init { - setDefaultCloseAction() + setDefaultCloseAction(previousScreen) scrollPane.setScrollingDisabled(true,true) val playerPickerTable = PlayerPickerTable(this, newGameParameters) diff --git a/core/src/com/unciv/ui/pickerscreens/PickerScreen.kt b/core/src/com/unciv/ui/pickerscreens/PickerScreen.kt index a4141bb8fb..353e92a4ba 100644 --- a/core/src/com/unciv/ui/pickerscreens/PickerScreen.kt +++ b/core/src/com/unciv/ui/pickerscreens/PickerScreen.kt @@ -45,9 +45,10 @@ open class PickerScreen : CameraStageBaseScreen() { stage.addActor(splitPane) } - fun setDefaultCloseAction() { + fun setDefaultCloseAction(previousScreen: CameraStageBaseScreen?=null) { closeButton.onClick { - game.setWorldScreen() + if(previousScreen!=null) game.setScreen(previousScreen) + else game.setWorldScreen() dispose() } } diff --git a/core/src/com/unciv/ui/saves/LoadGameScreen.kt b/core/src/com/unciv/ui/saves/LoadGameScreen.kt index b99549a877..070d0875cf 100644 --- a/core/src/com/unciv/ui/saves/LoadGameScreen.kt +++ b/core/src/com/unciv/ui/saves/LoadGameScreen.kt @@ -15,7 +15,7 @@ import com.unciv.ui.utils.* import java.text.SimpleDateFormat import java.util.* -class LoadGameScreen : PickerScreen() { +class LoadGameScreen(previousScreen:CameraStageBaseScreen) : PickerScreen() { lateinit var selectedSave:String private val copySavedGameToClipboardButton = "Copy saved game to clipboard".toTextButton() private val saveTable = Table() @@ -23,7 +23,7 @@ class LoadGameScreen : PickerScreen() { private val showAutosavesCheckbox = CheckBox("Show autosaves".tr(), skin) init { - setDefaultCloseAction() + setDefaultCloseAction(previousScreen) resetWindowState() topTable.add(ScrollPane(saveTable)).height(stage.height*2/3) diff --git a/core/src/com/unciv/ui/victoryscreen/VictoryScreen.kt b/core/src/com/unciv/ui/victoryscreen/VictoryScreen.kt index 5fcc869c90..4be8338d64 100644 --- a/core/src/com/unciv/ui/victoryscreen/VictoryScreen.kt +++ b/core/src/com/unciv/ui/victoryscreen/VictoryScreen.kt @@ -3,7 +3,6 @@ package com.unciv.ui.victoryscreen import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton -import com.unciv.UncivGame import com.unciv.logic.civilization.CivilizationInfo import com.unciv.models.ruleset.VictoryType import com.unciv.models.translations.tr @@ -11,10 +10,11 @@ import com.unciv.ui.EmpireOverviewScreen import com.unciv.ui.newgamescreen.NewGameScreen import com.unciv.ui.pickerscreens.PickerScreen import com.unciv.ui.utils.* +import com.unciv.ui.worldscreen.WorldScreen -class VictoryScreen : PickerScreen() { +class VictoryScreen(val worldScreen: WorldScreen) : PickerScreen() { - private val playerCivInfo = UncivGame.Current.gameInfo.getPlayerToViewAs() + private val playerCivInfo = worldScreen.viewingCiv val victoryTypes = playerCivInfo.gameInfo.gameParameters.victoryTypes private val scientificVictoryEnabled = victoryTypes.contains(VictoryType.Scientific) private val culturalVictoryEnabled = victoryTypes.contains(VictoryType.Cultural) @@ -85,13 +85,13 @@ class VictoryScreen : PickerScreen() { rightSideButton.isVisible = true rightSideButton.enable() rightSideButton.onClick { - UncivGame.Current.setScreen(NewGameScreen()) + game.setScreen(NewGameScreen(this, worldScreen.gameInfo)) } closeButton.setText("One more turn...!".tr()) closeButton.onClick { playerCivInfo.gameInfo.oneMoreTurnMode = true - UncivGame.Current.setWorldScreen() + game.setWorldScreen() } } diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index 9bfc75e60c..4a3e335e90 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -281,8 +281,8 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { if (!hasOpenPopups() && isPlayersTurn) { when { - !gameInfo.oneMoreTurnMode && viewingCiv.isDefeated() -> game.setScreen(VictoryScreen()) - !gameInfo.oneMoreTurnMode && gameInfo.civilizations.any { it.victoryManager.hasWon() } -> game.setScreen(VictoryScreen()) + !gameInfo.oneMoreTurnMode && (viewingCiv.isDefeated() || gameInfo.civilizations.any { it.victoryManager.hasWon() }) -> + game.setScreen(VictoryScreen(this)) viewingCiv.greatPeople.freeGreatPeople > 0 -> game.setScreen(GreatPersonPickerScreen(viewingCiv)) viewingCiv.popupAlerts.any() -> AlertPopup(this, viewingCiv.popupAlerts.first()).open() viewingCiv.tradeRequests.isNotEmpty() -> TradePopup(this).open() diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreenTopBar.kt b/core/src/com/unciv/ui/worldscreen/WorldScreenTopBar.kt index e00db5ff9b..58fdf4c097 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreenTopBar.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreenTopBar.kt @@ -155,7 +155,7 @@ class WorldScreenTopBar(val worldScreen: WorldScreen) : Table() { val yearText = "["+ abs(year)+"] "+ if (year<0) "BC" else "AD" turnsLabel.setText("Turn".tr()+" " + civInfo.gameInfo.turns + " | "+ yearText.tr()) - turnsLabel.onClick { UncivGame.Current.setScreen(VictoryScreen()) } + turnsLabel.onClick { UncivGame.Current.setScreen(VictoryScreen(worldScreen)) } val nextTurnStats = civInfo.statsForNextTurn val goldPerTurn = "(" + (if (nextTurnStats.gold > 0) "+" else "") + nextTurnStats.gold.roundToInt() + ")" diff --git a/core/src/com/unciv/ui/worldscreen/mainmenu/WorldScreenMenuPopup.kt b/core/src/com/unciv/ui/worldscreen/mainmenu/WorldScreenMenuPopup.kt index 232831a9c1..d6d529cf88 100644 --- a/core/src/com/unciv/ui/worldscreen/mainmenu/WorldScreenMenuPopup.kt +++ b/core/src/com/unciv/ui/worldscreen/mainmenu/WorldScreenMenuPopup.kt @@ -1,10 +1,8 @@ package com.unciv.ui.worldscreen.mainmenu import com.badlogic.gdx.Gdx -import com.badlogic.gdx.graphics.Color import com.unciv.Constants import com.unciv.UncivGame -import com.unciv.logic.IdChecker import com.unciv.models.translations.tr import com.unciv.ui.CivilopediaScreen import com.unciv.ui.MultiplayerScreen @@ -13,11 +11,11 @@ import com.unciv.ui.mapeditor.NewMapScreen import com.unciv.ui.newgamescreen.NewGameScreen import com.unciv.ui.saves.LoadGameScreen import com.unciv.ui.saves.SaveGameScreen -import com.unciv.ui.utils.* +import com.unciv.ui.utils.Popup +import com.unciv.ui.utils.addSeparator +import com.unciv.ui.utils.onClick import com.unciv.ui.victoryscreen.VictoryScreen import com.unciv.ui.worldscreen.WorldScreen -import java.util.* -import kotlin.concurrent.thread class WorldScreenMenuPopup(val worldScreen: WorldScreen) : Popup(worldScreen) { @@ -31,36 +29,36 @@ class WorldScreenMenuPopup(val worldScreen: WorldScreen) : Popup(worldScreen) { addSeparator() addSquareButton("Civilopedia".tr()){ - UncivGame.Current.setScreen(CivilopediaScreen(worldScreen.gameInfo.ruleSet)) + worldScreen.game.setScreen(CivilopediaScreen(worldScreen.gameInfo.ruleSet)) close() }.size(width,height) addSeparator() addSquareButton("Load game".tr()){ - UncivGame.Current.setScreen(LoadGameScreen()) + worldScreen.game.setScreen(LoadGameScreen(worldScreen)) close() }.size(width,height) addSeparator() addSquareButton("Save game".tr()){ - UncivGame.Current.setScreen(SaveGameScreen()) + worldScreen.game.setScreen(SaveGameScreen()) close() }.size(width,height) addSeparator() - addSquareButton("Start new game".tr()){ - UncivGame.Current.setScreen(NewGameScreen()) + addSquareButton("Start new game".tr()){ + worldScreen.game.setScreen(NewGameScreen(worldScreen, worldScreen.gameInfo)) }.size(width,height) addSeparator() addSquareButton("Multiplayer".tr()){ - UncivGame.Current.setScreen(MultiplayerScreen()) + worldScreen.game.setScreen(MultiplayerScreen()) close() }.size(width,height) addSeparator() - addSquareButton("Victory status".tr()){ - UncivGame.Current.setScreen(VictoryScreen()) + addSquareButton("Victory status".tr()){ + worldScreen.game.setScreen(VictoryScreen(worldScreen)) close() }.size(width,height) addSeparator()