View difference between Paste ID: 3UxyezTg and 28Tdz3QE
SHOW: | | - or go back to the newest paste.
1
--constants
2
---CONFIG_constants
3
local CONFIG_targetBlock = "minecraft:dirt"
4
---ARGUMENT_CONSTANTs
5
local tArgs = { ... }
6
local ZONE_DEPTH
7
-- local ACCEPTABLE_FUELS
8
if #tArgs < 2 then
9
    local myname = shell.getRunningProgram()
10
    local b = string.find(myname, "/")
11
    while b do
12
        local startindex, endindex = b
13
        myname = string.sub(endindex)
14
    end
15
    print( "Usage:"..myname.." <diameter> <quarry depth>" )
16
    return
17
elseif #tArgs >= 2 then
18
    ZONE_DEPTH = tonumber ( tArgs[2] )
19
end
20
local DIAMETER = tonumber( tArgs[1] )
21
 
22
-- if #tArgs > 2 then
23
    -- for n=3,#tArgs do
24
        -- ACCEPTABLE_FUELS = tArgs[2]
25
-- else
26
    -- ACCEPTABLE_FUELS 
27
-- end
28
--variables
29
local acceptableFuels = {["minecraft:coal"] = true}
30
local nextTurnDirection = right
31
local depth = 0    --this keeps track of how far we had descended from our starting position
32
local xPos,zPos = 0,0 --these store the turtle's location within its own relativistic world grid
33
local xDir,zDir = 0,1 --these are a direction vector that assumes we face positive Z initially 
34
                      --(but whether this is true is irrelevant since we don't rely on GPS, etc.
35
                      --We just track our location and direction internally)
36
 
37
--functions
38
local function turnLeft() --this just updates the direction vector
39
    turtle.turnLeft()
40
    xDir, zDir = -zDir, xDir --this is pretty smart vector handling, TBH. I might have to remember this...
41
end
42
 
43
local function turnRight() --this just updates the direction vector
44
    turtle.turnRight()
45
    xDir, zDir = zDir, -xDir
46
end
47
function refuel( amount ) -- checks if we have enough fuel, and if not, search the inventory for valid fuels
48
    local fuelLevel = turtle.getFuelLevel()
49
    if fuelLevel == "unlimited" then
50
        return true -- if fuel requirements are disabled for any reason, this function always returns true
51
    end
52
    
53
    local needed = amount or (xPos + zPos + depth + 2) -- if amount isn't specified, estimate how much we need to get "home"
54
    if turtle.getFuelLevel() < needed then
55
        local fueled = false
56
        for n=1,16 do
57
            if turtle.getItemCount(n) > 0 then
58
                turtle.select(n)
59
                local function membershipTest(x, mySet)
60
                    for n=1,#mySet do
61
                        if x == mySet[n] then
62
                            return true
63
                        end
64
                    end
65
                    return false
66
                end
67
                if acceptableFuels[turtle.getItemDetail().name] then --I only want to accept certain fuels
68
                    while turtle.getItemCount(n) > 0 and turtle.getFuelLevel() < needed do
69
                        turtle.refuel(1)
70
                    end
71
                    if turtle.getFuelLevel() >= needed then
72
                        turtle.select(1) -- reset the inventory cursor
73
                        return true
74
                    end
75
                end
76
            end
77
        end
78
        turtle.select(1)
79
        return false -- if the fuel requirements could not be met, refuel failed
80
    end
81
    
82
    return true
83
end
84
local function collect()    --checks if inventory has an open slot
85
    local bFull = true    --assume backpack is full until disproven
86
    for n=1,16 do
87
        local nCount = turtle.getItemCount(n)
88
        if nCount == 0 then --good, we have an empty slot
89
            bFull = false
90
        end
91
    end 
92
    if bFull then
93
        print( "No empty slots left." )
94
        return false
95
    end
96
    return true
97
end
98
local function chestIO( _bKeepOneFuelStack ) --adjusted to account for not dropping targetBlock
99
    print( "Unloading items..." )
100
    local targetBlockCount = 0
101
    for n=1,16 do
102
        local nCount = turtle.getItemCount(n)
103
        if nCount > 0 then
104
            turtle.select(n)            
105
            local bDrop = true
106
            if _bKeepOneFuelStack and turtle.refuel(0) then
107
                bDrop = false
108
                _bKeepOneFuelStack = false
109
            elseif turtle.getItemDetail().name == CONFIG_targetBlock then
110
                bDrop = false
111
                targetBlockCount = targetBlockCount + nCount
112
            end         
113
            if bDrop then
114
                turtle.drop()
115
            end
116
        end
117
    end
118
    local function countTargetBlock(threshold)
119
        local myCount = 0
120
        for n=1,16 do
121
            local nCount = turtle.getItemCount(n)
122
            if nCount > 0 then
123
                turtle.select(n)
124
                if turtle.getItemDetail().name == CONFIG_targetBlock then
125
                    myCount = myCount + nCount
126
                    if myCount > threshold then
127
                        return true
128
                    end
129
                end
130
            end
131
        end
132
        return false
133
    end
134
    if targetBlockCount < 512 then
135
        print ( "Waiting for"..CONFIG_targetBlock.."...")
136
        while not countTargetBlock(512) do
137
            os.pullEvent( "turtle_inventory" )
138
        end
139
    end
140
    turtle.select(1)
141
end
142
function goTo( x, y, z, xd, zd ) --given a location and a current direction vector, go to location
143
    --while we are too low, forcibly go up (y axis translation part 1)
144
    while depth > y do
145
        if turtle.up() then
146
            depth = depth - 1
147
        elseif turtle.digUp() or turtle.attackUp() then --if something was in the way[...]
148
            collect()                                  --update the inventory manager. Isn't functional programming fun?
149
        else
150
            sleep( 0.5 )
151
        end
152
    end
153
    --while we are too high, forcibly go down(y axis translation part 2)
154
    while depth < y do
155
        if turtle.down() then
156
            depth = depth + 1
157
        elseif turtle.digDown() or turtle.attackDown() then --if something was in the way[...]
158
            --ensure there's still empty space
159
            collect()
160
        else
161
            sleep( 0.5 )
162
        end
163
    end
164
    --x axis translation
165
    if xPos > x then        --if we need to go toward negative X
166
        while xDir ~= -1 do --... but we aren't facing negative X
167
            turnLeft()      --turn and update the vector
168
        end
169
        while xPos > x do --start moving left just like we did with up
170
            if turtle.forward() then
171
                xPos = xPos - 1
172
            elseif turtle.dig() or turtle.attack() then
173
                collect()
174
            else
175
                sleep( 0.5 )
176
            end
177
        end
178
    elseif xPos < x then    --same as above, but reversed
179
        while xDir ~= 1 do
180
            turnLeft()
181
        end
182
        while xPos < x do
183
            if turtle.forward() then
184
                xPos = xPos + 1
185
            elseif turtle.dig() or turtle.attack() then
186
                collect()
187
            else
188
                sleep( 0.5 )
189
            end
190
        end
191
    end
192
    --z axis translation
193
    if zPos > z then        --same as above, but the other axis (negative Z)
194
        while zDir ~= -1 do
195
            turnLeft()
196
        end
197
        while zPos > z do
198
            if turtle.forward() then
199
                zPos = zPos - 1
200
            elseif turtle.dig() or turtle.attack() then
201
                collect()
202
            else
203
                sleep( 0.5 )
204
            end
205
        end
206
    elseif zPos < z then    --same as above, but reverse (positive Z)
207
        while zDir ~= 1 do
208
            turnLeft()
209
        end
210
        while zPos < z do
211
            if turtle.forward() then
212
                zPos = zPos + 1
213
            elseif turtle.dig() or turtle.attack() then
214
                collect()
215
            else
216
                sleep( 0.5 )
217
            end
218
        end 
219
    end
220
    --Rotation to match aim vector
221
    while zDir ~= zd or xDir ~= xd do
222
        turnLeft()
223
    end
224
end
225
local function returnSupplies()
226
    local x,y,z,xd,zd = xPos,depth,zPos,xDir,zDir
227
    print( "Returning to surface..." )
228
    goTo( 0,0,0,0,-1 )
229
    
230
    chestIO( true )
231
    local fuelNeeded = 2*(x+y+z) + 1
232
    if not refuel( fuelNeeded ) then
233
        print( "Waiting for fuel" )
234
        while not refuel( fuelNeeded ) do
235
            os.pullEvent( "turtle_inventory" ) --waits until something modifies the inventory to add enough fuel
236
        end
237
    end
238
    
239
    print( "Resuming mining..." )
240
    goTo( x,y,z,xd,zd )
241
end
242
local function seekItem(itemID)
243
    for n=1,16 do
244
        local nCount = turtle.getItemCount(n)
245
        if nCount > 0 then
246
            turtle.select(n)
247
            if turtle.getItemDetail().name == itemID then
248
                return n
249
            end
250
        end
251
    end
252
	--return false --I could just let it return nil but I'd rather not
253
end
254
local function placeBlock(itemSlot)
255
	turtle.select(itemSlot)
256
	while not turtle.placeDown() do --I have the block, place it!
257
		if not turtle.digDown() then --but smash things if necessary
258
			turtle.attackDown()
259
		end
260
	end
261
	return true
262
end
263
local function seekAndPlaceBlock()
264
	local targetSlot = seekItem(CONFIG_targetBlock)
265
	if not targetSlot then
266
		print("out of target block"..targetSlot)
267
		returnSupplies()
268
		targetSlot = seekItem(CONFIG_targetBlock)
269
	end
270
	if not targetSlot then
271
		return false
272
	end
273
	placeBlock(targetSlot)
274
	return true
275
end 
276
local function forwardOp()
277
    if not refuel() then -- only move if we can get back from this location
278
        print( "Not enough Fuel" )
279
        returnSupplies()
280
    end
281
    --keep attempting to go forward; if unsuccessful, break & attack
282
    while not turtle.forward() do -- keep trying to move forward (digging or attacking if necessary) until successful
283
        if turtle.detect() then -- is there a block in front of us?
284
            if turtle.dig() then
285
                if not collect() then
286
                    returnSupplies()
287
                end
288
            else
289
                print ("forwardOp aborting!")
290
                return false -- The block in front of us couldn't be broken
291
            end
292
        elseif turtle.attack() then
293
            if not collect() then --no empty slots
294
                returnSupplies()
295
            end
296
        else
297
            sleep( 0.5 )
298
        end
299
    end
300
    --update location
301
    xPos = xPos + xDir -- adjust the turtle's memory of its location by the direction vector
302
    zPos = zPos + zDir -- see above
303
    --Place targetBlock below
304
	if not seekAndPlaceBlock() then
305
        print("could not place ".. CONFIG_targetBlock..". Is something in the way or did I break?")
306
    end
307
    turtle.select(1)
308
    return true
309
end
310
local function layerChangeOp()
311
    if not refuel() then -- only move if we can get back from this location
312
        print( "Not enough Fuel" )
313
        returnSupplies()
314
    end
315
    --keep attempting to go up; if unsuccessful, break & attack
316
    while not turtle.up() do -- keep trying to move up (digging or attacking if necessary) until successful
317
        if turtle.detectUp() then -- is there a block above of us?
318
            if turtle.digUp() then
319
                if not collect() then
320
                    returnSupplies()
321
                end
322
            else
323
                print ("layerChangeOp aborting!")
324
                return false -- The block above us couldn't be broken
325
            end
326
        elseif turtle.attackUp() then
327
            if not collect() then --no empty slots
328
                returnSupplies()
329
            end
330
        else
331
            sleep( 0.5 )
332
        end
333
    end
334
    turtle.select(1)
335
    return true
336
end
337
local function turnAround(turnDirection)
338
    if turnDirection == 0 then
339
        turnLeft()
340
        if not forwardOp() then
341
            print ("turnAround aborting!")
342
            return false
343
        end
344
        turnLeft()
345
    elseif turnDirection == 1 then
346
        turnRight()
347
        if not forwardOp() then
348
            print ("turnAround aborting!")
349
            return false
350
        end
351
        turnRight()
352
    else
353
        turnRight()
354
        if not forwardOp() then
355
            print ("turnAround aborting!")
356
            return false
357
        end
358
        turnRight()
359
    end
360
    return true
361
end
362
local function doRow(length)
363
    for m=1,length-1 do --first row gets done by turnaround
364
        if not forwardOp() then
365
            print ("doRow aborting!")
366
            return false
367
        end
368
    end
369
    return true
370
end
371
local function doLayer(width)--handles doRow and turnAround calls. Three-dimensional pathing calls are handled by doCuboid
372
    --don't forget to place a block on the first spot, not just after each forwardOp
373
	if not seekAndPlaceBlock() then
374
        print("could not place ".. CONFIG_targetBlock..". Is something in the way or did I break?")
375
    end
376
    turtle.select(1)
377
	local directionBit
378
	for n=1,width-1 do
379
		directionBit = math.fmod(n,2)
380
        if not doRow(DIAMETER) then
381
            print ("doLayer aborting!")
382
            return false
383
        end
384
        if not turnAround(directionBit) then
385
            print ("doLayer aborting!")
386-
        if not turnAround(math.fmod(n,2)) then
386+
387
        end
388
    end
389
    if not doRow(DIAMETER) then
390
        print ("doLayer aborting!")
391
        return false
392
    end
393
	if directionBit == 0 then
394
		turnRight()
395
		turnRight()
396
	else
397
		turnRight()
398
	end
399
    return true
400
end
401
local function doCuboid(height)
402
	for p=1,height-1 do
403
		if not doLayer(DIAMETER) then
404-
			print ("layerChangeOp return false. doCuboid aborting!")
404+
405
			return false
406
		end
407
		if not layerChangeOp() then
408
			print ("layerChangeOp returned false. doCuboid aborting!")
409
			return false
410
		end
411
	end
412
	if not doLayer(DIAMETER) then
413
		print ("doLayer returned false. doCuboid aborting!")
414
		return false
415
	end
416
end
417
goTo(0, ZONE_DEPTH-1, 0, 0, 1)
418
doCuboid(ZONE_DEPTH)