diff --git a/src/net/torvald/terrarum/IngameInstance.kt b/src/net/torvald/terrarum/IngameInstance.kt index 044ff8751..66342f1c9 100644 --- a/src/net/torvald/terrarum/IngameInstance.kt +++ b/src/net/torvald/terrarum/IngameInstance.kt @@ -13,8 +13,8 @@ import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid import net.torvald.terrarum.modulebasegame.ui.Notification import net.torvald.terrarum.modulebasegame.ui.UITooltip -import net.torvald.terrarum.tvda.VirtualDisk import net.torvald.terrarum.realestate.LandUtil +import net.torvald.terrarum.tvda.VirtualDisk import net.torvald.terrarum.ui.ConsoleWindow import net.torvald.util.SortedArrayList import org.khelekore.prtree.* @@ -120,6 +120,10 @@ open class IngameInstance(val batch: SpriteBatch) : Screen { val modifiedChunks = Array(16) { HashSet() } + internal var creationTime = App.getTIME_T() // cumulative value for the savegame + internal var lastPlayTime = App.getTIME_T() // cumulative value for the savegame + internal var totalPlayTime = 0L // cumulative value for the savegame + var loadedTime_t = App.getTIME_T() protected set diff --git a/src/net/torvald/terrarum/TitleScreen.kt b/src/net/torvald/terrarum/TitleScreen.kt index 760b0411b..bb4505684 100644 --- a/src/net/torvald/terrarum/TitleScreen.kt +++ b/src/net/torvald/terrarum/TitleScreen.kt @@ -131,7 +131,7 @@ class TitleScreen(batch: SpriteBatch) : IngameInstance(batch) { printdbg(this, "Demo world loaded") } catch (e: IOException) { - demoWorld = GameWorld(1, LandUtil.CHUNK_W, LandUtil.CHUNK_H, 0L, 0L, 0) + demoWorld = GameWorld(1, LandUtil.CHUNK_W, LandUtil.CHUNK_H, 0L, 0L) printdbg(this, "Demo world not found, using empty world") } diff --git a/src/net/torvald/terrarum/gameworld/GameWorld.kt b/src/net/torvald/terrarum/gameworld/GameWorld.kt index 56416aff0..ce84ddfab 100644 --- a/src/net/torvald/terrarum/gameworld/GameWorld.kt +++ b/src/net/torvald/terrarum/gameworld/GameWorld.kt @@ -43,12 +43,15 @@ open class GameWorld() : Disposable { var width: Int = 999; private set var height: Int = 999; private set - var creationTime: Long = App.getTIME_T() + /** Creation time for this world, NOT the entire savegame */ + internal var creationTime: Long = App.getTIME_T() internal set - var lastPlayTime: Long = App.getTIME_T() + /** Creation time for this world, NOT the entire savegame */ + internal var lastPlayTime: Long = App.getTIME_T() internal set // there's a case of save-and-continue-playing - var totalPlayTime: Long = 0 - internal set + /** Creation time for this world, NOT the entire savegame */ + internal var totalPlayTime = 0L // cumulative value for this very world + //layers @Transient lateinit open var layerWall: BlockLayer @@ -116,7 +119,7 @@ open class GameWorld() : Disposable { /** * Create new world */ - constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long, totalPlayTime: Long): this() { + constructor(worldIndex: Int, width: Int, height: Int, creationTIME_T: Long, lastPlayTIME_T: Long): this() { if (width <= 0 || height <= 0) throw IllegalArgumentException("Non-positive width/height: ($width, $height)") this.worldIndex = worldIndex @@ -138,7 +141,6 @@ open class GameWorld() : Disposable { creationTime = creationTIME_T lastPlayTime = lastPlayTIME_T - this.totalPlayTime = totalPlayTime App.tileMaker.tags.forEach { @@ -668,7 +670,7 @@ open class GameWorld() : Disposable { fun makeNullWorld(): GameWorld { if (nullWorldInstance == null) - nullWorldInstance = GameWorld(1, 1, 1, 0, 0, 0) + nullWorldInstance = GameWorld(1, 1, 1, 0, 0) return nullWorldInstance!! } diff --git a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt index f73f520d8..d5827f272 100644 --- a/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/BuildingMaker.kt @@ -65,7 +65,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) { private val timeNow = System.currentTimeMillis() / 1000 - val gameWorld = GameWorld(1, 1024, 256, timeNow, timeNow, 0) + val gameWorld = GameWorld(1, 1024, 256, timeNow, timeNow) init { // ghetto world for building diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 54b33369b..5eb82ed6a 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -295,7 +295,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { // init map as chosen size val timeNow = App.getTIME_T() - world = GameWorld(1, worldParams.width, worldParams.height, timeNow, timeNow, 0) // new game, so the creation time is right now + world = GameWorld(1, worldParams.width, worldParams.height, timeNow, timeNow) // new game, so the creation time is right now world.generatorSeed = worldParams.worldGenSeed gameworldIndices.add(world.worldIndex) world.extraFields["basegame.economy"] = GameEconomy() diff --git a/src/net/torvald/terrarum/modulebasegame/console/ExportMeta.kt b/src/net/torvald/terrarum/modulebasegame/console/ExportMeta.kt index 7d024bef7..ddcc3453e 100644 --- a/src/net/torvald/terrarum/modulebasegame/console/ExportMeta.kt +++ b/src/net/torvald/terrarum/modulebasegame/console/ExportMeta.kt @@ -18,8 +18,7 @@ import java.io.IOException object ExportMeta : ConsoleCommand { override fun execute(args: Array) { try { - val currentPlayTime_t = App.getTIME_T() - ingame!!.loadedTime_t - val str = WriteMeta(ingame!! as TerrarumIngame, currentPlayTime_t) + val str = WriteMeta(ingame!! as TerrarumIngame, App.getTIME_T()) val writer = java.io.FileWriter(App.defaultDir + "/Exports/savegame.json", false) writer.write(str) writer.close() @@ -40,7 +39,7 @@ object ExportWorld : ConsoleCommand { override fun execute(args: Array) { if (args.size == 2) { try { - val str = WriteWorld(ingame!! as TerrarumIngame) + val str = WriteWorld(ingame!! as TerrarumIngame, App.getTIME_T()) val writer = java.io.FileWriter(App.defaultDir + "/Exports/${args[1]}.json", false) writer.write(str) writer.close() diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt index 6645f923e..2f48c1ab5 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UILoadDemoSavefiles.kt @@ -45,8 +45,9 @@ class UILoadDemoSavefiles : UICanvas() { } catch (e: Throwable) { e.printStackTrace() + null } - }.sortedByDescending { (it as VirtualDisk).entries[0]!!.modificationDate }.forEachIndexed { index, disk -> + }.filter { it != null }.sortedByDescending { (it as VirtualDisk).entries[0]!!.modificationDate }.forEachIndexed { index, disk -> val x = (width - UIItemDemoSaveCells.WIDTH) / 2 val y = 144 + (24 + UIItemDemoSaveCells.HEIGHT) * index addUIitem(UIItemDemoSaveCells(this, x, y, disk as VirtualDisk)) @@ -102,9 +103,21 @@ class UIItemDemoSaveCells( private val x = initialX.toFloat() private val y = initialY.toFloat() + private fun parseDuration(seconds: Long): String { + val s = seconds % 60 + val m = (seconds / 60) % 60 + val h = (seconds / 3600) % 24 + val d = seconds / 86400 + return if (d == 0L) + "${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s" + else + "${d}d${h.toString().padStart(2,'0')}h${m.toString().padStart(2,'0')}m${s.toString().padStart(2,'0')}s" + } + private val lastPlayedTimestamp = Instant.ofEpochSecond(meta.lastplay_t) .atZone(TimeZone.getDefault().toZoneId()) - .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + .format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")) + + "/${parseDuration(meta.playtime_t)}" init { try { diff --git a/src/net/torvald/terrarum/serialise/WriteMeta.kt b/src/net/torvald/terrarum/serialise/WriteMeta.kt index b0c9858e2..a76771ef9 100644 --- a/src/net/torvald/terrarum/serialise/WriteMeta.kt +++ b/src/net/torvald/terrarum/serialise/WriteMeta.kt @@ -1,5 +1,6 @@ package net.torvald.terrarum.serialise +import net.torvald.terrarum.App import net.torvald.terrarum.ModMgr import net.torvald.terrarum.gameactors.ActorID import net.torvald.terrarum.modulebasegame.TerrarumIngame @@ -15,8 +16,9 @@ import net.torvald.terrarum.weather.WeatherMixer */ object WriteMeta { - operator fun invoke(ingame: TerrarumIngame, currentPlayTime_t: Long): String { + operator fun invoke(ingame: TerrarumIngame, time_t: Long): String { val world = ingame.world + val currentPlayTime_t = time_t - ingame.loadedTime_t val meta = WorldMeta( genver = Common.GENVER, @@ -26,9 +28,9 @@ object WriteMeta { weatseed0 = WeatherMixer.RNG.state0, weatseed1 = WeatherMixer.RNG.state1, playerid = ingame.actorGamer.referenceID, - creation_t = world.creationTime, - lastplay_t = world.lastPlayTime, - playtime_t = world.totalPlayTime + currentPlayTime_t, + creation_t = ingame.creationTime, + lastplay_t = App.getTIME_T(), + playtime_t = ingame.totalPlayTime + currentPlayTime_t, loadorder = ModMgr.loadOrder.toTypedArray(), worlds = ingame.gameworldIndices.toTypedArray() ) @@ -36,9 +38,9 @@ object WriteMeta { return Common.jsoner.toJson(meta) } - fun encodeToByteArray64(ingame: TerrarumIngame, currentPlayTime_t: Long): ByteArray64 { + fun encodeToByteArray64(ingame: TerrarumIngame, time_t: Long): ByteArray64 { val ba = ByteArray64() - this.invoke(ingame, currentPlayTime_t).toByteArray(Common.CHARSET).forEach { ba.add(it) } + this.invoke(ingame, time_t).toByteArray(Common.CHARSET).forEach { ba.add(it) } return ba } diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index e7e2a9ada..593b23592 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -46,13 +46,12 @@ object WriteSavegame { p.dispose() - val creation_t = ingame.world.creationTime + val creation_t = ingame.creationTime val time_t = App.getTIME_T() - val currentPlayTime_t = time_t - ingame.loadedTime_t // Write Meta // - val metaContent = EntryFile(WriteMeta.encodeToByteArray64(ingame, currentPlayTime_t)) + val metaContent = EntryFile(WriteMeta.encodeToByteArray64(ingame, time_t)) val meta = DiskEntry(-1, 0, creation_t, time_t, metaContent) addFile(disk, meta) @@ -98,7 +97,7 @@ object WriteSavegame { // Write World // val worldNum = ingame.world.worldIndex - val worldMeta = EntryFile(WriteWorld.encodeToByteArray64(ingame)) + val worldMeta = EntryFile(WriteWorld.encodeToByteArray64(ingame, time_t)) val world = DiskEntry(worldNum.toLong(), 0, creation_t, time_t, worldMeta) addFile(disk, world) @@ -182,6 +181,9 @@ object LoadSavegame { newIngame.gameLoadInfoPayload = worldParam newIngame.gameLoadMode = TerrarumIngame.GameLoadMode.LOAD_FROM newIngame.savegameArchive = disk + newIngame.creationTime = meta.creation_t + newIngame.lastPlayTime = meta.lastplay_t + newIngame.totalPlayTime = meta.playtime_t // load all the world blocklayer chunks val worldnum = world.worldIndex.toLong() diff --git a/src/net/torvald/terrarum/serialise/WriteWorld.kt b/src/net/torvald/terrarum/serialise/WriteWorld.kt index d3f3519c1..faf6d560c 100644 --- a/src/net/torvald/terrarum/serialise/WriteWorld.kt +++ b/src/net/torvald/terrarum/serialise/WriteWorld.kt @@ -25,10 +25,14 @@ object WriteWorld { actor != (CommonResourcePool.get("blockmarking_actor") as BlockMarkerActor) } - private fun preWrite(ingame: TerrarumIngame): GameWorld { + private fun preWrite(ingame: TerrarumIngame, time_t: Long): GameWorld { val world = ingame.world + val currentPlayTime_t = time_t - ingame.loadedTime_t + world.genver = Common.GENVER world.comp = Common.COMP_GZIP + world.lastPlayTime = time_t + world.totalPlayTime += currentPlayTime_t val actorIDbuf = ArrayList() ingame.actorContainerActive.filter { actorAcceptable(it) }.forEach { actorIDbuf.add(it.referenceID) } @@ -40,14 +44,14 @@ object WriteWorld { return world } - operator fun invoke(ingame: TerrarumIngame): String { - return Common.jsoner.toJson(preWrite(ingame)) + operator fun invoke(ingame: TerrarumIngame, time_t: Long): String { + return Common.jsoner.toJson(preWrite(ingame, time_t)) } - fun encodeToByteArray64(ingame: TerrarumIngame): ByteArray64 { + fun encodeToByteArray64(ingame: TerrarumIngame, time_t: Long): ByteArray64 { val baw = ByteArray64Writer(Common.CHARSET) - Common.jsoner.toJson(preWrite(ingame), baw) + Common.jsoner.toJson(preWrite(ingame, time_t), baw) baw.flush(); baw.close() return baw.toByteArray64()