save/load kinda mostly working but fixtures are not getting their sprites back

This commit is contained in:
minjaesong
2021-09-06 17:31:37 +09:00
parent ec08f8d07e
commit 1accf985e7
29 changed files with 230 additions and 126 deletions

View File

@@ -2,6 +2,7 @@ package net.torvald.terrarum.serialise
import net.torvald.spriteanimation.HasAssembledSprite
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.terrarum.AppLoader.printdbgerr
import net.torvald.terrarum.NoSuchActorWithIDException
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorWithBody
@@ -25,10 +26,19 @@ object WriteActor {
fun encodeToByteArray64(actor: Actor): ByteArray64 {
val baw = ByteArray64Writer(Common.CHARSET)
val classDef = """{"class":"${actor.javaClass.canonicalName}""""
baw.write(classDef)
Common.jsoner.toJson(actor, actor.javaClass, baw)
baw.flush(); baw.close()
// by this moment, contents of the baw will be:
// {"class":"some.class.Name"{"actorValue":{},......}
// (note that first bracket is not closed, and another open bracket after "class" property)
// and we want to turn it into this:
// {"class":"some.class.Name","actorValue":{},......}
val ba = baw.toByteArray64()
ba[classDef.toByteArray(Common.CHARSET).size.toLong()] = ','.code.toByte()
return baw.toByteArray64()
return ba
}
}
@@ -45,14 +55,11 @@ object WriteActor {
*/
object ReadActor {
fun readActorOnly(worldDataStream: Reader): Actor =
Common.jsoner.fromJson(null, worldDataStream)
operator fun invoke(worldDataStream: Reader): Actor =
fillInDetails(Common.jsoner.fromJson(null, worldDataStream))
operator fun invoke(ingame: TerrarumIngame, worldDataStream: Reader): Actor =
postRead(ingame, readActorOnly(worldDataStream))
private fun postRead(ingame: TerrarumIngame, actor: Actor): Actor {
// filling in Transients
private fun fillInDetails(actor: Actor): Actor {
actor.actorValue.actor = actor
if (actor is Pocketed)
@@ -66,6 +73,13 @@ object ReadActor {
actor.reassembleSprite(actor.sprite!!, actor.spriteGlow)
}
}
return actor
}
fun readActorAndAddToWorld(ingame: TerrarumIngame, worldDataStream: Reader): Actor {
val actor = invoke(worldDataStream)
// replace existing player
val oldPlayerID = ingame.actorNowPlaying?.referenceID
try {

View File

@@ -1,6 +1,10 @@
package net.torvald.terrarum.serialise
import net.torvald.ELLIPSIS
import net.torvald.terrarum.*
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.console.Echo
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.modulecomputers.virtualcomputer.tvd.*
@@ -39,29 +43,33 @@ object WriteSavegame {
addFile(disk, meta)
// Write BlockCodex//
val blockCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(BlockCodex).toByteArray(Common.CHARSET))))
val blocks = DiskEntry(-16, 0, "blocks".toByteArray(), creation_t, time_t, blockCodexContent)
addFile(disk, blocks)
// val blockCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(BlockCodex).toByteArray(Common.CHARSET))))
// val blocks = DiskEntry(-16, 0, "blocks".toByteArray(), creation_t, time_t, blockCodexContent)
// addFile(disk, blocks)
// Commented out; nothing to write
// Write ItemCodex//
val itemCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(ItemCodex).toByteArray(Common.CHARSET))))
val items = DiskEntry(-17, 0, "items".toByteArray(), creation_t, time_t, itemCodexContent)
addFile(disk, items)
// Gotta save dynamicIDs
// Write WireCodex//
val wireCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(WireCodex).toByteArray(Common.CHARSET))))
val wires = DiskEntry(-18, 0, "wires".toByteArray(), creation_t, time_t, wireCodexContent)
addFile(disk, wires)
// val wireCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(WireCodex).toByteArray(Common.CHARSET))))
// val wires = DiskEntry(-18, 0, "wires".toByteArray(), creation_t, time_t, wireCodexContent)
// addFile(disk, wires)
// Commented out; nothing to write
// Write MaterialCodex//
val materialCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(MaterialCodex).toByteArray(Common.CHARSET))))
val materials = DiskEntry(-19, 0, "materials".toByteArray(), creation_t, time_t, materialCodexContent)
addFile(disk, materials)
// val materialCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(MaterialCodex).toByteArray(Common.CHARSET))))
// val materials = DiskEntry(-19, 0, "materials".toByteArray(), creation_t, time_t, materialCodexContent)
// addFile(disk, materials)
// Commented out; nothing to write
// Write FactionCodex//
val factionCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(FactionCodex).toByteArray(Common.CHARSET))))
val factions = DiskEntry(-20, 0, "factions".toByteArray(), creation_t, time_t, factionCodexContent)
addFile(disk, factions)
// val factionCodexContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(FactionCodex).toByteArray(Common.CHARSET))))
// val factions = DiskEntry(-20, 0, "factions".toByteArray(), creation_t, time_t, factionCodexContent)
// addFile(disk, factions)
// Write Apocryphas//
val apocryphasContent = EntryFile(zip(ByteArray64.fromByteArray(Common.jsoner.toJson(Apocryphas).toByteArray(Common.CHARSET))))
@@ -105,29 +113,41 @@ object LoadSavegame {
private fun getFileReader(disk: VirtualDisk, id: Int): Reader = ByteArray64Reader(getFileBytes(disk, id), Common.CHARSET)
operator fun invoke(disk: VirtualDisk) {
val ingame = TerrarumIngame(AppLoader.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 player = ReadActor.readActorOnly(getFileReader(disk, 9545698)) as IngamePlayer
val world = ReadWorld.readWorldOnly(getFileReader(disk, player.worldCurrentlyPlaying))
val actors = world.actors.map { ReadActor.readActorOnly(getFileReader(disk, it)) }
val block = Common.jsoner.fromJson(BlockCodex.javaClass, getUnzipInputStream(getFileBytes(disk, -16)))
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 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 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)))
val ingame = TerrarumIngame(AppLoader.batch)
val worldParam = TerrarumIngame.Codices(meta, block, item, wire, material, faction, apocryphas)
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) }
ingame.actorNowPlaying = player
// 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
// ModMgr.reloadModules()
Terrarum.setCurrentIngameInstance(ingame)
val loadScreen = SanicLoadScreen
AppLoader.setLoadScreen(loadScreen)
AppLoader.setScreen(ingame)
Echo("${ccW}Savegame loaded from $ccY${disk.getDiskNameString(Common.CHARSET)}")
printdbg(this, "Savegame loaded from ${disk.getDiskNameString(Common.CHARSET)}")
Terrarum.ingame!!.consoleHandler.setAsOpen()
}
}

View File

@@ -53,17 +53,21 @@ object WriteWorld {
*/
object ReadWorld {
fun readWorldOnly(worldDataStream: Reader): GameWorld =
Common.jsoner.fromJson(GameWorld::class.java, worldDataStream)
operator fun invoke(worldDataStream: Reader): GameWorld =
fillInDetails(Common.jsoner.fromJson(GameWorld::class.java, worldDataStream))
operator fun invoke(ingame: TerrarumIngame, worldDataStream: Reader): GameWorld =
postRead(ingame, readWorldOnly(worldDataStream))
private fun postRead(ingame: TerrarumIngame, world: GameWorld): GameWorld {
world.postLoad()
ingame.world = world
private fun fillInDetails(world: GameWorld): GameWorld {
world.tileNumberToNameMap.forEach { l, s ->
world.tileNameToNumberMap[s] = l.toInt()
}
return world
}
fun readWorldAndSetNewWorld(ingame: TerrarumIngame, worldDataStream: Reader): GameWorld {
val world = invoke(worldDataStream)
ingame.world = world
return world
}
}