From f13379ada8847dc4796077eecdf81d2bc78a7dad Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 22 Jan 2022 10:40:49 +0900 Subject: [PATCH] fixed a bug where picking up a fixture placed on the world would drop one more fixture than it should do --- .../terrarum/TerrarumAppConfiguration.kt | 2 +- .../modulebasegame/gameactors/FixtureBase.kt | 37 +++++++++++++------ .../modulebasegame/gameactors/IngamePlayer.kt | 4 +- .../modulebasegame/ui/UIInventoryEscMenu.kt | 10 +++++ .../terrarum/serialise/GameSavingThread.kt | 16 ++++---- .../terrarum/serialise/QuickSaveThread.kt | 12 +++--- .../terrarum/serialise/WriteSavegame.kt | 12 +++--- 7 files changed, 57 insertions(+), 36 deletions(-) diff --git a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt index 4e31d9d8b..aa7647b59 100644 --- a/src/net/torvald/terrarum/TerrarumAppConfiguration.kt +++ b/src/net/torvald/terrarum/TerrarumAppConfiguration.kt @@ -48,7 +48,7 @@ along with this program. If not, see . * e.g. 0x02010034 will be translated as 2.1.52 * */ - const val VERSION_RAW = 0x00030001 + const val VERSION_RAW = 0x00030000 // Commit counts up to the Release 0.3: 2251 (plz update!) ////////////////////////////////////////////////////////// diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt index 0092c0628..b576d6f9d 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt @@ -140,7 +140,12 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange { this.isVisible = true - this.hitbox.setFromWidthHeight(posX * TILE_SIZED, posY * TILE_SIZED, blockBox.width * TILE_SIZED, blockBox.height * TILE_SIZED) + this.hitbox.setFromWidthHeight( + posX * TILE_SIZED, + posY * TILE_SIZED, + blockBox.width * TILE_SIZED, + blockBox.height * TILE_SIZED + ) // actually add this actor into the world INGAME.queueActorAddition(this) @@ -174,29 +179,34 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange { wireEmission.clear() wireConsumption.clear() } - - if (flagDespawn) { - val drop = ItemCodex.fixtureToItemID(this) - INGAME.queueActorAddition(DroppedItem(drop, hitbox.startX, hitbox.startY - 1.0)) - } } else { printdbg(this, "cannot despawn a fixture with non-empty inventory") } } + + private fun dropSelfAsAnItem() { + val drop = ItemCodex.fixtureToItemID(this) + INGAME.queueActorAddition(DroppedItem(drop, hitbox.startX, hitbox.startY - 1.0)) + } + + private var dropItem = false + override fun update(delta: Float) { - // if not flagged to despawn and not actually despawned (which sets worldBlockPos as null), always fill up fillerBlock if (!flagDespawn && worldBlockPos != null) { - // for removal-by-player because player is removing the filler block by pick + // removal-by-player because player is removing the filler block by pick + // no-flagDespawn check is there to prevent item dropping when externally despawned + // (e.g. picked the fixture up in which case the fixture must not drop itself to the world; it must go into the actor's inventory) forEachBlockbox { x, y -> if (world!!.getTileFromTerrain(x, y) != blockBox.collisionType) { flagDespawn = true + dropItem = true } } - } if (!canBeDespawned) flagDespawn = false if (canBeDespawned && flagDespawn) despawn() + if (canBeDespawned && dropItem) dropSelfAsAnItem() // actual actor removal is performed by the TerrarumIngame.killOrKnockdownActors super.update(delta) } @@ -229,8 +239,10 @@ interface CuedByWireChange { * Standard 32-bit binary flags. * * (LSB) - * - 0: fluid resist - when FALSE, the fixture will break itself to item/nothing. For example, crops has this flag FALSE. - * - 1: don't drop item when broken - when TRUE, the fixture will simply disappear instead of dropping itself. For example, crop has this flag TRUE. + * - 0: fluid resist - when FALSE, the fixture will break itself to item/nothing. + * For example, crops has this flag FALSE. + * - 1: don't drop item when broken - when TRUE, the fixture will simply disappear instead of + * dropping itself. For example, crop has this flag TRUE. * * (MSB) * @@ -243,7 +255,8 @@ inline class BlockBoxProps(val flags: Int) { /** * To not define the blockbox, simply use BlockBox.NULL * - * Null blockbox means the fixture won't bar any block placement. Fixtures like paintings will want to have such feature. (e.g. torch placed on top; buried) + * Null blockbox means the fixture won't bar any block placement. + * Fixtures like paintings will want to have such feature. (e.g. torch placed on top; buried) * * @param collisionType Collision type defined in BlockBox.Companion * @param width Width of the block box, tile-wise diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt index 8235bb169..1ec7f568b 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/IngamePlayer.kt @@ -11,6 +11,7 @@ import net.torvald.terrarum.App import net.torvald.terrarum.Terrarum import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.gameitems.GameItem +import net.torvald.terrarum.savegame.DiskSkimmer import net.torvald.terrarum.savegame.SimpleFileSystem import net.torvald.terrarum.utils.PlayerLastStatus import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack @@ -78,7 +79,7 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite { */ @Transient private lateinit var rebuildfun: (item: GameItem?) -> Unit @Transient private lateinit var rebuildfunGlow: (item: GameItem?) -> Unit - + @Transient internal var rebuildingDiskSkimmer: DiskSkimmer? = null /** * Example usage: @@ -103,6 +104,7 @@ class IngamePlayer : ActorHumanoid, HasAssembledSprite { fun reassembleSpriteFromDisk(disk: SimpleFileSystem, sprite: SpriteAnimation?, spriteGlow: SpriteAnimation?, heldItem: GameItem?) { if (animDesc != null && sprite != null) { rebuildfun = { item: GameItem? -> _rebuild(disk, -1025L, animDesc!!, sprite, item) }; rebuildfun(heldItem) + if (disk is DiskSkimmer) rebuildingDiskSkimmer = disk if (disk.getEntry(-1025L) != null) spriteHeadTexture = AssembleSheetPixmap.getMugshotFromVirtualDisk(disk, -1025L, animDesc!!) diff --git a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt index a8f8a9a53..117a32f61 100644 --- a/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt +++ b/src/net/torvald/terrarum/modulebasegame/ui/UIInventoryEscMenu.kt @@ -5,12 +5,15 @@ import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import net.torvald.terrarum.App +import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.INGAME import net.torvald.terrarum.Terrarum.getPlayerSaveFiledesc import net.torvald.terrarum.Terrarum.getWorldSaveFiledesc import net.torvald.terrarum.blendNormal +import net.torvald.terrarum.gameactors.AVKey import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.TitleScreen +import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_OFFSET_Y import net.torvald.terrarum.modulebasegame.ui.UIInventoryFull.Companion.INVENTORY_CELLS_UI_HEIGHT import net.torvald.terrarum.serialise.WriteSavegame @@ -108,6 +111,13 @@ class UIInventoryEscMenu(val full: UIInventoryFull) : UICanvas() { INGAME.makeSavegameBackupCopy(worldSavefile) WriteSavegame(saveTime_t, WriteSavegame.SaveMode.WORLD, INGAME.worldDisk, worldSavefile, INGAME as TerrarumIngame, false, onError) { // callback: + // rebuild the disk skimmers + INGAME.actorContainerActive.filterIsInstance().forEach { + printdbg(this, "Game Save callback -- rebuilding the disk skimmer for IngamePlayer ${it.actorValue.getAsString(AVKey.NAME)}") + it.rebuildingDiskSkimmer?.rebuild() + } + + // return to normal state System.gc() screen = 0 full.handler.unlockToggle() diff --git a/src/net/torvald/terrarum/serialise/GameSavingThread.kt b/src/net/torvald/terrarum/serialise/GameSavingThread.kt index f2fe7cc42..0b2909fc7 100644 --- a/src/net/torvald/terrarum/serialise/GameSavingThread.kt +++ b/src/net/torvald/terrarum/serialise/GameSavingThread.kt @@ -1,9 +1,7 @@ package net.torvald.terrarum.serialise import net.torvald.gdx.graphics.PixmapIO2 -import net.torvald.terrarum.ccG -import net.torvald.terrarum.ccW -import net.torvald.terrarum.console.Echo +import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer @@ -76,7 +74,7 @@ class WorldSavingThread( val tgaout = ByteArray64GrowableOutputStream() val gzout = GZIPOutputStream(tgaout) - Echo("Writing metadata...") + printdbg(this, "Writing metadata...") val creation_t = ingame.world.creationTime @@ -106,7 +104,7 @@ class WorldSavingThread( for (cy in 0 until ch) { val chunkNumber = LandUtil.chunkXYtoChunkNum(ingame.world, cx, cy).toLong() - Echo("Writing chunks... ${(cw*ch*layer) + chunkNumber + 1}/${cw*ch*layers.size}") +// Echo("Writing chunks... ${(cw*ch*layer) + chunkNumber + 1}/${cw*ch*layers.size}") val chunkBytes = WriteWorld.encodeChunk(layers[layer]!!, cx, cy) val entryID = 0x1_0000_0000L or layer.toLong().shl(24) or chunkNumber @@ -124,7 +122,7 @@ class WorldSavingThread( // Write Actors // actorsList.forEachIndexed { count, it -> - Echo("Writing actors... ${count+1}/${actorsList.size}") +// 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) @@ -134,7 +132,7 @@ class WorldSavingThread( } - Echo("Writing file to disk...") +// Echo("Writing file to disk...") disk.entries[0]!!.modificationDate = time_t // entry zero MUST NOT be used to get lastPlayDate, but we'll update it anyway @@ -144,7 +142,7 @@ class WorldSavingThread( - Echo ("${ccW}Game saved with size of $ccG${outFile.length()}$ccW bytes") + printdbg(this, "Game saved with size of ${outFile.length()} bytes") if (hasThumbnail) IngameRenderer.fboRGBexportedLatch = false @@ -177,7 +175,7 @@ class PlayerSavingThread( WriteSavegame.saveProgress = 0f - Echo("Writing The Player...") + printdbg(this, "Writing The Player...") WritePlayer(ingame.actorGamer, disk, ingame, time_t) disk.entries[0]!!.modificationDate = time_t VDUtil.dumpToRealMachine(disk, outFile) diff --git a/src/net/torvald/terrarum/serialise/QuickSaveThread.kt b/src/net/torvald/terrarum/serialise/QuickSaveThread.kt index 17e867b8f..e7a0b306f 100644 --- a/src/net/torvald/terrarum/serialise/QuickSaveThread.kt +++ b/src/net/torvald/terrarum/serialise/QuickSaveThread.kt @@ -1,9 +1,7 @@ package net.torvald.terrarum.serialise import net.torvald.gdx.graphics.PixmapIO2 -import net.torvald.terrarum.ccG -import net.torvald.terrarum.ccW -import net.torvald.terrarum.console.Echo +import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.modulebasegame.IngameRenderer import net.torvald.terrarum.modulebasegame.TerrarumIngame import net.torvald.terrarum.modulebasegame.gameactors.IngamePlayer @@ -69,7 +67,7 @@ class QuickSingleplayerWorldSavingThread( val tgaout = ByteArray64GrowableOutputStream() val gzout = GZIPOutputStream(tgaout) - Echo("Writing metadata...") + printdbg(this, "Writing metadata...") val creation_t = ingame.world.creationTime @@ -103,7 +101,7 @@ class QuickSingleplayerWorldSavingThread( ingame.world.getLayer(layerNum)?.let { layer -> chunks.forEach { chunkNumber -> - Echo("Writing chunks... $chunksWrote/$chunkCount") +// Echo("Writing chunks... $chunksWrote/$chunkCount") val chunkXY = LandUtil.chunkNumToChunkXY(ingame.world, chunkNumber) @@ -128,7 +126,7 @@ class QuickSingleplayerWorldSavingThread( // Write Actors // actorsList.forEachIndexed { count, it -> - Echo("Writing actors... ${count+1}/${actorsList.size}") + 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) @@ -142,7 +140,7 @@ class QuickSingleplayerWorldSavingThread( skimmer.injectDiskCRC(disk.hashCode()) skimmer.setSaveMode(1 + 2 * isAuto.toInt()) - Echo ("${ccW}Game saved with size of $ccG${outFile.length()}$ccW bytes") + printdbg(this, "Game saved with size of ${outFile.length()} bytes") if (hasThumbnail) IngameRenderer.fboRGBexportedLatch = false diff --git a/src/net/torvald/terrarum/serialise/WriteSavegame.kt b/src/net/torvald/terrarum/serialise/WriteSavegame.kt index e4d13a42c..35f4ad08b 100644 --- a/src/net/torvald/terrarum/serialise/WriteSavegame.kt +++ b/src/net/torvald/terrarum/serialise/WriteSavegame.kt @@ -43,11 +43,11 @@ object WriteSavegame { operator fun invoke(time_t: Long, mode: SaveMode, disk: VirtualDisk, outFile: File, ingame: TerrarumIngame, isAuto: Boolean, errorHandler: (Throwable) -> Unit, callback: () -> Unit) { savingStatus = 0 val hasThumbnail = (mode == SaveMode.WORLD) - Echo("Save queued") + printdbg(this, "Save queued") if (hasThumbnail) { IngameRenderer.screencapExportCallback = { - Echo("Generating thumbnail...") + printdbg(this, "Generating thumbnail...") val w = 960 val h = 640 @@ -61,7 +61,7 @@ object WriteSavegame { //p.dispose() IngameRenderer.fboRGBexportedLatch = true - Echo("Done thumbnail generation") + printdbg(this, "Done thumbnail generation") } IngameRenderer.screencapRequested = true } @@ -94,10 +94,10 @@ object WriteSavegame { savingStatus = 0 - Echo("Quicksave queued") + printdbg(this, "Quicksave queued") IngameRenderer.screencapExportCallback = { - Echo("Generating thumbnail...") + printdbg(this, "Generating thumbnail...") val w = 960 val h = 640 @@ -107,7 +107,7 @@ object WriteSavegame { //p.dispose() IngameRenderer.fboRGBexportedLatch = true - Echo("Done thumbnail generation") + printdbg(this, "Done thumbnail generation") } IngameRenderer.screencapRequested = true