diff --git a/src/net/torvald/terrarum/gameactors/Actor.kt b/src/net/torvald/terrarum/gameactors/Actor.kt index 93c1188b1..a807dfc47 100644 --- a/src/net/torvald/terrarum/gameactors/Actor.kt +++ b/src/net/torvald/terrarum/gameactors/Actor.kt @@ -51,10 +51,19 @@ abstract class Actor : Comparable, 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, Runnable { } } + open fun despawn() { + if (canBeDespawned) { + despawnHook(this) + } + } + /** * ActorValue change event handler * diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index 9c455a5b5..91aecd9f0 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -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 diff --git a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt index 59fdafa45..52243c936 100644 --- a/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt +++ b/src/net/torvald/terrarum/modulebasegame/TerrarumIngame.kt @@ -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 diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/Cultivable.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/Cultivable.kt index 0b71fedf2..c0e8320d3 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/Cultivable.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/Cultivable.kt @@ -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() diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt index d0acb5de8..a1369d71a 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt @@ -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) } diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt index 31208eadf..498b0a5b0 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureJukebox.kt @@ -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