Advertisement
civilwargeeky

Quarry 3.4.1

Feb 21st, 2014
682
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 49.87 KB | None | 0 0
  1. --[[
  2. Version 3.4.1
  3. Recent Changes:
  4.   Bedrock check only runs if there is a block in the way
  5.   Added New Rednet Support
  6.   Rednet messages work better
  7.   New Arguments!
  8.     -atChest [force] Using this with -resume will tell the turtle that it is at its chest, and needs to go back to where it was
  9.     -maxTries [number 1-9000] This is the number of times the turtle will try to mine something before it checks for bedrock
  10.   Arguments are no longer ignored if you use "-default", you just won't be prompted for anything.
  11.   Boolean (t/f) arguments now accept "yes" as well as "true"
  12. ]]
  13. --Defining things
  14. civilTable = nil; _G.civilTable = {}; setmetatable(civilTable, {__index = _G}); setfenv(1,civilTable)
  15. -------Defaults for Arguments----------
  16. --Arguments assignable by text
  17. x,y,z = 3,3,3 --These are just in case tonumber fails
  18. inverted = false --False goes from top down, true goes from bottom up [Default false]
  19. rednetEnabled = false --Default rednet on or off  [Default false]
  20. --Arguments assignable by tArgs
  21. dropSide = "front" --Side it will eject to when full or done [Default "front"]
  22. careAboutResources = true --Will not stop mining once inventory full if false [Default true]
  23. doCheckFuel = true --Perform fuel check [Default true]
  24. doRefuel = false --Whenever it comes to start location will attempt to refuel from inventory [Default false]
  25. invCheckFreq = 10 --Will check for inventory full every <-- moved spaces [Default 10]
  26. keepOpen = 1 --How many inventory slots it will attempt to keep open at all times [Default 1]
  27. fuelSafety = "moderate" --How much fuel it will ask for: safe, moderate, and loose [Default moderate]
  28. saveFile = "Civil_Quarry_Restore" --Where it saves restore data [Default "Civil_Quarry_Restore"]
  29. doBackup = true --If it will keep backups for session persistence [Default true]
  30. numberOfStacksPerRun = 8 --How many stacks (number of items) the turtle expects (on average) to have before it must dump off. Not in arguments. [Default 8]
  31. maxTries = 50 --How many times turtle will try to dig a block before it "counts" bedrock [Default 50]
  32. gpsEnabled = false -- If option is enabled, will attempt to find position via GPS api [Default false]
  33. gpsTimeout = 3 --The number of seconds the program will wait to get GPS coords. Not in arguments [Default 3]
  34. logging = true --Whether or not the turtle will log mining runs. [Default ...still deciding]
  35. logFolder = "Quarry_Logs" --What folder the turtle will store logs in [Default "Quarry_Logs"]
  36. logExtension = "" --The extension of the file (e.g. ".txt") [Default ""]
  37. startDown = 0 --How many blocks to start down from the top of the mine [Default 0]
  38. enderChestEnabled = false --Whether or not to use an ender chest [Default false]
  39. enderChestSlot = 16 --What slot to put the ender chest in [Default 16]
  40. --Standard number slots for fuel (you shouldn't care)
  41. fuelTable = { --Will add in this amount of fuel to requirement.
  42. safe = 1000,
  43. moderate = 200,
  44. loose = 0 } --Default 1000, 200, 0
  45. --Standard rednet channels
  46. channels = {
  47. send = os.getComputerID() + 1  ,
  48. receive = os.getComputerID() + 101 ,
  49. confirm = "Turtle Quarry Receiver",
  50. message = "Civil's Quarry",
  51. }
  52.  
  53. local help_paragraph = [[
  54. Welcome!: Welcome to quarry help. Below are help entries for all parameters. Examples and tips are at the bottom.
  55. -Default: This will force no prompts. If you use this and nothing else, only defaults will be used.
  56. -dim: [length] [width] [height] This sets the dimensions for the quarry
  57. -invert: [t/f] If true, quarry will be inverted (go up instead of down)
  58. -rednet: [t/f] If true and you have a wireless modem on the turtle, will attempt to make a rednet connection for sending important information to a screen
  59. -restore / -resume: If your quarry stopped in the middle of its run, use this to resume at the point where the turtle was. Not guarenteed to work properly. For more accurate location finding, check out the -GPS parameter
  60. -atChest: [force] This is for use with "-restore," this will tell the restarting turtle that it is at its home chest, so that if it had gotten lost, it now knows where it is.
  61. -doRefuel: [t/f] If true, the turtle will refuel itself with coal and planks it finds on its mining run
  62. -doCheckFuel: [t/f] If you for some reason don't want the program to check fuel usage, set to false. This is honestly a hold-over from when the refueling algorithm was awful...
  63. -chest: [side] This specifies what side the chest at the end will be on. You can say "top", "bottom", "front", "left", or "right"
  64. -enderChest: This one is special. If you use "-enderChest true" then it will use an enderChest in the default slot. However, you can also do "-enderChest [slot]" then it will take the ender chest from whatever slot you tell it to. Like 7... or 14... or whatever.
  65. -GPS: [force] If you use "-GPS" and there is a GPS network, then the turtle will record its first two positions to precisly calculate its position if it has to restart. This will only take two GPS readings
  66. -sendChannel: [number] This is what channel your turtle will send rednet messages on
  67. -receiveChannel: [number] This is what channel your turtle will receive rednet messages on
  68. -startY: [current Y coord] Randomly encountering bedrock? This is the parameter for you! Just give it what y coordinate you are at right now. If it is not within bedrock range, it will never say it found bedrock
  69. -maxTries: [number] This is the number of times the turtle will try to dig before deciding its run into bedrock.
  70. -logging: [t/f] If true, will record information about its mining run in a folder at the end of the mining run
  71. -doBackup: [t/f] If false, will not back up important information and cannot restore, but will not make an annoying file (Actually I don't really know why anyone would use this...)
  72. -saveFile: [word] This is what the backup file will be called
  73. -logFolder: [word] The folder that quarry logs will be stored in
  74. -logExtension: [word] The extension given to each quarry log (e.g. ".txt" or ".notepad" or whatever)
  75. -invCheckFreq: [number] This is how often the turtle will check if it has the proper amount of slots open
  76. -keepOpen: [number] This is the number of the slots the turtle will make sure are open. It will check every invCheckFreq blocks
  77. -careAboutResources: [t/f] Who cares about the materials! If set to false, it will just keep mining when its inventory is full
  78. -startDown: [number] If you set this, the turtle will go down this many blocks from the start before starting its quarry
  79.   =
  80.   C _ |
  81.       |
  82.       |
  83.       |
  84.       |_ _ _ _ >
  85. -manualPos: [xPos] [zPos] [yPos] [facing] This is for advanced use. If the server reset when the turtle was in the middle of a 100x100x100 quarry, fear not, you can now manually set the position of the turtle. yPos is always positive. The turtle's starting position is 0, 1, 1, 0. Facing is measured 0 - 3. 0 is forward, and it progresses clockwise. Example- "-manualPos 65 30 30 2"
  86. -help: Thats what this is :D
  87. Examples: Everything below is examples and tips for use
  88. Important Note:
  89.  None of the above parameters are necessary. They all have default values, and the above are just if you want to change them.
  90. Examples [1]:
  91.  Want to just start a quarry from the interface, without going through menus? It's easy! Just use some parameters. Assume you called the program "quarry." To start a 10x6x3 quarry, you just type in "quarry -dim 10 6 3 -default".
  92.   You just told it to start a quarry with dimensions 10x6x3, and "-default" means it won't prompt you about invert or rednet. Wasn't that easy?
  93. Examples [2]:
  94.   Okay, so you've got the basics of this now, so if you want, you can type in really long strings of stuff to make the quarry do exactly what you want. Now, say you want a 40x20x9, but you want it to go down to diamond level, and you're on the surface (at y = 64). You also want it to send rednet messages to your computer so you can see how its doing.
  95. Examples [2] [cont.]:
  96.   Oh yeah! You also want it to use an ender chest in slot 12 and restart if the server crashes. Yeah, you can do that. You would type
  97.   "quarry -dim 40x20x9 -invert false -startDown 45 -rednet true -enderChest 12 -restore"
  98.   BAM. Now you can just let that turtle do it's thing
  99. Tips:
  100.  The order of the parameters doesn't matter. "quarry -invert false -rednet true" is the same as "quarry -rednet true -invert false"
  101.  
  102.   Capitalization doesn't matter. "quarry -iNVErt FALSe" does the same thing as "quarry -invert false"
  103. Tips [cont.]:
  104.  For [t/f] parameters, you can also use "yes" and "no" so "quarry -invert yes"
  105.  
  106.  For [t/f] parameters, it only cares about the first letter. So you can use "quarry -invert t" or "quarry -invert y"
  107. Tips [cont.]:
  108.  If you are playing with fuel turned off, the program will automatically change settings for you so you don't have to :D
  109.  
  110.   If you want, you can load this program onto a computer, and use "quarry -help" so you can have help with the parameters whenever you want.
  111. Internal Config:
  112.   At the top of this program is an internal configuration file. If there is some setup that you use all the time, you can just change the config value at the top and run "quarry -default" for a quick setup.
  113.  
  114.   You can also use this if there are settings that you don't like the default value of.
  115. ]]
  116.  
  117. --Parsing help for display
  118. --[[The way the help table works:
  119. All help indexes are numbered. There is a help[i].title that contains the title,
  120. and the other lines are in help[i][1] - help[i][#help[i] ]
  121. Different lines (e.g. other than first) start with a space.
  122. As of now, the words are not wrapped, fix that later]]
  123. local help = {}
  124. local i = 0
  125. local titlePattern = ".-%:" --Find the beginning of the line, then characters, then a ":"
  126. local textPattern = "%:.+" --Find a ":", then characters until the end of the line
  127. for a in help_paragraph:gmatch("\n?.-\n") do --Matches in between newlines
  128. local current = string.sub(a,1,-2).."" --Concatenate Trick
  129. if string.sub(current,1,1) ~= " " then
  130. i = i + 1
  131. help[i] = {}
  132. help[i].title = string.sub(string.match(current, titlePattern),1,-2)..""
  133. help[i][1] = string.sub(string.match(current,textPattern) or " ",3,-1)
  134. elseif string.sub(current,1,1) == " " then
  135. table.insert(help[i], string.sub(current,2, -1).."")
  136. end
  137. end
  138.  
  139.  
  140. local supportsRednet = (peripheral.wrap("right") ~= nil)
  141.  
  142. local tArgs = {...}
  143. --You don't care about these
  144.       xPos,yPos,zPos,facing,percent,mined,moved,relxPos, rowCheck, connected, isInPath, layersDone, attacked, startY, chestFull, gotoDest, atChest
  145.     = 0,   1,   1,   0,     0,      0,    0,    1,       "right",  false,     true,     1,          0,        0,      false,     "",       false
  146.    
  147. local foundBedrock = false
  148.  
  149. local totals = {cobble = 0, fuel = 0, other = 0} -- Total for display (cannot go inside function)
  150. local function count() --Done any time inventory dropped and at end
  151. slot = {}        --1: Cobble 2: Fuel 3:Other
  152. for i=1, 16 do   --[1] is type, [2] is number
  153. slot[i] = {}
  154. slot[i][2] = turtle.getItemCount(i)
  155. end
  156. slot[1][1] = 1   -- = Assumes Cobble/Main
  157. for i=1, 16 do   --Cobble Check
  158. turtle.select(i)
  159. if turtle.compareTo(1)  then
  160. slot[i][1] = 1
  161. totals.cobble = totals.cobble + slot[i][2]
  162. elseif turtle.refuel(0) then
  163. slot[i][1] = 2
  164. totals.fuel = totals.fuel + slot[i][2]
  165. else
  166. slot[i][1] = 3
  167. totals.other = totals.other + slot[i][2]
  168. end
  169. end
  170. turtle.select(1)
  171. end
  172.  
  173. local getFuel, checkFuel
  174. if turtle then
  175.   getFuel = turtle.getFuelLevel  --This is for cleanup at the end
  176.   do --Common variable name...
  177.   local flag = turtle.getFuelLevel() == "unlimited"--Unlimited screws up my calculations
  178.   if flag then --Fuel is disabled
  179.     turtle.getFuelLevel = function() return math.huge end --Infinite Fuel
  180.   end --There is no "else" because it will already return the regular getFuel
  181.   end
  182.   checkFuel = turtle.getFuelLevel --Just an alias for backwards compat
  183. end
  184.  
  185.  -----------------------------------------------------------------
  186. --Input Phase
  187. local function screen(xPos,yPos)
  188. xPos, yPos = xPos or 1, yPos or 1
  189. term.setCursorPos(xPos,yPos); term.clear(); end
  190. local function screenLine(xPos,yPos)
  191. term.setCursorPos(xPos,yPos); term.clearLine(); end
  192.  
  193. screen(1,1)
  194. print("----- Welcome to Quarry! -----")
  195. print("")
  196.  
  197. local sides = {top = "top", right = "right", left = "left", bottom = "bottom", front = "front"} --Used to whitelist sides
  198. local changedT, tArgsWithUpper = {}, {}
  199. changedT.new = function(key, value) table.insert(changedT,{key, value}) end --Numeric list of lists
  200. local function capitalize(text) return (string.upper(string.sub(text,1,1))..string.sub(text,2,-1)) end
  201. for i=1, #tArgs do tArgsWithUpper[i] = tArgs[i]; tArgsWithUpper[tArgsWithUpper[i]] = i; tArgs[i] = tArgs[i]:lower(); tArgs[tArgs[i]] = i end --My signature key-value pair system, now with upper
  202.  
  203. local restoreFound, restoreFoundSwitch = false --Initializing so they are in scope
  204. function addParam(name, displayText, formatString, forcePrompt, trigger, variableOverride) --To anyone that doesn't understand this very well, probably not your best idea to go in here.
  205.   if trigger == nil then trigger = true end --Defaults to being able to run
  206.   if not trigger then return end --This is what the trigger is for. Will not run if trigger not there
  207.   if restoreFoundSwitch or tArgs["-default"] then forcePrompt = false end --Don't want to prompt if these
  208.   local toGetText = name:lower() --Because all params are now lowered
  209.   local formatType = formatString:match("^%a+"):lower() or error("Format String Unknown: "..formatString) --Type of format string
  210.   local args = formatString:sub(({formatString:find(formatType)})[2] + 2).."" --Everything in formatString but the type and space
  211.   local variable = variableOverride or name --Goes first to the override for name
  212.   local func = loadstring("return "..variable)
  213.   setfenv(func,getfenv(1))
  214.   local originalValue = assert(func)() --This is the default value, for checking to add to changed table
  215.   if originalValue == nil then error("From addParam, \""..variable.."\" returned nil",2) end --I may have gotten a wrong variable name
  216.   local givenValue, toRet --Initializing for use
  217.   if tArgs["-"..toGetText] then
  218.     givenValue = tArgsWithUpper[tArgs["-"..toGetText]+1] --This is the value after the desired parameter
  219.   elseif forcePrompt then
  220.     write(displayText.."? ")
  221.     givenValue = io.read()
  222.   end
  223.   if formatType == "force" then --This is the one exception. Should return true if givenValue is nothing
  224.     toRet = (tArgs["-"..toGetText] and true) or false --Will return true if param exists, otherwise false
  225.   end
  226.   if not (givenValue or toRet) then return end --Don't do anything if you aren't given anything. Leave it as default, except for "force"
  227.   if formatType == "boolean" then --All the format strings will be basically be put through a switch statement
  228.     toRet = givenValue:sub(1,1):lower() == "y" or givenValue:sub(1,1):lower() == "t" --Accepts true or yes
  229.     if formatString == "boolean special" then
  230.       toRet = givenValue:sub(1,1):lower() ~= "n" and givenValue:sub(1,1):lower() ~= "f" --Accepts anything but false or no
  231.     end
  232.   elseif formatType == "string" then
  233.     toRet = givenValue:match("^[%w%.]+") --Basically anything not a space or control character etc
  234.   elseif formatType == "number" then
  235.     toRet = tonumber(givenValue) --Note this is a local, not the above so we don't change anything
  236.     if not toRet then return end --We need a number... Otherwise compare errors
  237.     toRet = math.abs(math.floor(toRet)) --Get proper integers
  238.     local startNum, endNum = formatString:match("(%d+)%-(%d+)") --Gets range of numbers
  239.     startNum, endNum = tonumber(startNum), tonumber(endNum)
  240.     if not ((toRet >= startNum) and (toRet <= endNum)) then return end --Can't use these
  241.   elseif formatType == "side" then
  242.     local exclusionTab = {} --Ignore the wizardry here. Just getting arguments without format string
  243.     for a in args:gmatch("%S+") do exclusionTab[a] = true end --This makes a list of the sides to not include
  244.     if not exclusionTab[givenValue] then toRet = sides[givenValue] end --If side is not excluded
  245.   elseif formatType == "list" then
  246.     toRet = {}
  247.     for a in args:gmatch("[^,]") do
  248.       table.insert(toRet,a)
  249.     end
  250.   elseif formatType == "force" then --Do nothing, everything is already done
  251.   else error("Improper formatType",2)
  252.   end
  253.   if toRet == nil then return end --Don't want to set variables to nil... That's bad
  254.   tempParam = toRet --This is what loadstring will see :D
  255.   local func = loadstring(variable.." = tempParam")
  256.   setfenv(func, getfenv(1))
  257.   func()
  258.   tempParam = nil --Cleanup of global
  259.   if toRet ~= originalValue then
  260.     changedT.new(displayText, tostring(toRet))
  261.   end
  262.   return toRet
  263. end
  264.  
  265. --Check if it is a turtle
  266. if not(turtle or tArgs["help"] or tArgs["-help"] or tArgs["-?"] or tArgs["?"]) then --If all of these are false then
  267.   print("This is not a turtle, you might be looking for the \"Companion Rednet Program\" \nCheck My forum thread for that")
  268.   print("Press 'q' to quit, or any other key to start help ")
  269.   if ({os.pullEvent("char")})[2] ~= "q" then tArgs.help = true else error("",0) end
  270. end
  271.  
  272. if tArgs["help"] or tArgs["-help"] or tArgs["-?"] or tArgs["?"] then
  273. print("You have selected help, press any key to continue"); print("Use arrow keys to naviate, q to quit"); os.pullEvent("key")
  274. local pos = 1
  275. local key = 0
  276. while pos <= #help and key ~= keys.q do
  277. if pos < 1 then pos = 1 end
  278. screen(1,1)
  279. print(help[pos].title)
  280. for a=1, #help[pos] do print(help[pos][a]) end
  281. repeat
  282. _, key = os.pullEvent("key")
  283. until key == 200 or key == 208 or key == keys.q
  284. if key == 200 then pos = pos - 1 end
  285. if key == 208 then pos = pos + 1 end
  286. end
  287. error("",0)
  288. end
  289.  
  290. --Saving
  291. addParam("doBackup", "Backup Save File", "boolean")
  292. addParam("saveFile", "Save File Name", "string")
  293.  
  294. restoreFound = fs.exists(saveFile)
  295. restoreFoundSwitch = (tArgs["-restore"] or tArgs["-resume"] or tArgs["-atchest"]) and restoreFound
  296. if restoreFoundSwitch then
  297.   local file = fs.open(saveFile,"r")
  298.   local test = file.readAll() ~= ""
  299.   file.close()
  300.   if test then
  301.     os.run(getfenv(1),saveFile)
  302.     if gpsEnabled then --If it had saved gps coordinates
  303.       print("Found GPS Start Coordinates")
  304.       local currLoc = {gps.locate(gpsTimeout)} or {}
  305.       local backupPos = {xPos, yPos, zPos} --This is for comparing to later
  306.       if #currLoc > 0 and #gpsStartPos > 0 and #gpsSecondPos > 0 then --Cover all the different positions I'm using
  307.         print("GPS Position Successfully Read")
  308.         if currLoc[1] == gpsStartPos[1] and currLoc[3] == gpsStartPos[3] then --X coord, y coord, z coord in that order
  309.           xPos, yPos, zPos = 0,1,1
  310.           if facing ~= 0 then turnTo(0) end
  311.           print("Is at start")
  312.         else
  313.           if inverted then --yPos setting
  314.           ------------------------------------------------FIX THIS
  315.           end
  316.           local function copyTable(tab) local toRet = {}; for a, b in pairs(tab) do toRet[a] = b end; return toRet end
  317.           local a, b = copyTable(gpsStartPos), copyTable(gpsSecondPos) --For convenience
  318.           if b[3] - a[3] == -1 then--If went north (-Z)
  319.             a[1] = a[1] - 1 --Shift x one to west to create a "zero"
  320.             xPos, zPos = -currLoc[3] + a[3], currLoc[1] + -a[1]
  321.           elseif b[1] - a[1] == 1 then--If went east (+X)
  322.             a[3] = a[3] - 1 --Shift z up one to north to create a "zero"
  323.             xPos, zPos = currLoc[1] + -a[1], currLoc[3] + -a[3]
  324.           elseif b[3] - a[3] == 1 then--If went south (+Z)
  325.             a[1] = a[1] + 1 --Shift x one to east to create a "zero"
  326.             xPos, zPos = currLoc[3] + a[3], -currLoc[1] + a[3]
  327.           elseif b[1] - a[1] == -1 then--If went west (-X)
  328.             a[3] = a[3] + 1 --Shift z down one to south to create a "zero"
  329.             xPos, zPos = -currLoc[1] + a[1], -currLoc[3] + a[3]
  330.           else
  331.             print("Improper Coordinates")
  332.             print("GPS Locate Failed, Using Standard Methods")        ----Maybe clean this up a bit to use flags instead.
  333.           end  
  334.         end
  335.         print("X Pos: ",xPos)
  336.         print("Y Pos: ",yPos)
  337.         print("Z Pos: ",zPos)
  338.         print("Facing: ",facing)
  339.         for i=1, 3, 2 do --We want 1 and 3, but 2 could be coming back to start.
  340.           if backupPos[i] ~= currLoc[i] then
  341.             events = {} --We want to remove event queue if not in proper place, so won't turn at end of row or things.
  342.           end
  343.         end
  344.       else
  345.         print("GPS Locate Failed, Using Standard Methods")
  346.       end    
  347.     print("Restore File read successfully. Starting in 3"); sleep(3)
  348.     end
  349.   else
  350.     fs.delete(saveFile)
  351.     print("Restore file was empty, sorry, aborting")
  352.     error("",0)
  353.   end
  354. else --If turtle is just starting
  355.   events = {} --This is the event queue :D
  356.   originalFuel = checkFuel() --For use in logging. To see how much fuel is REALLY used
  357. end
  358.  
  359. --Dimensions
  360. if tArgs["-dim"] then local num = tArgs["-dim"];
  361. x = tonumber(tArgs[num + 1]) or x; z = tonumber(tArgs[num + 2]) or z; y = tonumber(tArgs[num + 3]) or y
  362. elseif not (tArgs["-default"] or restoreFoundSwitch) then
  363. print("What dimensions?")
  364. print("")
  365. --This will protect from negatives, letters, and decimals
  366. term.write("Length? ")
  367. x = math.floor(math.abs(tonumber(io.read()) or x))
  368. term.write("Width? ")
  369. z = math.floor(math.abs(tonumber(io.read()) or z))
  370. term.write("Height? ")
  371. y = math.floor(math.abs(tonumber(io.read()) or y))
  372. changedT.new("Length",x); changedT.new("Width",z); changedT.new("Height",y)
  373. end
  374. --Invert
  375. addParam("invert", "Inverted","boolean", true, nil, "inverted")
  376. addParam("startDown","Start Down","number 1-256")
  377. --Inventory
  378. addParam("chest", "Chest Drop Side", "side front", nil, nil, "dropSide")
  379. addParam("enderChest","Ender Chest Enabled","boolean special", nil, nil, "enderChestEnabled") --This will accept anything (including numbers) thats not "f" or "n"
  380. addParam("enderChest", "Ender Chest Slot", "number 1-16", nil, nil, "enderChestSlot") --This will get the number slot if given
  381. --Rednet
  382. addParam("rednet", "Rednet Enabled","boolean",true, supportsRednet, "rednetEnabled")
  383. addParam("gps", "GPS Location Services", "force", nil, (not restoreFoundSwitch) and supportsRednet, "gpsEnabled" ) --Has these triggers so that does not record position if restarted.
  384. if gpsEnabled and not restoreFoundSwitch then
  385.   gpsStartPos = {gps.locate(gpsTimeout)} --Stores position in array
  386.   gpsEnabled = #gpsStartPos > 0 --Checks if location received properly. If not, position is not saved
  387. end
  388. addParam("sendChannel", "Rednet Send Channel", "number 1-65535", false, supportsRednet, "channels.send")
  389. addParam("receiveChannel","Rednet Receive Channel", "number 1-65535", false, supportsRednet, "channels.receive")
  390. --Fuel
  391. addParam("doRefuel", "Refuel from Inventory","boolean", nil, turtle.getFuelLevel() ~= math.huge) --math.huge due to my changes
  392. addParam("doCheckFuel", "Check Fuel", "boolean", nil, turtle.getFuelLevel() ~= math.huge)
  393. --Logging
  394. addParam("logging", "Logging", "boolean")
  395. addParam("logFolder", "Log Folder", "string")
  396. addParam("logExtension","Log Extension", "string")
  397. --Misc
  398. addParam("startY", "Start Y","number 1-256")
  399. addParam("invCheckFreq","Inventory Check Frequency","number 1-342")
  400. addParam("keepOpen", "Slots to Keep Open", "number 1-15")
  401. addParam("careAboutResources", "Care About Resources","boolean")
  402. addParam("maxTries","Tries Before Bedrock", "number 1-9001")
  403. --Manual Position
  404. if tArgs["-manualpos"] then --Gives current coordinates in xPos,zPos,yPos, facing
  405.   local a = tArgs["-manualpos"]
  406.   xPos, zPos, yPos, facing = tonumber(tArgs[a+1]) or xPos, tonumber(tArgs[a+2]) or zPos, tonumber(tArgs[a+3]) or yPos, tonumber(tArgs[a+4]) or facing
  407.   changedT.new("xPos",xPos); changedT.new("zPos",zPos); changedT.new("yPos",yPos); changedT.new("facing",facing)
  408.   restoreFoundSwitch = true --So it doesn't do beginning of quarry behavior
  409. end
  410. if addParam("atChest", "Is at Chest", "force") then --This sets position to 0,1,1, facing forward, and queues the turtle to go back to proper row.
  411.   local neededLayer = math.floor((yPos+1)/3)*3-1 --Make it a proper layer, +- because mining rows are 2, 5, etc.
  412.   if neededLayer > 2 and neededLayer%3 ~= 2 then --If turtle was not on a proper mining layer
  413.     print("Last known pos was not in proper layer, restarting quarry")
  414.     sleep(4)
  415.     neededLayer = 2
  416.   end
  417.   xPos, zPos, yPos, facing, rowCheck, layersDone = 0,1,1, 0, "right", math.ceil(neededLayer/3)
  418.   events = {{"goto",1,1,neededLayer, 0}}
  419. end
  420.  
  421.  
  422. local function saveProgress(extras) --Session persistence
  423. exclusions = { modem = true, }
  424. if doBackup then
  425. local toWrite = ""
  426. for a,b in pairs(getfenv(1)) do
  427.   if not exclusions[a] then
  428.       --print(a ,"   ", b, "   ", type(b)) --Debug
  429.     if type(b) == "string" then b = "\""..b.."\"" end
  430.     if type(b) == "table" then b = textutils.serialize(b) end
  431.     if type(b) ~= "function" then
  432.       toWrite = toWrite..a.." = "..tostring(b).."\n"
  433.     end
  434.   end
  435. end
  436. toWrite = toWrite.."doCheckFuel = false\n" --It has already used fuel, so calculation unnesesary
  437. local file
  438. repeat
  439.   file = fs.open(saveFile,"w")
  440. until file --WHY DOES IT SAY ATTEMPT TO INDEX NIL!!!
  441. file.write(toWrite)
  442. if type(extras) == "table" then
  443.   for a, b in pairs(extras) do
  444.     file.write(a.." = "..tostring(b))
  445.   end
  446. end
  447. file.close()
  448. end
  449. end
  450.  
  451. local area = x*z
  452. local volume = x*y*z
  453. local lastHeight = y%3
  454. layers = math.ceil(y/3)
  455. local yMult = layers --This is basically a smart y/3 for movement
  456. local moveVolume = (area * yMult) --Kept for display percent
  457. --Calculating Needed Fuel--
  458. local exStack = numberOfStacksPerRun --Expected stacks of items before full
  459. neededFuel = yMult * x * z + --This is volume it will run through
  460.       (startDown + y)*(2+1/(64*exStack)) + --This is simplified and includes the y to get up times up and down + how many times it will drop stuff off
  461.       (x+z)*(yMult + 1/(64*exStack))  --Simplified as well: It is getting to start of row plus getting to start of row how many times will drop off stuff
  462.       --Original equation: x*z*y/3 + y * 2 + (x+z) * y/3 + (x + z + y) * (1/64*8)
  463. neededFuel = math.ceil(neededFuel)
  464.  
  465. --Getting Fuel
  466. if doCheckFuel and checkFuel() < neededFuel then
  467. neededFuel = neededFuel + fuelTable[fuelSafety] --For safety
  468.   print("Not enough fuel")
  469.   print("Current: ",checkFuel()," Needed: ",neededFuel)
  470.   print("Starting SmartFuel...")
  471.   sleep(2) --So they can read everything.
  472.   term.clear()
  473.   local oneFuel, neededFuelItems
  474.   local currSlot = 0
  475.   local function output(text, x, y) --For displaying fuel
  476.     local currX, currY = term.getCursorPos()
  477.     term.setCursorPos(x,y)
  478.     term.clearLine()
  479.     term.write(text)
  480.     term.setCursorPos(currX,currY)
  481.     end
  482.   local function roundTo(num, target) --For stacks of fuel
  483.     if num >= target then return target elseif num < 0 then return 0 else return num end
  484.   end
  485.   local function updateScreen()
  486.     output("Welcome to SmartFuel! Now Refueling...", 1,1)
  487.     output("Currently taking fuel from slot "..currSlot,1,2)
  488.     output("Current single fuel: "..tostring(oneFuel or 0),1,3)
  489.     output("Current estimate of needed fuel: ",1,4)
  490.     output("Single Items: "..math.ceil(neededFuelItems or 0),4,5)
  491.     output("Stacks:       "..math.ceil((neededFuelItems or 0) / 64),4,6)
  492.     output("Needed Fuel: "..tostring(neededFuel),1,12)
  493.     output("Current Fuel: "..tostring(checkFuel()),1,13)
  494.   end
  495.   while checkFuel() <= neededFuel do
  496.     currSlot = currSlot + 1
  497.     turtle.select(currSlot)
  498.     updateScreen()
  499.     while turtle.getItemCount(currSlot) == 0 do sleep(1.5) end
  500.     repeat
  501.       local previous = checkFuel()
  502.       turtle.refuel(1)
  503.       oneFuel = checkFuel() - previous
  504.       updateScreen()
  505.     until (oneFuel or 0) > 0 --Not an if to prevent errors if fuel taken out prematurely.
  506.     neededFuelItems = (neededFuel - checkFuel()) / oneFuel
  507.     turtle.refuel(math.ceil(roundTo(neededFuelItems, 64))) --Change because can only think about 64 at once.
  508.     if turtle.getItemCount(roundTo(currSlot + 1, 16)) == 0 then --Resets if no more fuel
  509.       currSlot = 0
  510.     end
  511.     neededFuelItems = (neededFuel - checkFuel()) / oneFuel
  512.   end
  513. end
  514. --Ender Chest Obtaining
  515. if enderChestEnabled then
  516.     if restoreFoundSwitch and turtle.getItemCount(enderChestSlot) == 0 then --If the turtle was stopped while dropping off items.
  517.       turtle.select(enderChestSlot)
  518.       turtle.dig()
  519.       turtle.select(1)
  520.     end
  521.   while turtle.getItemCount(enderChestSlot) ~= 1 do
  522.     screen(1,1)
  523.     print("You have decided to use an Ender Chest!")
  524.     print("Please place one Ender Chest in slot ",enderChestSlot)
  525.     sleep(1)
  526.   end
  527.   print("Ender Chest in slot ",enderChestSlot, " checks out")
  528.   sleep(2)
  529. end
  530. --Initial Rednet Handshake
  531. if rednetEnabled then
  532. screen(1,1)
  533. print("Rednet is Enabled")
  534. print("The Channel to open is "..channels.send)
  535. modem = peripheral.wrap("right")
  536. modem.open(channels.receive)
  537. local i = 0
  538.   repeat
  539.     local id = os.startTimer(3)
  540.     i=i+1
  541.     print("Sending Initial Message "..i)
  542.     modem.transmit(channels.send, channels.receive, channels.message)
  543.     local message
  544.     repeat
  545.       local event, idCheck, channel,_,locMessage, distance = os.pullEvent()
  546.       message = locMessage
  547.     until (event == "timer" and idCheck == id) or (event == "modem_message" and channel == channels.receive and message == channels.confirm)
  548.   until message == channels.confirm
  549. connected = true
  550. print("Connection Confirmed!")
  551. sleep(1.5)
  552. end
  553. function biometrics(isAtBedrock)
  554.   local toSend = { label = os.getComputerLabel() or "No Label", id = os.getComputerID(),
  555.     percent = percent, relxPos = relxPos, zPos = zPos, xPos = xPos, yPos = yPos,
  556.     layersDone = layersDone, x = x, z = z, layers = layers,
  557.     openSlots = getNumOpenSlots(), mined = mined, moved = moved,
  558.     chestFull = chestFull, isAtChest = (xPos == 0 and yPos == 1 and zPos == 1),
  559.     isGoingToNextLayer = (gotoDest == "layerStart"), foundBedrock = foundBedrock,
  560.     fuel = turtle.getFuelLevel(), volume = volume,
  561.     }
  562.   modem.transmit(channels.send, channels.receive, textutils.serialize(toSend))
  563.   id = os.startTimer(0.1)
  564.   local event, message
  565.   repeat
  566.     local locEvent, idCheck, confirm, _, locMessage, distance = os.pullEvent()
  567.     event, message = locEvent, locMessage
  568.   until (event == "timer" and idCheck == id) or (event == "modem_message" and confirm == channels.receive)
  569.   if event == "modem_message" then connected = true else connected = false end
  570.   message = message:lower()
  571.   if message == "stop" then error("Rednet said to stop...",0) end
  572.   if message == "return" then
  573.     endingProcedure()
  574.     error('Rednet said go back to start...',0)
  575.   end
  576.   if message == "drop" then
  577.     dropOff()
  578.   end
  579. end
  580. --Showing changes to settings
  581. screen(1,1)
  582. print("Your selected settings:")
  583. if #changedT == 0 then
  584. print("Completely Default")
  585. else
  586. for i=1, #changedT do
  587. print(changedT[i][1],": ",changedT[i][2]) --Name and Value
  588. end
  589. end
  590. print("\nStarting in 3"); sleep(1); print("2"); sleep(1); print("1"); sleep(1.5) --Dramatic pause at end
  591.  
  592.  
  593.  
  594. ----------------------------------------------------------------
  595. --Define ALL THE FUNCTIONS
  596. function eventAdd(...)
  597.   return table.insert(events,1, {...}) or true
  598. end
  599. function eventGet(pos)
  600.   return events[tonumber(pos) or #events]
  601. end
  602. function eventPop(pos)
  603.   return table.remove(events,tonumber(pos) or #events) or false --This will return value popped, tonumber returns nil if fail, so default to end
  604. end
  605. function eventRun(value, ...)
  606.   local argsList = {...}
  607.   if type(value) == "string" then
  608.     if value:sub(-1) ~= ")" then --So supports both "up()" and "up"
  609.       value = value .. "("
  610.       for a, b in pairs(argsList) do --Appending arguments
  611.         local toAppend
  612.         if type(b) == "table" then toAppend = textutils.serialize(b)
  613.         elseif type(b) == "string" then toAppend = "\""..tostring(b).."\"" --They weren't getting strings around them
  614.         else toAppend = tostring(b) end
  615.         value = value .. (toAppend or "true") .. ", "
  616.       end
  617.       if value:sub(-1) ~= "(" then --If no args, do not want to cut off
  618.         value = value:sub(1,-3)..""
  619.       end
  620.       value = value .. ")"
  621.     end
  622.     --print(value) --Debug
  623.     local func = loadstring(value)
  624.     setfenv(func, getfenv(1))
  625.     return func()
  626.   end
  627. end
  628.      
  629. function runAllEvents()
  630.   while #events > 0 do
  631.     local toRun = eventGet()
  632.     --print(toRun[1]) --Debug
  633.     eventRun(unpack(toRun))
  634.     eventPop()
  635.   end
  636. end
  637.  
  638. function display() --This is just the last screen that displays at the end
  639.   screen(1,1)
  640.   print("Total Blocks Mined: "..mined)
  641.   print("Current Fuel Level: "..turtle.getFuelLevel())
  642.   print("Cobble: "..totals.cobble)
  643.   print("Usable Fuel: "..totals.fuel)
  644.   print("Other: "..totals.other)
  645.   if rednetEnabled then
  646.     print("")
  647.     print("Sent Stop Message")
  648.     local finalTable = {mined = mined, cobble = totals.cobble, fuelblocks = totals.fuel,
  649.         other = totals.other, fuel = checkFuel() }
  650.     modem.transmit(channels.send,channels.receive,"stop")
  651.     sleep(0.5)
  652.     modem.transmit(channels.send,channels.receive,textutils.serialize(finalTable))
  653.     modem.close(channels.receive)
  654.   end
  655.   if doBackup then fs.delete(saveFile) end
  656. end
  657. function updateDisplay() --Runs in Mine(), display information to the screen in a certain place
  658. screen(1,1)
  659. print("Blocks Mined")
  660. print(mined)
  661. print("Percent Complete")
  662. print(percent.."%")
  663. print("Fuel")
  664. print(checkFuel())
  665.   -- screen(1,1)
  666.   -- print("Xpos: ")
  667.   -- print(xPos)
  668.   -- print("RelXPos: ")
  669.   -- print(relxPos)
  670.   -- print("Z Pos: ")
  671.   -- print(zPos)
  672.   -- print("Y pos: ")
  673.   -- print(yPos)
  674. if rednetEnabled then
  675. screenLine(1,7)
  676. print("Connected: "..tostring(connected))
  677. end
  678. end
  679. function logMiningRun(textExtension, extras) --Logging mining runs
  680. if logging then
  681. local number
  682. if not fs.isDir(logFolder) then
  683.   fs.delete(logFolder)
  684.   fs.makeDir(logFolder)
  685.   number = 1
  686. else
  687.   local i = 0
  688.   repeat
  689.     i = i + 1
  690.   until not fs.exists(logFolder.."/Quarry_Log_"..tostring(i)..(textExtension or ""))
  691.   number = i
  692. end
  693. handle = fs.open(logFolder.."/Quarry_Log_"..tostring(number)..(textExtension or ""),"w")
  694. local function write(...)
  695.   for a, b in ipairs({...}) do
  696.     handle.write(tostring(b))
  697.   end
  698.   handle.write("\n")
  699. end
  700. write("Welcome to the Quarry Logs!")
  701. write("Entry Number: ",number)
  702. write("Dimensions (X Z Y): ",x," ",z," ", y)
  703. write("Blocks Mined: ", mined)
  704. write("  Cobble: ", totals.cobble)
  705. write("  Usable Fuel: ", totals.fuel)
  706. write("  Other: ",totals.other)
  707. write("Total Fuel Used: ",  (originalFuel or (neededFuel + checkFuel()))- checkFuel()) --Protect against errors with some precision
  708. write("Expected Fuel Use: ", neededFuel)
  709. handle.close()
  710. end
  711. end
  712. function isFull(slots)
  713.   slots = slots or 16
  714.   local numUsed = 0
  715.   sleep(0)
  716.   for i=1, 16 do
  717.     if turtle.getItemCount(i) > 0 then numUsed = numUsed + 1 end
  718.   end
  719.   if numUsed > slots then
  720.     return true
  721.   end
  722.   return false
  723. end
  724. function dig(doAdd, func)
  725.   doAdd = doAdd or true
  726.   func = func or turtle.dig
  727.   if func() then
  728.     if doAdd then
  729.       mined = mined + 1
  730.     end
  731.     return true
  732.   end
  733.   return false
  734. end
  735. if not inverted then --Regular functions :) I switch definitions for optimizatoin (I thinK)
  736.   function digUp(doAdd)
  737.     return dig(doAdd,turtle.digUp)
  738.   end
  739.   function digDown(doAdd)
  740.     return dig(doAdd,turtle.digDown)
  741.   end
  742. else
  743.   function digDown(doAdd)
  744.     return dig(doAdd,turtle.digUp)
  745.   end
  746.   function digUp(doAdd)
  747.     return dig(doAdd,turtle.digDown)
  748.   end
  749. end
  750. function relativeXCalc()
  751.   if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end
  752. end
  753. function forward(doAdd)
  754.   if doAdd == nil then doAdd = true end
  755.   if turtle.forward() then
  756.     if doAdd then
  757.       moved = moved + 1
  758.     end
  759.     if facing == 0 then
  760.       xPos = xPos + 1
  761.     elseif facing == 1 then
  762.       zPos = zPos + 1
  763.     elseif facing == 2 then
  764.       xPos = xPos - 1
  765.     elseif facing == 3 then
  766.       zPos = zPos - 1
  767.     else
  768.       error("Function forward, facing should be 0 - 3, got "..tostring(facing),2)
  769.     end
  770.     relativeXCalc()
  771.     return true
  772.   end
  773.   return false
  774. end
  775. function up(sneak)
  776.   sneak = sneak or 1
  777.   if inverted and sneak == 1 then
  778.     down(-1)
  779.   else
  780.     while not turtle.up() do --Absolute dig, not relative
  781.       if not dig(true, turtle.digUp) then
  782.         attackUp()
  783.         sleep(0.5)
  784.       end
  785.     end
  786.     yPos = yPos - sneak --Oh! I feel so clever
  787.   end                   --This works because inverted :)
  788.   saveProgress()
  789.   if rednetEnabled then biometrics() end
  790. end
  791. function down(sneak)
  792.   sneak = sneak or 1
  793.   local count = 0
  794.   if inverted and sneak == 1 then
  795.     up(-1)
  796.   else
  797.     while not turtle.down() do
  798.       count = count + 1
  799.       if not dig(true, turtle.digDown) then --This is absolute dig down, not relative
  800.         attackDown()
  801.         sleep(0.2)
  802.       end
  803.       if count > 20 then bedrock() end
  804.     end
  805.     yPos = yPos + sneak
  806.   end
  807.   saveProgress()
  808.   if rednetEnabled then biometrics() end
  809. end
  810. function right(num)
  811.   num = num or 1
  812.   for i=1, num do facing = coterminal(facing+1); saveProgress(); turtle.turnRight() end
  813. end
  814. function left(num)
  815.   num = num or 1
  816.   for i=1, num do facing = coterminal(facing-1); saveProgress(); turtle.turnLeft() end
  817. end
  818. function attack(doAdd, func)
  819.   doAdd = doAdd or true
  820.   func = func or turtle.attack
  821.   if func() then
  822.     if doAdd then
  823.       attacked = attacked + 1
  824.     end
  825.     return true
  826.   end
  827.   return false
  828. end
  829. function attackUp(doAdd)
  830.   if inverted then
  831.     return attack(doAdd, turtle.attackDown)
  832.   else
  833.     return attack(doAdd, turtle.attackUp)
  834.   end
  835. end
  836. function attackDown(doAdd)
  837.   if inverted then
  838.     return attack(doAdd, turtle.attackUp)
  839.   else
  840.     return attack(doAdd, turtle.attackDown)
  841.   end
  842. end
  843.  
  844.  
  845. function mine(doDigDown, doDigUp, outOfPath,doCheckInv) -- Basic Move Forward
  846.   if doCheckInv == nil then doCheckInv = true end
  847.   if doDigDown == nil then doDigDown = true end
  848.   if doDigUp == nil then doDigUp = true end
  849.   if outOfPath == nil then outOfPath = false end
  850.   if inverted then
  851.     doDigUp, doDigDown = doDigDown, doDigUp --Just Switch the two if inverted
  852.   end
  853.   if doRefuel and checkFuel() <= fuelTable[fuelSafety]/2 then
  854.     for i=1, 16 do
  855.     if turtle.getItemCount(i) > 0 then
  856.       turtle.select(i)
  857.       if checkFuel() < 200 + fuelTable[fuelSafety] then
  858.         turtle.refuel()
  859.       end
  860.     end
  861.     end
  862.     turtle.select(1)
  863.   end
  864.   local count = 0
  865.   while not forward(not outOfPath) do
  866.     sleep(0) --Calls coroutine.yield to prevent errors
  867.     count = count + 1
  868.     if not dig() then
  869.       attack()
  870.     end
  871.     if count > 10 then
  872.       attack()
  873.       sleep(0.2)
  874.     end
  875.     if count > maxTries then
  876.       if turtle.getFuelLevel() == 0 then --Don't worry about inf fuel because I modified this function
  877.         saveProgress({doCheckFuel = true})
  878.         error("No more fuel",0)
  879.       elseif yPos > (startY-7) and turtle.detect() then --If it is near bedrock
  880.         bedrock()
  881.       else --Otherwise just sleep for a bit to avoid sheeps
  882.         sleep(1)
  883.       end
  884.     end
  885.   end
  886.   checkSanity() --Not kidding... This is necessary
  887.   saveProgress(tab)
  888.   if doDigUp then
  889.   while turtle.detectUp() do
  890.     sleep(0) --Calls coroutine.yield
  891.     if not dig(true,turtle.digUp) then --This needs to be an absolute, because we are switching doDigUp/Down
  892.       attackUp()
  893.       count = count + 1
  894.     end
  895.     if count > 50 and yPos > (startY-7) then --Same deal with bedrock as above
  896.       bedrock()
  897.     end
  898.     end
  899.   end
  900.   if doDigDown then
  901.    dig(true,turtle.digDown) --This needs to be absolute as well
  902.   end
  903.   percent = math.ceil(moved/moveVolume*100)
  904.   updateDisplay()
  905.   isInPath = (not outOfPath) --For rednet
  906.   if doCheckInv and careAboutResources then
  907.     if moved%invCheckFreq == 0 then
  908.      if isFull(16-keepOpen) then dropOff() end
  909.     end
  910.   end
  911.   if rednetEnabled then biometrics() end
  912. end
  913. --Insanity Checking
  914. function checkSanity()
  915.   if isInPath and not (facing == 0 or facing == 2) and #events == 0 then --If mining and not facing proper direction and not in a turn
  916.     turnTo(0)
  917.     rowCheck = "right"
  918.   end
  919.   if xPos < 0 or xPos > x or zPos < 0 or zPos > z or yPos < 0 then
  920.     saveProgress()
  921.     print("Oops. Detected that quarry was outside of predefined boundaries.")
  922.     print("Please go to my forum thread and report this with a short description of what happened")
  923.     print("If you could also run \"pastebin put Civil_Quarry_Restore\" and give me that code it would be great")
  924.     error("",0)
  925.   end
  926. end
  927.  
  928. local function fromBoolean(input) --Like a calculator
  929. if input then return 1 end
  930. return 0
  931. end
  932. local function multBoolean(first,second) --Boolean multiplication
  933. return (fromBoolean(first) * fromBoolean(second)) == 1
  934. end
  935. function coterminal(num, limit) --I knew this would come in handy :D
  936. limit = limit or 4 --This is for facing
  937. return math.abs((limit*fromBoolean(num < 0))-(math.abs(num)%limit))
  938. end
  939. if tArgs["-manualpos"] then
  940.   facing = coterminal(facing) --Done to improve support for "-manualPos"
  941.   if facing == 0 then rowCheck = "right" elseif facing == 2 then rowCheck = "left" end --Ditto
  942.   relativeXCalc() --Ditto
  943. end
  944.  
  945. --Direction: Front = 0, Right = 1, Back = 2, Left = 3
  946.  
  947. function turnTo(num)
  948.   num = num or facing
  949.   num = coterminal(num) --Prevent errors
  950.   local turnRight = true
  951.   if facing-num == 1 or facing-num == -3 then turnRight = false end --0 - 1 = -3, 1 - 0 = 1, 2 - 1 = 1
  952.   while facing ~= num do          --The above is used to smartly turn
  953.     if turnRight then
  954.       right()
  955.     else
  956.       left()
  957.     end
  958.   end
  959. end
  960. function goto(x,z,y, toFace, destination)
  961.   --Will first go to desired z pos, then x pos, y pos varies
  962.   x = x or 1; y = y or 1; z = z or 1; toFace = toFace or facing
  963.   gotoDest = destination or "" --This is used by biometrics
  964.   --Possible destinations: layerStart, quarryStart
  965.   if yPos > y then --Will go up first if below position
  966.     while yPos~=y do up() end
  967.   end
  968.   if zPos > z then
  969.     turnTo(3)
  970.   elseif zPos < z then
  971.     turnTo(1)
  972.   end
  973.   while zPos ~= z do mine(false,false,true,false) end
  974.   if xPos > x then
  975.     turnTo(2)
  976.   elseif xPos < x then
  977.     turnTo(0)
  978.   end
  979.   while xPos ~= x do mine(false,false,true,false) end
  980.   if yPos < y then --Will go down after if above position
  981.     while yPos~=y do down() end
  982.   end
  983.   turnTo(toFace)
  984.   saveProgress()
  985.   gotoDest = ""
  986. end
  987. function getNumOpenSlots()
  988.   local toRet = 0
  989.   for i=1, 16 do
  990.     if turtle.getItemCount(i) == 0 then
  991.       toRet = toRet + 1
  992.     end
  993.   end
  994.   return toRet
  995. end
  996. function drop(side, final, allowSkip)
  997. side = sides[side] or "front"    --The final number means that it will
  998. if final then final = 0 else final = 1 end --drop a whole stack at the end
  999. local allowSkip = allowSkip or (final == 0) --This will allow drop(side,t/f, rednetConnected)
  1000. count()
  1001. if doRefuel then
  1002.   for i=1, 16 do
  1003.     if slot[i][1] == 2 then
  1004.       turtle.select(i); turtle.refuel()
  1005.     end
  1006.   end
  1007.   turtle.select(1)
  1008. end
  1009. if side == "right" then turnTo(1) end
  1010. if side == "left" then turnTo(3) end
  1011. local whereDetect, whereDrop1, whereDropAll
  1012. local _1 = slot[1][2] - final --All but one if final, all if not final
  1013. if side == "top" then
  1014. whereDetect = turtle.detectUp ; whereDrop = turtle.dropUp
  1015. elseif side == "bottom" then
  1016. whereDetect = turtle.detectDown ; whereDrop = turtle.dropDown
  1017. else
  1018. whereDetect = turtle.detect; whereDrop = turtle.drop
  1019. end
  1020. local function waitDrop(val) --This will just drop, but wait if it can't
  1021.   val = val or 64
  1022.   local try = 1
  1023.   while not whereDrop(val) do
  1024.     print("Chest Full, Try "..try)
  1025.     chestFull = true
  1026.     if rednetEnabled then --To send that the chest is full
  1027.       biometrics()
  1028.     end
  1029.     try = try + 1
  1030.     sleep(2)
  1031.   end
  1032.   chestFull = false
  1033. end
  1034. repeat
  1035. local detected = whereDetect()
  1036. if detected then
  1037.   waitDrop(_1)
  1038.   for i=1, 2 do --This is so I quit flipping missing items when chests are partially filled
  1039.     for i=2, 16 do
  1040.       if turtle.getItemCount(i) > 0 then
  1041.         turtle.select(i)
  1042.         waitDrop(nil, i)
  1043.       end
  1044.     end
  1045.   end
  1046. elseif not allowSkip then
  1047.   print("Waiting for chest placement place a chest to continue")
  1048.   while not whereDetect() do
  1049.     sleep(1)
  1050.   end
  1051. end
  1052. until detected or allowSkip
  1053. if not allowSkip then totals.cobble = totals.cobble - 1 end
  1054. turtle.select(1)
  1055. end
  1056. function dropOff() --Not local because called in mine()
  1057.   local currX,currZ,currY,currFacing = xPos, zPos, yPos, facing
  1058.   if careAboutResources then
  1059.     if not enderChestEnabled then --Regularly
  1060.       eventAdd("goto", 1,1,currY,2) --Need this step for "-startDown"
  1061.       eventAdd("goto(0,1,1,2)")
  1062.       eventAdd("drop", dropSide,false)
  1063.       eventAdd("turnTo(0)")
  1064.       eventAdd("mine",false,false,true,false)
  1065.       eventAdd("goto(1,1,1, 0)")
  1066.       eventAdd("goto", 1, 1, currY, 0)
  1067.       eventAdd("goto", currX,currZ,currY,currFacing)
  1068.     else --If using an enderChest
  1069.       eventAdd("turnTo",currFacing-2)
  1070.       eventAdd("dig",false)
  1071.       eventAdd("turtle.select",enderChestSlot)
  1072.       eventAdd("turtle.place")
  1073.       eventAdd("drop","front",false)
  1074.       eventAdd("turtle.select", enderChestSlot)
  1075.       eventAdd("dig",false)
  1076.       eventAdd("turnTo",currFacing)
  1077.       eventAdd("turtle.select(1)")
  1078.     end
  1079.   runAllEvents()
  1080.   end
  1081. return true
  1082. end
  1083. function endingProcedure() --Used both at the end and in "biometrics"
  1084.   eventAdd("goto",1,1,yPos,2,"quarryStart") --Allows for startDown variable
  1085.   eventAdd("goto",0,1,1,2, "quarryStart") --Go back to base
  1086.   runAllEvents()
  1087.   --Output to a chest or sit there
  1088.   if enderChestEnabled then
  1089.     while turtle.detect() do dig(false) end --This gets rid of blocks in front of the turtle.
  1090.     eventAdd("turtle.select",enderChestSlot)
  1091.     eventAdd("turtle.place")
  1092.     eventAdd("turtle.select(1)")
  1093.   end
  1094.   eventAdd("drop",dropSide, true)
  1095.   eventAdd("turnTo(0)")
  1096.  
  1097.   --Display was moved above to be used in bedrock function
  1098.   eventAdd("display")
  1099.   --Log current mining run
  1100.   eventAdd("logMiningRun",logExtension)
  1101.   toQuit = true --I'll use this flag to clean up
  1102.   runAllEvents()
  1103.   --Cleanup
  1104.   turtle.getFuelLevel = getFuel
  1105. end
  1106. function bedrock()
  1107. foundBedrock = true --Let everyone know
  1108. if rednetEnabled then biometrics() end
  1109. if checkFuel() == 0 then error("No Fuel",0) end
  1110. local origin = {x = xPos, y = yPos, z = zPos}
  1111. print("Bedrock Detected")
  1112. if turtle.detectUp() then
  1113. print("Block Above")
  1114. local var
  1115. if facing == 0 then var = 2 elseif facing == 2 then var = 0 else error("Was facing left or right on bedrock") end
  1116. goto(xPos,zPos,yPos,var)
  1117. for i=1, relxPos do mine(true,true); end
  1118. end
  1119. endingProcedure()
  1120. print("\nFound bedrock at these coordinates: ")
  1121. print(origin.x," Was position in row\n",origin.z," Was row in layer\n",origin.y," Blocks down from start")
  1122. error("",0)
  1123. end
  1124.  
  1125. function endOfRowTurn(startZ, wasFacing, mineFunctionTable)
  1126. local halfFacing = 1
  1127. local toFace = coterminal(wasFacing + 2) --Opposite side
  1128. if zPos == startZ then
  1129.   if facing ~= halfFacing then turnTo(halfFacing) end
  1130.   mine(unpack(mineFunctionTable or {}))
  1131. end
  1132. if facing ~= toFace then
  1133.   turnTo(toFace)
  1134. end
  1135. end
  1136.  
  1137. -------------------------------------------------------------------------------------
  1138. --Pre-Mining Stuff dealing with session persistence
  1139. runAllEvents()
  1140. if toQuit then error("",0) end --This means that it was stopped coming for its last drop
  1141.  
  1142. local doDigDown, doDigUp = (lastHeight ~= 1), (lastHeight == 0) --Used in lastHeight
  1143. if not restoreFoundSwitch then --Regularly
  1144.   --Check if it is a mining turtle
  1145.   if not isMiningTurtle then
  1146.     local a, b = turtle.dig()
  1147.     if a then mined = mined + 1; isMiningTurtle = true
  1148.     elseif b == "Nothing to dig with" then
  1149.       print("This is not a mining turtle. To make a mining turtle, craft me together with a diamond pickaxe")
  1150.       error("",0)
  1151.     end
  1152.   end
  1153.   mine(false,false,true) --Get into quarry by going forward one
  1154.   if gpsEnabled and not restoreFoundSwitch then --The initial locate is done in the arguments. This is so I can figure out what quadrant the turtle is in.
  1155.   gpsSecondPos = {gps.locate(gpsTimeout)} --Note: Does not run this if it has already been restarted.
  1156. end
  1157.   for i = 1, startDown do
  1158.     eventAdd("down") --Add a bunch of down events to get to where it needs to be.
  1159.   end
  1160.   runAllEvents()
  1161.   if not(y == 1 or y == 2) then down() end --Go down. If y is one or two, it doesn't need to do this.
  1162. else --restore found
  1163.   if doDigDown then digDown() end
  1164.   if doDigUp then digUp() end  --Get blocks missed before stopped
  1165. end
  1166. --Mining Loops--------------------------------------------------------------------------
  1167. turtle.select(1)
  1168. while layersDone <= layers do -------------Height---------
  1169. local lastLayer = layersDone == layers --If this is the last layer
  1170. local secondToLastLayer = (layersDone + 1) == layers --This is for the going down at the end of a layer.
  1171. moved = moved + 1 --To account for the first position in row as "moved"
  1172. if doDigDown then digDown() end --This is because it doesn't mine first block in layer
  1173. if not restoreFoundSwitch then rowCheck = "right" end
  1174. relativeXCalc()
  1175. while zPos <= z do -------------Width----------
  1176. while relxPos < x do ------------Length---------
  1177. mine(not lastLayer or (doDigDown and lastLayer), not lastLayer or (doDigUp and lastLayer)) --This will be the idiom that I use for the mine function
  1178. end ---------------Length End-------
  1179. if zPos ~= z then --If not on last row of section
  1180.   local func
  1181.   if rowCheck == "right" then --Swithcing to next row
  1182.   func = "right"; rowCheck = "left"; else func = "left"; rowCheck = "right" end --Which way to turn
  1183.     eventAdd("endOfRowTurn", zPos, facing , {not lastLayer or (doDigDown and lastLayer), not lastLayer or (doDigUp and lastLayer)}) --The table is passed to the mine function
  1184.     runAllEvents()
  1185. else break
  1186. end
  1187. end ---------------Width End--------
  1188. eventAdd("goto",1,1,yPos,0, "layerStart") --Goto start of layer
  1189. runAllEvents()
  1190. if not lastLayer then --If there is another layer
  1191.   for i=1, 2+fromBoolean(not(lastHeight~=0 and secondToLastLayer)) do down() end --The fromBoolean stuff means that if lastheight is 1 and last and layer, will only go down two
  1192. end
  1193. layersDone = layersDone + 1
  1194. restoreFoundSwitch = false --This is done so that rowCheck works properly upon restore
  1195. end ---------------Height End-------
  1196.  
  1197. endingProcedure() --This takes care of getting to start, dropping in chest, and displaying ending screen
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement