mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-10 13:51:53 +09:00
fixed a bug when loading a packaged player, loading a spriteglow would read normal sprite's data instead
This commit is contained in:
@@ -28,6 +28,7 @@ import net.torvald.terrarum.itemproperties.ItemCodex
|
||||
import net.torvald.terrarum.itemproperties.MaterialCodex
|
||||
import net.torvald.terrarum.savegame.ByteArray64Reader
|
||||
import net.torvald.terrarum.savegame.DiskSkimmer
|
||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.ui.UICanvas
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
@@ -798,7 +799,7 @@ fun AppUpdateListOfSavegames() {
|
||||
println("${index+1}.\t${it.diskFile.absolutePath}")
|
||||
it.rebuild() // disk skimmer was created without initialisation, so do it now
|
||||
|
||||
val jsonFile = it.getFile(-1L)!!
|
||||
val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
||||
val json = JsonReader().parse(ByteArray64Reader(jsonFile.bytes, Common.CHARSET).readText())
|
||||
val worldUUID = UUID.fromString(json.getString("worldIndex"))
|
||||
App.savegameWorlds[worldUUID] = it
|
||||
@@ -824,7 +825,7 @@ fun AppUpdateListOfSavegames() {
|
||||
println("${index+1}.\t${it.diskFile.absolutePath}")
|
||||
it.rebuild() // disk skimmer was created without initialisation, so do it now
|
||||
|
||||
val jsonFile = it.getFile(-1L)!!
|
||||
val jsonFile = it.getFile(SAVEGAMEINFO)!!
|
||||
val json = JsonReader().parse(ByteArray64Reader(jsonFile.bytes, Common.CHARSET).readText())
|
||||
val playerUUID = UUID.fromString(json.getString("uuid"))
|
||||
App.savegamePlayers[playerUUID] = it
|
||||
|
||||
@@ -13,6 +13,10 @@ import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.toInt
|
||||
import net.torvald.terrarum.savegame.*
|
||||
import net.torvald.terrarum.savegame.VDFileID.LOADORDER
|
||||
import net.torvald.terrarum.savegame.VDFileID.ROOT
|
||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||
import net.torvald.terrarum.savegame.VDFileID.THUMBNAIL
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import java.io.File
|
||||
import java.util.zip.GZIPOutputStream
|
||||
@@ -123,7 +127,7 @@ class WorldSavingThread(
|
||||
IngameRenderer.fboRGBexport.dispose()
|
||||
|
||||
val thumbContent = EntryFile(tgaout.toByteArray64())
|
||||
val thumb = DiskEntry(-2, 0, creation_t, time_t, thumbContent)
|
||||
val thumb = DiskEntry(THUMBNAIL, ROOT, creation_t, time_t, thumbContent)
|
||||
addFile(disk, thumb)
|
||||
}
|
||||
|
||||
@@ -132,7 +136,7 @@ class WorldSavingThread(
|
||||
// Write World //
|
||||
|
||||
val worldMeta = EntryFile(WriteWorld.encodeToByteArray64(ingame, time_t, actorsList, playersList))
|
||||
val world = DiskEntry(-1L, 0, creation_t, time_t, worldMeta)
|
||||
val world = DiskEntry(SAVEGAMEINFO, ROOT, creation_t, time_t, worldMeta)
|
||||
addFile(disk, world)
|
||||
|
||||
WriteSavegame.saveProgress += 1f
|
||||
@@ -149,7 +153,7 @@ class WorldSavingThread(
|
||||
val entryID = 0x1_0000_0000L or layer.toLong().shl(24) or chunkNumber
|
||||
|
||||
val entryContent = EntryFile(chunkBytes)
|
||||
val entry = DiskEntry(entryID, 0, creation_t, time_t, entryContent)
|
||||
val entry = DiskEntry(entryID, ROOT, creation_t, time_t, entryContent)
|
||||
// "W1L0-92,15"
|
||||
addFile(disk, entry)
|
||||
|
||||
@@ -164,7 +168,7 @@ class WorldSavingThread(
|
||||
// Echo("Writing actors... ${count+1}/${actorsList.size}")
|
||||
|
||||
val actorContent = EntryFile(WriteActor.encodeToByteArray64(it))
|
||||
val actor = DiskEntry(it.referenceID.toLong(), 0, creation_t, time_t, actorContent)
|
||||
val actor = DiskEntry(it.referenceID.toLong(), ROOT, creation_t, time_t, actorContent)
|
||||
addFile(disk, actor)
|
||||
|
||||
WriteSavegame.saveProgress += 1
|
||||
@@ -177,7 +181,7 @@ class WorldSavingThread(
|
||||
loadOrderBa64Writer.flush(); loadOrderBa64Writer.close()
|
||||
val loadOrderText = loadOrderBa64Writer.toByteArray64()
|
||||
val loadOrderContents = EntryFile(loadOrderText)
|
||||
addFile(disk, DiskEntry(-4L, 0L, creation_t, time_t, loadOrderContents))
|
||||
addFile(disk, DiskEntry(LOADORDER, ROOT, creation_t, time_t, loadOrderContents))
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,6 +7,9 @@ import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.savegame.*
|
||||
import net.torvald.terrarum.savegame.VDFileID.ROOT
|
||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||
import net.torvald.terrarum.savegame.VDFileID.THUMBNAIL
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.toInt
|
||||
import net.torvald.terrarum.utils.PlayerLastStatus
|
||||
@@ -78,7 +81,7 @@ class QuickSingleplayerWorldSavingThread(
|
||||
IngameRenderer.fboRGBexport.dispose()
|
||||
|
||||
val thumbContent = EntryFile(tgaout.toByteArray64())
|
||||
val thumb = DiskEntry(-2, 0, creation_t, time_t, thumbContent)
|
||||
val thumb = DiskEntry(THUMBNAIL, ROOT, creation_t, time_t, thumbContent)
|
||||
addFile(disk, thumb)
|
||||
}
|
||||
|
||||
@@ -90,7 +93,7 @@ class QuickSingleplayerWorldSavingThread(
|
||||
ingame.world.playersLastStatus[it.uuid] = PlayerLastStatus(it, ingame.isMultiplayer)
|
||||
}
|
||||
val worldMeta = EntryFile(WriteWorld.encodeToByteArray64(ingame, time_t, actorsList, playersList))
|
||||
val world = DiskEntry(-1L, 0, creation_t, time_t, worldMeta)
|
||||
val world = DiskEntry(SAVEGAMEINFO, ROOT, creation_t, time_t, worldMeta)
|
||||
addFile(disk, world); skimmer.appendEntryOnly(world)
|
||||
|
||||
WriteSavegame.saveProgress += 1f
|
||||
@@ -112,7 +115,7 @@ class QuickSingleplayerWorldSavingThread(
|
||||
val entryID = 0x1_0000_0000L or layerNum.toLong().shl(24) or chunkNumber.toLong()
|
||||
|
||||
val entryContent = EntryFile(chunkBytes)
|
||||
val entry = DiskEntry(entryID, 0, creation_t, time_t, entryContent)
|
||||
val entry = DiskEntry(entryID, ROOT, creation_t, time_t, entryContent)
|
||||
// "W1L0-92,15"
|
||||
addFile(disk, entry); skimmer.appendEntryOnly(entry)
|
||||
|
||||
@@ -130,7 +133,7 @@ class QuickSingleplayerWorldSavingThread(
|
||||
printdbg(this, "Writing actors... ${count+1}/${actorsList.size}")
|
||||
|
||||
val actorContent = EntryFile(WriteActor.encodeToByteArray64(it))
|
||||
val actor = DiskEntry(it.referenceID.toLong(), 0, creation_t, time_t, actorContent)
|
||||
val actor = DiskEntry(it.referenceID.toLong(), ROOT, creation_t, time_t, actorContent)
|
||||
addFile(disk, actor); skimmer.appendEntryOnly(actor)
|
||||
|
||||
WriteSavegame.saveProgress += actorProgressMultiplier
|
||||
|
||||
@@ -10,6 +10,13 @@ import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.savegame.*
|
||||
import net.torvald.terrarum.savegame.VDFileID.BODYPARTGLOW_TO_ENTRY_MAP
|
||||
import net.torvald.terrarum.savegame.VDFileID.BODYPART_TO_ENTRY_MAP
|
||||
import net.torvald.terrarum.savegame.VDFileID.LOADORDER
|
||||
import net.torvald.terrarum.savegame.VDFileID.ROOT
|
||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||
import net.torvald.terrarum.savegame.VDFileID.SPRITEDEF
|
||||
import net.torvald.terrarum.savegame.VDFileID.SPRITEDEF_GLOW
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.spriteassembler.ADProperties
|
||||
import java.io.Reader
|
||||
@@ -95,17 +102,17 @@ object WritePlayer {
|
||||
val adlGlow = player.animDescGlow?.getRawADL() // NULLABLE!
|
||||
|
||||
val jsonContents = EntryFile(actorJson)
|
||||
val jsonCreationDate = playerDisk.getEntry(-1)?.creationDate ?: time_t
|
||||
addFile(playerDisk, DiskEntry(-1L, 0L, jsonCreationDate, time_t, jsonContents))
|
||||
val jsonCreationDate = playerDisk.getEntry(SAVEGAMEINFO)?.creationDate ?: time_t
|
||||
addFile(playerDisk, DiskEntry(SAVEGAMEINFO, ROOT, jsonCreationDate, time_t, jsonContents))
|
||||
|
||||
val adlContents = EntryFile(ByteArray64.fromByteArray(adl.toByteArray(Common.CHARSET)))
|
||||
val adlCreationDate = playerDisk.getEntry(-2)?.creationDate ?: time_t
|
||||
addFile(playerDisk, DiskEntry(-2L, 0L, adlCreationDate, time_t, adlContents))
|
||||
val adlCreationDate = playerDisk.getEntry(SPRITEDEF)?.creationDate ?: time_t
|
||||
addFile(playerDisk, DiskEntry(SPRITEDEF, ROOT, adlCreationDate, time_t, adlContents))
|
||||
|
||||
if (adlGlow != null) {
|
||||
val adlGlowContents = EntryFile(ByteArray64.fromByteArray(adlGlow.toByteArray(Common.CHARSET)))
|
||||
val adlGlowCreationDate = playerDisk.getEntry(-3)?.creationDate ?: time_t
|
||||
addFile(playerDisk, DiskEntry(-3L, 0L, adlGlowCreationDate, time_t, adlGlowContents))
|
||||
val adlGlowCreationDate = playerDisk.getEntry(SPRITEDEF_GLOW)?.creationDate ?: time_t
|
||||
addFile(playerDisk, DiskEntry(SPRITEDEF_GLOW, ROOT, adlGlowCreationDate, time_t, adlGlowContents))
|
||||
}
|
||||
|
||||
// write loadorder //
|
||||
@@ -114,7 +121,7 @@ object WritePlayer {
|
||||
loadOrderBa64Writer.flush(); loadOrderBa64Writer.close()
|
||||
val loadOrderText = loadOrderBa64Writer.toByteArray64()
|
||||
val loadOrderContents = EntryFile(loadOrderText)
|
||||
addFile(playerDisk, DiskEntry(-4L, 0L, jsonCreationDate, time_t, loadOrderContents))
|
||||
addFile(playerDisk, DiskEntry(LOADORDER, ROOT, jsonCreationDate, time_t, loadOrderContents))
|
||||
}
|
||||
|
||||
}
|
||||
@@ -152,15 +159,25 @@ object ReadActor {
|
||||
|
||||
|
||||
if (actor is ActorWithBody && actor is IngamePlayer) {
|
||||
val animFile = disk.getFile(-2L)
|
||||
val animFileGlow = disk.getFile(-3L)
|
||||
val bodypartsFile = disk.getFile(-1025)
|
||||
val animFile = disk.getFile(SPRITEDEF)
|
||||
val animFileGlow = disk.getFile(SPRITEDEF_GLOW)
|
||||
val bodypartsFile = disk.getFile(BODYPART_TO_ENTRY_MAP)
|
||||
|
||||
actor.animDesc = ADProperties(ByteArray64Reader(animFile!!.bytes, Common.CHARSET))
|
||||
actor.sprite = AssembledSpriteAnimation(actor.animDesc!!, actor, if (bodypartsFile != null) disk else null, if (bodypartsFile != null) -1025 else null)
|
||||
actor.sprite = AssembledSpriteAnimation(
|
||||
actor.animDesc!!,
|
||||
actor,
|
||||
if (bodypartsFile != null) disk else null,
|
||||
if (bodypartsFile != null) BODYPART_TO_ENTRY_MAP else null
|
||||
)
|
||||
if (animFileGlow != null) {
|
||||
actor.animDescGlow = ADProperties(ByteArray64Reader(animFileGlow.bytes, Common.CHARSET))
|
||||
actor.spriteGlow = AssembledSpriteAnimation(actor.animDescGlow!!, actor, if (bodypartsFile != null) disk else null, if (bodypartsFile != null) -1025 else null)
|
||||
actor.spriteGlow = AssembledSpriteAnimation(
|
||||
actor.animDescGlow!!,
|
||||
actor,
|
||||
if (bodypartsFile != null) disk else null,
|
||||
if (bodypartsFile != null) BODYPARTGLOW_TO_ENTRY_MAP else null
|
||||
)
|
||||
}
|
||||
|
||||
ItemCodex.loadFromSave(disk.getBackingFile(), actor.dynamicToStaticTable, actor.dynamicItemInventory)
|
||||
|
||||
@@ -14,6 +14,7 @@ import net.torvald.terrarum.modulebasegame.TerrarumIngame
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
|
||||
import net.torvald.terrarum.realestate.LandUtil
|
||||
import net.torvald.terrarum.savegame.*
|
||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.worlddrawer.WorldCamera
|
||||
import java.io.File
|
||||
@@ -120,13 +121,13 @@ object LoadSavegame {
|
||||
*/
|
||||
operator fun invoke(playerDisk: DiskSkimmer, worldDisk0: DiskSkimmer? = null) {
|
||||
val newIngame = TerrarumIngame(App.batch)
|
||||
val player = ReadActor.invoke(playerDisk, ByteArray64Reader(playerDisk.getFile(-1L)!!.bytes, Common.CHARSET)) as IngamePlayer
|
||||
val player = ReadActor.invoke(playerDisk, ByteArray64Reader(playerDisk.getFile(SAVEGAMEINFO)!!.bytes, Common.CHARSET)) as IngamePlayer
|
||||
|
||||
printdbg(this, "Player localhash: ${player.localHashStr}, hasSprite: ${player.sprite != null}")
|
||||
|
||||
val currentWorldId = player.worldCurrentlyPlaying
|
||||
val worldDisk = worldDisk0 ?: App.savegameWorlds[currentWorldId]!!
|
||||
val world = ReadWorld(ByteArray64Reader(worldDisk.getFile(-1L)!!.bytes, Common.CHARSET), worldDisk.diskFile)
|
||||
val world = ReadWorld(ByteArray64Reader(worldDisk.getFile(SAVEGAMEINFO)!!.bytes, Common.CHARSET), worldDisk.diskFile)
|
||||
|
||||
world.layerTerrain = BlockLayer(world.width, world.height)
|
||||
world.layerWall = BlockLayer(world.width, world.height)
|
||||
|
||||
@@ -24,6 +24,9 @@ import net.torvald.terrarum.savegame.EntryFile
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.serialise.SaveLoadError
|
||||
import net.torvald.terrarum.modulebasegame.serialise.LoadSavegame
|
||||
import net.torvald.terrarum.savegame.VDFileID.BODYPART_TO_ENTRY_MAP
|
||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||
import net.torvald.terrarum.savegame.VDFileID.SPRITEDEF
|
||||
import net.torvald.terrarum.spriteassembler.ADProperties
|
||||
import net.torvald.terrarum.spriteassembler.ADProperties.Companion.EXTRA_HEADROOM_X
|
||||
import net.torvald.terrarum.spriteassembler.ADProperties.Companion.EXTRA_HEADROOM_Y
|
||||
@@ -497,7 +500,7 @@ class UIItemPlayerCells(
|
||||
private var playerUUID: UUID? = null
|
||||
|
||||
init {
|
||||
skimmer.getFile(-1L)?.bytes?.let {
|
||||
skimmer.getFile(SAVEGAMEINFO)?.bytes?.let {
|
||||
val json = JsonReader().parse(ByteArray64Reader(it, Common.CHARSET))
|
||||
|
||||
playerUUID = UUID.fromString(json["uuid"]?.asString())
|
||||
@@ -554,15 +557,15 @@ class UIItemPlayerCells(
|
||||
override fun render(batch: SpriteBatch, camera: Camera) {
|
||||
// try to generate a texture
|
||||
if (skimmer.initialised && !hasTexture) {
|
||||
skimmer.getFile(-1L)?.bytes?.let {
|
||||
skimmer.getFile(SAVEGAMEINFO)?.bytes?.let {
|
||||
try {
|
||||
printdbg(this, "Generating portrait for $playerName")
|
||||
val frameName = "ANIM_IDLE_1"
|
||||
val animFile = skimmer.getFile(-2L)!!
|
||||
val animFile = skimmer.getFile(SPRITEDEF)!!
|
||||
val props = ADProperties(ByteArray64Reader(animFile.bytes, Common.CHARSET))
|
||||
|
||||
val imagesSelfContained = skimmer.hasEntry(-1025L)
|
||||
val bodypartMapping = Properties().also { if (imagesSelfContained) it.load(ByteArray64Reader(skimmer.getFile(-1025L)!!.bytes, Common.CHARSET)) }
|
||||
val imagesSelfContained = skimmer.hasEntry(BODYPART_TO_ENTRY_MAP)
|
||||
val bodypartMapping = Properties().also { if (imagesSelfContained) it.load(ByteArray64Reader(skimmer.getFile(BODYPART_TO_ENTRY_MAP)!!.bytes, Common.CHARSET)) }
|
||||
|
||||
val fileGetter = if (imagesSelfContained)
|
||||
AssembleSheetPixmap.getVirtualDiskFileGetter(bodypartMapping, skimmer)
|
||||
|
||||
@@ -20,6 +20,7 @@ import net.torvald.terrarum.savegame.ByteArray64Reader
|
||||
import net.torvald.terrarum.savegame.VirtualDisk
|
||||
import net.torvald.terrarum.serialise.Common
|
||||
import net.torvald.terrarum.modulebasegame.serialise.ReadActor
|
||||
import net.torvald.terrarum.savegame.VDFileID.SAVEGAMEINFO
|
||||
import net.torvald.terrarum.ui.*
|
||||
import net.torvald.terrarum.utils.RandomWordsName
|
||||
|
||||
@@ -91,7 +92,7 @@ class UINewWorld(val remoCon: UIRemoCon) : UICanvas() {
|
||||
// printdbg(this, "generate! Size=${sizeSelector.selection}, Name=${nameInput.getTextOrPlaceholder()}, Seed=${seedInput.getTextOrPlaceholder()}")
|
||||
|
||||
val ingame = TerrarumIngame(App.batch)
|
||||
val player = ReadActor.invoke(UILoadGovernor.playerDisk!!, ByteArray64Reader(UILoadGovernor.playerDisk!!.getFile(-1L)!!.bytes, Common.CHARSET)) as IngamePlayer
|
||||
val player = ReadActor.invoke(UILoadGovernor.playerDisk!!, ByteArray64Reader(UILoadGovernor.playerDisk!!.getFile(SAVEGAMEINFO)!!.bytes, Common.CHARSET)) as IngamePlayer
|
||||
val seed = try {
|
||||
seedInput.getTextOrPlaceholder().toLong()
|
||||
}
|
||||
|
||||
@@ -234,20 +234,31 @@ class VirtualDisk(
|
||||
}
|
||||
}
|
||||
|
||||
object VDFileID {
|
||||
const val ROOT = 0L
|
||||
const val SAVEGAMEINFO = -1L
|
||||
const val THUMBNAIL = -2L
|
||||
const val SPRITEDEF = -2L
|
||||
const val SPRITEDEF_GLOW = -3L
|
||||
const val LOADORDER = -4L
|
||||
const val BODYPART_TO_ENTRY_MAP = -1025L
|
||||
const val BODYPARTGLOW_TO_ENTRY_MAP = -1026L
|
||||
}
|
||||
|
||||
fun diskIDtoReadableFilename(id: EntryID): String = when (id) {
|
||||
0L -> "root"
|
||||
-1L -> "savegameinfo.json"
|
||||
-2L -> "thumbnail.tga.gz (world)/spritedef (player)"
|
||||
-3L -> "spritedef-glow (player)"
|
||||
-4L -> "loadOrder.txt"
|
||||
VDFileID.ROOT -> "root"
|
||||
VDFileID.SAVEGAMEINFO -> "savegameinfo.json"
|
||||
VDFileID.THUMBNAIL, VDFileID.SPRITEDEF -> "thumbnail.tga.gz (world)/spritedef (player)"
|
||||
VDFileID.SPRITEDEF_GLOW -> "spritedef-glow (player)"
|
||||
VDFileID.LOADORDER -> "loadOrder.txt"
|
||||
// -16L -> "blockcodex.json.gz"
|
||||
// -17L -> "itemcodex.json.gz"
|
||||
// -18L -> "wirecodex.json.gz"
|
||||
// -19L -> "materialcodex.json.gz"
|
||||
// -20L -> "factioncodex.json.gz"
|
||||
// -1024L -> "apocryphas.json.gz"
|
||||
-1025L -> "bodypart-to-entry.map"
|
||||
-1026L -> "bodypartglow-to-entry.map"
|
||||
VDFileID.BODYPART_TO_ENTRY_MAP -> "bodypart-to-entry.map"
|
||||
VDFileID.BODYPARTGLOW_TO_ENTRY_MAP -> "bodypartglow-to-entry.map"
|
||||
in 1..65535 -> "bodypart #$id.tga.gz (player)"
|
||||
in 1048576..2147483647 -> "actor #$id.json"
|
||||
in 0x0000_0001_0000_0000L..0x0000_FFFF_FFFF_FFFFL ->
|
||||
|
||||
Reference in New Issue
Block a user