mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-11 06:11:50 +09:00
propagation delay is now consistent; cosmetic wip
This commit is contained in:
@@ -23,6 +23,7 @@ open class Electric : FixtureBase {
|
||||
|
||||
protected constructor() : super() {
|
||||
oldSinkStatus = Array(blockBox.width * blockBox.height) { Vector2() }
|
||||
newSinkStatus = Array(blockBox.width * blockBox.height) { Vector2() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -51,6 +52,7 @@ open class Electric : FixtureBase {
|
||||
App.disposables.add(mainUI)
|
||||
|
||||
oldSinkStatus = Array(blockBox.width * blockBox.height) { Vector2() }
|
||||
newSinkStatus = Array(blockBox.width * blockBox.height) { Vector2() }
|
||||
}
|
||||
|
||||
companion object {
|
||||
@@ -59,8 +61,10 @@ open class Electric : FixtureBase {
|
||||
const val ELECTRIC_THRESHOLD_EDGE_DELTA = 0.7
|
||||
}
|
||||
|
||||
fun getWireEmitterAt(blockBoxIndex: BlockBoxIndex) = this.wireEmitterTypes[blockBoxIndex]
|
||||
fun getWireEmitterAt(point: Point2i) = this.wireEmitterTypes[pointToBlockBoxIndex(point)]
|
||||
fun getWireEmitterAt(x: Int, y: Int) = this.wireEmitterTypes[pointToBlockBoxIndex(x, y)]
|
||||
fun getWireSinkAt(blockBoxIndex: BlockBoxIndex) = this.wireSinkTypes[blockBoxIndex]
|
||||
fun getWireSinkAt(point: Point2i) = this.wireSinkTypes[pointToBlockBoxIndex(point)]
|
||||
fun getWireSinkAt(x: Int, y: Int) = this.wireSinkTypes[pointToBlockBoxIndex(x, y)]
|
||||
|
||||
@@ -79,33 +83,42 @@ open class Electric : FixtureBase {
|
||||
// Use case: signal buffer (sinkType=digital_bit), battery (sinkType=electricity), etc.
|
||||
val chargeStored: HashMap<String, Double> = HashMap()
|
||||
|
||||
private val newStates = HashMap<BlockBoxIndex, Vector2>()
|
||||
|
||||
/** Triggered when 'digital_bit' rises from low to high. Edge detection only considers the real component (labeled as 'x') of the vector */
|
||||
open fun onRisingEdge(readFrom: BlockBoxIndex) {}
|
||||
/** Triggered when 'digital_bit' rises from high to low. Edge detection only considers the real component (labeled as 'x') of the vector */
|
||||
open fun onFallingEdge(readFrom: BlockBoxIndex) {}
|
||||
/** Triggered when 'digital_bit' is held high. This function WILL NOT be triggered simultaneously with the rising edge. Level detection only considers the real component (labeled as 'x') of the vector */
|
||||
open fun onSignalHigh(readFrom: BlockBoxIndex) {}
|
||||
//open fun onSignalHigh(readFrom: BlockBoxIndex) {}
|
||||
/** Triggered when 'digital_bit' is held low. This function WILL NOT be triggered simultaneously with the falling edge. Level detection only considers the real component (labeled as 'x') of the vector */
|
||||
open fun onSignalLow(readFrom: BlockBoxIndex) {}
|
||||
//open fun onSignalLow(readFrom: BlockBoxIndex) {}
|
||||
|
||||
fun getWireStateAt(offsetX: Int, offsetY: Int): Vector2 {
|
||||
open fun updateSignal() {}
|
||||
|
||||
fun getWireStateAt(offsetX: Int, offsetY: Int, sinkType: WireEmissionType): Vector2 {
|
||||
val index = pointToBlockBoxIndex(offsetX, offsetY)
|
||||
return oldSinkStatus[index]
|
||||
}
|
||||
|
||||
private val oldSinkStatus: Array<Vector2>
|
||||
|
||||
open fun updateOnWireGraphTraversal(offsetX: Int, offsetY: Int, sinkType: WireEmissionType) {
|
||||
val index = pointToBlockBoxIndex(offsetX, offsetY)
|
||||
val old = oldSinkStatus[index]
|
||||
val wx = offsetX + intTilewiseHitbox.startX.toInt()
|
||||
val wy = offsetY + intTilewiseHitbox.startY.toInt()
|
||||
val new = WireCodex.getAllWiresThatAccepts("digital_bit").fold(Vector2()) { acc, (id, _) ->
|
||||
|
||||
return WireCodex.getAllWiresThatAccepts(sinkType).fold(Vector2()) { acc, (id, _) ->
|
||||
INGAME.world.getWireEmitStateOf(wx, wy, id).let {
|
||||
Vector2(acc.x + (it?.x ?: 0.0), acc.y + (it?.y ?: 0.0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getWireEmissionAt(offsetX: Int, offsetY: Int): Vector2 {
|
||||
return wireEmission[pointToBlockBoxIndex(offsetY, offsetY)] ?: Vector2()
|
||||
}
|
||||
|
||||
private val oldSinkStatus: Array<Vector2>
|
||||
private val newSinkStatus: Array<Vector2>
|
||||
|
||||
open fun updateOnWireGraphTraversal(offsetX: Int, offsetY: Int, sinkType: WireEmissionType) {
|
||||
val index = pointToBlockBoxIndex(offsetX, offsetY)
|
||||
val wx = offsetX + intTilewiseHitbox.startX.toInt()
|
||||
val wy = offsetY + intTilewiseHitbox.startY.toInt()
|
||||
|
||||
val new2 = WireCodex.getAllWiresThatAccepts(wireSinkTypes[index] ?: "").fold(Vector2()) { acc, (id, _) ->
|
||||
INGAME.world.getWireEmitStateOf(wx, wy, id).let {
|
||||
@@ -113,16 +126,6 @@ open class Electric : FixtureBase {
|
||||
}
|
||||
}
|
||||
|
||||
if (sinkType == "digital_bit") {
|
||||
if (new.x - old.x >= ELECTRIC_THRESHOLD_EDGE_DELTA && new.x >= ELECTIC_THRESHOLD_HIGH)
|
||||
onRisingEdge(index)
|
||||
else if (old.x - new.x >= ELECTRIC_THRESHOLD_EDGE_DELTA && new.x <= ELECTRIC_THRESHOLD_LOW)
|
||||
onFallingEdge(index)
|
||||
else if (new.x >= ELECTIC_THRESHOLD_HIGH)
|
||||
onSignalHigh(index)
|
||||
else if (new.y <= ELECTRIC_THRESHOLD_LOW)
|
||||
onSignalLow(index)
|
||||
}
|
||||
|
||||
oldSinkStatus[index].set(new2)
|
||||
}
|
||||
@@ -132,14 +135,42 @@ open class Electric : FixtureBase {
|
||||
*/
|
||||
override fun updateImpl(delta: Float) {
|
||||
super.updateImpl(delta)
|
||||
/*oldSinkStatus.indices.forEach { index ->
|
||||
val wx = (index % blockBox.width) + intTilewiseHitbox.startX.toInt()
|
||||
val wy = (index / blockBox.width) + intTilewiseHitbox.startY.toInt()
|
||||
val new = WireCodex.getAllWiresThatAccepts(getWireSinkAt(index % blockBox.width, index / blockBox.width) ?: "").fold(Vector2()) { acc, (id, _) ->
|
||||
INGAME.world.getWireEmitStateOf(wx, wy, id).let {
|
||||
Vector2(acc.x + (it?.x ?: 0.0), acc.y + (it?.y ?: 0.0))
|
||||
|
||||
val risingEdgeIndices = ArrayList<BlockBoxIndex>()
|
||||
val fallingEdgeIndices = ArrayList<BlockBoxIndex>()
|
||||
|
||||
for (y in 0 until blockBox.height) {
|
||||
for (x in 0 until blockBox.width) {
|
||||
// get indices of "rising edges"
|
||||
// get indices of "falling edges"
|
||||
|
||||
val wx = x + intTilewiseHitbox.startX.toInt()
|
||||
val wy = y + intTilewiseHitbox.startY.toInt()
|
||||
val new = WireCodex.getAllWiresThatAccepts(getWireSinkAt(x, y) ?: "").fold(Vector2()) { acc, (id, _) ->
|
||||
INGAME.world.getWireEmitStateOf(wx, wy, id).let {
|
||||
Vector2(acc.x + (it?.x ?: 0.0), acc.y + (it?.y ?: 0.0))
|
||||
}
|
||||
}
|
||||
val index = pointToBlockBoxIndex(x, y)
|
||||
|
||||
if (new.x - oldSinkStatus[index].x >= ELECTRIC_THRESHOLD_EDGE_DELTA && new.x >= ELECTIC_THRESHOLD_HIGH)
|
||||
risingEdgeIndices.add(index)
|
||||
else if (oldSinkStatus[index].x - new.x >= ELECTRIC_THRESHOLD_EDGE_DELTA && new.x <= ELECTRIC_THRESHOLD_LOW)
|
||||
fallingEdgeIndices.add(index)
|
||||
|
||||
|
||||
oldSinkStatus[index].set(new)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
risingEdgeIndices.forEach { onRisingEdge(it) }
|
||||
fallingEdgeIndices.forEach { onFallingEdge(it) }
|
||||
updateSignal()
|
||||
|
||||
|
||||
|
||||
/*oldSinkStatus.indices.forEach { index ->
|
||||
oldSinkStatus[index].set(new)
|
||||
}*/
|
||||
}
|
||||
|
||||
@@ -85,11 +85,11 @@ class FixtureSignalBlocker : Electric, Reorientable {
|
||||
|
||||
makeNewSprite(TextureRegionPack(itemImage.texture, 2*TILE_SIZE, 2*TILE_SIZE)).let {
|
||||
it.setRowsAndFrames(16,4)
|
||||
it.delays = FloatArray(8) { Float.POSITIVE_INFINITY }
|
||||
it.delays = FloatArray(16) { Float.POSITIVE_INFINITY }
|
||||
}
|
||||
makeNewSpriteEmissive(TextureRegionPack(itemImage2.texture, 2*TILE_SIZE, 2*TILE_SIZE)).let {
|
||||
it.setRowsAndFrames(16,4)
|
||||
it.delays = FloatArray(8) { Float.POSITIVE_INFINITY }
|
||||
it.delays = FloatArray(16) { Float.POSITIVE_INFINITY }
|
||||
}
|
||||
|
||||
setEmitterAndSink()
|
||||
@@ -103,19 +103,19 @@ class FixtureSignalBlocker : Electric, Reorientable {
|
||||
|
||||
private val I: Boolean
|
||||
get() = when (orientation) {
|
||||
0 -> getWireStateAt(0, 0).x >= ELECTIC_THRESHOLD_HIGH
|
||||
1 -> getWireStateAt(1, 0).x >= ELECTIC_THRESHOLD_HIGH
|
||||
2 -> getWireStateAt(1, 1).x >= ELECTIC_THRESHOLD_HIGH
|
||||
3 -> getWireStateAt(0, 1).x >= ELECTIC_THRESHOLD_HIGH
|
||||
0 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||
1 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||
2 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||
3 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||
else -> throw IllegalStateException("Orientation not in range ($orientation)")
|
||||
}
|
||||
|
||||
private val J: Boolean
|
||||
get() = when (orientation) {
|
||||
0 -> getWireStateAt(0, 1).x >= ELECTIC_THRESHOLD_HIGH
|
||||
1 -> getWireStateAt(0, 0).x >= ELECTIC_THRESHOLD_HIGH
|
||||
2 -> getWireStateAt(1, 0).x >= ELECTIC_THRESHOLD_HIGH
|
||||
3 -> getWireStateAt(1, 1).x >= ELECTIC_THRESHOLD_HIGH
|
||||
0 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||
1 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||
2 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||
3 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||
else -> throw IllegalStateException("Orientation not in range ($orientation)")
|
||||
}
|
||||
|
||||
@@ -130,10 +130,10 @@ class FixtureSignalBlocker : Electric, Reorientable {
|
||||
setWireEmissionAt(x, y, Vector2(I nimply J, 0.0))
|
||||
|
||||
// update sprite
|
||||
val one = getWireStateAt(0, 0).x >= ELECTIC_THRESHOLD_HIGH
|
||||
val two = getWireStateAt(1, 0).x >= ELECTIC_THRESHOLD_HIGH
|
||||
val four = getWireStateAt(0, 1).x >= ELECTIC_THRESHOLD_HIGH
|
||||
val eight = getWireStateAt(1, 1).x >= ELECTIC_THRESHOLD_HIGH
|
||||
val one = getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH || getWireEmissionAt(0, 0).x >= ELECTIC_THRESHOLD_HIGH
|
||||
val two = getWireStateAt(1, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH || getWireEmissionAt(1, 0).x >= ELECTIC_THRESHOLD_HIGH
|
||||
val four = getWireStateAt(0, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH || getWireEmissionAt(0, 1).x >= ELECTIC_THRESHOLD_HIGH
|
||||
val eight = getWireStateAt(1, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH || getWireEmissionAt(1, 1).x >= ELECTIC_THRESHOLD_HIGH
|
||||
|
||||
val state = one.toInt(0) or two.toInt(1) or four.toInt(2) or eight.toInt(3)
|
||||
|
||||
@@ -141,22 +141,10 @@ class FixtureSignalBlocker : Electric, Reorientable {
|
||||
(spriteEmissive as SheetSpriteAnimation).currentRow = state
|
||||
}
|
||||
|
||||
override fun onRisingEdge(readFrom: BlockBoxIndex) {
|
||||
updateK()
|
||||
}
|
||||
|
||||
override fun onFallingEdge(readFrom: BlockBoxIndex) {
|
||||
updateK()
|
||||
}
|
||||
|
||||
override fun onSignalHigh(readFrom: BlockBoxIndex) {
|
||||
updateK()
|
||||
}
|
||||
|
||||
override fun onSignalLow(readFrom: BlockBoxIndex) {
|
||||
updateK()
|
||||
}
|
||||
|
||||
private infix fun Boolean.nimply(other: Boolean) = (this && !other).toInt().toDouble()
|
||||
|
||||
override fun updateSignal() {
|
||||
updateK()
|
||||
}
|
||||
|
||||
}
|
||||
@@ -49,11 +49,8 @@ class FixtureSignalBulb : Electric {
|
||||
(spriteEmissive as SheetSpriteAnimation).currentRow = state.toInt()
|
||||
}
|
||||
|
||||
override fun onSignalHigh(readFrom: BlockBoxIndex) {
|
||||
light(true)
|
||||
}
|
||||
|
||||
override fun onSignalLow(readFrom: BlockBoxIndex) {
|
||||
light(false)
|
||||
override fun updateImpl(delta: Float) {
|
||||
super.updateImpl(delta)
|
||||
light(getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH)
|
||||
}
|
||||
}
|
||||
@@ -62,6 +62,9 @@ class FixtureWorldPortal : Electric {
|
||||
}
|
||||
|
||||
override fun onRisingEdge(readFrom: BlockBoxIndex) {
|
||||
if (getWireSinkAt(readFrom) != "digital_bit") return
|
||||
|
||||
|
||||
printdbg(this, "teleport! $teleportRequest")
|
||||
teleportRequest?.let {
|
||||
if (it.worldDiskToLoad != null && it.worldLoadParam != null) {
|
||||
|
||||
Reference in New Issue
Block a user