fixture will drop itself when mined

This commit is contained in:
minjaesong
2022-01-21 16:35:37 +09:00
parent 75afcaede3
commit fa68a1c377
15 changed files with 92 additions and 84 deletions

View File

@@ -36,7 +36,11 @@ open class DroppedItem : ActorWithBody {
fun canBePickedUp() = timeSinceSpawned > NO_PICKUP_TIME && !flagDespawn
constructor(itemID: ItemID, topLeftX: Int, topLeftY: Int) : super(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT) {
/**
* @param topLeftX world-wise coord
* @param topLeftY world-wise coord
*/
constructor(itemID: ItemID, topLeftX: Double, topLeftY: Double) : super(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT) {
this.itemID = itemID
if (itemID.startsWith("actor@"))

View File

@@ -66,7 +66,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
private set
fun forEachBlockbox(action: (Int, Int) -> Unit) {
worldBlockPos!!.let { (posX, posY) ->
worldBlockPos?.let { (posX, posY) ->
for (y in posY until posY + blockBox.height) {
for (x in posX until posX + blockBox.width) {
action(x, y)
@@ -76,20 +76,20 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
}
override fun updateForTerrainChange(cue: IngameInstance.BlockChangeQueueItem) {
fillFillerBlock()
}
private fun fillFillerBlock(bypassEvent: Boolean = false) {
private fun fillFillerBlock() {
forEachBlockbox { x, y ->
//printdbg(this, "fillerblock ${blockBox.collisionType} at ($x, $y)")
if (blockBox.collisionType == BlockBox.ALLOW_MOVE_DOWN) {
// if the collision type is allow_move_down, only the top surface tile should be "the platform"
// lower part must not have such property (think of the table!)
// TODO does this ACTUALLY work ?!
world!!.setTileTerrain(x, y, if (y == worldBlockPos!!.y) BlockBox.ALLOW_MOVE_DOWN else BlockBox.NO_COLLISION, bypassEvent)
world!!.setTileTerrain(x, y, if (y == worldBlockPos!!.y) BlockBox.ALLOW_MOVE_DOWN else BlockBox.NO_COLLISION, true)
}
else
world!!.setTileTerrain(x, y, blockBox.collisionType, bypassEvent)
world!!.setTileTerrain(x, y, blockBox.collisionType, true)
}
}
@@ -144,38 +144,45 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
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.addNewActor(this)
INGAME.queueActorAddition(this)
return true
}
val canBeDespawned: Boolean get() = inventory?.isEmpty() ?: true
/**
* Removes this instance of the fixture from the world
*/
open fun despawn() {
printdbg(this, "despawn ${nameFun()}")
if (canBeDespawned) {
printdbg(this, "despawn ${nameFun()}")
// remove filler block
forEachBlockbox { x, y ->
world!!.setTileTerrain(x, y, Block.AIR, true)
// remove filler block
forEachBlockbox { x, y ->
world!!.setTileTerrain(x, y, Block.AIR, true)
}
worldBlockPos = null
mainUI?.dispose()
this.isVisible = false
if (this is Electric) {
wireEmitterTypes.clear()
wireEmission.clear()
wireConsumption.clear()
}
val drop = ItemCodex.fixtureToItemID(this)
INGAME.queueActorAddition(DroppedItem(drop, hitbox.startX, hitbox.startY - 1.0))
}
worldBlockPos = null
mainUI?.dispose()
this.isVisible = false
if (this is Electric) {
wireEmitterTypes.clear()
wireEmission.clear()
wireConsumption.clear()
else {
printdbg(this, "cannot despawn a fixture with non-empty inventory")
}
// TODO drop self as an item (instance of DroppedItem)
}
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) {
@@ -187,11 +194,15 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
}
}
if (flagDespawn) despawn()
if (!canBeDespawned) flagDespawn = false
else if (flagDespawn) despawn()
// actual actor removal is performed by the TerrarumIngame.killOrKnockdownActors
super.update(delta)
}
override fun flagDespawn() {
if (canBeDespawned) flagDespawn = true
}
}
interface CuedByTerrainChange {

View File

@@ -34,7 +34,10 @@ open class FixtureInventory() {
*/
val itemList = ArrayList<InventoryPair>()
var wallet = BigInteger("0") // unified currency for whole civs; Dwarf Fortress approach seems too complicated
fun isEmpty() = getTotalCount() == 0
fun isNotEmpty() = getTotalCount() > 0
open fun add(itemID: ItemID, count: Int = 1) {
if (ItemCodex[itemID] == null)
throw NullPointerException("Item not found: $itemID")
@@ -136,12 +139,12 @@ open class FixtureInventory() {
else
getTotalCount().toDouble()
fun getTotalWeight(): Double = itemList.map { ItemCodex[it.itm]!!.mass * it.qty }.sum()
fun getTotalWeight(): Double = itemList.sumOf { ItemCodex[it.itm]!!.mass * it.qty }
/**
* Real amount
*/
fun getTotalCount(): Int = itemList.map { it.qty }.sum()
fun getTotalCount(): Int = itemList.sumOf { it.qty }
/**
* Unique amount, multiple items are calculated as one

View File

@@ -54,7 +54,7 @@ open class HumanoidNPC : ActorHumanoid, AIControlled, CanBeAnItem {
try {
// place the actor to the world
this@HumanoidNPC.setPosition(Terrarum.mouseX, Terrarum.mouseY)
INGAME.addNewActor(this@HumanoidNPC)
INGAME.queueActorAddition(this@HumanoidNPC)
// successful
return true
}