mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-12 19:44:05 +09:00
fixed a bug where a dynamic item would not get saved/loaded at all
This commit is contained in:
@@ -329,4 +329,4 @@ object Common {
|
||||
|
||||
}
|
||||
|
||||
class SaveLoadError(file: File, cause: Throwable) : RuntimeException("An error occured while loading save file '${file.absolutePath}'", cause)
|
||||
class SaveLoadError(file: File?, cause: Throwable) : RuntimeException("An error occured while loading save file '${file?.absolutePath}'", cause)
|
||||
@@ -2,13 +2,20 @@ package net.torvald.terrarum.serialise
|
||||
|
||||
import net.torvald.gdx.graphics.PixmapIO2
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.ItemCodex
|
||||
import net.torvald.terrarum.ReferencingRanges.PREFIX_DYNAMICITEM
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
||||
import net.torvald.terrarum.modulebasegame.IngameRenderer
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.toInt
|
||||
import net.torvald.terrarum.savegame.*
|
||||
import java.io.File
|
||||
import java.util.HashMap
|
||||
import java.util.zip.GZIPOutputStream
|
||||
|
||||
/**
|
||||
@@ -61,14 +68,14 @@ class WorldSavingThread(
|
||||
|
||||
val allTheActors = ingame.actorContainerActive.cloneToList() + ingame.actorContainerInactive.cloneToList()
|
||||
|
||||
val playersList: List<IngamePlayer> = allTheActors.filter{ it is IngamePlayer } as List<IngamePlayer>
|
||||
val playersList: List<IngamePlayer> = allTheActors.filterIsInstance<IngamePlayer>()
|
||||
val actorsList = allTheActors.filter { WriteWorld.actorAcceptable(it) }
|
||||
val layers = intArrayOf(0,1).map { ingame.world.getLayer(it) }
|
||||
val cw = ingame.world.width / LandUtil.CHUNK_W
|
||||
val ch = ingame.world.height / LandUtil.CHUNK_H
|
||||
|
||||
WriteSavegame.saveProgress = 0f
|
||||
WriteSavegame.saveProgressMax = 2f + (cw * ch * layers.size) + actorsList.size
|
||||
WriteSavegame.saveProgressMax = 3f + (cw * ch * layers.size) + actorsList.size
|
||||
|
||||
|
||||
val tgaout = ByteArray64GrowableOutputStream()
|
||||
@@ -79,6 +86,39 @@ class WorldSavingThread(
|
||||
val creation_t = ingame.world.creationTime
|
||||
|
||||
|
||||
// Write subset of Ingame.ItemCodex
|
||||
// The existing ItemCodex must be rewritten to clear out obsolete records
|
||||
|
||||
// We're assuming the dynamic item generated by players does exist in the world, and it's recorded
|
||||
// into the world's dynamicToStaticTable, therefore every item recorded into the world's dynamicToStaticTable
|
||||
// can be found in this world without need to look up the players
|
||||
ingame.world.dynamicToStaticTable.clear()
|
||||
ingame.world.dynamicItemInventory.clear()
|
||||
actorsList.filterIsInstance<Pocketed>().forEach { actor ->
|
||||
actor.inventory.forEach { (itemid, _) ->
|
||||
|
||||
printdbg(this, "World side dynamicitem: $itemid contained in $actor")
|
||||
|
||||
if (itemid.startsWith("$PREFIX_DYNAMICITEM:")) {
|
||||
ingame.world.dynamicToStaticTable[itemid] = ItemCodex.dynamicToStaticID(itemid)
|
||||
ingame.world.dynamicItemInventory[itemid] = ItemCodex[itemid]!!
|
||||
}
|
||||
}
|
||||
}
|
||||
actorsList.filterIsInstance<FixtureBase>().forEach { fixture ->
|
||||
fixture.inventory?.forEach { (itemid, _) ->
|
||||
|
||||
printdbg(this, "World side dynamicitem: $itemid contained in $fixture")
|
||||
|
||||
if (itemid.startsWith("$PREFIX_DYNAMICITEM:")) {
|
||||
ingame.world.dynamicToStaticTable[itemid] = ItemCodex.dynamicToStaticID(itemid)
|
||||
ingame.world.dynamicItemInventory[itemid] = ItemCodex[itemid]!!
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
if (hasThumbnail) {
|
||||
PixmapIO2._writeTGA(gzout, IngameRenderer.fboRGBexport, true, true)
|
||||
IngameRenderer.fboRGBexport.dispose()
|
||||
|
||||
@@ -4,9 +4,12 @@ import net.torvald.spriteanimation.HasAssembledSprite
|
||||
import net.torvald.spriteanimation.SpriteAnimation
|
||||
import net.torvald.terrarum.spriteassembler.ADProperties
|
||||
import net.torvald.terrarum.ItemCodex
|
||||
import net.torvald.terrarum.ReferencingRanges.PREFIX_DYNAMICITEM
|
||||
import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gameitems.GameItem
|
||||
import net.torvald.terrarum.gameitems.ItemID
|
||||
import net.torvald.terrarum.itemproperties.ItemRemapTable
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.savegame.*
|
||||
@@ -74,6 +77,17 @@ object WritePlayer {
|
||||
|
||||
player.worldCurrentlyPlaying = ingame?.world?.worldIndex ?: UUID(0L,0L)
|
||||
|
||||
// Write subset of Ingame.ItemCodex
|
||||
// The existing ItemCodex must be rewritten to clear out obsolete records
|
||||
player.dynamicToStaticTable.clear()
|
||||
player.dynamicItemInventory.clear()
|
||||
player.inventory.forEach { (itemid, _) ->
|
||||
if (itemid.startsWith("$PREFIX_DYNAMICITEM:")) {
|
||||
player.dynamicToStaticTable[itemid] = ItemCodex.dynamicToStaticID(itemid)
|
||||
player.dynamicItemInventory[itemid] = ItemCodex[itemid]!!
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
val actorJson = WriteActor.encodeToByteArray64(player)
|
||||
val adl = player.animDesc!!.getRawADL()
|
||||
@@ -142,6 +156,8 @@ object ReadActor {
|
||||
actor.animDescGlow = ADProperties(ByteArray64Reader(animFileGlow.bytes, Common.CHARSET))
|
||||
}
|
||||
|
||||
ItemCodex.loadFromSave(disk.getBackingFile(), actor.dynamicToStaticTable, actor.dynamicItemInventory)
|
||||
|
||||
val heldItem = ItemCodex[actor.inventory.itemEquipped[GameItem.EquipPosition.HAND_GRIP]]
|
||||
|
||||
if (bodypartsFile != null)
|
||||
|
||||
@@ -125,7 +125,7 @@ object LoadSavegame {
|
||||
|
||||
val currentWorldId = player.worldCurrentlyPlaying
|
||||
val worldDisk = worldDisk0 ?: App.savegameWorlds[currentWorldId]!!
|
||||
val world = ReadWorld(ByteArray64Reader(worldDisk.getFile(-1L)!!.bytes, Common.CHARSET))
|
||||
val world = ReadWorld(ByteArray64Reader(worldDisk.getFile(-1L)!!.bytes, Common.CHARSET), worldDisk.diskFile)
|
||||
|
||||
world.layerTerrain = BlockLayer(world.width, world.height)
|
||||
world.layerWall = BlockLayer(world.width, world.height)
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package net.torvald.terrarum.serialise
|
||||
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.ItemCodex
|
||||
import net.torvald.terrarum.ReferencingRanges
|
||||
import net.torvald.terrarum.gameactors.Actor
|
||||
import net.torvald.terrarum.gameactors.BlockMarkerActor
|
||||
@@ -15,6 +16,7 @@ import net.torvald.terrarum.savegame.ByteArray64
|
||||
import net.torvald.terrarum.savegame.ByteArray64Writer
|
||||
import net.torvald.terrarum.utils.PlayerLastStatus
|
||||
import net.torvald.terrarum.weather.WeatherMixer
|
||||
import java.io.File
|
||||
import java.io.Reader
|
||||
|
||||
/**
|
||||
@@ -90,22 +92,24 @@ object WriteWorld {
|
||||
*/
|
||||
object ReadWorld {
|
||||
|
||||
fun readLayerFormat(worldDataStream: Reader): GameWorld =
|
||||
fillInDetails(Common.jsoner.fromJson(GameWorldTitleScreen::class.java, worldDataStream))
|
||||
fun readLayerFormat(worldDataStream: Reader, origin: File?): GameWorld =
|
||||
fillInDetails(Common.jsoner.fromJson(GameWorldTitleScreen::class.java, worldDataStream), origin)
|
||||
|
||||
operator fun invoke(worldDataStream: Reader): GameWorld =
|
||||
fillInDetails(Common.jsoner.fromJson(GameWorld::class.java, worldDataStream))
|
||||
operator fun invoke(worldDataStream: Reader, origin: File?): GameWorld =
|
||||
fillInDetails(Common.jsoner.fromJson(GameWorld::class.java, worldDataStream), origin)
|
||||
|
||||
private fun fillInDetails(world: GameWorld): GameWorld {
|
||||
private fun fillInDetails(world: GameWorld, origin: File?): GameWorld {
|
||||
world.tileNumberToNameMap.forEach { l, s ->
|
||||
world.tileNameToNumberMap[s] = l.toInt()
|
||||
}
|
||||
|
||||
ItemCodex.loadFromSave(origin, world.dynamicToStaticTable, world.dynamicItemInventory)
|
||||
|
||||
return world
|
||||
}
|
||||
|
||||
fun readWorldAndSetNewWorld(ingame: TerrarumIngame, worldDataStream: Reader): GameWorld {
|
||||
val world = readLayerFormat(worldDataStream)
|
||||
fun readWorldAndSetNewWorld(ingame: TerrarumIngame, worldDataStream: Reader, origin: File?): GameWorld {
|
||||
val world = readLayerFormat(worldDataStream, origin)
|
||||
ingame.world = world
|
||||
return world
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user