fixed a bug where picking up a fixture placed on the world would drop one more fixture than it should do

This commit is contained in:
minjaesong
2022-01-22 10:40:49 +09:00
parent 0c70a7eebc
commit f13379ada8
7 changed files with 57 additions and 36 deletions

View File

@@ -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

View File

@@ -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!!)

View File

@@ -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<IngamePlayer>().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()