quarry_multi.lua
533 lines · 17.6 KB
quarry_multi.lua
Copy & run
wget https://perlytiara.github.io/turtles.tips/raw/programs/perlytiara/quarry/quarry_multi.lua
| 1 | -- quarry_multi.lua |
| 2 | -- Master script to launch multiple turtles with divided params for quarry |
| 3 | |
| 4 | -- Auto-detect a modem and open rednet |
| 5 | local function findModem() |
| 6 | for _, p in pairs(rs.getSides()) do |
| 7 | if peripheral.isPresent(p) and peripheral.getType(p) == "modem" then |
| 8 | return p |
| 9 | end |
| 10 | end |
| 11 | error("No modem attached to this computer.") |
| 12 | end |
| 13 | |
| 14 | local modemSide = findModem() |
| 15 | rednet.open(modemSide) |
| 16 | |
| 17 | local wrapped = peripheral.wrap(modemSide) |
| 18 | if wrapped and wrapped.isWireless and not wrapped.isWireless() then |
| 19 | print("Note: Wired modem detected. Ensure turtles are cabled to the same network.") |
| 20 | end |
| 21 | |
| 22 | -- Corner definitions (normalized x=0 left, 1 right; z=0 bottom, 1 top) |
| 23 | -- Turtles face EACH OTHER across the quarry for proper coordination |
| 24 | local corner_info = { |
| 25 | [1] = {name = "bottom-left (SW)", x = 0, z = 0, default_facing = 1}, -- +Z (facing north toward turtle 4) |
| 26 | [2] = {name = "bottom-right (SE)", x = 1, z = 0, default_facing = 1}, -- +Z (facing north toward turtle 3) |
| 27 | [3] = {name = "top-right (NE)", x = 1, z = 1, default_facing = -1}, -- -Z (facing south toward turtle 2) |
| 28 | [4] = {name = "top-left (NW)", x = 0, z = 1, default_facing = -1} -- -Z (facing south toward turtle 1) |
| 29 | } |
| 30 | |
| 31 | -- Function to divide dimension into n parts |
| 32 | local function divide_dim(dim, n) |
| 33 | local parts = {} |
| 34 | local base = math.floor(dim / n) |
| 35 | local rem = dim % n |
| 36 | for i = 1, n do |
| 37 | parts[i] = base + (i <= rem and 1 or 0) |
| 38 | end |
| 39 | return parts |
| 40 | end |
| 41 | |
| 42 | -- Wizard - Get dimensions |
| 43 | print("=== Quarry Dimensions ===") |
| 44 | local total_length |
| 45 | while true do |
| 46 | print("Enter total length (sizeZ, positive):") |
| 47 | total_length = tonumber(read()) |
| 48 | if total_length and total_length > 0 then |
| 49 | break |
| 50 | else |
| 51 | print("Invalid input. Please enter a positive number.") |
| 52 | end |
| 53 | end |
| 54 | |
| 55 | local total_width |
| 56 | while true do |
| 57 | print("Enter total width (sizeX, positive):") |
| 58 | total_width = tonumber(read()) |
| 59 | if total_width and total_width > 0 then |
| 60 | break |
| 61 | else |
| 62 | print("Invalid input. Please enter a positive number.") |
| 63 | end |
| 64 | end |
| 65 | |
| 66 | local total_depth |
| 67 | while true do |
| 68 | print("Enter total depth (sizeY, positive, default 256):") |
| 69 | local input = read() |
| 70 | if input == "" then |
| 71 | total_depth = 256 |
| 72 | break |
| 73 | else |
| 74 | total_depth = tonumber(input) |
| 75 | if total_depth and total_depth > 0 then |
| 76 | break |
| 77 | else |
| 78 | print("Invalid input. Please enter a positive number or press Enter for default (256).") |
| 79 | end |
| 80 | end |
| 81 | end |
| 82 | |
| 83 | -- Get number of turtles |
| 84 | local num |
| 85 | while true do |
| 86 | print("Enter number of turtles (1-4):") |
| 87 | num = tonumber(read()) |
| 88 | if num and num >= 1 and num <= 4 then |
| 89 | break |
| 90 | else |
| 91 | print("Invalid input. Please enter a number between 1 and 4.") |
| 92 | end |
| 93 | end |
| 94 | |
| 95 | -- Setup each turtle one by one |
| 96 | local turtles = {} |
| 97 | for i = 1, num do |
| 98 | print("\n=== Setting up Turtle " .. i .. " ===") |
| 99 | |
| 100 | -- Get corner |
| 101 | local corner |
| 102 | while true do |
| 103 | print("Turtle placement diagram (viewed from above):") |
| 104 | print(" 4(NW) <-----> 3(NE)") |
| 105 | print(" ^ ^") |
| 106 | print(" | QUARRY |") |
| 107 | print(" | AREA |") |
| 108 | print(" v v") |
| 109 | print(" 1(SW) <-----> 2(SE)") |
| 110 | print("") |
| 111 | print("Turtles face EACH OTHER across quarry:") |
| 112 | print(" 1 = bottom-left (SW) - face +Z (north toward turtle 4)") |
| 113 | print(" 2 = bottom-right (SE) - face +Z (north toward turtle 3)") |
| 114 | print(" 3 = top-right (NE) - face -Z (south toward turtle 2)") |
| 115 | print(" 4 = top-left (NW) - face -Z (south toward turtle 1)") |
| 116 | print("Enter corner number for turtle " .. i .. ":") |
| 117 | corner = tonumber(read()) |
| 118 | if corner and corner_info[corner] then |
| 119 | break |
| 120 | else |
| 121 | print("Invalid corner. Please enter 1, 2, 3, or 4.") |
| 122 | end |
| 123 | end |
| 124 | |
| 125 | -- Get turtle ID |
| 126 | local id |
| 127 | while true do |
| 128 | print("Enter turtle ID for " .. corner_info[corner].name .. ":") |
| 129 | print("(Use 'id' command on the turtle to get its ID)") |
| 130 | id = tonumber(read()) |
| 131 | if id and id > 0 then |
| 132 | break |
| 133 | else |
| 134 | print("Invalid ID. Please enter a positive number.") |
| 135 | end |
| 136 | end |
| 137 | |
| 138 | -- Get facing direction |
| 139 | local facing |
| 140 | while true do |
| 141 | print("Enter facing direction for " .. corner_info[corner].name .. ":") |
| 142 | print(" 1 = +Z (forward/north)") |
| 143 | print(" 2 = -Z (backward/south)") |
| 144 | print(" (default: " .. corner_info[corner].default_facing .. ")") |
| 145 | local input = read() |
| 146 | if input == "" then |
| 147 | facing = corner_info[corner].default_facing |
| 148 | break |
| 149 | else |
| 150 | local facing_input = tonumber(input) |
| 151 | if facing_input == 1 then |
| 152 | facing = 1 |
| 153 | break |
| 154 | elseif facing_input == 2 then |
| 155 | facing = -1 |
| 156 | break |
| 157 | else |
| 158 | print("Invalid facing. Please enter 1 or 2, or press Enter for default.") |
| 159 | end |
| 160 | end |
| 161 | end |
| 162 | |
| 163 | turtles[i] = {corner = corner, id = id, facing = facing} |
| 164 | print("Turtle " .. i .. " configured: " .. corner_info[corner].name .. " (ID: " .. id .. ") facing " .. (facing == 1 and "+Z" or "-Z")) |
| 165 | end |
| 166 | |
| 167 | -- Get options |
| 168 | print("\n=== Quarry Options ===") |
| 169 | local start_below |
| 170 | while true do |
| 171 | print("Preserve top layer (start digging below)? (y/n, default n):") |
| 172 | local input = read():lower() |
| 173 | if input == "" or input == "n" or input == "no" then |
| 174 | start_below = 0 |
| 175 | break |
| 176 | elseif input == "y" or input == "yes" then |
| 177 | start_below = 1 |
| 178 | break |
| 179 | else |
| 180 | print("Invalid input. Please enter 'y' for yes, 'n' for no, or press Enter for default (no).") |
| 181 | end |
| 182 | end |
| 183 | |
| 184 | local debug |
| 185 | while true do |
| 186 | print("Debug mode? (y/n, default n):") |
| 187 | local input = read():lower() |
| 188 | if input == "" or input == "n" or input == "no" then |
| 189 | debug = 0 |
| 190 | break |
| 191 | elseif input == "y" or input == "yes" then |
| 192 | debug = 1 |
| 193 | break |
| 194 | else |
| 195 | print("Invalid input. Please enter 'y' for yes, 'n' for no, or press Enter for default (no).") |
| 196 | end |
| 197 | end |
| 198 | |
| 199 | local auto_start |
| 200 | while true do |
| 201 | print("Auto-start turtles (skip fuel prompt)? (y/n, default y):") |
| 202 | local input = read():lower() |
| 203 | if input == "" or input == "y" or input == "yes" then |
| 204 | auto_start = 1 |
| 205 | break |
| 206 | elseif input == "n" or input == "no" then |
| 207 | auto_start = 0 |
| 208 | break |
| 209 | else |
| 210 | print("Invalid input. Please enter 'y' for yes, 'n' for no, or press Enter for default (yes).") |
| 211 | end |
| 212 | end |
| 213 | |
| 214 | local is_horizontal_pref = true |
| 215 | if num == 3 then |
| 216 | while true do |
| 217 | print("For 3 turtles, preferred split direction:") |
| 218 | print(" 1 = horizontal/width") |
| 219 | print(" 2 = vertical/length") |
| 220 | print(" (default: horizontal)") |
| 221 | local input = read() |
| 222 | if input == "" or input == "1" then |
| 223 | is_horizontal_pref = true |
| 224 | break |
| 225 | elseif input == "2" then |
| 226 | is_horizontal_pref = false |
| 227 | break |
| 228 | else |
| 229 | print("Invalid input. Please enter 1, 2, or press Enter for default (horizontal).") |
| 230 | end |
| 231 | end |
| 232 | end |
| 233 | |
| 234 | -- Compute counts |
| 235 | local count_bottom = 0 |
| 236 | local count_top = 0 |
| 237 | local count_left = 0 |
| 238 | local count_right = 0 |
| 239 | local bottom_turtles = {} |
| 240 | local top_turtles = {} |
| 241 | local left_turtles = {} |
| 242 | local right_turtles = {} |
| 243 | for _, t in ipairs(turtles) do |
| 244 | local info = corner_info[t.corner] |
| 245 | if info.z == 0 then |
| 246 | count_bottom = count_bottom + 1 |
| 247 | table.insert(bottom_turtles, t) |
| 248 | else |
| 249 | count_top = count_top + 1 |
| 250 | table.insert(top_turtles, t) |
| 251 | end |
| 252 | if info.x == 0 then |
| 253 | count_left = count_left + 1 |
| 254 | table.insert(left_turtles, t) |
| 255 | else |
| 256 | count_right = count_right + 1 |
| 257 | table.insert(right_turtles, t) |
| 258 | end |
| 259 | end |
| 260 | |
| 261 | -- Function to sort turtles by position (x or z) |
| 262 | local function sort_by_pos(t_list, key) |
| 263 | table.sort(t_list, function(a, b) |
| 264 | return corner_info[a.corner][key] < corner_info[b.corner][key] |
| 265 | end) |
| 266 | end |
| 267 | |
| 268 | -- Compute parameters for each turtle |
| 269 | local params_list = {} |
| 270 | local roles = {} |
| 271 | |
| 272 | for i, t in ipairs(turtles) do |
| 273 | local info = corner_info[t.corner] |
| 274 | local is_left = (info.x == 0) |
| 275 | local desired_x_dir = is_left and 1 or -1 |
| 276 | local facing_sign = t.facing |
| 277 | local sizeX_sign = desired_x_dir * facing_sign |
| 278 | local sizeZ_sign = facing_sign |
| 279 | |
| 280 | -- Placeholder, will compute abs later |
| 281 | params_list[i] = "" |
| 282 | roles[i] = info.name |
| 283 | end |
| 284 | |
| 285 | -- Now compute based on num |
| 286 | if num == 1 then |
| 287 | local t = turtles[1] |
| 288 | local info = corner_info[t.corner] |
| 289 | local is_left = (info.x == 0) |
| 290 | local desired_x_dir = is_left and 1 or -1 |
| 291 | local facing_sign = t.facing |
| 292 | local sizeX_sign = desired_x_dir * facing_sign |
| 293 | local sizeZ_sign = facing_sign |
| 294 | |
| 295 | local abs_sizeZ = total_length |
| 296 | local abs_sizeX = total_width |
| 297 | local sizeZ = t.facing * abs_sizeZ |
| 298 | local sizeX = (corner_info[t.corner].x == 0) and abs_sizeX or (-abs_sizeX) |
| 299 | params_list[1] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 300 | |
| 301 | elseif num == 2 then |
| 302 | -- Determine type |
| 303 | local all_bottom = count_bottom == 2 |
| 304 | local all_top = count_top == 2 |
| 305 | local all_left = count_left == 2 |
| 306 | local all_right = count_right == 2 |
| 307 | |
| 308 | if all_bottom or all_top then |
| 309 | -- Horizontal aligned, split width, full length |
| 310 | local group = all_bottom and bottom_turtles or top_turtles |
| 311 | sort_by_pos(group, "x") |
| 312 | local parts = divide_dim(total_width, 2) |
| 313 | local abs_sizeZ = total_length |
| 314 | for j = 1, 2 do |
| 315 | local idx = 0 -- find index in turtles |
| 316 | for k, tt in ipairs(turtles) do |
| 317 | if tt.corner == group[j].corner then idx = k break end |
| 318 | end |
| 319 | local abs_sizeX = parts[j] |
| 320 | local t = turtles[idx] |
| 321 | local info = corner_info[t.corner] |
| 322 | local is_left = (info.x == 0) |
| 323 | local desired_x_dir = is_left and 1 or -1 |
| 324 | local facing_sign = t.facing |
| 325 | local sizeX_sign = desired_x_dir * facing_sign |
| 326 | local sizeZ_sign = facing_sign |
| 327 | local sizeZ = t.facing * abs_sizeZ |
| 328 | local sizeX = (corner_info[t.corner].x == 0) and abs_sizeX or (-abs_sizeX) |
| 329 | params_list[idx] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 330 | end |
| 331 | elseif all_left or all_right then |
| 332 | -- Vertical aligned, split length, full width |
| 333 | local group = all_left and left_turtles or right_turtles |
| 334 | sort_by_pos(group, "z") |
| 335 | local parts = divide_dim(total_length, 2) |
| 336 | local abs_sizeX = total_width |
| 337 | for j = 1, 2 do |
| 338 | local idx = 0 |
| 339 | for k, tt in ipairs(turtles) do |
| 340 | if tt.corner == group[j].corner then idx = k break end |
| 341 | end |
| 342 | local abs_sizeZ = parts[j] |
| 343 | local t = turtles[idx] |
| 344 | local info = corner_info[t.corner] |
| 345 | local is_left = (info.x == 0) |
| 346 | local desired_x_dir = is_left and 1 or -1 |
| 347 | local facing_sign = t.facing |
| 348 | local sizeX_sign = desired_x_dir * facing_sign |
| 349 | local sizeZ_sign = facing_sign |
| 350 | local sizeZ = t.facing * abs_sizeZ |
| 351 | local sizeX = (corner_info[t.corner].x == 0) and abs_sizeX or (-abs_sizeX) |
| 352 | params_list[idx] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 353 | end |
| 354 | else |
| 355 | -- Diagonal |
| 356 | local h_parts_l = divide_dim(total_length, 2) |
| 357 | local h_parts_w = divide_dim(total_width, 2) |
| 358 | for j = 1, 2 do |
| 359 | local t = turtles[j] |
| 360 | local c = t.corner |
| 361 | local info = corner_info[c] |
| 362 | local is_left = (info.x == 0) |
| 363 | local desired_x_dir = is_left and 1 or -1 |
| 364 | local facing_sign = t.facing |
| 365 | local sizeX_sign = desired_x_dir * facing_sign |
| 366 | local sizeZ_sign = facing_sign |
| 367 | local abs_sizeZ = (corner_info[c].z == 0) and h_parts_l[1] or h_parts_l[2] |
| 368 | local abs_sizeX = (corner_info[c].x == 0) and h_parts_w[1] or h_parts_w[2] |
| 369 | -- Use facing direction for Z, position for X |
| 370 | local sizeZ = t.facing * abs_sizeZ -- facing determines Z direction |
| 371 | local sizeX = (corner_info[c].x == 0) and abs_sizeX or (-abs_sizeX) -- position determines X direction |
| 372 | params_list[j] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 373 | end |
| 374 | end |
| 375 | |
| 376 | elseif num == 3 then |
| 377 | -- Balanced split |
| 378 | local multiple_side, single_side, is_horizontal |
| 379 | if math.max(count_bottom, count_top) == 2 then |
| 380 | is_horizontal = true |
| 381 | elseif math.max(count_left, count_right) == 2 then |
| 382 | is_horizontal = false |
| 383 | else |
| 384 | is_horizontal = is_horizontal_pref |
| 385 | end |
| 386 | |
| 387 | if is_horizontal then |
| 388 | -- Split horizontal, balanced |
| 389 | local multiple_group, single_group |
| 390 | if count_bottom == 2 then |
| 391 | multiple_group = bottom_turtles |
| 392 | single_group = top_turtles |
| 393 | multiple_is_bottom = true |
| 394 | else |
| 395 | multiple_group = top_turtles |
| 396 | single_group = bottom_turtles |
| 397 | multiple_is_bottom = false |
| 398 | end |
| 399 | sort_by_pos(multiple_group, "x") |
| 400 | |
| 401 | local frac = 2 / 3 |
| 402 | local z_multiple = math.floor(total_length * frac + 0.5) |
| 403 | local z_single = total_length - z_multiple |
| 404 | local w_multiple1 = math.floor(total_width / 2) |
| 405 | local w_multiple2 = total_width - w_multiple1 |
| 406 | local w_single = total_width |
| 407 | |
| 408 | -- Multiple side |
| 409 | for j = 1, 2 do |
| 410 | local tt = multiple_group[j] |
| 411 | local idx = 0 |
| 412 | for k, u in ipairs(turtles) do |
| 413 | if u.corner == tt.corner then idx = k break end |
| 414 | end |
| 415 | local abs_sizeZ = z_multiple |
| 416 | local abs_sizeX = (j == 1) and w_multiple1 or w_multiple2 |
| 417 | local sizeZ = turtles[idx].facing * abs_sizeZ |
| 418 | local sizeX = ( (corner_info[tt.corner].x == 0 and 1 or -1) * turtles[idx].facing ) * abs_sizeX |
| 419 | params_list[idx] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 420 | end |
| 421 | |
| 422 | -- Single side |
| 423 | local tt = single_group[1] |
| 424 | local idx = 0 |
| 425 | for k, u in ipairs(turtles) do |
| 426 | if u.corner == tt.corner then idx = k break end |
| 427 | end |
| 428 | local abs_sizeZ = z_single |
| 429 | local abs_sizeX = w_single |
| 430 | local sizeZ = turtles[idx].facing * abs_sizeZ |
| 431 | local sizeX = ( (corner_info[tt.corner].x == 0 and 1 or -1) * turtles[idx].facing ) * abs_sizeX |
| 432 | params_list[idx] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 433 | else |
| 434 | -- Vertical balanced |
| 435 | local multiple_group, single_group |
| 436 | if count_left == 2 then |
| 437 | multiple_group = left_turtles |
| 438 | single_group = right_turtles |
| 439 | multiple_is_left = true |
| 440 | else |
| 441 | multiple_group = right_turtles |
| 442 | single_group = left_turtles |
| 443 | multiple_is_left = false |
| 444 | end |
| 445 | sort_by_pos(multiple_group, "z") |
| 446 | |
| 447 | local frac = 2 / 3 |
| 448 | local w_multiple = math.floor(total_width * frac + 0.5) |
| 449 | local w_single = total_width - w_multiple |
| 450 | local l_multiple1 = math.floor(total_length / 2) |
| 451 | local l_multiple2 = total_length - l_multiple1 |
| 452 | |
| 453 | -- Multiple side |
| 454 | for j = 1, 2 do |
| 455 | local tt = multiple_group[j] |
| 456 | local idx = 0 |
| 457 | for k, u in ipairs(turtles) do |
| 458 | if u.corner == tt.corner then idx = k break end |
| 459 | end |
| 460 | local abs_sizeX = w_multiple |
| 461 | local abs_sizeZ = (j == 1) and l_multiple1 or l_multiple2 |
| 462 | local sizeZ = turtles[idx].facing * abs_sizeZ |
| 463 | local sizeX = ( ( (multiple_is_left and 1 or -1) ) * turtles[idx].facing ) * abs_sizeX |
| 464 | params_list[idx] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 465 | end |
| 466 | |
| 467 | -- Single side |
| 468 | local tt = single_group[1] |
| 469 | local idx = 0 |
| 470 | for k, u in ipairs(turtles) do |
| 471 | if u.corner == tt.corner then idx = k break end |
| 472 | end |
| 473 | local abs_sizeX = w_single |
| 474 | local abs_sizeZ = total_length |
| 475 | local sizeZ = turtles[idx].facing * abs_sizeZ |
| 476 | local sizeX = ( ( (corner_info[tt.corner].x == 0 and 1 or -1) ) * turtles[idx].facing ) * abs_sizeX |
| 477 | params_list[idx] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 478 | end |
| 479 | |
| 480 | elseif num == 4 then |
| 481 | -- Split both dimensions |
| 482 | local h_parts_l = divide_dim(total_length, 2) |
| 483 | local h_parts_w = divide_dim(total_width, 2) |
| 484 | |
| 485 | for _, t in ipairs(turtles) do |
| 486 | local c = t.corner |
| 487 | local idx = 0 |
| 488 | for k, u in ipairs(turtles) do |
| 489 | if u.corner == c then idx = k break end |
| 490 | end |
| 491 | local abs_sizeZ = (corner_info[c].z == 0) and h_parts_l[1] or h_parts_l[2] |
| 492 | local abs_sizeX = (corner_info[c].x == 0) and h_parts_w[1] or h_parts_w[2] |
| 493 | -- Calculate based on position and facing direction |
| 494 | -- All turtles dig toward quarry center using their facing direction |
| 495 | local sizeZ = t.facing * abs_sizeZ -- facing determines Z direction |
| 496 | local sizeX = (corner_info[c].x == 0) and abs_sizeX or (-abs_sizeX) -- position determines X direction |
| 497 | params_list[idx] = tostring(sizeZ) .. " " .. tostring(sizeX) .. " " .. tostring(total_depth) .. " " .. debug .. " " .. start_below .. " " .. auto_start |
| 498 | end |
| 499 | end |
| 500 | |
| 501 | -- Summary |
| 502 | print("\n=== Quarry Configuration Summary ===") |
| 503 | print("Dimensions: " .. total_length .. " x " .. total_width .. " x " .. total_depth) |
| 504 | print("Turtles: " .. num) |
| 505 | for i = 1, num do |
| 506 | local t = turtles[i] |
| 507 | print(" Turtle " .. i .. ": " .. corner_info[t.corner].name .. " (ID: " .. t.id .. ") facing " .. (t.facing == 1 and "+Z" or "-Z")) |
| 508 | end |
| 509 | print("Start below: " .. (start_below == 1 and "Yes" or "No")) |
| 510 | print("Debug mode: " .. (debug == 1 and "Yes" or "No")) |
| 511 | print("Auto-start: " .. (auto_start == 1 and "Yes" or "No")) |
| 512 | |
| 513 | print("\nPress Enter to send commands to turtles, or Ctrl+T to cancel...") |
| 514 | read() |
| 515 | |
| 516 | -- Send to each |
| 517 | print("\n=== Sending Commands ===") |
| 518 | for i = 1, num do |
| 519 | local id = turtles[i].id |
| 520 | local param = params_list[i] |
| 521 | local role = corner_info[turtles[i].corner].name .. " facing " .. (turtles[i].facing == 1 and "+Z" or "-Z") |
| 522 | local payload = { command = "RUN", program = "quarry", args = param, masterId = os.getComputerID(), role = role } |
| 523 | |
| 524 | print("Sending to turtle ID " .. id .. " (" .. role .. "): quarry " .. param) |
| 525 | rednet.send(id, payload, "quarry-run") |
| 526 | rednet.send(id, params_list[i], "quarry-run") -- fallback with plain string |
| 527 | end |
| 528 | |
| 529 | print("\nCommands sent! Turtles should start digging now.") |
| 530 | print("Make sure each turtle is running 'quarry_listener' and has fuel in slot 1.") |
| 531 | |
| 532 | -- Note: For num=3, areas are approximately equal, but may differ slightly due to integer dimensions. Adjust total sizes for better balance if needed. |
| 533 |