mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-11 14:21:52 +09:00
first working instance of wire signal source block
This commit is contained in:
@@ -9,6 +9,7 @@ import net.torvald.terrarum.blockproperties.Fluid
|
||||
import net.torvald.terrarum.gameactors.ActorWithBody
|
||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||
import net.torvald.terrarum.gameitem.ItemID
|
||||
import net.torvald.terrarum.modulebasegame.TerrarumIngame.Companion.inUpdateRange
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.ActorHumanoid
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
||||
@@ -452,28 +453,18 @@ object WorldSimulator {
|
||||
|
||||
private val wiresimOverscan = 60
|
||||
|
||||
/*private fun wiresimGetSourceBlocks(): List<Q> {
|
||||
val ret = ArrayList<Q>()
|
||||
|
||||
val for_y_start = (WorldCamera.y.toFloat() / TILE_SIZE).floorInt()
|
||||
val for_y_end = for_y_start + BlocksDrawer.tilesInVertical - 1
|
||||
|
||||
val for_x_start = (WorldCamera.x.toFloat() / TILE_SIZE).floorInt()
|
||||
val for_x_end = for_x_start + BlocksDrawer.tilesInHorizontal - 1
|
||||
|
||||
val fixtures = Terrarum.ingame!!.actorContainer.filterIsInstance<FixtureBase>()
|
||||
|
||||
for (y in for_y_start - wiresimOverscan..for_y_end + wiresimOverscan) {
|
||||
for (x in for_x_start - wiresimOverscan..for_x_end + wiresimOverscan) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return ret
|
||||
}*/
|
||||
private fun wiresimGetSourceBlocks(): List<FixtureBase> =
|
||||
Terrarum.ingame!!.actorContainerActive.filter {
|
||||
it is FixtureBase && it.inUpdateRange(world) && it.wireEmitterType.isNotBlank()
|
||||
} as List<FixtureBase>
|
||||
|
||||
private fun simulateWires(delta: Float) {
|
||||
//val sourceBlocks = wiresimGetSourceBlocks()
|
||||
wiresimGetSourceBlocks().let { sources ->
|
||||
// signal-emitting fixtures must set emitState of its own tiles via update()
|
||||
sources.forEach {
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private enum class WireConStatus { THRU, END, BRANCH }
|
||||
|
||||
@@ -25,6 +25,7 @@ import net.torvald.terrarum.itemproperties.ItemCodex
|
||||
import net.torvald.terrarum.console.AVTracker
|
||||
import net.torvald.terrarum.console.ActorsList
|
||||
import net.torvald.terrarum.gameactors.WireActor
|
||||
import net.torvald.terrarum.gameworld.GameWorld
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.*
|
||||
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
|
||||
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
|
||||
@@ -53,8 +54,6 @@ import kotlin.math.roundToInt
|
||||
|
||||
open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
|
||||
private val ACTOR_UPDATE_RANGE = 4096
|
||||
|
||||
var historicalFigureIDBucket: ArrayList<Int> = ArrayList<Int>()
|
||||
|
||||
|
||||
@@ -100,6 +99,45 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
" $EMDASH M: J${Terrarum.memJavaHeap}M / N${Terrarum.memNativeHeap}M / U${Terrarum.memUnsafe}M / X${Terrarum.memXmx}M"
|
||||
else
|
||||
""
|
||||
|
||||
val ACTOR_UPDATE_RANGE = 4096
|
||||
|
||||
fun distToActorSqr(world: GameWorld, a: ActorWithBody, p: ActorWithBody) =
|
||||
minOf(// take min of normal position and wrapped (x < 0) position
|
||||
(a.hitbox.centeredX - p.hitbox.centeredX).sqr() +
|
||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr(),
|
||||
((a.hitbox.centeredX + world.width * TILE_SIZE) - p.hitbox.centeredX).sqr() +
|
||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr(),
|
||||
((a.hitbox.centeredX - world.width * TILE_SIZE) - p.hitbox.centeredX).sqr() +
|
||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr()
|
||||
)
|
||||
fun distToCameraSqr(world: GameWorld, a: ActorWithBody) =
|
||||
minOf(
|
||||
(a.hitbox.centeredX - WorldCamera.xCentre).sqr() +
|
||||
(a.hitbox.centeredY - WorldCamera.yCentre).sqr(),
|
||||
((a.hitbox.centeredX + world.width * TILE_SIZE) - WorldCamera.xCentre).sqr() +
|
||||
(a.hitbox.centeredY - WorldCamera.yCentre).sqr(),
|
||||
((a.hitbox.centeredX - world.width * TILE_SIZE) - WorldCamera.xCentre).sqr() +
|
||||
(a.hitbox.centeredY - WorldCamera.yCentre).sqr()
|
||||
)
|
||||
|
||||
/** whether the actor is within update range */
|
||||
fun ActorWithBody.inUpdateRange(world: GameWorld) = distToCameraSqr(world, this) <= ACTOR_UPDATE_RANGE.sqr()
|
||||
|
||||
/** whether the actor is within screen */
|
||||
fun ActorWithBody.inScreen(world: GameWorld) =
|
||||
|
||||
// y
|
||||
this.hitbox.endY >= WorldCamera.y && this.hitbox.startY <= WorldCamera.yEnd
|
||||
|
||||
&&
|
||||
|
||||
// x: camera is on the right side of the seam
|
||||
((this.hitbox.endX - world.width >= WorldCamera.x && this.hitbox.startX - world.width <= WorldCamera.xEnd) ||
|
||||
// x: camera in on the left side of the seam
|
||||
(this.hitbox.endX + world.width >= WorldCamera.x && this.hitbox.startX + world.width <= WorldCamera.xEnd) ||
|
||||
// x: neither
|
||||
(this.hitbox.endX >= WorldCamera.x && this.hitbox.startX <= WorldCamera.xEnd))
|
||||
}
|
||||
|
||||
|
||||
@@ -708,11 +746,11 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
}
|
||||
|
||||
private fun filterVisibleActors() {
|
||||
visibleActorsRenderBehind = actorsRenderBehind.filter { it.inScreen() }
|
||||
visibleActorsRenderMiddle = actorsRenderMiddle.filter { it.inScreen() }
|
||||
visibleActorsRenderMidTop = actorsRenderMidTop.filter { it.inScreen() }
|
||||
visibleActorsRenderFront = actorsRenderFront.filter { it.inScreen() }
|
||||
visibleActorsRenderOverlay=actorsRenderOverlay.filter { it.inScreen() }
|
||||
visibleActorsRenderBehind = actorsRenderBehind.filter { it.inScreen(world) }
|
||||
visibleActorsRenderMiddle = actorsRenderMiddle.filter { it.inScreen(world) }
|
||||
visibleActorsRenderMidTop = actorsRenderMidTop.filter { it.inScreen(world) }
|
||||
visibleActorsRenderFront = actorsRenderFront.filter { it.inScreen(world) }
|
||||
visibleActorsRenderOverlay=actorsRenderOverlay.filter { it.inScreen(world) }
|
||||
}
|
||||
|
||||
private fun repossessActor() {
|
||||
@@ -761,7 +799,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
var i = 0
|
||||
while (i < actorContainerSize) { // loop through actorContainerInactive
|
||||
val actor = actorContainerInactive[i]
|
||||
if (actor is ActorWithBody && actor.inUpdateRange() && !actor.forceDormant) {
|
||||
if (actor is ActorWithBody && actor.inUpdateRange(world) && !actor.forceDormant) {
|
||||
activateDormantActor(actor) // duplicates are checked here
|
||||
actorContainerSize -= 1
|
||||
i-- // array removed 1 elem, so we also decrement counter by 1
|
||||
@@ -788,7 +826,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
i-- // array removed 1 elem, so we also decrement counter by 1
|
||||
}
|
||||
// inactivate distant actors
|
||||
else if (actor is ActorWithBody && (!actor.inUpdateRange() || actor.forceDormant)) {
|
||||
else if (actor is ActorWithBody && (!actor.inUpdateRange(world) || actor.forceDormant)) {
|
||||
if (actor !is Projectile) { // if it's a projectile, don't inactivate it; just kill it.
|
||||
actorContainerInactive.add(actor) // naïve add; duplicates are checked when the actor is re-activated
|
||||
}
|
||||
@@ -857,39 +895,6 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
d.forEach { if (it < ret) ret = it }
|
||||
return ret
|
||||
}
|
||||
private fun distToActorSqr(a: ActorWithBody, p: ActorWithBody) =
|
||||
min(// take min of normal position and wrapped (x < 0) position
|
||||
(a.hitbox.centeredX - p.hitbox.centeredX).sqr() +
|
||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr(),
|
||||
((a.hitbox.centeredX + world.width * TILE_SIZE) - p.hitbox.centeredX).sqr() +
|
||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr(),
|
||||
((a.hitbox.centeredX - world.width * TILE_SIZE) - p.hitbox.centeredX).sqr() +
|
||||
(a.hitbox.centeredY - p.hitbox.centeredY).sqr()
|
||||
)
|
||||
private fun distToCameraSqr(a: ActorWithBody) =
|
||||
min(
|
||||
(a.hitbox.centeredX - WorldCamera.xCentre).sqr() +
|
||||
(a.hitbox.centeredY - WorldCamera.yCentre).sqr(),
|
||||
((a.hitbox.centeredX + world.width * TILE_SIZE) - WorldCamera.xCentre).sqr() +
|
||||
(a.hitbox.centeredY - WorldCamera.yCentre).sqr(),
|
||||
((a.hitbox.centeredX - world.width * TILE_SIZE) - WorldCamera.xCentre).sqr() +
|
||||
(a.hitbox.centeredY - WorldCamera.yCentre).sqr()
|
||||
)
|
||||
|
||||
/** whether the actor is within screen */
|
||||
private fun ActorWithBody.inScreen() =
|
||||
|
||||
// y
|
||||
this.hitbox.endY >= WorldCamera.y && this.hitbox.startY <= WorldCamera.yEnd
|
||||
|
||||
&&
|
||||
|
||||
// x: camera is on the right side of the seam
|
||||
((this.hitbox.endX - worldWidth >= WorldCamera.x && this.hitbox.startX - worldWidth <= WorldCamera.xEnd) ||
|
||||
// x: camera in on the left side of the seam
|
||||
(this.hitbox.endX + worldWidth >= WorldCamera.x && this.hitbox.startX + worldWidth <= WorldCamera.xEnd) ||
|
||||
// x: neither
|
||||
(this.hitbox.endX >= WorldCamera.x && this.hitbox.startX <= WorldCamera.xEnd))
|
||||
|
||||
|
||||
private val cameraWindowX = WorldCamera.x.toDouble()..WorldCamera.xEnd.toDouble()
|
||||
@@ -905,9 +910,6 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||
}
|
||||
}
|
||||
|
||||
/** whether the actor is within update range */
|
||||
private fun ActorWithBody.inUpdateRange() = distToCameraSqr(this) <= ACTOR_UPDATE_RANGE.sqr()
|
||||
|
||||
override fun removeActor(ID: Int) = removeActor(getActorByID(ID))
|
||||
/**
|
||||
* get index of the actor and delete by the index.
|
||||
|
||||
@@ -37,13 +37,23 @@ open class FixtureBase(
|
||||
/**
|
||||
* Block-wise position of this fixture when it's placed on the world. Null if it's not on the world
|
||||
*/
|
||||
private var worldBlockPos: Point2i? = null
|
||||
protected var worldBlockPos: Point2i? = null
|
||||
|
||||
init {
|
||||
if (mainUI != null)
|
||||
AppLoader.disposableSingletonsPool.add(mainUI)
|
||||
}
|
||||
|
||||
fun forEachBlockbox(action: (Int, Int) -> Unit) {
|
||||
worldBlockPos?.let { (posX, posY) ->
|
||||
for (y in posY until posY + blockBox.height) {
|
||||
for (x in posX until posX + blockBox.width) {
|
||||
action(x, y)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds this instance of the fixture to the world
|
||||
*
|
||||
@@ -80,8 +90,7 @@ open class FixtureBase(
|
||||
|
||||
|
||||
// fill the area with the filler blocks
|
||||
for (y in posY until posY + blockBox.height) {
|
||||
for (x in posX until posX + blockBox.width) {
|
||||
forEachBlockbox { x, y ->
|
||||
if (blockBox.collisionType == BlockBox.ALLOW_MOVE_DOWN) {
|
||||
// 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!)
|
||||
@@ -90,7 +99,6 @@ open class FixtureBase(
|
||||
}
|
||||
else
|
||||
world!!.setTileTerrain(x, y, blockBox.collisionType, false)
|
||||
}
|
||||
}
|
||||
|
||||
// set the position of this actor
|
||||
@@ -115,10 +123,8 @@ open class FixtureBase(
|
||||
val posY = worldBlockPos!!.y
|
||||
|
||||
// remove filler block
|
||||
for (x in posX until posX + blockBox.width) {
|
||||
for (y in posY until posY + blockBox.height) {
|
||||
forEachBlockbox { x, y ->
|
||||
world!!.setTileTerrain(x, y, Block.AIR, false)
|
||||
}
|
||||
}
|
||||
|
||||
worldBlockPos = null
|
||||
@@ -156,11 +162,9 @@ open class FixtureBase(
|
||||
|
||||
if (dropThis) {
|
||||
// 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)
|
||||
}
|
||||
forEachBlockbox { x, y ->
|
||||
if (world!!.getTileFromTerrain(x, y) == blockBox.collisionType) {
|
||||
world!!.setTileTerrain(x, y, Block.AIR, false)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@ package net.torvald.terrarum.modulebasegame.gameactors
|
||||
import net.torvald.terrarum.CommonResourcePool
|
||||
import net.torvald.terrarum.ModMgr
|
||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||
import net.torvald.terrarum.blockproperties.WireCodex
|
||||
import net.torvald.terrarum.gameactors.AVKey
|
||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||
import org.dyn4j.geometry.Vector2
|
||||
@@ -27,5 +28,14 @@ class FixtureLogicSignalEmitter(nameFun: () -> String) : FixtureBase(BlockBox(Bl
|
||||
companion object {
|
||||
const val MASS = 1.0
|
||||
}
|
||||
|
||||
override fun update(delta: Float) {
|
||||
// set emit
|
||||
worldBlockPos?.let { (x, y) ->
|
||||
WireCodex.getAll().filter { it.renderClass == "signal" }.forEach { prop ->
|
||||
world?.setWireEmitStateOf(x, y, prop.id, wireEmission)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user