Inksaver

Self-Replicating Turtle 2018 update

Apr 27th, 2014
8,321
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 151.33 KB | None | 0 0
  1. -- Replacement for code originally pasted in 2014
  2. -- selfReplicate2018.lua last modified 12/12/2018
  3. -- Using CC 1.65 to 1.79 on Minecraft 1.7.10 and 1.8.9
  4. -- Takes advantage of turtle.inspect() and turtle.getItemDetail()
  5. -- pastebin http://pastebin.com/2Zf5an8H
  6. -- multiline comments not used as Pastebin trashes the appearance of the code!
  7. -- functions in alphabetical order except main()
  8. -- classes declared before functions
  9. -- CraftOS 1.6 names: (altered in main() if using CraftOS 1.7)
  10.  
  11. -- global variables
  12. local ccComputer = "ComputerCraft:CC-Computer"
  13. local ccDisk = "ComputerCraft:disk"
  14. local ccTurtle = "ComputerCraft:CC-Turtle"
  15. local ccCraftyMiningTurtle = "ComputerCraft:CC-TurtleExpanded"
  16. local ccDiskDrive = "ComputerCraft:CC-Peripheral"
  17. local pastebinCode = "2Zf5an8H"
  18.  
  19. -- classes
  20. function classCoord(coordName)
  21.     -- 0 = go south (z increases)
  22.     -- 1 = go west  (x decreases)
  23.     -- 2 = go north (z decreases
  24.     -- 3 = go east  (x increases)
  25.  
  26.     -- compass[0] = "south"
  27.     -- compass[1] = "west"
  28.     -- compass[2] = "north"
  29.     -- compass[3] = "east"
  30.    
  31.     clsCoord = {} -- the table representing the class, which will double as the metatable for any instances
  32.     clsCoord.__index = clsCoord -- failed table lookups on the instances should fallback to the class table, to get methods
  33.  
  34.     local self = setmetatable({}, clsCoord)
  35.     self.name = coordName
  36.     self.x = 0
  37.     self.y = 0
  38.     self.z = 0
  39.     self.facing = 0
  40.     self.compass = "south"
  41.        
  42.     function clsCoord.getX(self)
  43.         return self.x
  44.     end
  45.     function clsCoord.setX(self, newVal) -- setter
  46.         self.x = newVal
  47.     end
  48.     function clsCoord.getY(self) -- getter
  49.         return self.y
  50.     end
  51.     function clsCoord.setY(self, newVal)
  52.         self.y = newVal
  53.     end
  54.     function clsCoord.getZ(self)
  55.         return self.z
  56.     end
  57.     function clsCoord.setZ(self, newVal)
  58.         self.z = newVal
  59.     end
  60.     function clsCoord.getFacing(self)
  61.         return self.facing
  62.     end
  63.     function clsCoord.setFacing(self, newVal) -- setter
  64.         self.facing = newVal
  65.         if self.facing < 0 then
  66.                 self.facing = 3
  67.         elseif self.facing > 3 then
  68.                 self.facing = 0
  69.         end
  70.         if self.facing == 0 then
  71.             self.compass = "south"
  72.         elseif self.facing == 1 then
  73.             self.compass = "west"
  74.         elseif self.facing == 2 then
  75.             self.compass = "north"
  76.         else
  77.             self.compass = "east"
  78.         end
  79.     end
  80.     function clsCoord.getCompass(self)
  81.         return self.compass
  82.     end
  83.     function clsCoord.setCompass(self, newVal) -- setter
  84.         self.compass = newVal
  85.  
  86.         if self.compass == "south" then
  87.             self.facing = 0
  88.         elseif self.compass == "west" then
  89.             self.facing = 1
  90.         elseif self.compass == "north" then
  91.             self.facing = 2
  92.         elseif self.compass == "east" then
  93.             self.facing = 3
  94.         end
  95.     end
  96.     function clsCoord.goUp(blocks)
  97.         blocks = blocks or 1
  98.         self.y = self.y + blocks
  99.     end
  100.     function clsCoord.goDown(blocks)
  101.         blocks = blocks or 1
  102.         self.y = self.y - blocks
  103.     end
  104.     --  uses:
  105.     --  location:getX()             get current turtle x coordinate
  106.     --  location:getY()             get current turtle y coordinate
  107.     --  location:getZ()             get current turtle z coordinate
  108.     --  location:setX(xCoord)       set current turtle x coordinate eg location:setX(-235)
  109.     --  location:setY(yCoord)       set current turtle y coordinate eg location:setY(66)
  110.     --  location:setZ(zCoord)       set current turtle z coordinate eg location:setZ(125)
  111.     --  location:getFacing()        returns a number 0 - 3 representing direction of player
  112.     --  location:setFacing(facing)  sets direction eg location:setFacing(1) (West)
  113.     --  location:getCompass()       returns direction as text eg "north"
  114.     --  location:setCompass("X")    sets direction using text eg location:setCompass("south")
  115.     --  location:goUp(X)            increases Y coord by X
  116.     --  location:goDown(X)          decreases Y coord by X
  117.     return self
  118. end
  119.  
  120. function classTreeFarm()
  121.     clsTreeFarm = {} -- the table representing the class, which will double as the metatable for any instances
  122.     clsTreeFarm.__index = clsTreeFarm -- failed table lookups on the instances should fallback to the class table, to get methods
  123.  
  124.     local self = setmetatable({}, clsTreeFarm)
  125.    
  126.     self.numSaplings = 0
  127.     self.timePlanted = 0
  128.     self.dayPlanted = 0
  129.     self.timeHarvested = 0
  130.     self.woodHarvested = 0
  131.     self.pondFilled = false
  132.     self.hopperPlaced = false
  133.     self.farmCreated = false
  134.     self.farmFlooded = false
  135.     self.waterFound = false
  136.    
  137.     function clsTreeFarm.reset(self)
  138.         self.numSaplings = 0
  139.         self.timePlanted = 0
  140.         self.dayPlanted = 0
  141.         self.timeHarvested = 0
  142.         self.woodHarvested = 0
  143.     end
  144.    
  145.     function clsTreeFarm.getPondFilled(self)
  146.         return self.pondFilled
  147.     end
  148.     function clsTreeFarm.setPondFilled(self, yesNo)
  149.         self.pondFilled = yesNo
  150.     end
  151.    
  152.     function clsTreeFarm.getWaterFound(self)
  153.         return self.waterFound
  154.     end
  155.     function clsTreeFarm.setWaterFound(self, yesNo)
  156.         self.waterFound = yesNo
  157.     end
  158.    
  159.     function clsTreeFarm.getHopperPlaced(self)
  160.         return self.hopperPlaced
  161.     end
  162.     function clsTreeFarm.setHopperPlaced(self, yesNo)
  163.         self.hopperPlaced = yesNo
  164.     end
  165.    
  166.     function clsTreeFarm.getFarmCreated(self)
  167.         return self.farmCreated
  168.     end
  169.     function clsTreeFarm.setFarmCreated(self, yesNo)
  170.         self.farmCreated = yesNo
  171.     end
  172.    
  173.     function clsTreeFarm.getFarmFlooded(self)
  174.         return self.farmFlooded
  175.     end
  176.     function clsTreeFarm.setFarmFlooded(self, yesNo)
  177.         self.farmFlooded = yesNo
  178.     end
  179.    
  180.     function clsTreeFarm.getNumSaplings(self)
  181.         return self.numSaplings
  182.     end
  183.     function clsTreeFarm.setNumSaplings(self, num)
  184.         self.numSaplings = num
  185.     end
  186.     function clsTreeFarm.addSapling(self)
  187.         self.numSaplings = self.numSaplings + 1
  188.     end
  189.     function clsTreeFarm.getTimePlanted(self)
  190.         return self.timePlanted
  191.     end
  192.     function clsTreeFarm.setTimePlanted(self, num)
  193.         self.timePlanted = num
  194.         self.dayPlanted = os.day()
  195.     end
  196.     function clsTreeFarm.getTimeHarvested(self)
  197.         return self.timeHarvested
  198.     end
  199.     function clsTreeFarm.setTimeHarvested(self, num)
  200.         self.timeHarvested = num
  201.     end
  202.    
  203.     function clsTreeFarm.getWoodHarvested(self)
  204.         return self.woodHarvested
  205.     end
  206.     function clsTreeFarm.setWoodHarvested(self, num)
  207.         self.woodHarvested = num
  208.     end
  209.    
  210.     function clsTreeFarm.getMaxHarvest(self)
  211.         return self.numSaplings * 5
  212.     end
  213.    
  214.     function clsTreeFarm.setDebug(self, saplings, trees)
  215.         --use if debugging and treeFarm already planted
  216.         self.numSaplings = saplings + trees
  217.         self.timePlanted = os.time()
  218.         if trees >= 6 then
  219.             self.dayPlanted = os.day() - 3
  220.         end
  221.     end
  222.    
  223.     function clsTreeFarm.getPotentialHarvest(self)
  224.         local currentDay = os.day()
  225.         local currentTime = os.time()
  226.         local numDays = 0
  227.         local numHours = 0
  228.         local harvest = 0
  229.        
  230.         --days measured from world creation
  231.         numDays = currentDay - self.dayPlanted
  232.        
  233.         --time 0 - 24 then resets
  234.         if currentTime > self.timePlanted then -- eg 13.5 > 7.5 (13.5 - 7.5 = 6 hours)
  235.             numHours = currentTime - self.timePlanted
  236.         else -- eg 6.465 < 21.454
  237.             numHours = 24 - self.timePlanted + currentTime -- eg 24 - 21.500 + 6.500 = 9 hours
  238.         end
  239.         -- 8 trees planted, half done in 12-14 minecraft hours
  240.         -- 1 tree  4.5 hrs
  241.         -- 2 trees 7 hrs
  242.         -- 3 trees 8 hrs
  243.         -- 4 trees 13 hrs
  244.         -- 5 trees 20 hrs
  245.         -- 6 trees 30 hours
  246.         -- estimate as half no of saplings per 12 hours
  247.         if numDays == 0 then
  248.             harvest = math.ceil((5 * self.numSaplings) / 2)
  249.         elseif numDays == 1 then
  250.             harvest = math.ceil(((5 * self.numSaplings) * 2) / 3)
  251.         else -- > 2 days probably most trees * 5 wood
  252.             harvest = 5 * self.numSaplings
  253.         end
  254.        
  255.         return harvest
  256.     end
  257.    
  258.     return self
  259. end
  260.  
  261. function classTurtle()  
  262.     clsTurtle = {} -- the table representing the class, which will double as the metatable for any instances
  263.     clsTurtle.__index = clsTurtle -- failed table lookups on the instances should fallback to the class table, to get methods
  264.  
  265.     local self = setmetatable({}, clsTurtle)
  266.     -- class scope variables
  267.     self.x = 0
  268.     self.y = 0
  269.     self.z = 0
  270.     self.facing = 0
  271.     self.compass = ""
  272.     self.equippedLeft = ""
  273.     self.equippedRight = ""
  274.     self.placeItem = ""
  275.     -- logging variables
  276.     self.useLog = false
  277.     self.logFileName = ""
  278.     self.logFileExists = false
  279.     self.mobAttack = false
  280.    
  281.     -- helper function for iterating lists
  282.     function clsTurtle.values(self,t) -- general diy iterator
  283.         local i = 0
  284.         return function() i = i + 1; return t[i] end
  285.     end
  286.    
  287.     -- logging methods
  288.     function clsTurtle.getUseLog(self)
  289.         return self.useLog
  290.     end
  291.     function clsTurtle.setUseLog(self, use)
  292.         self.useLog = use
  293.         return use
  294.     end
  295.     function clsTurtle.getLogExists(self)
  296.         exists = false
  297.         if fs.exists(self.logFileName) then
  298.             exists = true
  299.         end
  300.         return exists
  301.     end
  302.     function clsTurtle.getLogFileName(self)
  303.         return self.logFileName
  304.     end
  305.     function clsTurtle.setLogFileName(self, value)
  306.         self.logFileName = value
  307.     end
  308.     function clsTurtle.getCurrentFileSize(self)    
  309.         if self.logFileExists then
  310.             return fs.getSize(self.logFileName)
  311.         else
  312.             return 0
  313.         end
  314.     end
  315.     function clsTurtle.deleteLog(self)     
  316.         if fs.exists(self.logFileName) then
  317.             fs.delete(self.logFileName)
  318.         end
  319.         self.logFileExists = false
  320.        
  321.         return true
  322.     end
  323.     function clsTurtle.appendLine(self, newText)
  324.         local handle = ""
  325.        
  326.         if fs.exists(self.logFileName) then --logFile already created
  327.             handle = fs.open(self.logFileName, "a")
  328.         else
  329.             handle = fs.open(self.logFileName, "w") --create file
  330.         end
  331.         self.logFileExists = true
  332.         handle.writeLine(newText)
  333.         handle.close()
  334.     end
  335.     function clsTurtle.saveToLog(self, text, toScreen)
  336.         if toScreen == nil then
  337.             toScreen = true
  338.         end
  339.         if text ~= "" and text ~= nil then
  340.             if toScreen then
  341.                 print(text)
  342.             end
  343.             if self.useLog then
  344.                 clsTurtle.appendLine(self, text)
  345.             end
  346.         end
  347.     end
  348.    
  349.     -- getters and setters
  350.     function clsTurtle.getX(self) return self.x end
  351.     function clsTurtle.setX(self, newVal) self.x = newVal end
  352.     function clsTurtle.getY(self) return self.y end
  353.     function clsTurtle.setY(self, newVal) self.y = newVal end
  354.     function clsTurtle.getZ(self) return self.z end
  355.     function clsTurtle.setZ(self, newVal) self.z = newVal end
  356.     function clsTurtle.getFacing(self) return self.facing end
  357.     function clsTurtle.setFacing(self, newVal)
  358.         local direction = {"south","west","north","east"}
  359.         self.facing = newVal
  360.         if self.facing < 0 then
  361.             self.facing = 3
  362.         elseif self.facing > 3 then
  363.             self.facing = 0
  364.         end
  365.         self.compass = direction[self.facing + 1]
  366.     end
  367.     function clsTurtle.getCompass(self) return self.compass end
  368.     function clsTurtle.getPlaceItem(self) return self.placeItem end
  369.     function clsTurtle.setPlaceItem(self, item, useDamage)
  370.         local success = false
  371.         local slot = clsTurtle.getItemSlot(self, item, useDamage)
  372.         if slot > 0 then
  373.             self.placeItem = item
  374.         end
  375.     end
  376.     function clsTurtle.getEquipped(self, side)
  377.         retValue = ""
  378.         if side == "left" then
  379.             retValue = self.equippedLeft
  380.         else
  381.             retValue = self.equippedRight
  382.         end
  383.         return retValue
  384.     end
  385.     function clsTurtle.setEquipped(self, side, value)
  386.         if side == "left" then
  387.             self.equippedLeft = value
  388.         elseif side == "right" then
  389.             self.equippedRight = value
  390.         end
  391.     end
  392.    
  393.     -- change direction and movement methods
  394.     function clsTurtle.attack(self, direction) 
  395.         direction = direction or "forward"
  396.         local slot = turtle.getSelectedSlot()
  397.         turtle.select(1)
  398.         local success = false
  399.         local attackLimit = 10 -- won't get in infinite loop attacking a minecart chest
  400.  
  401.         if direction == "up" then
  402.             while turtle.attackUp() do --in case mob above
  403.                 sleep(1.5)
  404.                 attackLimit = attackLimit - 1
  405.                 if attackLimit <= 0 then
  406.                     break
  407.                 end        
  408.             end
  409.         elseif direction == "down" then
  410.             while turtle.attackDown() do --in case mob below
  411.                 sleep(1.5)
  412.                 attackLimit = attackLimit - 1
  413.                 if attackLimit <= 0 then
  414.                     break
  415.                 end
  416.             end
  417.         else
  418.             while turtle.attack() do --in case mob in front
  419.                 sleep(1.5)
  420.                 attackLimit = attackLimit - 1
  421.                 if attackLimit <= 0 then
  422.                     break
  423.                 end
  424.             end
  425.         end
  426.         if attackLimit > 0 then
  427.             success = true
  428.         end
  429.         turtle.select(slot)
  430.         return success
  431.     end
  432.    
  433.     function clsTurtle.back(self, steps)
  434.         steps = steps or 1
  435.         local success = false
  436.        
  437.         clsTurtle.refuel(self, steps)
  438.         turtle.select(1)
  439.         for i = 1, steps do
  440.             if not turtle.back() then --cant move back
  441.                 clsTurtle.turnRight(self, 2) --face backward direction
  442.                 if clsTurtle.forward(self, 1) then-- will also attack mobs if in the way
  443.                     success = true
  444.                     clsTurtle.changeCoords(self, "back")
  445.                 end
  446.                 clsTurtle.turnRight(self, 2)
  447.             end
  448.         end
  449.        
  450.         return success
  451.     end
  452.    
  453.     function clsTurtle.changeCoords(self, direction)
  454.         --  0 = go south (z increases)
  455.         --  1 = go west  (x decreases)
  456.         --  2 = go north (z decreases
  457.         --  3 = go east  (x increases)
  458.         if direction == "forward" then
  459.             if self.facing == 0 then
  460.                 self.z = self.z + 1
  461.             elseif self.facing == 1 then
  462.                 self.x = self.x - 1
  463.             elseif self.facing == 2 then
  464.                 self.z = self.z - 1
  465.             else
  466.                 self.x = self.x + 1
  467.             end
  468.         elseif direction == "back" then
  469.             if self.facing == 0 then
  470.                 self.z = self.z - 1
  471.             elseif self.facing == 1 then
  472.                 self.x = self.x + 1
  473.             elseif self.facing == 2 then
  474.                 self.z = self.z + 1
  475.             else
  476.                 self.x = self.x - 1
  477.             end
  478.         end
  479.     end
  480.  
  481.     function clsTurtle.down(self, steps)
  482.         steps = steps or 1
  483.         local success = false
  484.        
  485.         clsTurtle.refuel(self, steps)
  486.         turtle.select(1)
  487.         for i = 1, steps do
  488.             if turtle.detectDown() then -- block below
  489.                 if clsTurtle.getBlockType(self, "down") == "minecraft:bedrock" then
  490.                     break
  491.                 else
  492.                     turtle.digDown()
  493.                 end
  494.             end
  495.             if turtle.down() then --move down unless mob in the way
  496.                 success = true
  497.             else -- not bedrock, could be mob or minecart
  498.                 if clsTurtle.attack(self, "down") then -- attack succeeded
  499.                     if turtle.down() then
  500.                         success = true
  501.                     end
  502.                 end
  503.             end
  504.             if success then
  505.                 self.y = self.y - 1
  506.             end
  507.         end
  508.        
  509.         return success
  510.     end
  511.    
  512.     function clsTurtle.forward(self, steps)    
  513.         steps = steps or 1
  514.         local result, data
  515.         local success = true
  516.         local retryMove = 10
  517.        
  518.         clsTurtle.refuel(self, steps)
  519.         turtle.select(1)
  520.         for i = 1, steps do
  521.             while turtle.detect() do -- allow for sand/gravel falling
  522.                 if not clsTurtle.dig(self, "forward") then-- cannot dig. either bedrock or in server protected area
  523.                     success = false
  524.                     if clsTurtle.getBlockType(self, "forward") == "minecraft:bedrock" then
  525.                         print("Bedrock in front:function exit")
  526.                     end
  527.                     break
  528.                 end
  529.             end
  530.             success = false
  531.             if turtle.forward() then
  532.                 success = true
  533.             else
  534.                 if self.mobAttack then
  535.                     if clsTurtle.attack(self, "forward") then
  536.                         if turtle.forward() then
  537.                             success = true
  538.                         end
  539.                     else               
  540.                         result, data = turtle.forward()
  541.                         print(data..":function exit")
  542.                         break
  543.                     end
  544.                 else
  545.                     while not turtle.forward() do
  546.                         clsTurtle.saveToLog(self, "Waiting for mob to leave...", true)
  547.                         sleep(5)
  548.                         retryMove = retryMove - 1
  549.                         if retryMove <= 0 then
  550.                             break
  551.                         end
  552.                     end
  553.                     if retryMove  <= 0 then
  554.                         if clsTurtle.attack(self, "forward") then
  555.                             if turtle.forward() then
  556.                                 success = true
  557.                             end
  558.                         else               
  559.                             result, data = turtle.forward()
  560.                             print(data..":function exit")
  561.                             break
  562.                         end
  563.                     end
  564.                 end
  565.             end
  566.             if success then
  567.                 clsTurtle.changeCoords(self, "forward")
  568.             end
  569.         end
  570.         return success
  571.     end
  572.    
  573.     function clsTurtle.turnLeft(self, steps)
  574.         steps = steps or 1
  575.         for i = 1, steps do
  576.             turtle.turnLeft()
  577.             self.facing = self.facing - 1
  578.             if self.facing < 0 then
  579.                 self.facing = 3
  580.             end
  581.         end
  582.     end
  583.  
  584.     function clsTurtle.turnRight(self, steps)
  585.         steps = steps or 1
  586.         for i = 1, steps do
  587.             turtle.turnRight()
  588.             self.facing = self.facing + 1
  589.             if self.facing > 3 then
  590.                 self.facing = 0
  591.             end
  592.         end
  593.     end
  594.    
  595.     function clsTurtle.up(self, steps)
  596.         steps = steps or 1
  597.         local success = false
  598.         clsTurtle.refuel(self, steps)
  599.         turtle.select(1)
  600.  
  601.         for i = 1, steps do
  602.             if turtle.detectUp() then -- block above
  603.                 if clsTurtle.getBlockType(self, "up") == "minecraft:bedrock" then
  604.                     print("Bedrock above:function exit")
  605.                     break
  606.                 else
  607.                     clsTurtle.dig(self, "up")
  608.                 end
  609.             end
  610.             if turtle.up() then  --move up unless mob in the way
  611.                 success = true
  612.             else
  613.                 if clsTurtle.attack(self, "up") then -- attack succeeded
  614.                     if turtle.up() then
  615.                         success = true
  616.                     end
  617.                 end
  618.             end
  619.             if success then
  620.                 self.y = self.y + 1
  621.             end
  622.         end
  623.         return success
  624.     end
  625.    
  626.     -- other methods
  627.     function clsTurtle.clear(self)
  628.         term.clear()
  629.         term.setCursorPos(1,1)
  630.     end
  631.    
  632.     function clsTurtle.checkInventoryForItem(self, item, minQuantity, altItem, altMinQuantity) 
  633.         -- request player to add items to turtle inventory
  634.         clsTurtle.clear(self)
  635.         minQuantity = minQuantity or 1
  636.         altItem = altItem or ""
  637.         altMinQuantity = altMinQuantity or 0
  638.         local gotItemSlot = 0
  639.         local gotAltItemSlot = 0
  640.         local damage = 0
  641.         local count = 0
  642.         print("Add "..item.." to any single slot "..minQuantity.." needed")
  643.         if altItem ~= "" then
  644.             print("Or add "..altItem.." to any slot "..altMinQuantity.." needed")
  645.         end
  646.         while (count < minQuantity + altMinQuantity) do
  647.             gotItemSlot, damage, count = clsTurtle.getItemSlot(self, item, -1) -- 0 if not present. return slotData.leastSlot, slotData.leastSlotDamage, total, slotData -- first slot no, integer, integer, table
  648.             if gotItemSlot > 0 and count >= minQuantity then
  649.                 break
  650.             else
  651.                 sleep(0.5)
  652.             end
  653.             if altItem ~= "" then
  654.                 gotAltItemSlot, damage, count = clsTurtle.getItemSlot(self, altItem, -1)
  655.                 if gotAltItemSlot > 0 and count >= altMinQuantity then
  656.                     break  
  657.                 else
  658.                     sleep(0.5)
  659.                 end
  660.             end
  661.             coroutine.yield()
  662.         end
  663.     end
  664.    
  665.     function clsTurtle.craft(self, craftItem, craftQuantity, sourceItem1, sourceItem2, sourceItem3, refuel)
  666.         --Examples:
  667.         --make planks:  T:craft("minecraft:planks", 8, "minecraft:log", nil, nil, false)
  668.         --make planks:  clsTurtle.craft(self, "minecraft:planks", 8, "minecraft:log", nil, nil, false)
  669.         --make planks:  T:craft{craftItem = "minecraft:planks", craftQuantity = 8, sourceItem1 = "minecraft:log"}
  670.         --make 1 chest: T:craft{craftItem = "minecraft:chest", craftQuantity = 1, sourceItem1 = "minecraft:planks"}
  671.         --late stage:   T:craft{craftItem = "ccComputer", craftQuantity = 1, sourceItem1 = "minecraft:glass_pane", sourceItem2 = "minecraft:redstone", sourceItem3 = "minecraft:stone"}
  672.        
  673.         local sourceSlot1 = 0
  674.         local sourceSlot2 = 0  
  675.         local sourceSlot3 = 0
  676.         local sourceSlot4 = 0
  677.         local success = false
  678.         local emptySlot = 0
  679.         local turns = 0
  680.         local doContinue = true
  681.         local blockType = ""
  682.         local stockData = {}
  683.         local slot = turtle.getSelectedSlot()
  684.         local facing = self.facing
  685.         local chestDirection = "forward"
  686.         turtle.select(1)
  687.         -- check if at least 1 spare slot
  688.         if clsTurtle.getFirstEmptySlot(self) == 0 then
  689.             clsTurtle.emptyTrash(self, "down")
  690.             if clsTurtle.getFirstEmptySlot(self) == 0 then
  691.                 turtle.select(clsTurtle.getItemSlot(self, "minecraft:cobblestone"))
  692.                 turtle.dropUp()
  693.             end
  694.         end
  695.        
  696.         if clsTurtle.getItemSlot(self, "minecraft:chest", -1) == 0 then -- chest not found
  697.             if craftItem == "minecraft:chest" then --make a chest
  698.                 sourceSlot1 = clsTurtle.getItemSlot(self, sourceItem1)
  699.                 turtle.select(1)
  700.                 if turtle.craft() then
  701.                     turtle.transferTo(2, 1)
  702.                     turtle.transferTo(3, 1)
  703.                     turtle.transferTo(5, 1)
  704.                     turtle.transferTo(7, 1)
  705.                     turtle.transferTo(9, 1)
  706.                     turtle.transferTo(10, 1)
  707.                     turtle.transferTo(11, 1)
  708.                     if turtle.craft() then
  709.                         clsTurtle:saveToLog("First Chest crafted")
  710.                     end
  711.                 end
  712.             end
  713.             doContinue = false
  714.         end
  715.         if doContinue then
  716.             if sourceItem1 == "minecraft:log" or sourceItem1 == "minecraft:log2" then
  717.                 stockData = clsTurtle.getLogData(self) --{.total, .mostSlot, .mostCount, .mostModifier, mostName, .leastSlot, .leastCount, .leastModifier, leastName}
  718.                 clsTurtle:saveToLog("craft(): stock.mSlot="..stockData.mostSlot..", stock.mCount="..stockData.mostCount..", stock.lSlot="..stockData.leastSlot..", stock.lCount="..stockData.leastCount)
  719.                 if refuel then
  720.                     sourceSlot1 = stockData.leastSlot
  721.                     clsTurtle:saveToLog("craft(): slot no: "..stockData.leastSlot..", log count:"..stockData.leastCount)
  722.                 else
  723.                     if craftItem == "minecraft:planks" then
  724.                         if stockData.leastCount >= craftQuantity / 4 then -- check if enough in lowest slot
  725.                             sourceSlot1 = stockData.leastSlot
  726.                             clsTurtle.saveToLog(self, "craft(): slot no: "..stockData.leastSlot..", log count:"..stockData.leastCount)
  727.                         else
  728.                             sourceSlot1 = stockData.mostSlot
  729.                             clsTurtle.saveToLog(self, "craft(): slot no: "..stockData.mostSlot..", log count:"..stockData.mostCount)
  730.                         end
  731.                     end
  732.                 end
  733.             else
  734.                 sourceSlot1 = clsTurtle.getItemSlot(self, sourceItem1)
  735.             end
  736.             if sourceSlot1 == 0 then
  737.                 doContinue = false
  738.             end
  739.             if sourceItem2 == nil then -- no second recipe item needed
  740.                 sourceItem2 = ""
  741.                 sourceSlot2 = 0
  742.             else
  743.                 sourceSlot2 = clsTurtle.getItemSlot(self, sourceItem2) -- find slot number of second recipe item
  744.                 if sourceSlot2 == 0 then
  745.                     doContinue = false
  746.                 end
  747.             end
  748.             if sourceItem3 == nil then -- no third recipe item needed
  749.                 sourceItem3 = ""
  750.                 sourceSlot3 = 0
  751.             else
  752.                 sourceSlot3 = clsTurtle.getItemSlot(self, sourceItem3) -- find slot number of third recipe item
  753.                 if sourceSlot3 == 0 then
  754.                     doContinue = false
  755.                 end
  756.             end
  757.         end
  758.         if doContinue then
  759.             chestDirection = clsTurtle.getPlaceChestDirection(self)
  760.             blockType = clsTurtle.getBlockType(self, chestDirection)
  761.             while blockType ~= "minecraft:chest" do --check if chest placed eg mob in the way
  762.                 clsTurtle.dig(self, chestDirection)
  763.                 if not clsTurtle.place(self, "minecraft:chest", -1, chestDirection) then
  764.                     sleep(1) -- wait for mob to move
  765.                     chestDirection = clsTurtle.getPlaceChestDirection(self)
  766.                 end
  767.                 blockType = clsTurtle.getBlockType(self, chestDirection)
  768.             end
  769.             -- fill chest with everything except required items
  770.             for i = 1, 16 do
  771.                 if i ~= sourceSlot1 and i ~= sourceSlot2 and i ~= sourceSlot3 then
  772.                     clsTurtle.drop(self, i, chestDirection)
  773.                 end
  774.             end
  775.  
  776.             --turtle emptied out except for crafting items, so move them to slots 16,15,14,13. Start by moving them all to empty slots
  777.             emptySlot = clsTurtle.getFirstEmptySlot(self)
  778.             turtle.select(sourceSlot1)
  779.             turtle.transferTo(emptySlot) --move selected first item to empty slot
  780.             sourceSlot1 = emptySlot
  781.             if sourceSlot2 > 0 then
  782.                 emptySlot = clsTurtle.getFirstEmptySlot(self)
  783.                 turtle.select(sourceSlot2)
  784.                 turtle.transferTo(emptySlot) --move selected first item to empty slot
  785.                 sourceSlot2 = emptySlot
  786.             end
  787.             if sourceSlot3 > 0 then
  788.                 emptySlot = clsTurtle.getFirstEmptySlot(self)
  789.                 turtle.select(sourceSlot3)
  790.                 turtle.transferTo(emptySlot) --move selected first item to empty slot
  791.                 sourceSlot3 = emptySlot
  792.             end
  793.             if sourceSlot4 > 0 then
  794.                 emptySlot = clsTurtle.getFirstEmptySlot(self)
  795.                 turtle.select(sourceSlot4)
  796.                 turtle.transferTo(emptySlot) --move selected first item to empty slot
  797.                 sourceSlot4 = emptySlot
  798.             end
  799.             --now move to 16, (15,14,13)
  800.             turtle.select(sourceSlot1)
  801.             turtle.transferTo(16) --move selected first item to empty slot
  802.             sourceSlot1 = 16
  803.             if sourceSlot2 > 0 then
  804.                 turtle.select(sourceSlot2)
  805.                 turtle.transferTo(15) --move selected first item to empty slot
  806.                 sourceSlot1 = 15
  807.             end
  808.             if sourceSlot3 > 0 then
  809.                 turtle.select(sourceSlot3)
  810.                 turtle.transferTo(14) --move selected first item to empty slot
  811.                 sourceSlot1 = 14
  812.             end
  813.             if sourceSlot4 > 0 then
  814.                 turtle.select(sourceSlot4)
  815.                 turtle.transferTo(13) --move selected first item to empty slot
  816.                 sourceSlot1 = 13
  817.             end
  818.             --ready to craft
  819.             turtle.select(16)
  820.             if craftItem == ccComputer then --T:craft{craftItem = ccComputer, craftQuantity = 1, sourceItem1 = "minecraft:glass_panes", sourceItem2 = "minecraft:redstone",sourceItem3 = "minecraft:stone"}
  821.                 -- 1 glass_panes, 1 redstone, 7 stone
  822.                 turtle.select(16)
  823.                 turtle.transferTo(10, craftQuantity) --move glass panes to 10
  824.                 turtle.select(15)
  825.                 turtle.transferTo(6, craftQuantity) --move redstone to 6
  826.                 turtle.select(14) --stone
  827.                 turtle.transferTo(1, craftQuantity) --move stone to 6
  828.                 turtle.transferTo(2, craftQuantity)
  829.                 turtle.transferTo(3, craftQuantity)
  830.                 turtle.transferTo(5, craftQuantity)
  831.                 turtle.transferTo(7, craftQuantity)
  832.                 turtle.transferTo(9, craftQuantity)
  833.                 turtle.transferTo(11, craftQuantity)
  834.             elseif craftItem == ccDisk then  --T:craft{craftItem = ccDisk, craftQuantity = 1, sourceItem1 = "minecraft:paper", sourceItem2 = "minecraft:redstone"}
  835.                 -- 1 paper, 1 redstone
  836.                 turtle.select(16)
  837.                 turtle.transferTo(5, craftQuantity) --move paper to 5
  838.                 turtle.select(15)
  839.                 turtle.transferTo(1, craftQuantity) --move redstone to 1       
  840.             elseif craftItem == ccDiskDrive then --T:craft{craftItem = ccDiskDrive, craftQuantity = 1, sourceItem1 = "minecraft:redstone", sourceItem2 = "minecraft:stone"}
  841.                 -- 2 redstone, 7 stone
  842.                 turtle.select(16)
  843.                 turtle.transferTo(6, craftQuantity) --move to 6
  844.                 turtle.transferTo(10, craftQuantity) --move to 10
  845.                 turtle.select(15)
  846.                 turtle.transferTo(1, craftQuantity) --move stone to 6
  847.                 turtle.transferTo(2, craftQuantity)
  848.                 turtle.transferTo(3, craftQuantity)
  849.                 turtle.transferTo(5, craftQuantity)
  850.                 turtle.transferTo(7, craftQuantity)
  851.                 turtle.transferTo(9, craftQuantity)
  852.                 turtle.transferTo(11, craftQuantity)
  853.             elseif craftItem == ccTurtle then --T:craft{craftItem = ccTurtle, craftQuantity = 1, sourceItem1 = "minecraft:chest", sourceItem2 = ccComputer,sourceItem3 = "minecraft:iron_ingot"}
  854.                 -- 1 chest, 1 computer, 7 iron
  855.                 if sourceSlot2 ~= 15 then
  856.                     turtle.select(sourceSlot2) --computer
  857.                     turtle.transferTo(15, craftQuantity)
  858.                 end
  859.                 if sourceSlot3 ~= 14 then
  860.                     turtle.select(sourceSlot3) --iron
  861.                     turtle.transferTo(14)
  862.                 end
  863.                 turtle.select(16)
  864.                 turtle.transferTo(10, craftQuantity)
  865.                 turtle.select(15) --computer
  866.                 turtle.transferTo(6, craftQuantity)
  867.                 turtle.select(14) --iron
  868.                 turtle.transferTo(1, craftQuantity) --move iron
  869.                 turtle.transferTo(2, craftQuantity)
  870.                 turtle.transferTo(3, craftQuantity)
  871.                 turtle.transferTo(5, craftQuantity)
  872.                 turtle.transferTo(7, craftQuantity)
  873.                 turtle.transferTo(9, craftQuantity)
  874.                 turtle.transferTo(11, craftQuantity)
  875.             elseif craftItem == ccCraftyMiningTurtle then --T:craft{craftItem = ccCraftyMiningTurtle, craftQuantity = 1, sourceItem1 = "minecraft:crafting_table", sourceItem2 = "minecraft:diamond_pickaxe",sourceItem3 = ccTurtle}
  876.                 -- 1 crafting table, 1 diamond pickaxe,  1 turtle
  877.                 turtle.select(16)
  878.                 turtle.transferTo(1, craftQuantity) --move crafting table to 1
  879.                 turtle.select(15)
  880.                 turtle.transferTo(3, craftQuantity) --move pickaxe to 3
  881.                 turtle.select(14)
  882.                 turtle.transferTo(2, craftQuantity) --move turtle to 2
  883.             elseif craftItem == "minecraft:bucket" then --T:craft{craftItem = "minecraft:bucket", craftQuantity = 1, sourceItem1 = "minecraft:iron_ingot"}
  884.                 turtle.transferTo(1, craftQuantity)
  885.                 turtle.transferTo(3, craftQuantity)
  886.                 turtle.transferTo(6, craftQuantity)
  887.             elseif craftItem == "minecraft:chest" then  --T:craft{craftItem = "minecraft:chest", craftQuantity = 1, sourceItem1 = "minecraft:planks"}
  888.                 --8 planks = 1 chest
  889.                 turtle.transferTo(1, craftQuantity)
  890.                 turtle.transferTo(2, craftQuantity)
  891.                 turtle.transferTo(3, craftQuantity)
  892.                 turtle.transferTo(5, craftQuantity)
  893.                 turtle.transferTo(7, craftQuantity)
  894.                 turtle.transferTo(9, craftQuantity)
  895.                 turtle.transferTo(10, craftQuantity)
  896.                 turtle.transferTo(11, craftQuantity)
  897.             elseif craftItem == "minecraft:crafting_table" then --T:craft{craftItem = "minecraft:crafting_table", craftQuantity = 1, sourceItem1 = "minecraft:planks"}
  898.                 -- 4 planks = 1 table
  899.                 turtle.transferTo(1, craftQuantity)
  900.                 turtle.transferTo(2, craftQuantity)
  901.                 turtle.transferTo(5, craftQuantity)
  902.                 turtle.transferTo(6, craftQuantity)
  903.             elseif craftItem == "minecraft:diamond_pickaxe" then --T:craft{craftItem = "minecraft:diamond_pickaxe", craftQuantity = 1, sourceItem1 = "minecraft:stick", sourceItem2 = "minecraft:diamond"}
  904.                 --2 sticks + 3 diamonds = 1 axe
  905.                 turtle.select(16)
  906.                 turtle.transferTo(6, craftQuantity) --move stick to 6
  907.                 turtle.transferTo(10, craftQuantity) --move stick to 10
  908.                 turtle.select(15)
  909.                 turtle.transferTo(1, craftQuantity) --move diamond to 1
  910.                 turtle.transferTo(2, craftQuantity) --move diamond to 2
  911.                 turtle.transferTo(3, craftQuantity) --move diamond to 3
  912.             elseif craftItem == "minecraft:fence" then --T:craft{craftItem = "minecraft:fence", craftQuantity = 2, sourceItem1 = "minecraft:stick"}
  913.                 -- 6 stick = 2 fences
  914.                 turtle.transferTo(5, craftQuantity / 2)
  915.                 turtle.transferTo(6, craftQuantity / 2)
  916.                 turtle.transferTo(7, craftQuantity / 2)
  917.                 turtle.transferTo(9, craftQuantity / 2)
  918.                 turtle.transferTo(10, craftQuantity / 2)
  919.                 turtle.transferTo(11, craftQuantity / 2)   
  920.             elseif craftItem == "minecraft:furnace" then --T:craft{craftItem = "minecraft:furnace", craftQuantity = 1, sourceItem1 = "minecraft:cobblestone"}
  921.                 -- 8 cobblestone = 1 furnace
  922.                 turtle.transferTo(1, craftQuantity)
  923.                 turtle.transferTo(2, craftQuantity)
  924.                 turtle.transferTo(3, craftQuantity)
  925.                 turtle.transferTo(5, craftQuantity)
  926.                 turtle.transferTo(7, craftQuantity)
  927.                 turtle.transferTo(9, craftQuantity)
  928.                 turtle.transferTo(10, craftQuantity)
  929.                 turtle.transferTo(11, craftQuantity)
  930.             elseif craftItem == "minecraft:glass_pane" then --T:craft{craftItem = "minecraft:glass_pane", craftQuantity = 16, sourceItem1 = "minecraft:glass"}
  931.                 -- 6 glass = 16 panes
  932.                 turtle.transferTo(5, craftQuantity / 16)
  933.                 turtle.transferTo(6, craftQuantity / 16)
  934.                 turtle.transferTo(7, craftQuantity / 16)
  935.                 turtle.transferTo(9, craftQuantity / 16)
  936.                 turtle.transferTo(10, craftQuantity / 16)
  937.                 turtle.transferTo(11, craftQuantity / 16)
  938.             elseif craftItem == "minecraft:hopper" then  --T:craft{craftItem = "minecraft:hopper", craftQuantity = 1, sourceItem1 = "minecraft:iron_ingot", sourceItem2 = "minecraft:chest"}
  939.                 -- 5 iron, 1 chest
  940.                 turtle.select(16)
  941.                 turtle.transferTo(1, craftQuantity) --move iron to 1
  942.                 turtle.transferTo(3, craftQuantity)
  943.                 turtle.transferTo(5, craftQuantity)
  944.                 turtle.transferTo(7, craftQuantity)
  945.                 turtle.transferTo(10, craftQuantity)
  946.                 turtle.select(15)
  947.                 turtle.transferTo(6, craftQuantity) --move chest to 6      
  948.             elseif craftItem == "minecraft:ladder" then --T:craft{craftItem = "minecraft:ladder", craftQuantity = 3, sourceItem1 = "minecraft:stick"}
  949.                 -- 7 stick = 3 ladder
  950.                 turtle.transferTo(1, craftQuantity / 3)
  951.                 turtle.transferTo(3, craftQuantity / 3)
  952.                 turtle.transferTo(5, craftQuantity / 3)
  953.                 turtle.transferTo(6, craftQuantity / 3)
  954.                 turtle.transferTo(7, craftQuantity / 3)
  955.                 turtle.transferTo(9, craftQuantity / 3)
  956.                 turtle.transferTo(11, craftQuantity / 3)
  957.             elseif craftItem == "minecraft:paper" then --T:craft{craftItem = "minecraft:paper", craftQuantity = 3, sourceItem1 = "minecraft:reeds"}
  958.                 --3 reeds = 3 paper
  959.                 turtle.transferTo(1, craftQuantity / 3)
  960.                 turtle.transferTo(2, craftQuantity / 3)
  961.                 turtle.transferTo(3, craftQuantity / 3)
  962.             elseif craftItem == "minecraft:planks" then  --T:craft{craftItem = "minecraft:planks", craftQuantity = 4, sourceItem1 = "minecraft:log"}
  963.                 turtle.transferTo(1, craftQuantity / 4)
  964.             elseif craftItem == "minecraft:sign" then --T:craft{craftItem = "minecraft:sign", craftQuantity = 3, sourceItem1 = "minecraft:stick", sourceItem2 = "minecraft:planks"}
  965.                 -- 1 stick + 6 planks = 3 sign
  966.                 if sourceSlot2 ~= 15 then
  967.                     turtle.select(sourceSlot2) -- move planks to 15
  968.                     turtle.transferTo(15)
  969.                 end
  970.                 turtle.select(16)
  971.                 turtle.transferTo(10, craftQuantity / 3) --move sticks to 5
  972.                 turtle.select(15)
  973.                 turtle.transferTo(1, craftQuantity / 3) --move planks to 1
  974.                 turtle.transferTo(2, craftQuantity / 3) --move planks to 2
  975.                 turtle.transferTo(3, craftQuantity / 3) --move planks to 3
  976.                 turtle.transferTo(5, craftQuantity / 3) --move planks to 5
  977.                 turtle.transferTo(6, craftQuantity / 3) --move planks to 6
  978.                 turtle.transferTo(7, craftQuantity / 3) --move planks to 7
  979.             elseif craftItem == "minecraft:stair" then  --T:craft{craftItem = "minecraft:stair", craftQuantity = 4, sourceItem1 = "minecraft:cobblestone"}
  980.                 --6 cobblestone = 4 stair
  981.                 turtle.transferTo(1, craftQuantity / 4)
  982.                 turtle.transferTo(5, craftQuantity / 4)
  983.                 turtle.transferTo(6, craftQuantity / 4)
  984.                 turtle.transferTo(9, craftQuantity / 4)
  985.                 turtle.transferTo(10, craftQuantity / 4)
  986.                 turtle.transferTo(11, craftQuantity / 4)
  987.             elseif craftItem == "minecraft:stick" then --T:craft{craftItem = "stick", craftQuantity = 4, sourceItem1 = "minecraft:planks"} 
  988.                 -- 2 planks gives 4 sticks
  989.                 turtle.transferTo(1, craftQuantity / 4)
  990.                 turtle.transferTo(5, craftQuantity / 4)
  991.             elseif craftItem == "minecraft:torch" then --T:craft{craftItem = "minecraft:torch", craftQuantity = 4, sourceItem1 = "minecraft:stick", sourceItem2 = "minecraft:coal"}
  992.                 -- 1 stick + 1 coal/charcoal = 4 torch
  993.                 if sourceSlot2 ~= 15 then
  994.                     turtle.select(sourceSlot2) -- move coal/charcoal to 15
  995.                     turtle.transferTo(15)
  996.                 end
  997.                 turtle.select(16)
  998.                 turtle.transferTo(5, craftQuantity / 4) --move sticks to 5
  999.                 turtle.select(15)
  1000.                 turtle.transferTo(1, craftQuantity / 4) --move coal/charcoal to
  1001.             end
  1002.             for i = 13, 16 do -- empty remaining recipe items into chest
  1003.                 clsTurtle.drop(self, i, chestDirection)
  1004.             end
  1005.             -- Attempt to craft item into slot 16
  1006.             turtle.select(16)
  1007.             if turtle.craft() then
  1008.                 success = true
  1009.                 --now put crafted item in chest first, so will mix with any existing similar items
  1010.                 if refuel then
  1011.                     turtle.select(16)
  1012.                     turtle.refuel()
  1013.                 else
  1014.                     clsTurtle.drop(self, 16, chestDirection)
  1015.                 end
  1016.             else --crafting not successful, so empty out all items into chest
  1017.                 for i = 1, 16 do
  1018.                     if turtle.getItemCount(i) > 0 then
  1019.                         clsTurtle.drop(self, i, chestDirection)
  1020.                     end
  1021.                 end
  1022.             end
  1023.             while clsTurtle.suck(self, chestDirection) do end
  1024.             clsTurtle.dig(self, chestDirection) -- collect chest
  1025.             while facing ~= self.facing do --return to original position
  1026.                 clsTurtle.turnLeft(self, 1)
  1027.             end
  1028.         else
  1029.             clsTurtle.saveToLog(self, "Missing crafting ingredients.", true)
  1030.             success = false
  1031.         end
  1032.         turtle.select(slot)
  1033.         return success
  1034.     end
  1035.    
  1036.     function clsTurtle.craftChests(self, quantity, orLess)
  1037.         local chestsCrafted = 0
  1038.         local stockData = {}
  1039.         stockData = clsTurtle.getLogData(self)--{.total, .mostSlot, .mostCount, .mostModifier, mostName, .leastSlot, .leastCount, .leastModifier, leastName}
  1040.         local logNum = stockData.total
  1041.        
  1042.         if logNum >= 2 then -- at least one chest can be made
  1043.             if stockData.mostCount >= quantity * 2 then
  1044.                 if quantity > 8 then
  1045.                     clsTurtle.craft(self, "minecraft:planks", 64, stockData.mostName, nil, nil, false)
  1046.                     clsTurtle.craft(self, "minecraft:chest", 8, "minecraft:planks", nil, nil, false)
  1047.                     quantity = quantity - 8
  1048.                 end
  1049.                 stockData = clsTurtle.getLogData(self)
  1050.                 clsTurtle.craft(self, "minecraft:planks", quantity * 8, stockData.mostName, nil, nil, false)
  1051.                 clsTurtle.craft(self, "minecraft:chest", quantity, "minecraft:planks", nil, nil, false)
  1052.                 chestsCrafted = quantity
  1053.             else -- less than required logs
  1054.                 if orLess then
  1055.                     logNum = (math.floor(stockData.mostCount / 2)) * 2
  1056.                     logNeeded = quantity * 2 - logNum
  1057.                     clsTurtle.craft(self, "minecraft:planks", logNum * 4, stockData.mostName, nil, nil, false)
  1058.                     clsTurtle.craft(self, "minecraft:chest", logNum / 2, "minecraft:planks", nil, nil, false)
  1059.                     stockData = clsTurtle.getLogData(self)
  1060.                     logNum = (math.floor(stockData.mostCount / 2)) * 2
  1061.                     if logNum >= logNeeded then
  1062.                         clsTurtle.craft(self, "minecraft:planks", logNeeded * 4, stockData.mostName, nil, nil, false)
  1063.                         clsTurtle.craft(self, "minecraft:chest", logNeeded / 2, "minecraft:planks", nil, nil, false)
  1064.                     else
  1065.                         clsTurtle.craft(self, "minecraft:planks", logNum * 4, stockData.mostName, nil, nil, false)
  1066.                         clsTurtle.craft(self, "minecraft:chest", logNum / 2, "minecraft:planks", nil, nil, false)
  1067.                     end
  1068.                     chestsCrafted = logNeeded / 2
  1069.                 end
  1070.             end
  1071.         end
  1072.        
  1073.         return chestsCrafted
  1074.     end
  1075.  
  1076.     function clsTurtle.dig(self, direction)
  1077.         direction = direction or "forward"
  1078.         local success = false
  1079.         turtle.select(1)
  1080.         if direction == "up" then
  1081.             while turtle.digUp() do
  1082.                 sleep(0.7)
  1083.                 success = true
  1084.             end
  1085.         elseif direction == "down" then
  1086.             if turtle.digDown() then
  1087.                 success = true
  1088.             end
  1089.         else -- forward by default
  1090.             while turtle.dig() do
  1091.                 sleep(0.7)
  1092.                 success = true
  1093.             end
  1094.         end
  1095.         return success
  1096.     end
  1097.    
  1098.     function clsTurtle.drop(self, slot, direction, amount)
  1099.         direction = direction or "forward"
  1100.         turtle.select(slot)
  1101.         local success = false
  1102.         if direction == "up" then
  1103.             if amount == nil then
  1104.                 if turtle.dropUp() then
  1105.                     success = true
  1106.                 end
  1107.             else
  1108.                 if turtle.dropUp(amount) then
  1109.                     success = true
  1110.                 end
  1111.             end
  1112.         elseif direction == "down" then
  1113.             if amount == nil then
  1114.                 if turtle.dropDown() then
  1115.                     success = true
  1116.                 end
  1117.             else
  1118.                 if turtle.dropDown(amount) then
  1119.                     success = true
  1120.                 end
  1121.             end
  1122.         else
  1123.             if amount == nil then
  1124.                 if turtle.drop() then
  1125.                     success = true
  1126.                 end
  1127.             else
  1128.                 if turtle.drop(amount) then
  1129.                     success = true
  1130.                 end
  1131.             end
  1132.         end
  1133.         return success
  1134.     end
  1135.    
  1136.     function clsTurtle.dropItem(self, item, keepAmount, direction)
  1137.         keepAmount = keepAmount or 0
  1138.         direction = direction or "down"
  1139.         local itemSlot = 0
  1140.         local stockData = {}
  1141.        
  1142.         if keepAmount <= 0 then -- drop everything
  1143.             itemSlot = clsTurtle.getItemSlot(self, item)
  1144.             while itemSlot > 0 do
  1145.                 clsTurtle.drop(self, itemSlot, direction)
  1146.                 itemSlot = clsTurtle.getItemSlot(self, item)
  1147.             end
  1148.         elseif keepAmount >= 64 then -- drop everything else
  1149.             stockData = clsTurtle.getStock(self, item)
  1150.             if item == "minecraft:log" then
  1151.                 if stockData.mostSlot ~= stockData.leastSlot then
  1152.                     clsTurtle.drop(self, stockData.leastSlot, direction)
  1153.                 end
  1154.             else
  1155.                 while stockData.total > keepAmount do
  1156.                     if stockData.mostSlot ~= stockData.leastSlot then
  1157.                         clsTurtle.drop(self, stockData.leastSlot, direction)
  1158.                     else --only one slot but more than required in it
  1159.                         clsTurtle.drop(self, stockData.mostSlot, direction)
  1160.                     end
  1161.                     stockData = clsTurtle.getStock(self, item)
  1162.                 end
  1163.             end
  1164.         else --store specific amount
  1165.             itemSlot = clsTurtle.getItemSlot(self, item)
  1166.             local dropCount = turtle.getItemCount(itemSlot) - keepAmount
  1167.             if itemSlot > 0 then
  1168.                 clsTurtle.drop(self, itemSlot, direction, dropCount)
  1169.             end
  1170.         end
  1171.     end
  1172.    
  1173.     function clsTurtle.dumpRefuse(self)
  1174.         --dump dirt, cobble, sand, gravel
  1175.         local itemlist = {}
  1176.         local blockType = ""
  1177.         local blockModifier
  1178.         local slotCount
  1179.         local cobbleCount = 0
  1180.         local dirtCount = 0
  1181.  
  1182.         itemlist[1] = "minecraft:gravel"
  1183.         itemlist[2] = "minecraft:stone" --includes andesite, diorite etc
  1184.         itemlist[3] = "minecraft:dirt"
  1185.         itemlist[4] = "minecraft:flint"
  1186.         for x = 1, 15 do
  1187.             for i = x + 1 , 16 do
  1188.                 if turtle.getItemCount(i) > 0 then
  1189.                     turtle.select(i)
  1190.                     if turtle.compareTo(x) then
  1191.                         turtle.transferTo(x)
  1192.                     end
  1193.                 end
  1194.             end
  1195.         end
  1196.         for i = 1, 16 do
  1197.             slotCount, blockType, blockModifier = clsTurtle.getSlotContains(self, i)
  1198.             if blockType == "minecraft:cobblestone" then
  1199.                 if cobbleCount > 0 then
  1200.                     turtle.select(i)
  1201.                     turtle.drop()
  1202.                 else
  1203.                     cobbleCount = cobbleCount + 1
  1204.                 end
  1205.             end
  1206.             for j = 1, 4 do
  1207.                 if blockType == itemlist[j] then
  1208.                     turtle.select(i)
  1209.                     turtle.drop()
  1210.                     break
  1211.                 end
  1212.             end
  1213.         end
  1214.         turtle.select(1)
  1215.     end
  1216.    
  1217.     function clsTurtle.emptyTrash(self, direction)
  1218.         direction = direction or "down"
  1219.         local slotData = {}
  1220.         local item = ""
  1221.         local move = false
  1222.         local keepItems = {"minecraft:cobblestone", "minecraft:redstone", "minecraft:sand",
  1223.                             "minecraft:chest", "minecraft:log", "minecraft:log2", "minecraft:iron_ore", "minecraft:reeds", "minecraft:sapling",
  1224.                             "minecraft:bucket", "minecraft:lava_bucket", "minecraft:water_bucket", "minecraft:torch", "minecraft:diamond",
  1225.                             "minecraft:coal", "minecraft:iron_ingot"}
  1226.                            
  1227.         local keepit = false                   
  1228.         -- empty excess cobble, dirt, all gravel, unknown minerals
  1229.         --keep max of 1 stack
  1230.         clsTurtle.sortInventory(self)
  1231.         if direction == "down" then
  1232.             if clsTurtle.down(self, 1) then
  1233.                 move = true
  1234.             end
  1235.         end
  1236.         for i = 1, 16 do
  1237.             keepit = false
  1238.             if turtle.getItemCount(i) > 0 then
  1239.                 item = clsTurtle.getItemName(self, i)
  1240.                 for _,v in pairs(keepItems) do
  1241.                     if v == item then
  1242.                         keepit = true
  1243.                         break
  1244.                     end
  1245.                 end
  1246.                 if not keepit then
  1247.                     clsTurtle.saveToLog(self, "EmptyTrash():Dropping "..item, true)
  1248.                     turtle.select(i)
  1249.                     turtle.dropDown()
  1250.                 end
  1251.             end
  1252.         end
  1253.         clsTurtle.sortInventory(self)
  1254.         clsTurtle.emptyTrashItem(self, "down", "minecraft:cobblestone", 128)
  1255.         clsTurtle.emptyTrashItem(self, "down", "minecraft:redstone", 64)
  1256.         slotData = clsTurtle.getStock(self, "minecraft:coal", 0)
  1257.         if slotData.total > 64 then
  1258.             if slotData.mostSlot ~= slotData.leastSlot and slotData.leastSlot ~= 0 then
  1259.                 turtle.select(slotData.leastSlot)
  1260.                 turtle.refuel()
  1261.                 clsTurtle.saveToLog(self, "EmptyTrash():xs coal used for fuel", true)
  1262.             end
  1263.         end
  1264.         if direction == "down" and move then
  1265.             clsTurtle.up(self, 1)
  1266.         end
  1267.         turtle.select(1)
  1268.     end
  1269.    
  1270.     function clsTurtle.emptyTrashItem(self, direction, item, maxAmount)
  1271.         local stockData = clsTurtle.getStock(self, item)
  1272.        
  1273.         while stockData.total > maxAmount and stockData.mostSlot > 0 do
  1274.             turtle.select(stockData.mostSlot)
  1275.             if direction == "up" then
  1276.                 if not turtle.dropUp() then
  1277.                     if not turtle.dropDown() then
  1278.                         clsTurtle.saveToLog(self, "EmptyTrashItem():error ", true)
  1279.                         break
  1280.                     end
  1281.                 end
  1282.             else
  1283.                 if not turtle.dropDown() then
  1284.                     if not turtle.dropUp() then
  1285.                         clsTurtle.saveToLog(self, "EmptyTrashItem():error ", true)
  1286.                         break
  1287.                     end
  1288.                 end
  1289.             end
  1290.             stockData = clsTurtle.getStock(self, item)
  1291.         end
  1292.     end
  1293.    
  1294.     function clsTurtle.equip(self, side, useItem, useDamage)
  1295.         useDamage = useDamage or 0
  1296.         local slot, damage = clsTurtle.getItemSlot(self, useItem)
  1297.         local currentSlot = turtle.getSelectedSlot()
  1298.         self.success = false
  1299.        
  1300.         if slot > 0 and damage == useDamage then
  1301.             turtle.select(slot)
  1302.             if side == "right" then
  1303.                 if turtle.equipRight() then
  1304.                     self.success = true
  1305.                     self.equippedRight = useItem
  1306.                 end
  1307.             else
  1308.                 if turtle.equipLeft() then
  1309.                     self.success = true
  1310.                     self.equippedLeft = useItem
  1311.                 end
  1312.             end
  1313.         end
  1314.         turtle.select(currentSlot)
  1315.        
  1316.         return self.success
  1317.     end
  1318.    
  1319.     function clsTurtle.getBlockType(self, direction)
  1320.         -- turtle.inspect() returns two values
  1321.         -- 1) boolean (true/false) success
  1322.         -- 2) table with two values:
  1323.         --  .name (string) e.g. "minecraft:log"
  1324.         --  .metadata (integer) e.g. 0
  1325.         --  oak has metadata of 0, spruce 1, birch 2 etc
  1326.         local data = {} --initialise empty table variable
  1327.      
  1328.         if direction == "up" then
  1329.             success, data = turtle.inspectUp() -- store information about the block above in a table   
  1330.         elseif direction == "down" then
  1331.             success, data = turtle.inspectDown() -- store information about the block below in a table
  1332.         else
  1333.             success, data = turtle.inspect() -- store information about the block ahead in a table
  1334.         end
  1335.        
  1336.         return data.name, data.metadata -- returns nil, nil if no block
  1337.     end
  1338.    
  1339.     function clsTurtle.getFirstEmptySlot(self)
  1340.         local emptySlot = 0
  1341.         for i = 1,16 do
  1342.             if turtle.getItemCount(i) == 0 then
  1343.                 emptySlot = i
  1344.                 break
  1345.             end
  1346.         end
  1347.         return emptySlot
  1348.     end
  1349.    
  1350.     function clsTurtle.getItemName(self, slot)
  1351.         local data = {} --initialise empty table variable
  1352.         data.name = ""
  1353.        
  1354.         if turtle.getItemCount(slot) > 0 then
  1355.             data = turtle.getItemDetail(slot)
  1356.         end
  1357.        
  1358.         return data.name
  1359.     end
  1360.    
  1361.     function clsTurtle.getItemSlot(self, item, useDamage)
  1362.         -- return slot no with least count, damage(modifier) and total count available
  1363.         -- along with a table of mostSlot, mostCount, leastSlot, leastCount
  1364.         useDamage = useDamage or -1 -- -1 damage means is not relevant
  1365.         local data = {} --initialise empty table variable
  1366.         local slotData = {}
  1367.         local total = 0
  1368.         -- setup return table
  1369.         slotData.mostSlot = 0
  1370.         slotData.mostName = ""
  1371.         slotData.mostCount = 0
  1372.         slotData.mostModifier = 0
  1373.         slotData.leastSlot = 0
  1374.         slotData.leastName = ""
  1375.         slotData.leastCount = 0
  1376.         slotData.leastModifier = 0
  1377.         for i = 1, 16 do
  1378.             local count = turtle.getItemCount(i)
  1379.             if count > 0 then
  1380.                 data = turtle.getItemDetail(i)
  1381.                 if data.name == item and (data.damage == useDamage or useDamage == -1) then
  1382.                     total = total + count
  1383.                     if count > slotData.mostCount then--
  1384.                         slotData.mostSlot = i
  1385.                         slotData.mostName = data.name
  1386.                         slotData.mostCount = count
  1387.                         slotData.mostModifier = data.damage
  1388.                     end
  1389.                     if count < slotData.leastCount then--
  1390.                         slotData.leastSlot = i
  1391.                         slotData.leastName = data.name
  1392.                         slotData.leastCount = count
  1393.                         slotData.leastModifier = data.damage
  1394.                     end
  1395.                 end
  1396.             end
  1397.         end
  1398.         if slotData.mostSlot > 0 then
  1399.             if slotData.leastSlot == 0 then
  1400.                 slotData.leastSlot = slotData.mostSlot
  1401.                 slotData.leastName = slotData.mostName
  1402.                 slotData.leastCount = slotData.mostCount
  1403.                 slotData.leastModifier = slotData.mostModifier
  1404.             end
  1405.         end
  1406.        
  1407.         return slotData.leastSlot, slotData.leastModifier, total, slotData -- first slot no, integer, integer, table
  1408.     end
  1409.    
  1410.     function clsTurtle.getLogData(self)
  1411.         -- get the slot number and count of each type of log max and min only
  1412.         local leastSlot, leastDamage, total, total2
  1413.         local logData = {}
  1414.         local logData2 = {}
  1415.         local retData = {}
  1416.        
  1417.         leastSlot, leastDamage, total, logData = clsTurtle.getItemSlot(self, "minecraft:log", -1)
  1418.         leastSlot, leastDamage, total2, logData2 = clsTurtle.getItemSlot(self, "minecraft:log2", -1)
  1419.         retData.total = total + total2
  1420.         if logData.mostCount > logData2.mostCount then
  1421.             retData.mostSlot            = logData.mostSlot
  1422.             retData.mostCount           = logData.mostCount
  1423.             retData.mostModifier        = logData.mostModifier
  1424.             retData.mostName            = logData.mostName
  1425.             if logData2.leastCount > 0 then
  1426.                 retData.leastSlot       = logData2.leastSlot
  1427.                 retData.leastCount      = logData2.leastCount
  1428.                 retData.leastModifier   = logData2.leastModifier
  1429.                 retData.leastName       = logData2.leastName
  1430.             else
  1431.                 retData.leastSlot       = logData.leastSlot
  1432.                 retData.leastCount      = logData.leastCount
  1433.                 retData.leastModifier   = logData.leastModifier
  1434.                 retData.leastName       = logData.leastName
  1435.             end
  1436.         else
  1437.             retData.mostSlot            = logData2.mostSlot
  1438.             retData.mostCount           = logData2.mostCount
  1439.             retData.mostModifier        = logData2.mostModifier
  1440.             retData.mostName            = logData2.mostName
  1441.             if logData.mostCount > 0 then
  1442.                 retData.leastSlot       = logData.leastSlot
  1443.                 retData.leastCount      = logData.leastCount
  1444.                 retData.leastModifier   = logData.leastModifier
  1445.                 retData.leastName       = logData.leastName
  1446.             else
  1447.                 retData.leastSlot       = logData2.leastSlot
  1448.                 retData.leastCount      = logData2.leastCount
  1449.                 retData.leastModifier   = logData2.leastModifier
  1450.                 retData.leastName       = logData2.leastName
  1451.             end
  1452.         end
  1453.  
  1454.         return retData --{.total, .mostSlot, .mostCount, .mostModifier, mostName, .leastSlot, .leastCount, .leastModifier, leastName}
  1455.     end
  1456.    
  1457.     function clsTurtle.getLogStock(self)
  1458.         local logAmount = 0
  1459.         local stockData = clsTurtle.getStock(self, "minecraft:log")  --oak, spruce, birch, jungle
  1460.         logAmount = logAmount + stockData.total
  1461.         stockData = clsTurtle.getStock(self, "minecraft:log2")  --acacia, dark oak
  1462.         logAmount = logAmount + stockData.total
  1463.  
  1464.         return logAmount
  1465.     end
  1466.    
  1467.     function clsTurtle.getPlaceChestDirection(self)
  1468.         local facing = self.facing
  1469.         local chestDirection = "forward"
  1470.         while turtle.detect() do --check for clear space to place chest
  1471.             clsTurtle.turnRight(self, 1)
  1472.             if facing == self.facing then -- full circle
  1473.                 --check up and down
  1474.                 if turtle.detectDown() then -- no space below
  1475.                     if turtle.detectUp() then
  1476.                         if clsTurtle.dig(self, "up") then
  1477.                             chestDirection = "up"
  1478.                         end
  1479.                     else
  1480.                         chestDirection = "up"
  1481.                     end
  1482.                 else
  1483.                     chestDirection = "down"
  1484.                 end
  1485.                 break
  1486.             end
  1487.         end
  1488.         return chestDirection
  1489.     end
  1490.    
  1491.     function clsTurtle.getSlotContains(self, slotNo)
  1492.         local data = {} --initialise empty table variable
  1493.        
  1494.         if turtle.getItemCount(slotNo) > 0 then
  1495.             data = turtle.getItemDetail(slotNo)
  1496.         else
  1497.             data.count = 0
  1498.             data.name = ""
  1499.             data.damage = 0
  1500.         end
  1501.        
  1502.         return data.count, data.name, data.damage
  1503.     end
  1504.  
  1505.     function clsTurtle.getStock(self, item, modifier)
  1506.         -- return total units and slot numbers of max and min amounts
  1507.         local slot, damage, total, slotData = clsTurtle.getItemSlot(self, item, modifier) --return .leastSlot, .leastModifier, total, slotData
  1508.         local rt = {}
  1509.         rt.total = total
  1510.         rt.mostSlot = slotData.mostSlot
  1511.         rt.leastSlot = slotData.leastSlot
  1512.         rt.mostCount = slotData.mostCount
  1513.         rt.leastCount = slotData.leastCount
  1514.         if slot == 0 then
  1515.             if modifier == nil then
  1516.                 clsTurtle.saveToLog(self, "getStock()"..tostring(item).."= not found", true)
  1517.             else
  1518.                 clsTurtle.saveToLog(self, "getStock()"..tostring(item).."("..tostring(modifier)..")= not found")
  1519.             end
  1520.         end
  1521.        
  1522.         return rt --{rt.total, rt.mostSlot, rt.leastSlot, rt.mostCount, rt.leastCount}
  1523.     end
  1524.    
  1525.     function clsTurtle.go(self, path, useTorch, torchInterval)
  1526.         useTorch = useTorch or false -- used in m an M to place torches in mines
  1527.         torchInterval = torchInterval or 8
  1528.         local intervalList = {1, torchInterval * 1 + 1,
  1529.                                  torchInterval * 2 + 1,
  1530.                                  torchInterval * 3 + 1,
  1531.                                  torchInterval * 4 + 1,
  1532.                                  torchInterval * 5 + 1,
  1533.                                  torchInterval * 6 + 1}
  1534.         local slot = turtle.getSelectedSlot()
  1535.         turtle.select(1)       
  1536.         local commandList = {}
  1537.         local command = ""
  1538.         -- make a list of commands from path string eg "x0F12U1" = x0, F12, U1
  1539.         for i = 1, string.len(path) do
  1540.             local character = string.sub(path, i, i) -- examine each character in the string
  1541.             if tonumber(character) == nil then -- char is NOT a number
  1542.                 if command ~= "" then -- command is NOT empty eg "x0"
  1543.                     table.insert(commandList, command) -- add to table eg "x0"
  1544.                 end
  1545.                 command = character -- replace command with new character eg "F"
  1546.             else -- char IS a number
  1547.                 command = command..character -- add eg 1 to F = F1, 2 to F1 = F12
  1548.                 if i == string.len(path) then -- last character in the string
  1549.                     table.insert(commandList, command)
  1550.                 end
  1551.             end
  1552.         end
  1553.         -- R# L# F# B# U# D# +0 -0 = Right, Left, Forward, Back, Up, Down, up while detect and return, down while not detect
  1554.         -- dig:           x0,x1,x2 (up/fwd/down)
  1555.         -- suck:          s0,s1,s2
  1556.         -- place chest:   H0,H1,H2
  1557.         -- place sapling: S0,S1,S2
  1558.         -- place Torch:   T0,T1,T2
  1559.         -- place Hopper:  P0,P1,P2
  1560.         -- mine floor:    m# = mine # blocks above and below, checking for valuable items below, and filling space with cobble or dirt
  1561.         -- mine ceiling:  M# = mine # blocks, checking for valuable items above, and filling space with cobble or dirt
  1562.         -- mine ceiling:  N# same as M but not mining block below unless valuable
  1563.         -- place:         C,H,r,S,T,P = Cobble / cHest / DIrT / Sapling / Torch / hoPper in direction 0/1/2 (up/fwd/down) eg C2 = place cobble down
  1564.        
  1565.         clsTurtle.refuel(self, 15)
  1566.         turtle.select(1)
  1567.         for cmd in clsTurtle.values(self, commandList) do -- eg F12 or x1
  1568.             local move = string.sub(cmd, 1, 1)
  1569.             local modifier = tonumber(string.sub(cmd, 2))
  1570.             if move == "R" then
  1571.                 clsTurtle.turnRight(self, modifier)
  1572.             elseif move == "L" then
  1573.                 clsTurtle.turnLeft(self, modifier)
  1574.             elseif move == "B" then
  1575.                 clsTurtle.back(self, modifier)
  1576.             elseif move == "F" then
  1577.                 clsTurtle.forward(self, modifier)
  1578.             elseif move == "U" then
  1579.                 clsTurtle.up(self, modifier)
  1580.             elseif move == "D" then
  1581.                 clsTurtle.down(self, modifier)
  1582.             elseif move == "+" then
  1583.                 local height = 0
  1584.                 while turtle.detectUp() do
  1585.                     clsTurtle.up(self, 1)
  1586.                     height = height + 1
  1587.                 end
  1588.                 clsTurtle.down(self, height)
  1589.             elseif move == "-" then
  1590.                 while not turtle.inspectDown() do
  1591.                     clsTurtle.down(self, 1)
  1592.                 end      
  1593.             elseif move == "x" then
  1594.                 if modifier == 0 then
  1595.                     clsTurtle.dig(self, "up")
  1596.                 elseif modifier == 1 then
  1597.                     clsTurtle.dig(self, "forward")
  1598.                 elseif modifier == 2 then
  1599.                     while turtle.detectDown() do
  1600.                         turtle.digDown()
  1601.                     end
  1602.                 end
  1603.             elseif move == "s" then
  1604.                 if modifier == 0 then
  1605.                     while turtle.suckUp() do end
  1606.                 elseif modifier == 1 then
  1607.                     while turtle.suck() do end
  1608.                 elseif modifier == 2 then
  1609.                     while turtle.suckDown() do end
  1610.                 end
  1611.             elseif move == "m" then --mine block below and/or fill void
  1612.                 for i = 1, modifier + 1 do --eg m8 run loop 9 x
  1613.                     turtle.select(1)
  1614.                     if clsTurtle.isValuable(self, "down") then
  1615.                         turtle.digDown() -- dig if valuable
  1616.                     elseif clsTurtle.getBlockType(self, "down") == "minecraft:gravel" then
  1617.                         turtle.digDown() -- dig if gravel
  1618.                     else --check for lava
  1619.                         if clsTurtle.getBlockType(self, "down") == "minecraft:lava" then
  1620.                             clsTurtle.place(self, "minecraft:bucket", 0, "down")
  1621.                         end
  1622.                     end
  1623.                     clsTurtle.dig(self, "up") -- create player coridoor
  1624.                     if not turtle.detectDown() then
  1625.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1626.                             clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1627.                         end
  1628.                     end
  1629.                     if i <= modifier then -- m8 = move forward 8x
  1630.                         if useTorch then
  1631.                             if  i == intervalList[1] or
  1632.                                 i == intervalList[2] or
  1633.                                 i == intervalList[3] or
  1634.                                 i == intervalList[4] or
  1635.                                 i == intervalList[5] then
  1636.                                 clsTurtle.up(self, 1)
  1637.                                 clsTurtle.place(self, "minecraft:torch", -1, "down")
  1638.                                 clsTurtle.forward(self, 1)
  1639.                                 clsTurtle.down(self, 1)
  1640.                             else
  1641.                                 clsTurtle.forward(self, 1)
  1642.                             end
  1643.                         else
  1644.                             clsTurtle.forward(self, 1)
  1645.                         end
  1646.                     end
  1647.                 end
  1648.             elseif move == "n" then --mine block below and/or fill void + check left side
  1649.                 for i = 1, modifier + 1 do --eg m8 run loop 9 x
  1650.                     turtle.select(1)
  1651.                     if clsTurtle.isValuable(self, "down") then
  1652.                         turtle.digDown() -- dig if valuable
  1653.                     elseif clsTurtle.getBlockType(self, "down") == "minecraft:gravel" then
  1654.                         turtle.digDown() -- dig if gravel
  1655.                     else --check for lava
  1656.                         if clsTurtle.getBlockType(self, "down") == "minecraft:lava" then
  1657.                             clsTurtle.place(self, "minecraft:bucket", 0, "down")
  1658.                         end
  1659.                     end
  1660.                     clsTurtle.dig(self, "up") -- create player coridoor
  1661.                     if not turtle.detectDown() then
  1662.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1663.                             clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1664.                         end
  1665.                     end
  1666.                     clsTurtle.turnLeft(self, 1)
  1667.                     if clsTurtle.isValuable(self, "forward") then
  1668.                         turtle.dig() -- dig if valuable
  1669.                     end
  1670.                     if not turtle.detect() then
  1671.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward") then
  1672.                             clsTurtle.place(self, "minecraft:dirt", -1, "forward")
  1673.                         end
  1674.                     end
  1675.                     clsTurtle.turnRight(self, 1)   
  1676.                     if i <= modifier then -- m8 = move forward 8x
  1677.                         if useTorch then
  1678.                             if  i == intervalList[1] or
  1679.                                 i == intervalList[2] or
  1680.                                 i == intervalList[3] or
  1681.                                 i == intervalList[4] or
  1682.                                 i == intervalList[5] then
  1683.                                 clsTurtle.up(self, 1)
  1684.                                 clsTurtle.place(self, "minecraft:torch", -1, "down")
  1685.                                 clsTurtle.forward(self, 1)
  1686.                                 clsTurtle.down(self, 1)
  1687.                             else
  1688.                                 clsTurtle.forward(self, 1)
  1689.                             end
  1690.                         else
  1691.                             clsTurtle.forward(self, 1)
  1692.                         end
  1693.                     end
  1694.                 end
  1695.             elseif move == "M" then --mine block above and/or fill void
  1696.                 for i = 1, modifier + 1 do
  1697.                     turtle.select(1)
  1698.                     if clsTurtle.isValuable(self, "up") then
  1699.                         clsTurtle.dig(self, "up")
  1700.                     else --check for lava
  1701.                         if clsTurtle.getBlockType(self, "up") == "minecraft:lava" then
  1702.                             clsTurtle.place(self, "minecraft:bucket", 0, "up")
  1703.                         end
  1704.                     end
  1705.                     if not turtle.detectUp() then
  1706.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "up") then
  1707.                             clsTurtle.place(self, "minecraft:dirt", -1, "up")
  1708.                         end
  1709.                     end
  1710.                     if i <= modifier then -- will not move forward if modifier = 0
  1711.                         if useTorch then
  1712.                             if  i == intervalList[1] or
  1713.                                 i == intervalList[2] or
  1714.                                 i == intervalList[3] or
  1715.                                 i == intervalList[4] or
  1716.                                 i == intervalList[5] then
  1717.                                 clsTurtle.place(self, "minecraft:torch", 0, "down")
  1718.                             end
  1719.                         end
  1720.                         clsTurtle.forward(self, 1)
  1721.                     end
  1722.                 end
  1723.             elseif move == "N" then --mine block above and/or fill void + mine block below if valuable
  1724.                 for i = 1, modifier + 1 do
  1725.                     turtle.select(1)
  1726.                     if clsTurtle.isValuable(self, "up") then
  1727.                         clsTurtle.dig(self, "up")
  1728.                     else --check for lava
  1729.                         if clsTurtle.getBlockType(self, "up") == "minecraft:lava" then
  1730.                             clsTurtle.place(self, "minecraft:bucket", 0, "up")
  1731.                         end
  1732.                     end
  1733.                     if not turtle.detectUp() then
  1734.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "up") then
  1735.                             clsTurtle.place(self, "minecraft:dirt", -1, "up")
  1736.                         end
  1737.                     end
  1738.                     turtle.select(1)
  1739.                     if clsTurtle.isValuable(self, "down") then
  1740.                         turtle.digDown()
  1741.                     end
  1742.                     if i <= modifier then
  1743.                         clsTurtle.forward(self, 1)
  1744.                     end
  1745.                 end
  1746.             elseif move == "Q" then --mine block above and/or fill void + mine block below if valuable + left side
  1747.                 for i = 1, modifier + 1 do
  1748.                     turtle.select(1)
  1749.                     if clsTurtle.isValuable(self, "up") then
  1750.                         clsTurtle.dig(self, "up")
  1751.                     else --check for lava
  1752.                         if clsTurtle.getBlockType(self, "up") == "minecraft:lava" then
  1753.                             clsTurtle.place(self, "minecraft:bucket", 0, "up")
  1754.                         end
  1755.                     end
  1756.                     if not turtle.detectUp() then
  1757.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "up") then
  1758.                             clsTurtle.place(self, "minecraft:dirt", -1, "up")
  1759.                         end
  1760.                     end
  1761.                     clsTurtle.turnLeft(self, 1)
  1762.                     if clsTurtle.isValuable(self, "forward") then
  1763.                         turtle.dig() -- dig if valuable
  1764.                     end
  1765.                     if not turtle.detect() then
  1766.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward") then
  1767.                             clsTurtle.place(self, "minecraft:dirt", -1, "forward")
  1768.                         end
  1769.                     end
  1770.                     clsTurtle.turnRight(self, 1)   
  1771.                     if clsTurtle.isValuable(self, "down") then
  1772.                         turtle.digDown()
  1773.                     end
  1774.                     if i <= modifier then
  1775.                         clsTurtle.forward(self, 1)
  1776.                     end
  1777.                 end
  1778.             elseif move == "C" or move == "H" or move == "r" or move == "T" or move == "S" then --place item up/forward/down
  1779.                 local placeItem = "minecraft:cobblestone"
  1780.                 local direction = {"up", "forward", "down"}
  1781.                 if move == "H" then
  1782.                     placeItem = "minecraft:chest"
  1783.                 elseif move == "r" then
  1784.                     placeItem = "minecraft:dirt"
  1785.                 elseif move == "T" then
  1786.                     placeItem = "minecraft:torch"
  1787.                 elseif move == "S" then
  1788.                     placeItem = "minecraft:sapling"
  1789.                 end
  1790.                 if modifier == 0 then
  1791.                     clsTurtle.dig(self, "up")
  1792.                 elseif modifier == 1 then
  1793.                     clsTurtle.dig(self, "forward")
  1794.                 else
  1795.                     turtle.digDown()
  1796.                 end
  1797.                 if move == "C" then
  1798.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, direction[modifier + 1]) then
  1799.                         clsTurtle.place(self, "minecraft:dirt", -1, direction[modifier + 1])
  1800.                     end
  1801.                 else
  1802.                     clsTurtle.place(self, placeItem, -1, direction[modifier + 1])
  1803.                 end
  1804.             elseif move == "*" then
  1805.                 local goUp = 0
  1806.                 while not turtle.inspectDown() do
  1807.                     clsTurtle.down(self, 1)
  1808.                     goUp = goUp + 1
  1809.                 end
  1810.                 if goUp > 0 then
  1811.                     for i = 1, goUp do
  1812.                         clsTurtle.up(self, 1)
  1813.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1814.                             clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1815.                         end
  1816.                     end
  1817.                     goUp = 0
  1818.                 else
  1819.                     turtle.digDown()
  1820.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1821.                         clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1822.                     end
  1823.                 end
  1824.             elseif move == "c" then
  1825.                 if turtle.detectDown() then
  1826.                     --check if vegetation and remove
  1827.                     data = clsTurtle.getBlockType(self, "down")
  1828.                     if data.name ~= "minecraft:dirt" and data.name ~= "minecraft:stone" and data.name ~= "minecraft:cobblestone" and data.name ~= "minecraft:grass" then
  1829.                         turtle.digDown()
  1830.                     end
  1831.                 end
  1832.                 if not turtle.detectDown() then
  1833.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1834.                         clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1835.                     end
  1836.                 end
  1837.             elseif move == "Z" then -- mine to bedrock
  1838.                 for i = 1, modifier + 1 do 
  1839.                     turtle.select(1)
  1840.                     local goUp = 0
  1841.                     while clsTurtle.down(self, 1) do
  1842.                         goUp = goUp + 1
  1843.                     end
  1844.                     for j = goUp, 1, -1 do
  1845.                         for k = 1, 4 do
  1846.                             clsTurtle.turnRight(self, 1)
  1847.                             if clsTurtle.isValuable(self, "forward") then
  1848.                                 clsTurtle.place(self, "minecraft:cobblestone", -1, "forward")
  1849.                             end
  1850.                         end
  1851.                         clsTurtle.up(self, 1)
  1852.                         clsTurtle.place(self, "minecraft:cobblestone", -1, "down")
  1853.                         turtle.select(1)
  1854.                     end
  1855.                     if i <= modifier then
  1856.                         clsTurtle.forward(self, 2)
  1857.                     end
  1858.                 end
  1859.             end
  1860.         end
  1861.         turtle.select(slot)
  1862.     end
  1863.    
  1864.     function clsTurtle.harvestTree(self, extend)
  1865.         extend = extend or false
  1866.         local treeHeight = 0
  1867.         local addHeight = 0
  1868.         local onLeft = true
  1869.         local logType = clsTurtle.getBlockType(self, "forward")
  1870.         local slot = turtle.getSelectedSlot()
  1871.         clsTurtle.dig(self, "forward")
  1872.         clsTurtle.forward(self, 1) -- will force refuel if first tree
  1873.         clsTurtle.go(self, "L1") -- dig base of tree, go under tree
  1874.         -- check if on r or l of double width tree
  1875.         if clsTurtle.getBlockType(self, "forward", -1) == "minecraft:log" or clsTurtle.getBlockType(self, "forward", -1) == "minecraft:log2" then
  1876.             onLeft = false -- placed on right side of 2 block tree
  1877.         end
  1878.         clsTurtle.turnRight(self, 1)
  1879.         --craft chest if none onboard
  1880.         if clsTurtle.getItemSlot(self, "minecraft:chest", -1) == 0 then
  1881.             clsTurtle.go(self, "U2")
  1882.             clsTurtle.craft(self, "minecraft:planks", 8, logType, nil, nil, false)
  1883.             clsTurtle.craft(self, "minecraft:chest", 1, "minecraft:planks", nil, nil, false)
  1884.         else
  1885.             clsTurtle.go(self, "U2")
  1886.         end
  1887.         treeHeight = treeHeight + 2
  1888.         -- Loop to climb up tree and harvest trunk and surrounding leaves
  1889.         while clsTurtle.dig(self, "up") do -- continue loop while block detected above
  1890.             if clsTurtle.up(self, 1) then   -- Move up
  1891.                 treeHeight = treeHeight + 1
  1892.             end
  1893.             -- Inner loop to check for leaves
  1894.             for i = 1, 4 do
  1895.                 if turtle.detect() then -- check if leaves in front
  1896.                     turtle.dig() --Dig leaves
  1897.                 end
  1898.                 clsTurtle.turnRight(self, 1)
  1899.             end
  1900.         end
  1901.         -- At top of the tree. New loop to return to ground
  1902.         if extend then
  1903.             if onLeft then
  1904.                 clsTurtle.go(self, "F1R1F1R2")
  1905.             else
  1906.                 clsTurtle.go(self, "F1L1F1R2")
  1907.             end
  1908.             while turtle.detectUp() do
  1909.                 clsTurtle.up(self, 1)
  1910.                 addHeight = addHeight + 1
  1911.             end
  1912.             if addHeight > 0 then
  1913.                 clsTurtle.down(self, addHeight)
  1914.             end
  1915.         end
  1916.         for i = 1, treeHeight do
  1917.             clsTurtle.down(self, 1)
  1918.         end
  1919.         if extend then
  1920.             if onLeft then
  1921.                 clsTurtle.go(self, "F1L1F1R2")
  1922.             else
  1923.                 clsTurtle.go(self, "F1R1F1R2")
  1924.             end
  1925.         end
  1926.         turtle.select(slot)
  1927.     end
  1928.    
  1929.     function clsTurtle.initialise(self)
  1930.         clsTurtle.clear(self)
  1931.         if os.getComputerLabel() == nil then
  1932.             while name == "" do
  1933.                 clsTurtle.clear(self)
  1934.                 print("Type a name for this turtle")
  1935.                 local name = read()
  1936.             end
  1937.             os.setComputerLabel(name)
  1938.             clsTurtle.clear(self)
  1939.         end
  1940.         print("Checking equipment...\nDO NOT REMOVE ANY ITEMS!")
  1941.         self.equippedRight, self.equippedLeft = clsTurtle.setEquipment(self) -- set in equipped items
  1942.         local message = os.getComputerLabel().." is equipped with:\n"
  1943.         if self.equippedLeft ~= "" and self.equippedRight ~= "" then
  1944.             message = message.."Left: "..self.equippedLeft.." and Right: "..self.equippedRight
  1945.         elseif self.equippedLeft ~= "" then
  1946.             message = message.."Left: "..self.equippedLeft
  1947.         elseif self.equippedRight ~= "" then
  1948.             message = message.."Right: "..self.equippedRight
  1949.         end
  1950.         print(message)
  1951.         print("\n\nDo you want to create a logfile? (y/n)")
  1952.         local response = read()
  1953.         if response == "y" then
  1954.             self.useLog = true
  1955.             self.logFileName = "turtleLog.txt"
  1956.         end
  1957.     end
  1958.    
  1959.     function clsTurtle.isValuable(self, direction)
  1960.         local success = false
  1961.         local blockType = ""
  1962.         local blockModifier
  1963.  
  1964.         local itemList = "minecraft:dirt,minecraft:grass,minecraft:stone,minecraft:gravel,minecraft:chest,"..
  1965.                          "minecraft:cobblestone,minecraft:sand,minecraft:torch,minecraft:bedrock"
  1966.        
  1967.         if direction == "up" then
  1968.             if turtle.detectUp() then
  1969.                 blockType, blockModifier = clsTurtle.getBlockType(self, "up")
  1970.             end
  1971.         elseif direction == "down" then
  1972.             if turtle.detectDown() then
  1973.                 blockType, blockModifier = clsTurtle.getBlockType(self, "down")
  1974.             end
  1975.         elseif direction == "forward" then
  1976.             if turtle.detect() then
  1977.                 blockType, blockModifier = clsTurtle.getBlockType(self, "forward")
  1978.             end
  1979.         end
  1980.         if blockType ~= "" then --block found
  1981.             success = true
  1982.             if string.find(itemList, blockType) ~= nil then
  1983.                 success = false
  1984.             end
  1985.         end
  1986.         return success
  1987.     end
  1988.    
  1989.     function clsTurtle.isVegetation(self, blockName)
  1990.         blockName = blockName or ""
  1991.         local isVeg = false
  1992.         local vegList = {"minecraft:tallgrass", "minecraft:deadbush", "minecraft:cactus", "minecraft:leaves",
  1993.                          "minecraft:pumpkin", "minecraft:melon_block", "minecraft:vine", "minecraft:mycelium", "minecraft:waterliliy",
  1994.                          "minecraft:cocoa", "minecraft:double_plant", "minecraft:sponge", "minecraft:wheat"}
  1995.        
  1996.         -- check for flower, mushroom
  1997.         if string.find(blockName, "flower") ~= nil or string.find(blockName, "mushroom") ~= nil then
  1998.             isVeg = true
  1999.         end
  2000.         if not isVeg then
  2001.             for _,v in pairs(vegList) do
  2002.                 if v == blockName then
  2003.                     isVeg = true
  2004.                     break
  2005.                 end
  2006.             end
  2007.         end
  2008.        
  2009.         return isVeg
  2010.     end
  2011.    
  2012.     function clsTurtle.place(self, blockType, damageNo, direction)
  2013.         local success = false
  2014.         local slot = slot or clsTurtle.getItemSlot(self, blockType, damageNo)
  2015.  
  2016.         if slot > 0 then
  2017.             if direction == "down" then
  2018.                 clsTurtle.dig(self, "down")
  2019.                 turtle.select(slot)
  2020.                 if turtle.placeDown() then
  2021.                     if blockType == "minecraft:bucket" then
  2022.                         if turtle.refuel() then
  2023.                             clsTurtle.saveToLog("Refuelled with lava. Current fuel level: "..turtle.getFuelLevel())
  2024.                         end
  2025.                     end
  2026.                     success = true
  2027.                 else
  2028.                     if not clsTurtle.attack(self, "down") then
  2029.                         clsTurtle.saveToLog("Error placing "..blockType.." ? chest or minecart below")
  2030.                     end
  2031.                 end
  2032.             elseif direction == "up" then
  2033.                 clsTurtle.dig(self, "up")
  2034.                 turtle.select(slot)
  2035.                 if turtle.placeUp() then
  2036.                     if blockType == "minecraft:bucket" then
  2037.                         if turtle.refuel() then
  2038.                             clsTurtle.saveToLog("Refuelled with lava. Current fuel level: "..turtle.getFuelLevel())
  2039.                         end
  2040.                     end
  2041.                     success = true
  2042.                 else
  2043.                     clsTurtle.saveToLog("Error placing "..blockType.." ? chest or minecart above")
  2044.                 end
  2045.             else
  2046.                 clsTurtle.dig(self, "forward")
  2047.                 turtle.select(slot)
  2048.                 if turtle.place() then
  2049.                     if blockType == "minecraft:bucket" then
  2050.                         if turtle.refuel() then
  2051.                             clsTurtle.saveToLog("Refuelled with lava. Current fuel level: "..turtle.getFuelLevel())
  2052.                         end
  2053.                     end
  2054.                     success = true
  2055.                 else
  2056.                     clsTurtle.saveToLog("Error placing "..blockType.." ? chest or minecart ahead")
  2057.                 end
  2058.             end
  2059.         end
  2060.         turtle.select(1)
  2061.         return success
  2062.     end
  2063.    
  2064.     function clsTurtle.refuel(self, minLevel)  
  2065.         minLevel = minLevel or 15
  2066.         local itemSlot = 0
  2067.         local slot = turtle.getSelectedSlot()
  2068.         local count = 0
  2069.         local item = ""
  2070.         local damage = 0
  2071.         local success = false
  2072.         local data = {}
  2073.        
  2074.         if turtle.getFuelLevel() < minLevel then
  2075.             -- check each slot for fuel item
  2076.             itemSlot = clsTurtle.getItemSlot(self, "minecraft:lava_bucket", -1) --return slotData.leastSlot, slotData.leastSlotDamage, total, slotData
  2077.             if itemSlot > 0 then
  2078.                 turtle.select(itemSlot)
  2079.                 if turtle.refuel() then
  2080.                     clsTurtle.saveToLog(self, "refuel() lava used. level="..turtle.getFuelLevel(),true)
  2081.                     success = true
  2082.                 end
  2083.             end
  2084.             if not success then
  2085.                 itemSlot = clsTurtle.getItemSlot(self, "minecraft:coal", 1) --charcoal
  2086.                 if itemSlot > 0 then
  2087.                     turtle.select(itemSlot)
  2088.                     if turtle.refuel() then --use all charcoal
  2089.                         clsTurtle.saveToLog(self, "refuel() all charcoal used. level="..turtle.getFuelLevel(),true)
  2090.                         success = true
  2091.                     end
  2092.                 end
  2093.             end
  2094.             if not success then
  2095.                 itemSlot = clsTurtle.getItemSlot(self, "minecraft:coal", 0)
  2096.                 if itemSlot > 0 then
  2097.                     turtle.select(itemSlot)
  2098.                     if turtle.refuel(1) then
  2099.                         clsTurtle.saveToLog(self, "refuel() 1 coal used. level="..turtle.getFuelLevel(),true)
  2100.                         success = true
  2101.                     end
  2102.                 end
  2103.             end
  2104.             if not success then
  2105.                 itemSlot = clsTurtle.getItemSlot(self, "minecraft:planks", -1)
  2106.                 if itemSlot > 0 then
  2107.                     turtle.select(itemSlot)
  2108.                     if turtle.refuel() then
  2109.                         clsTurtle.saveToLog(self, "refuel() planks used. level="..turtle.getFuelLevel(),true)
  2110.                         success = true
  2111.                     end
  2112.                 end
  2113.             end
  2114.             if not success then
  2115.                 itemSlot = clsTurtle.getItemSlot(self, "minecraft:log", -1)
  2116.                 if itemSlot > 0 then --logs onboard
  2117.                     clsTurtle.saveToLog(self, "Refuelling with log slot "..tostring(itemSlot)..", crafting planks", true)
  2118.                     if turtle.getItemCount(itemSlot) == 1 then
  2119.                         turtle.select(itemSlot)
  2120.                         turtle.craft()
  2121.                         if turtle.refuel() then
  2122.                             clsTurtle.saveToLog(self, "refuel() planks used. level="..turtle.getFuelLevel(),true)
  2123.                             success = true
  2124.                         end
  2125.                     else
  2126.                         if clsTurtle.craft(self, "minecraft:planks", 4, "minecraft:log", nil, nil, true) then
  2127.                             success = true
  2128.                         else
  2129.                             clsTurtle.saveToLog(self, "refuel() error crafting planks", true)
  2130.                         end
  2131.                     end
  2132.                 end
  2133.             end        
  2134.             if not success then
  2135.                 itemSlot = clsTurtle.getItemSlot(self, "minecraft:log2", -1)
  2136.                 if itemSlot > 0 then --logs onboard
  2137.                     clsTurtle.saveToLog(self, "Refuelling with log2 slot "..tostring(itemSlot)..", crafting planks", true)
  2138.                     if turtle.getItemCount(itemSlot) == 1 then
  2139.                         turtle.select(itemSlot)
  2140.                         turtle.craft()
  2141.                         if turtle.refuel() then
  2142.                             clsTurtle.saveToLog(self, "refuel() planks used. level="..turtle.getFuelLevel(),true)
  2143.                             success = true
  2144.                         end
  2145.                     else
  2146.                         if clsTurtle.craft(self, "minecraft:planks", 4, "minecraft:log2", nil, nil, true) then
  2147.                             success = true
  2148.                         else
  2149.                             clsTurtle.saveToLog(self, "refuel() error crafting planks", true)  
  2150.                         end
  2151.                     end
  2152.                 end
  2153.             end        
  2154.             if not success then
  2155.                 term.clear()
  2156.                 term.setCursorPos(1,1)
  2157.                 print("Unable to refuel: "..turtle.getFuelLevel().." fuel remaining")
  2158.                 error()
  2159.             end
  2160.         end
  2161.         if not recursiveCall then -- only runs once
  2162.             if not success then
  2163.                 while turtle.getFuelLevel() < minLevel do
  2164.                     term.clear()
  2165.                     term.setCursorPos(1,1)
  2166.                     print("Unable to refuel: "..turtle.getFuelLevel().." fuel remaining")
  2167.                     print("Please add any fuel to any slot")
  2168.                     clsTurtle.refuel(self, minLevel, true) -- recursive function, flag set
  2169.                     sleep(1)
  2170.                 end
  2171.                 term.clear()
  2172.                 term.setCursorPos(1,1)
  2173.             end
  2174.         end
  2175.         turtle.select(slot)
  2176.         return success
  2177.     end
  2178.    
  2179.     function clsTurtle.setEquipment(self)
  2180.         -- if contains a crafting table, puts it on the right. Any other tool on the left
  2181.         local emptySlotR = clsTurtle:getFirstEmptySlot() -- first empty slot
  2182.         local emptySlotL = 0 -- used later
  2183.         local eqRight = ""
  2184.         local eqLeft = ""
  2185.         local count = 0
  2186.         local damage = 0
  2187.         if emptySlotR > 0 then -- empty slot found
  2188.             turtle.select(emptySlotR)
  2189.             if turtle.equipRight() then -- remove tool on the right
  2190.                 count, eqRight, damage = clsTurtle.getSlotContains(self, emptySlotR) -- eqRight contains name of tool from right side
  2191.                 emptySlotL = clsTurtle.getFirstEmptySlot(self) -- get next empty slot
  2192.             else
  2193.                 emptySlotL = emptySlotR
  2194.             end
  2195.             if emptySlotL > 0 then -- empty slot found
  2196.                 turtle.select(emptySlotL)
  2197.                 if turtle.equipLeft() then
  2198.                     count, eqLeft, damage = clsTurtle.getSlotContains(self, emptySlotL) -- eqLeft contains name of tool from left side
  2199.                 end
  2200.             end
  2201.             if eqRight == "minecraft:crafting_table" then
  2202.                 turtle.select(emptySlotR)
  2203.                 turtle.equipRight()
  2204.                 self.equippedRight = eqRight
  2205.                 eqRight = ""               
  2206.             elseif eqLeft == "minecraft:crafting_table" then
  2207.                 turtle.select(emptySlotL)
  2208.                 turtle.equipRight()
  2209.                 self.equippedRight = eqLeft
  2210.                 eqLeft = ""
  2211.             end
  2212.             if eqRight ~= "" then -- still contains a tool
  2213.                 turtle.select(emptySlotR)
  2214.                 turtle.equipLeft()
  2215.                 self.equippedLeft = eqRight
  2216.             end
  2217.             if eqLeft ~= "" then
  2218.                 turtle.select(emptySlotL)
  2219.                 turtle.equipLeft()
  2220.                 self.equippedLeft = eqLeft
  2221.             end
  2222.         end
  2223.         turtle.select(1)
  2224.         return self.equippedRight, self.equippedLeft
  2225.     end
  2226.    
  2227.     function clsTurtle.sortInventory(self)
  2228.         local turns = 0
  2229.         local chestSlot = clsTurtle.getItemSlot(self, "minecraft:chest", -1) --get the slot number containing a chest
  2230.         local blockType, blockModifier
  2231.         local facing = self.facing
  2232.         clsTurtle.saveToLog(self, "clsTurtle:sortInventory() started chest found in slot "..chestSlot, true)
  2233.         if chestSlot > 0 then -- chest found
  2234.             -- find empty block to place it.
  2235.             local chestDirection = clsTurtle.getPlaceChestDirection(self)
  2236.             blockType, blockModifier = clsTurtle.getBlockType(self, chestDirection)
  2237.             clsTurtle.saveToLog(self, "clsTurtle:sortInventory() looking "..chestDirection.." for chest...", true)
  2238.             while blockType ~= "minecraft:chest" do --check if chest placed eg mob in the way
  2239.                 if clsTurtle.place(self, "minecraft:chest", -1, chestDirection) then
  2240.                     clsTurtle.saveToLog(self, "clsTurtle:sortInventory() chest placed:"..chestDirection, true)
  2241.                     break
  2242.                 else
  2243.                     clsTurtle.saveToLog(self, "clsTurtle:sortInventory() chest NOT placed:"..chestDirection, true)
  2244.                     clsTurtle.dig(self, chestDirection) -- will force wait for mob
  2245.                     chestDirection = clsTurtle.getPlaceChestDirection(self)
  2246.                 end
  2247.                 blockType, blockModifier = clsTurtle.getBlockType(self, chestDirection)
  2248.             end
  2249.             -- fill chest with everything
  2250.             clsTurtle.saveToLog(self, "clsTurtle:sortInventory() emptying turtle:"..chestDirection, true)
  2251.             for i = 1, 16 do
  2252.                 clsTurtle.drop(self, i, chestDirection)
  2253.             end
  2254.             -- remove everything
  2255.             clsTurtle.saveToLog(self, "clsTurtle:sortInventory() refilling turtle:"..chestDirection, true)
  2256.             while clsTurtle.suck(self, chestDirection) do end
  2257.             clsTurtle.dig(self, chestDirection) -- collect chest
  2258.             clsTurtle.saveToLog(self, "clsTurtle:sortInventory() chest collected("..chestDirection..")", true)
  2259.             while facing ~= self.facing do --return to original position
  2260.                 clsTurtle.turnLeft(self, 1)
  2261.             end
  2262.         end
  2263.     end
  2264.  
  2265.     function clsTurtle.suck(self, direction)
  2266.         direction = direction or "forward"
  2267.         turtle.select(1)
  2268.         local success = false
  2269.         if direction == "up" then
  2270.             if turtle.suckUp() then
  2271.                 success = true
  2272.             end
  2273.         elseif direction == "down" then
  2274.             if turtle.suckDown() then
  2275.                 success = true
  2276.             end
  2277.         else
  2278.             if turtle.suck() then
  2279.                 success = true
  2280.             end
  2281.         end
  2282.         return success
  2283.     end
  2284.    
  2285.     clsTurtle.initialise(self)
  2286.    
  2287.     return self
  2288. end
  2289.  
  2290. -- local functions
  2291. function checkTreeFarm()
  2292.     -- will only be called if bucket already onboard
  2293.     -- do not bother if no saplings
  2294.     if not treeFarm:getPondFilled() then --pond not filled yet
  2295.         fillPond() -- use iron ore from creating mine for bucket, fill pond with water
  2296.     end
  2297.     if treeFarm:getPondFilled() then --pond filled
  2298.         if not treeFarm:getFarmCreated() then --treefarm not yet made
  2299.             clearTreeFarm() -- clear 11 x 10 area to right of base and plant 4 saplings
  2300.         end
  2301.         if treeFarm:getFarmCreated() then -- treefarm built
  2302.             if not treeFarm:getHopperPlaced() then --hopper not yet built
  2303.                 craftHopper()
  2304.             end
  2305.         end
  2306.         if treeFarm:getFarmCreated() and treeFarm:getHopperPlaced() then --treefarm built, hopper placed
  2307.             if not treeFarm:getFarmFlooded() then
  2308.                 floodTreeFarm()     -- Use bucket and pond to flood tree farm base ready for sapling collection
  2309.             end
  2310.         end
  2311.     end
  2312. end
  2313.  
  2314. function checkWaterCoordsOK(x,z)
  2315.     local result = false
  2316.     --  0 = go south (z increases)
  2317.     --  1 = go west  (x decreases)
  2318.     --  2 = go north (z decreases
  2319.     --  3 = go east  (x increases)
  2320.     -- check if water coords are within storage placement area 
  2321.     local relX = x - coordHome:getX() -- eg facing e -400 - -407 = +7
  2322.     local relZ = z - coordHome:getZ() -- eg facing e 270 - 278 = -8 (behind)
  2323.     if coordHome:getFacing() == 0 then
  2324.         --xCoord = xCoord + 1
  2325.         if relZ >= 3 or relZ <= -18 or relX >= 5 or relX <= -12 then --too far behind / in front to left/right
  2326.             result = true
  2327.         else
  2328.             if relZ < 3 or  relZ > -18 then
  2329.                 if relX >= 5 or relX <= -12 then
  2330.                     result = true
  2331.                 end
  2332.             elseif relX < 5 or relX > -12 then
  2333.                 if relZ >= 3 or relZ <= -18 then
  2334.                     result = true
  2335.                 end
  2336.             end
  2337.         end
  2338.     elseif coordHome:getFacing() == 1 then --facing west
  2339.         --xCoord = xCoord - 1
  2340.         if relX <= -3 or relX >= 18 or relZ <= -5 or relZ >= 12 then --too far behind / in front to left/right
  2341.             result = true
  2342.         else
  2343.             if relX > -3 or  relX < 18 then
  2344.                 if relZ <= -5 or relZ >= 12 then
  2345.                     result = true
  2346.                 end
  2347.             elseif relZ > -5 or relZ < 12 then
  2348.                 if relX <= -3 or relX >= 18 then
  2349.                     result = true
  2350.                 end
  2351.             end
  2352.         end
  2353.     elseif coordHome:getFacing() == 2 then
  2354.         --zCoord = zCoord - 1
  2355.         if relZ <= -3 or relZ >= 18 or relX <= -5 or relX >= 12 then --too far behind / in front to left/right
  2356.             result = true
  2357.         else
  2358.             if relZ > -3 or  relZ < 18 then
  2359.                 if relX <= -5 or relX >= 12 then
  2360.                     result = true
  2361.                 end
  2362.             elseif relX > -5 or relX < 12 then
  2363.                 if relZ <= -3 or relZ >= 18 then
  2364.                     result = true
  2365.                 end
  2366.             end
  2367.         end
  2368.     elseif coordHome:getFacing() == 3 then --facing east
  2369.         --xCoord = xCoord + 1
  2370.         if relX >= 3 or relX <= -18 or relZ >= 5 or relZ <= -12 then --too far behind / in front to left/right
  2371.             result = true
  2372.         else
  2373.             if relX < 3 or  relX > -18 then
  2374.                 if relZ >= 5 or relZ <= -12 then
  2375.                     result = true
  2376.                 end
  2377.             elseif relZ < 5 or relZ > -12 then
  2378.                 if relX >= 3 or relX <= -18 then
  2379.                     result = true
  2380.                 end
  2381.             end
  2382.         end
  2383.     end
  2384.    
  2385.     return result
  2386. end
  2387.  
  2388. function clearBase()
  2389.     local goUp = 0
  2390.     T:saveToLog("clearBase() Starting...", true)
  2391.     emptyAfterHarvest() --empty trash
  2392.     --craft furnace
  2393.     T:craft("minecraft:furnace", 1, "minecraft:cobblestone", nil, nil, false)
  2394.     --clear area around first tree 5 X 5 square
  2395.     T:go("F1x0C2L1")
  2396.     for i = 1, 3 do
  2397.         T:go("F1x2*0")
  2398.     end
  2399.     T:go("F1x0*2L1")
  2400.     for i = 1, 2 do
  2401.         T:go("F1x0*2")
  2402.     end
  2403.     T:go("F1x0*2L1")
  2404.     for i = 1, 5 do
  2405.         T:go("F1x0*2")
  2406.     end
  2407.     T:go("F1x0*2L1F1x0*2")
  2408.     T:go("F1x0*2D2x2C2U2")
  2409.     T:go("F1x0*2L1F1x0*2L1F1x0x2C2F1x0x2C2R1")
  2410.     T:go("F1x0C2F1x0C2")
  2411.     T:go("F1x0D1C2F1x0C2R1F1x0C2R1F1x0C2")
  2412.     T:go("F1x0C2U1C2F1L1")
  2413.     --put furnace above
  2414.     turtle.select(T:getItemSlot("minecraft:furnace"))
  2415.     turtle.placeUp()
  2416. end
  2417.  
  2418. function clearTreeFarm()
  2419.     local stockData = {}
  2420.     stockData = T:getStock("minecraft:log", -1)
  2421.     local numLogs = stockData.total
  2422.     stockData = T:getStock("minecraft:torch")
  2423.     local numTorches = stockData.total
  2424.     local torchesNeeded = 10 - numTorches
  2425.    
  2426.     T:saveToLog("clearTreeFarm() starting", true)
  2427.     --clear farm area
  2428.     treeFarm:reset()
  2429.     T:sortInventory()
  2430.     if torchesNeeded < 0 then
  2431.         torchesNeeded = 0
  2432.     else
  2433.         if numLogs > 4 then
  2434.             craftTorches(8) -- craft 6 torches for tree farm
  2435.         end
  2436.     end
  2437.     emptyTurtle(true)
  2438.     -- get saplings
  2439.     T:go("R1F2D1R2")
  2440.     while turtle.suckDown() do end
  2441.     stockData = T:getStock("minecraft:sapling", -1)
  2442.     if stockData.total > 0 then
  2443.         T:go("U1F2R1F4R2")
  2444.         --get cobble/dirt
  2445.         while turtle.suckDown() do end
  2446.         T:go("F4L1F2L1U1")-- on water enclosure wall
  2447.         -- build outer wall
  2448.         for i = 1, 9 do
  2449.             T:go("C2+0-0F1")
  2450.         end
  2451.         T:turnRight(1)
  2452.         for i = 1, 9 do
  2453.             T:go("C2+0-0F1")
  2454.         end
  2455.         T:turnRight(1)
  2456.         for i = 1, 10 do
  2457.             T:go("C2+0-0F1")
  2458.         end
  2459.         T:turnRight(1)
  2460.         for i = 1, 9 do
  2461.             T:go("C2+0-0F1")
  2462.         end
  2463.         T:turnRight(1)
  2464.         T:go("C2+0-0F1R1F1D1L1")
  2465.         --clear ground within outer wall
  2466.         for i = 1, 8 do -- left side
  2467.             T:go("c0+0-0F1")
  2468.         end -- col 2, row 2
  2469.         T:go("R1C2F1")
  2470.         for j = 1, 4 do
  2471.             for i = 1, 6 do
  2472.                 T:go("c0+0-0F1")
  2473.             end
  2474.             T:go("R1c0+0-0F1R1")
  2475.             for i = 1, 6 do
  2476.                 T:go("c0+0-0F1")
  2477.             end
  2478.             T:go("L1c0+0-0F1L1")
  2479.         end
  2480.         for i = 1, 6 do
  2481.             T:go("c0+0-0F1")
  2482.         end -- col 9, row 9 on right side of farm
  2483.         -- channel across end of farm
  2484.         T:go("c0+0-0L1D1") -- stay at bottom end
  2485.         T:go("R1x1C1R1C1R1C1C2F1C2L1C1R1F1C2L1C1R1F1C2L1C1R1F1C2L1C1R1F1C2L1C1R1F1C2L1C1R1F1C2L1C1R1F1x0C1R2F3U1L1F3")
  2486.         --place dirt and torches
  2487.         for i = 1, 4 do
  2488.             T:go("r0B1T0F4R1") --place dirt, Back, digUp, place Torch, forward 3,  turn right
  2489.         end
  2490.         T:go("B2U3F2") --dodge torch on first block
  2491.         T:go("S2F3S2R1F3S2R1F3S2F3D3R1F8R1")
  2492.         treeFarm:setFarmCreated(true)
  2493.         treeFarm:setTimePlanted(os.time())
  2494.         saveStatus("treeFarm")
  2495.         emptyTurtle(false)
  2496.     else -- no saplings abandon tree farm
  2497.         T:go("U1F2R1")
  2498.         T:saveToLog("No saplings: treeFarm abandoned")
  2499.     end
  2500.    
  2501. end
  2502.  
  2503. function craftBucket()
  2504.     local stockData = {}
  2505.     local success = false
  2506.    
  2507.     -- called only when under furnace
  2508.     stockData = T:getStock("minecraft:bucket", -1)
  2509.     if stockData.total == 0 then
  2510.         stockData = T:getStock("minecraft:iron_ore", -1)
  2511.         if stockData.total >= 3 then
  2512.             if smelt("minecraft:iron_ore", 3) then
  2513.                 if T:craft("minecraft:bucket", 1, "minecraft:iron_ingot", nil, nil, false) then
  2514.                     success = true
  2515.                 end
  2516.             end
  2517.         end
  2518.     else
  2519.         success = true
  2520.     end
  2521.    
  2522.     return success
  2523. end
  2524.  
  2525. function craftHopper()
  2526.     local doContinue = false
  2527.     local stockData = {}
  2528.    
  2529.     T:saveToLog("craftHopper() started")
  2530.     stockData = T:getStock("minecraft:iron_ore", -1)
  2531.     if stockData.total >= 5 then
  2532.         stockData = T:getStock("minecraft:chest")
  2533.         if stockData.total < 2 then
  2534.             if T:craftChests(1, false) >= 1 then
  2535.                 doContinue = true
  2536.             end
  2537.         end
  2538.         if doContinue then --chests x 1 available
  2539.             doContinue = false
  2540.             if smelt("minecraft:iron_ore", 5) then
  2541.                doContinue = true
  2542.             end
  2543.         end
  2544.         if doContinue then -- chests x 1, and iron x 5 available
  2545.             doContinue = false
  2546.             if T:craft("minecraft:hopper", 1, "minecraft:iron_ingot", "minecraft:chest", nil, false) then
  2547.                 doContinue = true  
  2548.             end
  2549.         end
  2550.         if doContinue then -- hopper available
  2551.             T:go("R1F4R2D2")
  2552.             T:place("minecraft:hopper", -1, "forward")
  2553.             T:go("U1C2U1F4R1")
  2554.             treeFarm:setHopperPlaced(true)
  2555.             saveStatus("treeFarm")
  2556.         end
  2557.     end
  2558.     T:saveToLog("craftHopper() completed")
  2559.     return doContinue
  2560. end
  2561.  
  2562. function craftMiningTurtle(numTurtles)
  2563.     local itemSlot = 0
  2564.     local keepNum = 0
  2565.     local logType = "minecraft:log"
  2566.     local logsNeeded = 0
  2567.     local numSticks = 0
  2568.     local sticksNeeded = 0
  2569.     local startFile = ""
  2570.     local itemInStock = 0
  2571.     local maxItemSlot = 0
  2572.     local minItemSlot = 0
  2573.     local stockData = {}
  2574.     local doContinue = false
  2575.    
  2576.     -- chest1 = sticks
  2577.     -- chest2 = logs (oak/birch/jungle etc)
  2578.     -- chest3 = cobblestone, dirt
  2579.     -- chest4 = sand
  2580.     -- chest5 = iron_ore
  2581.     -- chest6 = redstone
  2582.     -- chest7 = diamond
  2583.     -- chest8 = gold_ore, lapis, mossy_cobblestone, obsidian
  2584.     -- chest9 = saplings (oak/birch,jungle)
  2585.    
  2586.     -- Logs for Items needed:
  2587.     --                      1 turtle        2 turtles
  2588.     --          6 sand      2 logs          2 logs
  2589.     -- disk dr: 7 cobble    2 logs          2 logs
  2590.     -- turtle:  7 cobble    2 logs          4 logs
  2591.     -- ironore: 7 iron ore  2 logs          4 logs
  2592.     -- crafting:            1 log           2 logs
  2593.     -- chests:              2 logs          4 logs
  2594.     -- pickaxe:             1 log           1 log
  2595.     --                  Min 13 wood     Max 21 wood
  2596.     T:saveToLog("craftMiningTurtle() started")
  2597.     -- start under furnace / over chest1
  2598.     if numTurtles == 0 then
  2599.         term.clear()
  2600.         T:saveToLog("Not enough diamonds in this area.\nMission has failed", true)
  2601.         error()
  2602.     elseif numTurtles == 1 then -- 0 - 2 diamonds + pickaxe
  2603.         sticksNeeded = 2
  2604.         logsNeeded = 20
  2605.     elseif numTurtles == 2 then
  2606.         sticksNeeded = 4
  2607.         logsNeeded = 28
  2608.     end
  2609.    
  2610.     T:sortInventory()
  2611.     --use coal for fuel
  2612.     itemSlot = T:getItemSlot("minecraft:coal", -1)
  2613.     while itemSlot > 0 do
  2614.         turtle.select(itemSlot)
  2615.         turtle.refuel()
  2616.         itemSlot = T:getItemSlot("minecraft:coal", -1)
  2617.     end
  2618.     --empty turtle into correct storage
  2619.     T:dropItem("minecraft:stick", 0)
  2620.     T:forward(2) -- logs
  2621.     T:dropItem("minecraft:log", 0)
  2622.     T:dropItem("minecraft:log2", 0)
  2623.     T:forward(2) --dirt cobble
  2624.     T:dropItem("minecraft:cobblestone", 0)
  2625.     T:dropItem("minecraft:dirt", 0)
  2626.     T:forward(2) --sand reeds
  2627.     T:dropItem("minecraft:sand", 0)
  2628.     T:forward(2) --iron ore
  2629.     T:dropItem("minecraft:iron_ore", 0)
  2630.     T:dropItem("minecraft:bucket", 0)
  2631.     T:forward(2) --redstone
  2632.     T:dropItem("minecraft:redstone", 0)
  2633.     T:forward(2) -- diamond
  2634.     T:dropItem("minecraft:diamond", 0)
  2635.     T:forward(2)
  2636.     for i = 1, 16 do
  2637.         if turtle.getItemCount(i) > 0 then
  2638.             if T:getItemName(i) ~= "minecraft:chest" then
  2639.                 T:dropItem(T:getItemName(i))
  2640.             end
  2641.         end
  2642.     end
  2643.    
  2644.     -- only chest(s) left behind in turtle
  2645.     itemSlot = T:getItemSlot("minecraft:chest", 0)
  2646.     if itemSlot ~= 1 then
  2647.         turtle.select(itemSlot)
  2648.         turtle.transferTo(1)
  2649.     end
  2650.     -- go back and remove supplies
  2651.     T:go("R2F2") -- diamonds
  2652.     turtle.select(1)
  2653.     while turtle.suckDown() do end
  2654.     itemSlot = T:getItemSlot("minecraft:diamond", 0)
  2655.     keepNum = numTurtles * 3
  2656.     turtle.select(itemSlot)
  2657.     if turtle.getItemCount(itemSlot) > keepNum then
  2658.         turtle.dropDown(turtle.getItemCount(itemSlot) - keepNum)
  2659.     end
  2660.    
  2661.     T:forward(2) --redstone
  2662.     turtle.select(1)
  2663.     turtle.suckDown()
  2664.     itemSlot = T:getItemSlot("minecraft:redstone")
  2665.     keepNum = numTurtles + 3
  2666.     turtle.select(itemSlot)
  2667.     if turtle.getItemCount(itemSlot) > keepNum then
  2668.         turtle.dropDown(turtle.getItemCount(itemSlot) - keepNum)
  2669.     end
  2670.    
  2671.     T:forward(2) --iron ore
  2672.     turtle.select(1)
  2673.     turtle.suckDown()
  2674.     itemSlot = T:getItemSlot("minecraft:iron_ore")
  2675.     keepNum = numTurtles * 7
  2676.     turtle.select(itemSlot)
  2677.     if turtle.getItemCount(itemSlot) > keepNum then
  2678.         turtle.dropDown(turtle.getItemCount(itemSlot) - keepNum)
  2679.     end
  2680.    
  2681.    
  2682.     T:forward(2) --sand and reeds
  2683.     turtle.select(1)
  2684.     while turtle.suckDown() do end
  2685.     itemSlot = T:getItemSlot("minecraft:sand")
  2686.     keepNum = 6
  2687.     turtle.select(itemSlot)
  2688.     if turtle.getItemCount(itemSlot) > keepNum then
  2689.         turtle.dropDown(turtle.getItemCount(itemSlot) - keepNum)
  2690.     end
  2691.     itemSlot = T:getItemSlot("minecraft:reeds")
  2692.     turtle.select(itemSlot)
  2693.     keepNum = 3
  2694.     if turtle.getItemCount(itemSlot) > keepNum then
  2695.         turtle.dropDown(turtle.getItemCount(itemSlot) - keepNum)
  2696.     end
  2697.    
  2698.     T:forward(2) --cobblestone
  2699.     keepNum = numTurtles * 7 + 7
  2700.     repeat
  2701.         turtle.suckDown()
  2702.         stockData = T:getStock("minecraft:cobblestone")
  2703.     until stockData.total >= keepNum
  2704.     itemSlot = T:getItemSlot("minecraft:cobblestone")
  2705.     T:dropItem("minecraft:cobblestone", turtle.getItemCount(itemSlot) - keepNum)
  2706.     T:dropItem("minecraft:dirt", 0)
  2707.  
  2708.     T:forward(2) --logs
  2709.     while turtle.suckDown() do
  2710.         stockData = T:getStock("minecraft:log")
  2711.         if stockData.total >= logsNeeded then
  2712.             break
  2713.         end
  2714.         stockData = T:getStock("minecraft:log2")
  2715.         if stockData.total >= logsNeeded then
  2716.             break
  2717.         end
  2718.     end
  2719.     --empty furnace
  2720.     turtle.select(1)
  2721.     T:go("F2R2B1U1s1D1F1")
  2722.     itemSlot = T:getItemSlot("minecraft:planks")
  2723.     if itemSlot > 0 then
  2724.         stockData = T:getStock("minecraft:planks")
  2725.         if stockData.total >= 2 then
  2726.             craftSticks(4)
  2727.         end
  2728.         itemSlot = T:getItemSlot("minecraft:planks")
  2729.         if itemSlot > 0 then
  2730.             turtle.select(itemSlot)
  2731.             turtle.refuel()
  2732.         end
  2733.     end
  2734.     turtle.select(1)
  2735.     turtle.suckDown()
  2736.     itemSlot = T:getItemSlot("minecraft:stick")
  2737.     keepNum = sticksNeeded
  2738.     if itemSlot > 0 then
  2739.         if turtle.getItemCount(itemSlot) > keepNum then
  2740.             turtle.select(itemSlot)
  2741.             turtle.dropDown(turtle.getItemCount(itemSlot) - keepNum)
  2742.             sticksNeeded = 0
  2743.         end
  2744.     end
  2745.    
  2746.     -- logs: crafting table = 2, sticks  = 1, smelt
  2747.     -- planks: crafting table = 8, sticks = 2, smelt cobble = 21, smelt ironore = 14, smelt sand = 6, total 64
  2748.     stockData = T:getStock("minecraft:log")
  2749.     if stockData.total == 0 then
  2750.         stockData = T:getStock("minecraft:log2")
  2751.         logType = "minecraft:log2"
  2752.     end
  2753.     if stockData.total < logsNeeded then --not enough logs on board
  2754.         harvestTreeFarm()
  2755.         stockData = T:getStock("minecraft:log")
  2756.         logType = "minecraft:log"
  2757.         if stockData.total == 0 then
  2758.             stockData = T:getStock("minecraft:log2")
  2759.             logType = "minecraft:log2"
  2760.         end
  2761.     end
  2762.     if sticksNeeded > 0 then
  2763.         craftSticks(4)
  2764.     end
  2765.     T:craft("minecraft:diamond_pickaxe", 1, "minecraft:stick",  "minecraft:diamond", nil, false)
  2766.     if numTurtles == 2 then --make 2 diamond pickaxe
  2767.         T:craft("minecraft:diamond_pickaxe", 1, "minecraft:stick",  "minecraft:diamond", nil, false)
  2768.     end
  2769.     smelt("minecraft:cobblestone", 7  * numTurtles + 7)
  2770.     smelt("minecraft:iron_ore", 7 * numTurtles)
  2771.     smelt("minecraft:sand", 6)
  2772.     T:craft("minecraft:planks", 12 * numTurtles, logType, nil, nil, false)
  2773.     T:craftChests(numTurtles)
  2774.     T:craft("minecraft:crafting_table", numTurtles, "minecraft:planks", nil, nil, false)
  2775.     itemSlot = T:getItemSlot("minecraft:planks")
  2776.     if itemSlot > 0 then
  2777.         turtle.select(itemSlot)
  2778.         turtle.refuel()
  2779.     end
  2780.    
  2781.     T:craft("minecraft:paper", 3, "minecraft:reeds", nil, nil, false)
  2782.     T:craft("minecraft:glass_pane", 16, "minecraft:glass", nil, nil, false)
  2783.     T:craft(ccDisk, 1, "minecraft:paper", "minecraft:redstone", nil, false)
  2784.     T:craft(ccComputer, numTurtles, "minecraft:glass_pane", "minecraft:redstone", "minecraft:stone", false)
  2785.     T:craft(ccTurtle, numTurtles, "minecraft:chest", ccComputer, "minecraft:iron_ingot", false)
  2786.     T:craft(ccCraftyMiningTurtle, 1, "minecraft:crafting_table", "minecraft:diamond_pickaxe", ccTurtle, false)
  2787.     T:craft(ccDiskDrive, 1, "minecraft:redstone", "minecraft:stone", nil, false)
  2788.     T:go("R2F3R2")
  2789.     programTurtles(numTurtles)
  2790. end
  2791.  
  2792. function programTurtles(numTurtles)
  2793.     --program mining turtle
  2794.     turtle.select(T:getItemSlot(ccDiskDrive))
  2795.     turtle.place()
  2796.     turtle.select(T:getItemSlot(ccDisk))
  2797.     turtle.drop()
  2798.     T:go("U1F1") --now on top of disk drive
  2799.    
  2800.    
  2801.     if disk.isPresent("bottom") then
  2802.         local filepath = shell.getRunningProgram()
  2803.         local filename = fs.getName(filepath)
  2804.         if fs.getFreeSpace("/disk/") > 130000 then -- use filecopy
  2805.             fs.copy(filepath, "/disk/"..filename)
  2806.             T:saveToLog("selfReplicate.lua copied to floppy disk", true)
  2807.         else
  2808.             local text = "Config file not modified on this system."
  2809.             text = text.."\nUnable to copy 150kB file."
  2810.             text = text.."\nMy offspring will download files from"
  2811.             text = text.."\nPastebin if connected to the internet"
  2812.             text = text.."\nLast resort:\ncopy selfReplicate.lua\nusing Windows file explorer"
  2813.             T:saveToLog(text, true)
  2814.         end
  2815.        
  2816.         --This script is a file called startup stored on the floppy disk
  2817.         --When a turtle is placed next to the disk drive, it reads this script
  2818.         --which opens 'minerList.txt' and sets the label to Miner2, (as '2' is stored in this file)
  2819.         --Either copies start.lua to the turtle then modifies 'minerList.txt' to '3'
  2820.         --or if on a server, requests the start.lua file via http from pastebin
  2821.         --so the name Miner3 given for the second turtle, (if constructed)
  2822.        
  2823.         -- create/overwrite 'minerList.txt' on floppy disk
  2824.         startFile = fs.open("/disk/minerList.txt", "w")
  2825.         startFile.writeLine("2")
  2826.         startFile.close()
  2827.         -- create/overwrite startup
  2828.         startFile = fs.open("/disk/startup", "w")
  2829.         startFile.writeLine('function get(name, code)')
  2830.         startFile.writeLine('   local response = http.get("http://pastebin.com/raw.php?i="..textutils.urlEncode(code))')
  2831.         startFile.writeLine('   if response then')
  2832.         startFile.writeLine('       local sCode = response.readAll()')
  2833.         startFile.writeLine('       if sCode ~= nil and sCode ~= "" then')
  2834.         startFile.writeLine('           local file = fs.open( name, "w" )')
  2835.         startFile.writeLine('           response.close()')
  2836.         startFile.writeLine('           file.write(sCode)')
  2837.         startFile.writeLine('           file.close()')
  2838.         startFile.writeLine('           return true')
  2839.         startFile.writeLine('       end')
  2840.         startFile.writeLine('   end')
  2841.         startFile.writeLine('   return false')
  2842.         startFile.writeLine('end') 
  2843.         startFile.writeLine('if fs.exists("/disk/minerList.txt") then')
  2844.         startFile.writeLine('   textFile = fs.open("/disk/minerList.txt", "r")')
  2845.         startFile.writeLine('   textIn = textFile.readAll()')
  2846.         startFile.writeLine('   minerName = "Miner"..textIn')
  2847.         startFile.writeLine('   textFile.close()')
  2848.         startFile.writeLine('   textOut = tostring(tonumber(textIn) + 1)')
  2849.         startFile.writeLine('else')
  2850.         startFile.writeLine('   minerName = "Miner2"')
  2851.         startFile.writeLine('   textOut = "3"')
  2852.         startFile.writeLine('end')
  2853.         startFile.writeLine('textFile = fs.open("/disk/minerList.txt", "w")')
  2854.         startFile.writeLine('textFile.writeLine(textOut)')
  2855.         startFile.writeLine('textFile.close()')
  2856.         startFile.writeLine('if os.getComputerLabel() == nil or string.find(os.getComputerLabel(),"Miner") == nil then')
  2857.         startFile.writeLine('   os.setComputerLabel(minerName)')
  2858.         startFile.writeLine('end')
  2859.         startFile.writeLine('print("Hello, my name is "..os.getComputerLabel())')
  2860.         startFile.writeLine('if fs.exists("/disk/selfReplicate.lua") then')
  2861.         startFile.writeLine('   fs.copy("/disk/selfReplicate.lua", "selfReplicate.lua")')
  2862.         startFile.writeLine('   print("Replication program copied")')
  2863.         startFile.writeLine('else')
  2864.         startFile.writeLine('   get("selfReplicate.lua", "'..pastebinCode..'")')   
  2865.         startFile.writeLine('end')
  2866.         startFile.writeLine('print("Break me and move to a tree > 33 blocks away")')
  2867.         startFile.writeLine('print("use selfReplicate.lua to begin self replicating ")')
  2868.         startFile.close()
  2869.     end
  2870.     T:go("B1D1R1F1L1")
  2871.     turtle.select(T:getItemSlot(ccCraftyMiningTurtle))
  2872.     turtle.place() --next to disk drive
  2873.     T:turnLeft(1)
  2874.     if numTurtles == 2 then
  2875.         T:craft(ccCraftyMiningTurtle, 1, "minecraft:crafting_table", "minecraft:diamond_pickaxe", ccTurtle, false)
  2876.         T:go("F1R1U1")
  2877.         turtle.select(T:getItemSlot(ccCraftyMiningTurtle))
  2878.         turtle.place() --next to disk drive
  2879.         T:down(1)
  2880.     else
  2881.         T:go("F1R1")
  2882.     end
  2883.     term.clear()
  2884.     if numTurtles == 2 then
  2885.         T:saveToLog("Mission successful.\nI have replicated myself twice.\n\nRight-Click on my offspring to check their status...")
  2886.     else
  2887.         T:saveToLog("Mission partially successful.\nI have replicated myself once\n\nRight-Click on my offspring to check its status...")
  2888.     end
  2889. end
  2890.  
  2891. function craftSigns(signsNeeded)
  2892.     local success = false
  2893.     local woodNeeded = 0
  2894.     local woodInStock = 0
  2895.     local numPlanksNeeded = 0
  2896.     local logType = "minecraft:log"
  2897.     local stockData = {}
  2898.  
  2899.     turtle.suckDown() --get any sticks in chest below
  2900.     signsNeeded = signsNeeded or 3
  2901.     if signsNeeded > 12 then
  2902.         signsNeeded = 12
  2903.     end
  2904.     --make 3 signs by default , need 8 planks, leaves 3 sticks
  2905.     --  signs   planks  sticks  wood
  2906.     --  3       6 + 2   1       2
  2907.     --  6       12 + 2  2       4
  2908.     --  9       18 + 2  3       5
  2909.     --  12      24 + 2  4       7
  2910.    
  2911.     if signsNeeded == 3 then
  2912.         woodNeeded = 2
  2913.         numPlanksNeeded = 8
  2914.     elseif signsNeeded == 6 then
  2915.         woodNeeded = 4
  2916.         numPlanksNeeded = 16
  2917.     elseif signsNeeded == 9 then
  2918.         woodNeeded = 5
  2919.         numPlanksNeeded = 20
  2920.     else
  2921.         woodNeeded = 7
  2922.         numPlanksNeeded = 28
  2923.     end
  2924.  
  2925.     woodInStock = T:getLogStock()
  2926.     if woodInStock >= woodNeeded then
  2927.         stockData = T:getStock("minecraft:log")
  2928.         if stockData.total < woodNeeded then
  2929.             stockData = T:getStock("minecraft:log2")
  2930.             if stockData.total >= woodNeeded then
  2931.                 logType = "minecraft:log2"
  2932.             end
  2933.         end
  2934.         T:craft("minecraft:planks", numPlanksNeeded, logType, nil, nil, false)
  2935.         stockData = T:getStock("minecraft:stick")
  2936.         if stockData.total < 1 then
  2937.             T:craft("minecraft:stick", 4, "minecraft:planks", nil, nil, false)
  2938.         end
  2939.         if T:craft("minecraft:sign", signsNeeded, "minecraft:stick", "minecraft:planks", nil, false) then
  2940.             success = true
  2941.         end
  2942.         stockData = T:getStock("minecraft:planks")
  2943.         if stockData.total > 0 then
  2944.             turtle.select(stockData.mostSlot)
  2945.             turtle.refuel()
  2946.         end
  2947.         stockData = T:getStock("minecraft:stick")
  2948.         if stockData.total > 0 then
  2949.             turtle.select(stockData.mostSlot)
  2950.             turtle.dropDown()
  2951.         end
  2952.     end
  2953.     return success
  2954. end
  2955.  
  2956. function craftSticks(sticksNeeded)
  2957.     local success = false
  2958.     local makePlanks = false
  2959.     local woodNeeded = 0
  2960.     local planksNeeded = 0
  2961.     local doContinue = true
  2962.     local stockData = {}
  2963.    
  2964.     if sticksNeeded <= 4 then
  2965.         sticksNeeded = 4
  2966.         planksNeeded = 4   
  2967.         woodNeeded = 1
  2968.     elseif sticksNeeded <= 8 then
  2969.         sticksNeeded = 8
  2970.         planksNeeded = 4
  2971.         woodNeeded = 1
  2972.     elseif sticksNeeded <= 12 then
  2973.         sticksNeeded = 12
  2974.         planksNeeded = 8
  2975.         woodNeeded = 2
  2976.     else
  2977.         sticksNeeded = 16
  2978.         planksNeeded = 8
  2979.         woodNeeded = 2
  2980.     end
  2981.    
  2982.     stockData = T:getStock("minecraft:planks")
  2983.     if stockData.total < planksNeeded then
  2984.         makePlanks = true
  2985.     else
  2986.         woodNeeded = 0 --reset
  2987.     end
  2988.    
  2989.     if makePlanks then --need wood
  2990.         stockData = T:getLogData()
  2991.         if stockData.total >= woodNeeded then
  2992.             T:craft("minecraft:planks", planksNeeded, stockData.mostName, nil, nil, false)
  2993.         else
  2994.             doContinue = false
  2995.         end
  2996.     end
  2997.     if doContinue then
  2998.         if T:craft("minecraft:stick", sticksNeeded, "minecraft:planks", nil, nil, false) then
  2999.             success = true
  3000.         end
  3001.     end
  3002.    
  3003.     return success
  3004. end
  3005.  
  3006. function craftTorches(torchesNeeded)
  3007.     -- 4 torches min : 1 head + 1 stick = 4 torches. Min sticks  = 4, min planks = 4
  3008.     -- torches head planks sticks
  3009.     -- 4        1       4       4
  3010.     -- 8        2       4       4
  3011.     -- 12       3       4       4
  3012.     -- 16       4       4       4
  3013.     -- 20       5       4       8
  3014.     -- 24       6       4       8
  3015.     -- 28       7       4       8
  3016.     -- 32       8       4       8
  3017.     -- 36       9       8       12
  3018.     -- 40       10      8       12
  3019.     -- 44       11      8       12
  3020.     -- 48       12      8       12
  3021.     -- 52       13      8       16
  3022.     -- 56       14      8       16
  3023.     -- 60       15      8       16
  3024.     -- 64       16      8       16
  3025.     local logType = "minecraft:log"
  3026.     local headModifier = 1 --charcoal
  3027.     local headQuantity = 0
  3028.     local makeCharcoal = false
  3029.     local makePlanks = false
  3030.     local success = false
  3031.     local doContinue = true
  3032.     local woodNeeded = 0
  3033.     local planksNeeded = 0
  3034.     local sticksNeeded = 0
  3035.     local coalInStock = 0
  3036.     local charcoalInStock = 0
  3037.     local sticksInStock = 0
  3038.     local planksInStock = 0
  3039.     local stockData = {}
  3040.    
  3041.     T:saveToLog("craftTorches("..torchesNeeded..")")
  3042.     --turtle will be above storage chest to run this function
  3043.     turtle.select(1)
  3044.     --get sticks from storage
  3045.     while turtle.suckDown() do end
  3046.     stockData = T:getStock("minecraft:stick")
  3047.     sticksInStock = stockData.total
  3048.     torchesNeeded = math.floor(torchesNeeded / 4) * 4 -- correct torchesNeeded to multiple of 4
  3049.     headQuantity = torchesNeeded / 4 -- coal, charcoal
  3050.     stockData = T:getStock("minecraft:planks", -1)
  3051.     planksInStock = stockData.total
  3052.     -- calculate sticks/planks/logs needed
  3053.     if torchesNeeded == 0 then
  3054.         torchesNeeded = 4 -- torches min 4
  3055.         if sticksInStock < 4 then
  3056.             planksNeeded = 4 -- 1 wood
  3057.             sticksNeeded = 4 -- 2 planks
  3058.             woodNeeded = 1
  3059.         end
  3060.     elseif torchesNeeded <= 16 then-- 4, 8, 12, 16
  3061.         if sticksInStock < 4 then
  3062.             planksNeeded = 4  -- 8 planks = 16 sticks
  3063.             sticksNeeded = 4  -- 4 sticks
  3064.             woodNeeded = 1
  3065.         end
  3066.     elseif torchesNeeded <= 32 then-- 4, 8, 12, 16
  3067.         if sticksInStock < 8 then
  3068.             planksNeeded = 4  -- 8 planks = 16 sticks
  3069.             sticksNeeded = 8  -- 8 sticks
  3070.             woodNeeded = 2
  3071.         end
  3072.     elseif torchesNeeded <= 48 then-- 4, 8, 12, 16
  3073.         if sticksInStock < 12 then
  3074.             planksNeeded = 8  -- 8 planks = 16 sticks
  3075.             sticksNeeded = 12 -- 12 sticks
  3076.             woodNeeded = 2
  3077.         end
  3078.     else
  3079.         if sticksInStock < 16 then
  3080.             planksNeeded = 8  -- 8 planks = 16 sticks
  3081.             sticksNeeded = 16 -- 16 sticks
  3082.             woodNeeded = 2
  3083.         end
  3084.     end
  3085.     --need either coal or charcoal
  3086.     stockData = T:getStock("minecraft:coal", 0)
  3087.     coalInStock = stockData.total
  3088.     stockData = T:getStock("minecraft:coal", 1)
  3089.     charcoalInStock = stockData.total
  3090.    
  3091.     if coalInStock >= headQuantity  then
  3092.         headModifier  = 0 --use coal
  3093.     else
  3094.         headModifier  = 1 -- use charcoal
  3095.     end
  3096.     if headModifier == 1 then --use charcoal
  3097.         if charcoalInStock < headQuantity then
  3098.             makeCharcoal = true
  3099.         end
  3100.         -- extra logs needed for charcoal production
  3101.         woodNeeded = woodNeeded + headQuantity
  3102.         -- extra logs needed for charcoal fuel
  3103.         woodNeeded = woodNeeded + torchesNeeded / 4
  3104.     end
  3105.     T:saveToLog("craftTorches("..torchesNeeded..") coal="..coalInStock..", charcoal="..charcoalInStock..", planksNeeded="..planksNeeded..", woodNeeded="..woodNeeded)
  3106.     -- amount of logs needed known
  3107.     stockData = T:getStock("minecraft:log", -1)
  3108.     if stockData.total < woodNeeded then
  3109.         stockData = T:getStock("minecraft:log2")
  3110.         if stockData.total >= woodNeeded then
  3111.             logType = "minecraft:log2"
  3112.         else -- not enough log/log2 onboard
  3113.             getItemFromStorage("minecraft:log", true) -- get all types of log from storage
  3114.             stockData = T:getStock("minecraft:log")
  3115.             if stockData.total < woodNeeded then
  3116.                 stockData = T:getStock("minecraft:log2")
  3117.                 if stockData.total >= woodNeeded then
  3118.                     logType = "minecraft:log2"
  3119.                 else -- not enough logs to make torches
  3120.                     doContinue = false
  3121.                 end
  3122.             else
  3123.                 logType = "minecraft:log"
  3124.             end
  3125.         end
  3126.     end
  3127.     T:saveToLog("craftTorches("..torchesNeeded..") using "..logType)
  3128.  
  3129.     if doContinue then --enough raw materials onboard
  3130.         if sticksInStock == 0 or sticksInStock < headQuantity then
  3131.             stockData = T:getStock("minecraft:stick")
  3132.             if stockData.total < sticksNeeded then
  3133.                 doContinue = false
  3134.                 T:saveToLog("craftTorches("..torchesNeeded..") crafting sticks")
  3135.                 if craftSticks(sticksNeeded) then
  3136.                     doContinue = true
  3137.                 end
  3138.             end
  3139.         end
  3140.         if doContinue then
  3141.             if makeCharcoal then
  3142.                 doContinue = false
  3143.                 T:saveToLog("craftTorches("..torchesNeeded..") smelting charcoal")
  3144.                 if smelt(logType, headQuantity) then
  3145.                     doContinue = true
  3146.                 end
  3147.             end
  3148.             if doContinue then
  3149.                 --make  torches
  3150.                 T:saveToLog("craftTorches("..torchesNeeded..") crafting torches...")
  3151.                 if T:craft("minecraft:torch", torchesNeeded, "minecraft:stick", "minecraft:coal", nil, false) then
  3152.                     success = true
  3153.                 end
  3154.             end
  3155.         end
  3156.         stockData = T:getStock("minecraft:stick", -1)
  3157.         if stockData.total > 0 then
  3158.             T:saveToLog("craftTorches("..torchesNeeded..") storing sticks")
  3159.             turtle.select(stockData.mostSlot)
  3160.             turtle.dropDown()
  3161.         end
  3162.     end
  3163.    
  3164.     return success
  3165. end
  3166.  
  3167. function createMine(status)
  3168.     -- initial excavation in centre complete.
  3169.     T:saveToLog("createMine() Starting...", true)
  3170.     if status == 5 then
  3171.         createMinePrepare(14)
  3172.         T:saveToLog("createMine() Starting Level 14", true)
  3173.         createMineLevel(14)
  3174.         status = 6
  3175.         T:saveToLog("createMine() Level 14 complete. Saving Status '6'", true)
  3176.     end
  3177.     if status == 6 then
  3178.         createMinePrepare(11)
  3179.         T:saveToLog("createMine() Starting Level 11", true)
  3180.         createMineLevel(11)
  3181.         status = 7
  3182.         T:saveToLog("createMine() Level 11 complete. Saving Status '7'", true)
  3183.     end
  3184.     if status == 7 then
  3185.         createMinePrepare(8)
  3186.         T:saveToLog("createMine() Starting Level 8", true)
  3187.         createMineLevel(8)
  3188.         status = 8
  3189.         T:saveToLog("createMine() Level 8 complete. Saving Status '8'", true)
  3190.     end
  3191.     return status
  3192. end
  3193.  
  3194. function createMinePrepare(level)
  3195.     local logsRequired = 0
  3196.     local stockData = T:getStock("minecraft:coal", -1) --either coal or charcoal
  3197.     local numCoal = stockData.total
  3198.     local numLogs = T:getLogStock()
  3199.    
  3200.     emptyTurtle(false) -- keeps iron_ore, cobble, dirt, bucket, torches, signs, log, log2
  3201.     -- may have iron ore so attempt bucket crafting / check if bucket onboard
  3202.     if craftBucket() then -- checks or crafts a bucket
  3203.         checkTreeFarm()
  3204.     end
  3205.     -- wood needed for level 14 signs: 2 for signs
  3206.     -- wood needed for all levels: 5 for fuel, 3 for torches, 2 for chests
  3207.     if level == 14 then
  3208.         logsRequired = 12
  3209.     else
  3210.         logsRequired = 10
  3211.     end
  3212.     if numCoal >= 2 then
  3213.         logsRequired = logsRequired - 2
  3214.     end
  3215.     if numLogs < logsRequired then
  3216.         if treeFarm:getFarmCreated() then
  3217.             waitForTreeFarm(10)
  3218.         end
  3219.     end
  3220.     numLogs = T:getLogStock()
  3221.     local slot, modifier, total = T:getItemSlot("minecraft:chest", -1)
  3222.     if total < 2 and numLogs >= 2 then -- make 1 chest if 2 logs
  3223.         T:craftChests(1, true)
  3224.         numLogs = T:getLogStock()
  3225.     end
  3226.     slot, modifier, total = T:getItemSlot("minecraft:torch", -1)
  3227.     if total < 24 then
  3228.         if numLogs >= 4 or (numLogs >= 2 and numCoal >= 2) then
  3229.             craftTorches(24 - total)    -- craft 24 torches 3 logs
  3230.             numLogs = T:getLogStock()
  3231.         end
  3232.     end
  3233.     if level == 14 then
  3234.         slot, modifier, total = T:getItemSlot("minecraft:sign", -1)
  3235.         if total < 1 and numLogs >= 2 then
  3236.             craftSigns(3)   -- craft 3 signs 2 logs
  3237.         end
  3238.     end
  3239.     stockData = T:getStock("minecraft:log")
  3240.     if stockData.mostSlot ~= stockData.leastSlot then -- 2 types of log, so craft planks and refuel
  3241.         if stockData.leastCount <= 16 then
  3242.             T:craft("minecraft:planks", stockData.leastCount * 4, "minecraft:log", nil, nil, true)
  3243.         end
  3244.     end
  3245.     stockData = T:getStock("minecraft:sign")
  3246.     T:saveToLog("createMinePrepare("..level..") Signs avaiable: "..stockData.total, true)
  3247.     stockData = T:getStock("minecraft:torch")
  3248.     T:saveToLog("createMinePrepare("..level..") Torches avaiable: "..stockData.total, true)
  3249.     stockData = T:getStock("minecraft:chest")
  3250.     T:saveToLog("createMinePrepare("..level..") Chests avaiable: "..stockData.total - 1, true)
  3251. end
  3252.  
  3253. function createMineLevel(level)
  3254.     local tempYcoord = T:getY()
  3255.     local doContinue = false
  3256.     local blockType = ""
  3257.     local stockData = {}
  3258.  
  3259.     -- go down to level 14, 11, 8 and create + shape with firstTree at centre, 16 blocks length each arm
  3260.     -- torches at each end, and half way along
  3261.     T:forward(16) --now over mineshaft site
  3262.     if level == 14 then --first level so create mineshaft
  3263.         -- level out mine entrance and mark with a sign
  3264.         T:go("+0")
  3265.         while T:getY() >= tempYcoord - 1 do
  3266.             T:go("x1R1x1R1x1R1x1R1D1")
  3267.         end
  3268.         T:go("U1C1R1C1R1C1R1C1R1U1")
  3269.         if T:getItemSlot("minecraft:sign") > 0 then
  3270.             T:dig("forward")
  3271.             turtle.select(T:getItemSlot("minecraft:sign"))
  3272.             turtle.place("Diamond Mine\nPreparing for\nDeep Excavation\nLevel "..tostring(level))
  3273.             --dump remaining signs
  3274.             turtle.dropUp()
  3275.         end
  3276.     else   
  3277.         T:dig("forward") -- dig existing sign
  3278.         if T:getItemSlot("minecraft:sign") > 0 then
  3279.             turtle.select(T:getItemSlot("minecraft:sign"))
  3280.             turtle.place("Diamond Mine\nPreparing for\nDeep Excavation\nLevel "..tostring(level))
  3281.         end
  3282.     end
  3283.     mineEntrance:setX(T:getX())
  3284.     mineEntrance:setY(T:getY())
  3285.     mineEntrance:setZ(T:getZ())
  3286.     mineEntrance:setFacing(T:getFacing())
  3287.     T:turnRight(2)
  3288.     while T:getY() > level do
  3289.         T:down(1)
  3290.         if level == 14 then -- shaft mining, check for valuables
  3291.             for i = 1, 4 do
  3292.                 if T:isValuable("forward") then
  3293.                     mineItem(true, "forward")
  3294.                 else
  3295.                     blockType = T:getBlockType("forward")
  3296.                     if  blockType == "minecraft:water" or
  3297.                         blockType == "minecraft:flowing_water" or
  3298.                         blockType == "minecraft:lava" or
  3299.                         blockType == "minecraft:flowing_lava" then
  3300.                         T:go("C1")
  3301.                     end
  3302.                 end
  3303.                 T:turnRight(1)
  3304.             end
  3305.         end
  3306.     end
  3307.     T:go("x2R2C1D1C1R2")
  3308.     --ready to create mine at level 14 37x37 square
  3309.     T:go("m32U1R2M16D1", true, 8) -- mine ground level, go up, reverse and mine ceiling to mid-point, drop to ground
  3310.     T:place("minecraft:chest", -1, "down") --place chest in ground
  3311.     T:up(1) -- ready for emptyTrash() which moves down/up automatically
  3312.     T:emptyTrash("down")
  3313.     T:go("D1R1m16U1R2M16", true, 8) -- mine floor/ceiling of right side branch
  3314.     T:emptyTrash("down")
  3315.     T:go("D1m16U1R2M16", true, 8) -- mine floor/ceiling of left side branch
  3316.     T:emptyTrash("down")
  3317.     T:go("L1M15F1R1D1", true, 8) -- mine ceiling of entry coridoor, turn right
  3318.     T:go("n16R1n32R1n32R1n32R1n16U1", true, 8)-- mine floor of 36 x 36 square coridoor
  3319.     T:go("R1F16R2") --return to centre
  3320.     T:emptyTrash("down")
  3321.     T:go("F16R1") --return to entry shaft
  3322.     T:go("Q16R1Q32R1Q32R1Q32R1Q16x0F1R1", true, 8) --mine ceiling of 36x36 square coridoor. return to entry shaft + 1
  3323.     -- get rid of any remaining torches
  3324.     while T:getItemSlot("minecraft:torch", -1) > 0 do
  3325.         turtle.select(T:getItemSlot("minecraft:torch", -1))
  3326.         turtle.drop()
  3327.     end
  3328.     for i = 1, 8 do
  3329.         T:go("N32L1F1L1", true)
  3330.         T:dumpRefuse()
  3331.         T:go("N32R1F1R1", true)
  3332.         T:dumpRefuse()
  3333.     end
  3334.     T:go("R1F1R2C1R2F17L1") -- close gap in wall, return
  3335.     for i = 1, 8 do
  3336.         T:go("N32R1F1R1", true)
  3337.         T:dumpRefuse()
  3338.         T:go("N32L1F1L1", true)
  3339.         T:dumpRefuse() 
  3340.     end
  3341.     T:go("L1F1R2C1R2F16R1") -- close gap in wall, return
  3342.     --return to surface
  3343.     while T:getY() < mineEntrance:getY() do
  3344.         T:up(1)
  3345.     end --at surface now
  3346.     T:forward(16)
  3347.     T:turnRight(2)
  3348. end
  3349.  
  3350. function emptyAfterHarvest()
  3351.     local item = ""
  3352.     local keepit = false
  3353.     local keepItems = { "minecraft:dirt", "minecraft:cobblestone", "minecraft:chest", "minecraft:log", "minecraft:log2", "minecraft:coal",
  3354.                         "minecraft:sapling", "minecraft:iron_ore", "minecraft:diamond", "minecraft:redstone", "minecraft:sign", "minecraft:torch",
  3355.                         "minecraft:water_bucket", "minecraft:lava_bucket", "minecraft:bucket", "minecraft:planks",
  3356.                         "minecraft:sand", "minecraft:reeds", "minecraft:iron_ingot", "minecraft:emerald"}
  3357.    
  3358.     -- just finished harvesting all trees. get rid of apples, seeds any other junk
  3359.     -- or finished finding cobble after going into a disused mine
  3360.     for i = 1, 16 do
  3361.         keepit = false
  3362.         if turtle.getItemCount(i) > 0 then
  3363.             item = T:getItemName(i)
  3364.             for _,v in pairs(keepItems) do
  3365.                 if v == item then
  3366.                     keepit = true
  3367.                     break
  3368.                 end
  3369.             end
  3370.             if not keepit then
  3371.                 turtle.select(i)
  3372.                 turtle.dropDown()
  3373.             end
  3374.         end
  3375.     end
  3376. end
  3377.  
  3378. function emptyTurtle(keepAll)
  3379.     --  empty out turtle except for logs, coal, torches, signs, bucket, cobble, dirt,diamonds
  3380.     --  chest1 = sticks
  3381.     --  chest2 = logs (oak/birch/jungle etc)
  3382.     --  chest3 = cobblestone, dirt
  3383.     --  chest4 = sand
  3384.     --  chest5 = iron_ore
  3385.     --  chest6 = redstone
  3386.     --  chest7 = diamond
  3387.     --  chest8 = gold_ore, lapis, mossy_cobblestone, obsidian
  3388.     --  chest9 = saplings (oak/birch,jungle)
  3389.  
  3390.     local itemSlot = 0
  3391.     local stockData = {}
  3392.    
  3393.     T:sortInventory()
  3394.     stockData = T:getStock("minecraft:planks", -1)
  3395.     if stockData.total > 0 then
  3396.         turtle.select(stockData.leastSlot)
  3397.         turtle.refuel()
  3398.     end
  3399.    
  3400.     --sapling chest
  3401.     T:go("R1F2D1R2")
  3402.     while turtle.suckDown() do end --remove any junk in the sapling chest as well
  3403.     T:dropItem("minecraft:sapling", 0, "down")-- now only saplings in there
  3404.     T:go("U1F2R1")
  3405.     -- chest1 sticks only
  3406.     T:dropItem("minecraft:stick", 0, "down")
  3407.  
  3408.     T:forward(2) -- chest2 logs of any type, keep 1 stack
  3409.     T:dropItem("minecraft:log", 64, "down")
  3410.     T:dropItem("minecraft:log2", 64, "down")
  3411.    
  3412.     T:forward(2) -- chest3 dirt and cobble
  3413.     if not keepAll then -- keep max 1 stack cobble
  3414.         T:dropItem("minecraft:cobblestone", 64, "down")
  3415.         T:dropItem("minecraft:dirt", 64, "down")
  3416.     end
  3417.    
  3418.     T:forward(2) -- chest4 sand and reeds
  3419.     T:dropItem("minecraft:sand", 0, "down")
  3420.     T:dropItem("minecraft:reeds", 0, "down")
  3421.    
  3422.     T:forward(2) -- chest5 iron ore only
  3423.     T:dropItem("minecraft:iron_ore", 64, "down")
  3424.    
  3425.     T:forward(2) -- redstone
  3426.     T:dropItem("minecraft:redstone", 0, "down")
  3427.     T:forward(4)
  3428.     -- chest8 gold ore, mossy cobblestone, obsidian, lapis, mob drops, misc items
  3429.     for i = 1, 16 do
  3430.         itemName = T:getItemName(i)
  3431.         if itemName ~= ""
  3432.             and itemName ~= "minecraft:chest"
  3433.             and itemName ~= "minecraft:torch"
  3434.             and itemName ~= "minecraft:iron_ore"
  3435.             and itemName ~= "minecraft:cobblestone"
  3436.             and itemName ~= "minecraft:dirt"
  3437.             and itemName ~= "minecraft:log"
  3438.             and itemName ~= "minecraft:log2"
  3439.             and itemName ~= "minecraft:sign"
  3440.             and itemName ~= "minecraft:coal"
  3441.             and itemName ~= "minecraft:diamond"
  3442.             and itemName ~= "minecraft:bucket" then
  3443.             turtle.select(i)
  3444.             turtle.dropDown()
  3445.         end
  3446.     end
  3447.     T:go("R2F14R2")
  3448. end
  3449.  
  3450. function fillPond()
  3451.     local doContinue = false
  3452.     local fileHandle = ""
  3453.     local strText = ""
  3454.     local waterFound = false
  3455.     local numArms = 0
  3456.     local startFile = ""
  3457.     local itemSlot = 0
  3458.     local stockData = {}
  3459.     T:saveToLog("fillPond() started", true)
  3460.     -- reset turtle coordinates from file in case error has occurred with current location
  3461.     getCoords(true)
  3462.     -- read 'waterCoords.txt' from file
  3463.     if fs.exists("waterCoords.txt") then
  3464.         fileHandle = fs.open("waterCoords.txt", "r")
  3465.         strText = fileHandle.readLine()
  3466.         water:setX(tonumber(string.sub(strText, 3)))
  3467.         strText = fileHandle.readLine()
  3468.         water:setY(tonumber(string.sub(strText, 3)))
  3469.         strText = fileHandle.readLine()
  3470.         water:setZ(tonumber(string.sub(strText, 3)))
  3471.         fileHandle.close()
  3472.         T:saveToLog("Water coords from file x="..water:getX()..", y="..water:getY()..", z="..water:getZ(), true)
  3473.     end
  3474.     --T:sortInventory()
  3475.     stockData = T:getStock("minecraft:bucket", -1)
  3476.     if stockData.total == 0 then
  3477.         if craftBucket() then
  3478.             doContinue = true
  3479.         end
  3480.     else
  3481.         doContinue = true
  3482.     end
  3483.     if doContinue then -- bucket available
  3484.         -- fetch 2 buckets water and charge water pool
  3485.         -- place 4 buckets water in tree farm corners
  3486.         -- dig 4 corner blocks in treefarm to allow water flow down to hoppers
  3487.         goToWater() -- calls safeRun which constantly checks for water
  3488.         if T:getItemSlot("minecraft:water_bucket") == 0 then --no water found yet
  3489.             while not turtle.inspectDown() do -- must be air below
  3490.                 T:down(1)
  3491.             end
  3492.             safeRun(1, "minecraft:water")
  3493.             T:turnRight(1)
  3494.             safeRun(1, "minecraft:water")
  3495.             T:turnRight(1) --now facing south, ready to continue spiral
  3496.         end
  3497.         if T:getItemSlot("minecraft:water_bucket") == 0 then
  3498.             numArms = 4
  3499.             for i = 2, numArms, 2 do
  3500.                 safeRun(i, "minecraft:water")      
  3501.                 T:turnRight(1)
  3502.                 safeRun(i, "minecraft:water")
  3503.                 T:turnRight(1)
  3504.                 safeRun(i + 1, "minecraft:water")
  3505.                 T:turnRight(1)
  3506.                 if i + 1 < numArms then
  3507.                     safeRun(i + 1, "minecraft:water")
  3508.                     T:turnRight(1)
  3509.                 else
  3510.                     --return to starting position
  3511.                     safeRun(i / 2, "minecraft:water")
  3512.                     T:turnRight(1)
  3513.                     safeRun(i / 2 + 1, "minecraft:water")
  3514.                 end
  3515.             end
  3516.             --changeDirection()
  3517.             if T:getItemSlot("minecraft:water_bucket") > 0 then
  3518.                 startFile = fs.open("waterCoords.txt", "w")
  3519.                 startFile.writeLine("x="..T:getX())
  3520.                 startFile.writeLine("y="..T:getY())
  3521.                 startFile.writeLine("z="..T:getZ())
  3522.                 startFile.close()
  3523.             end
  3524.         end
  3525.         itemSlot = T:getItemSlot("minecraft:water_bucket", -1)
  3526.         if itemSlot > 0 then
  3527.             treeFarm:setWaterFound(true)
  3528.             returnHome()
  3529.             T:go("L1F3")
  3530.             turtle.select(T:getItemSlot("minecraft:water_bucket"))
  3531.             if turtle.placeDown() then
  3532.                 T:saveToLog("Water added to pond at: x="..T:getX()..", y="..T:getY()..", z="..T:getZ(),true)
  3533.                 T:go("R2F3L1")
  3534.             else
  3535.                 T:go("L1F1L1F1")
  3536.                 if turtle.placeDown() then
  3537.                     T:saveToLog("Water added (after moving) to pond at: x="..T:getX()..", y="..T:getY()..", z="..T:getZ(),true)
  3538.                 end
  3539.                 T:go("L1F1R1F2L1")
  3540.             end
  3541.             goToWater()
  3542.             returnHome()
  3543.             T:go("L1F2L1F1")
  3544.             itemSlot = T:getItemSlot("minecraft:water_bucket")
  3545.             if itemSlot > 0 then
  3546.                 turtle.select(itemSlot)
  3547.                 if turtle.placeDown() then
  3548.                     T:saveToLog("Water added to pond at: x="..T:getX()..", y="..T:getY()..", z="..T:getZ(),true)
  3549.                     T:go("R2F1R1F2L1")
  3550.                 else
  3551.                     T:go("R1F1R1F1")
  3552.                     if turtle.placeDown() then
  3553.                         T:saveToLog("Water added (after moving) to pond at: x="..T:getX()..", y="..T:getY()..", z="..T:getZ(),true)
  3554.                     end
  3555.                     T:go("R1F3L1")
  3556.                 end
  3557.             else
  3558.                 returnHome()
  3559.             end
  3560.         else
  3561.             print("Water not found")
  3562.             error()
  3563.         end
  3564.     end
  3565.     treeFarm:setPondFilled(true)
  3566.     saveStatus("treeFarm")
  3567. end
  3568.  
  3569. function findCobble()
  3570.     local atBedrock = false
  3571.     local blockType = ""
  3572.     local tempY = T:getY()
  3573.     T:saveToLog("findCobble() Starting...", true)
  3574.     --just finished harvesting all trees. get rid of apples, seeds any other junk
  3575.     emptyAfterHarvest()
  3576.     T:down(1)
  3577.     repeat
  3578.         turtle.select(1)
  3579.         if not T:down(1) then
  3580.             atBedrock = true
  3581.         end
  3582.         for i = 1, 4 do
  3583.             if T:isValuable("forward") then
  3584.                 -- call recursive function!!!
  3585.                 mineItem(true, "forward")
  3586.             else
  3587.                 T:dig("forward")
  3588.                 if T:getItemSlot("minecraft:gravel") > 0 then
  3589.                     turtle.select(T:getItemSlot("minecraft:gravel"))
  3590.                     turtle.drop()
  3591.                 elseif T:getItemSlot("minecraft:flint") > 0 then
  3592.                     turtle.select(T:getItemSlot("minecraft:flint"))
  3593.                     turtle.drop()
  3594.                 end
  3595.             end
  3596.             T:turnRight(1)
  3597.             turtle.select(1)
  3598.         end
  3599.     until atBedrock
  3600.     repeat
  3601.         T:up(1)
  3602.     until T:getY() == tempY - 4
  3603.     turtle.select(T:getItemSlot("minecraft:cobblestone"))
  3604.     for i = 1, 3 do
  3605.         for j = 1, 4 do
  3606.             turtle.select(T:getItemSlot("minecraft:cobblestone"))
  3607.             turtle.place()
  3608.             T:turnRight(1)
  3609.         end
  3610.         T:up(1)
  3611.     end
  3612.     T:up(1)
  3613. end
  3614.  
  3615. function floodTreeFarm()
  3616.     local slot = 0
  3617.     local success = true
  3618.     T:saveToLog("floodTreeFarm() started", true)
  3619.     T:go("L1F2R2") -- go to pond
  3620.    
  3621.     for i = 1, 9, 2 do --flood farm except for drainage channel
  3622.         slot = T:getItemSlot("minecraft:bucket")
  3623.         if slot > 0 then
  3624.             turtle.select(slot)
  3625.             turtle.placeDown() -- Fill 1
  3626.         end
  3627.         if i < 9 then
  3628.             T:forward(4 + i)
  3629.         else
  3630.             T:forward(12) -- far right side of farm
  3631.         end
  3632.         T:go("L1F8U1") --T:go("L FFFF FFFF U")
  3633.         slot = T:getItemSlot("minecraft:water_bucket")
  3634.         if slot > 0 then
  3635.             turtle.select(slot)
  3636.             turtle.placeDown()
  3637.         end
  3638.         T:turnLeft(1)
  3639.         if i < 9 then  -- return to left wall of farm
  3640.             T:forward(i)
  3641.         else
  3642.             T:forward(8)
  3643.         end
  3644.         T:go("L1F8D1R1F4R2")
  3645.         -- ready for next bucket fill
  3646.     end
  3647.     slot = T:getItemSlot("minecraft:bucket")
  3648.     if slot > 0 then
  3649.         turtle.select(slot)
  3650.         turtle.placeDown()
  3651.     end
  3652.     T:forward(12)
  3653.     slot = T:getItemSlot("minecraft:water_bucket")
  3654.     if slot > 0 then
  3655.         turtle.select(slot)
  3656.         turtle.placeDown()
  3657.         T:saveToLog("floodTreeFarm() completed")
  3658.     else
  3659.         T:saveToLog("floodTreeFarm() failed: no water obtained", true)
  3660.         success = false
  3661.     end
  3662.     T:go("R2F10R1")
  3663.     treeFarm:setFarmFlooded(true)
  3664.     saveStatus("treeFarm")
  3665.  
  3666.     return success
  3667. end
  3668.  
  3669. function getCoords(fromFile)
  3670.     fromFile = fromFile or false
  3671.     --get world coordinates from player
  3672.     local coord = 0
  3673.     local response = ""
  3674.     local continue = true
  3675.     local event = ""
  3676.     local param1 = ""
  3677.    
  3678.     term.clear()
  3679.     term.setCursorPos(1,1)
  3680.    
  3681.     if fs.exists("homeCoords.txt") then
  3682.         fileHandle = fs.open("homeCoords.txt", "r")
  3683.         strText = fileHandle.readLine()
  3684.         T:setX(tonumber(string.sub(strText, 3)))
  3685.         coordHome:setX(T:getX())
  3686.         strText = fileHandle.readLine()
  3687.         T:setY(tonumber(string.sub(strText, 3)))
  3688.         coordHome:setY(T:getY())
  3689.         strText = fileHandle.readLine()
  3690.         T:setZ(tonumber(string.sub(strText, 3)))
  3691.         strText = fileHandle.readLine()
  3692.         coordHome:setZ(T:getZ())
  3693.         T:setFacing(tonumber(string.sub(strText, 3)))
  3694.         coordHome:setFacing(T:getFacing())
  3695.         fileHandle.close()
  3696.         T:saveToLog("Coordinates loaded from file:", true)
  3697.         T:saveToLog("x = "..T:getX()..", y = "..T:getY()..", z = "..T:getZ()..", f = "..T:getFacing(), true)
  3698.         if not fromFile then
  3699.             print()
  3700.             print(os.getComputerLabel().." assumed to be at Home Location")
  3701.             print()
  3702.             print("starting in 3 seconds")
  3703.             print("STAND CLEAR!")
  3704.             os.sleep(3)
  3705.         end
  3706.     else
  3707.         print("IMPORTANT! Stand directly behind turtle")
  3708.         print("Press F3 to read coordinates")
  3709.         print()
  3710.         continue = true
  3711.         while continue do
  3712.             print("Please enter your X coordinate")
  3713.             write("  x = ")
  3714.             coord = nil
  3715.             while coord == nil do
  3716.                 coord = tonumber(read())
  3717.                 if coord == nil then
  3718.                     term.clear()
  3719.                     term.setCursorPos(1,1)
  3720.                     print("Incorrect input. Use numbers only!")
  3721.                     print()
  3722.                     print("Please enter your X coordinate")
  3723.                     write("  x = ")
  3724.                 end
  3725.             end
  3726.             T:setX(coord)
  3727.             term.clear()
  3728.             term.setCursorPos(1,1)
  3729.             print("Please enter your Y coordinate")
  3730.             write("  y = ")
  3731.             coord = nil
  3732.             while coord == nil do
  3733.                 coord = tonumber(read())
  3734.                 if coord == nil then
  3735.                     term.clear()
  3736.                     term.setCursorPos(1,1)
  3737.                     print("Incorrect input. Use numbers only")
  3738.                     print()
  3739.                     print("Please enter your y coordinate")
  3740.                     write("  y = ")
  3741.                 end
  3742.             end
  3743.             T:setY(coord)
  3744.             term.clear()
  3745.             term.setCursorPos(1,1)
  3746.             print("Please enter your Z coordinate")
  3747.             write("  z = ")
  3748.             coord = nil
  3749.             while coord == nil do
  3750.                 coord = tonumber(read())
  3751.                 if coord == nil then
  3752.                     term.clear()
  3753.                     term.setCursorPos(1,1)
  3754.                     print("Incorrect input. Use numbers only")
  3755.                     print()
  3756.                     print("Please enter your z coordinate")
  3757.                     write("  z = ")
  3758.                 end
  3759.             end
  3760.             T:setZ(coord)
  3761.             response = true
  3762.             while response do
  3763.                 response = false
  3764.                 term.clear()
  3765.                 term.setCursorPos(1,1)
  3766.                 print("Enter Direction you are facing:")
  3767.                 print("  0,1,2,3 (s,w,n,e)")
  3768.                 print()
  3769.                 print(  "  Direction = ")
  3770.                 event, param1 = os.pullEvent ("char")
  3771.                 if param1 == "s" or param1 == "S" then
  3772.                     coord = 0
  3773.                 elseif param1 == "w" or param1 == "W" then
  3774.                     coord = 1
  3775.                 elseif param1 == "n" or param1 == "N" then
  3776.                     coord = 2
  3777.                 elseif param1 == "e" or param1 == "E" then
  3778.                     coord = 3
  3779.                 elseif param1 == "0" or param1 == "1" or param1 == "2" or param1 == "3" then
  3780.                     coord = tonumber(param1)
  3781.                 else
  3782.                     print()
  3783.                     print("Incorrect input: "..param1)
  3784.                     print()
  3785.                     print("Use 0,1,2,3,n,s,w,e")
  3786.                     sleep(2)
  3787.                     response = true
  3788.                 end
  3789.             end
  3790.             T:setFacing(coord)
  3791.             term.clear()
  3792.             term.setCursorPos(1,1)
  3793.             print("Your current location is:")
  3794.             print()
  3795.             print("  x = "..T:getX())
  3796.             print("  y = "..T:getY())
  3797.             print("  z = "..T:getZ())
  3798.             print("  facing "..T:getCompass().." ("..T:getFacing()..")")
  3799.             print()
  3800.             write("Is this correct? (y/n)")
  3801.             event, param1 = os.pullEvent ("char")
  3802.             if param1 == "y" or param1 == "Y" then
  3803.                 continue = false
  3804.             end
  3805.         end
  3806.         -- correct coords to compensate for player standing position
  3807.         -- First tree is considered as point zero, on startup, turtle is in front of this tree
  3808.         -- Player is behind turtle, use 2 blocks to compensate
  3809.         -- facing:      Change:
  3810.         -- 0 (S)        z+1
  3811.         -- 1 (W)        x-1
  3812.         -- 2 (N)        z-1
  3813.         -- 3 (E)        x+1
  3814.  
  3815.         if T:getFacing() == 0 then
  3816.             T:setZ(T:getZ() + 2)
  3817.         elseif T:getFacing() == 1 then
  3818.             T:setX(T:getX() - 2)
  3819.         elseif T:getFacing() == 2 then
  3820.             T:setZ(T:getZ() - 2)
  3821.         elseif T:getFacing() == 3 then
  3822.             T:setX(T:getX() + 2)
  3823.         end
  3824.         coordHome:setX(T:getX())
  3825.         coordHome:setY(T:getY())
  3826.         coordHome:setZ(T:getZ())
  3827.         coordHome:setFacing(T:getFacing())
  3828.         -- create/overwrite 'homeCoords.txt'
  3829.         local fileHandle = fs.open("homeCoords.txt", "w")
  3830.         fileHandle.writeLine("x="..T:getX())
  3831.         fileHandle.writeLine("y="..T:getY())
  3832.         fileHandle.writeLine("z="..T:getZ())
  3833.         fileHandle.writeLine("f="..T:getFacing())
  3834.         fileHandle.close()
  3835.         T:saveToLog("homeCoords.txt file created", true)
  3836.         T:saveToLog("x = "..T:getX()..", y = "..T:getY()..", z = "..T:getZ()..", f = "..T:getFacing(), false)
  3837.         print()
  3838.         print("Press esc within 2 secs to watch the action!")
  3839.         sleep(2)
  3840.     end
  3841.     if not fromFile then
  3842.         term.clear()
  3843.         term.setCursorPos(1,1)
  3844.         print("Here we go...")
  3845.         sleep(2)
  3846.         term.clear()
  3847.         term.setCursorPos(1,1)
  3848.     end
  3849. end
  3850.  
  3851. function getItemFromStorage(item, allItems)
  3852.     local success = false
  3853.     local moves = 0
  3854.     allItems = allItems or false
  3855.    
  3856.     if item == "minecraft:log" or item == "minecraft:log2" then
  3857.         moves = 2
  3858.     elseif item == "minecraft:cobblestone" or item == "minecraft:dirt"then
  3859.         moves = 4
  3860.     elseif item == "minecraft:sand" or item == "minecraft:reeds" then
  3861.         moves = 6
  3862.     elseif item == "minecraft:iron_ore" then
  3863.         moves = 8
  3864.         numIronore = 0
  3865.     elseif item == "minecraft:redstone" then
  3866.         moves = 10
  3867.     elseif item == "minecraft:diamond" then
  3868.         moves = 12
  3869.     end
  3870.     T:forward(moves)
  3871.     turtle.select(1)
  3872.     if allItems then
  3873.         while turtle.suckDown() do -- all items
  3874.             success = true
  3875.         end
  3876.         if T:getFirstEmptySlot() == 0 then
  3877.             turtle.select(T:getItemSlot("minecraft:dirt"))
  3878.             turtle.dropDown()
  3879.         end
  3880.     else
  3881.         if turtle.suckDown() then -- item removed from chest
  3882.             success = true
  3883.         end
  3884.     end
  3885.     T:go("R2F"..moves.."R2")
  3886.    
  3887.     return success
  3888. end
  3889.  
  3890. function goToWater()
  3891.     local startX = T:getX()
  3892.     local startZ = T:getZ()
  3893.     local itemSlot = 0
  3894.     local waterCollected = false
  3895.     local nearHome = true
  3896.    
  3897.     T:saveToLog("goToWater() started.", true)
  3898.     if T:getX() < water:getX() then
  3899.         while T:getFacing() ~= 3 do
  3900.             T:turnRight(1)
  3901.         end
  3902.         while T:getX() < water:getX() do
  3903.             if nearHome then
  3904.                 T:forward(5)
  3905.                 nearHome = false
  3906.             else
  3907.                 safeRun(1, "minecraft:water")
  3908.                 if T:getItemSlot("minecraft:water_bucket", -1) > 0 then
  3909.                     waterCollected = true
  3910.                     T:saveToLog("Water collected at: x="..T:getX()..", y="..T:getY()..", z="..T:getZ(),true)
  3911.                 end
  3912.                 if T:getX() < startX then --going wrong way
  3913.                     T:turnRight(2)
  3914.                 end
  3915.             end
  3916.         end
  3917.     elseif T:getX() > water:getX() then
  3918.         while T:getFacing() ~= 1 do
  3919.             T:turnRight(1)
  3920.         end
  3921.         while T:getX() > water:getX() do
  3922.             if nearHome then
  3923.                 T:forward(5)
  3924.                 nearHome = false
  3925.             else
  3926.                 safeRun(1, "minecraft:water")
  3927.                 if T:getItemSlot("minecraft:water_bucket", -1) > 0 then
  3928.                     waterCollected = true
  3929.                     T:saveToLog("Water collected at: x="..T:getX()..", y="..T:getY()..", z="..T:getZ(),true)
  3930.                 end
  3931.                 if T:getX() > startX then --going wrong way
  3932.                     T:turnRight(2)
  3933.                 end
  3934.             end
  3935.         end
  3936.     end
  3937.     if T:getZ() > water:getZ() then -- go north
  3938.         while T:getFacing() ~= 2 do
  3939.             T:turnRight(1)
  3940.         end
  3941.         while T:getZ() > water:getZ() do
  3942.             if nearHome then
  3943.                 T:forward(5)
  3944.                 nearHome = false
  3945.             else
  3946.                 safeRun(1, "minecraft:water")
  3947.                 if T:getItemSlot("minecraft:water_bucket", -1) > 0 then
  3948.                     waterCollected = true
  3949.                     T:saveToLog("Water collected at: x="..T:getX()..", y="..T:getY()..", z="..T:getZ(),true)
  3950.                 end
  3951.                 if T:getZ() > startZ then --going wrong way
  3952.                     T:turnRight(2)
  3953.                 end
  3954.             end
  3955.         end
  3956.     elseif T:getZ() < water:getZ() then
  3957.         while T:getFacing() ~= 0 do
  3958.             T:turnRight(1)
  3959.         end
  3960.         while T:getZ() < water:getZ() do
  3961.             if nearHome then
  3962.                 T:forward(5)
  3963.                 nearHome = false
  3964.             else
  3965.                 safeRun(1, "minecraft:water")
  3966.                 if T:getItemSlot("minecraft:water_bucket", -1) > 0 then
  3967.                     waterCollected = true
  3968.                     T:saveToLog("Water collected at: x="..T:getX()..", y="..T:getY()..", z="..T:getZ(),true)
  3969.                 end
  3970.                 if T:getZ() < startZ then --going wrong way
  3971.                     T:turnRight(2)
  3972.                 end
  3973.             end
  3974.         end
  3975.     end
  3976.     if not waterCollected then
  3977.         T:saveToLog("goToWater() completed: no water", true)
  3978.     else
  3979.         T:saveToLog("goToWater() completed: water collected", true)
  3980.     end
  3981. end
  3982.  
  3983. function harvestAllTrees()
  3984.     -- create a 33 x 33 square with base camp in the centre
  3985.     --      - make sure on solid ground
  3986.     --      - If wood in front harvest tree.
  3987.     --      - else if leaves in front dig then move
  3988.     --      - else any other block climb up and over
  3989.     -- move in a spiral
  3990.     local numReeds = 0
  3991.     local numSand = 0
  3992.     local numLogs = 0
  3993.     local numSaplings = 0
  3994.     local waterFound  = false
  3995.     local stockData = {}
  3996.     local doContinue = true
  3997.    
  3998.     T:saveToLog("harvestAllTrees() Starting...", true)
  3999.     harvestRun(1) -- move 1 blocks
  4000.     T:turnRight(1)
  4001.     harvestRun(1, true)
  4002.     T:turnRight(1) --now facing south, ready to continue spiral
  4003.     numArms = 32 --32 for full version 4 for testing
  4004.     for i = 2, numArms, 2 do -- 2,4,6,8...32
  4005.         if i < 5 then
  4006.             harvestRun(i, true)
  4007.         else
  4008.             harvestRun(i)
  4009.         end    
  4010.         T:turnRight(1)
  4011.         if i < 5 then
  4012.             harvestRun(i, true)
  4013.         else
  4014.             harvestRun(i)
  4015.         end
  4016.         T:turnRight(1)
  4017.         if i < 5 then
  4018.             harvestRun(i + 1, true)
  4019.         else
  4020.             harvestRun(i + 1)
  4021.         end
  4022.         T:turnRight(1) --full square completed. Can return if supplies sufficient
  4023.         if i + 1 < numArms then
  4024.             -- toDo
  4025.             -- choose point to break
  4026.             T:saveToLog("harvestAllTrees() spiral arm no: "..i, true)
  4027.             stockData = T:getStock("minecraft:reeds")
  4028.             numReeds = stockData.total
  4029.             stockData =  T:getStock("minecraft:sand")
  4030.             numSand = stockData.total
  4031.             stockData =  T:getStock("minecraft:sapling")
  4032.             numSaplings = stockData.total
  4033.             numLogs = T:getLogStock()
  4034.             waterFound = treeFarm:getWaterFound()
  4035.             T:saveToLog("reeds = "..numReeds..", sand = "..numSand..", logs = "..numLogs..", Water found = "..tostring(waterFound),true)
  4036.             print("harvestAllTrees() spiral arm no: "..i)
  4037.             if numReeds >= 3 and numSand >= 6 and numLogs >= 40 and treeFarm:getWaterFound() then
  4038.                 if (numLogs >= 30 and numSaplings >=4) or (numLogs > 60 and numSaplings == 0)then
  4039.                     doContinue = false
  4040.                     T:saveToLog("harvestAllTrees() Abandoned after "..i.." spiral arms: Supplies sufficient", true)
  4041.                     --return to starting position
  4042.                     harvestRun(i / 2)
  4043.                     T:turnRight(1)
  4044.                     harvestRun(i / 2 + 1)
  4045.                     T:turnRight(2)
  4046.                     break
  4047.                 end
  4048.             end
  4049.             if i < 2 then
  4050.                 harvestRun(i + 1, true)
  4051.             else
  4052.                 harvestRun(i + 1)
  4053.             end
  4054.             T:turnRight(1)
  4055.         else -- i + 1 >= 32 (i = 32)
  4056.             --return to starting position
  4057.             harvestRun(i / 2)
  4058.             T:turnRight(1)
  4059.             harvestRun(i / 2 + 1)
  4060.         end
  4061.     end
  4062.     if doContinue then
  4063.         T:turnRight(2)
  4064.     end
  4065. end
  4066.  
  4067. function harvestRun(runLength, digDirt)
  4068.     local itemSlot = 0
  4069.     local logType = ""
  4070.     local startFile = ""
  4071.     local success = false
  4072.     local blockType = ""
  4073.     local blockModifier
  4074.    
  4075.     turtle.select(1)
  4076.     for i = 1, runLength do
  4077.         while not turtle.inspectDown() do -- must be air below
  4078.             turtle.suckDown() --pick any saplings
  4079.             T:down(1)
  4080.         end
  4081.         blockType, blockModifier = T:getBlockType("down")
  4082.         if blockType == "minecraft:sand" then
  4083.             itemSlot, blockModifier, total = T:getItemSlot("minecraft:sand", -1)
  4084.             if total < 6 then
  4085.                 harvestSand()
  4086.             end
  4087.         elseif blockType == "minecraft:flowing_water" or blockType == "minecraft:water" then
  4088.             if blockModifier == 0 then -- source block
  4089.                 if water:getX() == 0 then -- water coords not yet found
  4090.                     --T:saveToLog("Water source found: checking suitability", true)
  4091.                     --local relX = math.abs(math.abs(T:getX()) - math.abs(coordHome:getX()))
  4092.                     --local relZ = math.abs(math.abs(T:getZ()) - math.abs(coordHome:getZ()))
  4093.                     T:saveToLog("Water found, checking suitability: x="..T:getX()..", z="..T:getZ(), true)
  4094.                     --if relX > 5 or relZ > 5 then
  4095.                         if checkWaterCoordsOK(T:getX(),T:getZ()) then
  4096.                             water:setX(T:getX())
  4097.                             water:setY(T:getY())
  4098.                             water:setZ(T:getZ())
  4099.                             water:setFacing(T:getFacing())
  4100.                             -- create/overwrite 'waterCoords.txt'
  4101.                             startFile = fs.open("waterCoords.txt", "w")
  4102.                             startFile.writeLine("x="..T:getX())
  4103.                             startFile.writeLine("y="..T:getY())
  4104.                             startFile.writeLine("z="..T:getZ())
  4105.                             startFile.close()
  4106.                             treeFarm:setWaterFound(true)
  4107.                             T:saveToLog("Water confirmed and saved to file x="..water:getX()..", y="..water:getY()..", z="..water:getZ(), true)
  4108.                         else
  4109.                             T:saveToLog("Water too close to base camp x="..water:getX()..", y="..water:getY()..", z="..water:getZ(), true)
  4110.                         end
  4111.                     --else
  4112.                         --T:saveToLog("Water found: too close to base camp (rel X="..relX..", rel Z="..relZ..")", true)
  4113.                     --end
  4114.                 end
  4115.             end
  4116.         end
  4117.         blockType, blockModifier = T:getBlockType("up")
  4118.         if  blockType == "minecraft:log" or blockType == "minecraft:log2" then
  4119.             T:back(1)
  4120.             T:harvestTree()
  4121.         end
  4122.         if digDirt and i < 5 then
  4123.             turtle.select(1)
  4124.             if T:getY() == coordHome:getY() then
  4125.                 T:dig("up")
  4126.                 T:dig("down")
  4127.             end
  4128.         end
  4129.         turtle.suck()
  4130.        
  4131.         if turtle.detect() then --can't move forward
  4132.             blockType, blockModifier = T:getBlockType("forward")
  4133.             if  blockType == "minecraft:log" then
  4134.                 T:harvestTree()
  4135.                 T:back(1)
  4136.             elseif blockType == "minecraft:reeds" then
  4137.                 T:saveToLog("Reeds found", true)
  4138.                 while  blockType == "minecraft:reeds" do -- continue loop while reeds detected in front
  4139.                     T:up(1)    -- Move up
  4140.                     blockType, blockModifier = T:getBlockType("forward")
  4141.                 end
  4142.                 -- At top of the Reeds/Sugar Cane.
  4143.                 T:forward(1)
  4144.                 -- New loop to return to ground
  4145.                 blockType, blockModifier  = T:getBlockType("down")
  4146.                 while blockType == "minecraft:reeds" do -- While sugar cane detected below
  4147.                     T:down(1)
  4148.                     blockType, blockModifier = T:getBlockType("down")
  4149.                 end
  4150.                 T:back(1)
  4151.             -- check if leaves or grass in front, dig through  
  4152.             else --any block except log or reeds
  4153.                 if T:isVegetation(blockType) then -- tallgrass,flower, vine etc
  4154.                     T:dig("forward")
  4155.                 else
  4156.                     while turtle.detect() do
  4157.                         T:up(1)
  4158.                         blockType, blockModifier = T:getBlockType("forward")
  4159.                         if T:isVegetation(blockType) then -- tallgrass,flower, vine etc
  4160.                             break
  4161.                         elseif  blockType == "minecraft:log" or blockType == "minecraft:log2" then
  4162.                             T:harvestTree()
  4163.                             T:back(1)
  4164.                             break
  4165.                         end
  4166.                     end
  4167.                 end
  4168.             end
  4169.         end
  4170.         T:forward(1)
  4171.         -- check if wood below eg tree harvest started mid - trunk
  4172.         blockType, blockModifier = T:getBlockType("down")
  4173.         while blockType == "minecraft:log" or blockType == "minecraft:log2"  do
  4174.             T:down(1)
  4175.             blockType, blockModifier = T:getBlockType("down")
  4176.         end
  4177.     end
  4178. end
  4179.  
  4180. function harvestSand()
  4181.     local depth = 0
  4182.    
  4183.     T:saveToLog("harvestSand() started", true)
  4184.     local data = T:getBlockType("down")
  4185.     while data == "minecraft:sand" do -- While sand detected below
  4186.         T:down(1)
  4187.         depth = depth - 1
  4188.         data = T:getBlockType("down")
  4189.     end
  4190.    
  4191.     while depth < 0 do
  4192.         T:up(1)
  4193.         depth = depth + 1
  4194.         T:place("minecraft:dirt", -1, "down")
  4195.     end
  4196.     T:saveToLog("harvestSand() completed", true)
  4197. end
  4198.  
  4199. function harvestAndReplant()
  4200.     if T:isValuable("forward") then -- log in front
  4201.         T:harvestTree()
  4202.     else
  4203.         turtle.select(1)
  4204.         T:forward(1) --sapling harvested if still present
  4205.     end
  4206.     itemSlot = T:getItemSlot("minecraft:sapling", -1)
  4207.     if itemSlot > 0 then -- move up, plant sapling, move forward and down
  4208.         T:up(1)
  4209.         turtle.select(itemSlot)
  4210.         turtle.placeDown()
  4211.         T:forward(1)
  4212.         T:down(1)
  4213.     else
  4214.         T:forward(1) --no sapling so simply move forward
  4215.     end
  4216. end
  4217.  
  4218. function harvestTreeFarm()
  4219.     local itemSlot = 0
  4220.    
  4221.     T:saveToLog("harvestTreeFarm() started", true)
  4222.     treeFarm:reset()
  4223.     T:go("R1F2D1")
  4224.     turtle.select(1)
  4225.     while turtle.suckDown() do  end-- get saplings from chest
  4226.     T:go("U3F3L1F2")
  4227.     harvestAndReplant()
  4228.     T:forward(1)
  4229.     harvestAndReplant()
  4230.     T:go("R1F3R1")
  4231.     harvestAndReplant()
  4232.     T:forward(1)
  4233.     harvestAndReplant()
  4234.     T:go("F2R1F6D3")
  4235.     --store any remaining saplings
  4236.     T:dropItem("minecraft:sapling", 0)
  4237.     T:go("U1F2R1")
  4238.     --get rid of any apples
  4239.     if T:getItemSlot("minecraft:apple") > 0 then
  4240.         turtle.select(T:getItemSlot("minecraft:apple"))
  4241.         turtle.drop()
  4242.     end
  4243.     treeFarm:setTimePlanted(os.time())
  4244.     saveStatus("treeFarm")
  4245.     T:saveToLog("harvestTreeFarm() completed", true)
  4246. end
  4247.  
  4248. function initialise()
  4249.     -- create classes/objects
  4250.     T = classTurtle()
  4251.     coordHome = classCoord("homeLocation")
  4252.     mineEntrance = classCoord("mineEntrance")
  4253.     water = classCoord("water")
  4254.     treeFarm = classTreeFarm()
  4255.     loadStatus("treeFarm")
  4256. end
  4257.  
  4258. function loadStatus(obj)
  4259.     local fileHandle = ""
  4260.     local strText = ""
  4261.    
  4262.     if obj == "treeFarm" then
  4263.         if fs.exists("treeFarm.txt") then
  4264.             fileHandle = fs.open("treeFarm.txt", "r")
  4265.             strText = fileHandle.readLine()
  4266.             if strText == "true" then
  4267.                 treeFarm:setPondFilled(true)
  4268.             end
  4269.             strText = fileHandle.readLine()
  4270.             if strText == "true" then
  4271.                 treeFarm:setFarmCreated(true)
  4272.             end
  4273.             strText = fileHandle.readLine()
  4274.             if strText == "true" then
  4275.                 treeFarm:setHopperPlaced(true)
  4276.             end
  4277.             strText = fileHandle.readLine()
  4278.             if strText == "true" then
  4279.                 treeFarm:setFarmFlooded(true)
  4280.             end
  4281.             strText = fileHandle.readLine()
  4282.             treeFarm:setTimePlanted(tonumber(strText))
  4283.             fileHandle.close()
  4284.         end
  4285.     else
  4286.         strText = "0"
  4287.         if fs.exists(obj) then
  4288.             fileHandle = fs.open(obj, "r")
  4289.             strText = fileHandle.readLine()
  4290.             fileHandle.close()
  4291.         end
  4292.     end
  4293.    
  4294.     return strText
  4295. end
  4296.  
  4297. function mineItem(do3D, direction) 
  4298.     local doContinue = true
  4299.     local mineIt = false
  4300.     local blockType = ""
  4301.  
  4302.     --RECURSIVE FUNCTION - BEWARE!
  4303.    
  4304.     -- check if block in front is valuable. If so mine it
  4305.     -- direction only up/down if already called recursively
  4306.     if direction == "up" then
  4307.         mineIt, blockType = T:isValuable("up")
  4308.         if mineIt then
  4309.             T:dig("up")
  4310.         end
  4311.         -- move up into space dug out
  4312.         T:up(1)
  4313.         -- check if item in front is valuable
  4314.         mineIt, blockType = T:isValuable("forward")
  4315.         if mineIt then
  4316.             mineItem(do3D, "forward")
  4317.         end
  4318.         --check right side
  4319.         T:turnRight(1)
  4320.         mineIt, blockType = T:isValuable("forward")
  4321.         if mineIt then
  4322.             mineItem(do3D, "forward")
  4323.         end
  4324.         --check behind
  4325.         T:turnRight(1)
  4326.         mineIt, blockType = T:isValuable("forward")
  4327.         if mineIt then
  4328.             mineItem(do3D, "forward")
  4329.         end
  4330.         --check left side
  4331.         T:turnRight(1)
  4332.         mineIt, blockType = T:isValuable("forward")
  4333.         if mineIt then
  4334.             mineItem(do3D, "forward")
  4335.         end
  4336.         --return to front
  4337.         T:turnRight(1)
  4338.         T:down(1)
  4339.     end
  4340.     if direction == "down" then
  4341.         mineIt, blockType = T:isValuable("down")
  4342.         if mineIt then
  4343.             turtle.select(1)
  4344.             turtle.digDown()
  4345.         end
  4346.         -- move down into space dug out
  4347.         T:down(1)
  4348.         -- check if item in front is valuable
  4349.         mineIt, blockType = T:isValuable("forward")
  4350.         if mineIt then
  4351.             mineItem(do3D, "forward")
  4352.         end
  4353.         --check right side
  4354.         T:turnRight(1)
  4355.         mineIt, blockType = T:isValuable("forward")
  4356.         if mineIt then
  4357.             mineItem(do3D, "forward")
  4358.         end
  4359.         --check behind
  4360.         T:turnRight(1)
  4361.         mineIt, blockType = T:isValuable("forward")
  4362.         if mineIt then
  4363.             mineItem(do3D, "forward")
  4364.         end
  4365.         --check left side
  4366.         T:turnRight(1)
  4367.         mineIt, blockType = T:isValuable("forward")
  4368.         if mineIt then
  4369.             mineItem(do3D, "forward")
  4370.         end
  4371.         --return to front
  4372.         T:turnRight(1)
  4373.         T:up(1)
  4374.     end
  4375.     if direction == "forward" then
  4376.         mineIt, blockType = T:isValuable("forward")
  4377.         if mineIt then
  4378.             T:forward(1)
  4379.             mineIt, blockType = T:isValuable("up")
  4380.             if mineIt then
  4381.                 if do3D then
  4382.                     mineItem(do3D, "up")
  4383.                 else
  4384.                     T:dig("up")
  4385.                 end
  4386.             end
  4387.             mineIt, blockType = T:isValuable("down")
  4388.             if mineIt then
  4389.                 if do3D then
  4390.                     mineItem(do3D, "down")
  4391.                 else
  4392.                     turtle.select(1)
  4393.                     turtle.digDown()
  4394.                 end
  4395.             end
  4396.             -- check if item in front is valuable
  4397.             mineIt, blockType = T:isValuable("forward")
  4398.             if mineIt then
  4399.                 mineItem(do3D, "forward")
  4400.             end
  4401.             --check left side
  4402.             T:turnLeft(1)
  4403.             mineIt, blockType = T:isValuable("forward")
  4404.             if mineIt then
  4405.                 mineItem(do3D, "forward")
  4406.             end
  4407.             -- check right side
  4408.             T:turnRight(2)
  4409.             mineIt, blockType = T:isValuable("forward")
  4410.             if mineIt then
  4411.                 mineItem(do3D, "forward")
  4412.             end
  4413.             T:turnLeft(1)
  4414.             T:back(1)
  4415.         end
  4416.     end
  4417. end
  4418.  
  4419. function mineToBedrock(status)
  4420.     local returnPath = ""
  4421.     local stockData = {}
  4422.     T:saveToLog("mineToBedrock() started", true)
  4423.     -- start at furnace
  4424.     T:sortInventory()
  4425.     emptyTurtle(false)
  4426.     T:forward(16)
  4427.     turtle.dig()
  4428.     if T:getItemSlot("minecraft:sign") > 0 then
  4429.         turtle.select(T:getItemSlot("minecraft:sign"))
  4430.         turtle.place("Diamond Mine\nMining for\nDiamonds\nTo Bedrock\nSector "..status)
  4431.         turtle.select(1)
  4432.     end
  4433.     mineEntrance:setX(T:getX())
  4434.     mineEntrance:setY(T:getY())
  4435.     mineEntrance:setZ(T:getZ())
  4436.     mineEntrance:setFacing(T:getFacing())
  4437.     T:turnRight(2) 
  4438.     while T:getY() > 8 do
  4439.         T:down(1)
  4440.     end
  4441.     -- now at base of shaft, above torch, level 7
  4442.     while status < 12 do -- break when status = 12 or enough diamonds are found
  4443.         stockData = T:getStock("minecraft:diamond", 0) -- check numbers
  4444.         if stockData.total >= 6 then
  4445.             break
  4446.         end
  4447.         if status <= 8 then -- no sectors mined
  4448.             returnPath = "L1U1F15L1"
  4449.             T:go("F1L1F1R1D1")
  4450.             status = 9
  4451.         elseif status <= 9 then -- lower left sector mined: do upper left
  4452.             returnPath = "L1U1F15R1F16R2"
  4453.             T:go("F17L1F1R1D1")
  4454.             status = 10
  4455.         elseif status <= 10 then -- both left sectors mined: do lower right
  4456.             returnPath = "R1U1F1R1"
  4457.             T:go("R1F15L1F1D1")
  4458.             status = 11
  4459.         elseif status <= 11 then -- both left + lower right sectors mined: do upper right
  4460.             returnPath = "U1F16R1F1R1"
  4461.             T:go("F16R1F15L1F1D1")
  4462.             status = 12
  4463.         end
  4464.         for i = 1, 4 do
  4465.             T:go("Z7U1L1F2L1F1D1Z7")
  4466.             if i < 4 then
  4467.                 T:go("U1R1F2R1F1D1") --ready for next run
  4468.             else
  4469.                 T:go(returnPath) -- return to shaft
  4470.             end
  4471.             T:dumpRefuse()
  4472.         end
  4473.     end
  4474.     -- go home
  4475.     while T:getY() < mineEntrance:getY() do
  4476.         T:up(1)
  4477.     end --at surface now
  4478.     T:forward(16)
  4479.     T:turnRight(2)
  4480.     return status
  4481. end
  4482.  
  4483. function placeStorage()
  4484.     -- Chest1 sticks
  4485.     -- Chest2 logs
  4486.     -- chest3 cobblestone
  4487.     -- chest4 sand, reeds
  4488.     -- chest5 iron ore
  4489.     -- chest6 redstone
  4490.     -- chest7 diamond
  4491.     -- chest8 dirt, misc
  4492.     -- chest9 saplings (placed right side of furnace)
  4493.  
  4494.     -- make 9 chests need 18 logs
  4495.     -- this function runs when all trees harvested locally
  4496.     T:saveToLog("placeStorage() Starting...", true)
  4497.     T:craftChests(9, false)
  4498.     --remove furnace at start
  4499.     T:go("x0R1F2D1x2H2U1R2F2R1")
  4500.     T:go("H2F1x0C2")
  4501.     for i = 2, 8 do
  4502.         T:go("F1x0H2F1x0C2")
  4503.     end
  4504.     T:go("F1x0C2R1F1x0C2R1")
  4505.     for i = 1, 14 do
  4506.         T:go("F1x0C2")
  4507.     end
  4508.     T:go("R1F2R1x0C2")
  4509.     for i = 1, 14 do
  4510.         T:go("F1x0C2")
  4511.     end
  4512.     T:go("R1F1L1R2F16R2")
  4513.     --put furnace back
  4514.     turtle.select(T:getItemSlot("minecraft:furnace"))
  4515.     turtle.placeUp()
  4516. end
  4517.  
  4518. function relocateHome()
  4519.     local numArms = 4
  4520.     local gotHome = false
  4521.     for i = 2, numArms, 2 do
  4522.         if safeRun(i, "minecraft:furnace") then --furnace found
  4523.             gotHome = true
  4524.             break
  4525.         else
  4526.             T:turnRight(1)
  4527.             if safeRun(i, "minecraft:furnace") then
  4528.                 gotHome = true
  4529.                 break
  4530.             else
  4531.                 T:turnRight(1)
  4532.                 if safeRun(i + 1, "minecraft:furnace") then
  4533.                     gotHome = true
  4534.                     break
  4535.                 else
  4536.                     T:turnRight(1)
  4537.                     if i + 1 < numArms then
  4538.                         if safeRun(i + 1, "minecraft:furnace") then
  4539.                             gotHome = true
  4540.                             break
  4541.                         else
  4542.                             T:turnRight(1)
  4543.                         end
  4544.                     else
  4545.                         --return to starting position
  4546.                         safeRun(i / 2, "minecraft:furnace")
  4547.                         T:turnRight(1)
  4548.                         safeRun(i / 2 + 1, "minecraft:furnace")
  4549.                     end
  4550.                 end
  4551.             end
  4552.         end
  4553.     end
  4554.  
  4555.     return gotHome
  4556. end
  4557.  
  4558. function returnHome()
  4559.     local startX = T:getX()
  4560.     local startZ = T:getZ()
  4561.    
  4562.     T:saveToLog("returnHome() started", true)
  4563.     if T:getX() <= coordHome:getX() then
  4564.         while T:getFacing() ~= 3 do
  4565.             T:turnRight(1)
  4566.         end
  4567.         while T:getX() < coordHome:getX() do
  4568.             safeRun(1, "minecraft:furnace")
  4569.         end
  4570.     elseif T:getX() > coordHome:getX() then -- eg -200 current -211 home
  4571.         while T:getFacing() ~= 1 do
  4572.             T:turnRight(1)
  4573.         end
  4574.         while T:getX() > coordHome:getX() do
  4575.             safeRun(1, "minecraft:furnace")
  4576.         end
  4577.     end
  4578.     if T:getZ() >= coordHome:getZ() then -- go north
  4579.         while T:getFacing() ~= 2 do
  4580.             T:turnRight(1)
  4581.         end
  4582.         while T:getZ() > coordHome:getZ() do
  4583.             safeRun(1, "minecraft:furnace")
  4584.         end
  4585.     elseif T:getZ() < coordHome:getZ() then
  4586.         while T:getFacing() ~= 0 do
  4587.             T:turnRight(1)
  4588.         end
  4589.         while T:getZ() < coordHome:getZ() do
  4590.             safeRun(1, "minecraft:furnace")
  4591.         end
  4592.     end
  4593.     while T:getFacing() ~= coordHome:getFacing() do
  4594.         T:turnRight(1)
  4595.     end
  4596.    
  4597.     if T:getBlockType("up") == "minecraft:furnace" then
  4598.         T:saveToLog("returnHome() completed", true)
  4599.         getCoords(true)
  4600.     else
  4601.         if relocateHome() then
  4602.             T:saveToLog("returnHome() completed", true)
  4603.             getCoords(true)
  4604.         else
  4605.             T:saveToLog("returnHome() failed: I am lost!", true)
  4606.             error()
  4607.         end
  4608.     end
  4609. end
  4610.  
  4611. function safeRun(runLength, actionBlock)   
  4612.     actionBlock = actionBlock or ""
  4613.     local itemSlot = 0
  4614.     local success = false
  4615.     local doContinue = true
  4616.     local blockType, modifier
  4617.     turtle.select(1)
  4618.     for i = 1, runLength do
  4619.         if actionBlock == "minecraft:furnace" then
  4620.             blockType, modifier = T:getBlockType("up")
  4621.             if blockType == "minecraft:furnace" then
  4622.                 success = true
  4623.                 doContinue = false
  4624.                 break
  4625.             end
  4626.         elseif actionBlock == "minecraft:water" then
  4627.             blockType, modifier = T:getBlockType("down")
  4628.             if blockType == "minecraft:flowing_water" or blockType == "minecraft:water" then
  4629.                 if T:getItemSlot("minecraft:bucket", -1) > 0 then --water not yet found
  4630.                     if T:place("minecraft:bucket", -1, "down") then
  4631.                         T:saveToLog("Water bucket filled x="..T:getX()..", y="..T:getY()..", z="..T:getZ(), true)
  4632.                         success = true
  4633.                     else
  4634.                         T:saveToLog("Water found, but not source block "..T:getX()..", y="..T:getY()..", z="..T:getZ(), true)
  4635.                     end
  4636.                 end
  4637.             end
  4638.         end
  4639.         if doContinue then
  4640.             if turtle.detect() then --can't move forward
  4641.                 blockType, modifier = T:getBlockType("forward")
  4642.                 if blockType == "minecraft:leaves" or blockType == "minecraft:tallgrass" or blockType == "minecraft:double_plant" then
  4643.                     turtle.dig()
  4644.                 else -- not veg so climb up
  4645.                     while turtle.detect() do
  4646.                         T:up(1)
  4647.                         blockType, modifier = T:getBlockType("forward")
  4648.                         if blockType == "minecraft:leaves"
  4649.                             or blockType == "minecraft:tallgrass"
  4650.                             or blockType == "minecraft:double_plant" then
  4651.                             turtle.dig()
  4652.                             break
  4653.                         end
  4654.                     end
  4655.                 end
  4656.             end
  4657.             T:forward(1)
  4658.             while not turtle.inspectDown() do -- must be air below
  4659.                 T:down(1)
  4660.             end
  4661.             if actionBlock == "minecraft:furnace" then
  4662.                 blockType, modifier = T:getBlockType("up")
  4663.                 if blockType == actionBlock then
  4664.                     success = true
  4665.                     break
  4666.                 end
  4667.             elseif actionBlock == "minecraft:water" then
  4668.                 blockType, modifier = T:getBlockType("down")
  4669.                 if blockType == "minecraft:flowing_water" or blockType == "minecraft:water" then
  4670.                     if T:getItemSlot("minecraft:bucket", -1) > 0 then --water not yet found
  4671.                         if T:place("minecraft:bucket", -1, "down") then
  4672.                             T:saveToLog("Water bucket filled x="..T:getX()..", y="..T:getY()..", z="..T:getZ(), true)
  4673.                             success = true
  4674.                         else
  4675.                             T:saveToLog("Water found, but not source block "..T:getX()..", y="..T:getY()..", z="..T:getZ(), true)
  4676.                         end
  4677.                     end
  4678.                 end
  4679.             end
  4680.         end
  4681.     end
  4682.    
  4683.     return success
  4684. end
  4685.  
  4686. function saveStatus(text)
  4687.     local fileHandle = ""
  4688.     T:saveToLog("Saving Status: '"..text.."'", true)
  4689.     if text == "treeFarm" then
  4690.         fileHandle = fs.open("treeFarm.txt", "w")
  4691.         fileHandle.writeLine(tostring(treeFarm:getPondFilled()))
  4692.         fileHandle.writeLine(tostring(treeFarm:getFarmCreated()))
  4693.         fileHandle.writeLine(tostring(treeFarm:getHopperPlaced()))
  4694.         fileHandle.writeLine(tostring(treeFarm:getFarmFlooded()))
  4695.         fileHandle.writeLine(tostring(treeFarm:getTimePlanted()))
  4696.     else
  4697.         -- from e.g. saveStatus("harvestFirstTree")
  4698.         fileHandle = fs.open("currentStatus.txt", "w")
  4699.         fileHandle.writeLine(text)    
  4700.     end
  4701.     fileHandle.close()
  4702. end
  4703.  
  4704. function smelt(oreType, quantity)
  4705.     --log->charcoal, iron_ore->iron, cobblestone->stone, sand->glass
  4706.     --assume function called with turtle under furnace, at ground level
  4707.     --move next to furnace to place planks
  4708.     --move to top of furnace to place wood
  4709.     --move under furnace to remove charcoal, stone, glass, iron
  4710.     T:saveToLog("smelt("..oreType..", "..quantity..") started", true)
  4711.     local smeltType = ""
  4712.     local continue = true
  4713.     local waitTime = 0
  4714.     local planksNeeded = 0 --total needed for smelting
  4715.     local woodNeeded = 0
  4716.     local woodAvailable = 0
  4717.     local success = false
  4718.     local stockData = {}
  4719.     local logData = T:getLogData() --{.total, .mostSlot, .mostCount, .mostModifier, mostName, .leastSlot, .leastCount, .leastModifier, leastName}
  4720.    
  4721.     stockData = T:getStock("minecraft:planks", -1)
  4722.     if stockData.total > 0 then
  4723.         turtle.select(stockData.mostSlot)
  4724.         turtle.refuel()
  4725.         if stockData.leastSlot ~= stockData.mostSlot then
  4726.             turtle.select(stockData.leastSlot)
  4727.             turtle.refuel()
  4728.         end
  4729.     end
  4730.     woodAvailable = logData.total
  4731.     planksNeeded = quantity
  4732.     if oreType == "minecraft:log" then
  4733.         woodNeeded = quantity + math.ceil(quantity / 4)
  4734.     end
  4735.     if woodNeeded > woodAvailable then
  4736.         getItemFromStorage("minecraft:log", false)
  4737.         logData = T:getLogData()
  4738.         woodAvailable = logData.total
  4739.     end
  4740.     T:go("B1U2F1") --now on top
  4741.    
  4742.     if oreType == "minecraft:log" or oreType == "minecraft:log2" then --eg quantity = 2, needs 2 wood + 2 planks ASSUME only called if wood in stock
  4743.         smeltType = "minecraft:coal"   
  4744.     elseif oreType == "minecraft:cobblestone"then
  4745.         smeltType = "minecraft:stone"
  4746.     elseif oreType == "minecraft:iron_ore"  then
  4747.         smeltType = "minecraft:iron_ingot"
  4748.     elseif oreType == "minecraft:sand" then
  4749.         smeltType = "minecraft:glass"
  4750.     end
  4751.     turtle.select(T:getItemSlot(oreType))
  4752.     turtle.dropDown(quantity)
  4753.     T:go("B1D1") --in front of furnace, remove any existing planks and refuel
  4754.     turtle.select(16)
  4755.     if turtle.suck() then
  4756.         turtle.refuel()
  4757.     end
  4758.     planksNeeded = math.ceil(planksNeeded / 4) * 4 --eg 1/4 = 1 ,*4 = 4 planks
  4759.     T:turnRight(1) --side on to furnace
  4760.     T:craft("minecraft:planks", planksNeeded, logData.mostName, nil, nil, false)
  4761.     T:turnLeft(1)
  4762.     turtle.select(T:getItemSlot("minecraft:planks"))
  4763.     turtle.drop() --drop planks into furnace
  4764.     T:go("D1F1") --back under furnace
  4765.     turtle.select(1)
  4766.     repeat
  4767.         waitTime = waitTime + 1
  4768.         sleep(1)
  4769.         if waitTime == 10 then --every 10 secs check if any output
  4770.             if turtle.suckUp() then --continue to wait
  4771.                 continue = true
  4772.                 waitTime = 0
  4773.             else --either no product or all done
  4774.                 continue = false
  4775.             end
  4776.         end
  4777.     until not continue
  4778.    
  4779.     if T:getItemSlot(smeltType, -1) > 0 then
  4780.         success = true
  4781.         T:saveToLog("smelt("..oreType..", "..quantity..") completed", true)
  4782.     end
  4783.     return success
  4784. end
  4785.  
  4786. function waitForTreeFarm(woodNeeded)
  4787.     local woodGrowing = 0
  4788.     local maxWood = 0
  4789.    
  4790.     if woodNeeded > 0 and treeFarm:getFarmCreated() then
  4791.         woodGrowing = treeFarm:getPotentialHarvest()
  4792.         treeFarm:getMaxHarvest()
  4793.         while woodGrowing < woodNeeded do
  4794.             sleep(10)
  4795.             -- 10 secs = 12 minecraft minutes
  4796.             -- 1  min  = 1 hour 12 minutes
  4797.             -- 20 mins = 1 minecraft day
  4798.             woodGrowing = treeFarm:getPotentialHarvest()
  4799.             --will be equal to maxHarvest after 2 days
  4800.             T:saveToLog("waiting for tree farm to grow. potential harvest = "..woodGrowing.." from "..maxWood, true)
  4801.             if woodGrowing >= maxWood then
  4802.                 break
  4803.             end
  4804.         end
  4805.         harvestTreeFarm()
  4806.     end
  4807. end
  4808.  
  4809. function main()
  4810.     local functionList = {"T:harvestFirstTree()", "harvestAllTrees()", "findCobble()", "clearBase()", "placeStorage()",
  4811.                           "createMine(14)", "createMine(11)", "createMine(8)",
  4812.                           "mineToBedrock(1/4)", "mineToBedrock(2/4)", "mineToBedrock(3/4)",
  4813.                           "mineToBedrock(4/4)", "craftMiningTurtle()"}
  4814.        
  4815.     if os.version() == "CraftOS 1.7" then
  4816.         ccComputer = "computercraft:CC-Computer"
  4817.         ccDisk = "computercraft:disk"
  4818.         ccTurtle = "computercraft:CC-Turtle"
  4819.         ccCraftyMiningTurtle = "computercraft:CC-TurtleExpanded"
  4820.         ccDiskDrive = "computercraft:CC-Peripheral"
  4821.     end
  4822.     initialise()        -- Set up global variables and create objects
  4823.     getCoords(false)            -- Get/load current coordinates from player
  4824.     local status = tonumber(loadStatus("currentStatus.txt")) -- if continuing from previous run (debugging aid)
  4825.     T:saveToLog("Starting at function "..functionList[status + 1], true)
  4826.    
  4827.     if status == 0 then
  4828.         T:harvestTree(true) -- harvest first tree and make chest
  4829.         T:saveToLog("harvestFirstTree() Completed.", true)
  4830.         status = 1
  4831.         saveStatus(tostring(status))
  4832.     end
  4833.     if status <= 1 then
  4834.         harvestAllTrees()   -- harvest remaining trees in 33 x 33 square
  4835.         T:saveToLog("harvestAllTrees() Completed.", true)
  4836.         status = 2
  4837.         saveStatus(tostring(status))
  4838.     end
  4839.     if status <= 2 then
  4840.         findCobble()        -- get cobble and any incidental coal or iron ore
  4841.         T:saveToLog("findCobble() Completed.", true)
  4842.         status = 3
  4843.         saveStatus(tostring(status))
  4844.     end
  4845.     if status <= 3 then
  4846.         clearBase()         -- create cobble base station including 2x2 pond area
  4847.         T:saveToLog("clearBase() Completed.", true)
  4848.         status = 4
  4849.         saveStatus(tostring(status))
  4850.     end
  4851.     if status <= 4 then
  4852.         placeStorage()      -- craft chests and place in ground for storage
  4853.         T:saveToLog("placeStorage() Completed.", true)
  4854.         status = 5
  4855.         saveStatus(tostring(status))
  4856.     end
  4857.     -- status 5 = no mine yet; status 6 = mined level 14/13; status 7 = mined level 11/10; status 8 = mined level 8/7
  4858.     if status <= 7 then
  4859.         status = createMine(status)     -- create basic 3 layer mine minimal structure and collect iron ore
  4860.         saveStatus(tostring(status))       
  4861.     end
  4862.     local stockData = T:getStock("minecraft:iron_ore") -- check enough iron ore found
  4863.     local numIronOre = stockData.total
  4864.     stockData = T:getStock("minecraft:diamond", 0)
  4865.     if stockData.total < 6 or numIronOre < 14 then
  4866.         if status <= 11 then
  4867.             if stockData.total < 6 then -- 3 levels mined out, need more
  4868.                 status = mineToBedrock(status) -- 4 stages: status 9, 10, 11, 12
  4869.                 saveStatus(tostring(status))
  4870.             end
  4871.         end
  4872.     end
  4873.     if status <= 12 then
  4874.         stockData = T:getStock("minecraft:diamond", 0)
  4875.         if stockData.total < 3 then
  4876.             craftMiningTurtle(0)
  4877.         elseif stockData.total < 6 then
  4878.             craftMiningTurtle(1)
  4879.         else
  4880.             craftMiningTurtle(2)
  4881.         end
  4882.     end
  4883. end
  4884.  
  4885. --*********************Program runs from here*****************
  4886. main()
Add Comment
Please, Sign In to add comment