From aa1bd3cd7e0c2d48f3aa7fb90a7fa16b945df4a0 Mon Sep 17 00:00:00 2001 From: GGGuenni Date: Tue, 2 Feb 2021 15:43:51 +0100 Subject: [PATCH] Adding resign function for multiplayer (#3567) * Adding give up function for multiplayer * Update template.properties * Reviewed changes - Changed "give up" to "resign" - Removed unnecessary and harmful translations - Using YesNoPopup now * Add missing space * fixed first AI turn getting skipped --- .../jsons/translations/template.properties | 4 + core/src/com/unciv/logic/GameInfo.kt | 7 +- core/src/com/unciv/ui/MultiplayerScreen.kt | 76 ++++++++++++++++++- 3 files changed, 82 insertions(+), 5 deletions(-) diff --git a/android/assets/jsons/translations/template.properties b/android/assets/jsons/translations/template.properties index 1af7a61257..f8791c1b12 100644 --- a/android/assets/jsons/translations/template.properties +++ b/android/assets/jsons/translations/template.properties @@ -303,6 +303,10 @@ Add Currently Running Game = Game name = Loading latest game state... = Couldn't download the latest game state! = +Resign = +Are you sure you want to resign? = +You can only resign if it's your turn = +[civName] resigned and is now controlled by AI = # Save game menu diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index d2a3f427e7..bc6fb1e76f 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -103,7 +103,12 @@ class GameInfo { thisPlayer.startTurn() } - switchTurn() + //check is important or else switchTurn + //would skip a turn if an AI civ calls nextTurn + //this happens when resigning a multiplayer game + if (thisPlayer.isPlayerCivilization()){ + switchTurn() + } while (thisPlayer.playerType == PlayerType.AI || turns < UncivGame.Current.simulateUntilTurnForDebug diff --git a/core/src/com/unciv/ui/MultiplayerScreen.kt b/core/src/com/unciv/ui/MultiplayerScreen.kt index e9bcf6f956..fa7ccc7609 100644 --- a/core/src/com/unciv/ui/MultiplayerScreen.kt +++ b/core/src/com/unciv/ui/MultiplayerScreen.kt @@ -9,6 +9,7 @@ import com.unciv.logic.GameInfo import com.unciv.logic.GameSaver import com.unciv.logic.IdChecker import com.unciv.logic.UncivShowableException +import com.unciv.logic.civilization.PlayerType import com.unciv.models.translations.tr import com.unciv.ui.pickerscreens.PickerScreen import com.unciv.ui.utils.* @@ -379,9 +380,6 @@ class EditMultiplayerGameInfoScreen(game: GameInfo, gameName: String, backScreen topTable.add("Rename".toLabel()).row() topTable.add(textField).pad(10f).padBottom(30f).width(stage.width/2).row() - //TODO Change delete to "give up" - //->turn a player into an AI so everyone can still play without the user - //->should only be possible on the users turn because it has to be uploaded afterwards val deleteButton = "Delete save".toTextButton() deleteButton.onClick { val askPopup = Popup(this) @@ -402,7 +400,17 @@ class EditMultiplayerGameInfoScreen(game: GameInfo, gameName: String, backScreen askPopup.open() }.apply { color = Color.RED } - topTable.add(deleteButton) + val giveUpButton = "Resign".toTextButton() + giveUpButton.onClick { + val askPopup = YesNoPopup("Are you sure you want to resign?", { + giveUp(game.gameId, gameName, backScreen) + }, this) + askPopup.open() + } + giveUpButton.apply { color = Color.RED } + + topTable.add(deleteButton).pad(10f).row() + topTable.add(giveUpButton) //CloseButton Setup closeButton.setText("Back".tr()) @@ -431,6 +439,66 @@ class EditMultiplayerGameInfoScreen(game: GameInfo, gameName: String, backScreen } } } + + /** + * Helper function to decrease indentation + * Turns the current playerCiv into an AI civ and uploads the game afterwards. + */ + private fun giveUp(gameId: String, gameName: String, backScreen: MultiplayerScreen){ + //Create a popup + val popup = Popup(this) + popup.addGoodSizedLabel("Working...").row() + popup.open() + + thread { + try { + //download to work with newest game state + val gameInfo = OnlineMultiplayer().tryDownloadGame(gameId) + val playerCiv = gameInfo.currentPlayerCiv + + //only give up if it's the users turn + //this ensures that no one can upload a newer game state while we try to give up + if (playerCiv.playerId == game.settings.userId){ + //Set own civ info to AI + playerCiv.playerType = PlayerType.AI + playerCiv.playerId = "" + + //call next turn so turn gets simulated by AI + gameInfo.nextTurn() + + //Add notification so everyone knows what happened + //call for every civ cause AI players are skipped anyway + for (civ in gameInfo.civilizations){ + civ.addNotification("[${playerCiv.civName}] resigned and is now controlled by AI", Color.RED) + } + + //save game so multiplayer list stays up to date + GameSaver.saveGame(gameInfo, gameName, true) + OnlineMultiplayer().tryUploadGame(gameInfo) + Gdx.app.postRunnable { + popup.close() + //go back to the MultiplayerScreen + backScreen.game.setScreen(backScreen) + backScreen.reloadGameListUI() + } + } else { + Gdx.app.postRunnable { + //change popup text + popup.innerTable.clear() + popup.addGoodSizedLabel("You can only resign if it's your turn").row() + popup.addCloseButton() + } + } + } catch (ex: Exception) { + Gdx.app.postRunnable { + //change popup text + popup.innerTable.clear() + popup.addGoodSizedLabel("Could not upload game!").row() + popup.addCloseButton() + } + } + } + } } class AddMultiplayerGameScreen(backScreen: MultiplayerScreen) : PickerScreen(){