diff --git a/src/net/torvald/terrarum/ModMgr.kt b/src/net/torvald/terrarum/ModMgr.kt index f46c581fe..a5570feca 100644 --- a/src/net/torvald/terrarum/ModMgr.kt +++ b/src/net/torvald/terrarum/ModMgr.kt @@ -474,6 +474,10 @@ object ModMgr { entryPointClasses.forEach { it.dispose() } } + fun getLoadOrderTextForSavegame(): String { + return loadOrder.map { "$it ${moduleInfo[it]!!.version}" }.joinToString("\n") + } + object GameBlockLoader { init { diff --git a/src/net/torvald/terrarum/modulebasegame/serialise/WorldSavingThread.kt b/src/net/torvald/terrarum/modulebasegame/serialise/WorldSavingThread.kt index 0c5f99141..bf1924aaf 100644 --- a/src/net/torvald/terrarum/modulebasegame/serialise/WorldSavingThread.kt +++ b/src/net/torvald/terrarum/modulebasegame/serialise/WorldSavingThread.kt @@ -160,7 +160,7 @@ class WorldSavingThread( // write loadorder // val loadOrderBa64Writer = ByteArray64Writer(Common.CHARSET) - loadOrderBa64Writer.write(ModMgr.loadOrder.joinToString("\n")) + loadOrderBa64Writer.write(ModMgr.getLoadOrderTextForSavegame()) loadOrderBa64Writer.flush(); loadOrderBa64Writer.close() val loadOrderText = loadOrderBa64Writer.toByteArray64() val loadOrderContents = EntryFile(loadOrderText) diff --git a/src/net/torvald/terrarum/modulebasegame/serialise/WriteActor.kt b/src/net/torvald/terrarum/modulebasegame/serialise/WriteActor.kt index 7335014c6..3c7a41d53 100644 --- a/src/net/torvald/terrarum/modulebasegame/serialise/WriteActor.kt +++ b/src/net/torvald/terrarum/modulebasegame/serialise/WriteActor.kt @@ -116,7 +116,7 @@ object WritePlayer { // write loadorder // val loadOrderBa64Writer = ByteArray64Writer(Common.CHARSET) - loadOrderBa64Writer.write(ModMgr.loadOrder.joinToString("\n")) + loadOrderBa64Writer.write(ModMgr.getLoadOrderTextForSavegame()) loadOrderBa64Writer.flush(); loadOrderBa64Writer.close() val loadOrderText = loadOrderBa64Writer.toByteArray64() val loadOrderContents = EntryFile(loadOrderText) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UILoadManage.kt b/src/net/torvald/terrarum/modulebasegame/ui/UILoadManage.kt index 4116e3d49..1e1016dcb 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UILoadManage.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UILoadManage.kt @@ -13,12 +13,16 @@ import net.torvald.terrarum.CommonResourcePool import net.torvald.terrarum.gamecontroller.TerrarumKeyboardEvent import net.torvald.terrarum.langpack.Lang import net.torvald.terrarum.modulebasegame.serialise.LoadSavegame +import net.torvald.terrarum.savegame.VDFileID import net.torvald.terrarum.savegame.VDFileID.PLAYER_SCREENSHOT +import net.torvald.terrarum.savegame.VirtualDisk +import net.torvald.terrarum.serialise.Common import net.torvald.terrarum.tryDispose import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UIItemTextButton import net.torvald.terrarum.ui.UIItemTextLineInput +import net.torvald.unicode.EMDASH /** * Created by minjaesong on 2023-07-05. @@ -86,9 +90,14 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() { } } private val mainRenameButton = UIItemTextButton(this, - { Lang["MENU_LABEL_RENAME"] }, buttonX1third, buttonRowY, buttonWidth, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true).also { + { if (altDown) Lang["MENU_MODULES"] else Lang["MENU_LABEL_RENAME"] }, buttonX1third, buttonRowY, buttonWidth, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true).also { it.clickOnceListener = { _,_ -> - mode = MODE_RENAME + if (!altDown) { + mode = MODE_RENAME + } + else { + mode = MODE_SHOW_LOAD_ORDER + } } } private val mainBackButton = UIItemTextButton(this, @@ -149,6 +158,13 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() { } } + private val modulesBackButton = UIItemTextButton(this, + { Lang["MENU_LABEL_BACK"] }, buttonXcentre, buttonRowY, buttonWidth, alignment = UIItemTextButton.Companion.Alignment.CENTRE, hasBorder = true).also { + it.clickOnceListener = { _,_ -> + mode = MODE_INIT + } + } + private var mode = 0 private var mainButtons0 = listOf(mainGoButton, mainBackButton, mainRenameButton, mainDeleteButton) @@ -164,6 +180,7 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() { private val MODE_DELETE = 16 // are you sure? private val MODE_RENAME = 32 // show rename dialogue private val MODE_PREV_SAVES = 48 + private val MODE_SHOW_LOAD_ORDER = 64 private val MODE_LOAD = 256 // is needed to make the static loading screen init { @@ -210,6 +227,9 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() { renameButtons.forEach { it.update(delta) } renameInput.update(delta) } + MODE_SHOW_LOAD_ORDER -> { + modulesBackButton.update(delta) + } } } @@ -223,9 +243,13 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() { private var loadFiredFrameCounter = 0 + private var selectedRevision = 0 // 0: most recent, 1: second most recent, etc. + override fun renderUI(batch: SpriteBatch, camera: OrthographicCamera) { - val buttonYdelta = (full.titleTopGradEnd) - full.playerButtonSelected!!.posY - full.playerButtonSelected!!.render(batch, camera, 0, buttonYdelta) + if (mode != MODE_SHOW_LOAD_ORDER) { + val buttonYdelta = (full.titleTopGradEnd) - full.playerButtonSelected!!.posY + full.playerButtonSelected!!.render(batch, camera, 0, buttonYdelta) + } when (mode) { MODE_INIT -> { @@ -266,9 +290,55 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() { StaticLoadScreenSubstitute(batch) if (loadFiredFrameCounter == 2) LoadSavegame(full.loadManageSelectedGame) } + MODE_SHOW_LOAD_ORDER -> { + Toolkit.drawTextCentered(batch, App.fontUITitle, Lang["MENU_MODULES"], Toolkit.drawWidth, 0, full.titleTopGradEnd) + + val playerName = App.savegamePlayersName[full.playerButtonSelected!!.playerUUID] ?: "Player" + + val loadOrderPlayer = + App.savegamePlayers[full.playerButtonSelected!!.playerUUID]!!.files[selectedRevision].getFile( + VDFileID.LOADORDER + )?.getContent()?.toByteArray()?.toString(Common.CHARSET)?.split('\n')?.let { + it.mapIndexed { index, s -> "${(index+1).toString().padStart(it.size.fastLen())}. $s" } + } ?: listOf("$EMDASH") + val loadOrderWorld = + App.savegameWorlds[full.playerButtonSelected!!.worldUUID]!!.files[selectedRevision].getFile( + VDFileID.LOADORDER + )?.getContent()?.toByteArray()?.toString(Common.CHARSET)?.split('\n')?.let { + it.mapIndexed { index, s -> "${(index+1).toString().padStart(it.size.fastLen())}. $s" } + } ?: listOf("$EMDASH") + + Toolkit.drawTextCentered(batch, App.fontGame, playerName, modulesTextboxW, playerModTextboxX, full.titleTopGradEnd + 32) + Toolkit.drawTextCentered(batch, App.fontGame, Lang["MENU_LABEL_WORLD"], modulesTextboxW, worldModTextboxX, full.titleTopGradEnd + 32) + + val playerTBW = loadOrderPlayer.maxOfOrNull { App.fontGame.getWidth(it) } ?: 0 + val worldTBW = loadOrderWorld.maxOfOrNull { App.fontGame.getWidth(it) } ?: 0 + + val px = playerModTextboxX + (modulesTextboxW - playerTBW) / 2 + val wx = worldModTextboxX + (modulesTextboxW - worldTBW) / 2 + + // TODO box background + + loadOrderPlayer.forEachIndexed { index, s -> + App.fontGame.draw(batch, s, px, full.titleTopGradEnd + 64 + App.fontGame.lineHeight.toInt() * index) + } + loadOrderWorld.forEachIndexed { index, s -> + App.fontGame.draw(batch, s, wx, full.titleTopGradEnd + 64 + App.fontGame.lineHeight.toInt() * index) + } + + modulesBackButton.render(batch, camera) + } } } + private val modulesTextboxW = 280 + private val boxTextMargin = 3 + private val listGap = 10 + private val playerModTextboxX = Toolkit.drawWidth / 2 - (2 * boxTextMargin + listGap) - modulesTextboxW + private val worldModTextboxX = Toolkit.drawWidth / 2 + (2 * boxTextMargin + listGap) + + + override fun dispose() { screencap?.texture?.tryDispose() } @@ -285,6 +355,9 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() { renameInput.touchDown(screenX, screenY, pointer, button) renameButtons.forEach { it.touchDown(screenX, screenY, pointer, button) } } + MODE_SHOW_LOAD_ORDER -> { + modulesBackButton.touchDown(screenX, screenY, pointer, button) + } } return true @@ -302,9 +375,26 @@ class UILoadManage(val full: UILoadSavegame) : UICanvas() { renameInput.touchUp(screenX, screenY, pointer, button) renameButtons.forEach { it.touchUp(screenX, screenY, pointer, button) } } + MODE_SHOW_LOAD_ORDER -> { + modulesBackButton.touchUp(screenX, screenY, pointer, button) + } } return true } + private fun Int.fastLen(): Int { + return if (this < 0) 1 + this.unaryMinus().fastLen() + else if (this < 10) 1 + else if (this < 100) 2 + else if (this < 1000) 3 + else if (this < 10000) 4 + else if (this < 100000) 5 + else if (this < 1000000) 6 + else if (this < 10000000) 7 + else if (this < 100000000) 8 + else if (this < 1000000000) 9 + else 10 + } + } \ No newline at end of file