mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-14 12:34:05 +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.gameactors.ActorWithBody
|
||||||
import net.torvald.terrarum.gamecontroller.KeyToggler
|
import net.torvald.terrarum.gamecontroller.KeyToggler
|
||||||
import net.torvald.terrarum.gameitem.ItemID
|
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.ActorHumanoid
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
import net.torvald.terrarum.modulebasegame.gameactors.FixtureBase
|
||||||
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
import net.torvald.terrarum.worlddrawer.BlocksDrawer
|
||||||
@@ -452,28 +453,18 @@ object WorldSimulator {
|
|||||||
|
|
||||||
private val wiresimOverscan = 60
|
private val wiresimOverscan = 60
|
||||||
|
|
||||||
/*private fun wiresimGetSourceBlocks(): List<Q> {
|
private fun wiresimGetSourceBlocks(): List<FixtureBase> =
|
||||||
val ret = ArrayList<Q>()
|
Terrarum.ingame!!.actorContainerActive.filter {
|
||||||
|
it is FixtureBase && it.inUpdateRange(world) && it.wireEmitterType.isNotBlank()
|
||||||
val for_y_start = (WorldCamera.y.toFloat() / TILE_SIZE).floorInt()
|
} as List<FixtureBase>
|
||||||
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 simulateWires(delta: Float) {
|
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 }
|
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.AVTracker
|
||||||
import net.torvald.terrarum.console.ActorsList
|
import net.torvald.terrarum.console.ActorsList
|
||||||
import net.torvald.terrarum.gameactors.WireActor
|
import net.torvald.terrarum.gameactors.WireActor
|
||||||
|
import net.torvald.terrarum.gameworld.GameWorld
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.*
|
import net.torvald.terrarum.modulebasegame.gameactors.*
|
||||||
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
|
import net.torvald.terrarum.modulebasegame.gameactors.physicssolver.CollisionSolver
|
||||||
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
|
import net.torvald.terrarum.modulebasegame.gameworld.GameWorldExtension
|
||||||
@@ -53,8 +54,6 @@ import kotlin.math.roundToInt
|
|||||||
|
|
||||||
open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
||||||
|
|
||||||
private val ACTOR_UPDATE_RANGE = 4096
|
|
||||||
|
|
||||||
var historicalFigureIDBucket: ArrayList<Int> = ArrayList<Int>()
|
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"
|
" $EMDASH M: J${Terrarum.memJavaHeap}M / N${Terrarum.memNativeHeap}M / U${Terrarum.memUnsafe}M / X${Terrarum.memXmx}M"
|
||||||
else
|
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() {
|
private fun filterVisibleActors() {
|
||||||
visibleActorsRenderBehind = actorsRenderBehind.filter { it.inScreen() }
|
visibleActorsRenderBehind = actorsRenderBehind.filter { it.inScreen(world) }
|
||||||
visibleActorsRenderMiddle = actorsRenderMiddle.filter { it.inScreen() }
|
visibleActorsRenderMiddle = actorsRenderMiddle.filter { it.inScreen(world) }
|
||||||
visibleActorsRenderMidTop = actorsRenderMidTop.filter { it.inScreen() }
|
visibleActorsRenderMidTop = actorsRenderMidTop.filter { it.inScreen(world) }
|
||||||
visibleActorsRenderFront = actorsRenderFront.filter { it.inScreen() }
|
visibleActorsRenderFront = actorsRenderFront.filter { it.inScreen(world) }
|
||||||
visibleActorsRenderOverlay=actorsRenderOverlay.filter { it.inScreen() }
|
visibleActorsRenderOverlay=actorsRenderOverlay.filter { it.inScreen(world) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun repossessActor() {
|
private fun repossessActor() {
|
||||||
@@ -761,7 +799,7 @@ open class TerrarumIngame(batch: SpriteBatch) : IngameInstance(batch) {
|
|||||||
var i = 0
|
var i = 0
|
||||||
while (i < actorContainerSize) { // loop through actorContainerInactive
|
while (i < actorContainerSize) { // loop through actorContainerInactive
|
||||||
val actor = actorContainerInactive[i]
|
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
|
activateDormantActor(actor) // duplicates are checked here
|
||||||
actorContainerSize -= 1
|
actorContainerSize -= 1
|
||||||
i-- // array removed 1 elem, so we also decrement counter by 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
|
i-- // array removed 1 elem, so we also decrement counter by 1
|
||||||
}
|
}
|
||||||
// inactivate distant actors
|
// 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.
|
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
|
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 }
|
d.forEach { if (it < ret) ret = it }
|
||||||
return ret
|
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()
|
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))
|
override fun removeActor(ID: Int) = removeActor(getActorByID(ID))
|
||||||
/**
|
/**
|
||||||
* get index of the actor and delete by the index.
|
* 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
|
* 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 {
|
init {
|
||||||
if (mainUI != null)
|
if (mainUI != null)
|
||||||
AppLoader.disposableSingletonsPool.add(mainUI)
|
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
|
* Adds this instance of the fixture to the world
|
||||||
*
|
*
|
||||||
@@ -80,8 +90,7 @@ open class FixtureBase(
|
|||||||
|
|
||||||
|
|
||||||
// fill the area with the filler blocks
|
// fill the area with the filler blocks
|
||||||
for (y in posY until posY + blockBox.height) {
|
forEachBlockbox { x, y ->
|
||||||
for (x in posX until posX + blockBox.width) {
|
|
||||||
if (blockBox.collisionType == BlockBox.ALLOW_MOVE_DOWN) {
|
if (blockBox.collisionType == BlockBox.ALLOW_MOVE_DOWN) {
|
||||||
// if the collision type is allow_move_down, only the top surface tile should be "the platform"
|
// 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!)
|
// lower part must not have such property (think of the table!)
|
||||||
@@ -90,7 +99,6 @@ open class FixtureBase(
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
world!!.setTileTerrain(x, y, blockBox.collisionType, false)
|
world!!.setTileTerrain(x, y, blockBox.collisionType, false)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// set the position of this actor
|
// set the position of this actor
|
||||||
@@ -115,10 +123,8 @@ open class FixtureBase(
|
|||||||
val posY = worldBlockPos!!.y
|
val posY = worldBlockPos!!.y
|
||||||
|
|
||||||
// remove filler block
|
// remove filler block
|
||||||
for (x in posX until posX + blockBox.width) {
|
forEachBlockbox { x, y ->
|
||||||
for (y in posY until posY + blockBox.height) {
|
|
||||||
world!!.setTileTerrain(x, y, Block.AIR, false)
|
world!!.setTileTerrain(x, y, Block.AIR, false)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
worldBlockPos = null
|
worldBlockPos = null
|
||||||
@@ -156,11 +162,9 @@ open class FixtureBase(
|
|||||||
|
|
||||||
if (dropThis) {
|
if (dropThis) {
|
||||||
// fill blockbox with air
|
// fill blockbox with air
|
||||||
for (x in posX until posX + blockBox.width) {
|
forEachBlockbox { x, y ->
|
||||||
for (y in posY until posY + blockBox.height) {
|
if (world!!.getTileFromTerrain(x, y) == blockBox.collisionType) {
|
||||||
if (world!!.getTileFromTerrain(x, y) == blockBox.collisionType) {
|
world!!.setTileTerrain(x, y, Block.AIR, false)
|
||||||
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.CommonResourcePool
|
||||||
import net.torvald.terrarum.ModMgr
|
import net.torvald.terrarum.ModMgr
|
||||||
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
import net.torvald.terrarum.TerrarumAppConfiguration.TILE_SIZE
|
||||||
|
import net.torvald.terrarum.blockproperties.WireCodex
|
||||||
import net.torvald.terrarum.gameactors.AVKey
|
import net.torvald.terrarum.gameactors.AVKey
|
||||||
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
import net.torvald.terrarumsansbitmap.gdx.TextureRegionPack
|
||||||
import org.dyn4j.geometry.Vector2
|
import org.dyn4j.geometry.Vector2
|
||||||
@@ -27,5 +28,14 @@ class FixtureLogicSignalEmitter(nameFun: () -> String) : FixtureBase(BlockBox(Bl
|
|||||||
companion object {
|
companion object {
|
||||||
const val MASS = 1.0
|
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