From 8b1331770d467f013ed62ad61ccebf1fecad26c0 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Sat, 27 Jan 2024 17:27:20 +0900 Subject: [PATCH] dust and sound on placing fixtures --- .../terrarum/gameactors/ActorWithBody.kt | 22 ++++++++ .../modulebasegame/gameactors/FixtureBase.kt | 54 +++++++++++++++++++ .../gameactors/FixtureSwingingDoorBase.kt | 45 ++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt index e5f0b7e9b..9d34708a5 100644 --- a/src/net/torvald/terrarum/gameactors/ActorWithBody.kt +++ b/src/net/torvald/terrarum/gameactors/ActorWithBody.kt @@ -1989,6 +1989,28 @@ open class ActorWithBody : Actor { return tilePosList.forEach(consumer) } + fun forEachOccupyingTilePosXY(hitbox: Hitbox, consumer: (Pair) -> Unit) { + if (world == null) return + + + val newTilewiseHitbox = Hitbox.fromTwoPoints( + hitbox.startX.div(TILE_SIZE).floorToDouble(), + hitbox.startY.div(TILE_SIZE).floorToDouble(), + hitbox.endX.minus(PHYS_EPSILON_DIST).div(TILE_SIZE).floorToDouble(), + hitbox.endY.minus(PHYS_EPSILON_DIST).div(TILE_SIZE).floorToDouble(), + true + ) // NOT the same as intTilewiseHitbox !! + + val tilePosList = ArrayList>() + for (y in newTilewiseHitbox.startY.toInt()..newTilewiseHitbox.endY.toInt()) { + for (x in newTilewiseHitbox.startX.toInt()..newTilewiseHitbox.endX.toInt()) { + tilePosList.add(x to y) + } + } + + return tilePosList.forEach(consumer) + } + fun forEachFeetTileNum(consumer: (ItemID?) -> Unit) { if (world == null) return diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt index f59b00c68..bf1e1bcef 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt @@ -8,11 +8,14 @@ import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gameitems.ItemID import net.torvald.terrarum.gameworld.fmod +import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore +import net.torvald.terrarum.realestate.LandUtil import net.torvald.terrarum.ui.UICanvas import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import org.dyn4j.geometry.Vector2 import java.util.* import kotlin.collections.HashMap +import kotlin.math.roundToInt typealias BlockBoxIndex = Int typealias WireEmissionType = String @@ -318,11 +321,60 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange { actorThatInstalledThisFixture = installersUUID + makeNoiseAndDust(posX, posY) + onSpawn(posX0, posY0) return true } + /** + * @param posX top-left + * @param posY top-left + */ + open fun makeNoiseAndDust(posX: Int, posY: Int) { + val posYb = posY + blockBox.height - 1 + val posXc = posX + blockBox.width / 2 + + // make some noise + var soundSource = + if (spawnNeedsWall) 1 + else if (spawnNeedsFloor) 0 + else 2 + // 1: wall, 0: floor, 2: if wall is not solid, use wall; else, use floor + val wallTile = world!!.getTileFromWall(posXc, posYb) + val terrTile = world!!.getTileFromTerrain(posXc, posYb + 1) + + if (soundSource == 2) { + soundSource = if (BlockCodex[wallTile].isSolid) + 1 + else + 0 + } + + when (soundSource) { + 1 -> PickaxeCore.makeNoise(this, wallTile) + 0 -> PickaxeCore.makeNoise(this, terrTile) + } + + // make some dust + if (soundSource == 0) { + val y = posY + blockBox.height + for (x in posX until posX + blockBox.width) { + val tile = world!!.getTileFromTerrain(x, y) + PickaxeCore.makeDust(tile, x, y - 1, 4 + (Math.random() + Math.random()).roundToInt()) + } + } + else { + for (y in posY until posY + blockBox.height) { + for (x in posX until posX + blockBox.width) { + val tile = world!!.getTileFromWall(x, y) + PickaxeCore.makeDust(tile, x, y, 2 + (Math.random() + Math.random()).roundToInt()) + } + } + } + } + /** * 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. @@ -369,6 +421,8 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange { actorThatInstalledThisFixture = installersUUID + makeNoiseAndDust(posX, posY) + return true } diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSwingingDoorBase.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSwingingDoorBase.kt index 185fef66a..2ce73fa12 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSwingingDoorBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSwingingDoorBase.kt @@ -11,8 +11,10 @@ import net.torvald.terrarum.blockproperties.Block import net.torvald.terrarum.gameactors.* import net.torvald.terrarum.gameitems.mouseInInteractableRange import net.torvald.terrarum.langpack.Lang +import net.torvald.terrarum.modulebasegame.gameitems.PickaxeCore import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack import java.util.* +import kotlin.math.roundToInt /** * @param width of hitbox, in tiles, when the door is opened. Default to 2. Closed door always have width of 1. (this limits how big and thick the door can be) @@ -145,6 +147,49 @@ open class FixtureSwingingDoorBase : FixtureBase { override fun spawn(posX: Int, posY: Int, installersUUID: UUID?): Boolean = spawn(posX, posY, installersUUID, tilewiseHitboxWidth, tilewiseHitboxHeight) + override fun makeNoiseAndDust(posX: Int, posY: Int) { + val posYb = posY + blockBox.height - 1 + val posXc = posX + blockBox.width / 2 + + // make some noise + var soundSource = + if (spawnNeedsWall) 1 + else if (spawnNeedsFloor) 0 + else 2 + // 1: wall, 0: floor, 2: if wall is not solid, use wall; else, use floor + val wallTile = world!!.getTileFromWall(posXc, posYb) + val terrTile = world!!.getTileFromTerrain(posXc, posYb + 1) + + if (soundSource == 2) { + soundSource = if (BlockCodex[wallTile].isSolid) + 1 + else + 0 + } + + when (soundSource) { + 1 -> PickaxeCore.makeNoise(this, wallTile) + 0 -> PickaxeCore.makeNoise(this, terrTile) + } + + // make some dust + if (soundSource == 0) { + val y = posY + blockBox.height + for (x in (posX + tw - twClosed) until (posX + tw - twClosed) + twClosed) { + val tile = world!!.getTileFromTerrain(x, y) + PickaxeCore.makeDust(tile, x, y - 1, 4 + (Math.random() + Math.random()).roundToInt()) + } + } + else { + for (y in posY until posY + blockBox.height) { + for (x in (posX + tw - twClosed) until (posX + tw - twClosed) + twClosed) { + val tile = world!!.getTileFromWall(x, y) + PickaxeCore.makeDust(tile, x, y, 2 + (Math.random() + Math.random()).roundToInt()) + } + } + } + } + override fun canSpawnHere0(posX: Int, posY: Int): Boolean { val everyBlockboxPos = (posX until posX + blockBox.width).toList().cartesianProduct((posY until posY + blockBox.height).toList())