clientdig.lua
502 lines · 11.9 KB
CLIENT DIG--
Copy & run
wget https://perlytiara.github.io/turtles.tips/raw/programs/perlytiara/Maengorn/clientdig.lua
| 1 | --CLIENT DIG-- |
| 2 | |
| 3 | local SLOT_COUNT = 16 |
| 4 | |
| 5 | local CLIENT_PORT = 0 |
| 6 | local SERVER_PORT = 420 |
| 7 | |
| 8 | function findWirelessModem() |
| 9 | print("Searching for wireless modem...") |
| 10 | local peripherals = peripheral.getNames() |
| 11 | print("Found " .. #peripherals .. " peripherals") |
| 12 | |
| 13 | for _, side in ipairs(peripherals) do |
| 14 | local pType = peripheral.getType(side) |
| 15 | print(" " .. side .. ": " .. pType) |
| 16 | |
| 17 | if pType == "modem" then |
| 18 | local isWireless = peripheral.call(side, "isWireless") |
| 19 | print(" Wireless: " .. tostring(isWireless)) |
| 20 | if isWireless then |
| 21 | print("Found wireless modem on: " .. side) |
| 22 | return side |
| 23 | end |
| 24 | end |
| 25 | end |
| 26 | return nil |
| 27 | end |
| 28 | |
| 29 | local modemSide = findWirelessModem() |
| 30 | if not modemSide then |
| 31 | print("ERROR: No wireless modem found!") |
| 32 | print("This turtle needs a wireless modem for GPS and communication!") |
| 33 | print("Available peripherals:") |
| 34 | for _, side in ipairs(peripheral.getNames()) do |
| 35 | print(" " .. side .. ": " .. peripheral.getType(side)) |
| 36 | end |
| 37 | error("No wireless modem found!") |
| 38 | end |
| 39 | local modem = peripheral.wrap(modemSide) |
| 40 | modem.open(CLIENT_PORT) |
| 41 | print("Modem ready on " .. modemSide) |
| 42 | |
| 43 | function waitForGPS(timeout) |
| 44 | timeout = timeout or 10 |
| 45 | print("Waiting for GPS signal...") |
| 46 | local x, y, z = gps.locate(timeout, false) |
| 47 | |
| 48 | local retryCount = 0 |
| 49 | while not x do |
| 50 | retryCount = retryCount + 1 |
| 51 | print(string.format("GPS attempt %d: No signal!", retryCount)) |
| 52 | |
| 53 | if retryCount % 3 == 0 then |
| 54 | print("GPS troubleshooting:") |
| 55 | print(" - Need at least 4 GPS satellites") |
| 56 | print(" - Satellites must be spread out") |
| 57 | print(" - Check if satellites are running") |
| 58 | print(" - Ambiguous position = bad satellite placement") |
| 59 | else |
| 60 | print("Retrying in 3 seconds...") |
| 61 | end |
| 62 | |
| 63 | os.sleep(3) |
| 64 | x, y, z = gps.locate(timeout, false) |
| 65 | end |
| 66 | |
| 67 | print(string.format("GPS acquired: %d, %d, %d", x, y, z)) |
| 68 | return x, y, z |
| 69 | end |
| 70 | |
| 71 | function split (inputstr, sep) |
| 72 | if sep == nil then |
| 73 | sep = "%s" |
| 74 | end |
| 75 | local t={} |
| 76 | for str in string.gmatch(inputstr, "([^"..sep.."]+)") do |
| 77 | table.insert(t, str) |
| 78 | end |
| 79 | return t |
| 80 | end |
| 81 | |
| 82 | function parseParams(data) |
| 83 | coords = {} |
| 84 | params = split(data, " ") |
| 85 | |
| 86 | coords[1] = vector.new(params[1], params[2], params[3]) |
| 87 | coords[2] = vector.new(params[4], params[5], params[6]) |
| 88 | coords[3] = vector.new(params[7], params[8], params[9]) |
| 89 | |
| 90 | return (coords) |
| 91 | end |
| 92 | |
| 93 | |
| 94 | function checkFuel() |
| 95 | turtle.select(1) |
| 96 | |
| 97 | if(turtle.getFuelLevel() < 50) then |
| 98 | print("Attempting Refuel...") |
| 99 | for slot = 1, SLOT_COUNT, 1 do |
| 100 | turtle.select(slot) |
| 101 | if(turtle.refuel()) then |
| 102 | return true |
| 103 | end |
| 104 | end |
| 105 | |
| 106 | return false |
| 107 | else |
| 108 | return true |
| 109 | end |
| 110 | end |
| 111 | |
| 112 | |
| 113 | function getOrientation() |
| 114 | local x1, y1, z1 = waitForGPS() |
| 115 | loc1 = vector.new(x1, y1, z1) |
| 116 | if not turtle.forward() then |
| 117 | for j=1,6 do |
| 118 | if not turtle.forward() then |
| 119 | turtle.dig() |
| 120 | else |
| 121 | break |
| 122 | end |
| 123 | end |
| 124 | end |
| 125 | local x2, y2, z2 = waitForGPS() |
| 126 | loc2 = vector.new(x2, y2, z2) |
| 127 | heading = loc2 - loc1 |
| 128 | turtle.down() |
| 129 | turtle.down() |
| 130 | return ((heading.x + math.abs(heading.x) * 2) + (heading.z + math.abs(heading.z) * 3)) |
| 131 | end |
| 132 | |
| 133 | |
| 134 | function turnToFaceHeading(heading, destinationHeading) |
| 135 | if(heading > destinationHeading) then |
| 136 | for t = 1, math.abs(destinationHeading - heading), 1 do |
| 137 | turtle.turnLeft() |
| 138 | end |
| 139 | elseif(heading < destinationHeading) then |
| 140 | for t = 1, math.abs(destinationHeading - heading), 1 do |
| 141 | turtle.turnRight() |
| 142 | end |
| 143 | end |
| 144 | end |
| 145 | |
| 146 | function setHeadingZ(zDiff, heading) |
| 147 | local destinationHeading = heading |
| 148 | if(zDiff < 0) then |
| 149 | destinationHeading = 2 |
| 150 | elseif(zDiff > 0) then |
| 151 | destinationHeading = 4 |
| 152 | end |
| 153 | turnToFaceHeading(heading, destinationHeading) |
| 154 | |
| 155 | return destinationHeading |
| 156 | end |
| 157 | |
| 158 | function setHeadingX(xDiff, heading) |
| 159 | local destinationHeading = heading |
| 160 | if(xDiff < 0) then |
| 161 | destinationHeading = 1 |
| 162 | elseif(xDiff > 0) then |
| 163 | destinationHeading = 3 |
| 164 | end |
| 165 | |
| 166 | turnToFaceHeading(heading, destinationHeading) |
| 167 | return destinationHeading |
| 168 | end |
| 169 | |
| 170 | function digAndMove(n) |
| 171 | for x = 1, n, 1 do |
| 172 | while(turtle.detect()) do |
| 173 | turtle.dig() |
| 174 | end |
| 175 | turtle.forward() |
| 176 | checkFuel() |
| 177 | end |
| 178 | end |
| 179 | |
| 180 | function digAndMoveDown(n) |
| 181 | for y = 1, n, 1 do |
| 182 | print(y) |
| 183 | while(turtle.detectDown()) do |
| 184 | turtle.digDown() |
| 185 | end |
| 186 | turtle.down() |
| 187 | checkFuel() |
| 188 | end |
| 189 | end |
| 190 | |
| 191 | function digAndMoveUp(n) |
| 192 | for y = 1, n, 1 do |
| 193 | while(turtle.detectUp()) do |
| 194 | turtle.digUp() |
| 195 | end |
| 196 | turtle.up() |
| 197 | checkFuel() |
| 198 | end |
| 199 | end |
| 200 | |
| 201 | |
| 202 | function moveTo(coords, heading) |
| 203 | local currX, currY, currZ = waitForGPS() |
| 204 | local xDiff, yDiff, zDiff = coords.x - currX, coords.y - currY, coords.z - currZ |
| 205 | print(string.format("Distances from start: %d %d %d", xDiff, yDiff, zDiff)) |
| 206 | |
| 207 | -- -x = 1 |
| 208 | -- -z = 2 |
| 209 | -- +x = 3 |
| 210 | -- +z = 4 |
| 211 | |
| 212 | |
| 213 | -- Move to X start |
| 214 | heading = setHeadingX(xDiff, heading) |
| 215 | digAndMove(math.abs(xDiff)) |
| 216 | |
| 217 | -- Move to Z start |
| 218 | heading = setHeadingZ(zDiff, heading) |
| 219 | digAndMove(math.abs(zDiff)) |
| 220 | |
| 221 | -- Move to Y start |
| 222 | if(yDiff < 0) then |
| 223 | digAndMoveDown(math.abs(yDiff)) |
| 224 | elseif(yDiff > 0) then |
| 225 | digAndMoveUp(math.abs(yDiff)) |
| 226 | end |
| 227 | |
| 228 | |
| 229 | return heading |
| 230 | end |
| 231 | |
| 232 | |
| 233 | function calculateFuel(travels, digSize, fuelType) |
| 234 | local currX, currY, currZ = waitForGPS() |
| 235 | local xDiff, yDiff, zDiff = travels.x - currX, travels.y - currY, travels.z - currZ |
| 236 | |
| 237 | local volume = digSize.x + digSize.y + digSize.z |
| 238 | local travelDistance = (math.abs(xDiff) + math.abs(yDiff) + math.abs(zDiff)) * 2 |
| 239 | |
| 240 | local totalFuel = volume + travelDistance |
| 241 | print(string.format( "total steps: %d", totalFuel)) |
| 242 | |
| 243 | if(fuelType == "minecraft:coal") then |
| 244 | totalFuel = totalFuel / 80 |
| 245 | elseif(fuelType == "minecraft:coal_block") then |
| 246 | totalFuel = totalFuel / 800 |
| 247 | elseif(fuelType == "minecraft:charcoal") then |
| 248 | totalFuel = totalFuel / 80 |
| 249 | else |
| 250 | print("INVALID FUEL SOURCE") |
| 251 | os.exit(1) |
| 252 | end |
| 253 | |
| 254 | return math.floor(totalFuel) + 5 |
| 255 | end |
| 256 | |
| 257 | |
| 258 | |
| 259 | modem.transmit(SERVER_PORT, CLIENT_PORT, "CLIENT_DEPLOYED") |
| 260 | event, side, senderChannel, replyChannel, msg, distance = os.pullEvent("modem_message") |
| 261 | data = parseParams(msg) |
| 262 | |
| 263 | -- Pick up coal and refuel |
| 264 | local fuelNeeded = calculateFuel(data[1], data[2], "minecraft:coal") |
| 265 | turtle.suckDown(fuelNeeded) |
| 266 | checkFuel() |
| 267 | |
| 268 | print(string.format( "Extracting %d fuel...", fuelNeeded)) |
| 269 | |
| 270 | -- Grab Ender Chest |
| 271 | turtle.turnRight(1) |
| 272 | turtle.suck(1) |
| 273 | turtle.turnLeft(1) |
| 274 | |
| 275 | local startCoords = data[1] |
| 276 | local finalHeading = moveTo(startCoords, getOrientation()) |
| 277 | |
| 278 | local NORTH_HEADING = 2 |
| 279 | --Turn to face North |
| 280 | turnToFaceHeading(finalHeading, NORTH_HEADING) |
| 281 | finalHeading = NORTH_HEADING |
| 282 | --Now in Starting Position-- |
| 283 | |
| 284 | --------------------------------START MINING CODE----------------------------------------- |
| 285 | |
| 286 | |
| 287 | |
| 288 | |
| 289 | |
| 290 | ------------------------------------------------------------------------------------------ |
| 291 | |
| 292 | DROPPED_ITEMS = { |
| 293 | "minecraft:stone", |
| 294 | "minecraft:dirt", |
| 295 | "minecraft:basalt", |
| 296 | "minecraft:granite", |
| 297 | "minecraft:cobblestone", |
| 298 | "minecraft:sand", |
| 299 | "minecraft:gravel", |
| 300 | "minecraft:redstone", |
| 301 | "minecraft:flint", |
| 302 | "railcraft:ore_metal", |
| 303 | "extrautils2:ingredients", |
| 304 | "minecraft:dye", |
| 305 | "thaumcraft:nugget", |
| 306 | "thaumcraft:crystal_essence", |
| 307 | "thermalfoundation:material", |
| 308 | "projectred-core:resource_item", |
| 309 | "thaumcraft:ore_cinnabar", |
| 310 | "deepresonance:resonating_ore", |
| 311 | "forestry:apatite", |
| 312 | "biomesoplenty:loamy_dirt", |
| 313 | "chisel:marble", |
| 314 | "chisel:limestone", |
| 315 | } |
| 316 | function dropItems() |
| 317 | print("Purging Inventory...") |
| 318 | for slot = 1, SLOT_COUNT, 1 do |
| 319 | local item = turtle.getItemDetail(slot) |
| 320 | if(item ~= nil) then |
| 321 | for filterIndex = 1, #DROPPED_ITEMS, 1 do |
| 322 | if(item["name"] == DROPPED_ITEMS[filterIndex]) then |
| 323 | print("Dropping - " .. item["name"]) |
| 324 | turtle.select(slot) |
| 325 | turtle.dropDown() |
| 326 | end |
| 327 | end |
| 328 | end |
| 329 | end |
| 330 | end |
| 331 | |
| 332 | |
| 333 | function getEnderIndex() |
| 334 | for slot = 1, SLOT_COUNT, 1 do |
| 335 | local item = turtle.getItemDetail(slot) |
| 336 | if(item ~= nil) then |
| 337 | if(item["name"] == "enderstorage:ender_storage") then |
| 338 | return slot |
| 339 | end |
| 340 | end |
| 341 | end |
| 342 | return nil |
| 343 | end |
| 344 | |
| 345 | function manageInventory() |
| 346 | dropItems() |
| 347 | index = getEnderIndex() |
| 348 | if(index ~= nil) then |
| 349 | turtle.select(index) |
| 350 | turtle.digUp() |
| 351 | turtle.placeUp() |
| 352 | end |
| 353 | -- Chest is now deployed |
| 354 | for slot = 1, SLOT_COUNT, 1 do |
| 355 | local item = turtle.getItemDetail(slot) |
| 356 | if(item ~= nil) then |
| 357 | if(item["name"] ~= "minecraft:coal_block" and item["name"] ~= "minecraft:coal" and item["name"] ~= "minecraft:charcoal") then |
| 358 | turtle.select(slot) |
| 359 | turtle.dropUp() |
| 360 | end |
| 361 | end |
| 362 | end |
| 363 | -- Items are now stored |
| 364 | |
| 365 | turtle.digUp() |
| 366 | end |
| 367 | |
| 368 | |
| 369 | function detectAndDig() |
| 370 | while(turtle.detect()) do |
| 371 | turtle.dig() |
| 372 | end |
| 373 | end |
| 374 | |
| 375 | function forward() |
| 376 | detectAndDig() |
| 377 | turtle.forward() |
| 378 | end |
| 379 | |
| 380 | function leftTurn() |
| 381 | turtle.turnLeft() |
| 382 | detectAndDig() |
| 383 | turtle.forward() |
| 384 | turtle.turnLeft() |
| 385 | end |
| 386 | |
| 387 | |
| 388 | function rightTurn() |
| 389 | turtle.turnRight() |
| 390 | detectAndDig() |
| 391 | turtle.forward() |
| 392 | turtle.turnRight() |
| 393 | end |
| 394 | |
| 395 | |
| 396 | function dropTier(heading) |
| 397 | turtle.turnRight() |
| 398 | turtle.turnRight() |
| 399 | turtle.digDown() |
| 400 | turtle.down() |
| 401 | return flipDirection(heading) |
| 402 | end |
| 403 | |
| 404 | |
| 405 | function flipDirection(heading) |
| 406 | return ((heading + 1) % 4) + 1 |
| 407 | end |
| 408 | |
| 409 | function turnAround(tier, heading) |
| 410 | if(tier % 2 == 1) then |
| 411 | if(heading == 2 or heading == 3) then |
| 412 | rightTurn() |
| 413 | elseif(heading == 1 or heading == 4) then |
| 414 | leftTurn() |
| 415 | end |
| 416 | else |
| 417 | if(heading == 2 or heading == 3) then |
| 418 | leftTurn() |
| 419 | elseif(heading == 1 or heading == 4) then |
| 420 | rightTurn() |
| 421 | end |
| 422 | end |
| 423 | |
| 424 | return flipDirection(heading) |
| 425 | end |
| 426 | |
| 427 | |
| 428 | |
| 429 | function startQuary(width, height, depth, heading) |
| 430 | |
| 431 | for tier = 1, height, 1 do |
| 432 | for col = 1, width, 1 do |
| 433 | for row = 1, depth - 1, 1 do |
| 434 | if(not checkFuel()) then |
| 435 | print("Turtle is out of fuel, Powering Down...") |
| 436 | return |
| 437 | end |
| 438 | forward() |
| 439 | end |
| 440 | if(col ~= width) then |
| 441 | heading = turnAround(tier, heading) |
| 442 | end |
| 443 | manageInventory() |
| 444 | end |
| 445 | if(tier ~= height) then |
| 446 | heading = dropTier(heading) |
| 447 | end |
| 448 | end |
| 449 | |
| 450 | return heading |
| 451 | end |
| 452 | |
| 453 | |
| 454 | local quary = data[2] |
| 455 | finishedHeading = startQuary(quary.x, quary.y, quary.z, finalHeading) |
| 456 | |
| 457 | |
| 458 | |
| 459 | --------------------------------START RETURN TRIP CODE------------------------------------ |
| 460 | |
| 461 | |
| 462 | |
| 463 | |
| 464 | |
| 465 | ------------------------------------------------------------------------------------------ |
| 466 | |
| 467 | |
| 468 | function returnTo(coords, heading) |
| 469 | local currX, currY, currZ = waitForGPS() |
| 470 | local xDiff, yDiff, zDiff = coords.x - currX, coords.y - currY, coords.z - currZ |
| 471 | print(string.format("Distances from end: %d %d %d", xDiff, yDiff, zDiff)) |
| 472 | |
| 473 | -- Move to Y start |
| 474 | if(yDiff < 0) then |
| 475 | digAndMoveDown(math.abs(yDiff)) |
| 476 | elseif(yDiff > 0) then |
| 477 | digAndMoveUp(math.abs(yDiff)) |
| 478 | end |
| 479 | |
| 480 | -- Move to X start |
| 481 | heading = setHeadingX(xDiff, heading) |
| 482 | digAndMove(math.abs(xDiff)) |
| 483 | |
| 484 | -- Move to Z start |
| 485 | heading = setHeadingZ(zDiff, heading) |
| 486 | digAndMove(math.abs(zDiff)) |
| 487 | |
| 488 | |
| 489 | |
| 490 | return heading |
| 491 | end |
| 492 | |
| 493 | endCoords = data[3] |
| 494 | returnTo(endCoords ,finishedHeading) |
| 495 | |
| 496 | local timoutWait = 90 |
| 497 | for i = 1, timoutWait, 1 do |
| 498 | os.sleep(1) |
| 499 | print(string.format( "Waiting for brothers %d/%d", i, timoutWait)) |
| 500 | end |
| 501 | |
| 502 | modem.transmit(SERVER_PORT, CLIENT_PORT, "cum") |