CityScreen plays a sound when opened (#7163)

* added sounds to cityScreen

* changes? ..don't know how to name this commit

* removed try block

* improved era1 sound and added slider for city enter sounds

* added Information Era sound

* added Future Era sound

* better option name + translation

* added Atomic Era sound

* normalized sounds

* prevent spam + better era 0 and 1 sounds

* cleanup

* sound improvements to medieval and atomic

* volume now tied to sound effects

* improved information sound

* improved future sound

* sounds now stop if you exit the city screen

* improved Renaissance sound

* now in separate function

* now using the music controller

* better file names

* WLTK day sound + sounds are now configurable in Eras.json

* removed redundant setting and fixed comment

* added PlaySingle

* musicController no longer used

* Gdx.audio.newMusic is now used

* function name

* function are now in their own class

* CitySoundPlayer now has 1 instance in UncivGame and is hooked

* credits

* sounds loop

* loopable sounds

* updated credits

* fixed sound not stopping when changing city without leaving cityScreen

* changed WLTKNew sound

* added toggle for the sounds

* changed WLTK sound, removed music and made all tracks have the same volume

* addressed some of the issues

* addressed more issues

* increased sounds volume + volume slider

* made WLTK sound slightly quieter

* removed entry from Vanilla eras

* revert back to CitySoundPlayer.kt

* no more hooks

* removed unused stuff

* changees

* completly reverted MusicController

* and the MusicTrackChooserFlags

* fixed ESC not stopping sounds

* updated credits to mention the sounds are modified

* dispose()

* removed try block
This commit is contained in:
alexban011
2022-06-22 09:11:03 +03:00
committed by GitHub
parent 7de3fdf452
commit 8f53262fc4
21 changed files with 171 additions and 57 deletions

View File

@ -112,11 +112,13 @@ class UncivGame(parameters: UncivGameParameters) : Game() {
settings = gameSaver.getGeneralSettings() // needed for the screen
setScreen(GameStartScreen()) // NOT dependent on any atlas or skin
GameSounds.init()
musicController = MusicController() // early, but at this point does only copy volume from settings
audioExceptionHelper?.installHooks(
musicController.getAudioLoopCallback(),
musicController.getAudioExceptionHandler()
)
onlineMultiplayer = OnlineMultiplayer()
ImageGetter.resetAtlases()

View File

@ -32,6 +32,7 @@ class GameSettings {
var hasCrashedRecently = false
var soundEffectsVolume = 0.5f
var citySoundsVolume = 0.5f
var musicVolume = 0.5f
var pauseBetweenTracks = 10

View File

@ -29,6 +29,7 @@ class Era : RulesetObject(), IHasUniques {
var baseUnitBuyCost = 200
var embarkDefense = 3
var startPercent = 0
var citySound = "cityClassical"
var friendBonus = HashMap<String, List<String>>()
var allyBonus = HashMap<String, List<String>>()

View File

@ -0,0 +1,57 @@
package com.unciv.ui.audio
import com.badlogic.gdx.Files
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.audio.Music
import com.badlogic.gdx.files.FileHandle
import com.unciv.UncivGame
import com.unciv.logic.city.CityInfo
import com.unciv.utils.Log
class CityAmbiencePlayer {
private val soundsLocation = Files.FileType.Local
private var playingCitySound: Music? = null
val fileExtensions = listOf("mp3", "ogg", "wav") // All Gdx formats
private fun getFile(path: String) =
if (soundsLocation == Files.FileType.External && Gdx.files.isExternalStorageAvailable)
Gdx.files.external(path)
else Gdx.files.local(path)
private fun getSoundFolders() = sequence {
val visualMods = UncivGame.Current.settings.visualMods
val mods = UncivGame.Current.gameInfo!!.gameParameters.getModsAndBaseRuleset()
yieldAll(
(visualMods + mods).asSequence()
.map { getFile("mods")
.child(it).child("sounds") }
)
yield(getFile("sounds"))
}
private fun getSoundFile(fileName: String): FileHandle? = getSoundFolders()
.filter { it.exists() && it.isDirectory }
.flatMap { it.list().asSequence() }
// ensure only normal files with common sound extension
.filter { it.exists() && !it.isDirectory && it.extension() in fileExtensions }
.firstOrNull { it.name().contains(fileName) }
fun play(city: CityInfo) {
if (playingCitySound != null)
stop()
try {
val file = FileHandle(getSoundFile(city.civInfo.getEra().citySound).toString())
playingCitySound = Gdx.audio.newMusic(file)
playingCitySound?.volume = UncivGame.Current.settings.citySoundsVolume
playingCitySound?.isLooping = true
playingCitySound?.play()
} catch (ex: Throwable) {
playingCitySound?.dispose()
Log.error("Error while playing city sound: ", ex)
}
}
fun stop() {
playingCitySound?.dispose()
}
}

View File

@ -9,12 +9,14 @@ import com.unciv.UncivGame
import com.unciv.logic.automation.Automation
import com.unciv.logic.city.CityInfo
import com.unciv.logic.city.IConstruction
import com.unciv.logic.city.INonPerpetualConstruction
import com.unciv.logic.map.TileInfo
import com.unciv.models.UncivSound
import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.tile.TileImprovement
import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stat
import com.unciv.ui.audio.CityAmbiencePlayer
import com.unciv.ui.audio.SoundPlayer
import com.unciv.ui.images.ImageGetter
import com.unciv.ui.map.TileGroupMap
import com.unciv.ui.popup.ToastPopup
@ -23,11 +25,13 @@ import com.unciv.ui.utils.BaseScreen
import com.unciv.ui.utils.KeyCharAndCode
import com.unciv.ui.utils.RecreateOnResize
import com.unciv.ui.utils.ZoomableScrollPane
import com.unciv.ui.utils.extensions.center
import com.unciv.ui.utils.extensions.disable
import com.unciv.ui.utils.extensions.keyShortcuts
import com.unciv.ui.utils.extensions.onActivation
import com.unciv.ui.utils.extensions.onClick
import com.unciv.ui.utils.extensions.packIfNeeded
import com.unciv.ui.utils.extensions.toTextButton
import kotlin.collections.ArrayList
import com.unciv.ui.worldscreen.WorldScreen
class CityScreen(
@ -78,7 +82,11 @@ class CityScreen(
/** Button for exiting the city - sits on BOTTOM CENTER */
private val exitCityButton = "Exit city".toTextButton().apply {
labelCell.pad(10f)
onClick { exit() }
keyShortcuts.add(KeyCharAndCode.BACK)
onActivation {
exit()
cityAmbiencePlayer.stop()
}
}
/** Holds City tiles group*/
@ -108,8 +116,15 @@ class CityScreen(
// val should be OK as buying tiles is what changes this, and that would re-create the whole CityScreen
private val nextTileToOwn = city.expansion.chooseNewTileToOwn()
private val cityAmbiencePlayer = CityAmbiencePlayer()
init {
globalShortcuts.add(KeyCharAndCode.BACK) { game.popScreen() }
if (city.isWeLoveTheKingDayActive() && UncivGame.Current.settings.citySoundsVolume > 0) {
SoundPlayer.play(UncivSound("WLTK"))
}
if (UncivGame.Current.settings.citySoundsVolume > 0)
cityAmbiencePlayer.play(city)
UncivGame.Current.settings.addCompletedTutorialTask("Enter city screen")
addTiles()

View File

@ -33,9 +33,7 @@ fun displayTab(
optionsPopup.addCheckbox(this, "Show unit movement arrows", settings.showUnitMovements, true) { settings.showUnitMovements = it }
optionsPopup.addCheckbox(this, "Show tile yields", settings.showTileYields, true) { settings.showTileYields = it } // JN
optionsPopup.addCheckbox(this, "Show worked tiles", settings.showWorkedTiles, true) { settings.showWorkedTiles = it }
optionsPopup.addCheckbox(this, "Show resources and improvements", settings.showResourcesAndImprovements, true) {
settings.showResourcesAndImprovements = it
}
optionsPopup.addCheckbox(this, "Show resources and improvements", settings.showResourcesAndImprovements, true) { settings.showResourcesAndImprovements = it }
optionsPopup.addCheckbox(this, "Show tutorials", settings.showTutorials, true) { settings.showTutorials = it }
optionsPopup.addCheckbox(this, "Show pixel units", settings.showPixelUnits, true) { settings.showPixelUnits = it }
optionsPopup.addCheckbox(this, "Show pixel improvements", settings.showPixelImprovements, true) { settings.showPixelImprovements = it }

View File

@ -29,6 +29,7 @@ fun soundTab(
val music = UncivGame.Current.musicController
addSoundEffectsVolumeSlider(this, settings)
addCitySoundsVolumeSlider(this, settings)
if (UncivGame.Current.musicController.isMusicAvailable()) {
addMusicVolumeSlider(this, settings, music)
@ -84,6 +85,20 @@ private fun addSoundEffectsVolumeSlider(table: Table, settings: GameSettings) {
table.add(soundEffectsVolumeSlider).pad(5f).row()
}
private fun addCitySoundsVolumeSlider(table: Table, settings: GameSettings) {
table.add("City ambient sound volume".tr()).left().fillX()
val citySoundVolumeSlider = UncivSlider(
0f, 1.0f, 0.05f,
initial = settings.citySoundsVolume,
getTipText = UncivSlider::formatPercent
) {
settings.citySoundsVolume = it
settings.save()
}
table.add(citySoundVolumeSlider).pad(5f).row()
}
private fun addMusicVolumeSlider(table: Table, settings: GameSettings, music: MusicController) {
table.add("Music volume".tr()).left().fillX()