mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 12:21:52 +09:00
door and its ghost now spawns at the right position in the world
This commit is contained in:
@@ -36,7 +36,7 @@ class ItemHomeComputer(originalID: ItemID) : GameItem(originalID) {
|
||||
override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = mouseInInteractableRange(actor) {
|
||||
val item = FixtureHomeComputer()
|
||||
|
||||
if (item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1)) 1L else -1L
|
||||
if (item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY)) 1L else -1L
|
||||
// return true when placed, false when cannot be placed
|
||||
}
|
||||
}
|
||||
@@ -66,10 +66,9 @@ class BlockMarkerActor : ActorWithBody(Actor.RenderOrder.OVERLAY, physProp = Phy
|
||||
|
||||
override fun update(delta: Float) {
|
||||
if (isVisible) {
|
||||
hitbox.setPosition(
|
||||
Terrarum.mouseTileX * TILE_SIZED,
|
||||
(Terrarum.mouseTileY - floor((hitbox.height - 0.5) / TILE_SIZED)) * TILE_SIZED
|
||||
)
|
||||
val hbx = (Terrarum.mouseTileX - floor((hitbox.width - 0.5).div(2) / TILE_SIZED)) * TILE_SIZED
|
||||
val hby = (Terrarum.mouseTileY - floor((hitbox.height - 0.5) / TILE_SIZED)) * TILE_SIZED
|
||||
hitbox.setPosition(hbx, hby)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,9 @@ package net.torvald.terrarum.gameactors
|
||||
|
||||
import net.torvald.gdx.graphics.Cvec
|
||||
|
||||
/**
|
||||
* Lightbox is defined based on pixelwise position in the world!
|
||||
*/
|
||||
class Lightbox() {
|
||||
var hitbox: Hitbox = Hitbox(0.0,0.0,0.0,0.0)
|
||||
var light: Cvec = Cvec()
|
||||
|
||||
@@ -2,6 +2,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
|
||||
|
||||
import net.torvald.terrarum.*
|
||||
import net.torvald.terrarum.App.printdbg
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZED
|
||||
import net.torvald.terrarum.blockproperties.Block
|
||||
import net.torvald.terrarum.gameactors.ActorID
|
||||
@@ -59,6 +60,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
id: ActorID? = null
|
||||
) : super(renderOrder, PhysProperties.IMMOBILE, id) {
|
||||
blockBox = blockBox0
|
||||
setHitboxDimension(TILE_SIZE * blockBox.width, TILE_SIZE * blockBox.height, 0, 0)
|
||||
this.blockBoxProps = blockBoxProps
|
||||
this.renderOrder = renderOrder
|
||||
this.nameFun = nameFun
|
||||
@@ -112,11 +114,11 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
/**
|
||||
* Adds this instance of the fixture to the world
|
||||
*
|
||||
* @param posX tile-wise top-left position of the fixture
|
||||
* @param posY tile-wise top-left position of the fixture
|
||||
* @return true if successfully spawned, false if was not (e.g. occupied space)
|
||||
* @param posX0 tile-wise bottem-centre position of the fixture (usually [Terrarum.mouseTileX])
|
||||
* @param posY0 tile-wise bottem-centre position of the fixture (usually [Terrarum.mouseTileY])
|
||||
* @return true if successfully spawned, false if was not (e.g. space to spawn is occupied by something else)
|
||||
*/
|
||||
open fun spawn(posX: Int, posY: Int): Boolean {
|
||||
open fun spawn(posX0: Int, posY0: Int): Boolean {
|
||||
// place filler blocks
|
||||
// place the filler blocks where:
|
||||
// origin posX: centre-left if mouseX is on the right-half of the game window,
|
||||
@@ -128,33 +130,29 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
|
||||
// using the actor's hitbox
|
||||
|
||||
|
||||
// wrap x-position
|
||||
val posX = posX fmod world!!.width
|
||||
|
||||
|
||||
// check for existing blocks (and fixtures)
|
||||
var hasCollision = false
|
||||
checkForCollision@
|
||||
for (y in posY until posY + blockBox.height) {
|
||||
for (x in posX until posX + blockBox.width) {
|
||||
val tile = world!!.getTileFromTerrain(x, y)
|
||||
if (BlockCodex[tile].isSolid || BlockCodex[tile].isActorBlock) {
|
||||
hasCollision = true
|
||||
break@checkForCollision
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasCollision) {
|
||||
printdbg(this, "cannot spawn fixture ${nameFun()} at F${INGAME.WORLD_UPDATE_TIMER}, has tile collision; tilewise dim: (${blockBox.width}, ${blockBox.height}) ")
|
||||
return false
|
||||
}
|
||||
|
||||
printdbg(this, "spawn fixture ${nameFun()} at F${INGAME.WORLD_UPDATE_TIMER}, tilewise dim: (${blockBox.width}, ${blockBox.height})")
|
||||
val posX = (posX0 - blockBox.width.div(2)) fmod world!!.width
|
||||
val posY = posY0 - blockBox.height + 1
|
||||
|
||||
// set the position of this actor
|
||||
worldBlockPos = Point2i(posX, posY)
|
||||
|
||||
// check for existing blocks (and fixtures)
|
||||
var hasCollision = false
|
||||
forEachBlockbox { x, y, _, _ ->
|
||||
if (!hasCollision) {
|
||||
val tile = world!!.getTileFromTerrain(x, y)
|
||||
if (BlockCodex[tile].isSolid || BlockCodex[tile].isActorBlock) {
|
||||
hasCollision = true
|
||||
}
|
||||
}
|
||||
}
|
||||
if (hasCollision) {
|
||||
printdbg(this, "cannot spawn fixture ${nameFun()} at F${INGAME.WORLD_UPDATE_TIMER}, has tile collision; xy=($posX,$posY) tDim=(${blockBox.width},${blockBox.height})")
|
||||
return false
|
||||
}
|
||||
printdbg(this, "spawn fixture ${nameFun()} at F${INGAME.WORLD_UPDATE_TIMER}, xy=($posX,$posY) tDim=(${blockBox.width},${blockBox.height})")
|
||||
|
||||
|
||||
// fill the area with the filler blocks
|
||||
placeActorBlocks()
|
||||
|
||||
|
||||
@@ -22,9 +22,9 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
class FixtureSwingingDoorBase : FixtureBase, Luminous {
|
||||
|
||||
/* OVERRIDE THESE TO CUSTOMISE */
|
||||
open val tw = 2
|
||||
open val th = 3
|
||||
open val twClosed = 1
|
||||
open val tw = 2 // tilewise width of the door when opened
|
||||
open val th = 3 // tilewise height of the door
|
||||
open val twClosed = 1 // tilewise width of the door when closed
|
||||
open val opacity = BlockCodex[Block.STONE].opacity
|
||||
open val isOpacityActuallyLuminosity = false
|
||||
open val moduleName = "basegame"
|
||||
@@ -33,6 +33,12 @@ class FixtureSwingingDoorBase : FixtureBase, Luminous {
|
||||
open val customNameFun = { "DOOR_BASE" }
|
||||
/* END OF CUTOMISABLE PARAMETERS */
|
||||
|
||||
private val tilewiseHitboxWidth = tw * 2 - twClosed
|
||||
private val tilewiseHitboxHeight = th
|
||||
private val pixelwiseHitboxWidth = TILE_SIZE * tilewiseHitboxWidth
|
||||
private val pixelwiseHitboxHeight = TILE_SIZE * tilewiseHitboxHeight
|
||||
private val tilewiseDistToAxis = tw - twClosed
|
||||
|
||||
@Transient override val lightBoxList: ArrayList<Lightbox> = ArrayList()
|
||||
@Transient override val shadeBoxList: ArrayList<Lightbox> = ArrayList()
|
||||
|
||||
@@ -41,12 +47,9 @@ class FixtureSwingingDoorBase : FixtureBase, Luminous {
|
||||
// @Transient private var placeActorBlockLatch = false
|
||||
|
||||
constructor() : super(
|
||||
BlockBox(BlockBox.FULL_COLLISION, 1, 3), // temporary value, will be overwritten by reload()
|
||||
BlockBox(BlockBox.FULL_COLLISION, 1, 1), // temporary value, will be overwritten by spawn()
|
||||
nameFun = { "item not loaded properly, alas!" }
|
||||
) {
|
||||
val hbw = TILE_SIZE * (tw * 2 - twClosed)
|
||||
val hbh = TILE_SIZE * th
|
||||
|
||||
nameFun = customNameFun
|
||||
|
||||
density = 1200.0
|
||||
@@ -54,59 +57,69 @@ class FixtureSwingingDoorBase : FixtureBase, Luminous {
|
||||
|
||||
// loading textures
|
||||
CommonResourcePool.addToLoadingList("$moduleName-$textureIdentifier") {
|
||||
TextureRegionPack(ModMgr.getGdxFile(moduleName, texturePath), hbw, hbh)
|
||||
TextureRegionPack(ModMgr.getGdxFile(moduleName, texturePath), pixelwiseHitboxWidth, pixelwiseHitboxHeight)
|
||||
}
|
||||
CommonResourcePool.loadAll()
|
||||
makeNewSprite(FixtureBase.getSpritesheet(moduleName, texturePath, hbw, hbh)).let {
|
||||
makeNewSprite(FixtureBase.getSpritesheet(moduleName, texturePath, pixelwiseHitboxWidth, pixelwiseHitboxHeight)).let {
|
||||
it.setRowsAndFrames(3,1)
|
||||
}
|
||||
|
||||
// define light/shadebox
|
||||
// TODO: redefine when opened to left/right
|
||||
(if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList).add(
|
||||
Lightbox(Hitbox(0.0, 0.0, TILE_SIZED, th * TILE_SIZED), opacity))
|
||||
Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), opacity))
|
||||
|
||||
// define physical size
|
||||
setHitboxDimension(TILE_SIZE * tilewiseHitboxWidth, TILE_SIZE * tilewiseHitboxHeight, 0, 0)
|
||||
blockBox = BlockBox(BlockBox.FULL_COLLISION, tilewiseHitboxWidth, tilewiseHitboxHeight)
|
||||
|
||||
reload()
|
||||
}
|
||||
|
||||
override fun spawn(posX: Int, posY: Int) = spawn(posX, posY, TILE_SIZE * (tw * 2 - twClosed), TILE_SIZE * th)
|
||||
override fun spawn(posX: Int, posY: Int) = spawn(posX, posY, tilewiseHitboxWidth, tilewiseHitboxHeight)
|
||||
|
||||
// TODO move this function over FixtureBase once it's done and perfected
|
||||
protected fun spawn(posX: Int, posY: Int, hbw: Int, hbh: Int): Boolean {
|
||||
// wrap x-position
|
||||
val posX = posX fmod world!!.width
|
||||
/**
|
||||
* Identical to `spawn(Int, Int)` except it takes user-defined hitbox dimension instead of taking value from [blockBox].
|
||||
* Useful if [blockBox] cannot be determined on the time of the constructor call.
|
||||
*
|
||||
* @param posX tile-wise bottem-centre position of the fixture
|
||||
* @param posY tile-wise bottem-centre position of the fixture
|
||||
* @param thbw tile-wise Hitbox width
|
||||
* @param thbh tile-wise Hitbox height
|
||||
* @return true if successfully spawned, false if was not (e.g. space to spawn is occupied by something else)
|
||||
*/
|
||||
protected fun spawn(posX0: Int, posY0: Int, thbw: Int, thbh: Int): Boolean {
|
||||
val posX = (posX0 - thbw.div(2)) fmod world!!.width
|
||||
val posY = posY0 - thbh + 1
|
||||
|
||||
// define physical size
|
||||
setHitboxDimension(hbw, hbh, 0, 0)
|
||||
/*this.hitbox.setFromWidthHeight(
|
||||
// set the position of this actor
|
||||
worldBlockPos = Point2i(posX, posY)
|
||||
|
||||
// define physical position
|
||||
this.hitbox.setFromWidthHeight(
|
||||
posX * TILE_SIZED,
|
||||
posY * TILE_SIZED,
|
||||
blockBox.width * TILE_SIZED,
|
||||
blockBox.height * TILE_SIZED
|
||||
)*/
|
||||
blockBox = BlockBox(BlockBox.FULL_COLLISION, tw * 2 - twClosed, th)
|
||||
)
|
||||
|
||||
// check for existing blocks (and fixtures)
|
||||
var hasCollision = false
|
||||
checkForCollision@
|
||||
for (y in posY until posY + blockBox.height) {
|
||||
for (x in posX until posX + blockBox.width) {
|
||||
forEachBlockbox { x, y, _, _ ->
|
||||
if (!hasCollision) {
|
||||
val tile = world!!.getTileFromTerrain(x, y)
|
||||
if (BlockCodex[tile].isSolid || BlockCodex[tile].isActorBlock) {
|
||||
hasCollision = true
|
||||
break@checkForCollision
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (hasCollision) {
|
||||
printdbg(this, "cannot spawn fixture ${nameFun()} at F${INGAME.WORLD_UPDATE_TIMER}, has tile collision; tilewise dim: (${blockBox.width}, ${blockBox.height}) ")
|
||||
printdbg(this, "cannot spawn fixture ${nameFun()} at F${INGAME.WORLD_UPDATE_TIMER}, has tile collision; xy=($posX,$posY) tDim=(${blockBox.width},${blockBox.height})")
|
||||
return false
|
||||
}
|
||||
printdbg(this, "spawn fixture ${nameFun()} at F${INGAME.WORLD_UPDATE_TIMER}, xy=($posX,$posY) tDim=(${blockBox.width},${blockBox.height})")
|
||||
|
||||
printdbg(this, "spawn fixture ${nameFun()} at F${INGAME.WORLD_UPDATE_TIMER}, tilewise dim: (${blockBox.width}, ${blockBox.height})")
|
||||
|
||||
// set the position of this actor
|
||||
worldBlockPos = Point2i(posX - (hbw - 1) / 2, posY)
|
||||
|
||||
// fill the area with the filler blocks
|
||||
placeActorBlocks()
|
||||
@@ -128,19 +141,11 @@ class FixtureSwingingDoorBase : FixtureBase, Luminous {
|
||||
|
||||
nameFun = customNameFun
|
||||
|
||||
val hbw = TILE_SIZE * (tw * 2 - twClosed)
|
||||
val hbh = TILE_SIZE * th
|
||||
// define light/shadebox
|
||||
// TODO: redefine when opened to left/right
|
||||
(if (isOpacityActuallyLuminosity) lightBoxList else shadeBoxList).add(
|
||||
Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), opacity))
|
||||
|
||||
// redefined things that are affected by sprite size
|
||||
// blockBox = BlockBox(BlockBox.FULL_COLLISION, tw * 2 - twClosed, th)
|
||||
|
||||
// loading textures
|
||||
|
||||
// setHitboxDimension(hbw, hbh, TILE_SIZE * (tw * 2 - twClosed), 0)
|
||||
// setHitboxDimension(hbw, hbh, TILE_SIZE * ((tw * 2 - twClosed - 1) / 2), 0)
|
||||
|
||||
|
||||
// placeActorBlockLatch = false
|
||||
}
|
||||
|
||||
open protected fun closeDoor() {
|
||||
@@ -169,12 +174,14 @@ class FixtureSwingingDoorBase : FixtureBase, Luminous {
|
||||
|
||||
override fun placeActorBlocks() {
|
||||
forEachBlockbox { x, y, ox, oy ->
|
||||
printdbg(this, "placeActorBlocks xy=$x,$y oxy=$ox,$oy")
|
||||
|
||||
val tile = when (doorState) {
|
||||
// CLOSED --
|
||||
// fill the actorBlock so that:
|
||||
// N..N F N..N (repeated `th` times; N: no collision, F: full collision)
|
||||
0/*CLOSED*/ -> {
|
||||
if (ox in tw-1 until tw-1+twClosed) Block.ACTORBLOCK_FULL_COLLISION
|
||||
if (ox in tilewiseDistToAxis until tilewiseDistToAxis + twClosed) Block.ACTORBLOCK_FULL_COLLISION
|
||||
else Block.ACTORBLOCK_NO_COLLISION
|
||||
}
|
||||
else/*OPENED*/ -> Block.ACTORBLOCK_NO_COLLISION
|
||||
|
||||
@@ -33,8 +33,8 @@ open class FixtureItemBase(originalID: ItemID, val fixtureClassName: String) : G
|
||||
// println("FixtureItemBase init: $hash")
|
||||
}
|
||||
|
||||
// private var _ghostItem: FixtureBase? = null
|
||||
@Transient private var ghostItem = AtomicReference<FixtureBase>()
|
||||
@Transient private var ghostInit = AtomicBoolean(false)
|
||||
|
||||
override var dynamicID: ItemID = originalID
|
||||
override val originalName = "FIXTUREBASE"
|
||||
@@ -55,7 +55,6 @@ open class FixtureItemBase(originalID: ItemID, val fixtureClassName: String) : G
|
||||
|
||||
override var baseToolSize: Double? = baseMass
|
||||
|
||||
@Transient private var ghostInit = AtomicBoolean(false)
|
||||
|
||||
override fun effectWhileEquipped(actor: ActorWithBody, delta: Float) {
|
||||
// println("ghost: ${ghostItem}; ghostInit = $ghostInit; instance: $hash")
|
||||
@@ -87,7 +86,7 @@ open class FixtureItemBase(originalID: ItemID, val fixtureClassName: String) : G
|
||||
override fun startPrimaryUse(actor: ActorWithBody, delta: Float) = mouseInInteractableRange(actor) {
|
||||
val item = ghostItem.getAndSet(makeFixture()) // renew the "ghost" otherwise you'll be spawning exactly the same fixture again; old ghost will be returned
|
||||
|
||||
if (item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY - item.blockBox.height + 1)) 1 else -1
|
||||
if (item.spawn(Terrarum.mouseTileX, Terrarum.mouseTileY)) 1 else -1
|
||||
// return true when placed, false when cannot be placed
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user