fixed a bug where only the first wire item of same 'accepts' property would be chosen for signals be propagated

This commit is contained in:
minjaesong
2021-08-18 15:27:37 +09:00
parent f764448d06
commit c0ef84412b
2 changed files with 42 additions and 50 deletions

View File

@@ -475,34 +475,31 @@ object WorldSimulator {
// signal-emitting fixtures must set emitState of its own tiles via update() // signal-emitting fixtures must set emitState of its own tiles via update()
sources.forEach { sources.forEach {
(it as Electric).wireEmitterTypes.forEach { wireType, bbi -> (it as Electric).wireEmitterTypes.forEach { wireType, bbi ->
traverseWireGraph(world, it, wireType, bbi)
val startingPoint = WireGraphCursor(it.worldBlockPos!! + it.blockBoxIndexToPoint2i(bbi))
val signal = (it as Electric).wireEmission[bbi] ?: Vector2(0.0, 0.0)
world.getAllWiringGraph(startingPoint.x, startingPoint.y)?.keys?.filter { WireCodex[it].accepts == wireType }?.forEach { wire ->
traverseWireGraph(world, wire, startingPoint, signal)
}
} }
} }
} }
} }
private fun traverseWireGraph(world: GameWorld, fixture: FixtureBase, wireType: String, bbi: BlockBoxIndex) { private fun traverseWireGraph(world: GameWorld, wire: ItemID, startingPoint: WireGraphCursor, signal: Vector2) {
fun getAdjacent(cnx: Int, point: WireGraphCursor): List<WireGraphCursor> { fun getAdjacent(cnx: Int, point: WireGraphCursor): List<WireGraphCursor> {
val r = ArrayList<WireGraphCursor>() val r = ArrayList<WireGraphCursor>()
for (dir in intArrayOf(RIGHT,DOWN,LEFT,UP)) { for (dir in intArrayOf(RIGHT, DOWN, LEFT, UP)) {
if (cnx and dir != 0) r.add(point.copy().moveOneCell(dir)) if (cnx and dir != 0) r.add(point.copy().moveOneCell(dir))
} }
return r return r
} }
fixture.worldBlockPos?.let { sourceBlockPos -> var point = startingPoint.copy()
val signal = (fixture as Electric).wireEmission[bbi] ?: Vector2(0.0, 0.0)
var point = WireGraphCursor(sourceBlockPos + fixture.blockBoxIndexToPoint2i(bbi))
world.getAllWiresFrom(point.x, point.y)?.filter { WireCodex[it].accepts == wireType }?.forEach { wire ->
// this makes sure that only the emitters with wires installed will get traversed
world.getWireGraphOf(point.x, point.y, wire)?.let { _ ->
printdbg(this, wire)
val points = Queue<WireGraphCursor>() // a queue, enqueued at the end val points = Queue<WireGraphCursor>() // a queue, enqueued at the end
var marked = HashSet<Long>() val marked = HashSet<Long>()
fun mark(point: WireGraphCursor) { fun mark(point: WireGraphCursor) {
marked.add(point.longHash()) marked.add(point.longHash())
@@ -520,7 +517,8 @@ object WorldSimulator {
while (points.notEmpty()) { while (points.notEmpty()) {
point = deq() point = deq()
// TODO if we found a power receiver, do something to it // TODO if we found a power receiver, do something to it
for (x in getAdjacent(world.getWireGraphOf(point.x, point.y, wire)!!, point)) { world.getWireGraphOf(point.x, point.y, wire)?.let { connections ->
for (x in getAdjacent(connections, point)) {
if (!isMarked(x)) { if (!isMarked(x)) {
mark(x) mark(x)
enq(x) enq(x)
@@ -530,9 +528,6 @@ object WorldSimulator {
} }
} }
printdbg(this, "------------------------------------------")
}
}
private const val RIGHT = 1 private const val RIGHT = 1
private const val DOWN = 2 private const val DOWN = 2

View File

@@ -45,11 +45,9 @@ class WireGraphDebugger(originalID: ItemID) : GameItem(originalID) {
sb.clear() sb.clear()
Terrarum.ingame!!.world.getAllWiringGraph(mx, my)?.let { Terrarum.ingame!!.world.getAllWiringGraph(mx, my)?.forEach { (itemID, simCell) ->
it.forEach { (itemID, simCell) ->
if (sb.isNotEmpty()) sb.append('\n') if (sb.isNotEmpty()) sb.append('\n')
val connexionIcon = (simCell.connections + 0xE0A0).toChar() val connexionIcon = (simCell.connections + 0xE0A0).toChar()
val wireName = WireCodex[itemID].nameKey val wireName = WireCodex[itemID].nameKey
@@ -63,7 +61,6 @@ class WireGraphDebugger(originalID: ItemID) : GameItem(originalID) {
sb.append("\nR: $src $EMDASH d ${it.dist}") sb.append("\nR: $src $EMDASH d ${it.dist}")
} }
} }
}
if (sb.isNotEmpty()) { if (sb.isNotEmpty()) {
(Terrarum.ingame!! as TerrarumIngame).setTooltipMessage(sb.toString()) (Terrarum.ingame!! as TerrarumIngame).setTooltipMessage(sb.toString())