From f89c2618fd9b75227ba160b306c5a0ac62442723 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Thu, 26 Sep 2024 00:44:41 +0900 Subject: [PATCH] automated avatar building & fix avatar import --- .idea/artifacts/SpriteAssemblerApp.xml | 104 +++++------ assets/mods/basegame/sprites/fofu.properties | 31 ++++ .../sprites/fofu/fofu_arm_rest_left.tga | 3 + .../sprites/fofu/fofu_arm_rest_right.tga | 3 + .../mods/basegame/sprites/fofu/fofu_head.tga | 3 + .../sprites/fofu/fofu_leg_rest_left.tga | 3 + .../sprites/fofu/fofu_leg_rest_right.tga | 3 + .../basegame/sprites/fofu/fofu_tail_0.tga | 3 + .../mods/basegame/sprites/fofu/fofu_torso.tga | 3 + .../basegame/sprites/fofu_emsv.properties | 31 ++++ .../basegame/sprites/fofu_glow.properties | 31 ++++ .../gameactors/PlayerBuilderTestSubject1.kt | 6 +- .../modulebasegame/ui/UIImportAvatar.kt | 19 +- .../torvald/terrarum/savegame/VirtualDisk.kt | 8 +- .../terrarum/spriteassembler/AvatarBuilder.kt | 166 ++++++++++++++++++ .../graphics/sprites/furbud3_jointed.psd | 3 + 16 files changed, 358 insertions(+), 62 deletions(-) create mode 100644 assets/mods/basegame/sprites/fofu.properties create mode 100644 assets/mods/basegame/sprites/fofu/fofu_arm_rest_left.tga create mode 100644 assets/mods/basegame/sprites/fofu/fofu_arm_rest_right.tga create mode 100644 assets/mods/basegame/sprites/fofu/fofu_head.tga create mode 100644 assets/mods/basegame/sprites/fofu/fofu_leg_rest_left.tga create mode 100644 assets/mods/basegame/sprites/fofu/fofu_leg_rest_right.tga create mode 100644 assets/mods/basegame/sprites/fofu/fofu_tail_0.tga create mode 100644 assets/mods/basegame/sprites/fofu/fofu_torso.tga create mode 100644 assets/mods/basegame/sprites/fofu_emsv.properties create mode 100644 assets/mods/basegame/sprites/fofu_glow.properties create mode 100644 src/net/torvald/terrarum/spriteassembler/AvatarBuilder.kt create mode 100644 work_files/graphics/sprites/furbud3_jointed.psd diff --git a/.idea/artifacts/SpriteAssemblerApp.xml b/.idea/artifacts/SpriteAssemblerApp.xml index db463884b..ecaa3f1da 100644 --- a/.idea/artifacts/SpriteAssemblerApp.xml +++ b/.idea/artifacts/SpriteAssemblerApp.xml @@ -1,7 +1,7 @@ $PROJECT_DIR$/out - + @@ -31,56 +31,58 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/assets/mods/basegame/sprites/fofu.properties b/assets/mods/basegame/sprites/fofu.properties new file mode 100644 index 000000000..7b6227f07 --- /dev/null +++ b/assets/mods/basegame/sprites/fofu.properties @@ -0,0 +1,31 @@ +SPRITESHEET=mods/basegame/sprites/fofu/fofu_ +EXTENSION=.tga +CONFIG=SIZE 48,56;ORIGINX 29 +BODYPARTS=HEADGEAR 11,11;\ + HEAD 11,11;\ + ARM_REST_RIGHT 4,2;\ + ARM_REST_LEFT 4,2;\ + LEG_REST_RIGHT 4,7;\ + LEG_REST_LEFT 4,7;\ + TORSO 10,4;\ + TAIL_0 20,1;\ + HELD_ITEM 0,0 +SKELETON_STAND=HEADGEAR 0,32;HAIR_FORE 0,32;\ + ARM_REST_RIGHT -7,23;HELD_ITEM -6,11;\ + HAIR 0,32;HEAD 0,32;\ + TORSO 0,22;\ + LEG_REST_RIGHT -2,7;\ + LEG_REST_LEFT 2,7;\ + ARM_REST_LEFT 5,24;\ + TAIL_0 0,13 +ANIM_RUN=DELAY 0.15;ROW 2;SKELETON SKELETON_STAND +ANIM_RUN_1=LEG_REST_RIGHT 1,1;LEG_REST_LEFT -1,0 +ANIM_RUN_2=ALL 0,1;LEG_REST_RIGHT 0,-1;LEG_REST_LEFT 0,1 +ANIM_RUN_3=LEG_REST_RIGHT -1,0;LEG_REST_LEFT 1,1 +ANIM_RUN_4=ALL 0,1;LEG_REST_RIGHT 0,1;LEG_REST_LEFT 0,-1 + +ANIM_IDLE=DELAY 2;ROW 1;SKELETON SKELETON_STAND +ANIM_IDLE_1= +ANIM_IDLE_2=TORSO 0,-1;HEAD 0,-1;HAIR 0,-1;HELD_ITEM 0,-1;\ + ARM_REST_LEFT 0,-1;ARM_REST_RIGHT 0,-1;\ + HAIR_FORE 0,-1;HEADGEAR 0,-1 diff --git a/assets/mods/basegame/sprites/fofu/fofu_arm_rest_left.tga b/assets/mods/basegame/sprites/fofu/fofu_arm_rest_left.tga new file mode 100644 index 000000000..1cfca3386 --- /dev/null +++ b/assets/mods/basegame/sprites/fofu/fofu_arm_rest_left.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:6cf19b53078ccbfaa9507432e3acbb92e7c2ab740dd8e9fc4089618e46744471 +size 494 diff --git a/assets/mods/basegame/sprites/fofu/fofu_arm_rest_right.tga b/assets/mods/basegame/sprites/fofu/fofu_arm_rest_right.tga new file mode 100644 index 000000000..784b1fe71 --- /dev/null +++ b/assets/mods/basegame/sprites/fofu/fofu_arm_rest_right.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5ef7de78785900388c985bda74e7c098eb3bc1db372e9ffe88a2015049fe4d10 +size 522 diff --git a/assets/mods/basegame/sprites/fofu/fofu_head.tga b/assets/mods/basegame/sprites/fofu/fofu_head.tga new file mode 100644 index 000000000..5848f0ec3 --- /dev/null +++ b/assets/mods/basegame/sprites/fofu/fofu_head.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a2ed69862aa0e9b18944b9dda88f9963f86742fb8dc4e657dd414947303a87c5 +size 1386 diff --git a/assets/mods/basegame/sprites/fofu/fofu_leg_rest_left.tga b/assets/mods/basegame/sprites/fofu/fofu_leg_rest_left.tga new file mode 100644 index 000000000..37b592c41 --- /dev/null +++ b/assets/mods/basegame/sprites/fofu/fofu_leg_rest_left.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d222c44c4e1513dbb2cd45ffc2d7d4863b8d908e5ecfd430976de7c477a8d606 +size 498 diff --git a/assets/mods/basegame/sprites/fofu/fofu_leg_rest_right.tga b/assets/mods/basegame/sprites/fofu/fofu_leg_rest_right.tga new file mode 100644 index 000000000..2980acd16 --- /dev/null +++ b/assets/mods/basegame/sprites/fofu/fofu_leg_rest_right.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b007d035a24ef38e2c4be1f8b6b5df3e600668ebad6af197d02d2475fc6df165 +size 498 diff --git a/assets/mods/basegame/sprites/fofu/fofu_tail_0.tga b/assets/mods/basegame/sprites/fofu/fofu_tail_0.tga new file mode 100644 index 000000000..7c846c78d --- /dev/null +++ b/assets/mods/basegame/sprites/fofu/fofu_tail_0.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:58091d6a61f3a3760ad4b3e9d9ce2f42efe1c2b93ef937879c7bcd073ed2ff63 +size 930 diff --git a/assets/mods/basegame/sprites/fofu/fofu_torso.tga b/assets/mods/basegame/sprites/fofu/fofu_torso.tga new file mode 100644 index 000000000..a94cbe647 --- /dev/null +++ b/assets/mods/basegame/sprites/fofu/fofu_torso.tga @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2cd67722cef6eacdb17f86528bf65ca7c5ecde58edf77cb7d37fdb5e9da8caaf +size 914 diff --git a/assets/mods/basegame/sprites/fofu_emsv.properties b/assets/mods/basegame/sprites/fofu_emsv.properties new file mode 100644 index 000000000..66b444ded --- /dev/null +++ b/assets/mods/basegame/sprites/fofu_emsv.properties @@ -0,0 +1,31 @@ +SPRITESHEET=mods/basegame/sprites/fofu/fofuemsv_ +EXTENSION=.tga +CONFIG=SIZE 48,56;ORIGINX 29 +BODYPARTS=HEADGEAR 11,11;\ + HEAD 11,11;\ + ARM_REST_RIGHT 4,2;\ + ARM_REST_LEFT 4,2;\ + LEG_REST_RIGHT 4,7;\ + LEG_REST_LEFT 4,7;\ + TORSO 10,4;\ + TAIL_0 20,1;\ + HELD_ITEM 0,0 +SKELETON_STAND=HEADGEAR 0,32;HAIR_FORE 0,32;\ + ARM_REST_RIGHT -7,23;HELD_ITEM -6,11;\ + HAIR 0,32;HEAD 0,32;\ + TORSO 0,22;\ + LEG_REST_RIGHT -2,7;\ + LEG_REST_LEFT 2,7;\ + ARM_REST_LEFT 5,24;\ + TAIL_0 0,13 +ANIM_RUN=DELAY 0.15;ROW 2;SKELETON SKELETON_STAND +ANIM_RUN_1=LEG_REST_RIGHT 1,1;LEG_REST_LEFT -1,0 +ANIM_RUN_2=ALL 0,1;LEG_REST_RIGHT 0,-1;LEG_REST_LEFT 0,1 +ANIM_RUN_3=LEG_REST_RIGHT -1,0;LEG_REST_LEFT 1,1 +ANIM_RUN_4=ALL 0,1;LEG_REST_RIGHT 0,1;LEG_REST_LEFT 0,-1 + +ANIM_IDLE=DELAY 2;ROW 1;SKELETON SKELETON_STAND +ANIM_IDLE_1= +ANIM_IDLE_2=TORSO 0,-1;HEAD 0,-1;HAIR 0,-1;HELD_ITEM 0,-1;\ + ARM_REST_LEFT 0,-1;ARM_REST_RIGHT 0,-1;\ + HAIR_FORE 0,-1;HEADGEAR 0,-1 diff --git a/assets/mods/basegame/sprites/fofu_glow.properties b/assets/mods/basegame/sprites/fofu_glow.properties new file mode 100644 index 000000000..629b44acd --- /dev/null +++ b/assets/mods/basegame/sprites/fofu_glow.properties @@ -0,0 +1,31 @@ +SPRITESHEET=mods/basegame/sprites/fofu/fofuglow_ +EXTENSION=.tga +CONFIG=SIZE 48,56;ORIGINX 29 +BODYPARTS=HEADGEAR 11,11;\ + HEAD 11,11;\ + ARM_REST_RIGHT 4,2;\ + ARM_REST_LEFT 4,2;\ + LEG_REST_RIGHT 4,7;\ + LEG_REST_LEFT 4,7;\ + TORSO 10,4;\ + TAIL_0 20,1;\ + HELD_ITEM 0,0 +SKELETON_STAND=HEADGEAR 0,32;HAIR_FORE 0,32;\ + ARM_REST_RIGHT -7,23;HELD_ITEM -6,11;\ + HAIR 0,32;HEAD 0,32;\ + TORSO 0,22;\ + LEG_REST_RIGHT -2,7;\ + LEG_REST_LEFT 2,7;\ + ARM_REST_LEFT 5,24;\ + TAIL_0 0,13 +ANIM_RUN=DELAY 0.15;ROW 2;SKELETON SKELETON_STAND +ANIM_RUN_1=LEG_REST_RIGHT 1,1;LEG_REST_LEFT -1,0 +ANIM_RUN_2=ALL 0,1;LEG_REST_RIGHT 0,-1;LEG_REST_LEFT 0,1 +ANIM_RUN_3=LEG_REST_RIGHT -1,0;LEG_REST_LEFT 1,1 +ANIM_RUN_4=ALL 0,1;LEG_REST_RIGHT 0,1;LEG_REST_LEFT 0,-1 + +ANIM_IDLE=DELAY 2;ROW 1;SKELETON SKELETON_STAND +ANIM_IDLE_1= +ANIM_IDLE_2=TORSO 0,-1;HEAD 0,-1;HAIR 0,-1;HELD_ITEM 0,-1;\ + ARM_REST_LEFT 0,-1;ARM_REST_RIGHT 0,-1;\ + HAIR_FORE 0,-1;HEADGEAR 0,-1 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt index f23b831bd..edaf0ca1d 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/PlayerBuilderTestSubject1.kt @@ -10,9 +10,9 @@ import net.torvald.terrarum.gameactors.AVKey object PlayerBuilderTestSubject1 { operator fun invoke(): IngamePlayer { val p: IngamePlayer = IngamePlayer( - ModMgr.getGdxFile("basegame", "sprites/test_sprite.properties").path(), - ModMgr.getGdxFile("basegame", "sprites/test_sprite_glow.properties").path(), - ModMgr.getGdxFile("basegame", "sprites/test_sprite_emsv.properties").path(), + ModMgr.getGdxFile("basegame", "sprites/fofu.properties").path(), + ModMgr.getGdxFile("basegame", "sprites/fofu_glow.properties").path(), + ModMgr.getGdxFile("basegame", "sprites/fofu_emsv.properties").path(), 0L // random value thrown ) InjectCreatureRaw(p.actorValue, "basegame", "CreaturePlayer.json") diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIImportAvatar.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIImportAvatar.kt index 292d85719..a3c77c7e2 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIImportAvatar.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIImportAvatar.kt @@ -65,8 +65,9 @@ class UIImportAvatar(val remoCon: UIRemoCon) : Advanceable() { it.clickOnceListener = { _,_ -> if (filenameInput.getText().isNotBlank()) { - importReturnCode = doImport() - if (importReturnCode == 0) remoCon.openUI(UILoadSavegame(remoCon)) + val (importReturnCode, avatarDisk) = doImport() + this.importReturnCode = importReturnCode + if (importReturnCode == 0) remoCon.openUI(UINewWorld(remoCon, avatarDisk!!)) } } } @@ -143,14 +144,16 @@ class UIImportAvatar(val remoCon: UIRemoCon) : Advanceable() { override fun advanceMode(button: UIItem) { } - private fun doImport(): Int { + private fun doImport(): Pair { val file = File("${App.importDir}/${filenameInput.getText().trim()}") // check file's existence if (!file.exists()) { - return 1 + return 1 to null } + var retDisk: DiskSkimmer? = null + // try to mount the TEVd try { val dom = VDUtil.readDiskArchive(file) @@ -164,7 +167,7 @@ class UIImportAvatar(val remoCon: UIRemoCon) : Advanceable() { printdbg(this, "Avatar uuid: $uuid") - if (newFile.exists()) return 2 + if (newFile.exists()) return 2 to null // update playerinfo so that: // totalPlayTime to zero @@ -212,6 +215,8 @@ class UIImportAvatar(val remoCon: UIRemoCon) : Advanceable() { App.sortedPlayers.add(0, playerUUID) App.savegamePlayersName[playerUUID] = it.getDiskName(Common.CHARSET) } + + retDisk = it } catch (e: Throwable) { printdbgerr(this, e.stackTraceToString()) @@ -220,10 +225,10 @@ class UIImportAvatar(val remoCon: UIRemoCon) : Advanceable() { catch (e: Throwable) { // format error e.printStackTrace() - return -1 + return -1 to null } - return 0 + return 0 to retDisk } } diff --git a/src/net/torvald/terrarum/savegame/VirtualDisk.kt b/src/net/torvald/terrarum/savegame/VirtualDisk.kt index 6b961096c..ae0b44b26 100644 --- a/src/net/torvald/terrarum/savegame/VirtualDisk.kt +++ b/src/net/torvald/terrarum/savegame/VirtualDisk.kt @@ -313,6 +313,7 @@ object VDFileID { const val LOADORDER = -4L const val PLAYER_SCREENSHOT = -5L const val SPRITEDEF_EMISSIVE = -6L + const val SPRITEDEF_EMSV = -7L const val BODYPART_TO_ENTRY_MAP = -1025L const val BODYPARTGLOW_TO_ENTRY_MAP = -1026L const val BODYPARTEMISSIVE_TO_ENTRY_MAP = -1027L @@ -333,6 +334,11 @@ fun diskIDtoReadableFilename(id: EntryID, saveKind: Int?): String = when (id) { "spritedef-glow" else "file #$id" + VDFileID.SPRITEDEF_EMSV -> + if (saveKind == PLAYER_DATA) + "spritedef-glow" + else + "file #$id" VDFileID.PLAYER_SCREENSHOT -> if (saveKind == PLAYER_DATA) "screenshot.tga.gz" @@ -347,7 +353,7 @@ fun diskIDtoReadableFilename(id: EntryID, saveKind: Int?): String = when (id) { // -1024L -> "apocryphas.json.gz" VDFileID.BODYPART_TO_ENTRY_MAP -> "bodypart-to-entry.map" VDFileID.BODYPARTGLOW_TO_ENTRY_MAP -> "bodypartglow-to-entry.map" - VDFileID.BODYPARTEMISSIVE_TO_ENTRY_MAP -> "bodypartemissive-to-entry.map" + VDFileID.BODYPARTEMISSIVE_TO_ENTRY_MAP -> "bodypartemsv-to-entry.map" in 1..65535 -> if (saveKind == PLAYER_DATA) "bodypart #$id.tga.gz" diff --git a/src/net/torvald/terrarum/spriteassembler/AvatarBuilder.kt b/src/net/torvald/terrarum/spriteassembler/AvatarBuilder.kt new file mode 100644 index 000000000..dd7989cfc --- /dev/null +++ b/src/net/torvald/terrarum/spriteassembler/AvatarBuilder.kt @@ -0,0 +1,166 @@ +package net.torvald.terrarum.spriteassembler + +import com.badlogic.gdx.Gdx +import net.torvald.terrarum.App +import net.torvald.terrarum.savegame.* +import net.torvald.terrarum.savegame.VDFileID.BODYPARTEMISSIVE_TO_ENTRY_MAP +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.PLAYER_SCREENSHOT +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_EMSV +import net.torvald.terrarum.savegame.VDFileID.SPRITEDEF_GLOW +import net.torvald.terrarum.serialise.Common +import java.awt.BorderLayout +import java.awt.Dimension +import java.awt.GridLayout +import java.awt.event.MouseAdapter +import java.awt.event.MouseEvent +import java.io.File +import javax.swing.* + +/** + * Created by minjaesong on 2024-09-25. + */ +class AvatarBuilder : JFrame() { + + private val infilePath = JTextField().also { it.preferredSize = Dimension(400, 24) } + private val outfilePath = JTextField().also { it.preferredSize = Dimension(400, 24) } + private val buttonGo = JButton("Export!") + + init { + val panelPlayer = JPanel().also { + it.add(JLabel("Player File")) + it.add(infilePath) + } + + val panelOutput = JPanel().also { + it.add(JLabel("Output File")) + it.add(outfilePath) + } + + val controlPanel = JPanel().also { + it.add(buttonGo) + } + + val panelMain = JPanel().also { + it.layout = GridLayout(2, 1) + it.add(panelPlayer, 0) + it.add(panelOutput, 1) + } + + this.layout = BorderLayout() + this.add(panelMain, BorderLayout.CENTER) + this.add(controlPanel, BorderLayout.SOUTH) + this.title = "Terrarum Avatar Generator" + this.isVisible = true + this.setSize(480, 120) + this.defaultCloseOperation = WindowConstants.EXIT_ON_CLOSE + + buttonGo.addMouseListener(object : MouseAdapter() { + override fun mouseClicked(e: MouseEvent?) { + if (infilePath.text.isNotBlank() && outfilePath.text.isNotBlank()) { + try { + invoke(File(infilePath.text), File(outfilePath.text)) + popupMessage("Exported successfully!") + } + catch (e: Throwable) { + e.printStackTrace() + popupError(e.message ?: "null") + } + } + } + }) + } + + private fun popupMessage(message: String, title: String = "") { + JOptionPane.showOptionDialog( + null, + message, + title, + JOptionPane.DEFAULT_OPTION, + JOptionPane.INFORMATION_MESSAGE, + null, null, null + ) + } + + private fun popupError(message: String, title: String = "Uh oh…") { + JOptionPane.showOptionDialog( + null, + message, + title, + JOptionPane.DEFAULT_OPTION, + JOptionPane.ERROR_MESSAGE, + null, null, null + ) + } + + private var lastBodypartIndex = 0L + + operator fun invoke(playerSavegameFile: File, outFile: File) { + val dom = VDUtil.readDiskArchive(playerSavegameFile) + + val playerInfoFile = dom.getEntry(SAVEGAMEINFO)!! + val spritedefFile = dom.getEntry(SPRITEDEF)!! + val spritedefGlowFile = dom.getEntry(SPRITEDEF_GLOW) + val spritedefEmsvFile = dom.getEntry(SPRITEDEF_EMSV) + val screencap = dom.getEntry(PLAYER_SCREENSHOT) + val playerName = dom.diskName.toCanonicalString(Common.CHARSET) + val outDisk = VDUtil.createNewDisk(4294967295L, playerName, Common.CHARSET) + + val timeNow = App.getTIME_T() + + // initialise outDisk DOM + VDUtil.addFile(outDisk, playerInfoFile) + VDUtil.addFile(outDisk, spritedefFile) + spritedefGlowFile?.let { VDUtil.addFile(outDisk, it) } + spritedefEmsvFile?.let { VDUtil.addFile(outDisk, it) } + screencap?.let {VDUtil.addFile(outDisk, it) } + + + + putBodyparts(timeNow, outDisk, spritedefFile, BODYPART_TO_ENTRY_MAP) + spritedefGlowFile?.let { putBodyparts(timeNow, outDisk, it, BODYPARTGLOW_TO_ENTRY_MAP) } + spritedefEmsvFile?.let { putBodyparts(timeNow, outDisk, it, BODYPARTEMISSIVE_TO_ENTRY_MAP) } + + outDisk.saveKind = VDSaveKind.PLAYER_DATA + + VDUtil.dumpToRealMachine(outDisk, outFile) + } + + // will write: bodypart images, spritedef, to the disk + private fun putBodyparts(timeNow: Long, outDisk: VirtualDisk, spritedefFile: DiskEntry, bodypartsToEntryFileID: Long) { + val bodypartsToEntry = StringBuilder() + val adp = ADProperties(ByteArray64Reader(spritedefFile.contents.getContent() as ByteArray64, Common.CHARSET)) + val images = adp.bodyparts.map { // Pair: "HEAD" to "mods/basegame/sprites/***/prefix_HEAD.tga" + it.uppercase() to adp.toFilename(it) + } + + images.forEach { (name, path) -> + + val bodypartFileNative = File("assets/$path") + if (bodypartFileNative.exists()) { + lastBodypartIndex += 1L + + // write to bodypartsToEntry file content + bodypartsToEntry.append("$name=$lastBodypartIndex\n") + + // copy image into new disk + val bodypartFile = VDUtil.importFile(bodypartFileNative, lastBodypartIndex, Common.CHARSET) + VDUtil.addFile(outDisk, bodypartFile) + } + } + + // write bodypartsToEntry as a file + val bodypartsToEntryFileContent = EntryFile(ByteArray64.fromByteArray(bodypartsToEntry.toString().toByteArray(Common.CHARSET))) + val bodypartsToEntryFile = DiskEntry(bodypartsToEntryFileID, ROOT, timeNow, timeNow, bodypartsToEntryFileContent) + VDUtil.addFile(outDisk, bodypartsToEntryFile) + } + +} + +fun main(args: Array) { + AvatarBuilder() +} diff --git a/work_files/graphics/sprites/furbud3_jointed.psd b/work_files/graphics/sprites/furbud3_jointed.psd new file mode 100644 index 000000000..98e04e233 --- /dev/null +++ b/work_files/graphics/sprites/furbud3_jointed.psd @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7f57b09ec96ef20d3c584e58d3e8ccb929ebed5b6dcf897ef0f15503b3961026 +size 70054