Victory screen and victory detection use VictoryData (#9175)

* VictoryScreen uses VictoryData

* Victory detection no longer circumvents VictoryData
This commit is contained in:
SomeTroglodyte
2023-04-13 10:54:11 +02:00
committed by GitHub
parent 2e61023248
commit 0500f73770
6 changed files with 61 additions and 51 deletions

View File

@ -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) {

View File

@ -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()

View File

@ -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

View File

@ -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)

View File

@ -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))

View File

@ -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.