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