illegal tile monitoring in-game

This commit is contained in:
minjaesong
2024-10-04 18:55:34 +09:00
parent af0be41a82
commit ad734a7561
4 changed files with 46 additions and 3 deletions

Binary file not shown.

View File

@@ -2,4 +2,4 @@
"digital_bit";"basegame";"wires/ports.tga";0;0
"power_low";"basegame";"wires/ports.tga";1;0
"power_high";"basegame";"wires/ports.tga";2;0
"10base2";"basegame";"wires/ports.tga";2;0
"axle";"basegame";"wires/ports.tga";3;0
1 accepts fileModule file xpos ypos
2 digital_bit basegame wires/ports.tga 0 0
3 power_low basegame wires/ports.tga 1 0
4 power_high basegame wires/ports.tga 2 0
5 10base2 axle basegame wires/ports.tga 2 3 0

View File

@@ -15,6 +15,7 @@ import net.torvald.terrarum.gameworld.GameWorld.Companion.FLUID
import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.inUpdateRange
import net.torvald.terrarum.modulebasegame.gameactors.*
import net.torvald.terrarum.modulebasegame.gameitems.AxeCore
import net.torvald.terrarum.realestate.LandUtil
import net.torvald.terrarum.realestate.LandUtil.CHUNK_H
import net.torvald.terrarum.realestate.LandUtil.CHUNK_W
import org.dyn4j.geometry.Vector2
@@ -77,6 +78,9 @@ object WorldSimulator {
/** Must be called BEFORE the actors update -- actors depend on the R-Tree for various things */
operator fun invoke(player: ActorHumanoid?, delta: Float) {
if (ingame.WORLD_UPDATE_TIMER % 600L == 0L) {
App.measureDebugTime("WorldSimulator.removeIllegalTiles") { removeIllegalTiles() }
}
//printdbg(this, "============================")
@@ -101,6 +105,34 @@ object WorldSimulator {
fun removeIllegalTiles() {
// remove actorblocks that has no fixture association
ingame.actorNowPlaying?.let { player ->
val absoluteBlockBoxes = ingame.actorContainerActive.filter { it is FixtureBase }
.mapNotNull { (it as FixtureBase).getBlockBoxPositionsAbsolute() }.flatten().map {
LandUtil.getBlockAddr(world, it.first, it.second)
}
val RADIUS_W = 32
val RADIUS_H = 24
val px = player.intTilewiseHitbox.centeredX.toInt()
val py = player.intTilewiseHitbox.centeredY.toInt()
for (y in py - RADIUS_H..py + RADIUS_H) {
for (x in px - RADIUS_W..px + RADIUS_W) {
// is this block actorblock?
if (BlockCodex[world.getTileFromTerrain(x, y)].isActorBlock) {
// is this actorblock has no fixture association?
if (!absoluteBlockBoxes.contains(LandUtil.getBlockAddr(world, x, y))) {
// then, kill it
world.setTileTerrain(x, y, Block.AIR, false)
}
}
}
}
}
}
fun buryGrassImmediately() {
ingame.terrainChangeQueue.toList().forEach {
if (it != null) {

View File

@@ -173,14 +173,25 @@ open class FixtureBase : ActorWithBody, CuedByTerrainChange {
}
/**
* Returns BlockBox definition as a list of individual blocks, relative to the given coord.
*
* @param posX start position of the BlockBox, top-left
* @param posY start position of the BlockBox, top-left
* @return real block positions, in List of Pair(x, y)
* @return block positions, in List of Pair(x, y)
*/
open fun getBlockBoxPositions(posX: Int, posY: Int): List<Pair<Int, Int>> {
return (posX until posX + blockBox.width).toList().cartesianProduct((posY until posY + blockBox.height).toList())
}
/**
* Returns BlockBox definition as a list of individual blocks, absolute position in the world.
*
* @return in-world block positions, in List of Pair(x, y); `null` if the actor is not placed on the world
*/
fun getBlockBoxPositionsAbsolute(): List<Pair<Int, Int>>? = worldBlockPos?.let { (posX, posY) ->
return getBlockBoxPositions(posX, posY)
}
open fun canSpawnHere0(posX: Int, posY: Int): Boolean {
val everyBlockboxPos = getBlockBoxPositions(posX, posY)