mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-06-13 20:14:05 +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() {
|
protected constructor() : super() {
|
||||||
oldSinkStatus = Array(blockBox.width * blockBox.height) { Vector2() }
|
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)
|
App.disposables.add(mainUI)
|
||||||
|
|
||||||
oldSinkStatus = Array(blockBox.width * blockBox.height) { Vector2() }
|
oldSinkStatus = Array(blockBox.width * blockBox.height) { Vector2() }
|
||||||
|
newSinkStatus = Array(blockBox.width * blockBox.height) { Vector2() }
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@@ -59,8 +61,10 @@ open class Electric : FixtureBase {
|
|||||||
const val ELECTRIC_THRESHOLD_EDGE_DELTA = 0.7
|
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(point: Point2i) = this.wireEmitterTypes[pointToBlockBoxIndex(point)]
|
||||||
fun getWireEmitterAt(x: Int, y: Int) = this.wireEmitterTypes[pointToBlockBoxIndex(x, y)]
|
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(point: Point2i) = this.wireSinkTypes[pointToBlockBoxIndex(point)]
|
||||||
fun getWireSinkAt(x: Int, y: Int) = this.wireSinkTypes[pointToBlockBoxIndex(x, y)]
|
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.
|
// Use case: signal buffer (sinkType=digital_bit), battery (sinkType=electricity), etc.
|
||||||
val chargeStored: HashMap<String, Double> = HashMap()
|
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 */
|
/** 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) {}
|
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 */
|
/** 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) {}
|
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 */
|
/** 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 */
|
/** 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)
|
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 wx = offsetX + intTilewiseHitbox.startX.toInt()
|
||||||
val wy = offsetY + intTilewiseHitbox.startY.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 {
|
INGAME.world.getWireEmitStateOf(wx, wy, id).let {
|
||||||
Vector2(acc.x + (it?.x ?: 0.0), acc.y + (it?.y ?: 0.0))
|
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, _) ->
|
val new2 = WireCodex.getAllWiresThatAccepts(wireSinkTypes[index] ?: "").fold(Vector2()) { acc, (id, _) ->
|
||||||
INGAME.world.getWireEmitStateOf(wx, wy, id).let {
|
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)
|
oldSinkStatus[index].set(new2)
|
||||||
}
|
}
|
||||||
@@ -132,14 +135,42 @@ open class Electric : FixtureBase {
|
|||||||
*/
|
*/
|
||||||
override fun updateImpl(delta: Float) {
|
override fun updateImpl(delta: Float) {
|
||||||
super.updateImpl(delta)
|
super.updateImpl(delta)
|
||||||
/*oldSinkStatus.indices.forEach { index ->
|
|
||||||
val wx = (index % blockBox.width) + intTilewiseHitbox.startX.toInt()
|
val risingEdgeIndices = ArrayList<BlockBoxIndex>()
|
||||||
val wy = (index / blockBox.width) + intTilewiseHitbox.startY.toInt()
|
val fallingEdgeIndices = ArrayList<BlockBoxIndex>()
|
||||||
val new = WireCodex.getAllWiresThatAccepts(getWireSinkAt(index % blockBox.width, index / blockBox.width) ?: "").fold(Vector2()) { acc, (id, _) ->
|
|
||||||
INGAME.world.getWireEmitStateOf(wx, wy, id).let {
|
for (y in 0 until blockBox.height) {
|
||||||
Vector2(acc.x + (it?.x ?: 0.0), acc.y + (it?.y ?: 0.0))
|
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)
|
oldSinkStatus[index].set(new)
|
||||||
}*/
|
}*/
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,11 +85,11 @@ class FixtureSignalBlocker : Electric, Reorientable {
|
|||||||
|
|
||||||
makeNewSprite(TextureRegionPack(itemImage.texture, 2*TILE_SIZE, 2*TILE_SIZE)).let {
|
makeNewSprite(TextureRegionPack(itemImage.texture, 2*TILE_SIZE, 2*TILE_SIZE)).let {
|
||||||
it.setRowsAndFrames(16,4)
|
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 {
|
makeNewSpriteEmissive(TextureRegionPack(itemImage2.texture, 2*TILE_SIZE, 2*TILE_SIZE)).let {
|
||||||
it.setRowsAndFrames(16,4)
|
it.setRowsAndFrames(16,4)
|
||||||
it.delays = FloatArray(8) { Float.POSITIVE_INFINITY }
|
it.delays = FloatArray(16) { Float.POSITIVE_INFINITY }
|
||||||
}
|
}
|
||||||
|
|
||||||
setEmitterAndSink()
|
setEmitterAndSink()
|
||||||
@@ -103,19 +103,19 @@ class FixtureSignalBlocker : Electric, Reorientable {
|
|||||||
|
|
||||||
private val I: Boolean
|
private val I: Boolean
|
||||||
get() = when (orientation) {
|
get() = when (orientation) {
|
||||||
0 -> getWireStateAt(0, 0).x >= ELECTIC_THRESHOLD_HIGH
|
0 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||||
1 -> getWireStateAt(1, 0).x >= ELECTIC_THRESHOLD_HIGH
|
1 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||||
2 -> getWireStateAt(1, 1).x >= ELECTIC_THRESHOLD_HIGH
|
2 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||||
3 -> getWireStateAt(0, 1).x >= ELECTIC_THRESHOLD_HIGH
|
3 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||||
else -> throw IllegalStateException("Orientation not in range ($orientation)")
|
else -> throw IllegalStateException("Orientation not in range ($orientation)")
|
||||||
}
|
}
|
||||||
|
|
||||||
private val J: Boolean
|
private val J: Boolean
|
||||||
get() = when (orientation) {
|
get() = when (orientation) {
|
||||||
0 -> getWireStateAt(0, 1).x >= ELECTIC_THRESHOLD_HIGH
|
0 -> getWireStateAt(0, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||||
1 -> getWireStateAt(0, 0).x >= ELECTIC_THRESHOLD_HIGH
|
1 -> getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||||
2 -> getWireStateAt(1, 0).x >= ELECTIC_THRESHOLD_HIGH
|
2 -> getWireStateAt(1, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||||
3 -> getWireStateAt(1, 1).x >= ELECTIC_THRESHOLD_HIGH
|
3 -> getWireStateAt(1, 1, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH
|
||||||
else -> throw IllegalStateException("Orientation not in range ($orientation)")
|
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))
|
setWireEmissionAt(x, y, Vector2(I nimply J, 0.0))
|
||||||
|
|
||||||
// update sprite
|
// update sprite
|
||||||
val one = getWireStateAt(0, 0).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).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).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).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)
|
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
|
(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()
|
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()
|
(spriteEmissive as SheetSpriteAnimation).currentRow = state.toInt()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onSignalHigh(readFrom: BlockBoxIndex) {
|
override fun updateImpl(delta: Float) {
|
||||||
light(true)
|
super.updateImpl(delta)
|
||||||
}
|
light(getWireStateAt(0, 0, "digital_bit").x >= ELECTIC_THRESHOLD_HIGH)
|
||||||
|
|
||||||
override fun onSignalLow(readFrom: BlockBoxIndex) {
|
|
||||||
light(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -62,6 +62,9 @@ class FixtureWorldPortal : Electric {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun onRisingEdge(readFrom: BlockBoxIndex) {
|
override fun onRisingEdge(readFrom: BlockBoxIndex) {
|
||||||
|
if (getWireSinkAt(readFrom) != "digital_bit") return
|
||||||
|
|
||||||
|
|
||||||
printdbg(this, "teleport! $teleportRequest")
|
printdbg(this, "teleport! $teleportRequest")
|
||||||
teleportRequest?.let {
|
teleportRequest?.let {
|
||||||
if (it.worldDiskToLoad != null && it.worldLoadParam != null) {
|
if (it.worldDiskToLoad != null && it.worldLoadParam != null) {
|
||||||
|
|||||||
Reference in New Issue
Block a user