spawning of dropped item

This commit is contained in:
minjaesong
2021-08-06 21:43:50 +09:00
parent edc3d53f4e
commit ecce123299
9 changed files with 140 additions and 90 deletions

View File

@@ -34,9 +34,6 @@ open class ActorHumanoid(
physProp: PhysProperties = PhysProperties.HUMANOID_DEFAULT
) : ActorWithBody(RenderOrder.MIDDLE, physProp = physProp), Controllable, Pocketed, Factionable, Luminous, LandHolder, HistoricalFigure {
private val world: GameWorld?
get() = Terrarum.ingame?.world
var vehicleRiding: Controllable? = null // usually player only

View File

@@ -1,41 +1,93 @@
package net.torvald.terrarum.modulebasegame.gameactors
import com.badlogic.gdx.graphics.g2d.SpriteBatch
import net.torvald.terrarum.AppLoader.printdbg
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZEF
import net.torvald.terrarum.blockproperties.BlockCodex
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameactors.ActorWithBody
import net.torvald.terrarum.gameactors.PhysProperties
import net.torvald.terrarum.gameitem.GameItem
import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.itemproperties.ItemCodex
import net.torvald.terrarum.worlddrawer.WorldCamera
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
/**
* Created by minjaesong on 2016-03-15.
*/
open class DroppedItem(private val item: GameItem) : ActorWithBody(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT) {
open class DroppedItem(private val itemID: ItemID, topLeftX: Int, topLeftY: Int) : ActorWithBody(RenderOrder.MIDTOP, PhysProperties.PHYSICS_OBJECT) {
private val textureRegion = ItemCodex.getItemImage(itemID)
init {
if (item.dynamicID.startsWith("actor@"))
if (itemID.startsWith("actor@"))
throw RuntimeException("Attempted to create DroppedItem actor of a real actor; the real actor must be dropped instead.")
isVisible = true
avBaseMass = if (item.dynamicID.startsWith("item@"))
ItemCodex[item.dynamicID]!!.mass
avBaseMass = if (itemID.startsWith("item@") || itemID.startsWith("wire@"))
(ItemCodex[itemID]?.mass ?: 2.0).coerceAtMost(2.0)
else
BlockCodex[item.dynamicID].density / 1000.0 // block and wall
BlockCodex[itemID].density / 1000.0 // block and wall
actorValue[AVKey.SCALE] = ItemCodex[item.dynamicID]!!.scale
actorValue[AVKey.SCALE] = ItemCodex[itemID]?.scale ?: 1.0
setHitboxDimension(
textureRegion?.regionWidth ?: TILE_SIZE,
textureRegion?.regionHeight ?: TILE_SIZE,
0, 0
)
setPosition(topLeftX + (hitbox.width / 2.0), topLeftY + hitbox.height)
printdbg(this, "New dropped item $itemID")
}
override fun drawBody(batch: SpriteBatch) {
// copy-pasted from ActorWithBody.drawSpriteInGoodPosition()
if (world == null) return
val leftsidePadding = world!!.width.times(TILE_SIZE) - WorldCamera.width.ushr(1)
val rightsidePadding = WorldCamera.width.ushr(1)
val offsetX = hitboxTranslateX * scale
val offsetY = (textureRegion?.regionHeight ?: TILE_SIZE) * scale - hitbox.height - hitboxTranslateY * scale - 1
textureRegion?.let {
// FIXME test me: this extra IF statement is supposed to not draw actors that's outside of the camera.
// basic code without offsetX/Y DOES work, but obviously offsets are not tested.
if (WorldCamera.xCentre > leftsidePadding && centrePosPoint.x <= rightsidePadding) {
// camera center neg, actor center pos
batch.draw(it,
(hitbox.startX - offsetX).toFloat() + world!!.width * TILE_SIZE,
(hitbox.startY - offsetY).toFloat(),
TILE_SIZEF * scale.toFloat(), TILE_SIZEF * scale.toFloat()
)
}
else if (WorldCamera.xCentre < rightsidePadding && centrePosPoint.x >= leftsidePadding) {
// camera center pos, actor center neg
batch.draw(it,
(hitbox.startX - offsetX).toFloat() - world!!.width * TILE_SIZE,
(hitbox.startY - offsetY).toFloat(),
TILE_SIZEF * scale.toFloat(), TILE_SIZEF * scale.toFloat()
)
}
else {
batch.draw(it,
(hitbox.startX - offsetX).toFloat(),
(hitbox.startY - offsetY).toFloat(),
TILE_SIZEF * scale.toFloat(), TILE_SIZEF * scale.toFloat()
)
}
}
}
override fun update(delta: Float) {
super.update(delta)
}
override fun drawGlow(batch: SpriteBatch) {
super.drawGlow(batch)
}
override fun drawBody(batch: SpriteBatch) {
super.drawBody(batch)
}
}

View File

@@ -29,8 +29,6 @@ open class FixtureBase(
var blockBox: BlockBox = blockBox0
protected set // something like TapestryObject will want to redefine this
private val world: GameWorld
get() = Terrarum.ingame!!.world
/**
* Block-wise position of this fixture when it's placed on the world. Null if it's not on the world
@@ -66,7 +64,7 @@ open class FixtureBase(
checkForCollision@
for (y in posY until posY + blockBox.height) {
for (x in posX until posX + blockBox.width) {
val tile = world.getTileFromTerrain(x, y)
val tile = world!!.getTileFromTerrain(x, y)
if (BlockCodex[tile].isSolid || tile in Block.actorblocks) {
hasCollision = true
break@checkForCollision
@@ -84,10 +82,10 @@ open class FixtureBase(
// 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 == posY) BlockBox.ALLOW_MOVE_DOWN else BlockBox.NO_COLLISION, false)
world!!.setTileTerrain(x, y, if (y == posY) BlockBox.ALLOW_MOVE_DOWN else BlockBox.NO_COLLISION, false)
}
else
world.setTileTerrain(x, y, blockBox.collisionType, false)
world!!.setTileTerrain(x, y, blockBox.collisionType, false)
}
}
@@ -122,7 +120,7 @@ open class FixtureBase(
// remove filler block
for (x in posX until posX + blockBox.width) {
for (y in posY until posY + blockBox.height) {
world.setTileTerrain(x, y, Block.AIR, false)
world!!.setTileTerrain(x, y, Block.AIR, false)
}
}
@@ -152,7 +150,7 @@ open class FixtureBase(
outerLoop@
for (x in posX until posX + blockBox.width) {
for (y in posY until posY + blockBox.height) {
if (world.getTileFromTerrain(x, y) != blockBox.collisionType) {
if (world!!.getTileFromTerrain(x, y) != blockBox.collisionType) {
dropThis = true
break@outerLoop
}
@@ -163,8 +161,8 @@ open class FixtureBase(
// fill blockbox with air
for (x in posX until posX + blockBox.width) {
for (y in posY until posY + blockBox.height) {
if (world.getTileFromTerrain(x, y) == blockBox.collisionType) {
world.setTileTerrain(x, y, Block.AIR, false)
if (world!!.getTileFromTerrain(x, y) == blockBox.collisionType) {
world!!.setTileTerrain(x, y, Block.AIR, false)
}
}
}