diff --git a/src/net/torvald/terrarum/TitleScreen.kt b/src/net/torvald/terrarum/TitleScreen.kt index 7f9fc0fb6..1520e6621 100644 --- a/src/net/torvald/terrarum/TitleScreen.kt +++ b/src/net/torvald/terrarum/TitleScreen.kt @@ -155,7 +155,7 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { cameraPlayer = CameraPlayer(demoWorld, cameraAI) - demoWorld.worldTime.timeDelta = 0//100 + demoWorld.worldTime.timeDelta = 100 IngameRenderer.setRenderedWorld(demoWorld) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt new file mode 100644 index 000000000..a8cf89956 --- /dev/null +++ b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt @@ -0,0 +1,151 @@ +package net.torvald.terrarum.modulebasegame.ui + +import com.badlogic.gdx.graphics.Camera +import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.Pixmap +import com.badlogic.gdx.graphics.Texture +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.g2d.TextureRegion +import net.torvald.terrarum.* +import net.torvald.terrarum.App.printdbg +import net.torvald.terrarum.langpack.Lang +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.ByteArray64InputStream +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VDUtil +import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.VirtualDisk +import net.torvald.terrarum.serialise.Common +import net.torvald.terrarum.serialise.LoadSavegame +import net.torvald.terrarum.serialise.ReadMeta +import net.torvald.terrarum.ui.Toolkit +import net.torvald.terrarum.ui.UICanvas +import net.torvald.terrarum.ui.UIItem +import java.io.File +import java.util.zip.GZIPInputStream + +/** + * Created by minjaesong on 2021-09-09. + */ +class UILoadDemoSavefiles : UICanvas() { + + override var width: Int + get() = App.scr.width + set(value) {} + override var height: Int + get() = App.scr.height + set(value) {} + override var openCloseTime: Second = 0f + + // read savegames + init { + File(App.defaultSaveDir).listFiles().forEachIndexed { index, file -> + printdbg(this, "save file: ${file.absolutePath}") + + try { + val x = (width - UIItemDemoSaveCells.WIDTH) / 2 + val y = 144 + (24 + UIItemDemoSaveCells.HEIGHT) * index + val disk = VDUtil.readDiskArchive(file, charset = Common.CHARSET) + addUIitem(UIItemDemoSaveCells(this, x, y, disk)) + } + catch (e: Throwable) { + e.printStackTrace() + } + } + } + + override fun updateUI(delta: Float) { + uiItems.forEach { it.update(delta) } + } + + override fun renderUI(batch: SpriteBatch, camera: Camera) { + uiItems.forEach { it.render(batch, camera) } + + val loadGameTitleStr = Lang["MENU_IO_LOAD_GAME"] + App.fontGame.draw(batch, loadGameTitleStr, (width - App.fontGame.getWidth(loadGameTitleStr)).div(2).toFloat(), 62f) + } + + override fun doOpening(delta: Float) { + } + + override fun doClosing(delta: Float) { + } + + override fun endOpening(delta: Float) { + } + + override fun endClosing(delta: Float) { + } + + override fun dispose() {} +} + +class UIItemDemoSaveCells( + parent: UILoadDemoSavefiles, + initialX: Int, + initialY: Int, + val disk: VirtualDisk) : UIItem(parent, initialX, initialY) { + + companion object { + const val WIDTH = 480 + const val HEIGHT = 160 + } + + override val width: Int = WIDTH + override val height: Int = HEIGHT + + private lateinit var thumbPixmap: Pixmap + private lateinit var thumb: TextureRegion + private val grad = CommonResourcePool.getAsTexture("title_halfgrad") + + private val meta = ReadMeta(disk) + + private val x = initialX.toFloat() + private val y = initialY.toFloat() + + init { + try { + // load a thumbnail + val zippedTga = VDUtil.getAsNormalFile(disk, -2).getContent() + val gzin = GZIPInputStream(ByteArray64InputStream(zippedTga)) + val tgaFileContents = gzin.readAllBytes(); gzin.close() + + thumbPixmap = Pixmap(tgaFileContents, 0, tgaFileContents.size) + val thumbTex = Texture(thumbPixmap) + thumbTex.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear) + thumb = TextureRegion(thumbTex) + thumb.setRegion(0, thumbTex.height / 4, thumbTex.width, thumbTex.height / 2) + } + catch (e: NullPointerException) { + // use stock texture + } + + + } + + override var clickOnceListener: ((Int, Int, Int) -> Unit)? = { _: Int, _: Int, _: Int -> + LoadSavegame(disk) + } + + override fun render(batch: SpriteBatch, camera: Camera) { + batch.color = Color.WHITE + + // draw thumbnail + blendNormal(batch) + batch.draw(thumb, x, y + height, width.toFloat(), -height.toFloat()) + // draw gradient + blendMul(batch) + batch.draw(grad, x + width, y, -width.toFloat(), height.toFloat()) + // draw timestamp + blendNormal(batch) + val timestamp = "${meta.lastplay_t}" + val tlen = App.fontGame.getWidth(timestamp) + App.fontGame.draw(batch, timestamp, posX + (width - tlen) - 5f, posY + height - 23f) + + + super.render(batch, camera) + } + + override fun dispose() { + thumb.texture.dispose() + thumbPixmap.dispose() + } + +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UITitleRemoConYaml.kt b/src/net/torvald/terrarum/modulebasegame/ui/UITitleRemoConYaml.kt index 06d2bad98..0402fefa7 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UITitleRemoConYaml.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UITitleRemoConYaml.kt @@ -15,7 +15,8 @@ object UITitleRemoConYaml { val menus = """ - MENU_LABEL_CONTINUE - MENU_LABEL_NEW_GAME : net.torvald.terrarum.modulebasegame.ui.UIProxyNewRandomGame - - MENU_IO_LOAD + - MENU_IO_LOAD : net.torvald.terrarum.modulebasegame.ui.UILoadDemoSavefiles + - MENU_LABEL_RETURN - MENU_OPTIONS - MENU_OPTIONS_GRAPHICS - MENU_OPTIONS_CONTROLS diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index 69b1ef6fa..d27da653a 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -137,14 +137,14 @@ object LoadSavegame { private fun getFileReader(disk: VirtualDisk, id: Int): Reader = ByteArray64Reader(getFileBytes(disk, id), Common.CHARSET) operator fun invoke(disk: VirtualDisk) { - val ingame = TerrarumIngame(App.batch) + val newIngame = TerrarumIngame(App.batch) // NOTE: do NOT set ingame.actorNowPlaying as one read directly from the disk; // you'll inevitably read the player actor twice, and they're separate instances of the player! val meta = ReadMeta(disk) val currentWorld = (ReadActor(getFileReader(disk, Terrarum.PLAYER_REF_ID)) as IngamePlayer).worldCurrentlyPlaying val world = ReadWorld(getFileReader(disk, currentWorld)) - val actors = world.actors.map { ReadActor(getFileReader(disk, it)) } + val actors = world.actors.distinct().map { ReadActor(getFileReader(disk, it)) } // val block = Common.jsoner.fromJson(BlockCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -16))) val item = Common.jsoner.fromJson(ItemCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -17))) // val wire = Common.jsoner.fromJson(WireCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -18))) @@ -153,25 +153,26 @@ object LoadSavegame { val apocryphas = Common.jsoner.fromJson(Apocryphas.javaClass, getUnzipInputStream(getFileBytes(disk, -1024))) val worldParam = TerrarumIngame.Codices(meta, item, apocryphas) - ingame.world = world - ingame.gameLoadInfoPayload = worldParam - ingame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM - ingame.savegameArchive = disk - actors.forEach { ingame.addNewActor(it) } + newIngame.world = world + newIngame.gameLoadInfoPayload = worldParam + newIngame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM + newIngame.savegameArchive = disk + + actors.forEach { newIngame.addNewActor(it) } // by doing this, whatever the "possession" the player had will be broken by the game load - ingame.actorNowPlaying = ingame.getActorByID(Terrarum.PLAYER_REF_ID) as IngamePlayer + newIngame.actorNowPlaying = newIngame.getActorByID(Terrarum.PLAYER_REF_ID) as IngamePlayer // ModMgr.reloadModules() - Terrarum.setCurrentIngameInstance(ingame) - App.setScreen(ingame) + Terrarum.setCurrentIngameInstance(newIngame) + App.setScreen(newIngame) Echo("${ccW}Savegame loaded from $ccY${disk.getDiskNameString(Common.CHARSET)}") printdbg(this, "Savegame loaded from ${disk.getDiskNameString(Common.CHARSET)}") - Terrarum.ingame!!.consoleHandler.setAsOpen() +// Terrarum.ingame!!.consoleHandler.setAsOpen() } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/serialise/WriteWorld.kt b/src/net/torvald/terrarum/serialise/WriteWorld.kt index c86903e49..49ccaef59 100644 --- a/src/net/torvald/terrarum/serialise/WriteWorld.kt +++ b/src/net/torvald/terrarum/serialise/WriteWorld.kt @@ -3,6 +3,7 @@ package net.torvald.terrarum.serialise import net.torvald.terrarum.CommonResourcePool import net.torvald.terrarum.ReferencingRanges import net.torvald.terrarum.gameactors.Actor +import net.torvald.terrarum.gameactors.ActorID import net.torvald.terrarum.gameactors.BlockMarkerActor import net.torvald.terrarum.gameworld.GameWorld import net.torvald.terrarum.modulebasegame.TerrarumIngame @@ -25,8 +26,13 @@ object WriteWorld { val world = ingame.world world.genver = Common.GENVER world.comp = Common.COMP_GZIP - ingame.actorContainerActive.filter { actorAcceptable(it) }.forEach { world.actors.add(it.referenceID) } - ingame.actorContainerInactive.filter { actorAcceptable(it) }.forEach { world.actors.add(it.referenceID) } + + val actorIDbuf = ArrayList() + ingame.actorContainerActive.filter { actorAcceptable(it) }.forEach { actorIDbuf.add(it.referenceID) } + ingame.actorContainerInactive.filter { actorAcceptable(it) }.forEach { actorIDbuf.add(it.referenceID) } + + world.actors.clear() + world.actors.addAll(actorIDbuf.sorted().distinct()) return world }