new save format wip (no branching on this commit)

This commit is contained in:
minjaesong
2021-10-07 14:40:04 +09:00
parent d6a22f6567
commit 6d8a7520ac
15 changed files with 94 additions and 39 deletions

View File

@@ -4,6 +4,8 @@ import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Texture
import net.torvald.spriteassembler.ADProperties
import net.torvald.spriteassembler.AssembleSheetPixmap
import net.torvald.terrarum.tvda.DiskSkimmer
import net.torvald.terrarum.tvda.SimpleFileSystem
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
@@ -12,9 +14,9 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
interface HasAssembledSprite {
/** ADL path for main sprite. Necessary. */
var animDescPath: String
var animDesc: ADProperties?
/** ADL path for glow sprite. Optional. */
var animDescPathGlow: String?
var animDescGlow: ADProperties?
// FIXME sometimes the animmation is invisible (row and nFrames mismatch -- row is changed to 1 but it's drawing 3rd frame?)
@@ -28,10 +30,11 @@ interface HasAssembledSprite {
* reassembleSprite(this.sprite, this.spriteGlow)
* ```
*/
fun reassembleSprite(sprite: SpriteAnimation, spriteGlow: SpriteAnimation? = null) {
_rebuild(ADProperties(Gdx.files.internal(animDescPath)), sprite)
if (animDescPathGlow != null && spriteGlow != null)
_rebuild(ADProperties(Gdx.files.internal(animDescPathGlow)), spriteGlow)
fun reassembleSprite(sprite: SpriteAnimation?, anim: ADProperties?, spriteGlow: SpriteAnimation? = null, animGlow: ADProperties? = null) {
if (anim != null && sprite != null)
_rebuild(anim, sprite)
if (animGlow != null && spriteGlow != null)
_rebuild(animGlow, spriteGlow)
}
/*fun rebuild(animDescPath: String, spriteAnimation: SpriteAnimation) {
@@ -50,6 +53,8 @@ interface HasAssembledSprite {
private fun _rebuild(ad: ADProperties, sprite: SpriteAnimation) {
// TODO injecting held item/armour pictures? Would it be AssembleSheetPixmap's job?
// TODO resolve bodyparts (must read ID-to-bodypartmap.properties first)
val pixmap = AssembleSheetPixmap(ad)
val texture = Texture(pixmap)
texture.setFilter(Texture.TextureFilter.Nearest, Texture.TextureFilter.Nearest)

View File

@@ -2,6 +2,7 @@ package net.torvald.spriteassembler
import com.badlogic.gdx.files.FileHandle
import net.torvald.terrarum.linearSearchBy
import net.torvald.terrarum.serialise.Common
import java.io.InputStream
import java.io.Reader
import java.util.*
@@ -33,6 +34,7 @@ internal data class Transform(val joint: Joint, val translate: ADPropertyObject.
class ADProperties {
private var fileFrom = ""
private var adlString = ""
private val javaProp = Properties()
/** Every key is CAPITALISED */
@@ -68,30 +70,31 @@ class ADProperties {
var rows = -1; private set
var cols = -1; private set
fun getRawADL() = adlString
companion object {
const val ALL_JOINT_SELECT_KEY = "ALL"
}
constructor(gdxFile: FileHandle) {
fileFrom = gdxFile.path()
adlString = gdxFile.readString(Common.CHARSET.name())
javaProp.load(gdxFile.read())
continueLoad()
}
constructor(reader: Reader) {
adlString = reader.readText()
javaProp.load(reader)
continueLoad()
}
constructor(inputStream: InputStream) {
adlString = inputStream.readAllBytes().toString(Common.CHARSET)
javaProp.load(inputStream)
continueLoad()
}
constructor(javaProp: Properties) {
this.javaProp.putAll(javaProp.toMap())
}
private fun continueLoad() {
// sanity check
reservedProps.forEach {

View File

@@ -2,7 +2,9 @@ package net.torvald.spriteassembler
import com.badlogic.gdx.Gdx
import com.badlogic.gdx.graphics.Pixmap
import com.badlogic.gdx.utils.GdxRuntimeException
import net.torvald.terrarum.linearSearch
import java.io.InputStream
/**
* Assembles the single frame of the animation, outputs GDX Pixmap.
@@ -17,10 +19,13 @@ object AssembleSheetPixmap {
val canvas = Pixmap(properties.cols * properties.frameWidth, properties.rows * properties.frameHeight, Pixmap.Format.RGBA8888)
canvas.blending = Pixmap.Blending.SourceOver
val fileGetter = { path: String ->
Gdx.files.internal(path).read()
}
// actually draw
properties.transforms.forEach { t, _ ->
drawThisFrame(t, canvas, properties)
drawThisFrame(t, canvas, properties, fileGetter)
}
return canvas
@@ -28,15 +33,21 @@ object AssembleSheetPixmap {
private fun drawThisFrame(frameName: String,
canvas: Pixmap,
properties: ADProperties
properties: ADProperties,
fileGetter: (String) -> InputStream
) {
val theAnim = properties.getAnimByFrameName(frameName)
val skeleton = theAnim.skeleton.joints.reversed()
val transforms = properties.getTransform(frameName)
val bodypartOrigins = properties.bodyparts
val bodypartImages = properties.bodyparts.keys.map {
val file = Gdx.files.internal("assets/${properties.toFilename(it)}")
it to (if (file.exists()) Pixmap(file) else null)
try {
val bytes = fileGetter("assets/${properties.toFilename(it)}").readAllBytes()
it to Pixmap(bytes, 0, bytes.size)
}
catch (e: GdxRuntimeException) {
it to null
}
}.toMap()
val transformList = AssembleFrameBase.makeTransformList(skeleton, transforms)

View File

@@ -287,7 +287,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
private fun postInitForLoadFromSave(codices: Codices) {
codices.actors.forEach {
try {
val actor = ReadActor(LoadSavegame.getFileReader(codices.disk, it.toLong()))
val actor = ReadActor(codices.disk, LoadSavegame.getFileReader(codices.disk, it.toLong()))
addNewActor(actor)
}
catch (e: NullPointerException) {

View File

@@ -34,7 +34,7 @@ object ImportWorld : ConsoleCommand {
Echo("Usage: Importworld filename-without-extension")
}
}
/*
object ImportActor : ConsoleCommand {
override fun execute(args: Array<String>) {
if (args.size == 2) {
@@ -56,4 +56,4 @@ object ImportActor : ConsoleCommand {
override fun printUsage() {
Echo("Usage: Importactor filename-without-extension")
}
}
}*/

View File

@@ -1,6 +1,8 @@
package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.Gdx
import net.torvald.spriteanimation.HasAssembledSprite
import net.torvald.spriteassembler.ADProperties
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.gameactors.AVKey
@@ -13,15 +15,15 @@ import net.torvald.terrarum.gameactors.AVKey
class IngamePlayer : ActorHumanoid, HasAssembledSprite {
override var animDescPath = "invalid"
override var animDescPathGlow: String? = null
override var animDesc: ADProperties? = null
override var animDescGlow: ADProperties? = null
internal var worldCurrentlyPlaying = 0 // only filled up on save and load; DO NOT USE THIS
private constructor()
constructor(animDescPath: String, animDescPathGlow: String?, born: Long) : super(born) {
this.animDescPath = animDescPath
this.animDescPathGlow = animDescPathGlow
animDesc = ADProperties(Gdx.files.internal(animDescPath))
if (animDescPathGlow != null) animDescGlow = ADProperties(Gdx.files.internal(animDescPathGlow))
actorValue[AVKey.__HISTORICAL_BORNTIME] = born
}

View File

@@ -31,7 +31,7 @@ object PlayerBuilderTestSubject1 {
p.sprite = SpriteAnimation(p)
p.spriteGlow = SpriteAnimation(p)
p.reassembleSprite(p.sprite!!, p.spriteGlow)
p.reassembleSprite(p.sprite, p.animDesc, p.spriteGlow, p.animDescGlow)
p.setHitboxDimension(15, p.actorValue.getAsInt(AVKey.BASEHEIGHT) ?: ActorHumanoid.BASE_HEIGHT, 21, 0)
// ingame must teleport the player to the spawn point

View File

@@ -31,7 +31,7 @@ object PlayerBuilderWerebeastTest {
p.sprite = SpriteAnimation(p)
p.spriteGlow = SpriteAnimation(p)
p.reassembleSprite(p.sprite!!, p.spriteGlow)
p.reassembleSprite(p.sprite, p.animDesc, p.spriteGlow, p.animDescGlow)
p.setHitboxDimension(22, p.actorValue.getAsInt(AVKey.BASEHEIGHT)!!, 30, 0)
p.setPosition(3.0 * TILE_SIZE, 3.0 * TILE_SIZE)

View File

@@ -28,7 +28,6 @@ class UIProxyNewBuildingMaker : UICanvas() {
}
override fun doClosing(delta: Float) {
TODO("not implemented")
}
override fun endOpening(delta: Float) {
@@ -40,10 +39,8 @@ class UIProxyNewBuildingMaker : UICanvas() {
}
override fun endClosing(delta: Float) {
TODO("not implemented")
}
override fun dispose() {
TODO("not implemented")
}
}

View File

@@ -31,7 +31,6 @@ class UIProxyNewRandomGame : UICanvas() {
}
override fun doClosing(delta: Float) {
TODO("not implemented")
}
override fun endOpening(delta: Float) {

View File

@@ -2,14 +2,15 @@ package net.torvald.terrarum.serialise
import net.torvald.spriteanimation.HasAssembledSprite
import net.torvald.spriteanimation.SpriteAnimation
import net.torvald.spriteassembler.ADProperties
import net.torvald.terrarum.NoSuchActorWithIDException
import net.torvald.terrarum.gameactors.Actor
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer
import net.torvald.terrarum.modulebasegame.gameactors.Pocketed
import net.torvald.terrarum.tvda.ByteArray64
import net.torvald.terrarum.tvda.ByteArray64Writer
import net.torvald.terrarum.tvda.*
import java.io.Reader
/**
@@ -42,6 +43,22 @@ object WriteActor {
}
/**
* Player-specific [WriteActor].
*
* Created by minjaesong on 2021-10-07.
*/
object WritePlayer {
operator fun invoke(player: IngamePlayer, disk: VirtualDisk) {
val actorJson = WriteActor.encodeToByteArray64(player)
val adl = player.animDesc?.getRawADL() // NULLABLE!
val adlGlow = player.animDescGlow?.getRawADL() // NULLABLE!
}
operator fun invoke(player: IngamePlayer, skimmer: DiskSkimmer) {
}
}
/**
@@ -54,29 +71,37 @@ object WriteActor {
*/
object ReadActor {
operator fun invoke(worldDataStream: Reader): Actor =
fillInDetails(Common.jsoner.fromJson(null, worldDataStream))
operator fun invoke(disk: SimpleFileSystem, worldDataStream: Reader): Actor =
fillInDetails(disk, Common.jsoner.fromJson(null, worldDataStream))
fun readActorBare(worldDataStream: Reader): Actor =
Common.jsoner.fromJson(null, worldDataStream)
private fun fillInDetails(actor: Actor): Actor {
private fun fillInDetails(disk: SimpleFileSystem, actor: Actor): Actor {
actor.actorValue.actor = actor
if (actor is Pocketed)
actor.inventory.actor = actor
if (actor is ActorWithBody && actor is HasAssembledSprite) {
val animFile = disk.getFile(-2L)
val animFileGlow = disk.getFile(-3L)
actor.sprite = SpriteAnimation(actor)
if (actor.animDescPathGlow != null) actor.spriteGlow = SpriteAnimation(actor)
actor.reassembleSprite(actor.sprite ?: throw InternalError("actor.sprite (type: SpriteAnimation) is null"), actor.spriteGlow)
if (animFileGlow != null) actor.spriteGlow = SpriteAnimation(actor)
actor.reassembleSprite(
actor.sprite!!,
ADProperties(ByteArray64Reader(animFile!!.bytes, Common.CHARSET)),
actor.spriteGlow,
if (animFileGlow == null) null else ADProperties(ByteArray64Reader(animFileGlow.bytes, Common.CHARSET))
)
}
return actor
}
fun readActorAndAddToWorld(ingame: TerrarumIngame, worldDataStream: Reader): Actor {
val actor = invoke(worldDataStream)
fun readActorAndAddToWorld(ingame: TerrarumIngame, disk: SimpleFileSystem, worldDataStream: Reader): Actor {
val actor = invoke(disk, worldDataStream)
// replace existing player
val oldPlayerID = ingame.actorNowPlaying?.referenceID

View File

@@ -23,7 +23,7 @@ class DiskSkimmer(
val diskFile: File,
val charset: Charset = Charset.defaultCharset(),
noInit: Boolean = false
) {
): SimpleFileSystem {
/*
@@ -250,6 +250,8 @@ removefile:
}
}
override fun getFile(id: EntryID) = requestFile(id)?.contents as? EntryFile
/**
* Try to find a file with given path (which uses '/' as a separator). Is search is failed for whatever reason,
* `null` is returned.

View File

@@ -0,0 +1,8 @@
package net.torvald.terrarum.tvda
/**
* Created by minjaesong on 2021-10-07.
*/
interface SimpleFileSystem {
fun getFile(id: EntryID): EntryFile?
}

View File

@@ -124,7 +124,7 @@ class VirtualDisk(
/** capacity of 0 makes the disk read-only */
var capacity: Long,
var diskName: ByteArray = ByteArray(NAME_LENGTH)
) {
): SimpleFileSystem {
var extraInfoBytes = ByteArray(16)
val entries = HashMap<EntryID, DiskEntry>()
var isReadOnly: Boolean
@@ -143,6 +143,8 @@ class VirtualDisk(
extraInfoBytes = footer.toByteArray()
}
override fun getFile(id: EntryID) = try { VDUtil.getAsNormalFile(this, id) } catch (e: NullPointerException) { null }
private fun serializeEntriesOnly(): ByteArray64 {
val buffer = ByteArray64()
entries.forEach {

View File

@@ -84,7 +84,8 @@ class ArrayListMap<K, V> : MutableMap<K, V> {
}
override fun clear() {
TODO("not implemented") //To change body of created functions use File | Settings | File Templates.
keysArray.clear()
valuesArray.clear()
}
override fun compute(key: K, remappingFunction: BiFunction<in K, in V?, out V?>): V? {