View difference between Paste ID: 28Tdz3QE and PhgnMmRk
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-
	print("ZONE_DEPTH set")
18+
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-
		print("target slot was false: "..targetSlot)
267+
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-
    if not seekAndPlaceBlock() then
306+
307
    turtle.select(1)
308-
        --I explicitly REFUSE to handle the case where targetBlock cannot be placed at this point
308+
309-
        --...unless of course I screw up with returnSupplies
309+
310-
        if not seekAndPlaceBlock() then
310+
311-
            print("could not place ".. CONFIG_targetBlock..". Is something in the way or did I break?")
311+
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
    --Place targetBlock below
335
	if not seekAndPlaceBlock() then
336
        print("could not place ".. CONFIG_targetBlock..". Is something in the way or did I break?")
337
    end
338
    turtle.select(1)
339
    return true
340
end
341
local function turnAround(turnDirection)
342
    if turnDirection == 0 then
343
        turnLeft()
344
        if not forwardOp() then
345
            print ("turnAround aborting!")
346
            return false
347
        end
348
        turnLeft()
349
    elseif turnDirection == 1 then
350
        turnRight()
351
        if not forwardOp() then
352
            print ("turnAround aborting!")
353
            return false
354
        end
355
        turnRight()
356
    else
357
        turnRight()
358
        if not forwardOp() then
359
            print ("turnAround aborting!")
360
            return false
361
        end
362
        turnRight()
363
    end
364
    return true
365
end
366
local function doRow(length)
367
    for m=1,length-1 do --first row gets done by turnaround
368
        if not forwardOp() then
369
            print ("doRow aborting!")
370
            return false
371
        end
372
    end
373
    return true
374
end
375
local function doLayer(width)--handles doRow and turnAround calls. Three-dimensional pathing calls are handled by doCuboid
376
    --don't forget to place a block on the first spot, not just after each forwardOp
377
	if not seekAndPlaceBlock() then
378
        print("could not place ".. CONFIG_targetBlock..". Is something in the way or did I break?")
379
    end
380
    turtle.select(1)
381
	for n=1,width-1 do
382-
    for n=1,width-1 do
382+
383
            print ("doLayer aborting!")
384
            return false
385
        end
386
        if not turnAround(math.fmod(n,2)) then
387
            print ("doLayer aborting!")
388
            return false
389
        end
390
    end
391
    if not doRow(DIAMETER) then
392
        print ("doLayer aborting!")
393
        return false
394
    end
395
    return true
396
end
397
local function doCuboid(height)
398
	for p=1,height-1 do
399
		if not doLayer(DIAMETER) then
400
			print ("doLayer returned false. doCuboid aborting!")
401
			return false
402
		end
403
		if not layerChangeOp() then
404
			print ("layerChangeOp return false. doCuboid aborting!")
405
			return false
406
		end
407
		turnRight()
408
	end
409
	if not doLayer(DIAMETER) then
410-
	if not doLayer() then
410+
411
		return false
412
	end
413
end
414
goTo(0, ZONE_DEPTH-1, 0, 0, 1)
415-
goTo(0, 0, 0, 0, ZONE_DEPTH-1)
415+