From c0ef84412bf3b47beafc876e2ae15af5b3da5062 Mon Sep 17 00:00:00 2001 From: minjaesong Date: Wed, 18 Aug 2021 15:27:37 +0900 Subject: [PATCH] fixed a bug where only the first wire item of same 'accepts' property would be chosen for signals be propagated --- .../terrarum/gameworld/WorldSimulator.kt | 67 +++++++++---------- .../gameitems/WireGraphDebugger.kt | 25 +++---- 2 files changed, 42 insertions(+), 50 deletions(-) diff --git a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt index 8463dbfa2..df3747503 100644 --- a/src/net/torvald/terrarum/gameworld/WorldSimulator.kt +++ b/src/net/torvald/terrarum/gameworld/WorldSimulator.kt @@ -475,65 +475,60 @@ object WorldSimulator { // signal-emitting fixtures must set emitState of its own tiles via update() sources.forEach { (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 { val r = ArrayList() - 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)) } return r } - fixture.worldBlockPos?.let { sourceBlockPos -> + var point = startingPoint.copy() + val points = Queue() // a queue, enqueued at the end + val marked = HashSet() - val signal = (fixture as Electric).wireEmission[bbi] ?: Vector2(0.0, 0.0) - var point = WireGraphCursor(sourceBlockPos + fixture.blockBoxIndexToPoint2i(bbi)) + fun mark(point: WireGraphCursor) { + marked.add(point.longHash()) + // do some signal action + world.setWireEmitStateOf(point.x, point.y, wire, signal) + } - 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) + fun isMarked(point: WireGraphCursor) = marked.contains(point.longHash()) + fun enq(point: WireGraphCursor) = points.addFirst(point.copy()) + fun deq() = points.removeLast() - val points = Queue() // a queue, enqueued at the end - var marked = HashSet() + enq(point) + mark(point) - fun mark(point: WireGraphCursor) { - marked.add(point.longHash()) - // do some signal action - world.setWireEmitStateOf(point.x, point.y, wire, signal) - } - - fun isMarked(point: WireGraphCursor) = marked.contains(point.longHash()) - fun enq(point: WireGraphCursor) = points.addFirst(point.copy()) - fun deq() = points.removeLast() - - enq(point) - mark(point) - - while (points.notEmpty()) { - point = deq() - // TODO if we found a power receiver, do something to it - for (x in getAdjacent(world.getWireGraphOf(point.x, point.y, wire)!!, point)) { - if (!isMarked(x)) { - mark(x) - enq(x) - } - } + while (points.notEmpty()) { + point = deq() + // TODO if we found a power receiver, do something to it + world.getWireGraphOf(point.x, point.y, wire)?.let { connections -> + for (x in getAdjacent(connections, point)) { + if (!isMarked(x)) { + mark(x) + enq(x) } } } - - printdbg(this, "------------------------------------------") } } + private const val RIGHT = 1 private const val DOWN = 2 private const val LEFT = 4 diff --git a/src/net/torvald/terrarum/modulebasegame/gameitems/WireGraphDebugger.kt b/src/net/torvald/terrarum/modulebasegame/gameitems/WireGraphDebugger.kt index b89ba4279..6caa48486 100644 --- a/src/net/torvald/terrarum/modulebasegame/gameitems/WireGraphDebugger.kt +++ b/src/net/torvald/terrarum/modulebasegame/gameitems/WireGraphDebugger.kt @@ -45,23 +45,20 @@ class WireGraphDebugger(originalID: ItemID) : GameItem(originalID) { sb.clear() - Terrarum.ingame!!.world.getAllWiringGraph(mx, my)?.let { - it.forEach { (itemID, simCell) -> - if (sb.isNotEmpty()) sb.append('\n') + Terrarum.ingame!!.world.getAllWiringGraph(mx, my)?.forEach { (itemID, simCell) -> + if (sb.isNotEmpty()) sb.append('\n') + val connexionIcon = (simCell.connections + 0xE0A0).toChar() + val wireName = WireCodex[itemID].nameKey - val connexionIcon = (simCell.connections + 0xE0A0).toChar() - val wireName = WireCodex[itemID].nameKey + val emit = simCell.emitState + val recv = simCell.recvStates - val emit = simCell.emitState - val recv = simCell.recvStates - - sb.append("$connexionIcon $wireName") - sb.append("\nE: $emit") - recv.forEach { - val src = Terrarum.ingame!!.world.getWireEmitStateOf(it.src.x, it.src.y, itemID)!! - sb.append("\nR: $src $EMDASH d ${it.dist}") - } + sb.append("$connexionIcon $wireName") + sb.append("\nE: $emit") + recv.forEach { + val src = Terrarum.ingame!!.world.getWireEmitStateOf(it.src.x, it.src.y, itemID)!! + sb.append("\nR: $src $EMDASH d ${it.dist}") } }