diff --git a/android/assets/sounds/thatched-villagers.mp3 b/android/assets/sounds/thatched-villagers.mp3 new file mode 100644 index 0000000000..4107c94f9a Binary files /dev/null and b/android/assets/sounds/thatched-villagers.mp3 differ diff --git a/core/src/com/unciv/UnCivGame.kt b/core/src/com/unciv/UnCivGame.kt index 08109ee1de..a9ba8be322 100644 --- a/core/src/com/unciv/UnCivGame.kt +++ b/core/src/com/unciv/UnCivGame.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.Application import com.badlogic.gdx.Game import com.badlogic.gdx.Gdx import com.badlogic.gdx.Input +import com.badlogic.gdx.audio.Music import com.unciv.logic.GameInfo import com.unciv.logic.GameSaver import com.unciv.logic.GameStarter @@ -30,8 +31,13 @@ class UnCivGame(val version: String) : Game() { lateinit var worldScreen: WorldScreen + var music : Music? =null + val musicLocation = "music/thatched-villagers.mp3" + override fun create() { Current = this + + if(Gdx.app.type!= Application.ApplicationType.Desktop) viewEntireMapForDebug=false Gdx.input.setCatchKey(Input.Keys.BACK, true) @@ -49,6 +55,19 @@ class UnCivGame(val version: String) : Game() { } } else setScreen(LanguagePickerScreen()) + + startMusic() + } + + fun startMusic(){ + + val musicFile = Gdx.files.local(musicLocation) + if(musicFile.exists()){ + music = Gdx.audio.newMusic(musicFile) + music!!.isLooping=true + music!!.volume = 0.4f + music!!.play() + } } fun setScreen(screen: CameraStageBaseScreen) { diff --git a/core/src/com/unciv/models/metadata/GameSettings.kt b/core/src/com/unciv/models/metadata/GameSettings.kt index 2c9bf6c971..28464862d0 100644 --- a/core/src/com/unciv/models/metadata/GameSettings.kt +++ b/core/src/com/unciv/models/metadata/GameSettings.kt @@ -12,6 +12,7 @@ class GameSettings { var tutorialsShown = ArrayList() var hasCrashedRecently = false var soundEffectsVolume = 0.5f + var musicVolume = 0.5f var turnsBetweenAutosaves = 1 var tileSet:String = "FantasyHex" var showTutorials: Boolean = true diff --git a/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt b/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt index dac078eadf..2995065f77 100644 --- a/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt +++ b/core/src/com/unciv/ui/mapeditor/MapEditorOptionsTable.kt @@ -113,7 +113,7 @@ class MapDownloadTable(mapEditorScreen: MapEditorScreen):PopupTable(mapEditorScr for (downloadableMap in folderList.entries) { val downloadMapButton = TextButton(downloadableMap.name, CameraStageBaseScreen.skin) downloadMapButton.onClick { - val mapJsonGzipped = DropBox().downloadFile(downloadableMap.path_display) + val mapJsonGzipped = DropBox().downloadFileAsString(downloadableMap.path_display) if(mapJsonGzipped==""){ val couldNotDownloadMapPopup = PopupTable(screen) couldNotDownloadMapPopup.addGoodSizedLabel("Could not download map!").row() diff --git a/core/src/com/unciv/ui/worldscreen/optionstable/DropBox.kt b/core/src/com/unciv/ui/worldscreen/optionstable/DropBox.kt index aa8a3006eb..71430e63fd 100644 --- a/core/src/com/unciv/ui/worldscreen/optionstable/DropBox.kt +++ b/core/src/com/unciv/ui/worldscreen/optionstable/DropBox.kt @@ -5,6 +5,7 @@ import com.unciv.logic.GameSaver import com.unciv.ui.saves.Gzip import java.io.BufferedReader import java.io.DataOutputStream +import java.io.InputStream import java.io.InputStreamReader import java.net.HttpURLConnection import java.net.URL @@ -12,7 +13,7 @@ import java.nio.charset.StandardCharsets class DropBox(){ - fun dropboxApi(url:String, data:String="",contentType:String="",dropboxApiArg:String=""):String { + fun dropboxApi(url:String, data:String="",contentType:String="",dropboxApiArg:String=""): InputStream? { with(URL(url).openConnection() as HttpURLConnection) { requestMethod = "POST" // default is GET @@ -32,16 +33,12 @@ class DropBox(){ outputStream.flush() } - val reader = BufferedReader(InputStreamReader(inputStream)) - val output = reader.readText() - - println(output) - return output + return inputStream } catch (ex: Exception) { println(ex.message) val reader = BufferedReader(InputStreamReader(errorStream)) println(reader.readText()) - return "" + return null } } } @@ -52,20 +49,26 @@ class DropBox(){ return GameSaver().json().fromJson(FolderList::class.java,response) } - fun downloadFile(fileName:String):String{ + fun downloadFile(fileName:String): InputStream { val response = dropboxApi("https://content.dropboxapi.com/2/files/download", contentType = "text/plain",dropboxApiArg = "{\"path\":\"$fileName\"}") - return response + return response!! + } + + fun downloadFileAsString(fileName:String): String { + val inputStream = downloadFile(fileName) + val text = BufferedReader(InputStreamReader(inputStream)).readText() + return text } fun uploadFile(fileName: String, data: String, overwrite:Boolean=false){ val overwriteModeString = if(!overwrite) "" else ""","mode":{".tag":"overwrite"}""" - val response = dropboxApi("https://content.dropboxapi.com/2/files/upload", + dropboxApi("https://content.dropboxapi.com/2/files/upload", data,"application/octet-stream", """{"path":"$fileName"$overwriteModeString}""") } fun deleteFile(fileName:String){ - val response = dropboxApi("https://api.dropboxapi.com/2/files/delete_v2", + dropboxApi("https://api.dropboxapi.com/2/files/delete_v2", "{\"path\":\"$fileName\"}","application/json") } @@ -90,7 +93,7 @@ class OnlineMultiplayer(){ } fun tryDownloadGame(gameId: String): GameInfo { - val zippedGameInfo = DropBox().downloadFile(getGameLocation(gameId)) + val zippedGameInfo = DropBox().downloadFileAsString(getGameLocation(gameId)) return GameSaver().gameInfoFromString(Gzip.unzip(zippedGameInfo)) } } \ No newline at end of file diff --git a/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenOptionsTable.kt b/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenOptionsTable.kt index 09e885e0fb..8efb6d9351 100644 --- a/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenOptionsTable.kt +++ b/core/src/com/unciv/ui/worldscreen/optionstable/WorldScreenOptionsTable.kt @@ -1,10 +1,9 @@ package com.unciv.ui.worldscreen.optionstable +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.scenes.scene2d.Actor -import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane -import com.badlogic.gdx.scenes.scene2d.ui.SelectBox -import com.badlogic.gdx.scenes.scene2d.ui.Slider -import com.badlogic.gdx.scenes.scene2d.ui.TextField +import com.badlogic.gdx.scenes.scene2d.ui.* import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener import com.badlogic.gdx.utils.Array import com.unciv.UnCivGame @@ -113,6 +112,7 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr addTileSetSelectBox(innerTable) addSoundEffectsVolumeSlider(innerTable) + addMusicVolumeSlider(innerTable) innerTable.add("Version".toLabel()) innerTable.add(UnCivGame.Current.version.toLabel()).row() @@ -160,6 +160,43 @@ class WorldScreenOptionsTable(val worldScreen:WorldScreen) : PopupTable(worldScr innerTable.add(soundEffectsVolumeSlider).row() } + private fun addMusicVolumeSlider(innerTable: PopupTable) { + val musicLocation =Gdx.files.local(UnCivGame.Current.musicLocation) + if(musicLocation.exists()) { + innerTable.add("Music volume".tr()) + + val musicVolumeSlider = Slider(0f, 1.0f, 0.1f, false, skin) + musicVolumeSlider.value = UnCivGame.Current.settings.soundEffectsVolume + musicVolumeSlider.addListener(object : ChangeListener() { + override fun changed(event: ChangeEvent?, actor: Actor?) { + UnCivGame.Current.settings.musicVolume = musicVolumeSlider.value + UnCivGame.Current.settings.save() + UnCivGame.Current.music?.volume = 0.4f * musicVolumeSlider.value + } + }) + innerTable.add(musicVolumeSlider).row() + } + else{ + val downloadMusicButton = TextButton("Download music",CameraStageBaseScreen.skin) + innerTable.add(downloadMusicButton).colspan(2).row() + val errorTable = Table() + innerTable.add(errorTable).colspan(2).row() + + downloadMusicButton.onClick { + try{ + val file = DropBox().downloadFile("/Music/thatched-villagers.mp3") + musicLocation.write(file,false) + update() + UnCivGame.Current.startMusic() + } + catch (ex:Exception){ + errorTable.clear() + errorTable.add("Could not download music!".toLabel().setFontColor(Color.RED)) + } + } + } + } + private fun addResolutionSelectBox(innerTable: PopupTable) { innerTable.add("Resolution".toLabel()) diff --git a/docs/Credits.md b/docs/Credits.md index 652c9f4b27..7aa4906e54 100644 --- a/docs/Credits.md +++ b/docs/Credits.md @@ -520,3 +520,7 @@ Sounds are from FreeSound.org and are either Creative Commons or Public Domain * [uzzi_full_single](https://freesound.org/people/Deganoth/sounds/348685/) By Deganoth as 'shot' for bullet attacks +# Music +The following music is from https://filmmusic.io +"Thatched Villagers" by Kevin MacLeod (https://incompetech.com) +License: CC BY (http://creativecommons.org/licenses/by/4.0/)