diff --git a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt index d275cc4af0..06ab647d57 100644 --- a/core/src/com/unciv/logic/civilization/CivilizationInfo.kt +++ b/core/src/com/unciv/logic/civilization/CivilizationInfo.kt @@ -24,6 +24,7 @@ import com.unciv.models.ruleset.tile.ResourceSupplyList import com.unciv.models.ruleset.unit.BaseUnit import com.unciv.models.stats.Stats import com.unciv.models.translations.tr +import com.unciv.ui.VictoryScreen import java.util.* import kotlin.collections.ArrayList import kotlin.collections.HashMap @@ -275,7 +276,10 @@ class CivilizationInfo { override fun toString(): String {return civName} // for debug - fun isDefeated()= cities.isEmpty() && (citiesCreated > 0 || !getCivUnits().any {it.name== Constants.settler}) + /** Returns true if the civ was fully initialized and has no cities or settlers remaining */ + fun isDefeated()= cities.isEmpty() + && exploredTiles.isNotEmpty() // Dirty hack: exploredTiles are empty only before starting units are placed + && (citiesCreated > 0 || !getCivUnits().any { it.name == Constants.settler }) fun getEra(): TechEra { val maxEraOfTech = tech.researchedTechnologies diff --git a/core/src/com/unciv/ui/VictoryScreen.kt b/core/src/com/unciv/ui/VictoryScreen.kt index cb710d6d69..045b43ebd9 100644 --- a/core/src/com/unciv/ui/VictoryScreen.kt +++ b/core/src/com/unciv/ui/VictoryScreen.kt @@ -67,7 +67,10 @@ class VictoryScreen : PickerScreen() { } } - if(!someoneHasWon) setDefaultCloseAction() + if (playerCivInfo.isDefeated()) { + wonOrLost("") + } else if(!someoneHasWon) + setDefaultCloseAction() } diff --git a/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt b/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt index ee5e77a83e..0bb77ed38f 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldMapHolder.kt @@ -4,7 +4,9 @@ import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.math.Interpolation import com.badlogic.gdx.math.Vector2 -import com.badlogic.gdx.scenes.scene2d.* +import com.badlogic.gdx.scenes.scene2d.Actor +import com.badlogic.gdx.scenes.scene2d.Group +import com.badlogic.gdx.scenes.scene2d.Touchable import com.badlogic.gdx.scenes.scene2d.actions.FloatAction import com.badlogic.gdx.scenes.scene2d.ui.Table import com.unciv.Constants @@ -18,9 +20,9 @@ import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileMap import com.unciv.models.UncivSound import com.unciv.models.ruleset.unit.UnitType +import com.unciv.ui.map.TileGroupMap import com.unciv.ui.tilegroups.TileSetStrings import com.unciv.ui.tilegroups.WorldTileGroup -import com.unciv.ui.map.TileGroupMap import com.unciv.ui.utils.* import com.unciv.ui.worldscreen.unit.UnitContextMenu import kotlin.concurrent.thread @@ -186,8 +188,21 @@ class WorldMapHolder(internal val worldScreen: WorldScreen, internal val tileMap } + /** Returns true when the civ is a human player defeated in singleplayer game */ + private fun isMapRevealEnabled(viewingCiv: CivilizationInfo) = !viewingCiv.gameInfo.gameParameters.isOnlineMultiplayer + && viewingCiv.isCurrentPlayer() + && viewingCiv.isDefeated() + internal fun updateTiles(viewingCiv: CivilizationInfo) { + if (isMapRevealEnabled(viewingCiv)) { + viewingCiv.viewableTiles = tileMap.values.toSet() + + // Only needs to be done once + if (viewingCiv.exploredTiles.size != tileMap.values.size) + viewingCiv.exploredTiles = tileMap.values.map { it.position }.toHashSet() + } + val playerViewableTilePositions = viewingCiv.viewableTiles.map { it.position }.toHashSet() for (tileGroup in tileGroups.values){ diff --git a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt index 40ab8bbab6..ce2ba5c20b 100644 --- a/core/src/com/unciv/ui/worldscreen/WorldScreen.kt +++ b/core/src/com/unciv/ui/worldscreen/WorldScreen.kt @@ -177,7 +177,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { tutorialTaskTable.clear() val tutorialTask = getCurrentTutorialTask() - if (tutorialTask == "" || !game.settings.showTutorials) { + if (tutorialTask == "" || !game.settings.showTutorials || viewingCiv.isDefeated()) { tutorialTaskTable.isVisible = false } else { tutorialTaskTable.isVisible = true @@ -206,6 +206,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { if (!hasVisibleDialogs() && isPlayersTurn) { when { + !gameInfo.oneMoreTurnMode && viewingCiv.isDefeated() -> game.setScreen(VictoryScreen()) !gameInfo.oneMoreTurnMode && gameInfo.civilizations.any { it.victoryManager.hasWon() } -> game.setScreen(VictoryScreen()) viewingCiv.policies.freePolicies > 0 && viewingCiv.policies.canAdoptPolicy() -> game.setScreen(PolicyPickerScreen(this)) viewingCiv.greatPeople.freeGreatPeople > 0 -> game.setScreen(GreatPersonPickerScreen(viewingCiv)) @@ -289,7 +290,7 @@ class WorldScreen(val viewingCiv:CivilizationInfo) : CameraStageBaseScreen() { private fun updateDiplomacyButton(civInfo: CivilizationInfo) { diplomacyButtonWrapper.clear() - if(civInfo.getKnownCivs() + if(!civInfo.isDefeated() && civInfo.getKnownCivs() .filterNot { it.isDefeated() || it==viewingCiv || it.isBarbarian() } .any()) { displayTutorial(Tutorial.OtherCivEncountered)