poweredRun static method

SignalReaction poweredRun(
  1. Map<int, int> offToOn, {
  2. int reach = 8,
})

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