Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- --[[TO DO:
- Version 3.0.3
- Recent Changes:
- Everything has been drastically updated. Now mines three at a time...
- ]]
- --[[Things that might get done in the future:
- 1. Go around bedrock? Idea: If encounters bedrock, go up three and set y to yPos + 1, if on last run, then just
- goto(0,1,1,2); detection would be if cannot dig more than 20 times
- 2. Fuel Usage Check. Make a more advanced algorithm (Evan is working on it)
- 3. Maybe send basic commands from receiver program
- ]]
- --Defining things
- --Defaults for Arguments
- local tArgs = {...}
- --Arguments assignable by text
- local x,y,z = 3,3,3 --These are just in case tonumber fails
- local inverted = false --False goes from top down, true goes from bottom up [Default false
- local dropSide = "front" --Side it will eject to when full or done [Default "front"]
- local rednetEnabled = false --Default rednet on or off
- --Arguments assignable by tArgs
- local careAboutResources = true --Will not stop mining once inventory full if false [Default true]
- local doCheckFuel = true --Perform fuel check [Default true]
- local doRefuel = false --Whenever it comes to start location will attempt to refuel from inventory [Default false]
- local invCheckFreq = 10 --Will check for inventory full every <-- moved spaces [Default 10]
- local keepOpen = 1 --How many slots it will attempt to keep open at all times [Default 1]
- --Standard rednet channels
- local channels = {
- send = os.getComputerID() ,
- receive = 10 ,
- confirm = "Confirm"
- }
- local supportsRednet
- do
- local a = peripheral.wrap("right")
- supportsRednet = (a ~= nil)
- end
- local help = {[[-ToDo: Write stuff here about all the different functions-]], [[Second Page]]}
- --You don't care about these
- local xPos,yPos,zPos,facing,percent,mined,moved,relxPos, rowCheck, connected, isInPath
- = 0, 1, 1, 0, 0, 0, 0, 1, "right", false, true
- local totals = {cobble = 0, fuel = 0, other = 0} -- Total for display (cannot go inside function)
- function count() --Done any time inventory dropped and at end
- slot = {} --1: Cobble 2: Fuel 3:Other
- for i=1, 16 do --[1] is type, [2] is number
- slot[i] = {}
- slot[i][2] = turtle.getItemCount(i)
- end
- slot[1][1] = 1 -- = Assumes Cobble/Main
- for i=1, 16 do --Cobble Check
- turtle.select(i)
- if turtle.compareTo(1) then
- slot[i][1] = 1
- totals.cobble = totals.cobble + slot[i][2]
- elseif turtle.refuel(0) then
- slot[i][1] = 2
- totals.fuel = totals.fuel + slot[i][2]
- else
- slot[i][1] = 3
- totals.other = totals.other + slot[i][2]
- end
- end
- turtle.select(1)
- end
- local function checkFuel()
- return turtle.getFuelLevel()
- end
- local function isFull(slots)
- slots = slots or 16
- local numUsed = 0
- sleep(0.5)
- for i=1, slots do
- if turtle.getItemCount(i) > 0 then numUsed = numUsed + 1 end
- end
- if numUsed >= slots then return true end
- return false
- end
- -----------------------------------------------------------------
- --Input Phase
- local function screen(xPos,yPos)
- term.setCursorPos(xPos,yPos); term.clear(); end
- local function screenLine(xPos,yPos)
- term.setCursorPos(xPos,yPos); term.clearLine(); end
- screen(1,1)
- print("----- Welcome to Quarry! -----")
- print("")
- local sides = {top = "top", right = "right", left = "left", bottom = "bottom", front = "front"} --Used to whitelist sides
- local errorT = {num = "Numbers not recognized", zero = "Variable is out of range" }
- local changedT = {}
- changedT.new = function(key, value) changedT[#changedT+1] = {[key] = value} end
- changedT.getPair = function(i) for a, b in pairs(changedT[i]) do return a, b end end
- local function capitalize(text) return (string.upper(string.sub(text,1,1))..string.sub(text,2,-1)) end
- local function assert(condition, message, section) section = section or "[Blank]"; if condition then return condition else error("Error: "..message.."\nin section "..section, 0) end end
- local function checkNum(number, section) return assert(tonumber(number),errorT.num, section) end
- tArgs.checkStart = function(num) tArgs[tArgs[num]] = num end
- --tArgs.checkStart = function(num) tArgs.t[tArgs[num]] = {num, tArgs.t[num]} end --If you think this is needed
- for i=1, #tArgs do tArgs.checkStart(i) end
- --All the different arguments
- if tArgs["-?"] or tArgs["help"] then
- for i=1, #help do print(help[i]) end --Expand on this to include multiple pages
- error("",0)
- end
- if not tArgs["-DEFAULT-"] then
- local section = "Dimensions"
- --Dimesnions
- if tArgs["-dim"] then local num = tArgs["-dim"];
- x = checkNum(tArgs[num + 1],section); z = checkNum(tArgs[num + 2],section); y = checkNum(tArgs[num + 3],section)
- else
- print("What dimensions?")
- print("")
- --This will protect from negatives, letters, and decimals
- term.write("Length: ")
- x = math.floor(math.abs(tonumber(io.read()) or x))
- term.write("Width: ")
- z = math.floor(math.abs(tonumber(io.read()) or z))
- term.write("Height: ")
- y = math.floor(math.abs(tonumber(io.read()) or y))
- end
- changedT.new("x",x); changedT.new("z",z); changedT.new("y",y)
- assert(x~=0, errorT.zero, section); assert(z~=0, errorT.zero, section); assert(y~=0, errorT.zero, section)
- assert(not(x == 1 and y == 1 and z == 1) ,"1, 1, 1 dosen't work well at all, try again", section)
- if not tArgs["-vanilla"] then
- --Invert
- if tArgs["-invert"] then
- inverted = (string.lower(string.sub(tArgs[tArgs["-invert"]+1] or "",1,1)) == "t") else
- term.write("Inverted? ")
- inverted = (string.lower(string.sub(io.read(),1,1)) == "y")
- end
- changedT.new("Inverted", inverted)
- --Rednet
- if supportsRednet then
- if tArgs["-rednet"] then rednetEnabled = true
- else term.write("Rednet? "); rednetEnabled = (string.lower(string.sub(io.read(),1,1)) == "y") end
- changedT.new("Rednet Enabled", rednetEnabled)
- if tArgs["-sendChannel"] then
- channels.send = assert(tonumber(tArgs[tArgs["-sendChannel"]+1]), errorT.num)
- assert(channels.send > 0 and channels.send < 65535, errorT.zero)
- changedT.new("Send Channel",channels.send) end
- if tArgs["-receiveChannel"] then
- channels.receive = assert(tonumber(tArgs[tArgs["-receiveChannel"]+1]), errorT.num)
- assert(channels.receive > 0 and channels.receive < 65535 and channels.receive ~= channels.send, errorT.zero)
- changedT.new("Receive Channel",channels.receive) end
- end
- --Fuel
- if tArgs["-doRefuel"] then doRefuel = not doRefuel; changedT.new("Do Refuel",doRefuel) end
- if tArgs["-checkFuel"] then doCheckFuel = not doCheckFuel; changedT.new("Do Check Fuel", doCheckFuel) end
- if tArgs["-chest"] then
- dropSide = sides[tArgs[tArgs["-chest"]+1]] or dropSide; changedT.new("Chest Side",dropSide) end
- --Misc
- if tArgs["-invCheckFreq"] then
- invCheckFreq = math.abs(math.floor(checkNum(tArgs[tArgs["-invCheckFreq"]+1],"Inventory Check Frequency")))
- changedT.new("Inventory Check Frequency",invCheckFreq) end
- assert(invCheckFreq ~= 0, errorT.zero, "Inventory Check Frequency")
- if tArgs["-openSlots"] then
- keepOpen = math.abs(math.floor(checkNum(tArgs[tArgs["-openSlots"]+1],"Open Slots")))
- changedT.new("Slots to keep open", keepOpen) end
- assert(keepOpen ~= 0 and keepOpen < 16, errorT.zer, "Open Slots")if tArgs["-ignoreResources"] then careAboutResources = false end
- end; end
- local area = x*z
- local volume = x*y*z
- local lastHeight = y%3
- local dispY = y
- y = math.floor(y/3)*3
- local moveVolume = (area*(y/3 + math.ceil(lastHeight/2)))
- --Getting Fuel
- if doCheckFuel then --Calculating Needed Fuel
- local neededFuel = moveVolume
- if neededFuel < 100 then
- neededFuel = 100 else neededFuel = neededFuel * 2 --Placeholder algorithm until Evan is done
- end
- if checkFuel() < neededFuel then
- screen(1,1)
- print("More Fuel Needed")
- print("Current Fuel: ",checkFuel()," Needed: ",neededFuel)
- print("Place fuel in Bottom Right, press any key")
- os.pullEvent("char")
- turtle.select(16)
- while checkFuel() < neededFuel do
- if not turtle.refuel(1) then
- term.clearLine()
- print("Still too little fuel")
- term.clearLine()
- print("Press a key to resume fueling")
- os.pullEvent("char")
- end
- local x,y = term.getCursorPos()
- print(checkFuel().." Fuel")
- term.setCursorPos(x,y)
- end
- print(checkFuel().." Units of Fuel")
- sleep(3)
- turtle.select(1)
- end
- end
- --Initial Rednet Handshake
- if rednetEnabled then
- screen(1,1)
- print("Rednet is Enabled")
- print("The Channel to open is "..channels.send)
- modem = peripheral.wrap("right")
- modem.open(channels.receive)
- local i = 0
- repeat
- local id = os.startTimer(3)
- i=i+1
- print("Sending Initial Message "..i)
- modem.transmit(channels.send, channels.receive, "{ 'Initial' }")
- local message
- repeat
- local event, idCheck, channel,_,locMessage, distance = os.pullEvent()
- message = locMessage
- until (event == "timer" and idCheck == id) or (event == "modem_message" and channel == channels.receive and message == channels.confirm)
- until message == channels.confirm
- connected = true
- print("Connection Confirmed!")
- sleep(1.5)
- end
- local function biometrics(sendChannel, message)
- local commands = { Confirm = "Confirm" }
- local toSend = { ["x"] = x, ["y"] = (y/3 + math.ceil(lastHeight/2)),
- ["z"] = z, --The y calc is weird...
- ["xPos"] = xPos, ["yPos"] = yPos, ["zPos"] = zPos,
- ["percent"] = percent, ["mined" ]= mined,
- ["fuel"] = checkFuel(), ["moved"] = moved,
- ["remainingBlocks"] = (volume-mined), ["ID"] = os.getComputerID(),
- ["isInPath"] = isInPath, --Whether it is going back to start
- ["volume"] = volume, ["area"] = area}
- modem.transmit(channels.send, channels.receive, textutils.serialize(toSend))
- id = os.startTimer(0.1)
- local event
- repeat
- local locEvent, idCheck, confirm, _, locMessage, distance = os.pullEvent()
- event, message = locEvent, locMessage
- until (event == "timer" and idCheck == id) or (event == "modem_message" and confirm == channels.receive)
- if event == "modem_message" and commands[message] then connected = true else connected = false end
- --Stuff to do for different commands
- end
- --Showing changes to settings
- screen(1,1)
- print("Your selected settings:")
- if #changedT == 0 then
- print("Completely Default")
- else
- for i=1, #changedT do
- local title, value = changedT.getPair(i)
- print(capitalize(title)..": ",value)
- end
- end
- print("\nStarting in 3"); sleep(1); print("2"); sleep(1); print("1"); sleep(1.5)
- ----------------------------------------------------------------
- --Mining Phase
- local function updateDisplay() --Runs in Mine(), display information to the screen in a certain place
- screen(1,1)
- print("Blocks Mined")
- print(mined)
- print("Percent Complete")
- print(percent.."%")
- if rednetEnabled then
- screenLine(1,6)
- print("Connected: "..tostring(connected))
- end
- end
- local function mine(digDown, digUp, outOfPath,doCheckInv) -- Basic Move Forward
- if doCheckInv == nil then doCheckInv = true end
- if digDown == nil then digDown = true end
- if digUp == nil then digUp = true end
- while not turtle.forward() do
- if turtle.dig() then mined = mined + 1; else turtle.attack(); end
- end
- if digUp then
- while turtle.detectUp() do if turtle.digUp() then mined = mined + 1; end end
- end
- if digDown then
- if turtle.digDown() then mined = mined + 1; end
- end
- if outOfPath then isInPath = false; else isInPath = true; moved = moved + 1; end
- if facing == 0 then xPos = xPos +1
- elseif facing == 2 then xPos = xPos-1
- elseif facing == 1 then zPos = zPos+1
- elseif facing == 3 then zPos = zPos-1; end
- if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end --Maybe adjust this for out of path
- percent = math.ceil(moved/moveVolume*100)
- updateDisplay()
- local whereGoing
- if doCheckInv and careAboutResources then
- if moved%invCheckFreq == 0 then
- if isFull(16-keepOpen) then dropOff() end
- end; end
- if rednetEnabled then biometrics() end
- end
- --Direction: Front = 0, Right = 1, Back = 2, Left = 3
- local function facingF(num)
- facing = facing + num
- if facing > 3 then facing = 0 end
- if facing < 0 then facing = 3 end
- end
- if up then local temp1 = up end --Just in case another program uses this
- if down then local temp2 = down end
- function up(num, sneak)
- num = num or 1
- sneak = sneak or 1
- if inverted and sneak == 1 then
- down(num, -1)
- else
- for i=1, num do while not turtle.up() do
- while not turtle.digUp() do
- turtle.attackUp(); sleep(0.5); end
- mined = mined + 1
- end; yPos = yPos - sneak; end
- end
- end
- function down(num, sneak)
- num = num or 1
- sneak = sneak or 1
- if inverted and sneak == 1 then
- up(num, -1)
- else
- for i=1, num do while not turtle.down() do
- while not turtle.digDown() do
- turtle.attackDown(); sleep(0.5); end
- mined = mined+1
- end; yPos = yPos + sneak; end
- end
- end
- local function right(num)
- num = num or 1
- for i=1, num do turtle.turnRight(); facingF(1); end
- end
- local function left(num)
- num = num or 1
- for i=1, num do turtle.turnLeft(); facingF(-1) end
- end
- local function goto(x,z,y, toFace)
- x = x or 1; y = y or 1; z = z or 1; toFace = toFace or facing
- if yPos > y then while yPos~=y do up() end end
- if zPos > z then
- while facing ~= 3 do left() end
- elseif zPos < z then while facing ~= 1 do left() end
- end
- while zPos ~= z do mine(false,false,true,false) end
- if xPos> x then
- while facing ~= 2 do left() end
- elseif xPos < x then while facing ~= 0 do left() end
- end
- while xPos ~= x do mine(false,false,true,false) end
- if yPos < y then while yPos~=y do down() end end
- while facing ~= toFace do right() end
- end
- local function turnTo(num)
- num = num or 1; goto(xPos,zPos,yPos,num)
- end
- local function drop(side, final, allowSkip)
- side = sides[side] or "front" --The final number means that it will
- if final then final = 0 else final = 1 end --drop a whole stack at the end
- local allowSkip = allowSkip or (final == 0) --This will allow drop(side,t/f, rednetConnected)
- count()
- if doRefuel then
- for i=1, 16 do
- if slot[i][1] == 2 then
- turtle.select(i); turtle.refuel()
- end; end; end
- if side == "right" then turnTo(1) end
- if side == "left" then turnTo(3) end
- local whereDetect, whereDrop
- local _1 = tostring(slot[1][2] - final)
- if side == "top" then
- whereDetect = "turtle.detectUp()" ; whereDrop1 = "turtle.dropUp(".._1..")"; whereDropAll = "turtle.dropUp()"
- elseif side == "bottom" then
- whereDetect = "turtle.detectDown()" ; whereDrop1 = "turtle.dropDown(".._1..")"; whereDropAll = "turtle.dropDown()"
- else
- whereDetect = "turtle.detect()" ; whereDrop1 = "turtle.drop(".._1..")"; whereDropAll = "turtle.drop()" end
- repeat
- local detected = loadstring("return "..whereDetect)()
- if detected then
- assert(loadstring("if "..whereDetect.." then "
- ..whereDrop1..[[
- for i=2, 16 do
- if turtle.getItemCount(i) > 0 then turtle.select(i); ]]..whereDropAll.." end end end"))()
- elseif not allowSkip then
- print("Waiting for chest placement, press a key to continue")
- os.pullEvent("char")
- end
- until detected or allowSkip
- if not allowSkip then totals.cobble = totals.cobble - 1 end
- turtle.select(1)
- turnTo(0)
- end
- function dropOff() --Not local because called in mine()
- local currX,currZ,currY,currFacing = xPos, zPos, yPos, facing
- goto(0,1,1,2)
- drop(dropSide,false)
- goto(currX,currZ,currY,currFacing)
- end
- -------------------------------------------------------------------------------------
- local doDigDown, doDigUp
- if not inverted then doDigDown , doDigUp = (lastHeight ~= 1), false
- else doDigUp, doDigDown = (lastHeight ~= 1) , false; end --Used in lastHeight
- a=1
- mine(false,false, true)
- if y ~= 0 then down() end
- --Mining Loops
- turtle.select(1)
- while a <= y do -------------Height---------
- moved = moved + 1
- rowCheck = "right" --At the end of this row it will turn right
- if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end
- while zPos <= z do -------------Width----------
- while relxPos < x do ------------Length---------
- mine()
- end ---------------Length End-------
- if zPos ~= z then
- if rowCheck == "right" and zPos ~= z then --Swithcing to next row
- rowCheck = "left"; right(); mine(); right()
- else
- rowCheck = "right"; left(); mine(); left()
- end
- else break
- end
- end ---------------Width End--------
- goto(1,1,yPos,0)
- if yPos+1 ~= y then down(3) end
- a=a+3; end ---------------Height End-------
- if lastHeight ~= 0 then ---------LAST ROW--------- (copied from above)
- moved = moved + 1
- if y ~= 0 then down(2) end
- rowCheck = "right"
- if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end
- while zPos <= z do -------------Width----------
- while relxPos < x do ------------Length---------
- mine(doDigDown, doDigUp)
- end ---------------Length End-------
- if zPos ~= z then
- if rowCheck == "right" and zPos ~= z then --Swithcing to next row
- rowCheck = "left"; right(); mine(doDigDown, doDigUp); right()
- else
- rowCheck = "right"; left(); mine(doDigDown, doDigUp); left()
- end
- else break
- end
- end ---------------Width End--------
- goto(1,1,yPos,0)
- end
- if not inverted then
- if doDigDown then if turtle.digDown() then mined = mined + 1 end end
- else
- if doDigUp then if turtle.digUp() then mined = mined + 1 end end
- end
- goto(0,1,1,2)
- --Output to a chest or sit there
- drop(dropSide, true)
- --Display
- screen(1,1)
- print("Total Blocks Mined: "..mined)
- print("Current Fuel Level: "..turtle.getFuelLevel())
- print("Cobble: "..totals.cobble)
- print("Usable Fuel: "..totals.fuel)
- print("Other: "..totals.other)
- if rednetEnabled then
- print("")
- print("Sent Stop Message")
- finalTable = {{["Mined: "] = mined}, {["Cobble: "] = totals.cobble}, {["Fuel: "] = totals.fuel},
- {["Other: "] = totals.other}, {["Fuel: "] = checkFuel()} }
- modem.transmit(channels.send,channels.receive,"stop")
- modem.transmit(channels.send,channels.receive,textutils.serialize(finalTable))
- modem.close(channels.receive)
- end
- --The only global variables I had to use
- if temp1 then up = temp1 end
- if temp2 then down = temp2 end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement