mirror of
https://github.com/yairm210/Unciv.git
synced 2025-07-12 00:39:56 +07:00
Victory screen and victory detection use VictoryData (#9175)
* VictoryScreen uses VictoryData * Victory detection no longer circumvents VictoryData
This commit is contained in:
@ -18,6 +18,7 @@ import com.unciv.logic.civilization.NotificationIcon
|
||||
import com.unciv.logic.civilization.PlayerType
|
||||
import com.unciv.logic.civilization.managers.TechManager
|
||||
import com.unciv.logic.civilization.managers.TurnManager
|
||||
import com.unciv.logic.civilization.managers.VictoryManager
|
||||
import com.unciv.logic.map.CityDistanceData
|
||||
import com.unciv.logic.map.TileMap
|
||||
import com.unciv.logic.map.tile.Tile
|
||||
@ -397,6 +398,16 @@ class GameInfo : IsPartOfGameInfoSerialization, HasGameInfoSerializationVersion
|
||||
diplomaticVictoryVotesProcessed = true
|
||||
}
|
||||
|
||||
/** @return `true` if someone has won - checks existing [victoryData] and each civ's [VictoryManager.getVictoryTypeAchieved] */
|
||||
fun checkForVictory(): Boolean {
|
||||
if (victoryData != null) return true
|
||||
for (civ in civilizations) {
|
||||
TurnManager(civ).updateWinningCiv()
|
||||
if (victoryData != null) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
private fun addEnemyUnitNotification(thisPlayer: Civilization, tiles: List<Tile>, inOrNear: String) {
|
||||
// don't flood the player with similar messages. instead cycle through units by clicking the message multiple times.
|
||||
if (tiles.size < 3) {
|
||||
|
@ -291,7 +291,7 @@ class TurnManager(val civInfo: Civilization) {
|
||||
updateWinningCiv() // Maybe we did something this turn to win
|
||||
}
|
||||
|
||||
private fun updateWinningCiv(){
|
||||
fun updateWinningCiv(){
|
||||
if (civInfo.gameInfo.victoryData != null) return // Game already won
|
||||
|
||||
val victoryType = civInfo.victoryManager.getVictoryTypeAchieved()
|
||||
|
@ -10,6 +10,7 @@ object MusicMood {
|
||||
const val Golden = "Golden"
|
||||
const val Wonder = "Wonder"
|
||||
const val Researched = "Researched"
|
||||
const val Victory = "Victory"
|
||||
|
||||
val themeOrPeace = listOf(Theme, Peace)
|
||||
fun peaceOrWar(isAtWar: Boolean) = if (isAtWar) War else Peace
|
||||
|
@ -7,10 +7,13 @@ import com.badlogic.gdx.scenes.scene2d.ui.VerticalGroup
|
||||
import com.badlogic.gdx.utils.Align
|
||||
import com.unciv.Constants
|
||||
import com.unciv.UncivGame
|
||||
import com.unciv.logic.VictoryData
|
||||
import com.unciv.logic.civilization.Civilization
|
||||
import com.unciv.models.metadata.GameSetupInfo
|
||||
import com.unciv.models.ruleset.Victory
|
||||
import com.unciv.models.translations.tr
|
||||
import com.unciv.ui.audio.MusicMood
|
||||
import com.unciv.ui.audio.MusicTrackChooserFlags
|
||||
import com.unciv.ui.components.KeyCharAndCode
|
||||
import com.unciv.ui.components.TabbedPager
|
||||
import com.unciv.ui.components.extensions.areSecretKeysPressed
|
||||
@ -23,14 +26,13 @@ import com.unciv.ui.screens.basescreen.RecreateOnResize
|
||||
import com.unciv.ui.screens.newgamescreen.NewGameScreen
|
||||
import com.unciv.ui.screens.pickerscreens.PickerScreen
|
||||
import com.unciv.ui.screens.worldscreen.WorldScreen
|
||||
|
||||
//TODO someoneHasWon should look at gameInfo.victoryData
|
||||
import java.util.EnumSet
|
||||
|
||||
class VictoryScreen(
|
||||
private val worldScreen: WorldScreen,
|
||||
pageNumber: Int = 0
|
||||
) : PickerScreen(), RecreateOnResize {
|
||||
|
||||
private val music get() = UncivGame.Current.musicController
|
||||
private val gameInfo = worldScreen.gameInfo
|
||||
private val playerCiv = worldScreen.viewingCiv
|
||||
private val tabs = TabbedPager(separatorColor = Color.WHITE, shortcutScreen = this)
|
||||
@ -96,28 +98,18 @@ class VictoryScreen(
|
||||
tabs.selectPage(pageNumber)
|
||||
|
||||
//**************** Set up bottom area - buttons and description label ****************
|
||||
when {
|
||||
gameInfo.victoryData != null ->
|
||||
displayWinner(gameInfo.victoryData!!)
|
||||
playerCiv.isDefeated() -> {
|
||||
displayWonOrLost(Victory().defeatString)
|
||||
music.chooseTrack(playerCiv.civName, MusicMood.Defeat, EnumSet.of(MusicTrackChooserFlags.SuffixMustMatch))
|
||||
}
|
||||
else -> {
|
||||
rightSideButton.isVisible = false
|
||||
|
||||
var someoneHasWon = false
|
||||
|
||||
val playerVictoryType = playerCiv.victoryManager.getVictoryTypeAchieved()
|
||||
if (playerVictoryType != null) {
|
||||
someoneHasWon = true
|
||||
wonOrLost("You have won a [$playerVictoryType] Victory!", playerVictoryType, true)
|
||||
}
|
||||
for (civ in gameInfo.civilizations.filter { it.isMajorCiv() && it != playerCiv }) {
|
||||
val civVictoryType = civ.victoryManager.getVictoryTypeAchieved()
|
||||
if (civVictoryType != null) {
|
||||
someoneHasWon = true
|
||||
wonOrLost("[${civ.civName}] has won a [$civVictoryType] Victory!", civVictoryType, false)
|
||||
}
|
||||
}
|
||||
|
||||
if (playerCiv.isDefeated()) {
|
||||
wonOrLost("", null, false)
|
||||
} else if (!someoneHasWon) {
|
||||
setDefaultCloseAction()
|
||||
}
|
||||
}
|
||||
|
||||
//**************** Set up floating info panels ****************
|
||||
// When horizontal screen space is scarce so they would overlap, insert
|
||||
@ -146,18 +138,24 @@ class VictoryScreen(
|
||||
}
|
||||
}
|
||||
|
||||
private fun wonOrLost(description: String, victoryType: String?, hasWon: Boolean) {
|
||||
val victory = playerCiv.gameInfo.ruleset.victories[victoryType]
|
||||
private fun displayWinner(victoryData: VictoryData) {
|
||||
// We could add `, victoryTurn` to the left side - undecided how to display
|
||||
val (winningCiv, victoryType) = victoryData
|
||||
val victory = gameInfo.ruleset.victories[victoryType]
|
||||
?: Victory() // This contains our default victory/defeat texts
|
||||
val endGameMessage = when {
|
||||
hasWon -> victory.victoryString
|
||||
else -> victory.defeatString
|
||||
if (winningCiv == playerCiv.civName) {
|
||||
displayWonOrLost("You have won a [$victoryType] Victory!", victory.victoryString)
|
||||
music.chooseTrack(playerCiv.civName, listOf(MusicMood.Victory, MusicMood.Theme), EnumSet.of(MusicTrackChooserFlags.SuffixMustMatch))
|
||||
} else {
|
||||
displayWonOrLost("[$winningCiv] has won a [$victoryType] Victory!", victory.defeatString)
|
||||
music.chooseTrack(playerCiv.civName, MusicMood.Defeat, EnumSet.of(MusicTrackChooserFlags.SuffixMustMatch))
|
||||
}
|
||||
}
|
||||
|
||||
descriptionLabel.setText(description.tr() + "\n" + endGameMessage.tr())
|
||||
private fun displayWonOrLost(vararg descriptions: String) {
|
||||
descriptionLabel.setText(descriptions.joinToString("\n") { it.tr() })
|
||||
|
||||
rightSideButton.setText("Start new game".tr())
|
||||
rightSideButton.isVisible = true
|
||||
rightSideButton.enable()
|
||||
rightSideButton.onClick {
|
||||
val newGameSetupInfo = GameSetupInfo(gameInfo)
|
||||
|
@ -377,7 +377,7 @@ class WorldScreen(
|
||||
when {
|
||||
viewingCiv.shouldShowDiplomaticVotingResults() ->
|
||||
UncivGame.Current.pushScreen(DiplomaticVoteResultScreen(gameInfo.diplomaticVictoryVotesCast, viewingCiv))
|
||||
!gameInfo.oneMoreTurnMode && (viewingCiv.isDefeated() || gameInfo.civilizations.any { it.victoryManager.hasWon() }) ->
|
||||
!gameInfo.oneMoreTurnMode && (viewingCiv.isDefeated() || gameInfo.checkForVictory()) ->
|
||||
game.pushScreen(VictoryScreen(this))
|
||||
viewingCiv.greatPeople.freeGreatPeople > 0 ->
|
||||
game.pushScreen(GreatPersonPickerScreen(viewingCiv))
|
||||
|
@ -95,7 +95,7 @@ Triggers indicate context (call it intent, mood, whatever, it doesn't matter) by
|
||||
The current list of triggers is as follows:
|
||||
|
||||
| Description | Prefix | [^M] | Suffix | [^X] | Flags |
|
||||
| ----------- |:------ |:----:| ------:|:----:|:-----:|
|
||||
|----------------------------------------------------|:------------------|:----:|-----------------:|:-----:|:-----:|
|
||||
| Automatic next-track[^0] | | | Ambient | | |
|
||||
| Launch game[^1] | | | Menu | | |
|
||||
| Every 10th turn | (player civ name) | [^M] | Peace or War[^2] | | [^F] |
|
||||
@ -105,12 +105,13 @@ The current list of triggers is as follows:
|
||||
| First contact[^4] | (civ name) | [^M] | Theme or Peace | [^X] | |
|
||||
| War declaration[^5] | (civ name) | [^M] | War | [^X] | |
|
||||
| Civ defeated | (civ name) | | Defeat | [^X] | |
|
||||
| Player wins | (civ name) | | Victory | [^X] | |
|
||||
| Golden Age | (civ name) | [^M] | Golden | [^X] | |
|
||||
| Wonder built | (wonder name) | [^M] | Wonder | [^X] | |
|
||||
| Tech researched | (tech name) | [^M] | Researched | [^X] | |
|
||||
| Map editor: Select nation start location | (nation name) | [^M] | Theme | | [^S] |
|
||||
| Options: Volume slider or Default track downloaded | | | | | [^D] |
|
||||
| Options: Click currently playing label[^6] | | [^M] | Ambient | | [^S] |
|
||||
| Music controls (Options or from Menu) Next track | | | Ambient | | |
|
||||
|
||||
Legend:
|
||||
|
||||
@ -126,4 +127,3 @@ Legend:
|
||||
- [^3]: According to your relation to the picked player.
|
||||
- [^4]: Excluding City States.
|
||||
- [^5]: Both in the alert when another player declares War on you and declaring War yourself in Diplomacy screen.
|
||||
- [^6]: Yes these flags are not optimal.
|
||||
|
Reference in New Issue
Block a user