diff --git a/src/net/torvald/spriteanimation/HasAssembledSprite.kt b/src/net/torvald/spriteanimation/HasAssembledSprite.kt index 33742672e..edf19075e 100644 --- a/src/net/torvald/spriteanimation/HasAssembledSprite.kt +++ b/src/net/torvald/spriteanimation/HasAssembledSprite.kt @@ -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) diff --git a/src/net/torvald/spriteassembler/ADProperties.kt b/src/net/torvald/spriteassembler/ADProperties.kt index 6972dfb79..c999c8922 100644 --- a/src/net/torvald/spriteassembler/ADProperties.kt +++ b/src/net/torvald/spriteassembler/ADProperties.kt @@ -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 { diff --git a/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt b/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt index 7249f3a3e..333b50bb4 100644 --- a/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt +++ b/src/net/torvald/spriteassembler/AssembleSheetPixmap.kt @@ -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) diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 1c8c5662a..19c77ef2d 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -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) { diff --git a/src/net/torvald/terrarum/modulebasegame/console/ImportWorld.kt b/src/net/torvald/terrarum/modulebasegame/console/ImportWorld.kt index 84c137423..448a2be80 100644 --- a/src/net/torvald/terrarum/modulebasegame/console/ImportWorld.kt +++ b/src/net/torvald/terrarum/modulebasegame/console/ImportWorld.kt @@ -34,7 +34,7 @@ object ImportWorld : ConsoleCommand { Echo("Usage: Importworld filename-without-extension") } } - +/* object ImportActor : ConsoleCommand { override fun execute(args: Array) { if (args.size == 2) { @@ -56,4 +56,4 @@ object ImportActor : ConsoleCommand { override fun printUsage() { Echo("Usage: Importactor filename-without-extension") } -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt index cdf9d5e4c..c1ffe978f 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt @@ -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 } diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt index 3b7d7e017..2c9c0342f 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt @@ -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 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt index 847a0fc95..175296a28 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderWerebeastTest.kt @@ -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) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewBuildingMaker.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewBuildingMaker.kt index cea57a0e8..3704abb55 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewBuildingMaker.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewBuildingMaker.kt @@ -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") } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewRandomGame.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewRandomGame.kt index 32b040ddb..5b6ecc200 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewRandomGame.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIProxyNewRandomGame.kt @@ -31,7 +31,6 @@ class UIProxyNewRandomGame : UICanvas() { } override fun doClosing(delta: Float) { - TODO("not implemented") } override fun endOpening(delta: Float) { diff --git a/src/net/torvald/terrarum/serialise/WriteActor.kt b/src/net/torvald/terrarum/serialise/WriteActor.kt index b2d4a8a7e..652254fb0 100644 --- a/src/net/torvald/terrarum/serialise/WriteActor.kt +++ b/src/net/torvald/terrarum/serialise/WriteActor.kt @@ -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 diff --git a/src/net/torvald/terrarum/tvda/DiskSkimmer.kt b/src/net/torvald/terrarum/tvda/DiskSkimmer.kt index 5127eb837..6be6b2dcf 100644 --- a/src/net/torvald/terrarum/tvda/DiskSkimmer.kt +++ b/src/net/torvald/terrarum/tvda/DiskSkimmer.kt @@ -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. diff --git a/src/net/torvald/terrarum/tvda/SimpleFileSystem.kt b/src/net/torvald/terrarum/tvda/SimpleFileSystem.kt new file mode 100644 index 000000000..34adba0d9 --- /dev/null +++ b/src/net/torvald/terrarum/tvda/SimpleFileSystem.kt @@ -0,0 +1,8 @@ +package net.torvald.terrarum.tvda + +/** + * Created by minjaesong on 2021-10-07. + */ +interface SimpleFileSystem { + fun getFile(id: EntryID): EntryFile? +} \ No newline at end of file diff --git a/src/net/torvald/terrarum/tvda/VirtualDisk.kt b/src/net/torvald/terrarum/tvda/VirtualDisk.kt index 3592c226a..b3e0a322f 100644 --- a/src/net/torvald/terrarum/tvda/VirtualDisk.kt +++ b/src/net/torvald/terrarum/tvda/VirtualDisk.kt @@ -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() 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 { diff --git a/src/net/torvald/util/ArrayListMap.kt b/src/net/torvald/util/ArrayListMap.kt index 93711cc31..411aa7de7 100644 --- a/src/net/torvald/util/ArrayListMap.kt +++ b/src/net/torvald/util/ArrayListMap.kt @@ -84,7 +84,8 @@ class ArrayListMap : MutableMap { } 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): V? {