mirror of
https://github.com/yairm210/Unciv.git
synced 2025-02-01 02:14:51 +07:00
Fix TileSet mods can lock user out (#9023)
This commit is contained in:
parent
13f4dd0756
commit
be69f8b52d
@ -189,7 +189,9 @@ open class UncivGame(val isConsoleMode: Boolean = false) : Game(), PlatformSpeci
|
||||
|
||||
ImageGetter.resetAtlases()
|
||||
ImageGetter.setNewRuleset(ImageGetter.ruleset) // This needs to come after the settings, since we may have default visual mods
|
||||
if (settings.tileSet !in ImageGetter.getAvailableTilesets()) { // If one of the tilesets is no longer available, default back
|
||||
val availableTileSets = ImageGetter.getAvailableTilesets().toSet()
|
||||
.intersect(TileSetCache.getAvailableTilesets().toSet())
|
||||
if (settings.tileSet !in availableTileSets) { // If the configured tileset is no longer available, default back
|
||||
settings.tileSet = Constants.defaultTileset
|
||||
}
|
||||
|
||||
|
@ -80,4 +80,20 @@ object TileSetCache : HashMap<String, TileSet>() {
|
||||
set(name, tileset)
|
||||
}
|
||||
}
|
||||
|
||||
/** Determines potentially available TileSets - by scanning for TileSet jsons.
|
||||
*
|
||||
* Available before initialization finishes.
|
||||
* To get more reliable info, either wait until `this` is fully initialized,
|
||||
* or intersect with [ImageGetter.getAvailableTilesets]
|
||||
*/
|
||||
fun getAvailableTilesets() = sequence<FileHandle> {
|
||||
yieldAll(FileHandle("jsons/TileSets").list().asIterable())
|
||||
for (modFolder in FileHandle("mods").list()) {
|
||||
if (!modFolder.isDirectory || modFolder.name().startsWith('.'))
|
||||
continue
|
||||
yieldAll(modFolder.child("jsons/TileSets").list().asIterable())
|
||||
}
|
||||
}.filter { it.exists() }
|
||||
.map { it.nameWithoutExtension().removeSuffix("Config") }
|
||||
}
|
||||
|
@ -448,8 +448,16 @@ object ImageGetter {
|
||||
|
||||
fun getAvailableSkins() = ninePatchDrawables.keys.asSequence().map { it.split("/")[1] }.distinct()
|
||||
|
||||
fun getAvailableTilesets() = textureRegionDrawables.keys.asSequence().filter { it.startsWith("TileSets") && !it.contains("/Units/") }
|
||||
.map { it.split("/")[1] }.distinct()
|
||||
/** Determines available TileSets from the currently loaded Texture paths.
|
||||
*
|
||||
* Note [TileSetCache] will not necessarily load all of them, e.g. if a Mod fails
|
||||
* to provide a config json for a graphic with a Tileset path.
|
||||
*
|
||||
* Intersect with [TileSetCache.getAvailableTilesets] for a more reliable answer
|
||||
*/
|
||||
fun getAvailableTilesets() = textureRegionDrawables.keys.asSequence()
|
||||
.filter { it.startsWith("TileSets") && !it.contains("/Units/") }
|
||||
.map { it.split("/")[1] }.distinct()
|
||||
|
||||
fun getAvailableUnitsets() = textureRegionDrawables.keys.asSequence().filter { it.contains("/Units/") }
|
||||
.map { it.split("/")[1] }.distinct()
|
||||
|
@ -21,6 +21,7 @@ import com.unciv.models.metadata.BaseRuleset
|
||||
import com.unciv.models.metadata.GameSetupInfo
|
||||
import com.unciv.models.ruleset.Ruleset
|
||||
import com.unciv.models.ruleset.RulesetCache
|
||||
import com.unciv.models.tilesets.TileSetCache
|
||||
import com.unciv.ui.components.AutoScrollPane
|
||||
import com.unciv.ui.components.KeyCharAndCode
|
||||
import com.unciv.ui.components.UncivTooltip.Companion.addTooltip
|
||||
@ -51,6 +52,7 @@ import com.unciv.ui.screens.worldscreen.WorldScreen
|
||||
import com.unciv.ui.screens.worldscreen.mainmenu.WorldScreenMenuPopup
|
||||
import com.unciv.utils.concurrency.Concurrency
|
||||
import com.unciv.utils.concurrency.launchOnGLThread
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlin.math.min
|
||||
|
||||
|
||||
@ -104,51 +106,14 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
|
||||
// will not exist unless we reset the ruleset and images
|
||||
ImageGetter.ruleset = RulesetCache.getVanillaRuleset()
|
||||
|
||||
Concurrency.run("ShowMapBackground") {
|
||||
var scale = 1f
|
||||
var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance
|
||||
var mapHeight = stage.height / TileGroupMap.groupSize
|
||||
if (mapWidth * mapHeight > 3000f) { // 3000 as max estimated number of tiles is arbitrary (we had typically 721 before)
|
||||
scale = mapWidth * mapHeight / 3000f
|
||||
mapWidth /= scale
|
||||
mapHeight /= scale
|
||||
scale = min(scale, 20f)
|
||||
// This is an extreme safeguard - should an invalid settings.tileSet ever make it past the
|
||||
// guard in UncivGame.create, simply omit the background so the user can at least get to options
|
||||
// (let him crash when loading a game but avoid locking him out entirely)
|
||||
if (game.settings.tileSet in TileSetCache)
|
||||
Concurrency.run("ShowMapBackground") {
|
||||
showMapBackground()
|
||||
}
|
||||
|
||||
val baseRuleset = RulesetCache.getVanillaRuleset()
|
||||
easterEggRuleset = EasterEggRulesets.getTodayEasterEggRuleset()?.let {
|
||||
RulesetCache.getComplexRuleset(baseRuleset, listOf(it))
|
||||
}
|
||||
val mapRuleset = if (game.settings.enableEasterEggs) easterEggRuleset ?: baseRuleset else baseRuleset
|
||||
|
||||
val newMap = MapGenerator(mapRuleset)
|
||||
.generateMap(MapParameters().apply {
|
||||
shape = MapShape.rectangular
|
||||
mapSize = MapSizeNew(MapSize.Small)
|
||||
type = MapType.pangaea
|
||||
temperatureExtremeness = .7f
|
||||
waterThreshold = -0.1f // mainly land, gets about 30% water
|
||||
modifyForEasterEgg()
|
||||
})
|
||||
|
||||
launchOnGLThread { // for GL context
|
||||
ImageGetter.setNewRuleset(mapRuleset)
|
||||
val mapHolder = EditorMapHolder(
|
||||
this@MainMenuScreen,
|
||||
newMap
|
||||
) {}
|
||||
mapHolder.setScale(scale)
|
||||
backgroundTable.addAction(Actions.sequence(
|
||||
Actions.fadeOut(0f),
|
||||
Actions.run {
|
||||
backgroundTable.addActor(mapHolder)
|
||||
mapHolder.center(backgroundTable)
|
||||
},
|
||||
Actions.fadeIn(0.3f)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
val column1 = Table().apply { defaults().pad(10f).fillX() }
|
||||
val column2 = if (singleColumn) column1 else Table().apply { defaults().pad(10f).fillX() }
|
||||
|
||||
@ -220,6 +185,50 @@ class MainMenuScreen: BaseScreen(), RecreateOnResize {
|
||||
stage.addActor(helpButton)
|
||||
}
|
||||
|
||||
private fun CoroutineScope.showMapBackground() {
|
||||
var scale = 1f
|
||||
var mapWidth = stage.width / TileGroupMap.groupHorizontalAdvance
|
||||
var mapHeight = stage.height / TileGroupMap.groupSize
|
||||
if (mapWidth * mapHeight > 3000f) { // 3000 as max estimated number of tiles is arbitrary (we had typically 721 before)
|
||||
scale = mapWidth * mapHeight / 3000f
|
||||
mapWidth /= scale
|
||||
mapHeight /= scale
|
||||
scale = min(scale, 20f)
|
||||
}
|
||||
|
||||
val baseRuleset = RulesetCache.getVanillaRuleset()
|
||||
easterEggRuleset = EasterEggRulesets.getTodayEasterEggRuleset()?.let {
|
||||
RulesetCache.getComplexRuleset(baseRuleset, listOf(it))
|
||||
}
|
||||
val mapRuleset = if (game.settings.enableEasterEggs) easterEggRuleset ?: baseRuleset else baseRuleset
|
||||
|
||||
val newMap = MapGenerator(mapRuleset)
|
||||
.generateMap(MapParameters().apply {
|
||||
shape = MapShape.rectangular
|
||||
mapSize = MapSizeNew(MapSize.Small)
|
||||
type = MapType.pangaea
|
||||
temperatureExtremeness = 0.7f
|
||||
waterThreshold = -0.1f // mainly land, gets about 30% water
|
||||
modifyForEasterEgg()
|
||||
})
|
||||
|
||||
launchOnGLThread { // for GL context
|
||||
ImageGetter.setNewRuleset(mapRuleset)
|
||||
val mapHolder = EditorMapHolder(
|
||||
this@MainMenuScreen,
|
||||
newMap
|
||||
) {}
|
||||
mapHolder.setScale(scale)
|
||||
backgroundTable.addAction(Actions.sequence(
|
||||
Actions.fadeOut(0f),
|
||||
Actions.run {
|
||||
backgroundTable.addActor(mapHolder)
|
||||
mapHolder.center(backgroundTable)
|
||||
},
|
||||
Actions.fadeIn(0.3f)
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
private fun resumeGame() {
|
||||
if (GUI.isWorldLoaded()) {
|
||||
|
Loading…
Reference in New Issue
Block a user