Sort maps & accelerate playing a newly edited map (#6267)

* Sort map file lists

* Pre-select custom map if saved within last 15min
This commit is contained in:
SomeTroglodyte
2022-03-05 19:04:55 +01:00
committed by GitHub
parent 617f801558
commit 70517b9c3d
2 changed files with 34 additions and 23 deletions

View File

@ -6,6 +6,7 @@ import com.badlogic.gdx.graphics.Color
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.scenes.scene2d.ui.TextField import com.badlogic.gdx.scenes.scene2d.ui.TextField
import com.unciv.UncivGame
import com.unciv.logic.MapSaver import com.unciv.logic.MapSaver
import com.unciv.logic.UncivShowableException import com.unciv.logic.UncivShowableException
import com.unciv.logic.map.MapType import com.unciv.logic.map.MapType
@ -14,7 +15,6 @@ import com.unciv.models.ruleset.RulesetCache
import com.unciv.models.translations.tr import com.unciv.models.translations.tr
import com.unciv.ui.pickerscreens.PickerScreen import com.unciv.ui.pickerscreens.PickerScreen
import com.unciv.ui.utils.* import com.unciv.ui.utils.*
import kotlin.concurrent.thread
import com.unciv.ui.utils.AutoScrollPane as ScrollPane import com.unciv.ui.utils.AutoScrollPane as ScrollPane
class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousScreen: BaseScreen) class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousScreen: BaseScreen)
@ -66,15 +66,15 @@ class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousSc
} }
try { try {
val map = MapSaver.loadMap(chosenMap!!, checkSizeErrors = false) val map = MapSaver.loadMap(chosenMap!!, checkSizeErrors = false)
val missingMods = map.mapParameters.mods.filter { it !in RulesetCache }.toMutableList() val missingMods = map.mapParameters.mods.filter { it !in RulesetCache }.toMutableList()
// [TEMPORARY] conversion of old maps with a base ruleset contained in the mods // [TEMPORARY] conversion of old maps with a base ruleset contained in the mods
val newBaseRuleset = map.mapParameters.mods.filter { it !in missingMods }.firstOrNull { RulesetCache[it]!!.modOptions.isBaseRuleset } val newBaseRuleset = map.mapParameters.mods.filter { it !in missingMods }.firstOrNull { RulesetCache[it]!!.modOptions.isBaseRuleset }
if (newBaseRuleset != null) map.mapParameters.baseRuleset = newBaseRuleset if (newBaseRuleset != null) map.mapParameters.baseRuleset = newBaseRuleset
// //
if (map.mapParameters.baseRuleset !in RulesetCache) missingMods += map.mapParameters.baseRuleset if (map.mapParameters.baseRuleset !in RulesetCache) missingMods += map.mapParameters.baseRuleset
if (missingMods.isNotEmpty()) { if (missingMods.isNotEmpty()) {
postCrashHandlingRunnable { postCrashHandlingRunnable {
needPopup = false needPopup = false
@ -90,7 +90,7 @@ class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousSc
map.mapParameters.baseRuleset = modBaseRuleset map.mapParameters.baseRuleset = modBaseRuleset
map.mapParameters.mods -= modBaseRuleset map.mapParameters.mods -= modBaseRuleset
} }
game.setScreen(MapEditorScreen(map)) game.setScreen(MapEditorScreen(map))
dispose() dispose()
} catch (ex: Throwable) { } catch (ex: Throwable) {
@ -184,7 +184,8 @@ class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousSc
deleteButton.setText("Delete map".tr()) deleteButton.setText("Delete map".tr())
mapsTable.clear() mapsTable.clear()
for (map in MapSaver.getMaps()) { val collator = UncivGame.Current.settings.getCollatorFromLocale()
for (map in MapSaver.getMaps().sortedWith(compareBy(collator) { it.name() })) {
val existingMapButton = TextButton(map.name(), skin) val existingMapButton = TextButton(map.name(), skin)
existingMapButton.onClick { existingMapButton.onClick {
for (cell in mapsTable.cells) cell.actor.color = Color.WHITE for (cell in mapsTable.cells) cell.actor.color = Color.WHITE
@ -194,7 +195,7 @@ class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousSc
chosenMap = map chosenMap = map
mapNameTextField.text = map.name() mapNameTextField.text = map.name()
mapNameTextField.setSelection(Int.MAX_VALUE,Int.MAX_VALUE) // sets caret to end of text mapNameTextField.setSelection(Int.MAX_VALUE,Int.MAX_VALUE) // sets caret to end of text
deleteButton.enable() deleteButton.enable()
deleteButton.color = Color.RED deleteButton.color = Color.RED
} }

View File

@ -1,10 +1,10 @@
package com.unciv.ui.newgamescreen package com.unciv.ui.newgamescreen
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.files.FileHandle
import com.badlogic.gdx.scenes.scene2d.ui.SelectBox import com.badlogic.gdx.scenes.scene2d.ui.SelectBox
import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.utils.Array import com.badlogic.gdx.utils.Array
import com.unciv.UncivGame
import com.unciv.logic.MapSaver import com.unciv.logic.MapSaver
import com.unciv.logic.UncivShowableException import com.unciv.logic.UncivShowableException
import com.unciv.logic.map.MapType import com.unciv.logic.map.MapType
@ -24,14 +24,14 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen): Table() {
lateinit var mapTypeSelectBox: TranslatedSelectBox lateinit var mapTypeSelectBox: TranslatedSelectBox
private val mapFileSelectBox = createMapFileSelectBox() private val mapFileSelectBox = createMapFileSelectBox()
private val mapFilesSequence = sequence<FileHandleWrapper> { private val mapFilesSequence = sequence<FileHandle> {
yieldAll(MapSaver.getMaps().asSequence().map { FileHandleWrapper(it) }) yieldAll(MapSaver.getMaps().asSequence())
for (modFolder in RulesetCache.values.mapNotNull { it.folderLocation }) { for (modFolder in RulesetCache.values.mapNotNull { it.folderLocation }) {
val mapsFolder = modFolder.child("maps") val mapsFolder = modFolder.child("maps")
if (mapsFolder.exists()) if (mapsFolder.exists())
yieldAll(mapsFolder.list().asSequence().map { FileHandleWrapper(it) }) yieldAll(mapsFolder.list().asSequence())
} }
} }.map { FileHandleWrapper(it) }
init { init {
//defaults().pad(5f) - each nested table having the same can give 'stairs' effects, //defaults().pad(5f) - each nested table having the same can give 'stairs' effects,
@ -71,6 +71,10 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen): Table() {
newGameScreen.updateTables() newGameScreen.updateTables()
} }
// Pre-select custom if any map saved within last 15 minutes
if (mapFilesSequence.any { it.fileHandle.lastModified() > System.currentTimeMillis() - 900000 })
mapTypeSelectBox.selected = TranslatedSelectBox.TranslatedString(MapType.custom)
// activate once, so when we had a file map before we'll have the right things set for another one // activate once, so when we had a file map before we'll have the right things set for another one
updateOnMapTypeChange() updateOnMapTypeChange()
@ -110,20 +114,26 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen): Table() {
} }
return mapFileSelectBox return mapFileSelectBox
} }
private fun fillMapFileSelectBox() { private fun fillMapFileSelectBox() {
if (!mapFileSelectBox.items.isEmpty) return if (!mapFileSelectBox.items.isEmpty) return
val mapFiles = Array<FileHandleWrapper>() val mapFiles = Array<FileHandleWrapper>()
mapFilesSequence.forEach { mapFiles.add(it) } mapFilesSequence
.sortedWith(compareBy(UncivGame.Current.settings.getCollatorFromLocale()) { it.toString() })
.forEach { mapFiles.add(it) }
mapFileSelectBox.items = mapFiles mapFileSelectBox.items = mapFiles
val selectedItem = mapFiles.firstOrNull { it.fileHandle.name() == mapParameters.name }
if (selectedItem != null) { // Pre-select: a) map saved within last 15min or b) map named in mapParameters or c) alphabetically first
mapFileSelectBox.selected = selectedItem // This is a kludge - the better way would be to have a "play this map now" menu button in the editor
newGameScreen.gameSetupInfo.mapFile = mapFileSelectBox.selected.fileHandle // (which would ideally not even require a save file - which makes implementation non-trivial)
} else if (!mapFiles.isEmpty) { val selectedItem =
mapFileSelectBox.selected = mapFiles.first() mapFiles.maxByOrNull { it.fileHandle.lastModified() }
newGameScreen.gameSetupInfo.mapFile = mapFileSelectBox.selected.fileHandle ?.takeIf { it.fileHandle.lastModified() > System.currentTimeMillis() - 900000 }
} ?: mapFiles.firstOrNull { it.fileHandle.name() == mapParameters.name }
?: mapFiles.firstOrNull()
?: return
mapFileSelectBox.selected = selectedItem
newGameScreen.gameSetupInfo.mapFile = selectedItem.fileHandle
} }
// The SelectBox auto displays the text a object.toString(), which on the FileHandle itself includes the folder path. // The SelectBox auto displays the text a object.toString(), which on the FileHandle itself includes the folder path.
@ -131,5 +141,5 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen): Table() {
class FileHandleWrapper(val fileHandle: FileHandle) { class FileHandleWrapper(val fileHandle: FileHandle) {
override fun toString(): String = fileHandle.name() override fun toString(): String = fileHandle.name()
} }
} }