From 4602cb5bc17d4d66c799275330687166e1a43706 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Mon, 4 Mar 2024 19:07:25 +0900 Subject: [PATCH] propagation delay is now consistent; cosmetic wip --- .../modulebasegame/gameactors/FixtureBase.kt | 87 +++++++++++++------ .../gameactors/FixtureSignalBlocker.kt | 48 ++++------ .../gameactors/FixtureSignalBulb.kt | 9 +- .../gameactors/FixtureWorldPortal.kt | 3 + 4 files changed, 83 insertions(+), 64 deletions(-) diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt index 2c3906a4f..9702b6333 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureBase.kt @@ -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 = HashMap() + private val newStates = HashMap() /** 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 - - 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 + private val newSinkStatus: Array + + 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() + val fallingEdgeIndices = ArrayList() + + 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) }*/ } diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBlocker.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBlocker.kt index 20e13e300..efd1f2a23 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBlocker.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBlocker.kt @@ -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() + } + } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBulb.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBulb.kt index 12d2d687f..77ab08a3c 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBulb.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureSignalBulb.kt @@ -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) } } \ No newline at end of file diff --git a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureWorldPortal.kt b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureWorldPortal.kt index 14f83aded..796ae1e5e 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureWorldPortal.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameactors/FixtureWorldPortal.kt @@ -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) {