Inksaver

clsTurtle.lua (Turtle Class):2023/10/01

Feb 8th, 2016 (edited)
2,075
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 107.34 KB | None | 0 0
  1. version = 20231001.1500
  2. --[[
  3.     https://pastebin.com/tvfj90gK
  4.     Last edited: see version YYYYMMDD.HHMM
  5.     save as clsTurtle.lua, preferably in /lib folder
  6.     as is not meant to be run directly from CraftOS command line
  7.     usage:
  8.     T = require("lib/clsTurtle").new()
  9.     T:clear()
  10.     T:forward(2)
  11.     To use logging
  12.     T = require("lib.clsTurtle"):new(true) -- true enables logfile to log.txt
  13.    
  14.     Computercraft started with mc version 1.7.10 and went to 1.8.9
  15.     ccTweaked started around mc 1.12 and currently at 1.18
  16.     mc 1.18 has new blocks and bedrock at -64, so needs to be taken into account.
  17.     _HOST = The ComputerCraft and Minecraft version of the current computer environment.
  18.     For example, ComputerCraft 1.93.0 (Minecraft 1.15.2).
  19. ]]
  20.  
  21. local bedrock = 0
  22. local ceiling = 255
  23. local deletesWater = false
  24. local mcMajorVersion = tonumber(_HOST:sub(_HOST:find("Minecraft") + 10, _HOST:find("\)") - 1)) -- eg 1.18 or 1.20 -> 1.18, 1.20
  25. if tonumber(mcMajorVersion) == nil then -- 1.18.3 NAN
  26.     mcMajorVersion = tonumber(_HOST:sub(_HOST:find("Minecraft") + 10, _HOST:find("\)") - 3)) -- eg 1.19.4 -> 1.19
  27. end
  28. if mcMajorVersion < 1.7  and mcMajorVersion >= 1.18 then -- 1.12 to 1.??
  29.     bedrock = -64
  30.     ceiling = 319
  31. end
  32. if mcMajorVersion < 1.7  and mcMajorVersion <= 1.12 then -- 1.12 to 1.??
  33.     deletesWater = true
  34. end
  35. local stone = {
  36.                 "minecraft:cobblestone",
  37.                 "minecraft:cobbled_deepslate",
  38.                 "minecraft:netherrack",
  39.                 "minecraft:blackstone",
  40.                 "minecraft:basalt",
  41.                 "minecraft:tuff",
  42.                 "minecraft:granite",
  43.                 "minecraft:diorite",
  44.                 "minecraft:andesite",
  45.                 "minecraft:end_stone",
  46.                 "minecraft:obsidian",
  47.                 "minecraft:stone",
  48.                 "minecraft:dirt",
  49.                 "minecraft:glass",
  50.                 "minecraft:purpur_block",
  51.                 "minecraft:terracotta",
  52.                 "minecraft:white_terracotta",
  53.                 "minecraft:red_terracotta",
  54.                 "minecraft:orange_terracotta",
  55.                 "minecraft:yellow_terracotta",
  56.                 "minecraft:brown_terracotta",
  57.                 "minecraft:light_gray_terracotta"
  58.               } -- must be exact mc names!
  59.              
  60. local flowers =
  61. {
  62.     "minecraft:sapling",
  63.     "minecraft:oak_sapling",
  64.     "minecraft:spruce_sapling",
  65.     "minecraft:birch_sapling",
  66.     "minecraft:jungle_sapling",
  67.     "minecraft:acacia_sapling",
  68.     "minecraft:dark_oak_sapling",
  69.     "minecraft:leaves",
  70.     "minecraft:oak_leaves",
  71.     "minecraft:spruce_leaves",
  72.     "minecraft:birch_leaves",
  73.     "minecraft:jungle_leaves",
  74.     "minecraft:acacia_leaves",
  75.     "minecraft:dark_oak_leaves",
  76.     "minecraft:azalea_leaves",
  77.     "minecraft:flowering_azalea_leaves",
  78.     "minecraft:dandelion",
  79.     "minecraft:poppy",
  80.     "minecraft:blue_orchid",
  81.     "minecraft:allium",
  82.     "minecraft:azure_bluet",
  83.     "minecraft:red_tulip",
  84.     "minecraft:orange_tulip",
  85.     "minecraft:white_tulip",
  86.     "minecraft:pink_tulip",
  87.     "minecraft:oxeye_daisy",
  88.     "minecraft:cornflower",
  89.     "minecraft:lily_of_the_valley",
  90.     "minecraft:sunflower",
  91.     "minecraft:lilac",
  92.     "minecraft:rose_bush",
  93.     "minecraft:peony",
  94.     "minecraft:wither_rose",
  95.     "minecraft:spore_blossom",
  96.     "minecraft:fern",
  97.     "minecraft:large_fern",
  98.     "minecraft:grass",
  99.     "minecraft:tall_grass",
  100.     "minecraft:azalea",
  101.     "minecraft:flowering_azalea",
  102.     "minecraft:deadbush",
  103.     "minecraft:dead_bush",
  104.     "minecraft:seagrass",
  105.     "minecraft:tall_seagrass",
  106.     "minecraft:sea_pickle",
  107.     "minecraft:brown_mushroom",
  108.     "minecraft:red_mushroom",
  109.     "minecraft:crimson_fungus",
  110.     "minecraft:warped_fungus",
  111.     "minecraft:crimson_roots",
  112.     "minecraft:warped_roots",
  113.     "minecraft:vine",
  114.     "minecraft:vines",
  115.     "minecraft:weeping_vines",
  116.     "minecraft:twisting_vines",
  117.     "minecraft:sugar_cane",
  118.     "minecraft:kelp",
  119.     "minecraft:kelp_plant",
  120.     "minecraft:moss_block",
  121.     "minecraft:moss_carpet",
  122.     "minecraft:hanging_roots",
  123.     "minecraft:big_dripleaf",
  124.     "minecraft:small_dripleaf",
  125.     "minecraft:bamboo",
  126.     "minecraft:cactus",
  127.     "minecraft:glow_lichen",
  128.     "minecraft:waterlily",
  129.     "minecraft:lily_pad",
  130.     "minecraft:pumpkin",
  131.     "minecraft:melon",
  132.     "minecraft:melon_block",
  133.     "minecraft:cocoa",
  134.     "minecraft:double_plant",
  135.     "minecraft:sponge",
  136.     "minecraft:wet_sponge",
  137. }
  138.              
  139. local clsTurtle = {}
  140. clsTurtle.__index = clsTurtle
  141.  
  142. setmetatable(clsTurtle,
  143. {
  144.     __call = function (cls, ...)
  145.     return cls.new(...)
  146.     end,
  147. })
  148. -- if you want to pass arguments at construction...
  149. function clsTurtle.new(useLog) --note dot, NOT colon, list of args or ... table
  150.     local self = setmetatable({}, clsTurtle)
  151.     if useLog == nil then useLog = false end
  152.     self.x = 0
  153.     self.y = 0
  154.     self.z = 0
  155.     self.facing = 0
  156.     self.compass = ""
  157.     self.equippedLeft = ""
  158.     self.equippedRight = ""
  159.     self.placeSlot = 0
  160.     self.placeItem = ""
  161.     self.osVersion = os.version() -- eg CraftOS 1.8
  162.     self.userBlocks = {}
  163.     self.useLog = useLog
  164.     if self.useLog then
  165.         print("Logging enabled")
  166.         sleep(1.5)
  167.     end
  168.     self.logFileName = "log.txt"
  169.     self.logFileExists = false
  170.     return self
  171. end
  172.  
  173. -- helper function for iterating lists
  174. function clsTurtle.values(self,t) -- general diy iterator
  175.     local i = 0
  176.     return function()
  177.         i = i + 1
  178.         return t[i]
  179.     end
  180. end
  181. --[[
  182.     logging methods set from calling program
  183.     T:setLogFileName("log.txt") (example)
  184.     T:deleteLog() -- if new log required every time program is run
  185.     T:setUseLog(true) -- allows logging statements to be left in this class code, will only operate if this flag is set#
  186.     extensive use for debugging has been left in the function clsTurtle.checkInventoryForItem() as this was a nightmare to get working
  187. ]]
  188. function clsTurtle.getUseLog(self)
  189.     return self.useLog
  190. end
  191. function clsTurtle.setUseLog(self, use)
  192.     self.useLog = use
  193.     return use
  194. end
  195. function clsTurtle.getLogExists(self)
  196.     local exists = false
  197.     if fs.exists(self.logFileName) then
  198.         exists = true
  199.     end
  200.     return exists
  201. end
  202. function clsTurtle.getLogFileName(self)
  203.     return self.logFileName
  204. end
  205. function clsTurtle.setLogFileName(self, value)
  206.     self.logFileName = value
  207. end
  208. function clsTurtle.getCurrentFileSize(self)    
  209.     if self.logFileExists then
  210.         return fs.getSize(self.logFileName)
  211.     else
  212.         return 0
  213.     end
  214. end
  215. function clsTurtle.deleteLog(self)     
  216.     if fs.exists(self.logFileName) then
  217.         fs.delete(self.logFileName)
  218.     end
  219.     self.logFileExists = false
  220.    
  221.     return true
  222. end
  223. function clsTurtle.appendLine(self, newText)
  224.     local handle = ""
  225.    
  226.     if fs.exists(self.logFileName) then --logFile already created
  227.         handle = fs.open(self.logFileName, "a")
  228.     else
  229.         handle = fs.open(self.logFileName, "w") --create file
  230.     end
  231.     self.logFileExists = true
  232.     handle.writeLine(newText)
  233.     handle.close()
  234. end
  235. function clsTurtle.saveToLog(self, text, toScreen)
  236.     if toScreen == nil then
  237.         toScreen = true
  238.     end
  239.     if text ~= "" and text ~= nil then
  240.         if toScreen then
  241.             print(text)
  242.         end
  243.         if self.useLog then
  244.             clsTurtle.appendLine(self, text)
  245.             return true
  246.         end
  247.     end
  248.     return false
  249. end
  250.  
  251. -- getters and setters
  252. function clsTurtle.getValue(self) return self.value end --debug test for object creation with args
  253. function clsTurtle.getX(self) return self.x end
  254. function clsTurtle.setX(self, newVal) self.x = newVal end
  255. function clsTurtle.getY(self) return self.y end
  256. function clsTurtle.setY(self, newVal) self.y = newVal end
  257. function clsTurtle.getZ(self) return self.z end
  258. function clsTurtle.setZ(self, newVal) self.z = newVal end
  259. function clsTurtle.getFacing(self) return self.facing end
  260. function clsTurtle.setFacing(self, newVal)
  261.     local direction = {"south", "west", "north", "east"}
  262.     self.facing = newVal
  263.     if self.facing < 0 then
  264.         self.facing = 3
  265.     elseif self.facing > 3 then
  266.         self.facing = 0
  267.     end
  268.     self.compass = direction[self.facing + 1] --+1 to allow for lua indexing at 1
  269. end
  270. function clsTurtle.getCompass(self) return self.compass end
  271. function clsTurtle.getPlaceItem(self) return self.placeItem end
  272. function clsTurtle.setPlaceItem(self, item, useDamage)
  273.     local success = false
  274.     local slot = clsTurtle.getItemSlot(self, item, useDamage)
  275.     if slot > 0 then
  276.         self.placeItem = item
  277.     end
  278. end
  279. function clsTurtle.getEquipped(self, side)
  280.     retValue = ""
  281.     if side == "left" then
  282.         retValue = self.equippedLeft
  283.     else
  284.         retValue = self.equippedRight
  285.     end
  286.     return retValue
  287. end
  288. function clsTurtle.setEquipped(self, side, value)
  289.     if side == "left" then
  290.         self.equippedLeft = value
  291.     elseif side == "right" then
  292.         self.equippedRight = value
  293.     end
  294. end
  295. function clsTurtle.getUserBlocks(self)
  296.     -- self.userBlocks[1] = {string<name>, string<item>, int<count>, bool<userChoice>}
  297.     return self.userBlocks
  298. end
  299. function clsTurtle.getUserBlockType(self, name)
  300.     local retValue = {} --retValue["minecraft:stone_pressure_plate"] = 2
  301.     if next(self.userBlocks) ~= nil then
  302.         for i = 1, #self.userBlocks do
  303.             if self.userBlocks[i][1] == name then
  304.                 retValue[self.userBlocks[i][2]] = self.userBlocks[i][3]
  305.             end
  306.         end
  307.     end
  308.     return retValue --retValue["minecraft:stone_pressure_plate"] = 2, retValue["minecraft:oak_pressure_plate"] = 2
  309. end
  310. function clsTurtle.addUserBlocks(self, blockTable)
  311.     table.insert(self.userBlocks, blockTable)
  312. end
  313.  
  314. -- change direction and movement methods
  315. function clsTurtle.attack(self, direction) 
  316.     direction = direction or "all"
  317.     turtle.select(1)
  318.     local success = false
  319.     local attackLimit = 30 -- won't get in infinite loop attacking a minecart chest
  320.     local Attack
  321.     local up, down, forward = true, true, true
  322.     if direction == "up" then
  323.         Attack = turtle.attackUp
  324.     elseif direction == "down" then
  325.         Attack = turtle.attackDown
  326.     elseif direction == "forward" then
  327.         Attack = turtle.attack
  328.     end
  329.     if direction == "all" then
  330.         while up or down or forward do
  331.             forward = turtle.attack()
  332.             up = turtle.attackUp()
  333.             down = turtle.attackDown()
  334.             if up or down or forward then -- attack in at least 1 direction succeeeded
  335.                 sleep(0.5)
  336.             end
  337.             attackLimit = attackLimit - 1
  338.             if attackLimit <= 0 then
  339.                 break
  340.             end
  341.         end
  342.     else
  343.         while Attack() do --in case mob around
  344.             sleep(0.5)
  345.             attackLimit = attackLimit - 1
  346.             if attackLimit <= 0 then
  347.                 break
  348.             end        
  349.         end
  350.     end
  351.  
  352.     if attackLimit > 0 then
  353.         success = true
  354.     end
  355.     return success
  356. end
  357.  
  358. function clsTurtle.doMoves(self, numBlocksRequested, direction)
  359.     local errorMsg = nil
  360.     local numBlocksMoved = 0
  361.     local Move, Dig, Detect
  362.     local bypass = false
  363.     local bypassCount = 0
  364.     local blockType
  365.     numBlocksRequested = numBlocksRequested or 1
  366.     clsTurtle.refuel(self, steps)
  367.     turtle.select(1)
  368.     -- re-assign turtle functions to new variables
  369.     if direction == "forward" or direction == "back" then
  370.         Move = turtle.forward
  371.         Dig = turtle.dig
  372.         Detect = turtle.detect
  373.     elseif direction == "up" then
  374.         Move = turtle.up
  375.         Dig = turtle.digUp
  376.         Detect = turtle.detectUp
  377.     else
  378.         Move = turtle.down
  379.         Dig = turtle.digDown
  380.         Detect = turtle.detectDown
  381.     end
  382.    
  383.     if direction == "back" then
  384.         clsTurtle.turnRight(self, 2)
  385.     end
  386.     if numBlocksRequested == 0 then
  387.         return 0
  388.     end
  389.     for i = 1, numBlocksRequested, 1 do
  390.         local digOK, digError
  391.         if bypass then
  392.             bypassCount = bypassCount + 1
  393.             if bypassCount >= 1 then
  394.                 bypass = false
  395.                 bypassCount = 0
  396.             end
  397.         else
  398.             if Detect() then -- block above/forward/below
  399.                 blockType, bypass = clsTurtle.checkNoDigBlocks(self, direction)
  400.                 if bypass then --moved round bedrock, spawner, turtle or full chest
  401.                     digOK, digError = Dig()
  402.                     if digOK then
  403.                         sleep(0.5) -- allow sand / gravel to drop if digging forward / up
  404.                     else -- unable to dig, or nothing to dig
  405.                         if digError:lower():find("unbreakable") ~= nil then -- different messages between versions all contain 'unbreakable'
  406.                             errorMsg = digError
  407.                             print(digError)
  408.                             break
  409.                         else -- not bedrock, could be mob or minecart
  410.                             clsTurtle.attack(self)
  411.                         end
  412.                     end
  413.                 end
  414.             end
  415.             if not bypass then
  416.                 local moveOK, moveError = Move() -- try to move forward/up/down
  417.                 if moveOK then
  418.                     numBlocksMoved = numBlocksMoved + 1
  419.                     clsTurtle.changeCoords(self, direction)
  420.                 else
  421.                     while not moveOK do -- did not move if obstruction
  422.                         digOK, digError = Dig()
  423.                         if digOK then
  424.                             sleep(0.5) -- allow sand / gravel to drop if digging forward / up
  425.                         else -- unable to dig, or nothing to dig
  426.                             if digError:lower():find("unbreakable") ~= nil then -- different messages between versions all contain 'unbreakable'
  427.                                 errorMsg = digError
  428.                                 print(digError)
  429.                                 break
  430.                             else -- not bedrock, could be mob or minecart
  431.                                 clsTurtle.attack(self)
  432.                             end
  433.                         end
  434.                         moveOK, moveError = Move() -- try to move forward/up/down again
  435.                         if moveOK then
  436.                             numBlocksMoved = numBlocksMoved + 1
  437.                             clsTurtle.changeCoords(self, direction)
  438.                         end
  439.                     end
  440.                 end
  441.             end
  442.         end
  443.     end
  444.    
  445.     if direction == "back" then
  446.         clsTurtle.turnRight(self, 2)
  447.     end
  448.    
  449.     return numBlocksMoved, errorMsg
  450. end
  451.  
  452. function clsTurtle.back(self, steps)
  453.     steps = steps or 1
  454.     local success = false
  455.     local blocksMoved, errorMsg = clsTurtle.doMoves(self, steps, "back")
  456.     if blocksMoved == steps then
  457.         success = true
  458.     end
  459.     return success, blocksMoved, errorMsg
  460. end
  461.  
  462. function clsTurtle.changeCoords(self, direction)
  463.     --  0 = go south (z increases)
  464.     --  1 = go west  (x decreases)
  465.     --  2 = go north (z decreases
  466.     --  3 = go east  (x increases)
  467.     if direction == "forward" then
  468.         if self.facing == 0 then
  469.             self.z = self.z + 1
  470.         elseif self.facing == 1 then
  471.             self.x = self.x - 1
  472.         elseif self.facing == 2 then
  473.             self.z = self.z - 1
  474.         else
  475.             self.x = self.x + 1
  476.         end
  477.     elseif direction == "back" then
  478.         if self.facing == 0 then
  479.             self.z = self.z - 1
  480.         elseif self.facing == 1 then
  481.             self.x = self.x + 1
  482.         elseif self.facing == 2 then
  483.             self.z = self.z + 1
  484.         else
  485.             self.x = self.x - 1
  486.         end
  487.     elseif direction == "up" then
  488.         self.y = self.y + 1
  489.     elseif direction == "down" then
  490.         self.y = self.y - 1
  491.     end
  492. end
  493.  
  494. function clsTurtle.down(self, steps, getBlockType)
  495.     steps = steps or 1
  496.     if getBlockType == nil then getBlockType = false end
  497.     local success = false
  498.     local blockType = nil
  499.     local blocksMoved, errorMsg = clsTurtle.doMoves(self, steps, "down")
  500.     if blocksMoved == steps then
  501.         success = true
  502.     end
  503.     if getBlockType then
  504.         blockType = clsTurtle.getBlockType(self, "down")
  505.     end
  506.     return success, blocksMoved, errorMsg, blockType
  507. end
  508.  
  509. function clsTurtle.forward(self, steps)    
  510.     steps = steps or 1
  511.     local success = false
  512.     local blocksMoved, errorMsg = clsTurtle.doMoves(self, steps, "forward")
  513.     if blocksMoved == steps then
  514.         success = true
  515.     end
  516.     return success, blocksMoved, errorMsg
  517. end
  518.  
  519. function clsTurtle.turnLeft(self, steps)
  520.     steps = steps or 1
  521.     for i = 1, steps do
  522.         turtle.turnLeft()
  523.         self.facing = self.facing - 1
  524.         if self.facing < 0 then
  525.             self.facing = 3
  526.         end
  527.     end
  528. end
  529.  
  530. function clsTurtle.turnRight(self, steps)
  531.     steps = steps or 1
  532.     for i = 1, steps do
  533.         turtle.turnRight()
  534.         self.facing = self.facing + 1
  535.         if self.facing > 3 then
  536.             self.facing = 0
  537.         end
  538.     end
  539. end
  540.  
  541. function clsTurtle.up(self, steps)
  542.     steps = steps or 1
  543.     local success = false
  544.     local blocksMoved, errorMsg = clsTurtle.doMoves(self, steps, "up")
  545.     if blocksMoved == steps then
  546.         success = true
  547.     end
  548.     return success, blocksMoved, errorMsg
  549. end
  550. -- other methods
  551. function clsTurtle.checkInventoryForItem(self, items, quantities, required, message)
  552.     local lib = {}
  553.    
  554.     function lib.checkInventory(self, items, quantities, inventory)
  555.         --[[
  556.         Does the inventory have any or all of the items required?
  557.         Multiple choices are similar alternatives eg cobblestone, dirt. Most requests are single item
  558.         eg requested: {"stone", "dirt"}, quantities: { 256, 256 }
  559.         eg inventory: {"minecraft:cobblestone" = 128, "minecraft:dirt" = 100}  = 228: still need 28 cobble or dirt
  560.         could be empty!
  561.         ]]
  562.         -- on first entry currentItems = {}
  563.         local waiting = true            -- return value. set to false if not enough put in the inventory for this item
  564.         local quantitiesFound = {}      -- table of quantities found, based on no of items needed
  565.         for i = 1, #quantities do       -- Initialise table eg {0, 0, 0}   
  566.             table.insert(quantitiesFound, 0)
  567.         end
  568.         for i = 1, #items do                                -- check if item(s) already present
  569.             local findItem = items[i]
  570.             for k, v in pairs(inventory) do                 -- eg: {"minecraft:cobblestone" = 128, "minecraft:dirt" = 203}
  571.                 if findItem:find("\:") ~= nil then          -- specific item requested eg "minecraft:cobblestone"
  572.                     if findItem == k then                   -- exact match eg "minecraft:cobblestone" requested, "minecraft:cobblestone" found
  573.                         item = k                            -- item = "minecraft:cobblestone"
  574.                         quantitiesFound[i] = v
  575.                     end
  576.                 else                                        -- non specific eg "log", "pressure_plate", "stone"
  577.                     if findItem == "stone" then             -- check for allowed blocks in global table stone
  578.                         for _, stonetype in ipairs(stone) do
  579.                             if k == stonetype then          -- k = "minecraft:cobblestone" matches with stonetype
  580.                                 quantitiesFound[i] = quantitiesFound[i] + v
  581.                             end
  582.                         end
  583.                     elseif k:find(findItem) ~= nil then     -- similar item exists already eg "pressure_plate" is in "minecraft:stone_pressure_plate"
  584.                         quantitiesFound[i] = quantitiesFound[i] + v
  585.                     end
  586.                 end
  587.             end
  588.         end
  589.         local totalFound = 0
  590.         for i = 1, #quantities do
  591.             totalFound = totalFound + quantitiesFound[i]
  592.             if totalFound >= quantities[i] then
  593.                 waiting = false
  594.             end
  595.         end
  596.         if waiting then -- update quantities
  597.             for i = 1, #quantitiesFound do
  598.                 quantitiesFound[i] = totalFound -- when player asked to supply alternatives, this gives quantities
  599.             end
  600.         end
  601.         return waiting, quantitiesFound
  602.     end
  603.    
  604.     function lib.getInventory(self)
  605.         --[[ table eg: {"minecraft:cobblestone" = 256, "minecraft:cobbled_deepslate = 256"}  ]]
  606.         local inventory = {}
  607.         for slot = 1, 16 do
  608.             local slotContains, slotCount, slotDamage = clsTurtle.getSlotContains(self, slot)
  609.             if slotContains ~= "" then -- eg "minecraft:cobblestone"
  610.                 if inventory[slotContains] ~= nil then --already exists in inventory
  611.                     inventory[slotContains] = inventory[slotContains] + slotCount --update quantities
  612.                 else
  613.                     inventory[slotContains] = slotCount
  614.                 end
  615.             end
  616.         end
  617.         return inventory
  618.     end
  619.        
  620.     if required == nil then required = true end
  621.     if message == nil then message = "" end     -- add further instructions
  622.     local inventory = lib.getInventory(self)    -- create table of blocktypes and quantities
  623.     local inventoryChanged = false
  624.     local enteringLoop = true
  625.     local waiting = true
  626.     local quantitiesFound = {}
  627.     while waiting do -- true on first entry, also enteringLoop = true check slots and inventory in waiting loop to see if new items are added
  628.         --clsTurtle.clear(self)
  629.         if inventoryChanged or enteringLoop then
  630.             clsTurtle.clear(self)
  631.             enteringLoop = false --flag reset loop has iterated at least once
  632.             inventoryChanged = false
  633.             waiting, quantitiesFound = lib.checkInventory(self, items, quantities, inventory) -- are we still waiting, table of found quantities
  634.             if waiting then --insufficient items so ask for more
  635.                 if message ~= "" then
  636.                     print(message)
  637.                 end
  638.                 if quantitiesFound[1] < quantities[1] then
  639.                     print("Add "..quantities[1] - quantitiesFound[1].." "..clsTurtle.trimItemName(self, items[1]).." to any slot(s)")
  640.                     for i = 2, #items do
  641.                         print("Or add "..quantities[i] - quantitiesFound[i].." "..clsTurtle.trimItemName(self, items[i]).." to any slot(s)")
  642.                     end
  643.                 end
  644.                 if not required then
  645.                     print("(Optional: 'Enter' if not required)")
  646.                 end
  647.             end
  648.         end
  649.         if waiting then -- not enough onBoard, so wait for user to interact with inventory or press Enter
  650.             local event, param1 = os.pullEvent()
  651.             if event == "turtle_inventory" then
  652.                 inventoryChanged = true
  653.                 -- user has added, moved or removed inventory items
  654.                 inventory = lib.getInventory(self)
  655.             --elseif event == "key"  and not required then
  656.             elseif event == "key" then
  657.                 if param1 == keys.enter then
  658.                     clsTurtle.clear(self)
  659.                     return nil -- stop waiting and exit
  660.                 end
  661.             end
  662.         end
  663.     end
  664.     if required then
  665.         return quantitiesFound
  666.     else
  667.         return nil --if item not required
  668.     end
  669. end
  670.  
  671. function clsTurtle.checkNoDigBlocks(self, direction, moveRound)
  672.     if moveRound == nil then
  673.         moveRound = false
  674.     end
  675.     local bypass = false
  676.     local isSpawner = false
  677.     local blockType, blockModifier = clsTurtle.getBlockType(self, direction)
  678.     -- if mob spawner or chest found, go round it. Do not break!
  679.     if blockType ~= "" then
  680.         if blockType:find("spawner") ~= nil then
  681.             clsTurtle.writeCoords(self, "SpawnerCoords.txt")
  682.             bypass = true
  683.             isSpawner = true
  684.             print("Spawner Found!")
  685.         elseif blockType:find("turtle") ~= nil then --do not break another turtle
  686.             bypass = true
  687.         elseif blockType:find("chest") ~= nil or blockType:find("minecart") ~= nil then
  688.             local success, msg
  689.             repeat
  690.                 success, msg = clsTurtle.suck(self, direction)
  691.             until not success
  692.             if clsTurtle.getFirstEmptySlot(self) == 0 then -- turtle is full
  693.                 bypass = true
  694.             else
  695.                 clsTurtle.dig(self, direction)
  696.             end
  697.         end
  698.     end
  699.     if bypass and (moveRound or isSpawner)  then
  700.         if direction == "up" then
  701.             clsTurtle.go(self, "F1U2R2F1R2", false, 0, false, false)
  702.         elseif direction == "forward" then
  703.             clsTurtle.go(self, "U1F2D1", false, 0, false, false)
  704.         elseif direction == "down" then
  705.             clsTurtle.go(self, "F1D2R2F1R2", false, 0, false, false)
  706.         end
  707.         --blockType, blockModifier = clsTurtle.getBlockType(self, direction)
  708.     end
  709.     return blockType, bypass -- bypass true should be used to reduce steps in calling routine
  710. end
  711.  
  712. function clsTurtle.clear(self)
  713.     term.clear()
  714.     term.setCursorPos(1,1)
  715. end
  716.  
  717. function clsTurtle.craft(self, item, quantity) 
  718.     --[[
  719.         eg stairs, 40
  720.         setup for crafting chest, planks, stairs
  721.     ]]
  722.     local craftOK = false
  723.     local message = ""
  724.     local chestSlot = 0
  725.     local holeSlot = 0
  726.     local sourceSlot = 0
  727.     local turns = 0
  728.    
  729.     chestSlot = clsTurtle.getItemSlot(self, "chest", -1) --get the slot number containing a chest
  730.     if chestSlot == 0 then -- chest not found
  731.         if item == "planks" then -- could be new turtle and tree felling
  732.             sourceSlot = clsTurtle.getItemSlot(self, "log", -1) --get the slot number containing log(s)
  733.             if sourceSlot > 0 then
  734.                 if turtle.craft() then
  735.                     return true, ""
  736.                 else
  737.                     return false, "Unable to craft planks"
  738.                 end
  739.             end
  740.         elseif item == "chest" then -- assume chest needed and logs are onboard
  741.             sourceSlot = clsTurtle.getItemSlot(self, "log", -1) --get the slot number containing log(s)
  742.             if sourceSlot > 0 then
  743.                 if turtle.craft() then-- craft logs into planks
  744.                     sourceSlot = clsTurtle.getItemSlot(self, "planks", -1) --get the slot number containing planks
  745.                     if sourceSlot > 0 then             
  746.                         turtle.select(sourceSlot)
  747.                         turtle.transferTo(16) --move crafting item to 16
  748.                         turtle.select(16)
  749.                         turtle.transferTo(1, 1)
  750.                         turtle.transferTo(2, 1)
  751.                         turtle.transferTo(3, 1)
  752.                         turtle.transferTo(5, 1)
  753.                         turtle.transferTo(7, 1)
  754.                         turtle.transferTo(9, 1)
  755.                         turtle.transferTo(10, 1)
  756.                         turtle.transferTo(11, 1)
  757.                         if turtle.craft() then
  758.                             return true, ""
  759.                         else
  760.                             return false, "Unable to craft chest"
  761.                         end
  762.                     end
  763.                 else
  764.                     return false, "Unable to craft planks"
  765.                 end
  766.             else
  767.                 return false, "No logs available"
  768.             end
  769.         elseif item == "slab" then -- assume 3 stone -> slab for mob spawner
  770.             sourceSlot = clsTurtle.getItemSlot(self, "stone", -1) --get the slot number containing stone
  771.             if sourceSlot > 0 then
  772.                 turtle.select(sourceSlot)
  773.                 turtle.transferTo(16) --move crafting item to 16
  774.                 turtle.select(16)
  775.                 turtle.transferTo(1, 1)
  776.                 turtle.transferTo(2, 1)
  777.                 turtle.transferTo(3, 1)
  778.                 for i = 4, 16 do
  779.                     if turtle.getItemCount(i) > 0 then
  780.                         turtle.select(i)
  781.                         turtle.dropUp()
  782.                     end
  783.                 end
  784.                 if turtle.craft(1) then
  785.                     return true, ""
  786.                 else
  787.                     return false, "Unable to craft slab"
  788.                 end
  789.             end
  790.         else
  791.             return false, "No chest for crafting"
  792.         end
  793.     end
  794.     local stock = {}
  795.     --[[
  796.         rt.total = total
  797.         rt.mostSlot = slotData.mostSlot
  798.         rt.leastSlot = slotData.leastSlot
  799.         rt.mostCount = slotData.mostCount
  800.         rt.leastCount = slotData.leastCount
  801.         ]]
  802.     if item:find("stairs") ~= nil then -- craft stairs, check stone, planks
  803.         stock = clsTurtle.getStock(self, "stone", -1) --get the slot number containing stone
  804.         sourceSlot = stock.mostSlot
  805.         message = "No stone for crafting stairs"
  806.     elseif item:find("chest") ~= nil then -- craft chest
  807.         stock = clsTurtle.getStock(self, "planks", -1) --get the slot number containing planks
  808.         sourceSlot = stock.mostSlot
  809.         message = "No planks for crafting chest"
  810.     elseif item:find("planks") ~= nil then -- craft planks
  811.         stock = clsTurtle.getStock(self, "log", -1) --get the slot number containing logs
  812.         sourceSlot = stock.mostSlot
  813.         message = "No logs for crafting planks"
  814.     end
  815.     if sourceSlot == 0 then
  816.         return false, message
  817.     end
  818.     while turtle.detect() do --check for clear space to place chest
  819.         clsTurtle.turnRight(self, 1)
  820.         turns = turns + 1
  821.         if turns == 4 then
  822.             turns = 0
  823.             break
  824.         end
  825.     end
  826.     turtle.select(1)
  827.     while turtle.detect() do --clear space in front. Use loop in case of sand/gravel falling
  828.         turtle.dig()
  829.         sleep(.5)
  830.     end
  831.     turtle.select(chestSlot) --should be slot with chest
  832.     while not turtle.place() do
  833.         clsTurtle.attack(self)
  834.     end
  835.     -- fill chest with everything except required items
  836.     for i = 1, 16 do
  837.         if i ~= sourceSlot then
  838.             turtle.select(i)
  839.             turtle.drop()
  840.         end
  841.     end
  842.     -- error here if turtle empty
  843.     turtle.select(sourceSlot)
  844.     turtle.transferTo(16) --move crafting item to 16
  845.     --ready to craft
  846.     turtle.select(16)
  847.     if item:find("planks") ~= nil then -- crafting planks
  848.         turtle.transferTo(1, quantity / 4)
  849.     elseif item:find("chest") ~= nil then  --craft("chest", 1)
  850.         --8 planks = 1 chest
  851.         turtle.transferTo(1, 1)
  852.         turtle.transferTo(2, 1)
  853.         turtle.transferTo(3, 1)
  854.         turtle.transferTo(5, 1)
  855.         turtle.transferTo(7, 1)
  856.         turtle.transferTo(9, 1)
  857.         turtle.transferTo(10, 1)
  858.         turtle.transferTo(11, 1)
  859.     elseif item:find("stairs") ~= nil then  --craft("stairs", 40)
  860.         --6 cobblestone = 4 stairs
  861.         turtle.transferTo(1, math.ceil(quantity / 4))
  862.         turtle.transferTo(5, math.ceil(quantity / 4))
  863.         turtle.transferTo(6, math.ceil(quantity / 4))
  864.         turtle.transferTo(9, math.ceil(quantity / 4))
  865.         turtle.transferTo(10, math.ceil(quantity / 4))
  866.         turtle.transferTo(11, math.ceil(quantity / 4))
  867.     end
  868.     turtle.select(16)
  869.     turtle.drop() --drop remaining resources before crafting
  870.     -- Attempt to craft item into slot 16
  871.     if turtle.craft() then
  872.         craftOK = true
  873.         --now put crafted item in chest first, so will mix with any existing similar items
  874.         turtle.drop()
  875.     else --crafting not successful, so empty out all items into chest
  876.         for i = 1, 16 do
  877.             if turtle.getItemCount(i) > 0 then
  878.                 turtle.select(i)
  879.                 turtle.drop()
  880.             end
  881.         end
  882.     end
  883.     turtle.select(1) --empty chest into slot 1 onwards
  884.     while turtle.suck() do end
  885.     turtle.dig() -- collect chest
  886.     if turns > 0 then --return to original position
  887.         clsTurtle.turnLeft(self,turns)
  888.     end
  889.    
  890.     return craftOK, message
  891. end
  892.  
  893. function clsTurtle.createTunnel(self, length, allowAbandon)
  894.     -- clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting)
  895.     -- assume at floor level at start
  896.     local leaveExisting = true
  897.     local useTorch = false
  898.     local distance  = 1
  899.     local blockAbove = ""
  900.     local aboveType = 0
  901.     local blockBelow = ""
  902.     local belowType = 0
  903.     local waterCountAbove = 0
  904.     local waterCountBelow = 0
  905.     local onGround = true
  906.     for i = 1, length do
  907.         if onGround then -- 1, 3, 5, 7 etc
  908.             blockBelow, belowType = clsTurtle.getBlockType(self, "down")
  909.             if blockBelow ~= "" then
  910.                 if blockBelow:find("lava") ~= nil then
  911.                     clsTurtle.go(self, "C2L1C1R2C1L1", useTorch, 0, leaveExisting)
  912.                 elseif blockBelow:find("water") ~= nil then
  913.                     clsTurtle.go(self, "C2", useTorch, 0, leaveExisting)
  914.                     waterCountBelow = waterCountBelow + 1
  915.                 else
  916.                     clsTurtle.go(self, "C2", useTorch, 0, leaveExisting)
  917.                 end
  918.             else
  919.                 clsTurtle.go(self, "C2", useTorch, 0, leaveExisting)
  920.             end
  921.             clsTurtle.up(self, 1)
  922.             onGround = false
  923.             blockAbove, aboveType = clsTurtle.getBlockType(self, "up")
  924.             if blockAbove ~= "" then
  925.                 if blockAbove:find("lava") ~= nil then
  926.                     clsTurtle.go(self, "C0L1C1R2C1L1", useTorch, 0, leaveExisting)
  927.                 elseif blockAbove:find("water") ~= nil then
  928.                     clsTurtle.go(self, "C0L1C1R2C1L1", useTorch, 0, leaveExisting)
  929.                     waterCountAbove = waterCountAbove + 1
  930.                 else
  931.                     clsTurtle.go(self, "C0", useTorch, 0, leaveExisting)
  932.                 end
  933.             else
  934.                 clsTurtle.go(self, "C0", useTorch, 0, leaveExisting)
  935.             end
  936.             -- if on first block check behind
  937.             if i == 1 then
  938.                 clsTurtle.go(self, "R2C1R2", useTorch, 0, leaveExisting)
  939.             end
  940.             if distance >= 8 then
  941.                 if distance % 8 == 0 then -- 8th or other position
  942.                     clsTurtle.go(self, "t5", useTorch, 0, false)
  943.                 end
  944.             end
  945.         else -- at ceiling 2, 4, 6, 8 etc
  946.             blockAbove, aboveType = clsTurtle.getBlockType(self, "up")
  947.             if blockAbove ~= "" then
  948.                 if blockAbove:find("lava") ~= nil then
  949.                     clsTurtle.go(self, "C0L1C1R2C1L1", useTorch, 0, leaveExisting)
  950.                 elseif blockAbove:find("water") ~= nil then
  951.                     clsTurtle.go(self, "C0L1C1R2C1L1", useTorch, 0, leaveExisting)
  952.                     waterCountAbove = waterCountAbove + 1
  953.                 else
  954.                     clsTurtle.go(self, "C0", useTorch, 0, leaveExisting)
  955.                 end
  956.             else
  957.                 clsTurtle.go(self, "C0", useTorch, 0, leaveExisting)
  958.             end
  959.             if distance == 2 then
  960.                 clsTurtle.go(self, "t1", useTorch, 0, false)
  961.             end
  962.             clsTurtle.down(self, 1)
  963.             onGround = true
  964.             blockBelow, belowType = clsTurtle.getBlockType(self, "down")
  965.             if blockBelow ~= "" then
  966.                 if blockBelow:find("lava") ~= nil then
  967.                     clsTurtle.go(self, "C2L1C1R2C1L1", useTorch, 0, leaveExisting)
  968.                 elseif blockBelow:find("water") ~= nil then
  969.                     clsTurtle.go(self, "C2", useTorch, 0, leaveExisting)
  970.                     waterCountBelow = waterCountBelow + 1
  971.                 else
  972.                     clsTurtle.go(self, "C2", useTorch, 0, leaveExisting)
  973.                 end
  974.             else
  975.                 clsTurtle.go(self, "C2", useTorch, 0, leaveExisting)
  976.             end
  977.         end
  978.         -- now move forward if length > 1
  979.         if length > 1 then
  980.             if i < length then -- not on last iteration
  981.                 clsTurtle.forward(self,1)
  982.                 distance = distance + 1
  983.             else -- on last iteration
  984.                 if not onGround then
  985.                     clsTurtle.go(self, "C1", useTorch, 0, leaveExisting)
  986.                     clsTurtle.down(self, 1)
  987.                     onGround = true
  988.                 end
  989.             end
  990.         else -- one unit only so move down
  991.             clsTurtle.down(self, 1)
  992.             onGround = true
  993.         end
  994.        
  995.         if allowAbandon then
  996.             if waterCountAbove + waterCountBelow >= 6 then
  997.                 if not onGround then
  998.                     clsTurtle.down(self, 1)
  999.                     onGround = true
  1000.                 end
  1001.                 break
  1002.             end
  1003.         end
  1004.     end
  1005.    
  1006.     return distance -- 1 to length. cut short if 3 or more water
  1007. end
  1008.  
  1009. function clsTurtle.detect(self, direction)
  1010.     direction = direction or "forward"
  1011.    
  1012.     local Detect = turtle.detect
  1013.     if direction == "up" then
  1014.         Detect = turtle.detectUp
  1015.     elseif direction == "down" then
  1016.         Detect = turtle.detectDown
  1017.     end
  1018.    
  1019.     return Detect()
  1020. end
  1021.  
  1022. function clsTurtle.dig(self, direction, bypass, slot)
  1023.     --[[ To dig a chest use T:dig(direction, false)  ]]
  1024.     direction = direction or "forward"
  1025.     bypass = bypass or true -- allows digging any block including chests and spawners
  1026.     slot = slot or 1
  1027.     local success = false
  1028.     local blockType = ""
  1029.     local Dig = turtle.dig
  1030.     if direction == "up" then
  1031.         Dig = turtle.digUp
  1032.     elseif direction == "down" then
  1033.         Dig = turtle.digDown
  1034.     end
  1035.    
  1036.     turtle.select(slot)
  1037.     if bypass then
  1038.         blockType, bypass = clsTurtle.checkNoDigBlocks(self, direction, false)
  1039.     end
  1040.     if not bypass then --bypass true if chest, turtle or minecart
  1041.         while Dig() do
  1042.             sleep(0.5)
  1043.             success = true
  1044.         end
  1045.     end
  1046.     turtle.select(1)
  1047.     return success
  1048. end
  1049.  
  1050. function clsTurtle.digGravityBlock(self, direction)
  1051.     local Dig = turtle.dig
  1052.     if direction == "up" then
  1053.         Dig = turtle.digUp
  1054.     elseif direction == "down" then
  1055.         Dig = turtle.digDown
  1056.     end
  1057.     local blockType = clsTurtle.getBlockType(self, direction)
  1058.     turtle.select(1)
  1059.     if blockType:find("sand") ~= nil or blockType:find("gravel") ~= nil then
  1060.         Dig()
  1061.         return true
  1062.     else
  1063.         return false
  1064.     end
  1065.  
  1066. end
  1067.  
  1068. function clsTurtle.digValuable(self, direction)
  1069.     local Dig = turtle.dig
  1070.     if direction == "up" then
  1071.         Dig = turtle.digUp
  1072.     elseif direction == "down" then
  1073.         Dig = turtle.digDown
  1074.     end
  1075.     local isValuable, blockType = clsTurtle.isValuable(self, direction)
  1076.     if isValuable then
  1077.         Dig()
  1078.         return true
  1079.     else --check for lava
  1080.         if blockType:find("lava") ~= nil then
  1081.             clsTurtle.place(self, "minecraft:bucket", -1, direction)  -- will automatically find empty bucket and refuel
  1082.             return true
  1083.         else
  1084.             return false
  1085.         end
  1086.     end
  1087.     turtle.select(1)
  1088. end
  1089.  
  1090. function clsTurtle.drop(self, direction, slot, amount)
  1091.     direction = direction or "forward"
  1092.     slot = slot or 1
  1093.     local success = false
  1094.     local drop = turtle.drop
  1095.     if direction == "up" then
  1096.         drop = turtle.dropUp
  1097.     elseif direction == "down" then
  1098.         drop = turtle.dropDown
  1099.     end
  1100.     if slot == 0 then
  1101.         print("Slot 0 parameter T:drop")
  1102.         error()
  1103.     end
  1104.     turtle.select(slot)
  1105.  
  1106.     if amount == nil then
  1107.         success = drop()
  1108.     else
  1109.         success = drop(amount)
  1110.     end
  1111.     turtle.select(1)
  1112.     return success
  1113. end
  1114.  
  1115. function clsTurtle.dropAll(self, direction)
  1116.     direction = direction or "forward"
  1117.     local Drop = turtle.drop
  1118.     local success = true
  1119.     if direction == "up"  then
  1120.         Drop = turtle.dropUp
  1121.     elseif direction == "down" then
  1122.         Drop = turtle.dropDown
  1123.     end
  1124.     for i = 1, 16 do
  1125.         if turtle.getItemCount(i) > 0 then
  1126.             turtle.select(i)
  1127.             if not Drop() then
  1128.                 success = false
  1129.             end
  1130.         end
  1131.     end
  1132.     turtle.select(1)
  1133.     return success
  1134. end
  1135.  
  1136. function clsTurtle.dropItem(self, item, direction, keepAmount)
  1137.     direction = direction or "forward"
  1138.     local itemSlot = 0
  1139.     local stockData = {}
  1140.     local success = false
  1141.    
  1142.     if keepAmount == nil or keepAmount <= 0 then -- drop everything
  1143.         itemSlot = clsTurtle.getItemSlot(self, item, -1)
  1144.         while itemSlot > 0 do
  1145.             if not clsTurtle.drop(self, direction, itemSlot) then
  1146.                 return false
  1147.             end
  1148.             itemSlot = clsTurtle.getItemSlot(self, item, -1)
  1149.         end
  1150.     else -- keep a specific amount
  1151.         -- {rt.total, rt.mostSlot, rt.leastSlot, rt.mostCount, rt.leastCount}
  1152.         stockData = clsTurtle.getStock(self, item)
  1153.         while stockData.total > keepAmount do
  1154.             if stockData.total - stockData.leastCount > keepAmount then
  1155.                 success = clsTurtle.drop(self, direction, stockData.leastSlot)
  1156.             else
  1157.                 success = clsTurtle.drop(self, direction, stockData.leastSlot, stockData.total - keepAmount)
  1158.             end
  1159.             if not success then
  1160.                 break
  1161.             end
  1162.             stockData = clsTurtle.getStock(self, item)
  1163.         end
  1164.     end
  1165.     turtle.select(1)
  1166.     return success
  1167. end
  1168.  
  1169. function clsTurtle.dumpRefuse(self, direction, keepCobbleStacks)
  1170.     --dump dirt, cobble, sand, gravel
  1171.     local Drop = turtle.drop
  1172.     if direction == "up" then
  1173.         Drop = turtle.dropUp
  1174.     else
  1175.         Drop = turtle.dropDown
  1176.     end
  1177.     keepCobbleStacks = keepCobbleStacks or 0
  1178.     local itemlist = {"gravel", "stone", "sand", "flint"}
  1179.     local cobbleCount = 0
  1180.  
  1181.     for i = 1, 16 do
  1182.         local blockType, slotCount,  blockModifier = clsTurtle.getSlotContains(self, i)
  1183.        
  1184.         if blockType:find("cobble") ~= nil or blockType:find("netherrack") then
  1185.             if cobbleCount > keepCobbleStacks then
  1186.                 turtle.select(i)
  1187.                 Drop()
  1188.             else
  1189.                 cobbleCount = cobbleCount + 1
  1190.             end
  1191.         end
  1192.         for j = 1, #itemlist do
  1193.             if blockType:find(itemlist[j]) ~= nil then
  1194.                 turtle.select(i)
  1195.                 Drop()
  1196.                 break
  1197.             end
  1198.         end
  1199.     end
  1200.     turtle.select(1)
  1201. end
  1202.  
  1203. function clsTurtle.emptyInventory(self, direction)
  1204.     --[[ Dump everything!]]
  1205.     direction = direction or "down"
  1206.     local Drop = turtle.dropDown
  1207.     if direction == "up" then
  1208.         Drop = turtle.dropUp
  1209.     elseif direction == "forward" then
  1210.         Drop = turtle.drop
  1211.     end
  1212.     for i = 1, 16 do
  1213.         turtle.select(i)
  1214.         Drop()
  1215.     end
  1216.     turtle.select(1)
  1217. end
  1218.  
  1219. function clsTurtle.emptyInventorySelection(self, direction, exceptions, quantities)
  1220.     --[[ Dump everything except items in exceptions eg {"oak_sapling"}, {64} ]]
  1221.     clsTurtle.sortInventory(self)
  1222.     direction = direction or "down"
  1223.     local Drop = turtle.dropDown
  1224.     if direction == "up" then
  1225.         Drop = turtle.dropUp
  1226.     elseif direction == "forward" then
  1227.         Drop = turtle.drop
  1228.     end
  1229.     for i = 1, 16 do
  1230.         turtle.select(i)
  1231.         if turtle.getItemCount(i) > 0 then
  1232.             local item = turtle.getItemDetail(i)
  1233.             local name = item.name
  1234.             local inKeepItems = false
  1235.             local index = 0
  1236.             for j = 1, #exceptions do
  1237.                 --print("Checking "..i.." "..name.." with "..exceptions[j])
  1238.                 if name:find(exceptions[j]) ~= nil then
  1239.                     inKeepItems = true
  1240.                     index = j
  1241.                 end
  1242.             end
  1243.             if inKeepItems then
  1244.                 --print(name.." found "..quantities[index].." needed")
  1245.                 if quantities[index] > 0 then
  1246.                     local dropAmount = item.count - quantities[index]
  1247.                     quantities[index] = quantities[index] - item.count
  1248.                     if quantities[index] < 0 then
  1249.                         quantities[index] = 0
  1250.                     end
  1251.                     if dropAmount > 0 then
  1252.                         Drop(dropAmount)
  1253.                     end
  1254.                     -- else if 0 do not drop
  1255.                 end
  1256.             else
  1257.                 Drop()
  1258.             end
  1259.         end
  1260.     end
  1261.     turtle.select(1)
  1262. end
  1263.  
  1264. function clsTurtle.emptyTrash(self, direction)
  1265.     direction = direction or "down"
  1266.     local Drop = turtle.dropDown
  1267.     if direction == "up" then
  1268.         Drop = turtle.dropUp
  1269.     elseif direction == "forward" then
  1270.         Drop = turtle.drop
  1271.     end
  1272.     local slotData = {}
  1273.     local itemName = ""
  1274.     local move = false
  1275.     -- store these items permanently inside turtle
  1276.     local keepItems =   {"netherrack", "cobble", "chest", "torch", "ore", "bucket", "coal", "diamond", "debris", "deepslate","iron","gold","copper"}           
  1277.     local keepit = false                   
  1278.     -- empty excess cobble, dirt, all gravel, unknown minerals
  1279.     -- keep max of 1 stack
  1280.     clsTurtle.sortInventory(self, false) -- do not use chest for sorting as may leave items behind
  1281.     for i = 1, 16 do
  1282.         keepit = false
  1283.         if turtle.getItemCount(i) > 0 then
  1284.             itemName = clsTurtle.getItemName(self, i) -- eg 'minecraft:andesite'
  1285.             for _,v in pairs(keepItems) do
  1286.                 --if v == item then
  1287.                 if itemName:find(v) ~= nil then
  1288.                     keepit = true
  1289.                     break
  1290.                 end
  1291.             end
  1292.             if not keepit then
  1293.                 turtle.select(i)
  1294.                 Drop()
  1295.                 sleep(0.2)
  1296.             end
  1297.         end
  1298.     end
  1299.     clsTurtle.sortInventory(self, false)
  1300.     clsTurtle.emptyTrashItem(self, direction, "minecraft:cobblestone", 192)
  1301.     clsTurtle.emptyTrashItem(self, direction, "minecraft:netherrack", 192)
  1302.     clsTurtle.emptyTrashItem(self, direction, "minecraft:cobbled_deepslate", 192)
  1303.     slotData = clsTurtle.getStock(self, "minecraft:coal", 0)
  1304.     if slotData.total > 64 then
  1305.         if slotData.mostSlot ~= slotData.leastSlot and slotData.leastSlot ~= 0 then
  1306.             turtle.select(slotData.leastSlot)
  1307.             turtle.refuel()
  1308.         end
  1309.     end
  1310.     turtle.select(1)
  1311. end
  1312.  
  1313. function clsTurtle.emptyTrashItem(self, direction, item, keepAmount)
  1314.     --[[ deprecated. left for legacy applications ]]
  1315.     clsTurtle.dropItem(self, item, direction, keepAmount)
  1316. end
  1317.  
  1318. function clsTurtle.equip(self, side, useItem, useDamage)
  1319.     useDamage = useDamage or 0
  1320.     --slotData.leastSlot, slotData.leastModifier, total, slotData
  1321.     local slot, damage = clsTurtle.getItemSlot(self, useItem, -1)
  1322.     local currentSlot = turtle.getSelectedSlot()
  1323.     local success = false
  1324.     --[[
  1325.     minecraft:crafting_table
  1326.     minecraft:diamond_pickaxe
  1327.     minecraft:diamond_sword
  1328.     minecraft:diamond_shovel
  1329.     minecraft:diamond_hoe
  1330.     minecraft:diamond_axe
  1331.     wireless modem = ComputerCraft:CC-Peripheral, damage = 1
  1332.     ]]
  1333.     if slot > 0 then
  1334.     --if slot > 0 and damage == useDamage then
  1335.         turtle.select(slot)
  1336.         if side == "right" then
  1337.             if turtle.equipRight() then
  1338.                 success = true
  1339.                 self.equippedRight = useItem
  1340.             end
  1341.         else
  1342.             if turtle.equipLeft() then
  1343.                 success = true
  1344.                 self.equippedLeft = useItem
  1345.             end
  1346.         end
  1347.     end
  1348.     turtle.select(currentSlot)
  1349.    
  1350.     return success
  1351. end
  1352.  
  1353. function clsTurtle.fillVoid(self, direction, tblPreferredBlock, leaveExisting)
  1354.     assert(type(direction) == "string", "direction is not a string: "..tostring(direction))
  1355.     assert( tblPreferredBlock == nil or
  1356.             type(tblPreferredBlock) == "string" or
  1357.             type(tblPreferredBlock) == "table", "tblPreferredBlock is not nil, string or table: "..tostring(tblPreferredBlock))
  1358.     assert( leaveExisting == nil or type(leaveExisting) == "boolean", "leaveExisting is not boolean: "..tostring(leaveExisting))
  1359.    
  1360.     if tblPreferredBlock == nil or tblPreferredBlock == "" then tblPreferredBlock = {} end
  1361.     if type(tblPreferredBlock) ~= "table" then tblPreferredBlock = {tblPreferredBlock} end -- always use a table
  1362.     if leaveExisting == nil then leaveExisting = true end
  1363.    
  1364.    
  1365.    
  1366.     local Detect = turtle.detect
  1367.     local Place = turtle.place
  1368.     local Dig = turtle.dig
  1369.     if direction == "up" then
  1370.         Detect = turtle.detectUp
  1371.         Place = turtle.placeUp
  1372.         Dig = turtle.digUp
  1373.     elseif direction == "down" then
  1374.         Detect = turtle.detectDown
  1375.         Place = turtle.placeDown
  1376.         Dig = turtle.digDown
  1377.     end
  1378.    
  1379.    
  1380.    
  1381.     local lib = {}
  1382.    
  1383.     function lib.place(direction, placeBlock, currentBlock, slot)
  1384.         if placeBlock ~= currentBlock then -- current block does not match type to be used as filler
  1385.             turtle.select(slot)
  1386.             Dig()
  1387.             local attempts = 0
  1388.             while not Place() do
  1389.                 Dig()   -- added here in case of falling gravel etc.
  1390.                 attempts = attempts + 1
  1391.                 clsTurtle.attack(self)
  1392.                 print("Attacking: "..attempts.." / 5")
  1393.                 sleep(0.5)
  1394.                 if attempts == 5 then
  1395.                     break
  1396.                 end
  1397.             end
  1398.         end
  1399.         turtle.select(1)
  1400.         return true
  1401.     end
  1402.    
  1403.     local placed = false
  1404.     local noBlocks = false
  1405.     local slot = 0
  1406.     local placeBlock = ""
  1407.     --check if vegetation and remove
  1408.     if clsTurtle.isSeaweed(self, direction) then
  1409.         Dig()
  1410.     end
  1411.     if clsTurtle.isGravityBlock(self, direction) then
  1412.         Dig()
  1413.     end
  1414.    
  1415.     local continue = false
  1416.     local currentBlock = clsTurtle.getBlockType(self, direction)
  1417.     if currentBlock ~= "" then      -- solid block already present
  1418.         if  currentBlock:find("gravel") == nil and
  1419.             currentBlock:find("sand") == nil  and
  1420.             currentBlock:find("water") == nil and
  1421.             currentBlock:find("lava") == nil then -- not water, lava, sand or gravel
  1422.             if leaveExisting then
  1423.                 turtle.select(1)
  1424.                 return true, false
  1425.             end
  1426.         end
  1427.     end
  1428.    
  1429.     -- make a table of all existing blocks
  1430.     local stock = clsTurtle.getCurrentInventory(self) -- eg stock[1] = minecraft:dirt, stock[2] = "", stock[3] = "minecraft:cobblestone"
  1431.    
  1432.     --[[ debugging
  1433.     for k,v in pairs(tblPreferredBlock) do
  1434.         print("k: "..k.." v: "..tostring(v))
  1435.     end
  1436.     print("Enter to continue")
  1437.     read()]]
  1438.    
  1439.     if next(tblPreferredBlock) ~= nil then -- check for preferredBlock
  1440.         local found = false
  1441.         for i = 1, 16 do
  1442.             for k,v in pairs(tblPreferredBlock) do
  1443.                 if stock[i]:find(v) ~= nil then -- eg stock[3] = "minecraft:cobblestone"
  1444.                     slot = i
  1445.                     placeBlock = stock[i]
  1446.                     found = true
  1447.                     break
  1448.                 end
  1449.             end
  1450.             if found then -- block found
  1451.                 break
  1452.             end
  1453.         end
  1454.     end
  1455.     -- print("using slot no "..slot) read()
  1456.  
  1457.  
  1458.     if slot == 0 then -- no preferred block or not found
  1459.         -- check for any stock of stone in order
  1460.         local found = false
  1461.         for i = 1, #stone do -- using 'stone' table (class variable)
  1462.             for j = 1, 16 do
  1463.                 if stock[j] == stone[i] then
  1464.                     slot = j --slot no
  1465.                     placeBlock = stock[j]
  1466.                     found = true
  1467.                     break
  1468.                 end
  1469.             end
  1470.             if found then
  1471.                 break
  1472.             end
  1473.         end
  1474.     end
  1475.    
  1476.     if slot == 0 then -- no suitable block found
  1477.     -- print("No blocks found") read()
  1478.         noBlocks = true
  1479.     else
  1480.     -- print("Placing: "..placeBlock) read()
  1481.         placed = lib.place(direction, placeBlock, currentBlock, slot)
  1482.     end
  1483.    
  1484.     turtle.select(1)
  1485.     return placed, noBlocks
  1486. end
  1487.  
  1488. function clsTurtle.findBedrockTop(self, height)
  1489.     -- clsTurtle.place(self, blockType, damageNo, direction, leaveExisting
  1490.     -- clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting)
  1491.     local bedrockFound = false
  1492.     repeat
  1493.         bedrockFound = false
  1494.         clsTurtle.clear(self)
  1495.         print("Checking surrounding  blocks...")
  1496.         for i = 1, 4 do
  1497.             clsTurtle.turnLeft(self, 1)
  1498.             local block = clsTurtle.getBlockType(self, "forward")
  1499.             if block:find("bedrock") then
  1500.                 bedrockFound = true
  1501.                 print("Bedrock found...")
  1502.             else
  1503.                 print("Found: "..block .. " in front")
  1504.             end
  1505.         end
  1506.         if bedrockFound then
  1507.             clsTurtle.up(self, 1)
  1508.             height = height -1
  1509.             clsTurtle.place(self, "stone", -1, "down", true)
  1510.             print("Moving up...")
  1511.         end
  1512.     until not bedrockFound
  1513.     repeat
  1514.         bedrockFound = false
  1515.         local moved = 0
  1516.         for i = 1, 5 do
  1517.             if clsTurtle.forward(self, 1) then
  1518.                 moved = moved + 1
  1519.                 for i = 1, 4 do
  1520.                     clsTurtle.turnLeft(self, 1)
  1521.                     if clsTurtle.getBlockType(self, "forward"):find("bedrock") then
  1522.                         bedrockFound = true
  1523.                         print("Bedrock found: not continuing this row")
  1524.                     end
  1525.                 end
  1526.                 if bedrockFound then
  1527.                     break
  1528.                 end
  1529.             else -- hit bedrock
  1530.                 print("Hit bedrock in front")
  1531.                 bedrockFound = true
  1532.                 break
  1533.             end
  1534.         end
  1535.         clsTurtle.turnLeft(self, 2)
  1536.         for i = 1, moved do
  1537.             clsTurtle.go(self, "C2F1", false, 0, true)
  1538.         end
  1539.         clsTurtle.go(self, "L2C1", false, 0, true)
  1540.         if bedrockFound then
  1541.             print("Moving up...")
  1542.             clsTurtle.go(self, "U1C2", false, 0, true)
  1543.             height = height -1
  1544.         else
  1545.             print("Area clear of bedrock...")
  1546.         end
  1547.     until bedrockFound == false
  1548.     return height
  1549. end
  1550.  
  1551. function clsTurtle.getBlockType(self, direction)
  1552.     --[[ turtle.inspect() returns two values
  1553.         1) boolean (true/false) success
  1554.         2) table with two or more values:
  1555.         .name (string) e.g. "minecraft:log"
  1556.         .metadata (integer) e.g. 0
  1557.         oak has metadata of 0, spruce 1, birch 2 etc
  1558.         CC Tweaked / later MC versions:
  1559.         No .metadata
  1560.         .state {axis = "y"}
  1561.         .tags (["minecraft:logs"] = true, ["minecraft:logs_that_burn"] = true, ["minecraft:oak_logs"] = true}
  1562.     ]]
  1563.     local blockType = ""
  1564.     local blockModifier = nil
  1565.     local success = false
  1566.     local data = {} --initialise empty table variable
  1567.  
  1568.     if direction == "up" then
  1569.         success, data = turtle.inspectUp() -- store information about the block above in a table   
  1570.     elseif direction == "down" then
  1571.         success, data = turtle.inspectDown() -- store information about the block below in a table
  1572.     else
  1573.         success, data = turtle.inspect() -- store information about the block ahead in a table
  1574.     end
  1575.     if success then -- block found
  1576.         blockType = data.name -- eg "minecraft:log"
  1577.         blockModifier = data.metadata
  1578.     end
  1579.    
  1580.     return blockType, blockModifier, data -- eg "minecraft:oak_log" , "", table
  1581. end
  1582.  
  1583. function clsTurtle.getCoords(self, fromFile)
  1584.     fromFile = fromFile or false
  1585.     --get world coordinates from player
  1586.     local coord = 0
  1587.     local response = ""
  1588.     local continue = true
  1589.     local event = ""
  1590.     local param1 = ""
  1591.     local getInput = true
  1592.    
  1593.     clsTurtle.clear(self)
  1594.     -- use built-in filesystem fs
  1595.     if fs.exists("homeCoords.txt") then --ask user if current coords are correct
  1596.         local fileHandle = fs.open("homeCoords.txt", "r")
  1597.         strText = fileHandle.readLine()
  1598.         self.x = tonumber(string.sub(strText, 3))
  1599.         strText = fileHandle.readLine()
  1600.         self.y = tonumber(string.sub(strText, 3))
  1601.         strText = fileHandle.readLine()
  1602.         self.z = tonumber(string.sub(strText, 3))
  1603.         strText = fileHandle.readLine()
  1604.         clsTurtle.setFacing(self, tonumber(string.sub(strText, 3)))
  1605.         fileHandle.close()
  1606.         clsTurtle.saveToLog(self, "Coordinates loaded from file:", false)
  1607.         clsTurtle.saveToLog(self, "x = "..self.x..", y = "..self.y..", z = "..self.z..", f = "..self.facing, false)
  1608.         print("Coordinates loaded from file:\n")
  1609.         print("XYZ: - "..self.x.." / "..self.y.." / "..self.z.."\n")
  1610.         print("Facing: "..self.compass)
  1611.         print("\nUse F3 to check these coordinates")
  1612.         write("\nAre they correct (y/n + Enter)?")
  1613.         response = read()
  1614.         if response == "y" or response == "" then
  1615.             getInput = false
  1616.         else
  1617.             clsTurtle.clear(self)
  1618.         end
  1619.     end
  1620.     if getInput then
  1621.         print("IMPORTANT! Stand directly behind turtle")
  1622.         print("Press F3 to read coordinates")
  1623.         print()
  1624.         continue = true
  1625.         while continue do
  1626.             print("Please enter your X coordinate")
  1627.             write("  x = ")
  1628.             coord = nil
  1629.             while coord == nil do
  1630.                 coord = tonumber(read())
  1631.                 if coord == nil then
  1632.                     clsTurtle.clear(self)
  1633.                     print("Incorrect input. Use numbers only!")
  1634.                     print()
  1635.                     print("Please enter your X coordinate")
  1636.                     write("  x = ")
  1637.                 end
  1638.             end
  1639.             self.x = coord
  1640.             clsTurtle.clear(self)
  1641.             print("Please enter your Y coordinate")
  1642.             write("  y = ")
  1643.             coord = nil
  1644.             while coord == nil do
  1645.                 coord = tonumber(read())
  1646.                 if coord == nil then
  1647.                     clsTurtle.clear(self)
  1648.                     print("Incorrect input. Use numbers only")
  1649.                     print()
  1650.                     print("Please enter your y coordinate")
  1651.                     write("  y = ")
  1652.                 end
  1653.             end
  1654.             self.y = coord
  1655.             clsTurtle.clear(self)
  1656.             print("Please enter your Z coordinate")
  1657.             write("  z = ")
  1658.             coord = nil
  1659.             while coord == nil do
  1660.                 coord = tonumber(read())
  1661.                 if coord == nil then
  1662.                     clsTurtle.clear(self)
  1663.                     print("Incorrect input. Use numbers only")
  1664.                     print()
  1665.                     print("Please enter your z coordinate")
  1666.                     write("  z = ")
  1667.                 end
  1668.             end
  1669.             self.z = coord
  1670.             response = true
  1671.             while response do
  1672.                 response = false
  1673.                 clsTurtle.clear(self)
  1674.                 print("Enter Direction you are facing:")
  1675.                 print("  0,1,2,3 (s,w,n,e)")
  1676.                 print()
  1677.                 print(  "  Direction = ")
  1678.                 event, param1 = os.pullEvent ("char")
  1679.                 if param1 == "s" or param1 == "S" then
  1680.                     coord = 0
  1681.                 elseif param1 == "w" or param1 == "W" then
  1682.                     coord = 1
  1683.                 elseif param1 == "n" or param1 == "N" then
  1684.                     coord = 2
  1685.                 elseif param1 == "e" or param1 == "E" then
  1686.                     coord = 3
  1687.                 elseif param1 == "0" or param1 == "1" or param1 == "2" or param1 == "3" then
  1688.                     coord = tonumber(param1)
  1689.                 else
  1690.                     print()
  1691.                     print("Incorrect input: "..param1)
  1692.                     print()
  1693.                     print("Use 0,1,2,3,n,s,w,e")
  1694.                     sleep(2)
  1695.                     response = true
  1696.                 end
  1697.             end
  1698.             clsTurtle.setFacing(self, coord)
  1699.             clsTurtle.clear(self)
  1700.             print("Your current location is:")
  1701.             print()
  1702.             print("  x = "..self.x)
  1703.             print("  y = "..self.y)
  1704.             print("  z = "..self.z)
  1705.             print("  facing "..self.compass.." ("..self.facing..")")
  1706.             print()
  1707.             write("Is this correct? (y/n)")
  1708.             event, param1 = os.pullEvent ("char")
  1709.             if param1 == "y" or param1 == "Y" then
  1710.                 continue = false
  1711.             end
  1712.         end
  1713.         -- correct coords to compensate for player standing position
  1714.         -- First tree is considered as point zero, on startup, turtle is in front of this tree
  1715.         -- Player is behind turtle, use 2 blocks to compensate
  1716.         -- facing:      Change:
  1717.         -- 0 (S)        z+1
  1718.         -- 1 (W)        x-1
  1719.         -- 2 (N)        z-1
  1720.         -- 3 (E)        x+1
  1721.         if self.facing == 0 then
  1722.             self.z = self.z + 2
  1723.         elseif self.facing == 1 then
  1724.             self.x = self.x - 2
  1725.         elseif self.facing == 2 then
  1726.             self.z = self.z - 2
  1727.         elseif self.facing == 3 then
  1728.             self.x = self.x + 2
  1729.         end
  1730.        
  1731.         -- create/overwrite 'homeCoords.txt'
  1732.         local fileHandle = fs.open("homeCoords.txt", "w")
  1733.         fileHandle.writeLine("x="..self.x)
  1734.         fileHandle.writeLine("y="..self.y)
  1735.         fileHandle.writeLine("z="..self.z)
  1736.         fileHandle.writeLine("f="..self.facing)
  1737.         fileHandle.close()
  1738.         clsTurtle.saveToLog(self, "homeCoords.txt file created", true)
  1739.         clsTurtle.saveToLog(self, "x = "..clsTurtle.getX(self)..", y = "..clsTurtle.getY(self)..", z = "..clsTurtle.getZ(self)..", f = "..clsTurtle.getFacing(self), false)
  1740.     end
  1741. end
  1742.  
  1743. function clsTurtle.getCurrentInventory(self)
  1744.     -- make a table of all existing blocks
  1745.     local stock = {"","","","","","","","","","","","","","","",""}
  1746.     for i = 1, 16 do
  1747.         if turtle.getItemCount(i) > 0 then
  1748.             data = turtle.getItemDetail(i) -- returns {count = x, name = 'minecraft:item" in 1.16.2)
  1749.             stock[i] = data.name
  1750.         end
  1751.     end
  1752.     return stock -- eg stock[1] = minecraft:dirt, stock[2] = "", stock[3] = "minecraft:cobblestone"
  1753. end
  1754.  
  1755. function clsTurtle.getFirstEmptySlot(self)
  1756.     local slot = 0
  1757.     local emptySlots = 0
  1758.     for i = 1,16 do
  1759.         if turtle.getItemCount(i) == 0 then
  1760.             if slot == 0 then
  1761.                 slot = i
  1762.             end
  1763.             emptySlots = emptySlots  + 1
  1764.         end
  1765.     end
  1766.     return slot, emptySlots
  1767. end
  1768.  
  1769. function clsTurtle.getInput(self)
  1770.     --[[
  1771.         returns correctly interpreted value without errors caused by user
  1772.         usage: in main program - local input = T:getInput()
  1773.         local choice = input.getBoolean("Do you like Lua?")
  1774.         if choice then
  1775.             print("Yay!")
  1776.         end
  1777.     ]]
  1778.    
  1779.     local function tchelper(first, rest)
  1780.         return first:upper()..rest:lower()
  1781.     end
  1782.     local input = {}
  1783.     function input.getBoolean(prompt) -- assumes yes/no type entries from user
  1784.         while true do
  1785.             write(prompt.."_")
  1786.             userInput = read()
  1787.             if string.len(userInput) == 0 then
  1788.                 print("\nJust pressing the Enter key doesn't work...")
  1789.             else       
  1790.                 if string.sub(userInput, 1, 1):lower() == "y" then
  1791.                     userInput = true
  1792.                     break
  1793.                 elseif string.sub(userInput, 1, 1):lower() == "n" then
  1794.                     userInput = false
  1795.                     break
  1796.                 else
  1797.                     print("\nOnly anything starting with y or n is accepted...")
  1798.                 end
  1799.             end
  1800.         end
  1801.         return userInput
  1802.     end
  1803.     function input.getString(prompt, withTitle, minInt, maxInt) -- withTitle, minInt and maxInt are given defaults if not passed
  1804.         withTitle = withTitle or false
  1805.         minInt = minInt or 1
  1806.         maxInt = maxInt or 20
  1807.         while true do
  1808.             write(prompt.."_")
  1809.             userInput = read()
  1810.             if string.len(userInput) == 0 then
  1811.                 print("\nJust pressing Enter doesn't work...")
  1812.             else       
  1813.                 if string.len(userInput) >= minInt and string.len(userInput) <= maxInt then
  1814.                     if withTitle then
  1815.                         userInput = input.toTitle(userInput)
  1816.                     end
  1817.                     break
  1818.                 else
  1819.                     print("\nTry entering text between "..minInt.." and "..maxInt.." characters...")
  1820.                 end
  1821.             end
  1822.         end
  1823.    
  1824.         return userInput
  1825.     end
  1826.     function input.getInteger(prompt, minInt, maxInt) -- minInt and maxInt are given defaults if not passed
  1827.         minInt = minInt or 0
  1828.         maxInt = maxInt or 65536
  1829.         while true do
  1830.             write(prompt.."_")
  1831.             userInput = read()
  1832.             if string.len(userInput) == 0 then
  1833.                 print("\nJust pressing the Enter key doesn't work...")
  1834.             else
  1835.                 if tonumber(userInput) ~= nil then
  1836.                     userInput = tonumber(userInput)
  1837.                     if userInput >= minInt and userInput <= maxInt then
  1838.                         break
  1839.                     else
  1840.                         print("\nTry a number from "..minInt.." to "..maxInt.."...")
  1841.                     end
  1842.                 else
  1843.                     print("\nTry entering a number - "..userInput.." does not cut it...")
  1844.                 end
  1845.             end
  1846.         end
  1847.         return userInput
  1848.     end
  1849.    
  1850.     function input.toTitle(inputText) --converts any string to Title Case
  1851.         return inputText:gsub("(%a)([%w_']*)", tchelper)
  1852.     end
  1853.    
  1854.     return input
  1855. end
  1856.  
  1857. function clsTurtle.getItemCount(self, item, modifier)
  1858.     local slot, damage, total, slotData = clsTurtle.getItemSlot(self, item, modifier) --return .leastSlot, .leastModifier, total, slotData
  1859.     return total
  1860. end
  1861.  
  1862. function clsTurtle.getItemName(self, slot)
  1863.     local data = {} --initialise empty table variable
  1864.     data.name = ""
  1865.    
  1866.     if turtle.getItemCount(slot) > 0 then
  1867.         data = turtle.getItemDetail(slot)
  1868.     end
  1869.    
  1870.     return data.name
  1871. end
  1872.  
  1873. function clsTurtle.getItemSlot(self, item, useDamage)
  1874.     -- return slot no with least count, damage(modifier) and total count available
  1875.     -- along with a table of mostSlot, mostCount, leastSlot, leastCount
  1876.     -- if minecraft:log or log2, names for 1.16.2 changed to 'minecraft:oak_log' etc so use wildcards 'log'
  1877.     -- damage for 1.16.2 does not exist and is always nil
  1878.     item = item or "stone"
  1879.     useDamage = useDamage or -1 -- -1 damage means is not relevant
  1880.    
  1881.     local slotData = {} -- setup return table
  1882.     slotData.firstSlot = 0
  1883.     slotData.lastSlot = 0
  1884.     slotData.mostSlot = 0
  1885.     slotData.mostName = ""
  1886.     slotData.mostCount = 0
  1887.     slotData.mostModifier = 0
  1888.     slotData.leastSlot = 0
  1889.     slotData.leastName = ""
  1890.     slotData.leastCount = 0
  1891.     slotData.leastModifier = 0
  1892.    
  1893.     local lib = {}
  1894.    
  1895.     function lib.update(i, v)
  1896.         local count = turtle.getItemCount(i)
  1897.         if slotData.firstSlot == 0 then     -- setup .firstSlot
  1898.             slotData.firstSlot = i
  1899.         end
  1900.         if count > slotData.mostCount then  -- setup .mostCount
  1901.             slotData.mostSlot = i
  1902.             slotData.mostName = v
  1903.             slotData.mostCount = count
  1904.         end
  1905.         if count < slotData.leastCount then
  1906.             slotData.leastSlot = i
  1907.             slotData.leastName = v
  1908.             slotData.leastCount = count
  1909.         end
  1910.         slotData.lastSlot = i               -- setup / edit .lastSlot
  1911.        
  1912.         return count
  1913.     end
  1914.    
  1915.     local total = 0
  1916.     -- make a table of all existing blocks
  1917.     local stock = clsTurtle.getCurrentInventory(self)   -- returns full names of all inventory items in a list 1-16
  1918.    
  1919.     if item:find("\:") ~= nil then                  -- find exact match only
  1920.         for i,v in ipairs(stock) do                 -- iterate current inventory
  1921.             if v == item then                       -- item found
  1922.                 total = total + lib.update(i, v)
  1923.             end
  1924.         end
  1925.     elseif item:find("common") ~= nil or item == "any" or item == "stone" then -- find any stone, in prefence order from stone table
  1926.         local stoneFound = false
  1927.         for j = 1, #stone do -- using 'stone' table (class variable)
  1928.             for i = 1, 16 do
  1929.                 if stock[i] == stone[j] then
  1930.                     stoneFound = true -- found match in list priority
  1931.                     item = stone[j]
  1932.                     break
  1933.                 end
  1934.             end
  1935.             if stoneFound then
  1936.                 break
  1937.             end
  1938.         end
  1939.         if stoneFound then
  1940.             for i,v in ipairs(stock) do             -- iterate current inventory
  1941.                 if v:find(item) ~= nil then         -- item found
  1942.                     total = total + lib.update(i, v)
  1943.                 end
  1944.             end
  1945.         end
  1946.     else -- find matching name
  1947.         for i,v in ipairs(stock) do             -- iterate current inventory
  1948.             if v:find(item) ~= nil then         -- item found
  1949.                 total = total + lib.update(i, v)
  1950.             end
  1951.         end
  1952.     end
  1953.  
  1954.     if slotData.mostSlot > 0 then
  1955.         if slotData.leastSlot == 0 then
  1956.             slotData.leastSlot = slotData.mostSlot
  1957.             slotData.leastName = slotData.mostName
  1958.             slotData.leastCount = slotData.mostCount
  1959.             slotData.leastModifier = slotData.mostModifier
  1960.         end
  1961.     end
  1962.     --return slotData.leastSlot, slotData.leastModifier, total, slotData -- integer, integer, integer, table OR integer, nil, integer, table
  1963.     return slotData.lastSlot, slotData.leastModifier, total, slotData -- integer, integer, integer, table OR integer, nil, integer, table
  1964. end
  1965.  
  1966. function clsTurtle.getMostItem(self, excludeItem, stoneOnly)
  1967.     --[[ Used to get user choice of stone based on quantity ]]
  1968.     local lib = {}
  1969.    
  1970.     function lib.checkStone(item)
  1971.         for k,v in ipairs (stone) do
  1972.             if item == v then
  1973.                 return true
  1974.             end
  1975.         end
  1976.         return false
  1977.     end
  1978.    
  1979.     excludeItem = excludeItem or ""
  1980.     stoneOnly = stoneOnly or false
  1981.     local data = {}
  1982.     local inventory = {}
  1983.     local mostItem = ""
  1984.     local mostCount = 0
  1985.     for i = 1, 16 do
  1986.         if turtle.getItemCount(i) > 0 then
  1987.             data = turtle.getItemDetail(i)
  1988.             if inventory[data.name] == nil then
  1989.                 inventory[data.name] = data.count
  1990.             else
  1991.                 inventory[data.name] = inventory[data.name] + data.count
  1992.             end
  1993.         end
  1994.     end
  1995.     for k,v in pairs(inventory) do
  1996.         if mostItem == "" then                  -- not yet found mostItem
  1997.             if stoneOnly then                   -- only check for stone blocks
  1998.                 if lib.checkStone(k) then       -- stone found
  1999.                     if excludeItem == "" then   -- no excluded items
  2000.                         mostItem = k
  2001.                         mostCount = v
  2002.                     else
  2003.                         if k:find(excludeItem) == nil then -- not found
  2004.                             mostItem = k
  2005.                             mostCount = v
  2006.                         end
  2007.                     end
  2008.                 end
  2009.             else                                -- not just stone in count
  2010.                 if excludeItem == "" then       -- no excluded items
  2011.                     mostItem = k
  2012.                     mostCount = v
  2013.                 else
  2014.                     if k:find(excludeItem) == nil then -- not found
  2015.                         mostItem = k
  2016.                         mostCount = v
  2017.                     end
  2018.                 end
  2019.             end
  2020.         else                                    -- mostItem found
  2021.             if stoneOnly then                   -- only check for stone blocks
  2022.                 if lib.checkStone(k) then
  2023.                     if excludeItem == "" then   -- no excluded items
  2024.                         if inventory[k] > mostCount then
  2025.                             mostItem = k
  2026.                             mostCount = v
  2027.                         end
  2028.                     else
  2029.                         if k:find(excludeItem) == nil then -- not found
  2030.                             if inventory[k] > mostCount then
  2031.                                 mostItem = k
  2032.                                 mostCount = v
  2033.                             end
  2034.                         end
  2035.                     end
  2036.                 end
  2037.             else
  2038.                 if excludeItem == "" then           -- no excluded items
  2039.                     if inventory[k] > mostCount then
  2040.                         mostItem = k
  2041.                         mostCount = v
  2042.                     end
  2043.                 else
  2044.                     if k:find(excludeItem) == nil then -- not found
  2045.                         if inventory[k] > mostCount then
  2046.                             mostItem = k
  2047.                             mostCount = v
  2048.                         end
  2049.                     end
  2050.                 end
  2051.             end
  2052.         end
  2053.     end
  2054.    
  2055.     --print("mostItem: "..mostItem.." mostCount: "..mostCount) read()
  2056.     return mostItem, mostCount
  2057. end
  2058.  
  2059. function clsTurtle.getPolishedItem(self, blockType)
  2060.     --[[
  2061.         local blockType, count = T:getPolishedItem("")
  2062.         local blockType, count = T:getPolishedItem("slab")
  2063.         local blockType, count = T:getPolishedItem("stairs")
  2064.         local blockType, count = T:getPolishedItem("wall")
  2065.     ]]
  2066.     local data = {}
  2067.     local inventory = {}
  2068.    
  2069.     for i = 1, 16 do
  2070.         if turtle.getItemCount(i) > 0 then
  2071.             data = turtle.getItemDetail(i)
  2072.             if inventory[data.name] == nil then
  2073.                 inventory[data.name] = data.count
  2074.             else
  2075.                 inventory[data.name] = inventory[data.name] + data.count
  2076.             end
  2077.         end
  2078.     end
  2079.     for k,v in pairs(inventory) do
  2080.         if k:find("polished") ~= nil then -- contains polished stairs, wall, slab,
  2081.             if blockType == "slab" or blockType == "stairs" or blockType == "wall" then
  2082.                 if K:find(blockType) ~= nil then
  2083.                     return k, v
  2084.                 end
  2085.             else -- looking for polished_andesite, granite etc block
  2086.                 if k:find("slab") == nil and k:find("stairs") == nil and k:find("wall") == nil then
  2087.                     return k, v
  2088.                 end
  2089.             end
  2090.         end
  2091.     end
  2092.    
  2093.     return "", 0
  2094. end
  2095.  
  2096. function clsTurtle.getSaplingSlot(self, name)
  2097.     local saplingSlot = 0
  2098.     local count = 0
  2099.     local data = {name = ""} -- in case no saplings found
  2100.     if name == nil then
  2101.         name = "sapling"
  2102.     end
  2103.     for i = 1, 16 do
  2104.         count = turtle.getItemCount(i)
  2105.         if count > 0 then
  2106.             data = turtle.getItemDetail(i) -- returns {count = x, name = 'minecraft:item" in 1.16.2)
  2107.             if data.name:find(name) ~= nil then
  2108.                 saplingSlot = i
  2109.                 break
  2110.             end
  2111.         end
  2112.     end
  2113.     return saplingSlot, data.name, count -- 0, "" / "minecraft:oak_sapling", 6
  2114. end
  2115.  
  2116. function clsTurtle.getPlaceChestDirection(self)
  2117.     local facing = self.facing
  2118.     local chestDirection = "forward"
  2119.     local turns = 0
  2120.    
  2121.     for i = 1, 4 do
  2122.         if turtle.detect() then
  2123.             clsTurtle.turnRight(self, 1)
  2124.             turns = turns + 1
  2125.         else
  2126.             break
  2127.         end
  2128.     end
  2129.     if turns == 4 then -- full circle
  2130.         turns = 0
  2131.         if turtle.detectDown() then -- no space below
  2132.             if turtle.detectUp() then
  2133.                 if clsTurtle.dig(self, "up") then
  2134.                     chestDirection = "up"
  2135.                 end
  2136.             else
  2137.                 chestDirection = "up"
  2138.             end
  2139.         else
  2140.             chestDirection = "down"
  2141.         end
  2142.     end
  2143.     return chestDirection, turns -- will be "forward" or "up", 0 - 3
  2144. end
  2145.  
  2146. function clsTurtle.getSlotContains(self, slotNo)
  2147.     local data = {} --initialise empty table variable
  2148.    
  2149.     local slotCount = 0
  2150.     local slotContains = ""
  2151.     local slotDamage = 0
  2152.     if turtle.getItemCount(slotNo) > 0 then
  2153.         data = turtle.getItemDetail(slotNo)
  2154.         slotCount = data.count
  2155.         slotContains = data.name
  2156.         slotDamage = data.damage -- nil on CCTweaked
  2157.     end
  2158.    
  2159.     return slotContains, slotCount, slotDamage
  2160. end
  2161.  
  2162. function clsTurtle.getStock(self, item, modifier)
  2163.     -- return total units and slot numbers of max and min amounts
  2164.     local slot, damage, total, slotData = clsTurtle.getItemSlot(self, item, modifier) --return .leastSlot, .leastModifier, total, slotData
  2165.     local rt = {}
  2166.     rt.total = total
  2167.     rt.mostSlot = slotData.mostSlot
  2168.     rt.leastSlot = slotData.leastSlot
  2169.     rt.mostCount = slotData.mostCount
  2170.     rt.leastCount = slotData.leastCount
  2171.     if slot == 0 then
  2172.         if modifier == nil then
  2173.             --clsTurtle.saveToLog(self, "getStock()"..tostring(item).."= not found", true)
  2174.         else
  2175.             --clsTurtle.saveToLog(self, "getStock()"..tostring(item).."("..tostring(modifier)..")= not found")
  2176.         end
  2177.     end
  2178.    
  2179.     return rt --{rt.total, rt.mostSlot, rt.leastSlot, rt.mostCount, rt.leastCount}
  2180. end
  2181.  
  2182. function clsTurtle.getSolidBlockCount(self)
  2183.     local retValue = 0
  2184.     --local solids = {'cobble', 'stone', 'dirt', 'granite', 'andesite', 'diorite', 'deepslate', 'glass', 'tuff'}
  2185.     local slotCount, slotContains, slotDamage
  2186.     for i = 1, 16 do
  2187.         -- slotContains, slotCount, slotDamage
  2188.         slotContains, slotCount, slotDamage = clsTurtle.getSlotContains(self, i)
  2189.         for _, v in ipairs(stone) do
  2190.             if slotContains:find(v) ~= nil then
  2191.                 retValue = retValue + slotCount
  2192.                 break
  2193.             end
  2194.         end
  2195.     end
  2196.     return retValue
  2197. end
  2198.  
  2199. function clsTurtle.getTotalItemCount(self)
  2200.     local count = 0
  2201.    
  2202.     for i = 1, 16 do
  2203.         count = count + turtle.getItemCount(i)
  2204.     end
  2205.     return count
  2206. end
  2207.  
  2208. function clsTurtle.getWater(self, direction)
  2209.     direction = direction or "forward"
  2210.     -- assign place methods according to direction
  2211.     local Place = turtle.place
  2212.     if direction == "up" then
  2213.         Place = turtle.placeUp
  2214.     elseif direction == "down" then
  2215.         Place = turtle.placeDown
  2216.     end
  2217.     local slot = clsTurtle.getItemSlot(self, "minecraft:bucket")
  2218.     if slot > 0 then
  2219.         turtle.select(slot)
  2220.         if Place() then
  2221.             turtle.select(1)
  2222.             return true
  2223.         end
  2224.     end
  2225.     turtle.select(1)
  2226.     return false
  2227. end
  2228.  
  2229. function clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
  2230.     useTorch = useTorch or false -- used in m and M to place torches in mines
  2231.     if leaveExisting == nil then
  2232.         leaveExisting = false
  2233.     end
  2234.     torchInterval = torchInterval or 8
  2235.     if preferredBlock == nil or preferredBlock == "" then
  2236.         preferredBlock = {} -- used for C command to allow faster placing of specific block
  2237.     else
  2238.         if type(preferredBlock) ~= "table" then
  2239.             preferredBlock = {preferredBlock}
  2240.         end
  2241.     end
  2242.    
  2243.     local intervalList =
  2244.     {
  2245.         1,
  2246.         torchInterval * 1 + 1,
  2247.         torchInterval * 2 + 1,
  2248.         torchInterval * 3 + 1,
  2249.         torchInterval * 4 + 1,
  2250.         torchInterval * 5 + 1,
  2251.         torchInterval * 6 + 1
  2252.     }
  2253.     local slot = turtle.getSelectedSlot()
  2254.     turtle.select(1)       
  2255.     local commandList = {}
  2256.     local command = ""
  2257.     local direction = {"up", "forward", "down"}
  2258.     -- remove spaces from path
  2259.     path = string.gsub(path, " ", "")
  2260.     -- make a list of commands from path string eg "x0F12U1" = x0, F12, U1
  2261.     for i = 1, string.len(path) do
  2262.         local character = string.sub(path, i, i) -- examine each character in the string
  2263.         if tonumber(character) == nil then -- char is NOT a number
  2264.             if command ~= "" then -- command is NOT empty eg "x0"
  2265.                 table.insert(commandList, command) -- add to table eg "x0"
  2266.             end
  2267.             command = character -- replace command with new character eg "F"
  2268.         else -- char IS a number
  2269.             command = command..character -- add eg 1 to F = F1, 2 to F1 = F12
  2270.             if i == string.len(path) then -- last character in the string
  2271.                 table.insert(commandList, command)
  2272.             end
  2273.         end
  2274.     end
  2275.     -- R# L# F# B# U# D# +0 -0 d0 = Right, Left, Forward, Back, Up, Down, up while detect and return, down while not detect, down and place while not detect
  2276.     -- dig:           x0,x1,x2 (up/fwd/down)
  2277.     -- suck:          s0,s1,s2
  2278.     -- place chest:   H0,H1,H2
  2279.     -- place sapling: S0,S1,S2
  2280.     -- place Torch:   T0,T1,T2
  2281.     -- place Hopper:  P0,P1,P2
  2282.     -- mine floor:    m# = mine # blocks above and below, checking for valuable items below, and filling space with cobble or dirt
  2283.     -- mine ceiling:  M# = mine # blocks, checking for valuable items above, and filling space with cobble or dirt
  2284.     -- mine ceiling:  N# same as M but not mining block below unless valuable
  2285.     -- mine floor:    n# mine block below and/or fill void + check left side
  2286.     -- mine ceiling:  Q# same as M + mine block below if valuable + left side
  2287.     -- mine wall:     q# mine # blocks forward, check left side and patch
  2288.     -- tunnel top:    A# fill voids above and both sides
  2289.     -- tunnel bottom: E# fill voids both sides, remove floor
  2290.     -- tunnel bottom: X# fill voids both sides and floor
  2291.     -- QuickMine      V# take block above if valuable, fill void above, fill void below
  2292.     -- QuickCoridoor  W# take block below, take block above if valuable, fill void above
  2293.     -- mine - bedrock Z#
  2294.     -- place:         C,H,r,S,T,P,^ = Cobble / cHest / DIrT / Sapling / Torch / hoPper /stair in direction 0/1/2 (up/fwd/down) eg C2 = place cobble down
  2295.     -- place:         t = 0/1 = place behind, 2 = cobble first, up torch, forward down
  2296.     -- place:         e = ladder, direction
  2297.     -- place:         @ = any block in inventory, direction
  2298.     -- X              mine block below and/or fill void, then check sides (X = trench)
  2299.     -- +              while detectUp digUp and move up. Return to original position after
  2300.     -- ^              place stairs
  2301.     clsTurtle.refuel(self, 15)
  2302.     turtle.select(1)
  2303.     for cmd in clsTurtle.values(self, commandList) do -- eg F12 or x1
  2304.         local move = string.sub(cmd, 1, 1)
  2305.         local modifier = tonumber(string.sub(cmd, 2))
  2306.         if move == "A" then --mine block above and/or fill void + fill both sides
  2307.             turtle.select(1)
  2308.             --[[check block behind
  2309.             clsTurtle.turnRight(self, 2)
  2310.             clsTurtle.digValuable(self, "forward")
  2311.             clsTurtle.fillVoid(self, "forward")
  2312.             clsTurtle.turnRight(self, 2)]]
  2313.             for i = 1, modifier + 1 do --eg A16 run loop 17 x
  2314.                 clsTurtle.digValuable(self, "up")
  2315.                 clsTurtle.fillVoid(self, "up")
  2316.                 clsTurtle.turnLeft(self, 1)
  2317.                 clsTurtle.digValuable(self, "forward")
  2318.                 clsTurtle.fillVoid(self, "forward")
  2319.                 clsTurtle.turnRight(self, 2)
  2320.                 clsTurtle.digValuable(self, "forward")
  2321.                 clsTurtle.fillVoid(self, "forward")
  2322.                 clsTurtle.turnLeft(self, 1)
  2323.                 --clsTurtle.dig(self, "down") -- create player coridoor
  2324.                 if i <= modifier then -- A16 = move forward 16x
  2325.                     clsTurtle.forward(self, 1)
  2326.                 end
  2327.             end
  2328.             --check block at end
  2329.             clsTurtle.digValuable(self, "forward")
  2330.             clsTurtle.fillVoid(self, "forward")
  2331.         elseif move == "B" then
  2332.             clsTurtle.back(self, modifier)
  2333.         elseif move == "c" then
  2334.             if turtle.detectDown() then
  2335.                 --check if vegetation and remove
  2336.                 if clsTurtle.isSeaweed(self, "down") then
  2337.                     turtle.digDown()
  2338.                 end
  2339.             end
  2340.             if not turtle.detectDown() then
  2341.                 if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  2342.                     clsTurtle.place(self, "minecraft:dirt", -1, "down")
  2343.                 end
  2344.             end
  2345.         elseif move == "C" then
  2346.             -- fillVoid(self, direction, tblPreferredBlock, leaveExisting)
  2347.             local fill = false
  2348.             if leaveExisting then -- leave alone if non-gravity
  2349.                 if clsTurtle.detect(self, direction[modifier + 1]) then -- solid block ahead, not air, water or lava
  2350.                     if clsTurtle.digValuable(self, direction[modifier + 1]) then
  2351.                         fill = true
  2352.                     elseif clsTurtle.digGravityBlock(self, direction[modifier + 1]) then -- sand or gravel
  2353.                         fill = true
  2354.                     end
  2355.                 else    -- air, water or lava ahead
  2356.                     fill = true
  2357.                 end
  2358.             else
  2359.                 fill = true
  2360.             end
  2361.             if fill then
  2362.                 clsTurtle.fillVoid(self, direction[modifier + 1], preferredBlock, false)
  2363.             end
  2364.         elseif move == "d" then -- down and place while not detect
  2365.             if modifier == 1 then
  2366.                 clsTurtle.fillVoid(self, "forward", preferredBlock)
  2367.             end
  2368.             while not turtle.detectDown() do
  2369.                 clsTurtle.down(self, 1)
  2370.                 if modifier == 1 then
  2371.                     clsTurtle.fillVoid(self, "forward", preferredBlock)
  2372.                 end
  2373.             end
  2374.             if modifier == 1 then
  2375.                 clsTurtle.fillVoid(self, "forward", preferredBlock)
  2376.             end
  2377.         elseif move == "D" then
  2378.             clsTurtle.down(self, modifier)
  2379.         elseif move == "e" then -- ladder above / in front / below
  2380.             clsTurtle.place(self, "minecraft:ladder", -1, direction[modifier + 1], false)
  2381.         elseif move == "E" then --mine block below + fill both sides
  2382.             turtle.select(1)
  2383.             --check block behind
  2384.             clsTurtle.turnRight(self, 2)
  2385.             clsTurtle.digValuable(self, "forward")
  2386.             clsTurtle.fillVoid(self, "forward")
  2387.             clsTurtle.turnRight(self, 2)
  2388.             for i = 1, modifier + 1 do --eg A16 run loop 17 x
  2389.                 clsTurtle.turnLeft(self, 1)
  2390.                 clsTurtle.digValuable(self, "forward")
  2391.                 clsTurtle.fillVoid(self, "forward")
  2392.                 clsTurtle.turnRight(self, 2)
  2393.                 clsTurtle.digValuable(self, "forward")
  2394.                 clsTurtle.fillVoid(self, "forward")
  2395.                 clsTurtle.turnLeft(self, 1)
  2396.                 clsTurtle.dig(self, "down") -- create player coridoor
  2397.                 if i <= modifier then -- A16 = move forward 16x
  2398.                     clsTurtle.forward(self, 1)
  2399.                 end
  2400.             end
  2401.             --check block at end
  2402.             clsTurtle.digValuable(self, "forward")
  2403.             clsTurtle.fillVoid(self, "forward")
  2404.         elseif move == "F" then
  2405.             clsTurtle.forward(self, modifier)
  2406.         elseif move == "H" then
  2407.             clsTurtle.place(self, "minecraft:chest", -1, direction[modifier + 1], leaveExisting)
  2408.         elseif move == "L" then
  2409.             clsTurtle.turnLeft(self, modifier)
  2410.         elseif move == "m" then --mine block below and/or fill void
  2411.             --T:go("m8", false, 0, false, brick)
  2412.             for i = 1, modifier + 1 do --eg m8 run loop 9 x
  2413.                 turtle.select(1)
  2414.                 local isValuable, blockType = clsTurtle.isValuable(self, "down")
  2415.                 if isValuable or blockType == "minecraft:gravel" or not leaveExisting then
  2416.                     turtle.digDown() -- dig if gravel
  2417.                 elseif blockType == "minecraft:lava" then
  2418.                     clsTurtle.place(self, "minecraft:bucket", -1, "down")
  2419.                 end
  2420.                 clsTurtle.dig(self, "up") -- create player coridoor
  2421.                 if not turtle.detectDown() then
  2422.                     clsTurtle.fillVoid(self, "down", preferredBlock, leaveExisting)
  2423.                 end
  2424.                 if i <= modifier then -- n8 = move forward 8x. check for initial use in mine to avoid torch in wrong place
  2425.                     if useTorch then
  2426.                         if  (i == intervalList[1] and modifier >= 16) or
  2427.                             i == intervalList[2] or
  2428.                             i == intervalList[3] or
  2429.                             i == intervalList[4] or
  2430.                             i == intervalList[5] then
  2431.                             clsTurtle.up(self, 1)
  2432.                             clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  2433.                             clsTurtle.forward(self, 1)
  2434.                             clsTurtle.down(self, 1)
  2435.                         else
  2436.                             clsTurtle.forward(self, 1)
  2437.                         end
  2438.                     else
  2439.                         clsTurtle.forward(self, 1)
  2440.                     end
  2441.                 end
  2442.             end
  2443.         elseif move == "M" then --mine block above and/or fill void
  2444.             for i = 1, modifier + 1 do
  2445.                 turtle.select(1)
  2446.                 local isValuable, blockType = clsTurtle.isValuable(self, "up")
  2447.                 if isValuable then
  2448.                     clsTurtle.dig(self, "up")
  2449.                 elseif blockType == "minecraft:lava" then
  2450.                     clsTurtle.place(self, "minecraft:bucket", -1, "up")
  2451.                 end
  2452.                 if not turtle.detectUp()then
  2453.                     clsTurtle.fillVoid(self, "up", preferredBlock)
  2454.                 end
  2455.                 if i <= modifier then -- will not move forward if modifier = 0
  2456.                     if useTorch then
  2457.                         if  i == intervalList[1] or
  2458.                             i == intervalList[2] or
  2459.                             i == intervalList[3] or
  2460.                             i == intervalList[4] or
  2461.                             i == intervalList[5] then
  2462.                             clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  2463.                         end
  2464.                     end
  2465.                     clsTurtle.forward(self, 1)
  2466.                 end
  2467.             end
  2468.         elseif move == "n" then --mine block below and/or fill void + check left side
  2469.             for i = 1, modifier + 1 do --eg m8 run loop 9 x
  2470.                 turtle.select(1)
  2471.                 local isValuable, blockType = clsTurtle.isValuable(self, "down")
  2472.                 if isValuable or blockType == "minecraft:gravel" or not leaveExisting then
  2473.                     turtle.digDown() -- dig if valuable or gravel
  2474.                 else --check for lava
  2475.                     if blockType == "minecraft:lava" then
  2476.                         clsTurtle.place(self, "minecraft:bucket", -1, "down")
  2477.                     end
  2478.                 end
  2479.                 clsTurtle.dig(self, "up") -- create player coridoor
  2480.                 if not turtle.detectDown() then
  2481.                     clsTurtle.fillVoid(self, "down", preferredBlock)
  2482.                 end
  2483.                 clsTurtle.turnLeft(self, 1)
  2484.                 local isValuable, blockType = clsTurtle.isValuable(self, "forward")
  2485.                 if isValuable or not leaveExisting then
  2486.                     turtle.dig() -- dig if valuable
  2487.                 end
  2488.                 if not turtle.detect() then
  2489.                     clsTurtle.fillVoid(self, "forward", preferredBlock, leaveExisting)
  2490.                 end
  2491.                 clsTurtle.turnRight(self, 1)   
  2492.                 if i <= modifier then -- m8 = move forward 8x
  2493.                     if useTorch then
  2494.                         if  i == intervalList[1] or
  2495.                             i == intervalList[2] or
  2496.                             i == intervalList[3] or
  2497.                             i == intervalList[4] or
  2498.                             i == intervalList[5] then
  2499.                             clsTurtle.up(self, 1)
  2500.                             clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  2501.                             clsTurtle.forward(self, 1)
  2502.                             clsTurtle.down(self, 1)
  2503.                         else
  2504.                             clsTurtle.forward(self, 1)
  2505.                         end
  2506.                     else
  2507.                         clsTurtle.forward(self, 1)
  2508.                     end
  2509.                 end
  2510.             end
  2511.         elseif move == "N" then --mine block above and/or fill void + mine block below if valuable
  2512.             for i = 1, modifier + 1 do
  2513.                 turtle.select(1)
  2514.                 local isValuable, blockType = clsTurtle.isValuable(self, "up")
  2515.                 if isValuable then
  2516.                     clsTurtle.dig(self, "up")
  2517.                 elseif blockType == "minecraft:lava" then
  2518.                     clsTurtle.place(self, "minecraft:bucket", -1, "up")
  2519.                 end
  2520.                 if not turtle.detectUp() then
  2521.                     clsTurtle.fillVoid(self, "up", preferredBlock)
  2522.                 end
  2523.                 turtle.select(1)
  2524.                 isValuable, blockType = clsTurtle.isValuable(self, "down")
  2525.                 if isValuable then
  2526.                     clsTurtle.dig(self, "down")
  2527.                     clsTurtle.fillVoid(self, "down", preferredBlock)
  2528.                 else
  2529.                     if clsTurtle.getBlockType(self, "down") == "minecraft:lava" then
  2530.                         clsTurtle.place(self, "minecraft:bucket", -1, "down")
  2531.                     end
  2532.                 end
  2533.                 if i <= modifier then
  2534.                     clsTurtle.forward(self, 1)
  2535.                 end
  2536.             end
  2537.         elseif move == "P" then
  2538.             clsTurtle.place(self, "minecraft:hopper", -1, direction[modifier + 1], leaveExisting)
  2539.         elseif move == "q" then --mine block and fill voids on left side left side
  2540.             for i = 1, modifier + 1 do
  2541.                 turtle.select(1)
  2542.                 clsTurtle.turnLeft(self, 1)
  2543.                 if clsTurtle.isValuable(self, "forward") then
  2544.                     turtle.dig() -- dig if valuable
  2545.                 end
  2546.                 if not turtle.detect() then
  2547.                     clsTurtle.fillVoid(self, "forward", preferredBlock)
  2548.                 end
  2549.                 clsTurtle.turnRight(self, 1)   
  2550.                 if i <= modifier then
  2551.                     clsTurtle.forward(self, 1)
  2552.                 end
  2553.             end
  2554.         elseif move == "Q" then --mine block above and/or fill void + mine block below if valuable + left side
  2555.             for i = 1, modifier + 1 do
  2556.                 turtle.select(1)
  2557.                 if clsTurtle.isValuable(self, "up") then
  2558.                     clsTurtle.dig(self, "up")
  2559.                 else --check for lava
  2560.                     if clsTurtle.getBlockType(self, "up") == "minecraft:lava" then
  2561.                         clsTurtle.place(self, "minecraft:bucket", -1, "up")
  2562.                     end
  2563.                 end
  2564.                 if not turtle.detectUp() then
  2565.                     clsTurtle.fillVoid(self, "up", preferredBlock)
  2566.                 end
  2567.                 clsTurtle.turnLeft(self, 1)
  2568.                 if clsTurtle.isValuable(self, "forward") then
  2569.                     turtle.dig() -- dig if valuable
  2570.                 end
  2571.                 if not turtle.detect() then
  2572.                     clsTurtle.fillVoid(self, "forward", preferredBlock)
  2573.                 end
  2574.                 clsTurtle.turnRight(self, 1)   
  2575.                 if clsTurtle.isValuable(self, "down") then
  2576.                     turtle.digDown()
  2577.                 end
  2578.                 if i <= modifier then
  2579.                     clsTurtle.forward(self, 1)
  2580.                 end
  2581.             end
  2582.         elseif move == "r" then
  2583.             clsTurtle.place(self, "minecraft:dirt", -1, direction[modifier + 1], leaveExisting)
  2584.         elseif move == "R" then
  2585.             clsTurtle.turnRight(self, modifier)
  2586.         elseif move == "s" then
  2587.             if modifier == 0 then
  2588.                 while turtle.suckUp() do end
  2589.             elseif modifier == 1 then
  2590.                 while turtle.suck() do end
  2591.             elseif modifier == 2 then
  2592.                 while turtle.suckDown() do end
  2593.             end
  2594.         elseif move == "S" then
  2595.             clsTurtle.place(self, "sapling", -1, direction[modifier + 1], leaveExisting)
  2596.         elseif move == "t" then
  2597.             -- 0 = placeUp does not work with os 1.8
  2598.             -- 1 = turn round, placeForward
  2599.             -- 2 = placeDown
  2600.             -- 3 = turnLeft, placeUp
  2601.             -- 4 = turnround, placeUp
  2602.             -- 5 = place down without block
  2603.             if modifier == 0 then -- os < 1.8
  2604.                 clsTurtle.place(self, "minecraft:torch", -1, "up", false)
  2605.             elseif modifier == 1 then --place behind
  2606.                 clsTurtle.turnLeft(self, 2)
  2607.                 --local block, blockType = clsTurtle.isWaterOrLava(self, "forward")
  2608.                 --if block ~= "minecraft:water" and block ~= "minecraft:lava" then
  2609.                     clsTurtle.place(self, "minecraft:torch", -1, "forward", false)
  2610.                 --end
  2611.                 clsTurtle.turnLeft(self, 2)
  2612.             elseif modifier == 2 then -- place below for 2
  2613.                 if not clsTurtle.place(self, "minecraft:cobblestone", -1,"down") then
  2614.                     clsTurtle.place(self, "minecraft:dirt", -1, "down")
  2615.                 end
  2616.                 clsTurtle.up(self, 1)
  2617.                 --local block, blockType = clsTurtle.isWaterOrLava(self, "down")
  2618.                 --if block ~= "minecraft:water" and block ~= "minecraft:lava" then
  2619.                     clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  2620.                 --end
  2621.                 clsTurtle.forward(self, 1)
  2622.                 clsTurtle.down(self, 1)
  2623.             elseif modifier == 3 then --turnLeft, placeUp (on ground to wall)
  2624.                 clsTurtle.turnLeft(self, 1)
  2625.                 clsTurtle.place(self, "minecraft:torch", -1, "up", false)
  2626.                 clsTurtle.turnRight(self, 1)
  2627.             elseif modifier == 4 then --turnLeft, placeUp (on ground to wall)
  2628.                 clsTurtle.turnLeft(self, 2)
  2629.                 clsTurtle.place(self, "minecraft:torch", -1, "up", false)
  2630.                 clsTurtle.turnLeft(self, 2)
  2631.             elseif modifier == 5 then --cobble first, then torch
  2632.                 clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  2633.             end
  2634.         elseif move == "T" then
  2635.             clsTurtle.place(self, "minecraft:torch", -1, direction[modifier + 1], leaveExisting)
  2636.         elseif move == "u" then -- move up and place forward/down
  2637.             repeat
  2638.                 if modifier == 1 then
  2639.                     clsTurtle.fillVoid(self, "forward", preferredBlock, leaveExisting)
  2640.                 end
  2641.                 clsTurtle.up(self, 1)
  2642.                 if modifier == 1 then
  2643.                     clsTurtle.fillVoid(self, "forward", preferredBlock, leaveExisting)
  2644.                 end
  2645.                 clsTurtle.fillVoid(self, "down", preferredBlock, leaveExisting)
  2646.             until not turtle.inspectUp()
  2647.             if modifier == 1 then
  2648.                 clsTurtle.fillVoid(self, "forward", preferredBlock, leaveExisting)
  2649.             end
  2650.         elseif move == "U" then
  2651.             clsTurtle.up(self, modifier)
  2652.         elseif move == "x" then
  2653.             if modifier == 0 then
  2654.                 clsTurtle.dig(self, "up")
  2655.             elseif modifier == 1 then
  2656.                 clsTurtle.dig(self, "forward")
  2657.             elseif modifier == 2 then
  2658.                 while turtle.detectDown() do
  2659.                     turtle.digDown()
  2660.                 end
  2661.             end
  2662.         elseif move == "V" then --QuickMine
  2663.             for i = 1, modifier + 1 do
  2664.                 turtle.select(1)
  2665.                 local isValuable, blockType = clsTurtle.isValuable(self, "down")
  2666.                 if isValuable then
  2667.                     clsTurtle.dig(self, "down")
  2668.                 elseif blockType == "minecraft:lava" then
  2669.                     clsTurtle.place(self, "minecraft:bucket", -1, "down")
  2670.                 end
  2671.                 isValuable, blockType = clsTurtle.isValuable(self, "up")
  2672.                 if isValuable then
  2673.                     clsTurtle.dig(self, "up")
  2674.                 elseif blockType == "minecraft:lava" then
  2675.                     clsTurtle.place(self, "minecraft:bucket", -1, "up")
  2676.                 end
  2677.                 if not turtle.detectUp()then
  2678.                     clsTurtle.fillVoid(self, "up", preferredBlock)
  2679.                 end
  2680.                 if not turtle.detectDown()then
  2681.                     clsTurtle.fillVoid(self, "down", preferredBlock)
  2682.                 end
  2683.                 if i <= modifier then -- will not move forward if modifier = 0
  2684.                     clsTurtle.forward(self, 1)
  2685.                 end
  2686.             end
  2687.         elseif move == "W" then --QuickCoridoor
  2688.             for i = 1, modifier + 1 do
  2689.                 turtle.select(1)
  2690.                 local isValuable, blockType = clsTurtle.isValuable(self, "up")
  2691.                 if isValuable then
  2692.                     clsTurtle.dig(self, "up")
  2693.                 elseif blockType == "minecraft:lava" then
  2694.                     clsTurtle.place(self, "minecraft:bucket", -1, "up")
  2695.                 end
  2696.                 if not turtle.detectUp()then
  2697.                     clsTurtle.fillVoid(self, "up", preferredBlock)
  2698.                 end
  2699.                 clsTurtle.isWaterOrLava(self, "down") -- automatically removes lava
  2700.                 clsTurtle.dig(self, "down")
  2701.                 if i <= modifier then -- will not move forward if modifier = 0
  2702.                     clsTurtle.forward(self, 1)
  2703.                 end
  2704.             end
  2705.         elseif move == "X" then --mine block below and/or fill void, then check sides (X = trench)
  2706.             for i = 1, modifier + 1 do --eg X8 run loop 9 x
  2707.                 turtle.select(1)
  2708.                 local isValuable, blockType = clsTurtle.isValuable(self, "down")
  2709.                 if isValuable or blockType == "minecraft:gravel" or blockType == "minecraft:sand" or blockType:find("grass") ~= nil then
  2710.                     turtle.digDown() -- dig if gravel
  2711.                 else --check for lava
  2712.                     if blockType == "minecraft:lava" then
  2713.                         clsTurtle.place(self, "minecraft:bucket", -1, "down")
  2714.                     end
  2715.                 end
  2716.                 clsTurtle.dig(self, "up") -- create player coridoor
  2717.                 if not turtle.detectDown() then
  2718.                     clsTurtle.fillVoid(self, "down")
  2719.                 end
  2720.                 clsTurtle.turnRight(self, 1)
  2721.                 if not turtle.detect() then
  2722.                     clsTurtle.fillVoid(self, "forward")
  2723.                 end
  2724.                 clsTurtle.turnLeft(self, 2)
  2725.                 if not turtle.detect() then
  2726.                     clsTurtle.fillVoid(self, "forward")
  2727.                 end
  2728.                 clsTurtle.turnRight(self, 1)
  2729.                 if i <= modifier then -- X8 = move forward 8x
  2730.                     clsTurtle.forward(self, 1)
  2731.                 end
  2732.             end
  2733.         elseif move == "Z" then -- mine to bedrock
  2734.             for i = 1, modifier + 1 do 
  2735.                 turtle.select(1)
  2736.                 local goUp = 0
  2737.                 while clsTurtle.down(self, 1) do
  2738.                     goUp = goUp + 1
  2739.                 end
  2740.                 for j = goUp, 1, -1 do
  2741.                     for k = 1, 4 do
  2742.                         clsTurtle.turnRight(self, 1)
  2743.                         if clsTurtle.isValuable(self, "forward") then
  2744.                             clsTurtle.place(self, "minecraft:cobblestone", -1, "forward")
  2745.                         end
  2746.                     end
  2747.                     clsTurtle.up(self, 1)
  2748.                     clsTurtle.place(self, "minecraft:cobblestone", -1, "down")
  2749.                     turtle.select(1)
  2750.                 end
  2751.                 if i <= modifier then
  2752.                     clsTurtle.forward(self, 2)
  2753.                 end
  2754.             end
  2755.         elseif move == "+" then
  2756.             local height = 0
  2757.             while turtle.detectUp() do
  2758.                 clsTurtle.up(self, 1)
  2759.                 height = height + 1
  2760.             end
  2761.             clsTurtle.down(self, height)
  2762.         elseif move == "-" then
  2763.             while not turtle.inspectDown() do
  2764.                 clsTurtle.down(self, 1)
  2765.             end
  2766.         elseif move == "*" then
  2767.             local goUp = 0
  2768.             while not turtle.inspectDown() do
  2769.                 clsTurtle.down(self, 1)
  2770.                 goUp = goUp + 1
  2771.             end
  2772.             if goUp > 0 then
  2773.                 for i = 1, goUp do
  2774.                     clsTurtle.up(self, 1)
  2775.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  2776.                         clsTurtle.place(self, "minecraft:dirt", -1, "down")
  2777.                     end
  2778.                 end
  2779.                 goUp = 0
  2780.             else
  2781.                 turtle.digDown()
  2782.                 if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  2783.                     clsTurtle.place(self, "minecraft:dirt", -1, "down")
  2784.                 end
  2785.             end
  2786.         elseif move == "^" then --place stair
  2787.             if not clsTurtle.place(self, "stairs", -1, direction[modifier + 1], false) then -- ending false forces block replacement
  2788.                 print("could not place stairs "..direction[modifier + 1])
  2789.                 clsTurtle.place(self, "minecraft:cobblestone", -1, direction[modifier + 1], false)
  2790.             end
  2791.         elseif move == "@" then -- any item in inventory
  2792.             clsTurtle.place(self, "", -1, direction[modifier + 1], leaveExisting)
  2793.         end
  2794.     end
  2795.     turtle.select(slot)
  2796.     --turtle.select(1)
  2797. end
  2798.  
  2799. function clsTurtle.harvestTree(self, extend, craftChest, direction)
  2800.     extend = extend or false
  2801.     craftChest = craftChest or false
  2802.     direction = direction or "forward"
  2803.     local goHeight = 0
  2804.     local onLeft = true     -- default position in double tree
  2805.     if direction == "forward" then
  2806.         turtle.dig()        -- dig base of tree
  2807.         clsTurtle.forward(self, 1) -- go under tree with 1 log. Will refuel if needed
  2808.     end
  2809.     -- check if on r or l of double width tree
  2810.     clsTurtle.turnLeft(self, 1)
  2811.     local blockType = clsTurtle.getBlockType(self, "forward")
  2812.     if blockType:find("log") ~= nil then
  2813.         extend = true
  2814.         onLeft = false              -- placed on right side of 2 block tree
  2815.     end
  2816.     clsTurtle.turnRight(self, 2)    -- check if double tree
  2817.     blockType = clsTurtle.getBlockType(self, "forward")
  2818.     if blockType:find("log") ~= nil then
  2819.         extend = true
  2820.         onLeft = true               -- placed on left side of 2 block tree
  2821.     end
  2822.     clsTurtle.turnLeft(self, 1) -- return to correct position
  2823.     if craftChest then
  2824.         clsTurtle.dig(self, "up")
  2825.         clsTurtle.up(self, 1)
  2826.         clsTurtle.dig(self, "up")
  2827.         while not clsTurtle.detect(self, "down") do
  2828.             clsTurtle.down(self, 1)
  2829.         end
  2830.         clsTurtle.craft(self, "planks", 8)
  2831.         clsTurtle.craft(self, "chest", 1)
  2832.         while clsTurtle.detect(self, "up") do
  2833.             clsTurtle.up(self, 1)
  2834.             goHeight = goHeight + 1
  2835.         end
  2836.     end
  2837.     -- Loop to climb up tree and harvest trunk and surrounding leaves
  2838.     while clsTurtle.dig(self, "up") do -- continue loop while block detected above
  2839.         clsTurtle.up(self, 1)  -- Move up
  2840.         goHeight = goHeight + 1
  2841.         -- Inner loop to check for leaves/ break double tree logs
  2842.         for i = 1, 4 do
  2843.             blockType = clsTurtle.getBlockType(self, "forward")
  2844.             if blockType:find("log") ~= nil or blockType:find("leaves") ~= nil then
  2845.                 clsTurtle.dig(self, "forward") --Dig leaves / logs in double tree. Leave bee nests
  2846.             end
  2847.             clsTurtle.turnRight(self, 1)
  2848.         end
  2849.     end
  2850.     -- At top of the tree. New loop to return to ground
  2851.     if extend then
  2852.         if onLeft then
  2853.             clsTurtle.go(self, "F1R1F1R2")
  2854.         else
  2855.             clsTurtle.go(self, "F1L1F1R2")
  2856.         end
  2857.         while turtle.detectUp() do
  2858.             clsTurtle.up(self, 1)
  2859.             goHeight = goHeight + 1
  2860.         end
  2861.     end
  2862.     for i = 1, goHeight do
  2863.         if extend then
  2864.             for j = 1, 4 do
  2865.                 clsTurtle.dig(self, "forward")
  2866.                 clsTurtle.turnRight(self, 1)
  2867.             end
  2868.         end
  2869.         clsTurtle.down(self, 1)
  2870.     end
  2871.     -- check for logs below in case felling started above ground
  2872.     while clsTurtle.getBlockType(self, "down"):find("log") ~= nil do
  2873.         clsTurtle.down(self, 1)
  2874.     end
  2875.     if extend then
  2876.         if onLeft then
  2877.             clsTurtle.go(self, "F1L1F1R2")
  2878.         else
  2879.             clsTurtle.go(self, "F1R1F1R2")
  2880.         end
  2881.     end
  2882.     return extend   -- true if double tree
  2883. end
  2884.  
  2885. function clsTurtle.harvestWholeTree(self, direction)   
  2886.     --RECURSIVE FUNCTION - BEWARE!
  2887.     local blockType, modifier, height
  2888.  
  2889.     if direction == "up" then
  2890.         clsTurtle.refuel(self, 15)
  2891.         if clsTurtle.isLog(self, "up") then
  2892.             clsTurtle.up(self, 1)
  2893.             if clsTurtle.isLog(self, "up") then
  2894.                 clsTurtle.harvestWholeTree(self, "up")
  2895.             end
  2896.         end
  2897.         clsTurtle.down(self, 1)
  2898.         for i = 1, 4 do
  2899.             -- check all round
  2900.             if clsTurtle.isLog(self, "forward") then
  2901.                 clsTurtle.harvestWholeTree(self, "forward")
  2902.             else
  2903.                 blockType, modifier = clsTurtle.getBlockType(self, "forward")
  2904.                 if blockType ~= "" then
  2905.                     if string.find(blockType, "leaves") ~= nil then
  2906.                         clsTurtle.forward(self, 1)
  2907.                         clsTurtle.harvestWholeTree(self, "forward")
  2908.                         clsTurtle.back(self, 1)
  2909.                     end
  2910.                 end
  2911.             end
  2912.             clsTurtle.turnRight(self, 1)
  2913.         end
  2914.     elseif direction == "forward" then
  2915.         if clsTurtle.isLog(self, "forward") then
  2916.             clsTurtle.refuel(self, 15)
  2917.            
  2918.             clsTurtle.forward(self, 1)
  2919.             if turtle.detectUp() then
  2920.                 turtle.digUp()
  2921.             end
  2922.             if clsTurtle.isLog(self, "forward") then
  2923.                 clsTurtle.harvestWholeTree(self, "forward")
  2924.             end
  2925.             --check left side
  2926.             clsTurtle.turnLeft(self, 1)
  2927.             if clsTurtle.isLog(self, "forward") then
  2928.                 clsTurtle.harvestWholeTree(self, "forward")
  2929.             end
  2930.             -- check right side
  2931.             clsTurtle.turnRight(self, 2)
  2932.             if clsTurtle.isLog(self, "forward") then
  2933.                 clsTurtle.harvestWholeTree(self, "forward")
  2934.             end
  2935.             clsTurtle.turnLeft(self, 1)
  2936.             clsTurtle.back(self, 1)
  2937.         end
  2938.     end
  2939. end
  2940.  
  2941. function clsTurtle.isEmpty(self)
  2942.     local isEmpty = true
  2943.     for i = 1, 16 do
  2944.         if turtle.getItemCount(i) > 0 then
  2945.             isEmpty = false
  2946.             break
  2947.         end
  2948.     end
  2949.     return isEmpty
  2950. end
  2951.  
  2952. function clsTurtle.isLog(self, direction)
  2953.     local success = false
  2954.     local blockType, modifier
  2955.    
  2956.     local Detect = turtle.detect
  2957.     if direction == 'up' then
  2958.         Detect = turtle.detectUp
  2959.     elseif direction == 'down' then
  2960.         Detect = turtle.detectDown
  2961.     end
  2962.    
  2963.     if Detect() then
  2964.         blockType, modifier = clsTurtle.getBlockType(self, direction)
  2965.         if string.find(blockType, 'log') ~= nil then
  2966.             success = true
  2967.         end
  2968.     end
  2969.    
  2970.     return success
  2971. end
  2972.  
  2973. function clsTurtle.isValuable(self, direction)
  2974.     local success = false
  2975.     local ignoreList = "minecraft:dirt,minecraft:grass,minecraft:stone,minecraft:gravel,minecraft:chest,"..
  2976.                      "minecraft:cobblestone,minecraft:sand,minecraft:torch,minecraft:bedrock,minecraft:ladder"..
  2977.                      "minecraft:netherrack,minecraft:blackstone,minecraft:basalt"..
  2978.                      "minecraft:granite,minecraft:diorite,minecraft:andesite"..
  2979.                      "minecraft:deepslate,minecraft:cobbled_deepslate,minecraft:tuff,minecraft:obsidian,minecraft:end_stone"
  2980.  
  2981.                      
  2982.     local Detect = turtle.detect
  2983.    
  2984.     if direction == "up" then
  2985.         Detect = turtle.detectUp
  2986.     elseif direction == "down" then
  2987.         Detect = turtle.detectDown
  2988.     end
  2989.    
  2990.     local blockType = clsTurtle.getBlockType(self, direction)
  2991.    
  2992.     if blockType ~= "" then --block found
  2993.         success = true
  2994.         if ignoreList:find(blockType) ~= nil then
  2995.             success = false
  2996.         end
  2997.         if blockType:find("lava") ~= nil or blockType:find("water") ~= nil then
  2998.             success = false
  2999.         end
  3000.     end
  3001.     if success then
  3002.         -- check if diamond. or netherite if so ensure space in inventory
  3003.         if blockType:find("diamond") ~= nil or blockType:find("debris") ~= nil then
  3004.             clsTurtle.dumpRefuse(self, direction)
  3005.         end
  3006.     end
  3007.     return success, blockType
  3008. end
  3009.  
  3010. function clsTurtle.isSeaweed(self, direction)
  3011.     --[[ look for seaweed in specified direction ]]
  3012.     local Detect = turtle.detect
  3013.     local blockName, blockModifier
  3014.     if direction == "up" then
  3015.         Detect = turtle.detectUp
  3016.     elseif direction == "down" then
  3017.         Detect = turtle.detectDown
  3018.     end
  3019.     if Detect() then
  3020.         blockName, blockModifier = clsTurtle.getBlockType(self, direction)
  3021.     end
  3022.     if clsTurtle.isVegetation(self, blockName) then
  3023.         return true
  3024.     end
  3025.     return false
  3026. end
  3027.  
  3028. function clsTurtle.isGravityBlock(self, direction)
  3029.     --[[ look for sand, gravel, concrete powder ]]
  3030.     local blockName = clsTurtle.getBlockType(self, direction)
  3031.     if blockName:find("sand") ~= nil or blockName:find("gravel") ~= nil then
  3032.         return true
  3033.     end
  3034.     return false
  3035. end
  3036.  
  3037. function clsTurtle.isEmpty(self)
  3038.     for i = 1, 16 do
  3039.         if turtle.getItemCount(i) > 0 then
  3040.             return false
  3041.         end
  3042.     end
  3043.     return true
  3044. end
  3045.  
  3046. function clsTurtle.isVegetation(self, blockName)
  3047.     blockName = blockName or ""
  3048.     for _, v in pairs(flowers) do
  3049.         if blockName == v then
  3050.             return true
  3051.         end
  3052.     end
  3053.    
  3054.     return false
  3055. end
  3056.  
  3057. function clsTurtle.isWater(self, direction)
  3058.     direction = direction or "forward"
  3059.     local isWater = false
  3060.     local isSource = false
  3061.     local isIce = false
  3062.     local level = nil
  3063.     local isAir = false
  3064.    
  3065.     local blockType, blockModifier, data = clsTurtle.getBlockType(self, direction)     
  3066.     if blockType == "" then
  3067.         return false, false, false, nil, true
  3068.     end
  3069.     if blockType:find("water") ~= nil or blockType == "minecraft:bubble_column" or blockType:find("ice") ~= nil then -- allows for bubble_column
  3070.         isWater = true
  3071.         if blockType == "minecraft:bubble_column" then
  3072.             isSource = true
  3073.         end
  3074.         if blockType:find("ice") ~= nil then
  3075.             isSource = true
  3076.             isIce = true
  3077.         end
  3078.         level = data.state.level
  3079.         if level ~= nil then
  3080.             if level == 0 then
  3081.                 isSource = true
  3082.             end
  3083.         end
  3084.     end
  3085.    
  3086.     -- isWater  = source, ice, flowing water or bubble column
  3087.     -- isSource = source or ice
  3088.     -- isIce    = ice
  3089.     -- level    = nil or flowing water value
  3090.     -- air      = NOT water, source, ice
  3091.     return isWater, isSource, isIce, level, isAir --true, true, false, 0, false = source true, false, false, 1 if next to source
  3092. end
  3093.  
  3094. function clsTurtle.isWaterOrLava(self, direction)
  3095.     direction = direction or "forward"
  3096.     local blockType = ""
  3097.     local blockModifier = -1
  3098.     if not clsTurtle.detect(self, direction) then --air, water or lava
  3099.         blockType, blockModifier = clsTurtle.getBlockType(self, direction)
  3100.         if blockType:find("lava") ~= nil then
  3101.             clsTurtle.place(self, "minecraft:bucket", -1, direction, false) -- auto refuel
  3102.         end
  3103.     end
  3104.     return blockType, blockModifier -- "" or 'minecraft:xxxx"
  3105. end
  3106.  
  3107. function clsTurtle.menu(self, title, list)
  3108.     local retValue = 0
  3109.     response = true
  3110.     while response do
  3111.         response = false
  3112.         clsTurtle.clear(self)
  3113.         print(title.."\n")
  3114.         for i = 1, #list, 1 do
  3115.             print("\t"..i..".  "..list[i])
  3116.         end
  3117.         print("Type number of your choice (1 to "..#list..")_")
  3118.         event, param1 = os.pullEvent ("char")
  3119.         local choice = tonumber(param1)
  3120.         if choice ~= nil then -- number typed
  3121.             if choice >= 1 or choice <= #list then
  3122.                 retValue = choice
  3123.             end
  3124.         else
  3125.             print()
  3126.             print("Incorrect input: "..param1)
  3127.             print()
  3128.             print("Type numbers only, from 1 to "..#list)
  3129.             sleep(2)
  3130.             response = true
  3131.         end
  3132.     end
  3133.     return retValue -- 1 to no of items in the list
  3134. end
  3135.  
  3136. function clsTurtle.place(self, blockType, damageNo, direction, leaveExisting, signText)
  3137.     if blockType == "" then --use any
  3138.         blockType = "stone"
  3139.     end
  3140.     damageNo = damageNo or -1
  3141.     direction = direction or "forward"
  3142.     if leaveExisting == nil then
  3143.         leaveExisting = true
  3144.     end
  3145.     signText = signText or ""
  3146.    
  3147.     local success = false
  3148.     local doContinue = true
  3149.     local dig = true
  3150.     -- assign place methods according to direction
  3151.     local Place = turtle.place
  3152.     if direction == "up" then
  3153.         Place = turtle.placeUp
  3154.     elseif direction == "down" then
  3155.         Place = turtle.placeDown
  3156.     end
  3157.     local slot = clsTurtle.getItemSlot(self, blockType, damageNo)
  3158.     if blockType == "minecraft:bucket" then -- empty bucket for lava or water
  3159.         if slot > 0 then
  3160.             turtle.select(slot)
  3161.             if Place() then -- lava or water collected
  3162.                 if clsTurtle.getSlotContains(self, slot) == "minecraft:lava_bucket" then
  3163.                     clsTurtle.refuel(self, 0)
  3164.                 end
  3165.                 turtle.select(1)
  3166.                 return true, slot
  3167.             end
  3168.         end
  3169.     else
  3170.         local existingBlock = clsTurtle.getBlockType(self, direction)
  3171.         if leaveExisting then -- do not remove existing block unless sand gravel water or lava
  3172.             if clsTurtle.detect(self, direction) then -- not water or lava
  3173.                 if existingBlock:find("sand") ~= nil or existingBlock:find("gravel") ~= nil then --leave anything except sand/gravel   
  3174.                     doContinue = true
  3175.                 end
  3176.             else
  3177.                 doContinue = true
  3178.             end
  3179.         end
  3180.         if existingBlock:find("cobble") ~= nil and blockType:find("cobble") ~= nil then -- already cobble or cobbled deepslate
  3181.             doContinue = false-- no need to replace 1 cobble with another
  3182.         end
  3183.         if doContinue then -- air / water or lava in next block or leaveExisting = false
  3184.             while clsTurtle.dig(self, direction) do
  3185.                 sleep(0.1)
  3186.             end
  3187.             if slot > 0 then -- item to place found
  3188.                 turtle.select(slot)
  3189.                 local attempts = 0
  3190.                 while not Place(signText) do
  3191.                     if clsTurtle.attack(self) then
  3192.                         print("Attacking "..blockType.." ? chest or minecart below")
  3193.                         sleep(1)
  3194.                         --clsTurtle.saveToLog("Error placing "..blockType.." ? chest or minecart below")
  3195.                     end
  3196.                     attempts = attempts + 1
  3197.                     if attempts > 1 then
  3198.                         turtle.select(1)
  3199.                         return false, slot
  3200.                     end
  3201.                 end
  3202.                 success = true
  3203.             end
  3204.         end
  3205.     end
  3206.     turtle.select(1)
  3207.     return success, slot
  3208. end
  3209.  
  3210. function clsTurtle.placeWater(self, direction)
  3211.     direction = direction or "forward"
  3212.     -- assign place methods according to direction
  3213.     local Place = turtle.place
  3214.     if direction == "up" then
  3215.         Place = turtle.placeUp
  3216.     elseif direction == "down" then
  3217.         Place = turtle.placeDown
  3218.     end
  3219.     local slot = clsTurtle.getItemSlot(self, "minecraft:water_bucket")
  3220.     if slot > 0 then
  3221.         turtle.select(slot)
  3222.         if Place() then
  3223.             turtle.select(1)
  3224.             return true
  3225.         end
  3226.     end
  3227.    
  3228.     turtle.select(1)
  3229.     return false
  3230. end
  3231.  
  3232. function clsTurtle.refuel(self, minLevel, toLimitOnly) 
  3233.     minLevel = minLevel or 15
  3234.     if toLimitOnly == nil then
  3235.         toLimitOnly = false
  3236.     end
  3237.     if minLevel == 0 then
  3238.         toLimitOnly = true
  3239.     end
  3240.     local itemSlot = 0
  3241.     local slot = turtle.getSelectedSlot()
  3242.     local count = 0
  3243.     local item = ""
  3244.     local damage = 0
  3245.     local refuelOK = false
  3246.    
  3247.     if turtle.getFuelLevel() >= minLevel and minLevel > 0 then -- prevent auto refuel eg fell tree
  3248.         return false
  3249.     end
  3250.  
  3251.     if turtle.getFuelLevel() >= turtle.getFuelLimit() and toLimitOnly then
  3252.         return false
  3253.     else
  3254.         if turtle.getFuelLevel() < minLevel or minLevel == 0 then
  3255.             -- check each slot for fuel item
  3256.             for i = 1, 16 do
  3257.                 item, count, damage = clsTurtle.getSlotContains(self, i)
  3258.                 if item == "minecraft:lava_bucket" then
  3259.                     turtle.select(i)
  3260.                     if turtle.refuel() then
  3261.                         print("refuelled with lava: "..turtle.getFuelLevel().." / "..turtle.getFuelLimit())
  3262.                         refuelOK = true
  3263.                         break
  3264.                     else
  3265.                         print("lava block deleted: "..turtle.getFuelLevel().." / "..turtle.getFuelLimit())
  3266.                         refuelOK = true
  3267.                         break
  3268.                     end
  3269.                 end
  3270.                 if item == "minecraft:coal" then
  3271.                     turtle.select(i)
  3272.                     if turtle.refuel(1) then
  3273.                         while turtle.getFuelLevel() < minLevel and turtle.getItemCount(i) > 0 do
  3274.                             turtle.refuel(1)
  3275.                         end
  3276.                         print("refuelled with coal: "..turtle.getFuelLevel())
  3277.                         refuelOK = true
  3278.                     end
  3279.                 end
  3280.             end
  3281.             if not refuelOK then
  3282.                 for i = 1, 16 do
  3283.                     item, count, damage = clsTurtle.getSlotContains(self, i)
  3284.                     if string.find(item, "planks") ~= nil then
  3285.                         turtle.select(i)
  3286.                         if turtle.refuel() then
  3287.                             print("refuelled with planks: "..turtle.getFuelLevel())
  3288.                             refuelOK = true
  3289.                         end
  3290.                     end
  3291.                 end
  3292.             end
  3293.             if not refuelOK then
  3294.                 local success = false
  3295.                 for i = 1, 16 do
  3296.                     item, count, damage = clsTurtle.getSlotContains(self, i)
  3297.                     if string.find(item, "log") ~= nil then --logs onboard
  3298.                         print("Refuelling with log slot "..tostring(i)..", crafting planks")
  3299.                         if clsTurtle.craft(self, "planks", 4) then
  3300.                             success = true
  3301.                         else
  3302.                             print("refuel() error crafting planks")
  3303.                         end
  3304.                         if success then
  3305.                             local planksSlot, damage, count = clsTurtle.getItemSlot(self, "planks", -1)
  3306.                             turtle.select(planksSlot)
  3307.                             if turtle.refuel() then
  3308.                                 refuelOK = true
  3309.                             end
  3310.                         end
  3311.                     end
  3312.                 end
  3313.             end
  3314.             if not refuelOK and turtle.getFuelLevel() == 0 then
  3315.                 term.clear()
  3316.                 term.setCursorPos(1,1)
  3317.                 print("Unable to refuel: "..turtle.getFuelLevel().." fuel remaining")
  3318.                 --checkInventoryForItem(self, items, quantities, required, message)
  3319.                 local result = clsTurtle.checkInventoryForItem(self, {"minecraft:lava_bucket", "coal", "planks"}, {1, 10, 32}, false) -- false allows user to press enter
  3320.                 if result == nil then
  3321.                     return false
  3322.                 end
  3323.             end
  3324.         end
  3325.         turtle.select(slot)
  3326.        
  3327.         return refuelOK
  3328.     end
  3329. end
  3330.  
  3331. function clsTurtle.selectPlaceItem(self, item, useDamage)
  3332.     local success = false
  3333.     clsTurtle.getItemSlot(self, item, useDamage)
  3334.     if self.placeSlot > 0 then
  3335.         self.placeItem = item
  3336.     end
  3337. end
  3338.  
  3339. function clsTurtle.setEquipment(self)
  3340.     -- if contains a crafting table, puts it on the right. Any other tool on the left
  3341.     clsTurtle.clear(self)
  3342.     print("Setting up equipment...")
  3343.     local emptySlotR = clsTurtle.getFirstEmptySlot(self) -- first empty slot
  3344.     if emptySlotR == 0 then -- all slots full
  3345.         turtle.select(16)
  3346.         turtle.drop()
  3347.         emptySlotR = 16
  3348.     end
  3349.     local emptySlotL = 0 -- used later
  3350.     local eqRight = ""
  3351.     local eqLeft = ""
  3352.     local equippedRight = ""
  3353.     local equippedLeft = ""
  3354.     local count = 0
  3355.     local damage = 0
  3356.     local pickaxeSlot, damage, total = clsTurtle.getItemSlot(self, "minecraft:diamond_pickaxe", -1)
  3357.     local swordSlot, damage, total = clsTurtle.getItemSlot(self, "minecraft:diamond_sword", -1)
  3358.     local hoeSlot, damage, total = clsTurtle.getItemSlot(self, "minecraft:diamond_hoe", -1)
  3359.     local craftTableSlot, damage, total = clsTurtle.getItemSlot(self, "minecraft:crafting_table", -1)
  3360.     if emptySlotR > 0 then -- empty slot found
  3361.         turtle.select(emptySlotR)
  3362.         if turtle.equipRight() then -- remove tool on the right
  3363.             eqRight, count, damage = clsTurtle.getSlotContains(self, emptySlotR) -- eqRight contains name of tool from right side
  3364.             if eqRight == "minecraft:crafting_table" then
  3365.                 craftTableSlot = emptySlotR
  3366.                 eqRight = ""
  3367.             elseif eqRight == "minecraft:diamond_pickaxe" then
  3368.                 pickaxeSlot = emptySlotR
  3369.                 eqRight = ""
  3370.             elseif eqRight == "minecraft:diamond_sword" then
  3371.                 swordSlot = emptySlotR
  3372.                 eqRight = ""
  3373.             elseif eqRight == "minecraft:diamond_hoe" then
  3374.                 hoeSlot = emptySlotR
  3375.                 eqRight = ""
  3376.             end -- eqRight
  3377.             emptySlotL = clsTurtle.getFirstEmptySlot(self) -- get next empty slot
  3378.             if emptySlotL == 0 then -- all slots full
  3379.                 if emptySlotR ~= 15 then
  3380.                     turtle.select(15)
  3381.                     turtle.drop()
  3382.                     emptySlotL = 15
  3383.                 else
  3384.                     turtle.select(16)
  3385.                     turtle.drop()
  3386.                     emptySlotL = 16
  3387.                 end
  3388.             end
  3389.         else -- nothing equipped on right side
  3390.             emptySlotL = emptySlotR
  3391.         end
  3392.         if emptySlotL > 0 then -- empty slot found
  3393.             turtle.select(emptySlotL)
  3394.             if turtle.equipLeft() then -- remove tool on the left
  3395.                 eqLeft, count, damage = clsTurtle.getSlotContains(self, emptySlotL) -- eqLeft contains name of tool from left side
  3396.                 if eqLeft == "minecraft:diamond_pickaxe" then
  3397.                     pickaxeSlot = emptySlotL
  3398.                     eqLeft = ""
  3399.                 elseif eqLeft == "minecraft:diamond_sword" then
  3400.                     swordSlot = emptySlotL
  3401.                     eqLeft = ""
  3402.                 elseif eqLeft == "minecraft:diamond_hoe" then
  3403.                     hoeSlot = emptySlotL
  3404.                     eqLeft = ""
  3405.                 elseif eqLeft == "minecraft:crafting_table" then
  3406.                     craftTableSlot = emptySlotL
  3407.                     eqLeft = ""
  3408.                 end
  3409.             end
  3410.         end
  3411.         if pickaxeSlot > 0 then
  3412.             turtle.select(pickaxeSlot)
  3413.             turtle.equipLeft()
  3414.             equippedLeft = "minecraft:diamond_pickaxe" 
  3415.             self.equippedLeft = "minecraft:diamond_pickaxe"
  3416.         end
  3417.         if craftTableSlot > 0 then
  3418.             turtle.select(craftTableSlot)
  3419.             turtle.equipRight()
  3420.             equippedRight = "minecraft:crafting_table"
  3421.             self.equippedRight = "minecraft:crafting_table"
  3422.         end
  3423.         inInventory = ""
  3424.         if swordSlot > 0 then
  3425.             inInventory = "minecraft:diamond_sword"
  3426.         elseif hoeSlot > 0 then
  3427.             inInventory = "minecraft:diamond_hoe"
  3428.         end
  3429.     end
  3430.     -- any tools equipped except diamond_pickaxe and crafting_table have been removed to inventory
  3431.     return equippedRight, equippedLeft, inInventory
  3432. end
  3433.    
  3434. function clsTurtle.sortInventory(self, useChest)
  3435.     useChest = useChest or true
  3436.     local lib = {}
  3437.    
  3438.     function lib.checkForStorage(self)
  3439.         local blockType = clsTurtle.getBlockType(self, "forward")
  3440.         if blockType:find("barrel") ~= nil or blockType:find("chest") ~= nil then
  3441.             return "forward"
  3442.         end
  3443.         blockType = clsTurtle.getBlockType(self, "up")
  3444.         if blockType:find("barrel") ~= nil or blockType:find("chest") ~= nil then
  3445.             return "up"
  3446.         end
  3447.         blockType = clsTurtle.getBlockType(self, "down")
  3448.         if blockType:find("barrel") ~= nil or blockType:find("chest") ~= nil then
  3449.             return "down"
  3450.         end
  3451.         return ""
  3452.     end
  3453.    
  3454.     function lib.chestSort(self, chestDirection)
  3455.         for i = 1, 16 do    -- fill chest with everything
  3456.             clsTurtle.drop(self, chestDirection, i)
  3457.         end
  3458.         local success, msg
  3459.         repeat
  3460.             success, msg = clsTurtle.suck(self, chestDirection)
  3461.         until not success
  3462.         --while clsTurtle.suck(self, chestDirection) do end -- remove everything
  3463.     end
  3464.    
  3465.     local chestSlot = 0
  3466.     if useChest then
  3467.         chestSlot = clsTurtle.getItemSlot(self, "minecraft:chest", -1) --get the slot number containing a chest
  3468.         if chestSlot == 0 then
  3469.             chestSlot = clsTurtle.getItemSlot(self, "minecraft:barrel", -1) --get the slot number containing a barrel
  3470.         end
  3471.     end
  3472.     local blockType
  3473.     local facing = self.facing
  3474.     local chestPlaced = false
  3475.     local chestDirection, turns = "", 0
  3476.     if chestSlot > 0 then -- chest found
  3477.         local chestDirection, turns = clsTurtle.getPlaceChestDirection(self)    -- find empty block to place it.
  3478.         for i = 1, 10 do    -- attempt to place chest 10x
  3479.             if clsTurtle.place(self, "minecraft:chest", -1, chestDirection) then
  3480.                 chestPlaced = true
  3481.                 break
  3482.             elseif clsTurtle.place(self, "minecraft:barrel", -1, chestDirection) then
  3483.                 chestPlaced = true
  3484.                 break
  3485.             else
  3486.                 clsTurtle.attack(self) -- will force wait for mob
  3487.             end
  3488.         end
  3489.         if chestPlaced then
  3490.             lib.chestSort(self, chestDirection)
  3491.             --while clsTurtle.suck(self, chestDirection) do end -- remove everything
  3492.             clsTurtle.dig(self, chestDirection, false) -- collect chest (false = do not bypass chest)
  3493.         end
  3494.         if turns > 0 then   --return to original position
  3495.             clsTurtle.turnLeft(self, turns)
  3496.         end
  3497.     else
  3498.         if useChest then -- false eg in mining, where storage chest may be full, and essential items not retrieved
  3499.             chestDirection = lib.checkForStorage(self)
  3500.             if chestDirection ~= "" then
  3501.                 chestPlaced = true
  3502.                 lib.chestSort(self, chestDirection)
  3503.             end
  3504.         end
  3505.     end
  3506.     if not chestPlaced then -- no chest or unable to place it
  3507.         for x = 1, 15 do -- sort inventory
  3508.             for i = x + 1 , 16 do
  3509.                 if turtle.getItemCount(i) > 0 then
  3510.                     turtle.select(i)
  3511.                     if turtle.compareTo(x) then
  3512.                         turtle.transferTo(x)
  3513.                     end
  3514.                 end
  3515.             end
  3516.         end
  3517.         for  x = 1, 15 do
  3518.             if turtle.getItemCount(x) == 0 then -- slot empty, move from next available filled slot
  3519.                 for i = x + 1, 16 do
  3520.                     if turtle.getItemCount(i) > 0 then
  3521.                         turtle.select(i)
  3522.                         turtle.transferTo(x)
  3523.                         break
  3524.                     end
  3525.                 end
  3526.             end
  3527.         end
  3528.     end
  3529.     turtle.select(1)
  3530. end
  3531.  
  3532. function clsTurtle.suck(self, direction, slot, quantity)
  3533.     slot = slot or 1
  3534.     direction = direction or "forward"
  3535.     -- success, msg = turtle.suck()
  3536.     -- success = true / false
  3537.     -- msg = "No space for items" / nil
  3538.    
  3539.     turtle.select(slot)
  3540.     local Suck = turtle.suck
  3541.     if direction == "up" then
  3542.         Suck = turtle.suckUp
  3543.     elseif direction == "down" then
  3544.         Suck = turtle.suckDown
  3545.     end
  3546.     local success, msg
  3547.     if quantity == nil then
  3548.         success, msg = Suck()
  3549.     else
  3550.         success, msg = Suck(quantity)
  3551.     end
  3552.     turtle.select(1)
  3553.     return success, msg
  3554. end
  3555.  
  3556. function clsTurtle.trimItemName(self, item)
  3557.     itemName = item
  3558.     colonPos = item:find(":")
  3559.     if colonPos ~= nil then
  3560.         itemName = item:sub(colonPos + 1)
  3561.     end
  3562.    
  3563.     return itemName
  3564. end
  3565.  
  3566. function clsTurtle.writeCoords(self, filename)
  3567.     -- create/append e.g 'SpawnerCoords.txt'
  3568.     local fileHandle = fs.open(filename, "a")
  3569.     fileHandle.writeLine("x="..self.x)
  3570.     fileHandle.writeLine("y="..self.y)
  3571.     fileHandle.writeLine("z="..self.z)
  3572.     fileHandle.writeLine("f="..self.facing)
  3573.     fileHandle.close()
  3574.     clsTurtle.saveToLog(self, filename.." file created", true)
  3575.     clsTurtle.saveToLog(self, "x = "..clsTurtle.getX(self)..", y = "..clsTurtle.getY(self)..", z = "..clsTurtle.getZ(self)..", f = "..clsTurtle.getFacing(self), false)
  3576. end
  3577.  
  3578. doLog = clsTurtle.saveToLog --shortcut for logging within this class. usage: doLog(self, string<text>, bool<toScreen=true>) ex: doLog(self, "This message also shows on terminal", true)
  3579. return clsTurtle
Add Comment
Please, Sign In to add comment