View difference between Paste ID: cH5RZT7k and V40x6A16
SHOW: | | - or go back to the newest paste.
1
-- == Movement Constants ==
2-
local d = "north"
2+
local FORWARD = 1
3
local BACK = 2
4
local UP = 4
5-
if (#arg == 3) then
5+
local DOWN = 8
6-
    width = tonumber(arg[1])
6+
local TURN_RIGHT = 16
7-
    depth = tonumber(arg[2])
7+
local TURN_LEFT = 32
8
-- == Data ==
9
-- Constants
10-
    print('None or Malformed Size Given, Defaulting to 10x10x2 up')
10+
11
local LABEL = os.getComputerLabel()
12
local WIRELESS = false
13
local SERVER_CHANNEL = 65534
14
local ERROR_SERVER_CHANNEL = 65535
15
local CHANNEL = nil
16
-- Mutable Data
17
local moves = {}
18
local dt = "right" -- Direction Tangent (right, left)
19
local dv = "up" -- Direction Vertical (up, down)
20
local refill_lava = false -- Consume picked up lava
21
local width, depth, height = 10, 10, 2
22
-- == Peripherals ==
23
local modem = nil
24-
    "minecraft:dye",
24+
local peripherals = peripheral.getNames()
25
for name = 1, #peripherals, 1 do
26
    if(peripheral.getType(peripherals[name]) == "modem") then
27
        modem = peripheral.wrap(peripherals[name])
28
        WIRELESS = true
29
        break
30
    end
31
end
32
33
if(WIRELESS) then
34
    if(LABEL == "white") then CHANNEL = 0
35
    elseif(LABEL == "orange") then CHANNEL = 1
36
    elseif(LABEL == "magenta") then CHANNEL = 2
37
    elseif(LABEL == "light_blue") then CHANNEL = 3
38
    elseif(LABEL == "yellow") then CHANNEL = 4
39
    elseif(LABEL == "lime") then CHANNEL = 5
40
    elseif(LABEL == "pink") then CHANNEL = 6
41
    elseif(LABEL == "gray" or LABEL == "grey") then CHANNEL = 7
42
    elseif(LABEL == "light_gray" or LABEL == "light_grey") then CHANNEL = 8
43
    elseif(LABEL == "cyan") then CHANNEL = 9
44
    elseif(LABEL == "purple") then CHANNEL = 10
45
    elseif(LABEL == "blue") then CHANNEL = 11
46
    elseif(LABEL == "brown") then CHANNEL = 12
47
    elseif(LABEL == "green") then CHANNEL = 13
48
    elseif(LABEL == "red") then CHANNEL = 14
49
    elseif(LABEL == "black") then CHANNEL = 15
50-
function getEnderIndex()
50+
51
52
    if(CHANNEL == nil) then
53
        c = term.getTextColor()
54-
            if(item["name"] == "enderstorage:ender_storage") then
54+
        term.setTextColor(colors.red)
55
        print("Modem without a label. This robot has no channel!")
56
        term.setTextColor(c)
57
        WIRELESS = false
58
    else
59
        modem.open(CHANNEL)
60
    end
61
end
62-
function manageInventory()
62+
63-
    dropItems()
63+
-- Stolen From: http://lua-users.org/wiki/SimpleRound
64-
    index = getEnderIndex()
64+
function round(num, numDecimalPlaces)
65-
    if(index ~= nil) then
65+
    local mult = 10^(numDecimalPlaces or 0)
66
    return math.floor(num * mult + 0.5) / mult
67-
        turtle.digUp()      
67+
68-
        turtle.placeUp()  
68+
69
function transmit(message)
70
    if(WIRELESS) then
71
        modem.transmit(SERVER_CHANNEL, CHANNEL, message)
72
    end
73
end
74-
            if(item["name"] ~= "minecraft:coal_block" and item["name"] ~= "minecraft:coal") then
74+
75
function transmitError(message, forward)
76
    if(WIRELESS) then
77
        modem.transmit(ERROR_SERVER_CHANNEL, CHANNEL, message)
78
        if(forward) then
79
            transmit(message)
80
        end
81
    end
82-
    turtle.digUp()
82+
83
84
function get_file_name(file)
85
    file = file or debug.getinfo(1,'S').source
86
    return file:match("^@(.+)$")
87-
    
87+
88-
    if(turtle.getFuelLevel() < 50) then
88+
89
HOLD_ITEMS = {
90
    "minecraft:coal",
91
    "minecraft:coal_block",
92
    "minecraft:bucket"
93
}
94
95
DROPPED_ITEMS = {
96
    "minecraft:stone",
97
    "minecraft:dirt",
98
    "minecraft:cobblestone",
99
    "minecraft:sand",
100
    "minecraft:gravel",
101
    "minecraft:redstone",
102
    "minecraft:flint",
103
    "minecraft:clay_ball",
104
    "railcraft:ore_metal",
105
    "railcraft:ore_metal_poor",
106
    "extrautils2:ingredients",
107-
        turtle.digUp()
107+
    "chisel:marble2",
108
    "chisel:limestone2",
109
    "chisel:basalt2",
110
--    "minecraft:dye", -- Lapis Lazuli
111
    "thaumcraft:nugget",
112-
function forward()
112+
113
    "thermalfoundation:material",
114-
    turtle.forward()
114+
115
    "thaumcraft:ore_cinnabar",
116
    "deepresonance:resonating_ore",
117
    "forestry:apatite"
118-
    turtle.turnLeft()
118+
119
120-
    turtle.forward()
120+
121-
    turtle.turnLeft()
121+
122
    for slot = 1, SLOT_COUNT, 1 do
123
        local item = turtle.getItemDetail(slot)
124
        if(item ~= nil) then
125
            for filterIndex = 1, #DROPPED_ITEMS, 1 do
126
                if(item["name"] == DROPPED_ITEMS[filterIndex]) then
127-
    turtle.turnRight()
127+
128
                    turtle.select(slot)
129-
    turtle.forward()
129+
130-
    turtle.turnRight()
130+
131
            end
132
        end
133
    end
134-
function flipDirection()
134+
135-
    if(d == "north") then
135+
136-
        d = "south"
136+
function getItemIndex(find_item)
137-
    elseif(d == "south") then
137+
    if(type(find_item) ~= "string") then
138-
        d = "north"
138+
        error("Expected string but got " .. type(find_item))
139-
    elseif(d == "west") then
139+
140-
        d = "east"
140+
141-
    elseif(d == "east") then
141+
142-
        d = "west"
142+
143
            if(item["name"] == find_item) then
144-
    
144+
145
            end
146
        end
147-
function turnAround(tier)
147+
148-
    if(tier % 2 == 1) then
148+
149-
        if(d == "north" or d == "east") then
149+
150-
            rightTurn()
150+
151-
        elseif(d == "south" or d == "west") then
151+
function countAllOf(search_item)
152-
            leftTurn()
152+
    if(type(search_item) ~= "string") then
153
        error("Expected string but got " .. type(search_item))
154
    end
155-
        if(d == "north" or d == "east") then
155+
    count = 0
156-
            leftTurn()
156+
157-
        elseif(d == "south" or d == "west") then
157+
158-
            rightTurn()
158+
159
            if(item["name"] == search_item) then
160
                count = count + turtle.getItemCount()
161
            end
162
        end
163
    end
164
    return count
165-
function riseTier()
165+
166-
    turtle.turnRight()
166+
167-
    turtle.turnRight()
167+
function countStoredFuel()
168
    return countAllOf("minecraft:coal") * 80 + countAllOf("minecraft:coal_block") * 720 + countAllOf("minecraft:lava_bucket") * 1000
169-
    turtle.digUp()
169+
170-
    turtle.up()
170+
171
function coalesce()
172
    for slot = 1, SLOT_COUNT - 1, 1 do
173
        local base_item = turtle.getItemDetail(slot)
174
        if(base_item ~= nil) then
175-
    for tier = 1, height, 1 do
175+
            for i = slot + 1, SLOT_COUNT, 1 do
176
                local item = turtle.getItemDetail(slot)
177
                if(item ~= nil and base_item["name"] == item["name"]) then
178
                    turtle.select(i)
179-
                    print("Turtle is out of fuel, Powering Down...")
179+
                    turtle.transferTo(slot)
180
                end
181
            end
182-
                forward()
182+
183-
                print(string.format("Row: %d   Col: %d", row, col))
183+
184
end
185
186-
                turnAround(tier)
186+
function getNumberFreeSlots()
187
    local freeSlots = 0
188-
            manageInventory()
188+
189
        local item = turtle.getItemDetail(slot)
190-
        riseTier()
190+
        if(item == nil) then
191
            freeSlots = freeSlots + 1
192
        end
193
    end
194-
start()
194+
    return freeSlots
195
end
196
197
function shouldReturnItem(item)
198-
198+
    if(refill_lava and item["name"] == "minecraft:lava_bucket") then
199
        return false
200
    end
201
    for filterIndex = 1, #HOLD_ITEMS, 1 do
202
        if(item["name"] == HOLD_ITEMS[filterIndex]) then
203
            return false
204
        end
205
    end
206
    return true
207
end
208
209
function manageInventory(dumpAll)
210
    transmit("Managing Inventory")
211
    index = turtle.getSelectedSlot()
212
    while(index ~= nil) do
213
        index = getItemIndex("enderstorage:ender_storage")
214
        if(index == nil) then break end
215
        digUp()
216
        dropItems()
217
        turtle.select(index)
218
        if(turtle.placeUp()) then
219
            break
220
        else
221
            print("Chest not placed correctly... Trying again")
222
        end
223
    end
224
    local success, data = turtle.inspectUp()
225
    if(index == nil or (success and data.name ~= "enderstorage:ender_storage")) then
226
        transmitError("Ender Storage Missing")
227
        return false
228
    end
229
    -- Chest is now deployed
230
    coalesce()
231
    for slot = 1, SLOT_COUNT, 1 do
232
        local item = turtle.getItemDetail(slot)
233
        if(item ~= nil) then
234
            if(dumpAll or shouldReturnItem(item)) then
235
                turtle.select(slot)
236
                turtle.dropUp()
237
            elseif not shouldReturnItem(item) and turtle.getItemSpace(slot) <= 0 then
238
                for i = slot + 1, SLOT_COUNT, 1 do
239
                    local dump = turtle.getItemDetail(i)
240
                    if(dump ~= nil and item["name"] == dump["name"]) then
241
                        turtle.select(i)
242
                        turtle.dropUp()
243
                    end
244
                end
245
            end
246
        end
247
    end
248
    -- Items are now stored
249
    turtle.select(1)
250
    if(getNumberFreeSlots() >= 1) then
251
        digUp()
252
    else
253
        transmitError("Cannot Pick Up Ender Storage, Full Inventory")
254
        print("Cannot pick up Ender Storage, full inventory")
255
        return false
256
    end
257
    return true
258
end
259
260
function checkFuel()
261
    if(turtle.getFuelLevel() < 25) then
262
        -- transmit("Attempting Refuel...")
263
        print("Attempting Refuel...")
264
        for slot = 1, SLOT_COUNT, 1 do
265
            turtle.select(slot)
266
            if(turtle.refuel(1)) then
267
                -- transmit("Refuel Success!   Fuel: " .. turtle.getFuelLevel())
268
                return true
269
            end
270
        end
271
        return false
272
    else
273
        return true
274
    end
275
end
276
277
function digUp()
278
    local success, data = turtle.inspectUp()
279
    if(success and data.name == "minecraft:lava" and bucket_index ~= nil and getNumberFreeSlots() > 1) then
280
        -- transmit("Bucketing Lava Up...")
281
        turtle.select(bucket_index)
282
        turtle.placeUp()
283
        lava_index = getItemIndex("minecraft:lava_bucket")
284
        if(refill_lava and lava_index and turtle.getFuelLevel() + 1000 < turtle.getFuelLimit()) then
285
            -- transmit("Consumed newly bucketed lava.   Fuel: " .. turtle.getFuelLevel())
286
            turtle.select(getItemIndex("minecraft:lava_bucket"))
287
            turtle.refuel()
288
            turtle.transferTo(bucket_index)
289
        end
290
        bucket_index = getItemIndex("minecraft:bucket")
291
    end
292
    local block_above = data.name
293
    while(turtle.detectUp()) do
294
        local success, data = turtle.inspectUp()
295
        if(success) then
296
            block_above = data.name
297
        end
298
        if(block_above == "minecraft:gravel" or block_above == "minecraft:sand") then
299
            turtle.digUp()
300
            os.sleep(0.75)
301
        else
302
            turtle.digUp()
303
        end
304
    end
305
end
306
307
function detectAndDig()
308
    slot = turtle.getSelectedSlot()
309
    bucket_index = getItemIndex("minecraft:bucket")
310
    local success, data = turtle.inspect()
311
    if(success and data.name == "minecraft:lava" and bucket_index ~= nil and getNumberFreeSlots() > 1) then
312
        -- transmit("Bucketing Lava...")
313
        turtle.select(bucket_index)
314
        turtle.place()
315
        lava_index = getItemIndex("minecraft:lava_bucket")
316
        if(refill_lava and lava_index and turtle.getFuelLevel() + 1000 < turtle.getFuelLimit()) then
317
            -- transmit("Consumed newly bucketed lava.   Fuel: " .. turtle.getFuelLevel())
318
            turtle.select(lava_index)
319
            turtle.refuel()
320
            turtle.transferTo(bucket_index)
321
        end
322
        bucket_index = getItemIndex("minecraft:bucket")
323
    end
324
    while(turtle.detect()) do
325
        turtle.dig()
326
    end
327
    digUp()
328
    local success, data = turtle.inspectDown()
329
    if(success and data.name == "minecraft:lava" and bucket_index ~= nil and getNumberFreeSlots() > 1) then
330
        -- transmit("Bucketing Lava Down...")
331
        turtle.select(bucket_index)
332
        turtle.placeDown()
333
        lava_index = getItemIndex("minecraft:lava_bucket")
334
        if(refill_lava and lava_index and turtle.getFuelLevel() + 1000 < turtle.getFuelLimit()) then
335
            -- transmit("Consumed newly bucketed lava.   Fuel: " .. turtle.getFuelLevel())
336
            turtle.select(getItemIndex("minecraft:lava_bucket"))
337
            turtle.refuel()
338
            turtle.transferTo(bucket_index)
339
        end
340
        bucket_index = getItemIndex("minecraft:bucket")
341
    end
342
    if(turtle.detectDown()) then
343
        turtle.digDown()
344
    end
345
    turtle.select(slot)
346
end
347
348
function invertMove(move)
349
    if move == FORWARD or move == UP or move == TURN_RIGHT then
350
        return move * 2
351
    elseif move == BACK or move == DOWN or move == TURN_LEFT then
352
        return move / 2
353
    end
354
    return move
355
end
356
357
function stackSmash()
358
    local i = 1
359
    while i <= #moves do
360
        if(moves[i] == invertMove(moves[i + 1])) then
361
            for j = 1, 2, 1 do
362
                table.remove(moves, i)
363
            end
364
            i = i - (2 - 1)
365
        end
366
        if(moves[i] == moves[i+1] and moves[i] == moves[i+2] and moves[i] == moves[i+3] and (moves[i] == TURN_LEFT or moves[i] == TURN_RIGHT)) then
367
            for j = 1, 4, 1 do
368
                table.remove(moves, i)
369
            end
370
            i = i - (4 - 1)
371
        end
372
        i = i + 1
373
    end
374
end
375
376
function forward(times)
377
    times = times or 1
378
    for i = 1, times, 1 do
379
        if(not checkFuel()) then
380
            transmitError("Turtle is out of fuel, Powering Down...")
381
            error("Turtle is out of fuel, Powering Down...")
382
        end
383
        if(turtle.forward()) then
384
            table.insert(moves, FORWARD)
385
            stackSmash()
386
        else
387
            return false
388
        end
389
    end
390
    return true
391
end
392
393
function back(times)
394
    times = times or 1
395
    for i = 1, times, 1 do
396
        if(not checkFuel()) then
397
            transmitError("Turtle is out of fuel, Powering Down...")
398
            error("Turtle is out of fuel, Powering Down...")
399
        end
400
        if(turtle.back()) then
401
            table.insert(moves, BACK)
402
            stackSmash()
403
        else
404
            return false
405
        end
406
    end
407
    return true
408
end
409
410
function up(times)
411
    times = times or 1
412
    for i = 1, times, 1 do
413
        if(not checkFuel()) then
414
            transmitError("Turtle is out of fuel, Powering Down...")
415
            error("Turtle is out of fuel, Powering Down...")
416
        end
417
        if(turtle.up()) then
418
            table.insert(moves, UP)
419
            stackSmash()
420
        else
421
            return false
422
        end
423
    end
424
    return true
425
end
426
427
function down(times)
428
    times = times or 1
429
    for i = 1, times, 1 do
430
        if(not checkFuel()) then
431
            transmitError("Turtle is out of fuel, Powering Down...")
432
            error("Turtle is out of fuel, Powering Down...")
433
        end
434
        if(turtle.down()) then
435
            table.insert(moves, DOWN)
436
            stackSmash()
437
        else
438
            return false
439
        end
440
    end
441
    return true
442
end
443
444
function turnLeft(times)
445
    times = times or 1
446
    for i = 1, times, 1 do
447
        if(not checkFuel()) then
448
            transmitError("Turtle is out of fuel, Powering Down...")
449
            error("Turtle is out of fuel, Powering Down...")
450
        end
451
        if(turtle.turnLeft()) then
452
            table.insert(moves, TURN_LEFT)
453
            stackSmash()
454
        else
455
            return false
456
        end
457
    end
458
    return true
459
end
460
461
function turnRight(times)
462
    times = times or 1
463
    for i = 1, times, 1 do
464
        if(not checkFuel()) then
465
            transmitError("Turtle is out of fuel, Powering Down...")
466
            error("Turtle is out of fuel, Powering Down...")
467
        end
468
        if(turtle.turnRight()) then
469
            table.insert(moves, TURN_RIGHT)
470
            stackSmash()
471
        else
472
            return false
473
        end
474
    end
475
    return true
476
end
477
478
function leftTurn()
479
    turnLeft()
480
    detectAndDig()
481
    forward()
482
    turnLeft()
483
    detectAndDig()
484
end
485
486
487
function rightTurn()
488
    turnRight()
489
    detectAndDig()
490
    forward()
491
    turnRight()
492
    detectAndDig()
493
end
494
495
function flipDirection(logging)
496
    if(logging == nil) then logging = true end
497
    if(logging) then
498
        turnLeft(2)
499
    else
500
        turtle.turnLeft()
501
        turtle.turnLeft()
502
    end
503
end
504
505
function flipDirectionTangent()
506
    if(dt == "right") then
507
        dt = "left"
508
    elseif(dt == "left") then
509
        dt = "right"
510
    end
511
end
512
513
function flipDirectionVertical()
514
    if(dv == "up") then
515
        dv = "down"
516
    elseif(dv == "down") then
517
        dv = "up"
518
    end
519
end
520
521
function turnAround()
522
    if(dt == "right") then
523
        rightTurn()
524
    elseif(dt == "left") then
525
        leftTurn()
526
    end
527
    flipDirectionTangent()
528
end
529
530
function riseTier(delta)
531
    flipDirection()
532
    delta = delta or 1 -- Default delta is 1
533
    for step = 1, delta, 1 do
534
		digUp()
535
		turtle.digDown()
536
        if(dv == "up") then
537
            up()
538
        elseif(dv == "down") then
539
            down()
540
        end
541
    end
542
end
543
544
function returnToStart()
545
    flipDirection(false)
546
    for i = #moves, 1, -1 do
547
        move = moves[i]
548
        if move == UP or move == DOWN or move == TURN_LEFT or move == TURN_RIGHT then
549
            move = invertMove(move)
550
        end
551
        if move == FORWARD then
552
            detectAndDig()
553
            forward()
554
        elseif move == BACK then back()
555
        elseif move == UP then up()
556
        elseif move == DOWN then down()
557
        elseif move == TURN_LEFT then turnLeft()
558
        elseif move == TURN_RIGHT then turnRight()
559
        end
560
    end
561
	flipDirection(false)
562
end
563
564
function start()
565
    transmit("Begin " .. depth .. "x" .. width .. "x" .. height .. " " .. dv .. " and " .. dt)
566
    print("Volume: D x W x H = " .. depth .. " x " .. width .. " x " .. height)
567
    print("Direction: " .. dv .. " and to the " .. dt)
568
    if(WIRELESS) then
569
        print("Wireless is Enabled")
570
    end
571
    count = 0
572
    delta = 3
573
    total = depth * width * height
574
    height = math.max(height - 1, 1)
575
	tier = math.min(height, 2)
576
	while tier <= height do
577
        for col = 1, width, 1 do
578
            for row = 1, depth - 1, 1 do
579
                if(not checkFuel()) then
580
                    transmitError("Turtle is out of fuel, Powering Down...")
581
                    error("Turtle is out of fuel, Powering Down...")
582
                    return
583
                end
584
                if(getNumberFreeSlots() < 1) then
585
                    -- transmit("Inventory Full, Dropping Items...")
586
                    coalesce()
587
                    dropItems()
588
                    if(getNumberFreeSlots() < 1) then
589
                        if(not manageInventory()) then
590
                            transmitError("Turtle cannot find ender chest... Returning to Start")
591
                            print("Turtle cannot find ender chest...")
592
                            returnToStart()
593
                            return
594
                        end
595
                    end
596
                end
597
                detectAndDig()
598
                count = count + delta
599
                while not forward() do
600
                    checkFuel()
601
                    if turtle.detect() then
602
                        turtle.dig()
603
                    else
604
                        turtle.attack()
605
                    end
606
                end
607
                print(string.format("Row: %d   Col: %d   Tier: %d   Fuel: %d", row, col, tier, turtle.getFuelLevel()))
608
            end
609
            if(col ~= width) then
610
                turnAround()
611
            end
612
            transmit("Completed Column #" .. col .. "   Fuel: " .. turtle.getFuelLevel() .. "   Completion: " .. count .. "/" .. total .. " (" .. round(100*count/total, 3) .. "%)")
613
        end
614
        transmit("Completed Layer #" .. tier .. "   Fuel: " .. turtle.getFuelLevel() .. "   Completion: " .. count .. "/" .. total .. " (" .. round(100*count/total) .. "%)")
615
        if(tier < height) then
616
            if(tier + 2 < height) then
617
                delta = 3
618
                tier = tier + 2
619
                riseTier(3)
620
			elseif(tier + 1 < height) then
621
                delta = 2
622
                tier = tier + 1
623
				riseTier(2)
624
            else
625
                delta = 1
626
                riseTier()
627
            end
628
        end
629
        tier = tier + 1
630
    end
631
    transmit("Completed All Layers, Returning to Start" .. "   Fuel: " .. turtle.getFuelLevel())
632
    returnToStart()
633
    transmit("At Start" .. "   Fuel: " .. turtle.getFuelLevel())
634
	if(not manageInventory(true)) then
635
        transmit("Turtle cannot find ender chest, This is a serious issue...")
636
        print("Turtle cannot find ender chest, This is a serious issue...")
637
    end
638
    transmit("End " .. depth .. "x" .. width .. "x" .. height .. " " .. dv .. " and " .. dt)
639
end
640
641
if (#arg >= 3) then
642
    depth = tonumber(arg[1])
643
	width = tonumber(arg[2])
644
    height = tonumber(arg[3])
645
	for i = 4, #arg, 1 do
646
    	if arg[i] == "flip" then flipDirection()
647
        elseif arg[i] == "up" or arg[i] == "down" then dv = arg[i]
648
        elseif arg[i] == "left" or arg[i] == "right" then dt = arg[i]
649
        elseif arg[i] == "refill" then refill_lava = true
650
        else error("Unkown Argument #" .. i .. ": " .. arg[i])
651
        end
652
    end
653
else
654
    error("Usage: " .. get_file_name() .. " depth width height [left] [right] [up] [down] [flip]\n - left -- robot goes left (overrides right)\n - right -- robot goes right [default] (overrides left)\n - up -- robot goes up [default] (overrides down)\n - down -- robot goes down (overrides up)\n - flip -- robot immediately rotates 180 degrees\n - refill -- robot consumes lava buckets [disabled by default]")
655
end
656
657
start()