View difference between Paste ID: aE0Vku7Z and UmtT2Xzx
SHOW: | | - or go back to the newest paste.
1
local MINFUELLEVEL = 4000
2
local tunnelLength = 0
3
local torches = false
4
local garbage = {
5
    ["minecraft:cobblestone"] = true,
6
    ["minecraft:dirt"] = true,
7
    ["minecraft:gravel"] = true,
8
    ["minecraft:stone"] = true,
9
    ["minecraft:sand"] = true
10
}
11
12
13
14
15
16
local args = {...}
17
18
local sides = {"left", "right"}
19
local equipment = {left = nil, right = nil}
20
local tools = {["minecraft:compass"] = true, ["advancedperipherals:geo_scanner"] = true, ["minecraft:diamond_pickaxe"] = true}
21-
local tools = {["minecraft:compass"] = true, ["plethora:module"] = true, ["minecraft:diamond_pickaxe"] = true}
21+
22
local pos = vector.new(0, 0, 0)
23
local heading = vector.new(1, 0, 0)
24
local directions = {NORTH = vector.new(0, 0, -1), EAST = vector.new(1, 0, 0), SOUTH = vector.new(0, 0, 1), WEST = vector.new(-1, 0, 0)}
25
local orientations = {[vector.new(0, 0, -1):tostring()] = 0, [vector.new(1, 0, 0):tostring()] = 1, [vector.new(0, 0, 1):tostring()] = 2, [vector.new(-1, 0, 0):tostring()] = 3}
26
local home = vector.new(0, 0, 0)
27
local startingHeading
28
-- init
29
function init()
30
31
    if args then
32
        if args[1] then
33
            tunnelLength = args[1]
34
        end
35
36
        if args[2] then
37
            torches = args[2]
38
        end
39
    end
40
41
    heading = getFacing()
42
    startingHeading = heading
43
    print(heading)
44
    for _, side in pairs(sides) do
45
        local tool = peripheral.getType(side) 
46
        if tool then
47
            equipment[side] = tool
48
        end
49
    end
50
51
    for side, tool in pairs(equipment) do
52
        print(side .. ": " .. tool)
53
    end
54
55
    scanInventory()
56
end
57
58
-- inventory functions
59
function scanInventory()
60
    inventory = {}
61
62
    for i = 1, 16 do
63
        local data = turtle.getItemDetail(i)
64
        if data then
65
            if inventory[data.name] then
66
                table.insert(inventory[data.name], i)
67
            else
68
                inventory[data.name] = {i}
69
            end
70
        end
71
    end
72
end
73
74
function selectItem(itemName)
75
    scanInventory()
76
    if not inventory[itemName] then return false end
77
78
    turtle.select(inventory[itemName][1])
79
    return true
80
end
81
82
function equipItem(itemName, side)
83
    side = side or "right"
84
    scanInventory()
85
    if not inventory[itemName] then return false end
86
    turtle.select(inventory[itemName][1])
87
88
    if side == "right" then
89
        turtle.equipRight()
90
    else
91
        turtle.equipLeft()
92
    end
93
end
94
95
function purgeInv()
96
    for i = 1, 16 do
97
        local data = turtle.getItemDetail(i)
98
        if data then
99
            if garbage[data.name] then
100
                turtle.select(i)
101
                turtle.dropUp()
102
            end
103
104
            for b = 1, i-1 do
105
                local d = turtle.getItemDetail(b)
106
                if d then
107
                    if d.name == data.name then
108
                        turtle.select(i)
109
                        turtle.transferTo(b)
110
                    end
111
                end
112
            end
113
        end
114
    end
115
end
116
117
function refuel()
118
    scanInventory()
119
    if inventory["minecraft:coal"] then
120
        turtle.select(inventory["minecraft:coal"][1])
121
        turtle.refuel()
122
    end
123
end
124
125
function emptyInventory()
126
    purgeInv()
127
128
    for i = 1, 16 do
129
        local data = turtle.getItemDetail(i)
130
        if data then
131
            if not tools[data.name] then
132
                turtle.select(i)
133
                turtle.drop()
134
            end
135
        end
136
    end
137
end
138
139
function getEmptySpace()
140
    local emptySpace = 0
141
142
    for i = 1, 16 do
143
        local count = turtle.getItemCount(i)
144
        if count == 0 then
145
            emptySpace = emptySpace + 1
146
        end
147
    end
148
    return emptySpace
149
end
150
-- navigation
151
function getFacing()
152
    equipItem("minecraft:compass")
153
    local facing = peripheral.call("right", "getFacing")
154
    return directions[string.upper(facing)]
155
end
156
157
function compareVectors(vec1, vec2)
158
    if vec1.x == vec2.x and vec1.y == vec2.y and vec1.z == vec2.z then
159
        return true
160
    else
161
        return false
162
    end
163
end
164
165
function turnRight()
166
    turtle.turnRight()
167
168
    if compareVectors(heading, vector.new(1, 0, 0)) then
169
        heading = vector.new(0, 0, 1)
170
    elseif compareVectors(heading, vector.new(-1, 0, 0)) then
171
        heading = vector.new(0, 0, -1)
172
    elseif compareVectors(heading, vector.new(0, 0, 1)) then
173
        heading = vector.new(-1, 0, 0)
174
    elseif compareVectors(heading, vector.new(0, 0, -1)) then
175
        heading = vector.new(1, 0, 0)
176
    end
177
178
    return true
179
end
180
181
function turnLeft()
182
    turtle.turnLeft()
183
 
184
    if compareVectors(heading, vector.new(1, 0, 0)) then
185
        heading = vector.new(0, 0, -1)
186
    elseif compareVectors(heading, vector.new(-1, 0, 0)) then
187
        heading = vector.new(0, 0, 1)
188
    elseif compareVectors(heading, vector.new(0, 0, 1)) then
189
        heading = vector.new(1, 0, 0)
190
    elseif compareVectors(heading, vector.new(0, 0, -1)) then
191
        heading = vector.new(-1, 0, 0)
192
    end
193
194
    return true
195
end
196
197
function forward()
198
    local tries = 0
199
    repeat 
200
        if tries > 50 then return false end
201
        tries = tries + 1
202
        turtle.dig() 
203
    until turtle.forward()
204
    pos = pos + heading
205
    return true
206
end
207
208
function back()
209
    if not turtle.back() then
210
        turnRight()
211
        turnRight()
212
        forward()
213
        turnLeft()
214
        turnLeft()
215
    else
216
        pos = pos - heading
217
    end
218
219
    return true
220
end
221
222
function up()
223
    repeat turtle.digUp() until turtle.up() 
224
225
    pos = pos + vector.new(0, 1, 0)
226
    return true
227
end
228
229
function down()
230
    local tries = 0
231
    repeat
232
        if tries > 50 then return false end
233
        tries = tries + 1
234
        turtle.digDown()
235
    until turtle.down() 
236
237
    pos = pos + vector.new(0, -1, 0)
238
    return true
239
end
240
241
function turnToHeading(newHeading)
242
    if compareVectors(newHeading, heading) then
243
        return true
244
    end
245
246
    if compareVectors(newHeading, -heading) then
247
        turnRight()
248
        turnRight()
249
        return true
250
    end
251
252
    if orientations[newHeading:tostring()] == 0 and orientations[heading:tostring()] == 3 then
253
        turnRight()
254
        return true
255
    end
256
257
    if orientations[newHeading:tostring()] == 3 and orientations[heading:tostring()] == 0 then
258
        turnLeft()
259
        return true
260
    end
261
262
263
    if orientations[newHeading:tostring()] > orientations[heading:tostring()] then
264
        turnRight()
265
    else
266
        turnLeft()
267
    end
268
end
269
270
function goto(newPos)
271
    if newPos.x > pos.x then
272
        turnToHeading(vector.new(1, 0, 0))
273
        while newPos.x > pos.x do
274
            if not forward() then return false end
275
        end
276
    end
277
278
    if newPos.x < pos.x then
279
        turnToHeading(vector.new(-1, 0, 0))
280
        while newPos.x < pos.x do
281
            if not forward() then return false end
282
        end
283
    end
284
285
    if newPos.z > pos.z then
286
        turnToHeading(vector.new(0, 0, 1))
287
        while newPos.z > pos.z do
288
            if not forward() then return false end
289
        end
290
    end
291
292
    if newPos.z < pos.z then
293
        turnToHeading(vector.new(0, 0, -1))
294
        while newPos.z < pos.z do
295
            if not forward() then return false end
296
        end
297
    end
298
299
    while newPos.y > pos.y do
300
        up()
301
    end
302
303
    while newPos.y < pos.y do
304
        if not down() then return false end
305
    end
306
end
307
308
309
-- mining functions
310
function isOreBlock(name)
311
    if string.find(name, "ore")  and string.find(name, "minecraft") then return true end
312
    if string.find(name, "ore")  and string.find(name, "thermal") then return true end
313
    return false
314
end
315
316
function scanArea()
317
    if equipment.right ~= "advancedperipherals:geo_scanner" then
318-
    if equipment.right ~= "plethora:scanner" then
318+
        equipItem("advancedperipherals:geo_scanner")
319-
        equipItem("plethora:module")
319+
320
321
    local data = peripheral.call("right", "scan")
322
    local ores = {}
323
324
    for _, block in pairs(data) do
325
        if isOreBlock(block.name) then
326
            block.x = block.x + pos.x
327
            block.y = block.y + pos.y
328
            block.z = block.z + pos.z
329
            table.insert(ores, block)
330
        end
331
    end
332
333
    return ores
334
end
335
336
function getDistance(pos1, pos2)
337
    local x = math.abs(pos1.x - pos2.x)
338
    local y = math.abs(pos1.y - pos2.y)
339
    local z = math.abs(pos1.z - pos2.z)
340
    return (x + y + z)
341
end
342
343
function createMiningPath(ores)
344
    local unassignedOres = ores
345
    local assignedOres = {}
346
347
    local lowestScore = 999
348
    local lowestIndex = 1
349
    for i = 1, #unassignedOres do
350
        local dis = getDistance(unassignedOres[i], pos)
351
        if dis < lowestScore then
352
            lowestIndex = i
353
            lowestScore = dis
354
        end
355
    end
356
357
    table.insert(assignedOres, unassignedOres[lowestIndex])
358
    table.remove(unassignedOres, lowestIndex)
359
360
    while #unassignedOres > 0 do
361
362
        local lowestScore = 999
363
        local lowestIndex = 1
364
        for i = 1, #unassignedOres do
365
            local dis = getDistance(unassignedOres[i], assignedOres[#assignedOres])
366
            if dis < lowestScore then
367
                lowestIndex = i
368
                lowestScore = dis
369
            end
370
        end 
371
        table.insert(assignedOres, unassignedOres[lowestIndex])
372
        table.remove(unassignedOres, lowestIndex)
373
    end
374
375
    print(#assignedOres)
376
    return assignedOres
377
end
378
379
function scanAndMine()
380
    local ores = scanArea()
381
    equipItem("minecraft:diamond_pickaxe")
382
    local path = createMiningPath(ores)
383
384
    print(#path)
385
    for i = 1, #path do
386
        if i % 5 == 0 then
387
            purgeInv()
388
            if getEmptySpace() < 3 then
389
                dumpItems()
390
            end
391
        end
392
393
        goto(vector.new(path[i].x, path[i].y, path[i].z))
394
    end
395
end
396
397
function dumpItems()
398
    local thisPos = pos
399
    local thisHeading = heading
400
    goto(home)
401
    turnToHeading(-startingHeading)
402
    emptyInventory()
403
404
    goto(thisPos)
405
    turnToHeading(thisHeading)
406
end
407
408
function main()
409
    equipItem("minecraft:diamond_pickaxe")
410
    for i = 1, 5 do
411
        turtle.digUp()
412
        forward()
413
    end
414
    for i = 1, tunnelLength/8 do
415
        equipItem("minecraft:diamond_pickaxe")
416
        for b = 1, 8 do
417
            turtle.digUp()
418
            forward()
419
        end
420
421
        local curPos = pos
422
        local curHeading = heading
423
        scanAndMine()
424
        goto(curPos)
425
        turnToHeading(curHeading)
426
        purgeInv()
427
428
        if turtle.getFuelLevel() < MINFUELLEVEL then
429
            refuel()
430
			if turtle.getFuelLevel() < MINFUELLEVEL then
431
				goto(home)
432
				return
433
			end
434
        end
435
    end
436
    goto(home)
437
    turnToHeading(-startingHeading)
438
    emptyInventory()
439
end
440
441
init()
442
main()