diff --git a/core/src/com/unciv/models/tilesets/TileSetCache.kt b/core/src/com/unciv/models/tilesets/TileSetCache.kt index 53b936ac88..cd42b9a6b6 100644 --- a/core/src/com/unciv/models/tilesets/TileSetCache.kt +++ b/core/src/com/unciv/models/tilesets/TileSetCache.kt @@ -3,24 +3,50 @@ package com.unciv.models.tilesets import com.badlogic.gdx.Gdx import com.badlogic.gdx.files.FileHandle import com.unciv.JsonParser +import com.unciv.UncivGame import com.unciv.ui.utils.ImageGetter -object TileSetCache : HashMap(){ - fun loadTileSetConfigs(consoleMode: Boolean = false, printOutput: Boolean = false){ +object TileSetCache : HashMap() { + private data class TileSetAndMod(val tileSet: String, val mod: String) + private val allConfigs = HashMap() + + /** Combine [TileSetConfig]s for chosen mods. + * Vanilla always active, even with a base ruleset mod active. + * Permanent visual mods always included as long as UncivGame.Current is initialized. + * Other active mods can be passed in parameter [ruleSetMods], if that is `null` and a game is in + * progress, that game's mods are used instead. + */ + fun assembleTileSetConfigs(ruleSetMods: HashSet? = null) { + val mods = mutableSetOf("") + if (UncivGame.isCurrentInitialized()) { + mods.addAll(UncivGame.Current.settings.visualMods) + if (ruleSetMods != null) + mods.addAll(ruleSetMods) + else if (UncivGame.Current.isGameInfoInitialized()) + mods.addAll(UncivGame.Current.gameInfo.ruleSet.mods) + } clear() + allConfigs.filter { it.key.mod in mods }.forEach { + if (it.key.tileSet in this) this[it.key.tileSet]!!.updateConfig(it.value) + else this[it.key.tileSet] = it.value + } + } + + fun loadTileSetConfigs(consoleMode: Boolean = false, printOutput: Boolean = false){ + allConfigs.clear() var tileSetName = "" //load internal TileSets - val fileHandles: Sequence = if (consoleMode) FileHandle("jsons/TileSets").list().asSequence() - else ImageGetter.getAvailableTilesets().map { Gdx.files.internal("jsons/TileSets/$it.json")}.filter { it.exists() } + val fileHandles: Sequence = + if (consoleMode) FileHandle("jsons/TileSets").list().asSequence() + else ImageGetter.getAvailableTilesets().map { Gdx.files.internal("jsons/TileSets/$it.json")}.filter { it.exists() } for (configFile in fileHandles){ tileSetName = configFile.nameWithoutExtension().removeSuffix("Config") try { - if (this[tileSetName] == null) - this[tileSetName] = JsonParser().getFromJson(TileSetConfig::class.java, configFile) - else - this[tileSetName]!!.updateConfig(JsonParser().getFromJson(TileSetConfig::class.java, configFile)) + val key = TileSetAndMod(tileSetName, "") + assert(key !in allConfigs) + allConfigs[key] = JsonParser().getFromJson(TileSetConfig::class.java, configFile) if (printOutput) { println("TileSetConfig loaded successfully: ${configFile.name()}") println() @@ -35,20 +61,21 @@ object TileSetCache : HashMap(){ } //load mod TileSets - val modsHandles = if (consoleMode) FileHandle("mods").list() - else Gdx.files.local("mods").list() + val modsHandles = + if (consoleMode) FileHandle("mods").list() + else Gdx.files.local("mods").list() for (modFolder in modsHandles) { - if (modFolder.name().startsWith('.')) continue + val modName = modFolder.name() + if (modName.startsWith('.')) continue if (!modFolder.isDirectory) continue try { for (configFile in modFolder.child("jsons/TileSets").list()){ tileSetName = configFile.nameWithoutExtension().removeSuffix("Config") - if (this[tileSetName] == null) - this[tileSetName] = JsonParser().getFromJson(TileSetConfig::class.java, configFile) - else - this[tileSetName]!!.updateConfig(JsonParser().getFromJson(TileSetConfig::class.java, configFile)) + val key = TileSetAndMod(tileSetName, modName) + assert(key !in allConfigs) + allConfigs[key] = JsonParser().getFromJson(TileSetConfig::class.java, configFile) if (printOutput) { println("TileSetConfig loaded successfully: ${configFile.path()}") println() @@ -62,5 +89,7 @@ object TileSetCache : HashMap(){ } } } + + assembleTileSetConfigs() } -} \ No newline at end of file +} diff --git a/core/src/com/unciv/ui/mapeditor/MapEditorMenuPopup.kt b/core/src/com/unciv/ui/mapeditor/MapEditorMenuPopup.kt index 01cc0a6796..eea6bfb7f9 100644 --- a/core/src/com/unciv/ui/mapeditor/MapEditorMenuPopup.kt +++ b/core/src/com/unciv/ui/mapeditor/MapEditorMenuPopup.kt @@ -28,7 +28,7 @@ class MapEditorMenuPopup(var mapEditorScreen: MapEditorScreen): Popup(mapEditorS } class MapEditorRulesetPopup(mapEditorScreen: MapEditorScreen) : Popup(mapEditorScreen) { - var ruleset = mapEditorScreen.ruleset.clone() // don't take the actual one, so w can decide to not make changes + var ruleset = mapEditorScreen.ruleset.clone() // don't take the actual one, so we can decide to not make changes init { val mods = mapEditorScreen.tileMap.mapParameters.mods diff --git a/core/src/com/unciv/ui/utils/ImageGetter.kt b/core/src/com/unciv/ui/utils/ImageGetter.kt index c178bd3518..89b2fcbf7d 100644 --- a/core/src/com/unciv/ui/utils/ImageGetter.kt +++ b/core/src/com/unciv/ui/utils/ImageGetter.kt @@ -21,6 +21,7 @@ import com.unciv.models.ruleset.Nation import com.unciv.models.ruleset.Ruleset import com.unciv.models.ruleset.tile.ResourceType import com.unciv.models.stats.Stats +import com.unciv.models.tilesets.TileSetCache import kotlin.math.atan2 import kotlin.math.max import kotlin.math.min @@ -87,6 +88,8 @@ object ImageGetter { textureRegionDrawables[region.name] = drawable } } + + TileSetCache.assembleTileSetConfigs(ruleset.mods) } diff --git a/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt b/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt index b480a23773..043409c39b 100644 --- a/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt +++ b/core/src/com/unciv/ui/worldscreen/mainmenu/OptionsPopup.kt @@ -8,6 +8,7 @@ import com.unciv.MainMenuScreen import com.unciv.logic.civilization.PlayerType import com.unciv.models.UncivSound import com.unciv.models.ruleset.RulesetCache +import com.unciv.models.tilesets.TileSetCache import com.unciv.models.translations.TranslationFileWriter import com.unciv.models.translations.Translations import com.unciv.models.translations.tr @@ -363,6 +364,7 @@ class OptionsPopup(val previousScreen:CameraStageBaseScreen) : Popup(previousScr tileSetSelectBox.onChange { settings.tileSet = tileSetSelectBox.selected + TileSetCache.assembleTileSetConfigs() reloadWorldAndOptions() } }