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

@@ -49,7 +49,7 @@ open class ActorWithBody(renderOrder: RenderOrder, val physProp: PhysProperties)
/** This is GameWorld? only because the title screen also uses this thing as its camera;
* titlescreen does not use instance of Ingame.
*/
private val world: GameWorld?
protected val world: GameWorld?
get() = Terrarum.ingame?.world

View File

@@ -33,8 +33,6 @@ class WireActor(id: ActorID) : ActorWithBody(RenderOrder.WIRES, PhysProperties.I
private var worldX = 0
private var worldY = 0
private val world: GameWorld
get() = Terrarum.ingame!!.world
/**
* @param itemID must start with "wire@"
@@ -58,7 +56,7 @@ class WireActor(id: ActorID) : ActorWithBody(RenderOrder.WIRES, PhysProperties.I
sprite!!.currentRow = 0
val nearbyTiles = getNearbyTilesPos(worldX, worldY).map { world.getAllWiresFrom(it.x, it.y) }
val nearbyTiles = getNearbyTilesPos(worldX, worldY).map { world!!.getAllWiresFrom(it.x, it.y) }
var ret = 0
for (i in 0..3) {
if (nearbyTiles[i]?.contains(itemID) == true) {

View File

@@ -463,7 +463,7 @@ open class GameWorld : Disposable {
/**
* @return true if block is broken
*/
fun inflictTerrainDamage(x: Int, y: Int, damage: Double): Boolean {
fun inflictTerrainDamage(x: Int, y: Int, damage: Double): ItemID? {
val damage = damage.toFloat()
val addr = LandUtil.getBlockAddr(this, x, y)
@@ -483,12 +483,13 @@ open class GameWorld : Disposable {
// remove tile from the world
if (terrainDamages[addr] ?: 0f >= BlockCodex[getTileFromTerrain(x, y)].strength) {
val tileBroke = getTileFromTerrain(x, y)
setTileTerrain(x, y, Block.AIR, false)
terrainDamages.remove(addr)
return true
return tileBroke
}
return false
return null
}
fun getTerrainDamage(x: Int, y: Int): Float =
terrainDamages[LandUtil.getBlockAddr(this, x, y)] ?: 0f
@@ -496,7 +497,7 @@ open class GameWorld : Disposable {
/**
* @return true if block is broken
*/
fun inflictWallDamage(x: Int, y: Int, damage: Double): Boolean {
fun inflictWallDamage(x: Int, y: Int, damage: Double): ItemID? {
val damage = damage.toFloat()
val addr = LandUtil.getBlockAddr(this, x, y)
@@ -512,12 +513,13 @@ open class GameWorld : Disposable {
// remove tile from the world
if (wallDamages[addr]!! >= BlockCodex[getTileFromWall(x, y)].strength) {
val tileBroke = getTileFromWall(x, y)
setTileWall(x, y, Block.AIR, false)
wallDamages.remove(addr)
return true
return tileBroke
}
return false
return null
}
fun getWallDamage(x: Int, y: Int): Float =
wallDamages[LandUtil.getBlockAddr(this, x, y)] ?: 0f

View File

@@ -176,7 +176,7 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
}
private fun drawSpriteInGoodPosition(sprite: TextureRegion, batch: SpriteBatch) {
val leftsidePadding = world.width.times(TILE_SIZE) - WorldCamera.width.ushr(1)
val leftsidePadding = world!!.width.times(TILE_SIZE) - WorldCamera.width.ushr(1)
val rightsidePadding = WorldCamera.width.ushr(1)
if (hitbox.startX in WorldCamera.x - hitbox.width..WorldCamera.x + WorldCamera.width.toDouble() &&
@@ -184,14 +184,14 @@ class BuildingMaker(batch: SpriteBatch) : IngameInstance(batch) {
if (WorldCamera.xCentre > leftsidePadding && hitbox.centeredX <= rightsidePadding) {
// camera center neg, actor center pos
batch.draw(sprite,
hitbox.startX.toFloat() + world.width * TILE_SIZE,
hitbox.startX.toFloat() + world!!.width * TILE_SIZE,
hitbox.startY.toFloat()
)
}
else if (WorldCamera.xCentre < rightsidePadding && hitbox.centeredY >= leftsidePadding) {
// camera center pos, actor center neg
batch.draw(sprite,
hitbox.startX.toFloat() - world.width * TILE_SIZE,
hitbox.startX.toFloat() - world!!.width * TILE_SIZE,
hitbox.startY.toFloat()
)
}

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)
}
}
}

View File

@@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.g2d.TextureRegion
import net.torvald.terrarum.CommonResourcePool
import net.torvald.terrarum.Point2d
import net.torvald.terrarum.Terrarum
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
import net.torvald.terrarum.blockproperties.Block
import net.torvald.terrarum.gameactors.AVKey
import net.torvald.terrarum.gameitem.GameItem
@@ -11,6 +12,7 @@ import net.torvald.terrarum.gameitem.ItemID
import net.torvald.terrarum.itemproperties.Calculate
import net.torvald.terrarum.itemproperties.MaterialCodex
import net.torvald.terrarum.modulebasegame.TerrarumIngame
import net.torvald.terrarum.modulebasegame.gameactors.DroppedItem
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore.BASE_MASS_AND_SIZE
import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore.TOOL_DURABILITY_BASE
import kotlin.math.roundToInt
@@ -20,8 +22,7 @@ import kotlin.math.roundToInt
*/
object PickaxeCore {
fun startPrimaryUse(delta: Float, item: GameItem): Boolean {
val player = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying
if (player == null) return false
val player = (Terrarum.ingame!! as TerrarumIngame).actorNowPlaying ?: return false
val mouseTileX = Terrarum.mouseTileX
val mouseTileY = Terrarum.mouseTileY
@@ -51,7 +52,9 @@ object PickaxeCore {
(Terrarum.ingame!!.world).inflictTerrainDamage(
mouseTileX, mouseTileY,
Calculate.pickaxePower(player, item.material) * swingDmgToFrameDmg
)
)?.let { tileBroken ->
Terrarum.ingame!!.addNewActor(DroppedItem(tileBroken, mouseTileX * TILE_SIZE, mouseTileY * TILE_SIZE))
}
return true
}