poweredRun static method
A run of powered rails (or any line of blocks): offToOn pairs the
states. The run is the blocks joined on the four sides from the cell
(capped at 64); every one within reach steps along it of a powered one
is on. Register it for every state.
Implementation
static SignalReaction poweredRun(Map<int, int> offToOn, {int reach = 8}) {
final onToOff = {for (final e in offToOn.entries) e.value: e.key};
bool inRun(int id) => offToOn.containsKey(id) || onToOff.containsKey(id);
const four = [IVec3(1, 0, 0), IVec3(-1, 0, 0), IVec3(0, 0, 1), IVec3(0, 0, -1)];
return (net, c, id) {
final w = net.world;
int at(IVec3 p) => w.getBlockXYZ(p.x, p.y, p.z);
final run = <IVec3>[c];
final seen = <IVec3>{c};
var head = 0;
while (head < run.length && run.length < 64) {
final cur = run[head++];
for (final d in four) {
final n = cur + d;
if (seen.contains(n)) continue;
final nid = at(n);
if (nid != VoxelBlockTable.air && inRun(nid)) {
seen.add(n);
run.add(n);
}
}
}
final dist = <IVec3, int>{};
final queue = <IVec3>[];
for (final cell in run) {
if (net.isPowered(cell)) {
dist[cell] = 0;
queue.add(cell);
}
}
head = 0;
while (head < queue.length) {
final cur = queue[head++];
for (final d in four) {
final n = cur + d;
if (seen.contains(n) && !dist.containsKey(n)) {
dist[n] = dist[cur]! + 1;
queue.add(n);
}
}
}
for (final cell in run) {
final cur = at(cell);
final off = onToOff[cur] ?? cur;
final want = (dist[cell] ?? 99) <= reach ? offToOn[off]! : off;
if (cur != want) w.setBlock(cell, want);
}
};
}