// Tool helpers: reach, brushes, and plain digging. // ---------- Tools ---------- 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; } // Plain digging in a circle. The game itself uses the resonance drill (drill.js); the tests use // this to clear rock quickly. function toolDig(cx, cy, r) { const tier = BIT_TIERS[player.bitTier]; let dug = 0, tooHard = 0, far = 0; forBrush(cx, cy, r, (x, y, i) => { if (!inDrillReach(x, y)) { far++; return; } const m = mat[i]; if (bgm[i] && (m === EMPTY || PH[m] === PH_GAS || PH[m] === PH_LIQUID)) { if (cutTree(i, x, y, tier)) dug++; return; } if (PH[m] !== PH_SOLID) return; if (PARTMAT[m] || part[i] || mach[i]) return; const h = HARD[m]; if (h > tier.hard) { tooHard = m; return; } const p = digp[i] + tier.speed * 60 / (1 + h * h * 0.6); if (p >= 255) { const to = YLD[m]; const b = blockP[((y / BS) | 0) * BW + ((x / BS) | 0)]; setCell(i, to, temp[i], 0); discover(to, x, y, m, 'dig'); if (b === BP_WALL && !blockIntegrity(((y / BS) | 0) * BW + ((x / BS) | 0))) blockP[((y / BS) | 0) * BW + ((x / BS) | 0)] = 0; dug++; if ((dug & 3) === 0) emit({ t: 'debris', x, y, m }); } else digp[i] = p; }); stats.dug += dug; let status = ''; void 0; if (far && !dug && !tooHard) status = `Out of reach; your bit reaches ${drillReach()} grains.`; if (tooHard && !dug) { const need = BIT_TIERS.find(b => b.hard >= HARD[tooHard]); const nb = need ? need.name.toLowerCase() : 'better bit'; status = HARD[tooHard] > 6 ? `${MD[tooHard].name} cannot be drilled.` : `${MD[tooHard].name} is too hard; needs ${/^[aeiou]/.test(nb) ? 'an' : 'a'} ${nb}.`; } return { dug, status, tooHard }; }