From a0f6596ee8d445919811b67fd546f25d36c45a00 Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Sun, 3 Oct 2021 10:56:27 +0200 Subject: [PATCH] MusicController tweaks and hooks for mood - War and Peace (#5364) * MusicController tweaks and hooks for mood - War and Peace * MusicController tweaks and hooks for mood - patch1 * MusicController tweaks and hooks for mood - const object * MusicController tweaks and hooks for mood - patch2 Co-authored-by: Yair Morgenstern --- core/src/com/unciv/UncivGame.kt | 3 +- core/src/com/unciv/logic/GameInfo.kt | 8 ++- .../src/com/unciv/ui/audio/MusicController.kt | 61 ++++++++++++++----- core/src/com/unciv/ui/audio/MusicMood.kt | 12 ++++ .../unciv/ui/audio/MusicTrackChooserFlags.kt | 15 +++++ .../unciv/ui/audio/MusicTrackController.kt | 16 +++-- .../ui/newgamescreen/GameOptionsTable.kt | 10 ++- .../ui/newgamescreen/PlayerPickerTable.kt | 5 ++ .../src/com/unciv/ui/trade/DiplomacyScreen.kt | 9 ++- .../com/unciv/ui/worldscreen/AlertPopup.kt | 10 ++- .../com/unciv/ui/worldscreen/TradePopup.kt | 28 ++++++--- .../ui/worldscreen/mainmenu/OptionsPopup.kt | 6 +- 12 files changed, 144 insertions(+), 39 deletions(-) create mode 100644 core/src/com/unciv/ui/audio/MusicMood.kt diff --git a/core/src/com/unciv/UncivGame.kt b/core/src/com/unciv/UncivGame.kt index b94a873d45..509af0ef52 100644 --- a/core/src/com/unciv/UncivGame.kt +++ b/core/src/com/unciv/UncivGame.kt @@ -15,6 +15,7 @@ import com.unciv.models.tilesets.TileSetCache import com.unciv.models.translations.Translations import com.unciv.ui.LanguagePickerScreen import com.unciv.ui.audio.MusicController +import com.unciv.ui.audio.MusicMood import com.unciv.ui.utils.* import com.unciv.ui.worldscreen.PlayerReadyScreen import com.unciv.ui.worldscreen.WorldScreen @@ -111,7 +112,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() { // This stuff needs to run on the main thread because it needs the GL context Gdx.app.postRunnable { - musicController.chooseTrack() + musicController.chooseTrack(suffix = MusicMood.Menu) ImageGetter.ruleset = RulesetCache.getBaseRuleset() // so that we can enter the map editor without having to load a game first diff --git a/core/src/com/unciv/logic/GameInfo.kt b/core/src/com/unciv/logic/GameInfo.kt index 4c9913cb36..5a961fce34 100644 --- a/core/src/com/unciv/logic/GameInfo.kt +++ b/core/src/com/unciv/logic/GameInfo.kt @@ -16,6 +16,8 @@ import com.unciv.models.ruleset.Difficulty import com.unciv.models.ruleset.ModOptionsConstants import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.RulesetCache +import com.unciv.ui.audio.MusicMood +import com.unciv.ui.audio.MusicTrackChooserFlags import com.unciv.models.ruleset.unit.BaseUnit import java.util.* import kotlin.math.min @@ -199,8 +201,12 @@ class GameInfo { currentPlayerCiv = getCivilization(currentPlayer) if (currentPlayerCiv.isSpectator()) currentPlayerCiv.popupAlerts.clear() // no popups for spectators + if (turns % 10 == 0) //todo measuring actual play time might be nicer + UncivGame.Current.musicController.chooseTrack(currentPlayerCiv.civName, + MusicMood.peaceOrWar(currentPlayerCiv.isAtWar()), MusicTrackChooserFlags.setNextTurn) - // Start our turn immediately before the player can made decisions - affects whether our units can commit automated actions and then be attacked immediately etc. + // Start our turn immediately before the player can make decisions - affects + // whether our units can commit automated actions and then be attacked immediately etc. notifyOfCloseEnemyUnits(thisPlayer) } diff --git a/core/src/com/unciv/ui/audio/MusicController.kt b/core/src/com/unciv/ui/audio/MusicController.kt index 999298b56a..3e2b2ab450 100644 --- a/core/src/com/unciv/ui/audio/MusicController.kt +++ b/core/src/com/unciv/ui/audio/MusicController.kt @@ -29,7 +29,7 @@ class MusicController { private const val musicHistorySize = 8 // number of names to keep to avoid playing the same in short succession private val fileExtensions = listOf("mp3", "ogg") // flac, opus, m4a... blocked by Gdx, `wav` we don't want - internal const val consoleLog = false + internal const val consoleLog = true private fun getFile(path: String) = if (musicLocation == FileType.External && Gdx.files.isExternalStorageAvailable) @@ -98,9 +98,10 @@ class MusicController { fireOnChange() } private fun fireOnChange() { + if (onTrackChangeListener == null) return val fileName = currentlyPlaying() if (fileName.isEmpty()) { - onTrackChangeListener?.invoke(fileName) + fireOnChange(fileName) return } val fileNameParts = fileName.split('/') @@ -108,7 +109,16 @@ class MusicController { var trackName = fileNameParts[if (fileNameParts.size > 3 && fileNameParts[2] == "music") 3 else 1] for (extension in fileExtensions) trackName = trackName.removeSuffix(".$extension") - onTrackChangeListener?.invoke(modName + (if (modName.isEmpty()) "" else ": ") + trackName) + fireOnChange(modName + (if (modName.isEmpty()) "" else ": ") + trackName) + } + private fun fireOnChange(trackLabel: String) { + try { + onTrackChangeListener?.invoke(trackLabel) + } catch (ex: Throwable) { + if (consoleLog) + println("onTrackChange event invoke failed: ${ex.message}") + onTrackChangeListener = null + } } /** @@ -143,10 +153,13 @@ class MusicController { // Next track - if top slot empty and a next exists, move it to top and start current = next next = null - if (!current!!.play()) - state = ControllerState.Shutdown - else + if (!current!!.play()) { + // Retry another track if playback start fails, after an extended pause + ticksOfSilence = -silenceLengthInTicks - 1000 + state = ControllerState.Silence + } else { fireOnChange() + } } // else wait for the thread of next.load() to finish } else if (!current!!.isPlaying()) { // normal end of track @@ -201,14 +214,17 @@ class MusicController { (!flags.contains(MusicTrackChooserFlags.PrefixMustMatch) || it.nameWithoutExtension().startsWith(prefix)) && (!flags.contains(MusicTrackChooserFlags.SuffixMustMatch) || it.nameWithoutExtension().endsWith(suffix)) } - // sort them by prefix match / suffix match / not last played / random + // randomize + .shuffled() + // sort them by prefix match / suffix match / not last played .sortedWith(compareBy( { if (it.nameWithoutExtension().startsWith(prefix)) 0 else 1 } , { if (it.nameWithoutExtension().endsWith(suffix)) 0 else 1 } , { if (it.path() in musicHistory) 1 else 0 } - , { Random().nextInt() })) // Then just pick the first one. Not as wasteful as it looks - need to check all names anyway - .firstOrNull() + )).firstOrNull() + // Note: shuffled().sortedWith(), ***not*** .sortedWith(.., Random) + // the latter worked with older JVM's, current ones *crash* you when a compare is not transitive. } //endregion @@ -216,9 +232,10 @@ class MusicController { /** This tells the music controller about active mods - all are allowed to provide tracks */ fun setModList ( newMods: HashSet ) { - //todo: Ensure this gets updated where appropriate. - // loadGame; newGame: Choose Map with Mods?; map editor... - // check against "ImageGetter.ruleset=" ? + // This is hooked in most places where ImageGetter.setNewRuleset is called. + // Changes in permanent audiovisual mods are effective without this notification. + // Only the map editor isn't hooked, so if we wish to play mod-nation-specific tunes in the + // editor when e.g. a starting location is picked, that will have to be added. mods = newMods } @@ -227,14 +244,15 @@ class MusicController { * Called without parameters it will choose a new ambient music track and start playing it with fade-in/out. * Will do nothing when no music files exist or the master volume is zero. * - * @param prefix file name prefix, meant to represent **Context** - in most cases a Civ name or default "Ambient" - * @param suffix file name suffix, meant to represent **Mood** - e.g. Peace, War, Theme... + * @param prefix file name prefix, meant to represent **Context** - in most cases a Civ name + * @param suffix file name suffix, meant to represent **Mood** - e.g. Peace, War, Theme, Defeat, Ambient + * (Ambient is the default when a track ends and exists so War Peace and the others are not chosen in that case) * @param flags a set of optional flags to tune the choice and playback. * @return `true` = success, `false` = no match, no playback change */ fun chooseTrack ( prefix: String = "", - suffix: String = "", + suffix: String = "Ambient", flags: EnumSet = EnumSet.noneOf(MusicTrackChooserFlags::class.java) ): Boolean { if (baseVolume == 0f) return false @@ -289,6 +307,17 @@ class MusicController { return true } + /** Variant of [chooseTrack] that tries several moods ([suffixes]) until a match is chosen */ + fun chooseTrack ( + prefix: String = "", + suffixes: List, + flags: EnumSet = EnumSet.noneOf(MusicTrackChooserFlags::class.java) + ): Boolean { + for (suffix in suffixes) { + if (chooseTrack(prefix, suffix, flags)) return true + } + return false + } /** * Pause playback with fade-out @@ -346,7 +375,7 @@ class MusicController { private fun shutdown() { state = ControllerState.Idle fireOnChange() - onTrackChangeListener = null + // keep onTrackChangeListener! OptionsPopup will want to know when we start up again if (musicTimer != null) { musicTimer!!.cancel() musicTimer = null diff --git a/core/src/com/unciv/ui/audio/MusicMood.kt b/core/src/com/unciv/ui/audio/MusicMood.kt new file mode 100644 index 0000000000..db834f79ff --- /dev/null +++ b/core/src/com/unciv/ui/audio/MusicMood.kt @@ -0,0 +1,12 @@ +package com.unciv.ui.audio + +object MusicMood { + const val Theme = "Theme" + const val Peace = "Peace" + const val War = "War" + const val Defeat = "Defeat" + const val Menu = "Menu" + + val themeOrPeace = listOf(Theme, Peace) + fun peaceOrWar(isAtWar: Boolean) = if (isAtWar) War else Peace +} diff --git a/core/src/com/unciv/ui/audio/MusicTrackChooserFlags.kt b/core/src/com/unciv/ui/audio/MusicTrackChooserFlags.kt index 0cffd89a17..3a7f46db37 100644 --- a/core/src/com/unciv/ui/audio/MusicTrackChooserFlags.kt +++ b/core/src/com/unciv/ui/audio/MusicTrackChooserFlags.kt @@ -1,5 +1,7 @@ package com.unciv.ui.audio +import java.util.* + enum class MusicTrackChooserFlags { /** Makes prefix parameter a mandatory match */ PrefixMustMatch, @@ -11,4 +13,17 @@ enum class MusicTrackChooserFlags { PlaySingle, /** directly choose the 'fallback' file for playback */ PlayDefaultFile, + ; + + companion object { + // EnumSet factories + /** EnumSet.of([PlayDefaultFile], [PlaySingle]) */ + val setPlayDefault: EnumSet = EnumSet.of(PlayDefaultFile, PlaySingle) + /** EnumSet.of([PrefixMustMatch], [PlaySingle]) */ + val setSelectNation: EnumSet = EnumSet.of(PrefixMustMatch) + /** EnumSet.of([PrefixMustMatch], [SuffixMustMatch]) */ + val setSpecific: EnumSet = EnumSet.of(PrefixMustMatch, SuffixMustMatch) + /** EnumSet.of([PrefixMustMatch], [SlowFade]) */ + val setNextTurn: EnumSet = EnumSet.of(PrefixMustMatch, SlowFade) + } } diff --git a/core/src/com/unciv/ui/audio/MusicTrackController.kt b/core/src/com/unciv/ui/audio/MusicTrackController.kt index 61dda35bc1..dfec5674d7 100644 --- a/core/src/com/unciv/ui/audio/MusicTrackController.kt +++ b/core/src/com/unciv/ui/audio/MusicTrackController.kt @@ -148,16 +148,24 @@ class MusicTrackController(private var volume: Float) { if (!state.canPlay || music == null) { throw IllegalStateException("MusicTrackController.play called on uninitialized instance") } + // Unexplained observed exception: Gdx.Music.play fails with + // "Unable to allocate audio buffers. AL Error: 40964" (AL_INVALID_OPERATION) + // Approach: This track dies, parent controller will enter state Silence thus retry after a while. + if (tryPlay(music!!)) return true + state = State.Error + return false + } + + private fun tryPlay(music: Music): Boolean { return try { - music!!.volume = volume - if (!music!!.isPlaying) // for fade-over this could be called by the end of the previous track - music!!.play() + music.volume = volume + if (!music.isPlaying) // for fade-over this could be called by the end of the previous track + music.play() true } catch (ex: Exception) { println("Exception playing music: ${ex.message}") if (MusicController.consoleLog) ex.printStackTrace() - state = State.Error false } } diff --git a/core/src/com/unciv/ui/newgamescreen/GameOptionsTable.kt b/core/src/com/unciv/ui/newgamescreen/GameOptionsTable.kt index 746eebf690..90cbb1f7bf 100644 --- a/core/src/com/unciv/ui/newgamescreen/GameOptionsTable.kt +++ b/core/src/com/unciv/ui/newgamescreen/GameOptionsTable.kt @@ -6,6 +6,8 @@ import com.unciv.models.metadata.BaseRuleset import com.unciv.models.metadata.GameSpeed import com.unciv.models.ruleset.RulesetCache import com.unciv.models.ruleset.VictoryType +import com.unciv.ui.audio.MusicMood +import com.unciv.ui.audio.MusicTrackChooserFlags import com.unciv.ui.utils.* class GameOptionsTable( @@ -187,9 +189,11 @@ class GameOptionsTable( var desiredCiv = "" if (gameParameters.mods.contains(it)) { val modNations = RulesetCache[it]?.nations - if (modNations != null && modNations.size > 0) { - desiredCiv = modNations.keys.first() - } + if (modNations != null && modNations.size > 0) desiredCiv = modNations.keys.first() + + val music = UncivGame.Current.musicController + if (!music.chooseTrack(it, MusicMood.Theme, MusicTrackChooserFlags.setSelectNation) && desiredCiv.isNotEmpty()) + music.chooseTrack(desiredCiv, MusicMood.themeOrPeace, MusicTrackChooserFlags.setSelectNation) } updatePlayerPickerTable(desiredCiv) diff --git a/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt b/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt index 6210241697..24c6b496ac 100644 --- a/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt +++ b/core/src/com/unciv/ui/newgamescreen/PlayerPickerTable.kt @@ -18,6 +18,8 @@ import com.unciv.models.metadata.Player import com.unciv.models.ruleset.Nation import com.unciv.models.ruleset.Ruleset import com.unciv.models.translations.tr +import com.unciv.ui.audio.MusicMood +import com.unciv.ui.audio.MusicTrackChooserFlags import com.unciv.ui.mapeditor.GameParametersScreen import com.unciv.ui.pickerscreens.PickerScreen import com.unciv.ui.utils.* @@ -347,6 +349,9 @@ private class NationPickerPopup( private fun returnSelected() { if (selectedNation == null) return + + UncivGame.Current.musicController.chooseTrack(selectedNation!!.name, MusicMood.themeOrPeace, MusicTrackChooserFlags.setSelectNation) + if (previousScreen is GameParametersScreen) previousScreen.mapEditorScreen.tileMap.switchPlayersNation( player, diff --git a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt index f681025f8e..8b4a78a55f 100644 --- a/core/src/com/unciv/ui/trade/DiplomacyScreen.kt +++ b/core/src/com/unciv/ui/trade/DiplomacyScreen.kt @@ -21,15 +21,18 @@ import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.stats.Stat import com.unciv.models.translations.fillPlaceholders import com.unciv.models.translations.tr +import com.unciv.ui.audio.MusicMood +import com.unciv.ui.audio.MusicTrackChooserFlags import com.unciv.ui.civilopedia.CivilopediaScreen import com.unciv.ui.tilegroups.CityButton import com.unciv.ui.utils.* import com.unciv.ui.utils.UncivTooltip.Companion.addTooltip +import kotlin.collections.ArrayList import kotlin.math.floor import kotlin.math.roundToInt import com.unciv.ui.utils.AutoScrollPane as ScrollPane -class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() { +class DiplomacyScreen(val viewingCiv:CivilizationInfo): CameraStageBaseScreen() { private val leftSideTable = Table().apply { defaults().pad(10f) } private val rightSideTable = Table() @@ -694,6 +697,9 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() { if (promisesTable != null) diplomacyTable.add(promisesTable).row() } + UncivGame.Current.musicController.chooseTrack(otherCiv.civName, + MusicMood.peaceOrWar(viewingCiv.isAtWarWith(otherCiv)), MusicTrackChooserFlags.setSelectNation) + return diplomacyTable } @@ -831,6 +837,7 @@ class DiplomacyScreen(val viewingCiv:CivilizationInfo):CameraStageBaseScreen() { diplomacyManager.declareWar() setRightSideFlavorText(otherCiv, otherCiv.nation.attacked, "Very well.") updateLeftSideTable() + UncivGame.Current.musicController.chooseTrack(otherCiv.civName, MusicMood.War, MusicTrackChooserFlags.setSpecific) }, this).open() } return declareWarButton diff --git a/core/src/com/unciv/ui/worldscreen/AlertPopup.kt b/core/src/com/unciv/ui/worldscreen/AlertPopup.kt index 1252f02baf..958cfb7add 100644 --- a/core/src/com/unciv/ui/worldscreen/AlertPopup.kt +++ b/core/src/com/unciv/ui/worldscreen/AlertPopup.kt @@ -4,12 +4,16 @@ import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.unciv.Constants +import com.unciv.UncivGame import com.unciv.logic.civilization.* import com.unciv.logic.civilization.diplomacy.RelationshipLevel import com.unciv.models.translations.fillPlaceholders import com.unciv.models.translations.tr +import com.unciv.ui.audio.MusicMood +import com.unciv.ui.audio.MusicTrackChooserFlags import com.unciv.ui.trade.LeaderIntroTable import com.unciv.ui.utils.* +import java.util.* /** * [Popup] communicating events other than trade offers to the player. @@ -47,6 +51,7 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu } init { + val music = UncivGame.Current.musicController when (popupAlert.type) { AlertType.WarDeclaration -> { @@ -58,12 +63,14 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu responseTable.add(getCloseButton("You'll pay for this!")) responseTable.add(getCloseButton("Very well.")) add(responseTable) + music.chooseTrack(civInfo.civName, MusicMood.War, MusicTrackChooserFlags.setSpecific) } AlertType.Defeated -> { val civInfo = worldScreen.gameInfo.getCivilization(popupAlert.value) addLeaderName(civInfo) addGoodSizedLabel(civInfo.nation.defeated).row() add(getCloseButton("Farewell.")) + music.chooseTrack(civInfo.civName, MusicMood.Defeat, EnumSet.of(MusicTrackChooserFlags.SuffixMustMatch)) } AlertType.FirstContact -> { val civInfo = worldScreen.gameInfo.getCivilization(popupAlert.value) @@ -75,6 +82,7 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu } else { addGoodSizedLabel(nation.introduction).row() add(getCloseButton("A pleasure to meet you.")) + music.chooseTrack(civInfo.civName, MusicMood.themeOrPeace, MusicTrackChooserFlags.setSpecific) } } AlertType.CityConquered -> { @@ -90,7 +98,7 @@ class AlertPopup(val worldScreen: WorldScreen, val popupAlert: PopupAlert): Popu city.liberateCity(conqueringCiv) worldScreen.shouldUpdate = true close() - } + } addLiberateOption(city.foundingCiv, liberateAction) addSeparator() } diff --git a/core/src/com/unciv/ui/worldscreen/TradePopup.kt b/core/src/com/unciv/ui/worldscreen/TradePopup.kt index b0a0f858e5..3ff74c53b6 100644 --- a/core/src/com/unciv/ui/worldscreen/TradePopup.kt +++ b/core/src/com/unciv/ui/worldscreen/TradePopup.kt @@ -3,6 +3,7 @@ package com.unciv.ui.worldscreen import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.ui.Table import com.unciv.Constants +import com.unciv.UncivGame import com.unciv.logic.civilization.NotificationIcon import com.unciv.logic.civilization.diplomacy.DiplomacyFlags import com.unciv.logic.trade.TradeEvaluation @@ -10,6 +11,8 @@ import com.unciv.logic.trade.TradeLogic import com.unciv.logic.trade.TradeOffer import com.unciv.logic.trade.TradeType import com.unciv.models.translations.tr +import com.unciv.ui.audio.MusicMood +import com.unciv.ui.audio.MusicTrackChooserFlags import com.unciv.ui.trade.DiplomacyScreen import com.unciv.ui.trade.LeaderIntroTable import com.unciv.ui.utils.* @@ -34,22 +37,27 @@ class TradePopup(worldScreen: WorldScreen): Popup(worldScreen){ val viewingCiv = worldScreen.viewingCiv val tradeRequest = viewingCiv.tradeRequests.first() - init{ + init { val requestingCiv = worldScreen.gameInfo.getCivilization(tradeRequest.requestingCiv) val nation = requestingCiv.nation + val trade = tradeRequest.trade + val isPeaceTreaty = trade.ourOffers.any { it.type == TradeType.Treaty && it.name == Constants.peaceTreaty } + val ourResources = viewingCiv.getCivResourcesByName() + val music = UncivGame.Current.musicController + + if (isPeaceTreaty) + music.chooseTrack(nation.name, MusicMood.Peace, MusicTrackChooserFlags.setSpecific) val leaderIntroTable = LeaderIntroTable(requestingCiv) add(leaderIntroTable) addSeparator() - val trade = tradeRequest.trade val tradeOffersTable = Table().apply { defaults().pad(10f) } tradeOffersTable.add("[${nation.name}]'s trade offer".toLabel()) // empty column to separate offers columns better tradeOffersTable.add().pad(0f, 15f) tradeOffersTable.add("Our trade offer".toLabel()) tradeOffersTable.row() - val ourResources = viewingCiv.getCivResourcesByName() fun getOfferText(offer:TradeOffer): String { var tradeText = offer.getOfferText() @@ -90,12 +98,14 @@ class TradePopup(worldScreen: WorldScreen): Popup(worldScreen){ addButton("Not this time.", 'n') { val diplomacyManager = requestingCiv.getDiplomacyManager(viewingCiv) - if(trade.ourOffers.all { it.type == TradeType.Luxury_Resource } && trade.theirOffers.all { it.type==TradeType.Luxury_Resource }) + if (trade.ourOffers.all { it.type == TradeType.Luxury_Resource } && trade.theirOffers.all { it.type==TradeType.Luxury_Resource }) diplomacyManager.setFlag(DiplomacyFlags.DeclinedLuxExchange,20) // offer again in 20 turns - if(trade.ourOffers.any { it.name == Constants.researchAgreement }) + if (trade.ourOffers.any { it.name == Constants.researchAgreement }) diplomacyManager.setFlag(DiplomacyFlags.DeclinedResearchAgreement,20) // offer again in 20 turns - if(trade.ourOffers.any { it.type == TradeType.Treaty && it.name == Constants.peaceTreaty }) - diplomacyManager.setFlag(DiplomacyFlags.DeclinedPeace,5) + if (isPeaceTreaty) { + diplomacyManager.setFlag(DiplomacyFlags.DeclinedPeace, 5) + music.chooseTrack(nation.name, MusicMood.War, MusicTrackChooserFlags.setSpecific) + } close() requestingCiv.addNotification("[${viewingCiv.civName}] has denied your trade request", viewingCiv.civName, NotificationIcon.Trade) @@ -119,14 +129,14 @@ class TradePopup(worldScreen: WorldScreen): Popup(worldScreen){ viewingCiv.tradeRequests.remove(tradeRequest) super.close() } - + class TradeThanksPopup(leaderIntroTable: LeaderIntroTable, worldScreen: WorldScreen): Popup(worldScreen) { init { add(leaderIntroTable) addSeparator().padBottom(15f) addGoodSizedLabel("Excellent!").row() addCloseButton("Farewell.", KeyCharAndCode.SPACE) { - worldScreen.shouldUpdate=true + 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 } diff --git a/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt b/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt index 740f7e8ef1..0865973829 100644 --- a/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt +++ b/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt @@ -13,7 +13,6 @@ import com.unciv.UncivGame import com.unciv.logic.MapSaver import com.unciv.logic.civilization.PlayerType import com.unciv.models.UncivSound -import com.unciv.models.metadata.BaseRuleset import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.RulesetCache import com.unciv.models.tilesets.TileSetCache @@ -420,7 +419,7 @@ class OptionsPopup(val previousScreen: CameraStageBaseScreen) : Popup(previousSc val music = previousScreen.game.musicController music.setVolume(it) if (!music.isPlaying()) - music.chooseTrack(flags = EnumSet.of(MusicTrackChooserFlags.PlayDefaultFile, MusicTrackChooserFlags.PlaySingle)) + music.chooseTrack(flags = MusicTrackChooserFlags.setPlayDefault) } add(musicVolumeSlider).pad(5f).row() } @@ -467,6 +466,7 @@ class OptionsPopup(val previousScreen: CameraStageBaseScreen) : Popup(previousSc label.setText("Currently playing: [$it]".tr()) } } + label.onClick { previousScreen.game.musicController.chooseTrack(flags = MusicTrackChooserFlags.setNextTurn) } } private fun Table.addDownloadMusic() { @@ -486,7 +486,7 @@ class OptionsPopup(val previousScreen: CameraStageBaseScreen) : Popup(previousSc previousScreen.game.musicController.downloadDefaultFile() Gdx.app.postRunnable { tabs.replacePage("Sound", getSoundTab()) - previousScreen.game.musicController.chooseTrack(flags = EnumSet.of(MusicTrackChooserFlags.PlayDefaultFile, MusicTrackChooserFlags.PlaySingle)) + previousScreen.game.musicController.chooseTrack(flags = MusicTrackChooserFlags.setPlayDefault) } } catch (ex: Exception) { Gdx.app.postRunnable {