diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index de19446842..1689cd3829 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -2,7 +2,6 @@ package com.unciv.logic import com.badlogic.gdx.graphics.Color import com.unciv.Constants -import com.unciv.models.metadata.GameParameters import com.unciv.logic.automation.NextTurnAutomation import com.unciv.logic.city.CityConstructions import com.unciv.logic.civilization.CivilizationInfo @@ -12,11 +11,15 @@ import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileMap import com.unciv.models.gamebasics.Difficulty import com.unciv.models.gamebasics.GameBasics +import com.unciv.models.metadata.GameParameters import java.util.* class GameInfo { @Transient lateinit var difficultyObject: Difficulty // Since this is static game-wide, and was taking a large part of nextTurn @Transient lateinit var currentPlayerCiv:CivilizationInfo // this is called thousands of times, no reason to search for it with a find{} every time + /** This is used in multiplayer games, where I may have a saved game state on my phone + * that is inconsistent with the saved game on the cloud */ + @Transient var isUpToDate=false var civilizations = mutableListOf() var difficulty="Chieftain" // difficulty is game-wide, think what would happen if 2 human players could play on different difficulties? diff --git a/core/src/com/unciv/logic/GameStarter.kt b/core/src/com/unciv/logic/GameStarter.kt index 3531b29117..e86a5787f3 100644 --- a/core/src/com/unciv/logic/GameStarter.kt +++ b/core/src/com/unciv/logic/GameStarter.kt @@ -6,8 +6,8 @@ import com.unciv.logic.civilization.CivilizationInfo import com.unciv.logic.map.BFS import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileMap -import com.unciv.models.metadata.GameParameters import com.unciv.models.gamebasics.GameBasics +import com.unciv.models.metadata.GameParameters import java.util.* import kotlin.collections.ArrayList @@ -18,6 +18,7 @@ class GameStarter{ gameInfo.gameParameters = newGameParameters gameInfo.tileMap = TileMap(newGameParameters) gameInfo.tileMap.gameInfo = gameInfo // need to set this transient before placing units in the map + gameInfo.difficulty = newGameParameters.difficulty val availableCivNames = Stack() @@ -34,8 +35,8 @@ class GameStarter{ else availableCivNames.pop() val playerCiv = CivilizationInfo(nationName) - gameInfo.difficulty = newGameParameters.difficulty playerCiv.playerType = player.playerType + playerCiv.playerId = player.playerId gameInfo.civilizations.add(playerCiv) } diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index 685ef3bbdb..25a59e2c73 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -42,9 +42,10 @@ class CivilizationInfo { @Transient var statsForNextTurn = Stats() @Transient var detailedCivResources = ResourceSupplyList() + var playerType = PlayerType.AI + /** Used in online multiplayer for human players */ var playerId = "" var gold = 0 @Deprecated("As of 2.11.1") var difficulty = "Chieftain" - var playerType = PlayerType.AI var civName = "" var tech = TechManager() var policies = PolicyManager() diff --git a/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt b/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt index bb63f64d5b..41a79061d7 100644 --- a/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt +++ b/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt @@ -96,9 +96,9 @@ class MapEditorOptionsTable(mapEditorScreen: MapEditorScreen): PopupTable(mapEdi exitMapEditorButton.onClick { UnCivGame.Current.setWorldScreen(); mapEditorScreen.dispose() } add(exitMapEditorButton ).row() - val closeOptionsButtton = TextButton("Close".tr(), skin) - closeOptionsButtton.onClick { remove() } - add(closeOptionsButtton).row() + val closeOptionsButton = TextButton("Close".tr(), skin) + closeOptionsButton.onClick { close() } + add(closeOptionsButton).row() open() } @@ -125,7 +125,7 @@ class MapDownloadTable(mapEditorScreen: MapEditorScreen):PopupTable(mapEditorScr } catch (ex: Exception) { addGoodSizedLabel("Could not get list of maps!").row() } - addButton("Close") { remove() } + addButton("Close") { close() } open() } } \ 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 9a2c09382a..ad06154efc 100644 --- a/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt +++ b/core/src/com/unciv/ui/newgamescreen/NewGameScreen.kt @@ -15,6 +15,7 @@ import com.unciv.ui.utils.enable import com.unciv.ui.utils.onClick import com.unciv.ui.worldscreen.WorldScreen import com.unciv.ui.worldscreen.optionstable.PopupTable +import java.util.* import kotlin.concurrent.thread class NewGameScreen: PickerScreen(){ @@ -34,13 +35,28 @@ class NewGameScreen: PickerScreen(){ rightSideButton.setText("Start game!".tr()) rightSideButton.onClick { if (newGameParameters.players.none { it.playerType == PlayerType.Human }) { - val popup = PopupTable(this) - popup.addGoodSizedLabel("No human players selected!").row() - popup.addButton("Close") { popup.remove() } - popup.open() + val noHumanPlayersPopup = PopupTable(this) + noHumanPlayersPopup.addGoodSizedLabel("No human players selected!").row() + noHumanPlayersPopup.addButton("Close") { noHumanPlayersPopup.close() } + noHumanPlayersPopup.open() return@onClick } + if (newGameParameters.isOnlineMultiplayer){ + for(player in newGameParameters.players.filter{ it.playerType == PlayerType.Human}) { + try { + UUID.fromString(player.playerId) + } + catch (ex:Exception) { + val invalidPlayerIdPopup = PopupTable(this) + invalidPlayerIdPopup.addGoodSizedLabel("Invalid player ID!").row() + invalidPlayerIdPopup.addButton("Close") { invalidPlayerIdPopup.remove() } + invalidPlayerIdPopup.open() + return@onClick + } + } + } + Gdx.input.inputProcessor = null // remove input processing - nothing will be clicked! rightSideButton.disable() rightSideButton.setText("Working...".tr()) @@ -50,10 +66,10 @@ class NewGameScreen: PickerScreen(){ try { newGame = GameStarter().startNewGame(newGameParameters) } catch (exception: Exception) { - val popup = PopupTable(this) - popup.addGoodSizedLabel("It looks like we can't make a map with the parameters you requested!".tr()).row() - popup.addGoodSizedLabel("Maybe you put too many players into too small a map?".tr()).row() - popup.open() + val cantMakeThatMapPopup = PopupTable(this) + cantMakeThatMapPopup.addGoodSizedLabel("It looks like we can't make a map with the parameters you requested!".tr()).row() + cantMakeThatMapPopup.addGoodSizedLabel("Maybe you put too many players into too small a map?".tr()).row() + cantMakeThatMapPopup.open() } } } diff --git a/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt b/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt index a6b055a92c..43a0f7b35a 100644 --- a/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt +++ b/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt @@ -86,8 +86,6 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters: playerIdTable.add(setCurrentUserButton) playerTable.add(playerIdTable).colspan(playerTable.columns) - - } return playerTable @@ -111,7 +109,7 @@ class PlayerPickerTable(val newGameScreen: NewGameScreen, val newGameParameters: nationListTable.add(NationTable(nation, halfWidth) { player.chosenCiv = nation.name - nationsPopup.remove() + nationsPopup.close() update() }).pad(10f).width(halfWidth).row() } diff --git a/core/src/com/unciv/ui/worldscreen/AlertPopup.kt b/core/src/com/unciv/ui/worldscreen/AlertPopup.kt index af37eca665..da7498126d 100644 --- a/core/src/com/unciv/ui/worldscreen/AlertPopup.kt +++ b/core/src/com/unciv/ui/worldscreen/AlertPopup.kt @@ -101,9 +101,9 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu worldScreen.alertPopupIsOpen = true } - fun close(){ + override fun close(){ worldScreen.viewingCiv.popupAlerts.remove(popupAlert) worldScreen.alertPopupIsOpen = false - remove() + super.close() } } \ No newline at end of file diff --git a/core/src/com/unciv/ui/worldscreen/TradePopup.kt b/core/src/com/unciv/ui/worldscreen/TradePopup.kt index 4e78eafc4d..fea7959378 100644 --- a/core/src/com/unciv/ui/worldscreen/TradePopup.kt +++ b/core/src/com/unciv/ui/worldscreen/TradePopup.kt @@ -43,13 +43,13 @@ class TradePopup(worldScreen: WorldScreen): PopupTable(worldScreen){ tradeLogic.currentTrade.set(trade) tradeLogic.acceptTrade() currentPlayerCiv.tradeRequests.remove(tradeRequest) - remove() + close() PopupTable(worldScreen).apply { add(otherCivLeaderName.toLabel()).colspan(2) addSeparator() addGoodSizedLabel("Excellent!").row() addButton("Farewell."){ - this.remove() + close() worldScreen.shouldUpdate=true // in all cases, worldScreen.shouldUpdate should be set to true when we remove the last of the popups // in order for the next trade to appear immediately @@ -68,14 +68,14 @@ class TradePopup(worldScreen: WorldScreen): PopupTable(worldScreen){ if(trade.ourOffers.any{ it.type==TradeType.Treaty && it.name== Constants.peaceTreaty }) diplomacyManager.setFlag(DiplomacyFlags.DeclinedPeace,5) - remove() + close() requestingCiv.addNotification("[${currentPlayerCiv.civName}] has denied your trade request", Color.GOLD) worldScreen.shouldUpdate=true } addButton("How about something else...".tr()){ currentPlayerCiv.tradeRequests.remove(tradeRequest) - remove() + close() val diplomacyScreen= DiplomacyScreen() val tradeTable = diplomacyScreen.setTrade(requestingCiv) diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index 8758eed9c9..a5b8dbe0d8 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -26,6 +26,7 @@ import com.unciv.ui.trade.DiplomacyScreen import com.unciv.ui.utils.* import com.unciv.ui.worldscreen.bottombar.BattleTable import com.unciv.ui.worldscreen.bottombar.WorldScreenBottomBar +import com.unciv.ui.worldscreen.optionstable.PopupTable import com.unciv.ui.worldscreen.unit.UnitActionsTable import kotlin.concurrent.thread @@ -99,6 +100,20 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { tileMapHolder.setCenterPosition(tileToCenterOn,true) update() + + if(gameInfo.gameParameters.isOnlineMultiplayer && !gameInfo.isUpToDate){ + val loadingGamePopup = PopupTable(this) + loadingGamePopup.add("Loading latest game state...") + loadingGamePopup.open() + thread { + try{ + // todo!!! + } + catch (ex:Exception){ + loadingGamePopup.close() + } + } + } } // This is private so that we will set the shouldUpdate to true instead. diff --git a/core/src/com/unciv/ui/worldscreen/optionstable/PopupTable.kt b/core/src/com/unciv/ui/worldscreen/optionstable/PopupTable.kt index fb9422e5a1..dc7acc6406 100644 --- a/core/src/com/unciv/ui/worldscreen/optionstable/PopupTable.kt +++ b/core/src/com/unciv/ui/worldscreen/optionstable/PopupTable.kt @@ -6,7 +6,6 @@ import com.badlogic.gdx.scenes.scene2d.ui.Label import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.utils.Align -import com.unciv.UnCivGame import com.unciv.models.gamebasics.tr import com.unciv.ui.utils.* @@ -25,6 +24,8 @@ open class PopupTable(val screen: CameraStageBaseScreen): Table(CameraStageBaseS screen.stage.addActor(this) } + open fun close(){ remove() } + fun addGoodSizedLabel(text: String): Cell