propagation delay is now consistent; cosmetic wip

This commit is contained in:
minjaesong
2024-03-04 19:07:25 +09:00
parent 1c39036cc8
commit 4602cb5bc1
4 changed files with 83 additions and 64 deletions

View File

@@ -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)
}*/
}

View File

@@ -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()
}
}

View File

@@ -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)
}
}

View File

@@ -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) {