diff --git a/src/net/torvald/terrarum/SanicLoadScreen.kt b/src/net/torvald/terrarum/SanicLoadScreen.kt index 2221a1119..441198816 100644 --- a/src/net/torvald/terrarum/SanicLoadScreen.kt +++ b/src/net/torvald/terrarum/SanicLoadScreen.kt @@ -62,7 +62,7 @@ object SanicLoadScreen : LoadScreenBase() { val textX: Float; get() = (App.scr.width * 0.72f).floor() - private var genuineSonic = false // the "NOW LOADING..." won't appear unless the arrow first run passes it (it's totally not a GenuineIntel tho) + private var genuineSonic = false // the "NOW LOADING..." won't appear unless the arrow first run passes it private var messageBackgroundColour = Color(0x404040ff) private var messageForegroundColour = Color.WHITE diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 5eb82ed6a..bb4edd8d6 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -16,10 +16,7 @@ import net.torvald.terrarum.concurrent.ThreadExecutor import net.torvald.terrarum.console.AVTracker import net.torvald.terrarum.console.ActorsList import net.torvald.terrarum.console.Authenticator -import net.torvald.terrarum.gameactors.AVKey -import net.torvald.terrarum.gameactors.Actor -import net.torvald.terrarum.gameactors.ActorWithBody -import net.torvald.terrarum.gameactors.WireActor +import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gamecontroller.IngameController import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.gameitem.GameItem @@ -36,8 +33,11 @@ import net.torvald.terrarum.modulebasegame.worldgenerator.Worldgen import net.torvald.terrarum.modulebasegame.worldgenerator.WorldgenParams import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.serialise.Common +import net.torvald.terrarum.serialise.LoadSavegame +import net.torvald.terrarum.serialise.ReadActor import net.torvald.terrarum.serialise.WriteMeta import net.torvald.terrarum.tvda.VDUtil +import net.torvald.terrarum.tvda.VirtualDisk import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.weather.WeatherMixer import net.torvald.terrarum.worlddrawer.BlocksDrawer @@ -242,13 +242,15 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { } data class Codices( + val disk: VirtualDisk, val meta: WriteMeta.WorldMeta, // val block: BlockCodex, val item: ItemCodex, // val wire: WireCodex, // val material: MaterialCodex, // val faction: FactionCodex, - val apocryphas: Map + val apocryphas: Map, + val actors: List ) private fun setTheRealGamerFirstTime(actor: IngamePlayer) { @@ -275,9 +277,22 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { Terrarum.itemCodex.loadFromSave(codices.item) Terrarum.apocryphas = HashMap(codices.apocryphas) + + } } + /** Load rest of the game with GL context */ + private fun postInitForLoadFromSave(codices: Codices) { + codices.actors.forEach { + val actor = ReadActor(LoadSavegame.getFileReader(codices.disk, it.toLong())) + addNewActor(actor) + } + + // by doing this, whatever the "possession" the player had will be broken by the game load + actorNowPlaying = getActorByID(Terrarum.PLAYER_REF_ID) as IngamePlayer + } + /** * Init instance by creating new world */ @@ -518,6 +533,9 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) { world.spawnY * TILE_SIZED ) } + else if (gameLoadMode == GameLoadMode.LOAD_FROM) { + postInitForLoadFromSave(gameLoadInfoPayload as Codices) + } postInit() diff --git a/src/net/torvald/terrarum/serialise/WriteActor.kt b/src/net/torvald/terrarum/serialise/WriteActor.kt index bd9f5a48e..fe3bc4803 100644 --- a/src/net/torvald/terrarum/serialise/WriteActor.kt +++ b/src/net/torvald/terrarum/serialise/WriteActor.kt @@ -57,6 +57,8 @@ object ReadActor { operator fun invoke(worldDataStream: Reader): Actor = fillInDetails(Common.jsoner.fromJson(null, worldDataStream)) + fun readActorBare(worldDataStream: Reader): Actor = + Common.jsoner.fromJson(null, worldDataStream) private fun fillInDetails(actor: Actor): Actor { actor.actorValue.actor = actor diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index 593b23592..26ec2a1ae 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -153,68 +153,78 @@ object WriteSavegame { */ object LoadSavegame { - private fun getFileBytes(disk: VirtualDisk, id: Long): ByteArray64 = VDUtil.getAsNormalFile(disk, id).getContent() - private fun getFileReader(disk: VirtualDisk, id: Long): Reader = ByteArray64Reader(getFileBytes(disk, id), Common.CHARSET) + fun getFileBytes(disk: VirtualDisk, id: Long): ByteArray64 = VDUtil.getAsNormalFile(disk, id).getContent() + fun getFileReader(disk: VirtualDisk, id: Long): Reader = ByteArray64Reader(getFileBytes(disk, id), Common.CHARSET) operator fun invoke(disk: VirtualDisk) { 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.toLong())) as IngamePlayer).worldCurrentlyPlaying - val world = ReadWorld(getFileReader(disk, currentWorld.toLong())) - val actors = world.actors.distinct().map { ReadActor(getFileReader(disk, it.toLong())) } -// 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))) -// val material = Common.jsoner.fromJson(MaterialCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -19))) -// val faction = Common.jsoner.fromJson(FactionCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -20))) - val apocryphas = Common.jsoner.fromJson(Apocryphas.javaClass, getUnzipInputStream(getFileBytes(disk, -1024))) - // set lateinit vars on the gameworld - world.layerTerrain = BlockLayer(world.width, world.height) - world.layerWall = BlockLayer(world.width, world.height) - val worldParam = TerrarumIngame.Codices(meta, item, apocryphas) - newIngame.world = world - 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() - val cw = LandUtil.CHUNK_W; val ch = LandUtil.CHUNK_H - val chunksX = world.width / cw - for (layer in 0L..1L) { - val worldLayer = world.getLayer(layer.toInt()) + val loadJob = { loadscreen: LoadScreenBase -> + val meta = ReadMeta(disk) + // 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 currentWorld = (ReadActor.readActorBare(getFileReader(disk, Terrarum.PLAYER_REF_ID.toLong())) as IngamePlayer).worldCurrentlyPlaying + val world = ReadWorld(getFileReader(disk, currentWorld.toLong())) + val actors = world.actors.distinct()//.map { ReadActor(getFileReader(disk, it.toLong())) } + // 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))) + // val material = Common.jsoner.fromJson(MaterialCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -19))) + // val faction = Common.jsoner.fromJson(FactionCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -20))) + val apocryphas = Common.jsoner.fromJson(Apocryphas.javaClass, getUnzipInputStream(getFileBytes(disk, -1024))) - for (chunk in 0L until (world.width * world.height) / (cw * ch)) { - val chunkFile = VDUtil.getAsNormalFile(disk, worldnum.shl(32) or layer.shl(24) or chunk) - val cx = chunk % chunksX - val cy = chunk / chunksX - ReadWorld.decodeChunkToLayer(chunkFile.getContent(), worldLayer, cx.toInt(), cy.toInt()) + + // set lateinit vars on the gameworld + world.layerTerrain = BlockLayer(world.width, world.height) + world.layerWall = BlockLayer(world.width, world.height) + + val worldParam = TerrarumIngame.Codices(disk, meta, item, apocryphas, actors) + newIngame.world = world + 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() + val cw = LandUtil.CHUNK_W; + val ch = LandUtil.CHUNK_H + val chunksX = world.width / cw + for (layer in 0L..1L) { + val worldLayer = world.getLayer(layer.toInt()) + + for (chunk in 0L until (world.width * world.height) / (cw * ch)) { + val chunkFile = VDUtil.getAsNormalFile(disk, worldnum.shl(32) or layer.shl(24) or chunk) + val cx = chunk % chunksX + val cy = chunk / chunksX + ReadWorld.decodeChunkToLayer(chunkFile.getContent(), worldLayer, cx.toInt(), cy.toInt()) + } } - } - actors.forEach { newIngame.addNewActor(it) } - - // by doing this, whatever the "possession" the player had will be broken by the game load - newIngame.actorNowPlaying = newIngame.getActorByID(Terrarum.PLAYER_REF_ID) as IngamePlayer +// actors.forEach { newIngame.addNewActor(it) } + + +// newIngame.gameInitialised = true // ModMgr.reloadModules() + + Echo("${ccW}Savegame loaded from $ccY${disk.getDiskNameString(Common.CHARSET)}") + printdbg(this, "Savegame loaded from ${disk.getDiskNameString(Common.CHARSET)}") + } + + SanicLoadScreen.preLoadJob = loadJob + SanicLoadScreen.screenToLoad = newIngame Terrarum.setCurrentIngameInstance(newIngame) - App.setScreen(newIngame) + App.setLoadScreen(SanicLoadScreen) - Echo("${ccW}Savegame loaded from $ccY${disk.getDiskNameString(Common.CHARSET)}") - printdbg(this, "Savegame loaded from ${disk.getDiskNameString(Common.CHARSET)}") -// Terrarum.ingame!!.consoleHandler.setAsOpen() } } \ No newline at end of file