Display map ruleset when picking map, don't show unloadable maps

This commit is contained in:
Yair Morgenstern 2023-05-14 21:51:19 +03:00
parent 5bbd8bce53
commit e6135fa486

View File

@ -6,75 +6,86 @@ import com.badlogic.gdx.scenes.scene2d.actions.Actions
import com.badlogic.gdx.scenes.scene2d.ui.Container
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Array as GdxArray
import com.unciv.UncivGame
import com.unciv.logic.UncivShowableException
import com.unciv.logic.files.MapSaver
import com.unciv.logic.map.MapParameters
import com.unciv.models.ruleset.RulesetCache
import com.unciv.ui.components.extensions.onChange
import com.unciv.ui.components.extensions.pad
import com.unciv.ui.components.extensions.toLabel
import com.unciv.ui.popups.Popup
import com.unciv.ui.screens.basescreen.BaseScreen
import com.unciv.ui.screens.victoryscreen.LoadMapPreview
import com.unciv.utils.Log
import com.unciv.utils.Concurrency
import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import com.badlogic.gdx.utils.Array as GdxArray
class MapFileSelectTable(
private val newGameScreen: NewGameScreen,
private val mapParameters: MapParameters
) : Table() {
private val mapFileSelectBox = SelectBox<FileHandleWrapper>(BaseScreen.skin)
private val mapFileSelectBox = SelectBox<MapWrapper>(BaseScreen.skin)
private val miniMapWrapper = Container<Group?>()
private var mapPreviewJob: Job? = null
private val mapFilesSequence = sequence<FileHandle> {
yieldAll(MapSaver.getMaps().asSequence())
for (modFolder in RulesetCache.values.mapNotNull { it.folderLocation }) {
val mapsFolder = modFolder.child(MapSaver.mapsFolder)
if (mapsFolder.exists())
yieldAll(mapsFolder.list().asSequence())
// The SelectBox auto displays the text a object.toString(), which on the FileHandle itself includes the folder path.
// So we wrap it in another object with a custom toString()
private class MapWrapper(val fileHandle: FileHandle, val mapParameters: MapParameters) {
override fun toString(): String = mapParameters.baseRuleset + " - "+ fileHandle.name()
}
}.map { FileHandleWrapper(it) }
private val mapWrappers= ArrayList<MapWrapper>()
private val columnWidth = newGameScreen.getColumnWidth()
init {
defaults().pad(5f, 10f) // Must stay same as in MapParametersTable
val mapFileLabel = "{Map file}:".toLabel()
setDebug(true)
add(mapFileLabel).left()
add(mapFileSelectBox)
// because SOME people gotta give the hugest names to their maps
.maxWidth((columnWidth - mapFileLabel.prefWidth).coerceAtLeast(120f))
.width(columnWidth * 2 / 3)
.right().row()
add(miniMapWrapper)
.pad(15f)
.colspan(2).center().row()
mapFileSelectBox.onChange { onSelectBoxChange() }
val mapFilesSequence = sequence<FileHandle> {
yieldAll(MapSaver.getMaps().asSequence())
for (modFolder in RulesetCache.values.mapNotNull { it.folderLocation }) {
val mapsFolder = modFolder.child(MapSaver.mapsFolder)
if (mapsFolder.exists())
yieldAll(mapsFolder.list().asSequence())
}
}
// The SelectBox auto displays the text a object.toString(), which on the FileHandle itself includes the folder path.
// So we wrap it in another object with a custom toString()
private class FileHandleWrapper(val fileHandle: FileHandle) {
override fun toString(): String = fileHandle.name()
for (mapFile in mapFilesSequence) {
val mapParameters = try {
MapSaver.loadMapParameters(mapFile)
} catch (_: Exception) {
continue
}
mapWrappers.add(MapWrapper(mapFile, mapParameters))
}
}
fun isNotEmpty() = mapFilesSequence.any()
fun recentlySavedMapExists() = mapFilesSequence.any {
fun isNotEmpty() = mapWrappers.isNotEmpty()
fun recentlySavedMapExists() = mapWrappers.any {
it.fileHandle.lastModified() > System.currentTimeMillis() - 900000
}
fun fillMapFileSelectBox() {
if (!mapFileSelectBox.items.isEmpty) return
val mapFiles = GdxArray<FileHandleWrapper>()
mapFilesSequence
val mapFiles = GdxArray<MapWrapper>()
mapWrappers
.sortedWith(compareBy(UncivGame.Current.settings.getCollatorFromLocale()) { it.toString() })
.sortedByDescending { it.mapParameters.baseRuleset == newGameScreen.gameSetupInfo.gameParameters.baseRuleset }
.forEach { mapFiles.add(it) }
mapFileSelectBox.items = mapFiles
@ -95,24 +106,12 @@ class MapFileSelectTable(
private fun onSelectBoxChange() {
cancelBackgroundJobs()
val mapFile = mapFileSelectBox.selected.fileHandle
val mapParams = try {
MapSaver.loadMapParameters(mapFile)
} catch (ex:Exception){
Log.error("Failed to load map parameters", ex)
Popup(newGameScreen).apply {
addGoodSizedLabel("Could not load map!").row()
if (ex is UncivShowableException)
addGoodSizedLabel(ex.message).row()
addCloseButton()
open()
}
return
}
mapParameters.name = mapFile.name()
newGameScreen.gameSetupInfo.mapFile = mapFile
val mapMods = mapParams.mods.partition { RulesetCache[it]?.modOptions?.isBaseRuleset == true }
val mapMods = mapFileSelectBox.selected.mapParameters.mods.partition { RulesetCache[it]?.modOptions?.isBaseRuleset == true }
newGameScreen.gameSetupInfo.gameParameters.mods = LinkedHashSet(mapMods.second)
newGameScreen.gameSetupInfo.gameParameters.baseRuleset = mapMods.first.firstOrNull() ?: mapParams.baseRuleset
newGameScreen.gameSetupInfo.gameParameters.baseRuleset = mapMods.first.firstOrNull()
?: mapFileSelectBox.selected.mapParameters.baseRuleset
newGameScreen.updateRuleset()
newGameScreen.updateTables()
hideMiniMap()