From 70517b9c3dee72ed6f32b36fa4cd52ff394a7f60 Mon Sep 17 00:00:00 2001 From: SomeTroglodyte <63000004+SomeTroglodyte@users.noreply.github.com> Date: Sat, 5 Mar 2022 19:04:55 +0100 Subject: [PATCH] Sort maps & accelerate playing a newly edited map (#6267) * Sort map file lists * Pre-select custom map if saved within last 15min --- .../ui/mapeditor/SaveAndLoadMapScreen.kt | 15 +++---- .../unciv/ui/newgamescreen/MapOptionsTable.kt | 42 ++++++++++++------- 2 files changed, 34 insertions(+), 23 deletions(-) diff --git a/core/src/com/unciv/ui/mapeditor/SaveAndLoadMapScreen.kt b/core/src/com/unciv/ui/mapeditor/SaveAndLoadMapScreen.kt index b94ba4d8fd..2557f7a22b 100644 --- a/core/src/com/unciv/ui/mapeditor/SaveAndLoadMapScreen.kt +++ b/core/src/com/unciv/ui/mapeditor/SaveAndLoadMapScreen.kt @@ -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.TextButton import com.badlogic.gdx.scenes.scene2d.ui.TextField +import com.unciv.UncivGame import com.unciv.logic.MapSaver import com.unciv.logic.UncivShowableException 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.ui.pickerscreens.PickerScreen import com.unciv.ui.utils.* -import kotlin.concurrent.thread import com.unciv.ui.utils.AutoScrollPane as ScrollPane class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousScreen: BaseScreen) @@ -66,15 +66,15 @@ class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousSc } try { val map = MapSaver.loadMap(chosenMap!!, checkSizeErrors = false) - + val missingMods = map.mapParameters.mods.filter { it !in RulesetCache }.toMutableList() // [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 } if (newBaseRuleset != null) map.mapParameters.baseRuleset = newBaseRuleset // - + if (map.mapParameters.baseRuleset !in RulesetCache) missingMods += map.mapParameters.baseRuleset - + if (missingMods.isNotEmpty()) { postCrashHandlingRunnable { needPopup = false @@ -90,7 +90,7 @@ class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousSc map.mapParameters.baseRuleset = modBaseRuleset map.mapParameters.mods -= modBaseRuleset } - + game.setScreen(MapEditorScreen(map)) dispose() } catch (ex: Throwable) { @@ -184,7 +184,8 @@ class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousSc deleteButton.setText("Delete map".tr()) 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) existingMapButton.onClick { for (cell in mapsTable.cells) cell.actor.color = Color.WHITE @@ -194,7 +195,7 @@ class SaveAndLoadMapScreen(mapToSave: TileMap?, save:Boolean = false, previousSc chosenMap = map mapNameTextField.text = map.name() mapNameTextField.setSelection(Int.MAX_VALUE,Int.MAX_VALUE) // sets caret to end of text - + deleteButton.enable() deleteButton.color = Color.RED } diff --git a/core/src/com/unciv/ui/newgamescreen/MapOptionsTable.kt b/core/src/com/unciv/ui/newgamescreen/MapOptionsTable.kt index 13f8d9828d..ce9d3b6890 100644 --- a/core/src/com/unciv/ui/newgamescreen/MapOptionsTable.kt +++ b/core/src/com/unciv/ui/newgamescreen/MapOptionsTable.kt @@ -1,10 +1,10 @@ package com.unciv.ui.newgamescreen -import com.badlogic.gdx.Gdx import com.badlogic.gdx.files.FileHandle import com.badlogic.gdx.scenes.scene2d.ui.SelectBox import com.badlogic.gdx.scenes.scene2d.ui.Table import com.badlogic.gdx.utils.Array +import com.unciv.UncivGame import com.unciv.logic.MapSaver import com.unciv.logic.UncivShowableException import com.unciv.logic.map.MapType @@ -24,14 +24,14 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen): Table() { lateinit var mapTypeSelectBox: TranslatedSelectBox private val mapFileSelectBox = createMapFileSelectBox() - private val mapFilesSequence = sequence { - yieldAll(MapSaver.getMaps().asSequence().map { FileHandleWrapper(it) }) + private val mapFilesSequence = sequence { + yieldAll(MapSaver.getMaps().asSequence()) for (modFolder in RulesetCache.values.mapNotNull { it.folderLocation }) { val mapsFolder = modFolder.child("maps") if (mapsFolder.exists()) - yieldAll(mapsFolder.list().asSequence().map { FileHandleWrapper(it) }) + yieldAll(mapsFolder.list().asSequence()) } - } + }.map { FileHandleWrapper(it) } init { //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() } + // 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 updateOnMapTypeChange() @@ -110,20 +114,26 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen): Table() { } return mapFileSelectBox } - + private fun fillMapFileSelectBox() { if (!mapFileSelectBox.items.isEmpty) return val mapFiles = Array() - mapFilesSequence.forEach { mapFiles.add(it) } + mapFilesSequence + .sortedWith(compareBy(UncivGame.Current.settings.getCollatorFromLocale()) { it.toString() }) + .forEach { mapFiles.add(it) } mapFileSelectBox.items = mapFiles - val selectedItem = mapFiles.firstOrNull { it.fileHandle.name() == mapParameters.name } - if (selectedItem != null) { - mapFileSelectBox.selected = selectedItem - newGameScreen.gameSetupInfo.mapFile = mapFileSelectBox.selected.fileHandle - } else if (!mapFiles.isEmpty) { - mapFileSelectBox.selected = mapFiles.first() - newGameScreen.gameSetupInfo.mapFile = mapFileSelectBox.selected.fileHandle - } + + // Pre-select: a) map saved within last 15min or b) map named in mapParameters or c) alphabetically first + // This is a kludge - the better way would be to have a "play this map now" menu button in the editor + // (which would ideally not even require a save file - which makes implementation non-trivial) + val selectedItem = + mapFiles.maxByOrNull { it.fileHandle.lastModified() } + ?.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. @@ -131,5 +141,5 @@ class MapOptionsTable(private val newGameScreen: NewGameScreen): Table() { class FileHandleWrapper(val fileHandle: FileHandle) { override fun toString(): String = fileHandle.name() } - + }