diff --git a/android/assets/jsons/TileSets/FantasyHexConfig.json b/android/assets/jsons/TileSets/FantasyHexConfig.json new file mode 100644 index 0000000000..11ca34a304 --- /dev/null +++ b/android/assets/jsons/TileSets/FantasyHexConfig.json @@ -0,0 +1,12 @@ +{ + "useColorAsBaseTerrain": "false", + "ruleVariants": { + "Mountain+Barringer Crater": ["Barringer Crater"], + "Mountain+Cerro de Potosi": ["Cerro de Potosi"], + "Mountain+Grand Mesa": ["Grand Mesa"], + "Mountain+Krakatoa": ["Krakatoa"], + "Mountain+Mount Fuji": ["Mount Fuji"], + "Mountain+Old Faithful": ["Old Faithful"], + "Mountain+Rock of Gibraltar": ["Rock of Gibraltar"] + } +} \ No newline at end of file diff --git a/core/src/com/unciv/UncivGame.kt b/core/src/com/unciv/UncivGame.kt index 7e6527e630..a068332186 100644 --- a/core/src/com/unciv/UncivGame.kt +++ b/core/src/com/unciv/UncivGame.kt @@ -13,6 +13,7 @@ import com.unciv.logic.GameSaver import com.unciv.logic.civilization.PlayerType import com.unciv.models.metadata.GameSettings import com.unciv.models.ruleset.RulesetCache +import com.unciv.models.tilesets.TileSetCache import com.unciv.models.translations.Translations import com.unciv.ui.LanguagePickerScreen import com.unciv.ui.utils.* @@ -97,6 +98,7 @@ class UncivGame(parameters: UncivGameParameters) : Game() { RulesetCache.loadRulesets(printOutput = true) translations.tryReadTranslationForCurrentLanguage() translations.loadPercentageCompleteOfLanguages() + TileSetCache.loadTileSetConfigs(printOutput = true) if (settings.userId.isEmpty()) { // assign permanent user id settings.userId = UUID.randomUUID().toString() diff --git a/core/src/com/unciv/models/tilesets/TileSetCache.kt b/core/src/com/unciv/models/tilesets/TileSetCache.kt new file mode 100644 index 0000000000..370365b78e --- /dev/null +++ b/core/src/com/unciv/models/tilesets/TileSetCache.kt @@ -0,0 +1,62 @@ +package com.unciv.models.tilesets + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.files.FileHandle +import com.unciv.JsonParser + +object TileSetCache : HashMap(){ + fun loadTileSetConfigs(consoleMode: Boolean = false, printOutput: Boolean = false){ + clear() + var tileSetName = "" + + //load default TileSets + for (configFile in Gdx.files.local("jsons/TileSets").list()){ + 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)) + if (printOutput) { + println("TileSetConfig loaded successfully: ${configFile.name()}") + println() + } + } catch (ex: Exception){ + if (printOutput){ + println("Exception loading TileSetConfig '${configFile.path()}':") + println(" ${ex.localizedMessage}") + println(" (Source file ${ex.stackTrace[0].fileName} line ${ex.stackTrace[0].lineNumber})") + } + } + } + + //load mod TileSets + val modsHandles = if (consoleMode) FileHandle("mods").list() + else Gdx.files.local("mods").list() + + for (modFolder in modsHandles) { + if (modFolder.name().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)) + if (printOutput) { + println("TileSetConfig loaded successfully: ${configFile.path()}") + println() + } + } + } catch (ex: Exception){ + if (printOutput) { + println("Exception loading TileSetConfig '${modFolder.name()}/jsons/TileSets/${tileSetName}':") + println(" ${ex.localizedMessage}") + println(" (Source file ${ex.stackTrace[0].fileName} line ${ex.stackTrace[0].lineNumber})") + } + } + } + } +} \ No newline at end of file diff --git a/core/src/com/unciv/models/tilesets/TileSetConfig.kt b/core/src/com/unciv/models/tilesets/TileSetConfig.kt new file mode 100644 index 0000000000..6aa3489ab7 --- /dev/null +++ b/core/src/com/unciv/models/tilesets/TileSetConfig.kt @@ -0,0 +1,13 @@ +package com.unciv.models.tilesets + +class TileSetConfig { + var useColorAsBaseTerrain = true + var ruleVariants: HashMap> = HashMap() + + fun updateConfig(other: TileSetConfig){ + useColorAsBaseTerrain = other.useColorAsBaseTerrain + for ((tileSetString, renderOrder) in other.ruleVariants){ + ruleVariants[tileSetString] = renderOrder + } + } +} \ No newline at end of file diff --git a/core/src/com/unciv/ui/tilegroups/TileGroup.kt b/core/src/com/unciv/ui/tilegroups/TileGroup.kt index ff7a4fb464..19f5447ebb 100644 --- a/core/src/com/unciv/ui/tilegroups/TileGroup.kt +++ b/core/src/com/unciv/ui/tilegroups/TileGroup.kt @@ -182,10 +182,14 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings, resourceAndImprovementSequence = resourceAndImprovementSequence.filterNotNull() val terrainImages = (sequenceOf(tileInfo.baseTerrain) + tileInfo.terrainFeatures.asSequence()).filterNotNull() - val allTogether = (terrainImages + resourceAndImprovementSequence).joinToString("+").let { tileSetStrings.getTile(it) } + val allTogether = (terrainImages + resourceAndImprovementSequence).joinToString("+") + val allTogetherLocation = tileSetStrings.getTile(allTogether) - if (ImageGetter.imageExists(allTogether)) return listOf(allTogether) - else return getTerrainImageLocations(terrainImages) + getImprovementAndResourceImages(resourceAndImprovementSequence) + return when { + tileSetStrings.tileSetConfig.ruleVariants[allTogether] != null -> tileSetStrings.tileSetConfig.ruleVariants[allTogether]!!.map { tileSetStrings.getTile(it) } + ImageGetter.imageExists(allTogetherLocation) -> listOf(allTogetherLocation) + else -> getTerrainImageLocations(terrainImages) + getImprovementAndResourceImages(resourceAndImprovementSequence) + } } fun getTerrainImageLocations(terrainSequence: Sequence): List { @@ -195,8 +199,6 @@ open class TileGroup(var tileInfo: TileInfo, var tileSetStrings:TileSetStrings, } fun getImprovementAndResourceImages(resourceAndImprovementSequence: Sequence): List { - if(tileInfo.resource=="Silk") - println() val altogether = resourceAndImprovementSequence.joinToString("+").let { tileSetStrings.getTile(it) } if (ImageGetter.imageExists(altogether)) return listOf(altogether) else return resourceAndImprovementSequence.map { tileSetStrings.getTile(it) }.toList() diff --git a/core/src/com/unciv/ui/tilegroups/TileSetStrings.kt b/core/src/com/unciv/ui/tilegroups/TileSetStrings.kt index 3ca9a1884f..e1261dc15c 100644 --- a/core/src/com/unciv/ui/tilegroups/TileSetStrings.kt +++ b/core/src/com/unciv/ui/tilegroups/TileSetStrings.kt @@ -1,11 +1,14 @@ package com.unciv.ui.tilegroups import com.unciv.UncivGame +import com.unciv.models.tilesets.TileSetCache +import com.unciv.models.tilesets.TileSetConfig class TileSetStrings { // this is so that when we have 100s of TileGroups, they won't all individually come up with all these strings themselves, // it gets pretty memory-intensive (10s of MBs which is a lot for lower-end phones) val tileSetLocation = "TileSets/" + UncivGame.Current.settings.tileSet + "/" + val tileSetConfig = TileSetCache[UncivGame.Current.settings.tileSet] ?: TileSetConfig() val hexagon = tileSetLocation + "Hexagon" val crosshatchHexagon = tileSetLocation + "CrosshatchHexagon" diff --git a/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt b/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt index bc2d49dea6..402adc5b88 100644 --- a/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt +++ b/desktop/src/com/unciv/app/desktop/ConsoleLauncher.kt @@ -12,6 +12,7 @@ import com.unciv.models.metadata.GameSpeed import com.unciv.models.metadata.Player import com.unciv.models.ruleset.RulesetCache import com.unciv.models.simulation.Simulation +import com.unciv.models.tilesets.TileSetCache import com.unciv.ui.newgamescreen.GameSetupInfo internal object ConsoleLauncher { @@ -35,6 +36,7 @@ internal object ConsoleLauncher { } RulesetCache.loadRulesets(true) + TileSetCache.loadTileSetConfigs(true) val gameParameters = getGameParameters("China", "Greece") val mapParameters = getMapParameters()