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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 171 additions and 57 deletions

View File

@ -1,7 +1,7 @@
[ [
// Source: the fandom, so take these with a grain of salt // Source: the fandom, so take these with a grain of salt
// I also did some testing in the official version, but by far not all // I also did some testing in the official version, but by far not all
{ {
"name": "Ancient era", "name": "Ancient era",
"researchAgreementCost": 150, "researchAgreementCost": 150,
@ -13,6 +13,7 @@
"baseUnitBuyCost": 200, "baseUnitBuyCost": 200,
"embarkDefense": 3, "embarkDefense": 3,
"startPercent": 0, "startPercent": 0,
"citySound": "cityAncient",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+3 Culture] per turn"], "Cultured": ["Provides [+3 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -42,6 +43,7 @@
"baseUnitBuyCost": 200, "baseUnitBuyCost": 200,
"embarkDefense": 4, "embarkDefense": 4,
"startPercent": 10, "startPercent": 10,
"citySound": "cityClassical",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+3 Culture] per turn"], "Cultured": ["Provides [+3 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -73,6 +75,7 @@
"baseUnitBuyCost": 200, "baseUnitBuyCost": 200,
"embarkDefense": 6, "embarkDefense": 6,
"startPercent": 25, "startPercent": 25,
"citySound": "cityMedieval",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+6 Culture] per turn"], "Cultured": ["Provides [+6 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -100,11 +103,12 @@
"startingCulture": 300, "startingCulture": 300,
"settlerPopulation": 2, "settlerPopulation": 2,
"settlerBuildings": ["Shrine","Monument","Granary","Lighthouse"], "settlerBuildings": ["Shrine","Monument","Granary","Lighthouse"],
"startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus", "startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus",
"The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus"], "The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus"],
"baseUnitBuyCost": 300, "baseUnitBuyCost": 300,
"embarkDefense": 8, "embarkDefense": 8,
"startPercent": 37, "startPercent": 37,
"citySound": "cityRenaissance",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+6 Culture] per turn"], "Cultured": ["Provides [+6 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -138,6 +142,7 @@
"baseUnitBuyCost": 400, "baseUnitBuyCost": 400,
"embarkDefense": 10, "embarkDefense": 10,
"startPercent": 50, "startPercent": 50,
"citySound": "cityIndustrial",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -171,11 +176,12 @@
"settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Amphitheater","Barracks","Library","Colosseum"], "settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Amphitheater","Barracks","Library","Colosseum"],
"startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus", "startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus",
"The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus", "The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus",
"Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Alhambra", "Notre Dame", "Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Alhambra", "Notre Dame",
"Sistine Chapel", "Forbidden Palace", "Leaning Tower of Pisa", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin"], "Sistine Chapel", "Forbidden Palace", "Leaning Tower of Pisa", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin"],
"baseUnitBuyCost": 600, "baseUnitBuyCost": 600,
"embarkDefense": 13, "embarkDefense": 13,
"startPercent": 65, "startPercent": 65,
"citySound": "cityModern",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -209,12 +215,13 @@
"settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Amphitheater","Barracks","Library","Colosseum"], "settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Amphitheater","Barracks","Library","Colosseum"],
"startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus", "startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus",
"The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus", "The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus",
"Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Alhambra", "Notre Dame", "Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Alhambra", "Notre Dame",
"Sistine Chapel", "Forbidden Palace", "Leaning Tower of Pisa", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin", "Sistine Chapel", "Forbidden Palace", "Leaning Tower of Pisa", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin",
"The Louvre", "Big Ben", "Brandenburg Gate"], "The Louvre", "Big Ben", "Brandenburg Gate"],
"baseUnitBuyCost": 800, "baseUnitBuyCost": 800,
"embarkDefense": 16, "embarkDefense": 16,
"startPercent": 65, "startPercent": 65,
"citySound": "cityAtomic",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -248,16 +255,17 @@
"settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Amphitheater","Barracks","Library","Colosseum","Theatre","Bank"], "settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Amphitheater","Barracks","Library","Colosseum","Theatre","Bank"],
"startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus", "startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus",
"The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus", "The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus",
"Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Alhambra", "Notre Dame", "Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Alhambra", "Notre Dame",
"Sistine Chapel", "Forbidden Palace", "Leaning Tower of Pisa", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin", "Sistine Chapel", "Forbidden Palace", "Leaning Tower of Pisa", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin",
"The Louvre", "Big Ben", "Brandenburg Gate", "The Louvre", "Big Ben", "Brandenburg Gate",
"Eiffel Tower", "Statue of Liberty", "Neuschwanstein", "Cristo Redentor"], "Eiffel Tower", "Statue of Liberty", "Neuschwanstein", "Cristo Redentor"],
"baseUnitBuyCost": 1000, "baseUnitBuyCost": 1000,
"embarkDefense": 20, "embarkDefense": 20,
"startPercent": 80, "startPercent": 80,
// So theoretically this is always just all the wonders at least 2 eras old. So we could just use that. // So theoretically this is always just all the wonders at least 2 eras old. So we could just use that.
// But where is the modularity? The excluding of very specific wonders? That is no fun. // But where is the modularity? The excluding of very specific wonders? That is no fun.
// So we just write down the entire long list (sorted by era!) instead. // So we just write down the entire long list (sorted by era!) instead.
"citySound": "cityInformation",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -279,8 +287,8 @@
"Starting in this era disables religion" "Starting in this era disables religion"
] ]
}, },
{ // Technically, this Era doesn't exist in the original game. { // Technically, this Era doesn't exist in the original game.
// But as it is _really_ usefull to have for testing, I'd like to keep it. // But as it is _really_ usefull to have for testing, I'd like to keep it.
// The stats are just copy-pasted from the information era. // The stats are just copy-pasted from the information era.
"name": "Future era", "name": "Future era",
"researchAgreementCost": 400, "researchAgreementCost": 400,
@ -294,13 +302,14 @@
"settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Amphitheater","Barracks","Library","Colosseum","Theatre","Bank"], "settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Amphitheater","Barracks","Library","Colosseum","Theatre","Bank"],
"startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus", "startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus",
"The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus", "The Great Lighthouse", "Hanging Gardens", "Terracotta Army", "The Oracle", "Petra", "Great Wall", "Colossus",
"Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Alhambra", "Notre Dame", "Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Alhambra", "Notre Dame",
"Sistine Chapel", "Forbidden Palace", "Leaning Tower of Pisa", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin", "Sistine Chapel", "Forbidden Palace", "Leaning Tower of Pisa", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin",
"The Louvre", "Big Ben", "Brandenburg Gate", "The Louvre", "Big Ben", "Brandenburg Gate",
"Eiffel Tower", "Statue of Liberty", "Neuschwanstein", "Cristo Redentor"], "Eiffel Tower", "Statue of Liberty", "Neuschwanstein", "Cristo Redentor"],
"baseUnitBuyCost": 1000, "baseUnitBuyCost": 1000,
"embarkDefense": 25, "embarkDefense": 25,
"startPercent": 80, "startPercent": 80,
"citySound": "cityFuture",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -322,4 +331,4 @@
"Starting in this era disables religion" "Starting in this era disables religion"
] ]
} }
] ]

View File

@ -1,7 +1,7 @@
[ [
// Source: the fandom, so take these with a grain of salt // Source: the fandom, so take these with a grain of salt
// I also did some testing in the official version, but by far not all // I also did some testing in the official version, but by far not all
{ {
"name": "Ancient era", "name": "Ancient era",
"researchAgreementCost": 150, "researchAgreementCost": 150,
@ -13,6 +13,7 @@
"baseUnitBuyCost": 200, "baseUnitBuyCost": 200,
"embarkDefense": 3, "embarkDefense": 3,
"startPercent": 0, "startPercent": 0,
"citySound": "cityAncient",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+3 Culture] per turn"], "Cultured": ["Provides [+3 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -42,6 +43,7 @@
"baseUnitBuyCost": 200, "baseUnitBuyCost": 200,
"embarkDefense": 4, "embarkDefense": 4,
"startPercent": 10, "startPercent": 10,
"citySound": "cityClassical",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+3 Culture] per turn"], "Cultured": ["Provides [+3 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -73,6 +75,7 @@
"baseUnitBuyCost": 200, "baseUnitBuyCost": 200,
"embarkDefense": 6, "embarkDefense": 6,
"startPercent": 25, "startPercent": 25,
"citySound": "cityMedieval",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+6 Culture] per turn"], "Cultured": ["Provides [+6 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -100,11 +103,12 @@
"startingCulture": 300, "startingCulture": 300,
"settlerPopulation": 2, "settlerPopulation": 2,
"settlerBuildings": ["Monument","Granary","Lighthouse"], "settlerBuildings": ["Monument","Granary","Lighthouse"],
"startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus", "startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus",
"The Great Lighthouse", "Hanging Gardens", "The Oracle", "Great Wall", "Colossus"], "The Great Lighthouse", "Hanging Gardens", "The Oracle", "Great Wall", "Colossus"],
"baseUnitBuyCost": 300, "baseUnitBuyCost": 300,
"embarkDefense": 8, "embarkDefense": 8,
"startPercent": 37, "startPercent": 37,
"citySound": "cityRenaissance",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+6 Culture] per turn"], "Cultured": ["Provides [+6 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -138,6 +142,7 @@
"baseUnitBuyCost": 400, "baseUnitBuyCost": 400,
"embarkDefense": 10, "embarkDefense": 10,
"startPercent": 50, "startPercent": 50,
"citySound": "cityIndustrial",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -167,11 +172,12 @@
"settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Temple","Barracks","Library","Colosseum"], "settlerBuildings": ["Monument","Granary","Lighthouse","Market","Workshop","Temple","Barracks","Library","Colosseum"],
"startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus", "startingObsoleteWonders": ["Temple of Artemis", "Stonehenge", "The Great Library", "Mausoleum of Halicarnassus", "The Pyramids", "Statue of Zeus",
"The Great Lighthouse", "Hanging Gardens", "The Oracle", "Great Wall", "Colossus", "The Great Lighthouse", "Hanging Gardens", "The Oracle", "Great Wall", "Colossus",
"Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Notre Dame", "Hagia Sophia", "Chichen Itza", "Machu Picchu", "Angkor Wat", "Notre Dame",
"Sistine Chapel", "Forbidden Palace", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin"], "Sistine Chapel", "Forbidden Palace", "Himeji Castle", "Taj Mahal", "Porcelain Tower", "Kremlin"],
"baseUnitBuyCost": 600, "baseUnitBuyCost": 600,
"embarkDefense": 13, "embarkDefense": 13,
"startPercent": 65, "startPercent": 65,
"citySound": "cityModern",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -207,6 +213,7 @@
"baseUnitBuyCost": 800, "baseUnitBuyCost": 800,
"embarkDefense": 16, "embarkDefense": 16,
"startPercent": 65, "startPercent": 65,
"citySound": "cityAtomic",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -243,9 +250,10 @@
"baseUnitBuyCost": 1000, "baseUnitBuyCost": 1000,
"embarkDefense": 20, "embarkDefense": 20,
"startPercent": 80, "startPercent": 80,
// So theoretically this is always just all the wonders at least 2 eras old. So we could just use that. // So theoretically this is always just all the wonders at least 2 eras old. So we could just use that.
// But where is the modularity? The excluding of very specific wonders? That is no fun. // But where is the modularity? The excluding of very specific wonders? That is no fun.
// So we just write down the entire long list (sorted by era!) instead. // So we just write down the entire long list (sorted by era!) instead.
"citySound": "cityInformation",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],
@ -263,8 +271,8 @@
}, },
"iconRGB": [76, 176, 81], "iconRGB": [76, 176, 81],
}, },
{ // Technically, this Era doesn't exist in the original game. { // Technically, this Era doesn't exist in the original game.
// But as it is _really_ usefull to have for testing, I'd like to keep it. // But as it is _really_ usefull to have for testing, I'd like to keep it.
// The stats are just copy-pasted from the information era. // The stats are just copy-pasted from the information era.
"name": "Future era", "name": "Future era",
"researchAgreementCost": 400, "researchAgreementCost": 400,
@ -285,6 +293,7 @@
"baseUnitBuyCost": 1000, "baseUnitBuyCost": 1000,
"embarkDefense": 25, "embarkDefense": 25,
"startPercent": 80, "startPercent": 80,
"citySound": "cityFuture",
"friendBonus": { "friendBonus": {
"Cultured": ["Provides [+13 Culture] per turn"], "Cultured": ["Provides [+13 Culture] per turn"],
"Maritime": ["Provides [+2 Food] [in capital] per turn"], "Maritime": ["Provides [+2 Food] [in capital] per turn"],

View File

@ -674,6 +674,7 @@ Visit repository =
Turns between autosaves = Turns between autosaves =
Sound effects volume = Sound effects volume =
Music volume = Music volume =
City ambient sound volume =
Pause between tracks = Pause between tracks =
Currently playing: [title] = Currently playing: [title] =
Download music = Download music =

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

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

View File

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

View File

@ -29,6 +29,7 @@ class Era : RulesetObject(), IHasUniques {
var baseUnitBuyCost = 200 var baseUnitBuyCost = 200
var embarkDefense = 3 var embarkDefense = 3
var startPercent = 0 var startPercent = 0
var citySound = "cityClassical"
var friendBonus = HashMap<String, List<String>>() var friendBonus = HashMap<String, List<String>>()
var allyBonus = 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.automation.Automation
import com.unciv.logic.city.CityInfo import com.unciv.logic.city.CityInfo
import com.unciv.logic.city.IConstruction import com.unciv.logic.city.IConstruction
import com.unciv.logic.city.INonPerpetualConstruction
import com.unciv.logic.map.TileInfo import com.unciv.logic.map.TileInfo
import com.unciv.models.UncivSound
import com.unciv.models.ruleset.Building import com.unciv.models.ruleset.Building
import com.unciv.models.ruleset.tile.TileImprovement import com.unciv.models.ruleset.tile.TileImprovement
import com.unciv.models.ruleset.unique.UniqueType import com.unciv.models.ruleset.unique.UniqueType
import com.unciv.models.stats.Stat 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.images.ImageGetter
import com.unciv.ui.map.TileGroupMap import com.unciv.ui.map.TileGroupMap
import com.unciv.ui.popup.ToastPopup 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.KeyCharAndCode
import com.unciv.ui.utils.RecreateOnResize import com.unciv.ui.utils.RecreateOnResize
import com.unciv.ui.utils.ZoomableScrollPane 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.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.onClick
import com.unciv.ui.utils.extensions.packIfNeeded import com.unciv.ui.utils.extensions.packIfNeeded
import com.unciv.ui.utils.extensions.toTextButton import com.unciv.ui.utils.extensions.toTextButton
import kotlin.collections.ArrayList
import com.unciv.ui.worldscreen.WorldScreen import com.unciv.ui.worldscreen.WorldScreen
class CityScreen( class CityScreen(
@ -78,7 +82,11 @@ class CityScreen(
/** Button for exiting the city - sits on BOTTOM CENTER */ /** Button for exiting the city - sits on BOTTOM CENTER */
private val exitCityButton = "Exit city".toTextButton().apply { private val exitCityButton = "Exit city".toTextButton().apply {
labelCell.pad(10f) labelCell.pad(10f)
onClick { exit() } keyShortcuts.add(KeyCharAndCode.BACK)
onActivation {
exit()
cityAmbiencePlayer.stop()
}
} }
/** Holds City tiles group*/ /** 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 // 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 nextTileToOwn = city.expansion.chooseNewTileToOwn()
private val cityAmbiencePlayer = CityAmbiencePlayer()
init { 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") UncivGame.Current.settings.addCompletedTutorialTask("Enter city screen")
addTiles() 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 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 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 worked tiles", settings.showWorkedTiles, true) { settings.showWorkedTiles = it }
optionsPopup.addCheckbox(this, "Show resources and improvements", settings.showResourcesAndImprovements, true) { optionsPopup.addCheckbox(this, "Show resources and improvements", settings.showResourcesAndImprovements, true) { settings.showResourcesAndImprovements = it }
settings.showResourcesAndImprovements = it
}
optionsPopup.addCheckbox(this, "Show tutorials", settings.showTutorials, true) { settings.showTutorials = 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 units", settings.showPixelUnits, true) { settings.showPixelUnits = it }
optionsPopup.addCheckbox(this, "Show pixel improvements", settings.showPixelImprovements, true) { settings.showPixelImprovements = 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 val music = UncivGame.Current.musicController
addSoundEffectsVolumeSlider(this, settings) addSoundEffectsVolumeSlider(this, settings)
addCitySoundsVolumeSlider(this, settings)
if (UncivGame.Current.musicController.isMusicAvailable()) { if (UncivGame.Current.musicController.isMusicAvailable()) {
addMusicVolumeSlider(this, settings, music) addMusicVolumeSlider(this, settings, music)
@ -84,6 +85,20 @@ private fun addSoundEffectsVolumeSlider(table: Table, settings: GameSettings) {
table.add(soundEffectsVolumeSlider).pad(5f).row() 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) { private fun addMusicVolumeSlider(table: Table, settings: GameSettings, music: MusicController) {
table.add("Music volume".tr()).left().fillX() table.add("Music volume".tr()).left().fillX()

View File

@ -757,49 +757,55 @@ Unless otherwise specified, all the following are from [the Noun Project](https:
Sounds are from FreeSound.org unless otherwise noted and are either Creative Commons or Public Domain unless otherwise noted Sounds are from FreeSound.org unless otherwise noted and are either Creative Commons or Public Domain unless otherwise noted
- [Soft two-fingered snap](https://freesound.org/people/EathanMarkson/sounds/388958/) By EathanMarkson as 'click' for most clicks - [Soft two-fingered snap](https://freesound.org/people/EathanMarkson/sounds/388958/) By EathanMarkson as 'click' for most clicks
- [Pencil1](https://freesound.org/people/stijn/sounds/43673/) By stijn as 'paper' for opening and closing the tech picker - [Pencil1](https://freesound.org/people/stijn/sounds/43673/) By stijn as 'paper' for opening and closing the tech picker
- [SawInOut01](https://freesound.org/people/kingof_thelab/sounds/340243/) By kingof_thelab for construction picking? - [SawInOut01](https://freesound.org/people/kingof_thelab/sounds/340243/) By kingof_thelab for construction picking?
- [Chain Snare #1](https://freesound.org/people/lovesbody/sounds/322079/) By lovesbody as 'fortify' - [Chain Snare #1](https://freesound.org/people/lovesbody/sounds/322079/) By lovesbody as 'fortify'
- [Level up](https://freesound.org/people/Marregheriti/sounds/266100/) By Marregheriti as 'upgrade' for upgrading units - [Level up](https://freesound.org/people/Marregheriti/sounds/266100/) By Marregheriti as 'upgrade' for upgrading units
- [levelup](https://freesound.org/people/Seidhepriest/sounds/382915/) By Seidhepriest as 'chimes' for special actions (free tech, build city, hurry wonder etc.) - [levelup](https://freesound.org/people/Seidhepriest/sounds/382915/) By Seidhepriest as 'chimes' for special actions (free tech, build city, hurry wonder etc.)
- [Coin](https://freesound.org/people/TheDJoe93/sounds/97373/) By TheDJoe93 as 'coin' for purchasing tiles and constructions - [Coin](https://freesound.org/people/TheDJoe93/sounds/97373/) By TheDJoe93 as 'coin' for purchasing tiles and constructions
- [fast simple chop 1](https://freesound.org/people/dave.des/sounds/127196/) By dave.dev as 'whoosh' for moving units around, also in edited form to produce the 'swap units' sound. - [fast simple chop 1](https://freesound.org/people/dave.des/sounds/127196/) By dave.dev as 'whoosh' for moving units around, also in edited form to produce the 'swap units' sound.
- [Military kick](https://freesound.org/people/Dodgy%20C/sounds/72070/) By Dodgy C as 'promote' for unit promotions - [Military kick](https://freesound.org/people/Dodgy%20C/sounds/72070/) By Dodgy C as 'promote' for unit promotions
- [Tank reload](https://freesound.org/people/KieranKeegan/sounds/418882/) By KieranKeegan as 'setup' for siege unit setup - [Tank reload](https://freesound.org/people/KieranKeegan/sounds/418882/) By KieranKeegan as 'setup' for siege unit setup
- [Scribble_short](https://freesound.org/people/waldram/sounds/257518/) By waldram as 'policy' for adopting policies - [Scribble_short](https://freesound.org/people/waldram/sounds/257518/) By waldram as 'policy' for adopting policies
- [Hit Impact](https://freesound.org/people/Mrguff/sounds/369711/) by Mrguff as 'throw' for catapult & trebuchet attacks - [Hit Impact](https://freesound.org/people/Mrguff/sounds/369711/) by Mrguff as 'throw' for catapult & trebuchet attacks
- [Slingshot fly by 2](https://freesound.org/people/saturdaysoundguy/sounds/394186/) by saturdaysoundguy as 'arrow' for arrow attacks - [Slingshot fly by 2](https://freesound.org/people/saturdaysoundguy/sounds/394186/) by saturdaysoundguy as 'arrow' for arrow attacks
- [Metal hit slide](https://freesound.org/people/orginaljun/sounds/149102/) by orginaljun as 'nonmetalhit' for pre-metal melee sounds - [Metal hit slide](https://freesound.org/people/orginaljun/sounds/149102/) by orginaljun as 'nonmetalhit' for pre-metal melee sounds
- [klick_anlauf](https://freesound.org/people/jascha/sounds/16576/) By jascha as 'metalhit' for metal melee sounds - [klick_anlauf](https://freesound.org/people/jascha/sounds/16576/) By jascha as 'metalhit' for metal melee sounds
- [Horse's whinny](https://freesound.org/people/Kubuzz/sounds/347036/) By Kubuzz as 'horse' for cavalry attack sounds - [Horse's whinny](https://freesound.org/people/Kubuzz/sounds/347036/) By Kubuzz as 'horse' for cavalry attack sounds
- [machine gun 001 - loop](https://freesound.org/people/pgi/sounds/212602/) By pgi as 'machinegun' for machine gun attack sound - [machine gun 001 - loop](https://freesound.org/people/pgi/sounds/212602/) By pgi as 'machinegun' for machine gun attack sound
- [uzzi_full_single](https://freesound.org/people/Deganoth/sounds/348685/) By Deganoth as 'shot' for bullet attacks - [uzzi_full_single](https://freesound.org/people/Deganoth/sounds/348685/) By Deganoth as 'shot' for bullet attacks
- [Grenade Launcher 2](https://soundbible.com/2140-Grenade-Launcher-2.html) By Daniel Simon as city bombard sound (CC Attribution 3.0 license) - [Grenade Launcher 2](https://soundbible.com/2140-Grenade-Launcher-2.html) By Daniel Simon as city bombard sound (CC Attribution 3.0 license)
- [Woosh](https://soundbible.com/2068-Woosh.html) by Mark DiAngelo as 'slider' sound (CC Attribution 3.0 license) - [Woosh](https://soundbible.com/2068-Woosh.html) by Mark DiAngelo as 'slider' sound (CC Attribution 3.0 license)
- [Tornado-Siren-II](https://soundbible.com/1937-Tornado-Siren-II.html) by Delilah as part of 'nuke' sound (CC Attribution 3.0 license) - [Tornado-Siren-II](https://soundbible.com/1937-Tornado-Siren-II.html) by Delilah as part of 'nuke' sound (CC Attribution 3.0 license)
- [Explosion-Ultra-Bass](https://soundbible.com/1807-Explosion-Ultra-Bass.html) by Mark DiAngelo as part of 'nuke' sound (CC Attribution 3.0 license) - [Explosion-Ultra-Bass](https://soundbible.com/1807-Explosion-Ultra-Bass.html) by Mark DiAngelo as part of 'nuke' sound (CC Attribution 3.0 license)
- [Short Choir](https://freesound.org/people/Breviceps/sounds/444491/) by Breviceps as 'choir' for free great person pick - [Short Choir](https://freesound.org/people/Breviceps/sounds/444491/) by Breviceps as 'choir' for free great person pick
- [Death Robot! Robotic scream](https://freesound.org/people/vultraz168/sounds/334660/) by vultraz168 for Giant Death Robot Attack (CC0 1.0 Universal license) - [Death Robot! Robotic scream](https://freesound.org/people/vultraz168/sounds/334660/) by vultraz168 for Giant Death Robot Attack (CC0 1.0 Universal license)
- [ceremonial cannon fire](https://freesound.org/people/DylanSmithSound/sounds/274826/) by DylanSmithSound for cannon - [ceremonial cannon fire](https://freesound.org/people/DylanSmithSound/sounds/274826/) by DylanSmithSound for cannon
- [artillery fire](https://freesound.org/people/Tomashevsky/sounds/476664/) by Tomashevsky for artillery - [artillery fire](https://freesound.org/people/Tomashevsky/sounds/476664/) by Tomashevsky for artillery
- [20mm cannons](https://freesound.org/people/Piotr123/sounds/551534/) by Piotr123 for ship guns - [20mm cannons](https://freesound.org/people/Piotr123/sounds/551534/) by Piotr123 for ship guns
- "bombing" is made by the Unciv team using Audacity from - "bombing" is made by the Unciv team using Audacity from
- [lancaster bomber](https://freesound.org/people/confusion_music/sounds/103439/) by confusion_music - aircraft - [lancaster bomber](https://freesound.org/people/confusion_music/sounds/103439/) by confusion_music - aircraft
- [Artillery Explosion (Close) (Mixed)](https://freesound.org/people/EFlexMusic/sounds/388528/) by EFlexMusic - impact - [Artillery Explosion (Close) (Mixed)](https://freesound.org/people/EFlexMusic/sounds/388528/) by EFlexMusic - impact
- [SFX Hit drop/bomb effect 5](https://freesound.org/people/old_waveplay/sounds/187502/) by old_waveplay - bass - [SFX Hit drop/bomb effect 5](https://freesound.org/people/old_waveplay/sounds/187502/) by old_waveplay - bass
- "jetgun" for Jet Fighter attack is made by the Unciv team using Audacity from - "jetgun" for Jet Fighter attack is made by the Unciv team using Audacity from
- [Fighter Jet Aircraft Fly by (synthesised)](https://freesound.org/people/Headphaze/sounds/347795/) by Headphaze - [Fighter Jet Aircraft Fly by (synthesised)](https://freesound.org/people/Headphaze/sounds/347795/) by Headphaze
- [Machine Gun 001 - triple shot](https://freesound.org/people/pgi/sounds/212600/) by pgi - [Machine Gun 001 - triple shot](https://freesound.org/people/pgi/sounds/212600/) by pgi
- Excerpt from [Tanks Shooting](https://freesound.org/people/qubodup/sounds/189344/) by qubodup for tankshot - Excerpt from [Tanks Shooting](https://freesound.org/people/qubodup/sounds/189344/) by qubodup for tankshot
- "torpedo" is made by the Unciv team using Audacity from - "torpedo" is made by the Unciv team using Audacity from
- [Torpedo launch underwater](https://freesound.org/people/jobro/sounds/35530/) by jobro - [Torpedo launch underwater](https://freesound.org/people/jobro/sounds/35530/) by jobro
- [Artillery Explosion (Close) (Mixed)](https://freesound.org/people/EFlexMusic/sounds/388528/) by EFlexMusic - [Artillery Explosion (Close) (Mixed)](https://freesound.org/people/EFlexMusic/sounds/388528/) by EFlexMusic
- [elephant 44](https://freesound.org/people/y89312/sounds/139875/) by y89312 for Naruesan's Elephant sound - [elephant 44](https://freesound.org/people/y89312/sounds/139875/) by y89312 for Naruesan's Elephant sound
- Excerpt from [Missile Strike](https://freesound.org/people/BaDoink/sounds/570690/) by BaDoink for guided missile - Excerpt from [Missile Strike](https://freesound.org/people/BaDoink/sounds/570690/) by BaDoink for guided missile
- Excerpt from [FireBurning_v2.wav](https://freesound.org/people/pcaeldries/sounds/30322/) by pcaeldries for 'remove heresy' action of inquisitor ([License](http://creativecommons.org/licenses/by/3.0/)) - Excerpt from [FireBurning_v2.wav](https://freesound.org/people/pcaeldries/sounds/30322/) by pcaeldries for 'remove heresy' action of inquisitor ([License](http://creativecommons.org/licenses/by/3.0/))
- [Up Chime 2](https://freesound.org/people/FoolBoyMedia/sounds/352666/) by FoolBoyMedia for notifications - [Up Chime 2](https://freesound.org/people/FoolBoyMedia/sounds/352666/) by FoolBoyMedia for notifications
- [dingaling](https://freesound.org/people/morrisjm/sounds/268756/) by morrisjm (based on [Calling_Bell_02.wav](https://freesound.org/people/RSilveira_88/sounds/216306/) by RSilveira_88) for notifications - [dingaling](https://freesound.org/people/morrisjm/sounds/268756/) by morrisjm (based on [Calling_Bell_02.wav](https://freesound.org/people/RSilveira_88/sounds/216306/) by RSilveira_88) for notifications
- City ambience sounds made by Unciv Team using Audacity from CC0 sounds and
- [Street Musician Playing Renaissance Melody on Glockenspiel](https://freesound.org/people/_MC5_/sounds/542107/) by MC5 for Renaissance city sound
- [Ambience, Machine Factory](https://freesound.org/people/InspectorJ/sounds/385943/) by InspectorJ for Industrial city sound
- [Rock_Hammer_Chisel_01](https://freesound.org/people/dheming/sounds/240981/#) by dheming for Ancient city sound
- [Future City ambience](https://freesound.org/people/bolkmar/sounds/502896/) by bolkmar for Future city sound
- [Jingle_Achievement](https://freesound.org/people/LittleRobotSoundFactory/sounds/270404/) by LittleRobotSoundFactory for We Love The King sound
## Music ## Music