// Tool helpers: reach, brushes, and plain digging. // ---------- Tools ---------- // Building reaches about as far as the screen shows (t64): the view box the UI sets each frame // (setBuildRange), at least REACH from its centre and at most BUILD_MAX; anything beyond becomes // a blueprint ghost. With no view (tests, headless), a REACH box around the bot. const BUILD_MAX = 200; let buildBox = null; function setBuildRange(cx, cy, w, h) { const hw = Math.max(REACH, Math.min(BUILD_MAX, w / 2)), hh = Math.max(REACH, Math.min(BUILD_MAX, h / 2)); if (!buildBox) buildBox = { cx, cy, hw, hh }; else { buildBox.cx = cx; buildBox.cy = cy; buildBox.hw = hw; buildBox.hh = hh; } } function inBuildRange(x, y) { if (!buildBox) { const dx = x - (bot.x + bot.w / 2), dy = y - (bot.y + bot.h / 2); return Math.abs(dx) <= REACH && Math.abs(dy) <= REACH; } return Math.abs(x - buildBox.cx) <= buildBox.hw && Math.abs(y - buildBox.cy) <= buildBox.hh; } function inReach(x, y) { const dx = x - (bot.x + bot.w / 2), dy = y - (bot.y + bot.h / 2); return dx * dx + dy * dy <= REACH * REACH; } function forBrush(cx, cy, r, fn) { const r2 = (r + 0.5) * (r + 0.5); for (let dy = -r; dy <= r; dy++) for (let dx = -r; dx <= r; dx++) { if (dx * dx + dy * dy > r2) continue; const x = cx + dx, y = cy + dy; if (x < 0 || y < 0 || x >= W || y >= H) continue; if (!inReach(x, y)) continue; if (fn(x, y, y * W + x) === false) return; } } // Drill: breaks solids loose. Nothing goes into the bag. // how far the drill reaches: set by the bit, and stretched or shortened by the pulse width function drillReach(w = drillWidth) { return Math.round(BIT_TIERS[player.bitTier].reach * (PULSE_W[w] || PULSE_W[1]).reach); } function inDrillReach(x, y, w) { const dx = x - (bot.x + bot.w / 2), dy = y - (bot.y + bot.h / 2), R2 = drillReach(w); return dx * dx + dy * dy <= R2 * R2; }