Using "rudimentary" loading scene for loading from savegame

This commit is contained in:
minjaesong
2021-09-14 00:15:02 +09:00
parent d731812e4e
commit de62b41a69
4 changed files with 81 additions and 51 deletions

View File

@@ -62,7 +62,7 @@ object SanicLoadScreen : LoadScreenBase() {
val textX: Float; get() = (App.scr.width * 0.72f).floor() 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 messageBackgroundColour = Color(0x404040ff)
private var messageForegroundColour = Color.WHITE private var messageForegroundColour = Color.WHITE

View File

@@ -16,10 +16,7 @@ import net.torvald.terrarum.concurrent.ThreadExecutor
import net.torvald.terrarum.console.AVTracker import net.torvald.terrarum.console.AVTracker
import net.torvald.terrarum.console.ActorsList import net.torvald.terrarum.console.ActorsList
import net.torvald.terrarum.console.Authenticator import net.torvald.terrarum.console.Authenticator
import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameactors.*
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.gameactors.WireActor
import net.torvald.terrarum.gamecontroller.IngameController import net.torvald.terrarum.gamecontroller.IngameController
import net.torvald.terrarum.gamecontroller.KeyToggler import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameitem.GameItem 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.modulebasegame.worldgenerator.WorldgenParams
import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.serialise.Common 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.serialise.WriteMeta
import net.torvald.terrarum.tvda.VDUtil import net.torvald.terrarum.tvda.VDUtil
import net.torvald.terrarum.tvda.VirtualDisk
import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarum.ui.UICanvas
import net.torvald.terrarum.weather.WeatherMixer import net.torvald.terrarum.weather.WeatherMixer
import net.torvald.terrarum.worlddrawer.BlocksDrawer import net.torvald.terrarum.worlddrawer.BlocksDrawer
@@ -242,13 +242,15 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
} }
data class Codices( data class Codices(
val disk: VirtualDisk,
val meta: WriteMeta.WorldMeta, val meta: WriteMeta.WorldMeta,
// val block: BlockCodex, // val block: BlockCodex,
val item: ItemCodex, val item: ItemCodex,
// val wire: WireCodex, // val wire: WireCodex,
// val material: MaterialCodex, // val material: MaterialCodex,
// val faction: FactionCodex, // val faction: FactionCodex,
val apocryphas: Map<String, Any> val apocryphas: Map<String, Any>,
val actors: List<ActorID>
) )
private fun setTheRealGamerFirstTime(actor: IngamePlayer) { private fun setTheRealGamerFirstTime(actor: IngamePlayer) {
@@ -275,9 +277,22 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
Terrarum.itemCodex.loadFromSave(codices.item) Terrarum.itemCodex.loadFromSave(codices.item)
Terrarum.apocryphas = HashMap(codices.apocryphas) 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 * Init instance by creating new world
*/ */
@@ -518,6 +533,9 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
world.spawnY * TILE_SIZED world.spawnY * TILE_SIZED
) )
} }
else if (gameLoadMode == GameLoadMode.LOAD_FROM) {
postInitForLoadFromSave(gameLoadInfoPayload as Codices)
}
postInit() postInit()

View File

@@ -57,6 +57,8 @@ object ReadActor {
operator fun invoke(worldDataStream: Reader): Actor = operator fun invoke(worldDataStream: Reader): Actor =
fillInDetails(Common.jsoner.fromJson(null, worldDataStream)) fillInDetails(Common.jsoner.fromJson(null, worldDataStream))
fun readActorBare(worldDataStream: Reader): Actor =
Common.jsoner.fromJson(null, worldDataStream)
private fun fillInDetails(actor: Actor): Actor { private fun fillInDetails(actor: Actor): Actor {
actor.actorValue.actor = actor actor.actorValue.actor = actor

View File

@@ -153,68 +153,78 @@ object WriteSavegame {
*/ */
object LoadSavegame { object LoadSavegame {
private fun getFileBytes(disk: VirtualDisk, id: Long): ByteArray64 = VDUtil.getAsNormalFile(disk, id).getContent() 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 getFileReader(disk: VirtualDisk, id: Long): Reader = ByteArray64Reader(getFileBytes(disk, id), Common.CHARSET)
operator fun invoke(disk: VirtualDisk) { operator fun invoke(disk: VirtualDisk) {
val newIngame = 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.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 loadJob = { loadscreen: LoadScreenBase ->
val worldnum = world.worldIndex.toLong() val meta = ReadMeta(disk)
val cw = LandUtil.CHUNK_W; val ch = LandUtil.CHUNK_H // NOTE: do NOT set ingame.actorNowPlaying as one read directly from the disk;
val chunksX = world.width / cw // you'll inevitably read the player actor twice, and they're separate instances of the player!
for (layer in 0L..1L) { val currentWorld = (ReadActor.readActorBare(getFileReader(disk, Terrarum.PLAYER_REF_ID.toLong())) as IngamePlayer).worldCurrentlyPlaying
val worldLayer = world.getLayer(layer.toInt()) 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) // set lateinit vars on the gameworld
val cx = chunk % chunksX world.layerTerrain = BlockLayer(world.width, world.height)
val cy = chunk / chunksX world.layerWall = BlockLayer(world.width, world.height)
ReadWorld.decodeChunkToLayer(chunkFile.getContent(), worldLayer, cx.toInt(), cy.toInt())
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) } // 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
// newIngame.gameInitialised = true
// ModMgr.reloadModules() // 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) 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()
} }
} }