// Redstone input detection for the transmitter. // // Mirrors the approach already proven in hemp-addon's sun lamp: try the script // API's getRedstonePower() first, and fall back to inspecting the six // neighbouring blocks when it is unavailable or reports nothing. export const REDSTONE_FACES = [ [1, 0, 0], [-1, 0, 0], [0, 1, 0], [0, -1, 0], [0, 0, 1], [0, 0, -1], ]; export function isPowerSource(b) { if (!b) return false; const t = b.typeId; if (t === "minecraft:redstone_block") return true; if (t === "minecraft:lit_redstone_torch" || t === "minecraft:redstone_torch") { try { return b.permutation.getState("toggle_bit") !== false; } catch (_) {} return t === "minecraft:lit_redstone_torch"; } if (t === "minecraft:powered_repeater") return true; if (t === "minecraft:powered_comparator") return true; if (t === "minecraft:lever") { try { return b.permutation.getState("open_bit") === true; } catch (_) { return false; } } if (t.endsWith("_button")) { try { return b.permutation.getState("button_pressed_bit") === true; } catch (_) { return false; } } if (t.endsWith("_pressure_plate")) { try { const r = b.permutation.getState("redstone_signal") ?? 0; return r > 0; } catch (_) { return false; } } if (t === "minecraft:redstone_wire") { try { const p = b.permutation.getState("redstone_signal") ?? 0; return p > 0; } catch (_) { return false; } } if (t === "minecraft:daylight_detector_inverted") return true; return false; } /** * Is this transmitter receiving power? * * `ignoreKeys` holds the position keys of receivers on the SAME channel. A * powered receiver is a real redstone block, so without this guard a * transmitter sitting next to its own channel's receiver would latch itself on * forever. We skip those positions, and when one is adjacent we also skip the * getRedstonePower() fast path, because that call cannot exclude a position. */ export function isTransmitterPowered(block, ignoreKeys) { const dim = block.dimension; const dimId = dim.id; const { x, y, z } = block.location; let adjacentSameChannelReceiver = false; if (ignoreKeys && ignoreKeys.size > 0) { for (const [dx, dy, dz] of REDSTONE_FACES) { if (ignoreKeys.has(`${dimId}|${x + dx}|${y + dy}|${z + dz}`)) { adjacentSameChannelReceiver = true; break; } } } if (!adjacentSameChannelReceiver) { try { const p = block.getRedstonePower(); if (typeof p === "number" && p > 0) return true; } catch (_) {} } for (const [dx, dy, dz] of REDSTONE_FACES) { const pos = { x: x + dx, y: y + dy, z: z + dz }; if (ignoreKeys && ignoreKeys.has(`${dimId}|${pos.x}|${pos.y}|${pos.z}`)) continue; let nb; try { nb = dim.getBlock(pos); } catch (_) { continue; } if (isPowerSource(nb)) return true; } return false; }