actors now always calls despawn() when being despawned

This commit is contained in:
minjaesong
2024-02-05 14:39:21 +09:00
parent 1685d0f045
commit 2d42525092
6 changed files with 39 additions and 16 deletions

View File

@@ -51,10 +51,19 @@ abstract class Actor : Comparable<Actor>, Runnable {
OVERLAY // screen overlay, not affected by lightmap
}
abstract fun update(delta: Float)
open fun update(delta: Float) {
if (!canBeDespawned) flagDespawn = false // actively deny despawning request if cannot be despawned
if (canBeDespawned && flagDespawn) {
despawn()
despawned = true
}
}
var actorValue = ActorValue(this)
@Volatile var flagDespawn = false
@Transient var despawnHook: (Actor) -> Unit = {}
@Transient open val canBeDespawned = true
@Volatile internal var despawned = false
override fun equals(other: Any?): Boolean {
if (other == null) return false
@@ -84,6 +93,12 @@ abstract class Actor : Comparable<Actor>, Runnable {
}
}
open fun despawn() {
if (canBeDespawned) {
despawnHook(this)
}
}
/**
* ActorValue change event handler
*

View File

@@ -518,6 +518,7 @@ open class ActorWithBody : Actor {
}
override fun update(delta: Float) {
super.update(delta)
// re-scale hitbox
// it's just much better to poll them than use perfectly-timed setter because latter simply cannot exist

View File

@@ -1298,7 +1298,7 @@ open class TerrarumIngame(batch: FlippingSpriteBatch) : IngameInstance(batch) {
val actor = actorContainerActive[i]
val actorIndex = i
// kill actors flagged to despawn
if (actor.flagDespawn) {
if (actor.despawned) {
queueActorRemoval(actor)
actorContainerSize -= 1
i-- // array removed 1 elem, so we also decrement counter by 1

View File

@@ -9,6 +9,7 @@ import net.torvald.terrarum.App.printdbg
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.gamecontroller.KeyToggler
import net.torvald.terrarum.gameitems.ItemID
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore
import net.torvald.terrarum.modulebasegame.worldgenerator.Treegen
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
@@ -73,6 +74,16 @@ open class SaplingBase(val species: Int) : Cultivable(72000) {
(sprite as SheetSpriteAnimation).currentRow = species
(sprite as SheetSpriteAnimation).currentFrame = variant
// check for soil
val groundTile = INGAME.world.getTileFromTerrain(intTilewiseHitbox.startX.toInt(), intTilewiseHitbox.endY.toInt() + 1)
if (BlockCodex[groundTile].hasNoTagOf("CULTIVABLE")) {
despawnHook = {
printdbg(this, "Sapling despawn!")
PickaxeCore.dropItem("item@basegame:${160 + species}", intTilewiseHitbox.canonicalX.toInt(), intTilewiseHitbox.canonicalY.toInt())
}
flagDespawn()
}
if (!flagDespawn) {
tickGrowthCounter()

View File

@@ -451,14 +451,12 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
}
/** force disable despawn when inventory is not empty */
open val canBeDespawned: Boolean get() = inventory?.isEmpty() ?: true
@Transient open var despawnHook: (FixtureBase) -> Unit = {}
override val canBeDespawned: Boolean get() = inventory?.isEmpty() ?: true
/**
* Removes this instance of the fixture from the world
*/
open fun despawn() {
override fun despawn() {
if (canBeDespawned) {
printdbg(this, "despawn at T${INGAME.WORLD_UPDATE_TIMER}: ${nameFun()}")
@@ -493,16 +491,10 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
INGAME.queueActorAddition(DroppedItem(drop, hitbox.startX, hitbox.startY - 1.0))
}
protected var dropItem = false
/**
* This function MUST BE super-called for make despawn call to work at all.
*/
override fun update(delta: Float) {
if (!canBeDespawned) flagDespawn = false // actively deny despawning request if cannot be despawned
if (canBeDespawned && flagDespawn) despawn()
if (canBeDespawned && dropItem) dropSelfAsAnItem()
// actual actor removal is performed by the TerrarumIngame.killOrKnockdownActors
super.update(delta)
}
@@ -514,8 +506,10 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
actorBlockFillingFunction()
}
if (!canBeDespawned) flagDespawn = false
if (canBeDespawned && flagDespawn) despawn()
if (canBeDespawned && dropItem) dropSelfAsAnItem()
if (canBeDespawned && flagDespawn) {
despawn()
despawned = true
}
// actual actor removal is performed by the TerrarumIngame.killOrKnockdownActors
super.update(delta)
}

View File

@@ -94,6 +94,10 @@ class FixtureJukebox : Electric, PlaysMusic {
App.audioMixerReloadHooks[this] = {
loadConvolver(musicTracks[musicNowPlaying])
}
despawnHook = {
stopGracefully()
}
}
@Transient override var lightBoxList = arrayListOf(Lightbox(Hitbox(0.0, 0.0, TILE_SIZED * 2, TILE_SIZED * 3), Cvec(0.44f, 0.41f, 0.40f, 0.2f)))
@@ -228,8 +232,6 @@ class FixtureJukebox : Electric, PlaysMusic {
}
}
@Transient override var despawnHook: (FixtureBase) -> Unit = { stopGracefully() }
override fun reload() {
super.reload()
// cannot resume playback, just stop the music