Guest User

Quarry 3.0.3

a guest
Apr 2nd, 2013
798
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. --[[TO DO:
  2. Version 3.0.3
  3. Recent Changes:
  4.    Everything has been drastically updated. Now mines three at a time...
  5. ]]
  6. --[[Things that might get done in the future:
  7. 1. Go around bedrock? Idea: If encounters bedrock, go up three and set y to yPos + 1, if on last run, then just
  8.       goto(0,1,1,2); detection would be if cannot dig more than 20 times
  9. 2. Fuel Usage Check. Make a more advanced algorithm (Evan is working on it)
  10. 3.  Maybe send basic commands from receiver program
  11. ]]
  12. --Defining things
  13.  
  14. --Defaults for Arguments
  15. local tArgs = {...}
  16. --Arguments assignable by text
  17. local x,y,z = 3,3,3 --These are just in case tonumber fails
  18. local inverted = false --False goes from top down, true goes from bottom up [Default false
  19. local dropSide = "front" --Side it will eject to when full or done [Default "front"]
  20. local rednetEnabled = false --Default rednet on or off
  21. --Arguments assignable by tArgs
  22. local careAboutResources = true --Will not stop mining once inventory full if false [Default true]
  23. local doCheckFuel = true --Perform fuel check [Default true]
  24. local doRefuel = false --Whenever it comes to start location will attempt to refuel from inventory [Default false]
  25. local invCheckFreq = 10 --Will check for inventory full every <-- moved spaces [Default 10]
  26. local keepOpen = 1 --How many slots it will attempt to keep open at all times [Default 1]
  27. --Standard rednet channels
  28. local channels = {
  29. send = os.getComputerID()  ,
  30. receive = 10 ,
  31. confirm = "Confirm"
  32. }
  33.  
  34. local supportsRednet
  35. do
  36. local a = peripheral.wrap("right")
  37. supportsRednet = (a ~= nil)
  38. end
  39.  
  40. local help = {[[-ToDo: Write stuff here about all the different functions-]], [[Second Page]]}
  41. --You don't care about these
  42. local xPos,yPos,zPos,facing,percent,mined,moved,relxPos, rowCheck, connected, isInPath
  43.     = 0,   1,   1,   0,     0,      0,    0,    1,       "right",  false,     true
  44.  
  45. local totals = {cobble = 0, fuel = 0, other = 0} -- Total for display (cannot go inside function)
  46. function count() --Done any time inventory dropped and at end
  47. slot = {}        --1: Cobble 2: Fuel 3:Other
  48. for i=1, 16 do   --[1] is type, [2] is number
  49. slot[i] = {}
  50. slot[i][2] = turtle.getItemCount(i)
  51. end
  52. slot[1][1] = 1   -- = Assumes Cobble/Main
  53. for i=1, 16 do   --Cobble Check
  54. turtle.select(i)
  55. if turtle.compareTo(1)  then
  56. slot[i][1] = 1
  57. totals.cobble = totals.cobble + slot[i][2]
  58. elseif turtle.refuel(0) then
  59. slot[i][1] = 2
  60. totals.fuel = totals.fuel + slot[i][2]
  61. else
  62. slot[i][1] = 3
  63. totals.other = totals.other + slot[i][2]
  64. end
  65. end
  66. turtle.select(1)
  67. end
  68. local function checkFuel()
  69. return turtle.getFuelLevel()
  70. end
  71. local function isFull(slots)
  72. slots = slots or 16
  73. local numUsed = 0
  74. sleep(0.5)
  75. for i=1, slots do
  76. if turtle.getItemCount(i) > 0 then numUsed = numUsed + 1 end
  77. end
  78. if numUsed >= slots then return true end
  79. return false
  80. end
  81.  
  82.  -----------------------------------------------------------------
  83. --Input Phase
  84. local function screen(xPos,yPos)
  85. term.setCursorPos(xPos,yPos); term.clear(); end
  86. local function screenLine(xPos,yPos)
  87. term.setCursorPos(xPos,yPos); term.clearLine(); end
  88.  
  89. screen(1,1)
  90. print("----- Welcome to Quarry! -----")
  91. print("")
  92.  
  93. local sides = {top = "top", right = "right", left = "left", bottom = "bottom", front = "front"} --Used to whitelist sides
  94. local errorT = {num = "Numbers not recognized", zero = "Variable is out of range" }
  95. local changedT = {}
  96. changedT.new = function(key, value) changedT[#changedT+1] = {[key] = value} end
  97. changedT.getPair = function(i) for a, b in pairs(changedT[i]) do return a, b end end
  98. local function capitalize(text) return (string.upper(string.sub(text,1,1))..string.sub(text,2,-1)) end
  99. 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
  100. local function checkNum(number, section) return assert(tonumber(number),errorT.num, section) end
  101. tArgs.checkStart = function(num) tArgs[tArgs[num]] = num end
  102. --tArgs.checkStart = function(num) tArgs.t[tArgs[num]] = {num, tArgs.t[num]} end --If you think this is needed
  103. for i=1, #tArgs do tArgs.checkStart(i) end
  104.  
  105. --All the different arguments
  106. if tArgs["-?"] or tArgs["help"] then
  107. for i=1, #help do print(help[i]) end --Expand on this to include multiple pages
  108. error("",0)
  109. end
  110.  
  111.  
  112. if not tArgs["-DEFAULT-"] then
  113. local section = "Dimensions"
  114. --Dimesnions
  115. if tArgs["-dim"] then local num = tArgs["-dim"];
  116. x = checkNum(tArgs[num + 1],section); z = checkNum(tArgs[num + 2],section); y = checkNum(tArgs[num + 3],section)
  117. else
  118. print("What dimensions?")
  119. print("")
  120. --This will protect from negatives, letters, and decimals
  121. term.write("Length: ")
  122. x = math.floor(math.abs(tonumber(io.read()) or x))
  123. term.write("Width: ")
  124. z = math.floor(math.abs(tonumber(io.read()) or z))
  125. term.write("Height: ")
  126. y = math.floor(math.abs(tonumber(io.read()) or y))
  127. end
  128. changedT.new("x",x); changedT.new("z",z); changedT.new("y",y)
  129. assert(x~=0, errorT.zero, section); assert(z~=0, errorT.zero, section); assert(y~=0, errorT.zero, section)
  130. assert(not(x == 1 and y == 1 and z == 1) ,"1, 1, 1 dosen't work well at all, try again", section)
  131. if not tArgs["-vanilla"] then
  132. --Invert
  133. if tArgs["-invert"] then
  134. inverted = (string.lower(string.sub(tArgs[tArgs["-invert"]+1] or "",1,1)) == "t") else
  135. term.write("Inverted? ")
  136. inverted = (string.lower(string.sub(io.read(),1,1)) == "y")
  137. end
  138. changedT.new("Inverted", inverted)
  139. --Rednet
  140. if supportsRednet then
  141. if tArgs["-rednet"] then rednetEnabled = true
  142. else term.write("Rednet? "); rednetEnabled = (string.lower(string.sub(io.read(),1,1)) == "y") end
  143. changedT.new("Rednet Enabled", rednetEnabled)
  144. if tArgs["-sendChannel"] then
  145. channels.send = assert(tonumber(tArgs[tArgs["-sendChannel"]+1]), errorT.num)
  146. assert(channels.send > 0 and channels.send < 65535, errorT.zero)
  147. changedT.new("Send Channel",channels.send) end
  148. if tArgs["-receiveChannel"] then
  149. channels.receive = assert(tonumber(tArgs[tArgs["-receiveChannel"]+1]), errorT.num)
  150. assert(channels.receive > 0 and channels.receive < 65535 and channels.receive ~= channels.send, errorT.zero)
  151. changedT.new("Receive Channel",channels.receive) end
  152. end
  153. --Fuel
  154. if tArgs["-doRefuel"] then doRefuel = not doRefuel; changedT.new("Do Refuel",doRefuel) end
  155. if tArgs["-checkFuel"] then doCheckFuel = not doCheckFuel; changedT.new("Do Check Fuel", doCheckFuel) end
  156. if tArgs["-chest"] then
  157. dropSide = sides[tArgs[tArgs["-chest"]+1]] or dropSide; changedT.new("Chest Side",dropSide) end
  158. --Misc
  159. if tArgs["-invCheckFreq"] then
  160. invCheckFreq = math.abs(math.floor(checkNum(tArgs[tArgs["-invCheckFreq"]+1],"Inventory Check Frequency")))
  161. changedT.new("Inventory Check Frequency",invCheckFreq) end
  162. assert(invCheckFreq ~= 0, errorT.zero, "Inventory Check Frequency")
  163. if tArgs["-openSlots"] then
  164. keepOpen = math.abs(math.floor(checkNum(tArgs[tArgs["-openSlots"]+1],"Open Slots")))
  165. changedT.new("Slots to keep open", keepOpen) end
  166. assert(keepOpen ~= 0 and keepOpen < 16, errorT.zer, "Open Slots")if tArgs["-ignoreResources"] then careAboutResources = false end
  167. end; end
  168.  
  169. local area = x*z
  170. local volume = x*y*z
  171. local lastHeight = y%3
  172. local dispY = y
  173. y = math.floor(y/3)*3
  174. local moveVolume = (area*(y/3 + math.ceil(lastHeight/2)))
  175.  
  176. --Getting Fuel
  177. if doCheckFuel then --Calculating Needed Fuel
  178. local neededFuel = moveVolume
  179. if neededFuel < 100 then
  180. neededFuel = 100 else neededFuel = neededFuel * 2 --Placeholder algorithm until Evan is done
  181. end
  182. if checkFuel() < neededFuel then
  183. screen(1,1)
  184. print("More Fuel Needed")
  185. print("Current Fuel: ",checkFuel()," Needed: ",neededFuel)
  186. print("Place fuel in Bottom Right, press any key")
  187. os.pullEvent("char")
  188. turtle.select(16)
  189. while checkFuel() < neededFuel do
  190. if not turtle.refuel(1) then
  191. term.clearLine()
  192. print("Still too little fuel")
  193. term.clearLine()
  194. print("Press a key to resume fueling")
  195. os.pullEvent("char")
  196. end
  197. local x,y = term.getCursorPos()
  198. print(checkFuel().." Fuel")
  199. term.setCursorPos(x,y)
  200. end
  201. print(checkFuel().." Units of Fuel")
  202. sleep(3)
  203. turtle.select(1)
  204. end
  205. end
  206. --Initial Rednet Handshake
  207. if rednetEnabled then
  208. screen(1,1)
  209. print("Rednet is Enabled")
  210. print("The Channel to open is "..channels.send)
  211. modem = peripheral.wrap("right")
  212. modem.open(channels.receive)
  213. local i = 0
  214. repeat
  215. local id = os.startTimer(3)
  216. i=i+1
  217. print("Sending Initial Message "..i)
  218. modem.transmit(channels.send, channels.receive, "{ 'Initial' }")
  219. local message
  220. repeat
  221. local event, idCheck, channel,_,locMessage, distance = os.pullEvent()
  222. message = locMessage
  223. until (event == "timer" and idCheck == id) or (event == "modem_message" and channel == channels.receive and message == channels.confirm)
  224. until message == channels.confirm
  225. connected = true
  226. print("Connection Confirmed!")
  227. sleep(1.5)
  228. end
  229. local function biometrics(sendChannel, message)
  230. local commands = { Confirm = "Confirm" }
  231. local toSend = { ["x"] = x, ["y"] = (y/3 + math.ceil(lastHeight/2)),
  232.      ["z"] = z,                     --The y calc is weird...
  233.     ["xPos"] = xPos, ["yPos"] = yPos, ["zPos"] = zPos,
  234.     ["percent"] = percent, ["mined" ]= mined,
  235.     ["fuel"] = checkFuel(), ["moved"] = moved,
  236.     ["remainingBlocks"] = (volume-mined), ["ID"] = os.getComputerID(),
  237.     ["isInPath"] = isInPath, --Whether it is going back to start
  238.     ["volume"] = volume, ["area"] = area}
  239. modem.transmit(channels.send, channels.receive, textutils.serialize(toSend))
  240. id = os.startTimer(0.1)
  241. local event
  242. repeat
  243. local locEvent, idCheck, confirm, _, locMessage, distance = os.pullEvent()
  244. event, message = locEvent, locMessage
  245. until (event == "timer" and idCheck == id) or (event == "modem_message" and confirm == channels.receive)
  246. if event == "modem_message" and commands[message] then connected = true else connected = false end
  247. --Stuff to do for different commands
  248. end
  249.  
  250. --Showing changes to settings
  251. screen(1,1)
  252. print("Your selected settings:")
  253. if #changedT == 0 then
  254. print("Completely Default")
  255. else
  256. for i=1, #changedT do
  257. local title, value = changedT.getPair(i)
  258. print(capitalize(title)..": ",value)
  259. end
  260. end
  261. print("\nStarting in 3"); sleep(1); print("2"); sleep(1); print("1"); sleep(1.5)
  262.  
  263. ----------------------------------------------------------------
  264. --Mining Phase
  265. local function updateDisplay() --Runs in Mine(), display information to the screen in a certain place
  266. screen(1,1)
  267. print("Blocks Mined")
  268. print(mined)
  269. print("Percent Complete")
  270. print(percent.."%")
  271. if rednetEnabled then
  272. screenLine(1,6)
  273. print("Connected: "..tostring(connected))
  274. end
  275. end
  276. local function mine(digDown, digUp, outOfPath,doCheckInv) -- Basic Move Forward
  277. if doCheckInv == nil then doCheckInv = true end
  278. if digDown == nil then digDown = true end
  279. if digUp == nil then digUp = true end
  280.  
  281. while not turtle.forward() do
  282. if turtle.dig() then mined = mined + 1; else turtle.attack(); end
  283. end
  284. if digUp then
  285. while turtle.detectUp() do if turtle.digUp() then mined = mined + 1; end end
  286. end
  287. if digDown then
  288. if turtle.digDown() then mined = mined + 1; end
  289. end
  290. if outOfPath then isInPath = false; else isInPath = true; moved = moved + 1; end
  291. if facing == 0 then xPos = xPos +1
  292. elseif facing == 2 then xPos = xPos-1
  293. elseif facing == 1 then zPos = zPos+1
  294. elseif facing == 3 then zPos = zPos-1; end
  295. if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end --Maybe adjust this for out of path
  296. percent = math.ceil(moved/moveVolume*100)
  297. updateDisplay()
  298. local whereGoing
  299. if doCheckInv and careAboutResources then
  300. if moved%invCheckFreq == 0 then
  301.  if isFull(16-keepOpen) then dropOff() end
  302. end; end
  303. if rednetEnabled then biometrics() end
  304. end
  305. --Direction: Front = 0, Right = 1, Back = 2, Left = 3
  306. local function facingF(num)
  307. facing = facing + num
  308. if facing > 3 then facing = 0 end
  309. if facing < 0 then facing = 3 end
  310. end
  311.  
  312. if up then local temp1 = up end --Just in case another program uses this
  313. if down then local temp2 = down end
  314. function up(num, sneak)
  315. num = num or 1
  316. sneak = sneak or 1
  317. if inverted and sneak == 1 then
  318.     down(num, -1)
  319. else
  320.     for i=1, num do while not turtle.up() do
  321.         while not turtle.digUp() do
  322.         turtle.attackUp(); sleep(0.5); end
  323.         mined = mined + 1
  324.     end; yPos = yPos - sneak; end
  325. end
  326. end
  327. function down(num, sneak)
  328. num = num or 1
  329. sneak = sneak or 1
  330. if inverted and sneak == 1 then
  331.     up(num, -1)
  332. else
  333.     for i=1, num do while not turtle.down() do
  334.         while not turtle.digDown() do
  335.         turtle.attackDown(); sleep(0.5); end
  336.         mined = mined+1
  337.     end; yPos = yPos + sneak; end
  338. end
  339. end
  340. local function right(num)
  341. num = num or 1
  342. for i=1, num do turtle.turnRight(); facingF(1); end
  343. end
  344. local function left(num)
  345. num = num or 1
  346. for i=1, num do turtle.turnLeft(); facingF(-1) end
  347. end
  348. local function goto(x,z,y, toFace)
  349. x = x or 1; y = y or 1; z = z or 1; toFace = toFace or facing
  350. if yPos > y then while yPos~=y do up() end end
  351.  if zPos > z then
  352.  while facing ~= 3 do left() end
  353.  elseif zPos < z then while facing ~= 1 do left() end
  354.  end
  355.  while zPos ~= z do mine(false,false,true,false) end
  356.   if xPos> x then
  357.   while facing ~= 2 do left() end
  358.   elseif xPos < x then while facing ~= 0 do left() end
  359.   end
  360.   while xPos ~= x do mine(false,false,true,false) end
  361. if yPos < y then while yPos~=y do down() end end
  362. while facing ~= toFace do right() end
  363. end
  364. local function turnTo(num)
  365. num = num or 1; goto(xPos,zPos,yPos,num)
  366. end
  367. local function drop(side, final, allowSkip)
  368. side = sides[side] or "front"    --The final number means that it will
  369. if final then final = 0 else final = 1 end --drop a whole stack at the end
  370. local allowSkip = allowSkip or (final == 0) --This will allow drop(side,t/f, rednetConnected)
  371.   count()
  372.   if doRefuel then
  373.   for i=1, 16 do
  374.   if slot[i][1] == 2 then
  375.   turtle.select(i); turtle.refuel()
  376.   end; end; end
  377. if side == "right" then turnTo(1) end
  378. if side == "left" then turnTo(3) end
  379. local whereDetect, whereDrop
  380. local _1 = tostring(slot[1][2] - final)
  381. if side == "top" then
  382. whereDetect = "turtle.detectUp()" ; whereDrop1 = "turtle.dropUp(".._1..")"; whereDropAll = "turtle.dropUp()"
  383. elseif side == "bottom" then
  384. whereDetect = "turtle.detectDown()" ; whereDrop1 = "turtle.dropDown(".._1..")"; whereDropAll = "turtle.dropDown()"
  385. else
  386. whereDetect = "turtle.detect()" ; whereDrop1 = "turtle.drop(".._1..")"; whereDropAll = "turtle.drop()" end
  387. repeat
  388. local detected = loadstring("return "..whereDetect)()
  389. if detected then
  390. assert(loadstring("if "..whereDetect.." then "
  391. ..whereDrop1..[[
  392. for i=2, 16 do
  393. if turtle.getItemCount(i) > 0 then turtle.select(i); ]]..whereDropAll.." end end end"))()
  394. elseif not allowSkip then
  395. print("Waiting for chest placement, press a key to continue")
  396. os.pullEvent("char")
  397. end
  398. until detected or allowSkip
  399. if not allowSkip then totals.cobble = totals.cobble - 1 end
  400. turtle.select(1)
  401. turnTo(0)
  402. end
  403. function dropOff() --Not local because called in mine()
  404. local currX,currZ,currY,currFacing = xPos, zPos, yPos, facing
  405. goto(0,1,1,2)
  406. drop(dropSide,false)
  407. goto(currX,currZ,currY,currFacing)
  408. end
  409. -------------------------------------------------------------------------------------
  410. local doDigDown, doDigUp
  411. if not inverted then doDigDown , doDigUp = (lastHeight ~= 1), false
  412. else doDigUp, doDigDown = (lastHeight ~= 1) , false; end --Used in lastHeight
  413. a=1
  414. mine(false,false, true)
  415. if y ~= 0 then down() end
  416. --Mining Loops
  417. turtle.select(1)
  418. while a <= y do -------------Height---------
  419. moved = moved + 1
  420. rowCheck = "right" --At the end of this row it will turn right
  421. if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end
  422. while zPos <= z do -------------Width----------
  423. while relxPos < x do ------------Length---------
  424. mine()
  425.  
  426. end ---------------Length End-------
  427. if zPos ~= z then
  428. if rowCheck == "right" and zPos ~= z then --Swithcing to next row
  429. rowCheck = "left"; right(); mine(); right()
  430. else
  431. rowCheck = "right"; left(); mine(); left()
  432. end
  433. else break
  434. end
  435. end ---------------Width End--------
  436. goto(1,1,yPos,0)
  437. if yPos+1 ~= y then down(3) end
  438. a=a+3; end ---------------Height End-------
  439. if lastHeight ~= 0 then ---------LAST ROW--------- (copied from above)
  440. moved = moved + 1
  441. if y ~= 0 then down(2) end
  442. rowCheck = "right"
  443. if rowCheck == "right" then relxPos = xPos else relxPos = (x-xPos)+1 end
  444. while zPos <= z do -------------Width----------
  445. while relxPos < x do ------------Length---------
  446. mine(doDigDown, doDigUp)
  447. end ---------------Length End-------
  448. if zPos ~= z then
  449. if rowCheck == "right" and zPos ~= z then --Swithcing to next row
  450. rowCheck = "left"; right(); mine(doDigDown, doDigUp); right()
  451. else
  452. rowCheck = "right"; left(); mine(doDigDown, doDigUp); left()
  453. end
  454. else break
  455. end
  456. end ---------------Width End--------
  457. goto(1,1,yPos,0)
  458. end
  459. if not inverted then
  460.     if doDigDown then if turtle.digDown() then mined = mined + 1 end end
  461.   else
  462.     if doDigUp then if turtle.digUp() then mined = mined + 1 end end
  463. end
  464. goto(0,1,1,2)
  465.  
  466. --Output to a chest or sit there
  467. drop(dropSide, true)
  468. --Display
  469. screen(1,1)
  470. print("Total Blocks Mined: "..mined)
  471. print("Current Fuel Level: "..turtle.getFuelLevel())
  472. print("Cobble: "..totals.cobble)
  473. print("Usable Fuel: "..totals.fuel)
  474. print("Other: "..totals.other)
  475. if rednetEnabled then
  476. print("")
  477. print("Sent Stop Message")
  478. finalTable = {{["Mined: "] = mined}, {["Cobble: "] = totals.cobble}, {["Fuel: "] = totals.fuel},
  479.     {["Other: "] = totals.other}, {["Fuel: "] = checkFuel()} }
  480. modem.transmit(channels.send,channels.receive,"stop")
  481. modem.transmit(channels.send,channels.receive,textutils.serialize(finalTable))
  482. modem.close(channels.receive)
  483. end
  484.  
  485. --The only global variables I had to use
  486. if temp1 then up = temp1 end
  487. if temp2 then down = temp2 end
RAW Paste Data