some fixtures now require wall or floor to spawn

This commit is contained in:
minjaesong
2023-12-05 01:42:49 +09:00
parent 06949985d1
commit 161b356077
12 changed files with 56 additions and 19 deletions

View File

@@ -18,6 +18,8 @@ import net.torvald.tsvm.peripheral.VMProgramRom
*/ */
class FixtureHomeComputer : FixtureBase { class FixtureHomeComputer : FixtureBase {
@Transient override val spawnNeedsFloor = true
// TODO: write serialiser for TSVM && allow mods to have their own serialiser // TODO: write serialiser for TSVM && allow mods to have their own serialiser
private val vm = VM(ModMgr.getGdxFile("dwarventech", "bios").path(), 0x200000, TheRealWorld(), arrayOf( private val vm = VM(ModMgr.getGdxFile("dwarventech", "bios").path(), 0x200000, TheRealWorld(), arrayOf(
VMProgramRom(ModMgr.getGdxFile("dwarventech", "bios/tsvmbios.js").path()) VMProgramRom(ModMgr.getGdxFile("dwarventech", "bios/tsvmbios.js").path())

View File

@@ -137,6 +137,9 @@ open class Electric : FixtureBase {
*/ */
open class FixtureBase : ActorWithBody, CuedByTerrainChange { open class FixtureBase : ActorWithBody, CuedByTerrainChange {
@Transient open val spawnNeedsWall: Boolean = false
@Transient open val spawnNeedsFloor: Boolean = false
/** Real time, in nanoseconds */ /** Real time, in nanoseconds */
@Transient var spawnRequestedTime: Long = 0L @Transient var spawnRequestedTime: Long = 0L
protected set protected set
@@ -215,6 +218,17 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
} }
} }
private fun <S, T> List<S>.cartesianProduct(other: List<T>) = this.flatMap { thisIt ->
other.map { otherIt ->
thisIt to otherIt
}
}
val everyBlockboxPos: List<Pair<Int, Int>>?
get() = worldBlockPos?.let { (posX, posY) ->
(posX until posX + blockBox.width).toList().cartesianProduct((posY until posY + blockBox.height).toList())
}
override fun updateForTerrainChange(cue: IngameInstance.BlockChangeQueueItem) { override fun updateForTerrainChange(cue: IngameInstance.BlockChangeQueueItem) {
placeActorBlocks() placeActorBlocks()
} }
@@ -237,19 +251,31 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
fun canSpawnHere(posX0: Int, posY0: Int): Boolean { fun canSpawnHere(posX0: Int, posY0: Int): Boolean {
val posX = (posX0 - blockBox.width.minus(1).div(2)) fmod world!!.width // width.minus(1) so that spawning position would be same as the ghost's position val posX = (posX0 - blockBox.width.minus(1).div(2)) fmod world!!.width // width.minus(1) so that spawning position would be same as the ghost's position
val posY = posY0 - blockBox.height + 1 val posY = posY0 - blockBox.height + 1
return canSpawnHere0(posX, posY)
}
private fun canSpawnHere0(posX: Int, posY: Int): Boolean {
val everyBlockboxPos = (posX until posX + blockBox.width).toList().cartesianProduct((posY until posY + blockBox.height).toList())
// check for existing blocks (and fixtures) // check for existing blocks (and fixtures)
var hasCollision = false var cannotSpawn = false
worldBlockPos = Point2i(posX, posY) worldBlockPos = Point2i(posX, posY)
forEachBlockbox { x, y, _, _ ->
if (!hasCollision) { cannotSpawn = everyBlockboxPos.any { (x, y) -> !BlockCodex[world!!.getTileFromTerrain(x, y)].hasTag("INCONSEQUENTIAL") }
val tile = world!!.getTileFromTerrain(x, y)
if (!BlockCodex[tile].hasTag("INCONSEQUENTIAL")) { // check for walls, if spawnNeedsWall = true
hasCollision = true if (spawnNeedsWall) {
} cannotSpawn = cannotSpawn or everyBlockboxPos.any { (x, y) -> !BlockCodex[world!!.getTileFromWall(x, y)].isSolid }
}
} }
return !hasCollision
// check for floors, if spawnNeedsFloor == true
if (spawnNeedsFloor) {
val y = posY + blockBox.height
val xs = posX until posX + blockBox.width
cannotSpawn = cannotSpawn or xs.any { x -> !BlockCodex[world!!.getTileFromTerrain(x, y)].isSolid }
}
return !cannotSpawn
} }
/** /**
@@ -329,16 +355,7 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
) )
// check for existing blocks (and fixtures) // check for existing blocks (and fixtures)
var hasCollision = false if (!canSpawnHere0(posX, posY)) {
forEachBlockbox { x, y, _, _ ->
if (!hasCollision) {
val tile = world!!.getTileFromTerrain(x, y)
if (!BlockCodex[tile].hasTag("INCONSEQUENTIAL")) {
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})") 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 return false
} }

View File

@@ -22,6 +22,7 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
*/ */
class FixtureSmelterBasic : FixtureBase, CraftingStation { class FixtureSmelterBasic : FixtureBase, CraftingStation {
@Transient override val spawnNeedsFloor = true
@Transient override val tags = listOf("basicsmelter") @Transient override val tags = listOf("basicsmelter")
constructor() : super( constructor() : super(

View File

@@ -13,6 +13,8 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
*/ */
internal class FixtureStorageChest : FixtureBase { internal class FixtureStorageChest : FixtureBase {
@Transient override val spawnNeedsFloor = true
constructor() : super( constructor() : super(
BlockBox(BlockBox.ALLOW_MOVE_DOWN, 1, 1), BlockBox(BlockBox.ALLOW_MOVE_DOWN, 1, 1),
mainUI = UIStorageChest(), mainUI = UIStorageChest(),

View File

@@ -43,6 +43,7 @@ open class FixtureSwingingDoorBase : FixtureBase {
private var pixelwiseHitboxHeight = TILE_SIZE * tilewiseHitboxHeight private var pixelwiseHitboxHeight = TILE_SIZE * tilewiseHitboxHeight
private var tilewiseDistToAxis = tw - twClosed private var tilewiseDistToAxis = tw - twClosed
@Transient override val spawnNeedsWall = true
@Transient override var lightBoxList = arrayListOf(Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), Cvec(0))) @Transient override var lightBoxList = arrayListOf(Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), Cvec(0)))
// the Cvec will be calculated dynamically on Update // the Cvec will be calculated dynamically on Update
@Transient override var shadeBoxList = arrayListOf(Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), Cvec(0))) @Transient override var shadeBoxList = arrayListOf(Lightbox(Hitbox(TILE_SIZED * tilewiseDistToAxis, 0.0, TILE_SIZED * twClosed, TILE_SIZED * th), Cvec(0)))

View File

@@ -7,6 +7,7 @@ import net.torvald.terrarum.blockproperties.Block
* Created by minjaesong on 2022-07-28. * Created by minjaesong on 2022-07-28.
*/ */
class FixtureSwingingDoorOak : FixtureSwingingDoorBase { class FixtureSwingingDoorOak : FixtureSwingingDoorBase {
@Transient override val spawnNeedsWall = true
constructor() : super() { constructor() : super() {
_construct( _construct(
2, 2,
@@ -24,6 +25,7 @@ class FixtureSwingingDoorOak : FixtureSwingingDoorBase {
} }
class FixtureSwingingDoorEbony : FixtureSwingingDoorBase { class FixtureSwingingDoorEbony : FixtureSwingingDoorBase {
@Transient override val spawnNeedsWall = true
constructor() : super() { constructor() : super() {
_construct( _construct(
2, 2,
@@ -41,6 +43,7 @@ class FixtureSwingingDoorEbony : FixtureSwingingDoorBase {
} }
class FixtureSwingingDoorBirch : FixtureSwingingDoorBase { class FixtureSwingingDoorBirch : FixtureSwingingDoorBase {
@Transient override val spawnNeedsWall = true
constructor() : super() { constructor() : super() {
_construct( _construct(
2, 2,
@@ -58,6 +61,7 @@ class FixtureSwingingDoorBirch : FixtureSwingingDoorBase {
} }
class FixtureSwingingDoorRosewood : FixtureSwingingDoorBase { class FixtureSwingingDoorRosewood : FixtureSwingingDoorBase {
@Transient override val spawnNeedsWall = true
constructor() : super() { constructor() : super() {
_construct( _construct(
2, 2,

View File

@@ -18,6 +18,8 @@ import kotlin.properties.Delegates
*/ */
internal class FixtureTapestry : FixtureBase { internal class FixtureTapestry : FixtureBase {
@Transient override val spawnNeedsWall = true
var artName = ""; private set var artName = ""; private set
var artAuthor = ""; private set var artAuthor = ""; private set

View File

@@ -20,6 +20,8 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
*/ */
internal class FixtureTikiTorch : FixtureBase { internal class FixtureTikiTorch : FixtureBase {
@Transient override val spawnNeedsFloor = true
private val rndHash1 = (Math.random() * 256).toInt() private val rndHash1 = (Math.random() * 256).toInt()
private val rndHash2 = (Math.random() * 256).toInt() private val rndHash2 = (Math.random() * 256).toInt()

View File

@@ -10,6 +10,7 @@ import kotlin.math.roundToInt
*/ */
class FixtureTypewriter : FixtureBase { class FixtureTypewriter : FixtureBase {
@Transient override val spawnNeedsFloor = true
var typewriterKeymapName = "us_qwerty" // used to control the keyboard input behaviour var typewriterKeymapName = "us_qwerty" // used to control the keyboard input behaviour
private set private set

View File

@@ -13,6 +13,8 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
*/ */
class FixtureWallCalendar : FixtureBase { class FixtureWallCalendar : FixtureBase {
@Transient override val spawnNeedsWall = true
constructor() : super( constructor() : super(
BlockBox(BlockBox.NO_COLLISION, 1, 1), BlockBox(BlockBox.NO_COLLISION, 1, 1),
nameFun = { Lang["ITEM_CALENDAR"] }, nameFun = { Lang["ITEM_CALENDAR"] },

View File

@@ -17,6 +17,7 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
*/ */
class FixtureWorkbench : FixtureBase, CraftingStation { class FixtureWorkbench : FixtureBase, CraftingStation {
@Transient override val spawnNeedsFloor = true
@Transient override val tags = listOf("basiccrafting") @Transient override val tags = listOf("basiccrafting")
constructor() : super( constructor() : super(

View File

@@ -19,6 +19,8 @@ import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
*/ */
class FixtureWorldPortal : Electric { class FixtureWorldPortal : Electric {
@Transient override val spawnNeedsFloor = true
constructor() : super( constructor() : super(
BlockBox(BlockBox.NO_COLLISION, 5, 2), BlockBox(BlockBox.NO_COLLISION, 5, 2),
nameFun = { Lang["ITEM_WORLD_PORTAL"] }, nameFun = { Lang["ITEM_WORLD_PORTAL"] },