Inksaver

Survival Toolkit v. 1 (Single file)

Jan 7th, 2017
1,543
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 118.66 KB | None | 0 0
  1. --**********Toolkit**********
  2. --http://pastebin.com/qxqdTqg8
  3. --Last edited 13/03/2020 20:46
  4. --
  5. -- classes
  6. function createCoordinatesObject(coordName)
  7.     -- 0 = go south (z increases)
  8.     -- 1 = go west  (x decreases)
  9.     -- 2 = go north (z decreases
  10.     -- 3 = go east  (x increases)
  11.  
  12.     -- compass[0] = "south"
  13.     -- compass[1] = "west"
  14.     -- compass[2] = "north"
  15.     -- compass[3] = "east"
  16.    
  17.     clsCoord = {} -- the table representing the class, which will double as the metatable for any instances
  18.     clsCoord.__index = clsCoord -- failed table lookups on the instances should fallback to the class table, to get methods
  19.  
  20.     local self = setmetatable({}, clsCoord)
  21.     self.name = coordName
  22.     self.x = 0
  23.     self.y = 0
  24.     self.z = 0
  25.     self.facing = 0
  26.     self.compass = "south"
  27.        
  28.     function clsCoord.getX(self)
  29.         return self.x
  30.     end
  31.     function clsCoord.setX(self, newVal) -- setter
  32.         self.x = newVal
  33.     end
  34.     function clsCoord.getY(self) -- getter
  35.         return self.y
  36.     end
  37.     function clsCoord.setY(self, newVal)
  38.         self.y = newVal
  39.     end
  40.     function clsCoord.getZ(self)
  41.         return self.z
  42.     end
  43.     function clsCoord.setZ(self, newVal)
  44.         self.z = newVal
  45.     end
  46.     function clsCoord.getFacing(self)
  47.         return self.facing
  48.     end
  49.     function clsCoord.setFacing(self, newVal) -- setter
  50.         self.facing = newVal
  51.         if self.facing < 0 then
  52.                 self.facing = 3
  53.         elseif self.facing > 3 then
  54.                 self.facing = 0
  55.         end
  56.         if self.facing == 0 then
  57.             self.compass = "south"
  58.         elseif self.facing == 1 then
  59.             self.compass = "west"
  60.         elseif self.facing == 2 then
  61.             self.compass = "north"
  62.         else
  63.             self.compass = "east"
  64.         end
  65.     end
  66.     function clsCoord.getCompass(self)
  67.         return self.compass
  68.     end
  69.     function clsCoord.setCompass(self, newVal) -- setter
  70.         self.compass = newVal
  71.  
  72.         if self.compass == "south" then
  73.             self.facing = 0
  74.         elseif self.compass == "west" then
  75.             self.facing = 1
  76.         elseif self.compass == "north" then
  77.             self.facing = 2
  78.         elseif self.compass == "east" then
  79.             self.facing = 3
  80.         end
  81.     end
  82.     function clsCoord.setAllValues(self, x, y, z, f)
  83.         self.x = x
  84.         self.y = y
  85.         self.z = z
  86.         clsCoord.setFacing(self, f)
  87.     end
  88.     function clsCoord.goUp(blocks)
  89.         blocks = blocks or 1
  90.         self.y = self.y + blocks
  91.     end
  92.     function clsCoord.goDown(blocks)
  93.         blocks = blocks or 1
  94.         self.y = self.y - blocks
  95.     end
  96.     --  uses:
  97.     --  location:getX()             get current turtle x coordinate
  98.     --  location:getY()             get current turtle y coordinate
  99.     --  location:getZ()             get current turtle z coordinate
  100.     --  location:setX(xCoord)       set current turtle x coordinate eg location:setX(-235)
  101.     --  location:setY(yCoord)       set current turtle y coordinate eg location:setY(66)
  102.     --  location:setZ(zCoord)       set current turtle z coordinate eg location:setZ(125)
  103.     --  location:getFacing()        returns a number 0 - 3 representing direction of player
  104.     --  location:setFacing(facing)  sets direction eg location:setFacing(1) (West)
  105.     --  location:getCompass()       returns direction as text eg "north"
  106.     --  location:setCompass("X")    sets direction using text eg location:setCompass("south")
  107.     --  location:goUp(X)            increases Y coord by X
  108.     --  location:goDown(X)          decreases Y coord by X
  109.     return self
  110. end
  111.  
  112. function createTurtleObject()  
  113.     clsTurtle = {} -- the table representing the class, which will double as the metatable for any instances
  114.     clsTurtle.__index = clsTurtle -- failed table lookups on the instances should fallback to the class table, to get methods
  115.  
  116.     local self = setmetatable({}, clsTurtle)
  117.     self.x = 0
  118.     self.y = 0
  119.     self.z = 0
  120.     self.facing = 0
  121.     self.compass = ""
  122.     self.equippedLeft = ""
  123.     self.equippedRight = ""
  124.     self.placeSlot = 0
  125.     self.placeItem = ""
  126.     self.osVersion = os.version() -- eg CraftOS 1.8
  127.    
  128.     -- helper function for iterating lists
  129.     function clsTurtle.values(self,t) -- general diy iterator
  130.         local i = 0
  131.         return function() i = i + 1; return t[i] end
  132.     end
  133.     -- logging methods
  134.     function clsTurtle.getUseLog(self)
  135.         return self.useLog
  136.     end
  137.    
  138.     function clsTurtle.setUseLog(self, use)
  139.         self.useLog = use
  140.         return use
  141.     end
  142.    
  143.     function clsTurtle.getLogExists(self)
  144.         exists = false
  145.         if fs.exists(self.logFileName) then
  146.             exists = true
  147.         end
  148.         return exists
  149.     end
  150.    
  151.     function clsTurtle.getLogFileName(self)
  152.         return self.logFileName
  153.     end
  154.     function clsTurtle.setLogFileName(self, value)
  155.         self.logFileName = value
  156.     end
  157.     function clsTurtle.getCurrentFileSize(self)    
  158.         if self.logFileExists then
  159.             return fs.getSize(self.logFileName)
  160.         else
  161.             return 0
  162.         end
  163.     end
  164.     function clsTurtle.deleteLog(self)     
  165.         if fs.exists(self.logFileName) then
  166.             fs.delete(self.logFileName)
  167.         end
  168.         self.logFileExists = false
  169.        
  170.         return true
  171.     end
  172.     function clsTurtle.appendLine(self, newText)
  173.         local handle = ""
  174.        
  175.         if fs.exists(self.logFileName) then --logFile already created
  176.             handle = fs.open(self.logFileName, "a")
  177.         else
  178.             handle = fs.open(self.logFileName, "w") --create file
  179.         end
  180.         self.logFileExists = true
  181.         handle.writeLine(newText)
  182.         handle.close()
  183.     end
  184.    
  185.     function clsTurtle.saveToLog(self, text, toScreen)
  186.         if toScreen == nil then
  187.             toScreen = true
  188.         end
  189.         if text ~= "" and text ~= nil then
  190.             if toScreen then
  191.                 print(text)
  192.             end
  193.             if self.useLog then
  194.                 clsTurtle.appendLine(self, text)
  195.             end
  196.         end
  197.     end
  198.    
  199.     -- getters and setters
  200.     function clsTurtle.getX(self) return self.x end
  201.     function clsTurtle.setX(self, newVal) self.x = newVal end
  202.     function clsTurtle.getY(self) return self.y end
  203.     function clsTurtle.setY(self, newVal) self.y = newVal end
  204.     function clsTurtle.getZ(self) return self.z end
  205.     function clsTurtle.setZ(self, newVal) self.z = newVal end
  206.     function clsTurtle.getFacing(self) return self.facing end
  207.     function clsTurtle.setFacing(self, newVal)
  208.         local direction = {"south","west","north","east"}
  209.         self.facing = newVal
  210.         if self.facing < 0 then
  211.             self.facing = 3
  212.         elseif self.facing > 3 then
  213.             self.facing = 0
  214.         end
  215.         self.compass = direction[self.facing + 1]
  216.     end
  217.     function clsTurtle.getCompass(self) return self.compass end
  218.     function clsTurtle.getPlaceItem(self) return self.placeItem end
  219.     function clsTurtle.setPlaceItem(self, item, useDamage)
  220.         local success = false
  221.         local slot = clsTurtle.getItemSlot(self, item, useDamage)
  222.         if slot > 0 then
  223.             self.placeItem = item
  224.         end
  225.     end
  226.     function clsTurtle.getEquipped(self, side)
  227.         retValue = ""
  228.         if side == "left" then
  229.             retValue = self.equippedLeft
  230.         else
  231.             retValue = self.equippedRight
  232.         end
  233.         return retValue
  234.     end
  235.     function clsTurtle.setEquipped(self, side, value)
  236.         if side == "left" then
  237.             self.equippedLeft = value
  238.         elseif side == "right" then
  239.             self.equippedRight = value
  240.         end
  241.     end
  242.    
  243.     -- change direction and movement methods
  244.     function clsTurtle.attack(self, direction) 
  245.         direction = direction or "forward"
  246.         local slot = turtle.getSelectedSlot()
  247.         turtle.select(1)
  248.         local success = false
  249.         local attackLimit = 10 -- won't get in infinite loop attacking a minecart chest
  250.  
  251.         if direction == "up" then
  252.             while turtle.attackUp() do --in case mob above
  253.                 sleep(1.5)
  254.                 attackLimit = attackLimit - 1
  255.                 if attackLimit <= 0 then
  256.                     break
  257.                 end        
  258.             end
  259.         elseif direction == "down" then
  260.             while turtle.attackDown() do --in case mob below
  261.                 sleep(1.5)
  262.                 attackLimit = attackLimit - 1
  263.                 if attackLimit <= 0 then
  264.                     break
  265.                 end
  266.             end
  267.         else
  268.             while turtle.attack() do --in case mob in front
  269.                 sleep(1.5)
  270.                 attackLimit = attackLimit - 1
  271.                 if attackLimit <= 0 then
  272.                     break
  273.                 end
  274.             end
  275.         end
  276.         if attackLimit > 0 then
  277.             success = true
  278.         end
  279.         turtle.select(slot)
  280.         return success
  281.     end
  282.    
  283.     function clsTurtle.back(self, steps)
  284.         steps = steps or 1
  285.         local success = false
  286.        
  287.         clsTurtle.refuel(self, steps)
  288.         turtle.select(1)
  289.         for i = 1, steps do
  290.             if not turtle.back() then --cant move back
  291.                 clsTurtle.turnRight(self, 2) --face backward direction
  292.                 if clsTurtle.forward(self, 1) then-- will also attack mobs if in the way
  293.                     success = true
  294.                     clsTurtle.changeCoords(self, "back")
  295.                 end
  296.                 clsTurtle.turnRight(self, 2)
  297.             end
  298.         end
  299.        
  300.         return success
  301.     end
  302.    
  303.     function clsTurtle.changeCoords(self, direction)
  304.         --  0 = go south (z increases)
  305.         --  1 = go west  (x decreases)
  306.         --  2 = go north (z decreases
  307.         --  3 = go east  (x increases)
  308.         if direction == "forward" then
  309.             if self.facing == 0 then
  310.                 self.z = self.z + 1
  311.             elseif self.facing == 1 then
  312.                 self.x = self.x - 1
  313.             elseif self.facing == 2 then
  314.                 self.z = self.z - 1
  315.             else
  316.                 self.x = self.x + 1
  317.             end
  318.         elseif direction == "back" then
  319.             if self.facing == 0 then
  320.                 self.z = self.z - 1
  321.             elseif self.facing == 1 then
  322.                 self.x = self.x + 1
  323.             elseif self.facing == 2 then
  324.                 self.z = self.z + 1
  325.             else
  326.                 self.x = self.x - 1
  327.             end
  328.         end
  329.     end
  330.    
  331.     function clsTurtle.getCoords(self, fromFile)
  332.         fromFile = fromFile or false
  333.         --get world coordinates from player
  334.         local coord = 0
  335.         local response = ""
  336.         local continue = true
  337.         local event = ""
  338.         local param1 = ""
  339.         local getInput = true
  340.        
  341.         clsTurtle.clear(self)
  342.         -- use built-in filesystem fs
  343.         if fs.exists("homeCoords.txt") then --ask user if current coords are correct
  344.             local fileHandle = fs.open("homeCoords.txt", "r")
  345.             strText = fileHandle.readLine()
  346.             self.x = tonumber(string.sub(strText, 3))
  347.             strText = fileHandle.readLine()
  348.             self.y = tonumber(string.sub(strText, 3))
  349.             strText = fileHandle.readLine()
  350.             self.z = tonumber(string.sub(strText, 3))
  351.             strText = fileHandle.readLine()
  352.             clsTurtle.setFacing(self, tonumber(string.sub(strText, 3)))
  353.             fileHandle.close()
  354.             clsTurtle.saveToLog(self, "Coordinates loaded from file:", false)
  355.             clsTurtle.saveToLog(self, "x = "..self.x..", y = "..self.y..", z = "..self.z..", f = "..self.facing, false)
  356.             print("Coordinates loaded from file:\n")
  357.             print("XYZ: - "..self.x.." / "..self.y.." / "..self.z.."\n")
  358.             print("Facing: "..self.compass)
  359.             print("\nUse F3 to check these coordinates")
  360.             write("\nAre they correct (y/n + Enter)?")
  361.             response = read()
  362.             if response == "y" or response == "" then
  363.                 getInput = false
  364.             else
  365.                 clsTurtle.clear(self)
  366.             end
  367.         end
  368.         if getInput then
  369.             print("IMPORTANT! Stand directly behind turtle")
  370.             print("Press F3 to read coordinates")
  371.             print()
  372.             continue = true
  373.             while continue do
  374.                 print("Please enter your X coordinate")
  375.                 write("  x = ")
  376.                 coord = nil
  377.                 while coord == nil do
  378.                     coord = tonumber(read())
  379.                     if coord == nil then
  380.                         clsTurtle.clear(self)
  381.                         print("Incorrect input. Use numbers only!")
  382.                         print()
  383.                         print("Please enter your X coordinate")
  384.                         write("  x = ")
  385.                     end
  386.                 end
  387.                 self.x = coord
  388.                 clsTurtle.clear(self)
  389.                 print("Please enter your Y coordinate")
  390.                 write("  y = ")
  391.                 coord = nil
  392.                 while coord == nil do
  393.                     coord = tonumber(read())
  394.                     if coord == nil then
  395.                         clsTurtle.clear(self)
  396.                         print("Incorrect input. Use numbers only")
  397.                         print()
  398.                         print("Please enter your y coordinate")
  399.                         write("  y = ")
  400.                     end
  401.                 end
  402.                 self.y = coord
  403.                 clsTurtle.clear(self)
  404.                 print("Please enter your Z coordinate")
  405.                 write("  z = ")
  406.                 coord = nil
  407.                 while coord == nil do
  408.                     coord = tonumber(read())
  409.                     if coord == nil then
  410.                         clsTurtle.clear(self)
  411.                         print("Incorrect input. Use numbers only")
  412.                         print()
  413.                         print("Please enter your z coordinate")
  414.                         write("  z = ")
  415.                     end
  416.                 end
  417.                 self.z = coord
  418.                 response = true
  419.                 while response do
  420.                     response = false
  421.                     clsTurtle.clear(self)
  422.                     print("Enter Direction you are facing:")
  423.                     print("  0,1,2,3 (s,w,n,e)")
  424.                     print()
  425.                     print(  "  Direction = ")
  426.                     event, param1 = os.pullEvent ("char")
  427.                     if param1 == "s" or param1 == "S" then
  428.                         coord = 0
  429.                     elseif param1 == "w" or param1 == "W" then
  430.                         coord = 1
  431.                     elseif param1 == "n" or param1 == "N" then
  432.                         coord = 2
  433.                     elseif param1 == "e" or param1 == "E" then
  434.                         coord = 3
  435.                     elseif param1 == "0" or param1 == "1" or param1 == "2" or param1 == "3" then
  436.                         coord = tonumber(param1)
  437.                     else
  438.                         print()
  439.                         print("Incorrect input: "..param1)
  440.                         print()
  441.                         print("Use 0,1,2,3,n,s,w,e")
  442.                         sleep(2)
  443.                         response = true
  444.                     end
  445.                 end
  446.                 clsTurtle.setFacing(self, coord)
  447.                 clsTurtle.clear(self)
  448.                 print("Your current location is:")
  449.                 print()
  450.                 print("  x = "..self.x)
  451.                 print("  y = "..self.y)
  452.                 print("  z = "..self.z)
  453.                 print("  facing "..self.compass.." ("..self.facing..")")
  454.                 print()
  455.                 write("Is this correct? (y/n)")
  456.                 event, param1 = os.pullEvent ("char")
  457.                 if param1 == "y" or param1 == "Y" then
  458.                     continue = false
  459.                 end
  460.             end
  461.             -- correct coords to compensate for player standing position
  462.             -- First tree is considered as point zero, on startup, turtle is in front of this tree
  463.             -- Player is behind turtle, use 2 blocks to compensate
  464.             -- facing:      Change:
  465.             -- 0 (S)        z+1
  466.             -- 1 (W)        x-1
  467.             -- 2 (N)        z-1
  468.             -- 3 (E)        x+1
  469.             if self.facing == 0 then
  470.                 self.z = self.z + 2
  471.             elseif self.facing == 1 then
  472.                 self.x = self.x - 2
  473.             elseif self.facing == 2 then
  474.                 self.z = self.z - 2
  475.             elseif self.facing == 3 then
  476.                 self.x = self.x + 2
  477.             end
  478.            
  479.             -- create/overwrite 'homeCoords.txt'
  480.             local fileHandle = fs.open("homeCoords.txt", "w")
  481.             fileHandle.writeLine("x="..self.x)
  482.             fileHandle.writeLine("y="..self.y)
  483.             fileHandle.writeLine("z="..self.z)
  484.             fileHandle.writeLine("f="..self.facing)
  485.             fileHandle.close()
  486.             clsTurtle.saveToLog(self, "homeCoords.txt file created", true)
  487.             clsTurtle.saveToLog(self, "x = "..T:getX()..", y = "..T:getY()..", z = "..T:getZ()..", f = "..T:getFacing(), false)
  488.         end
  489.     end
  490.  
  491.     function clsTurtle.down(self, steps, checkDungeon)
  492.         steps = steps or 1
  493.         if checkDungeon == nil then
  494.             checkDungeon = false
  495.         end
  496.         local success = false
  497.        
  498.         clsTurtle.refuel(self, steps)
  499.         turtle.select(1)
  500.         for i = 1, steps do
  501.             if turtle.detectDown() then -- block below
  502.                 if checkDungeon then
  503.                     if clsTurtle.isDungeon(self, "down") then
  504.                         clsTurtle.writeCoords(self, "DungeonCoords.txt")
  505.                         print("Mossy cobblestone found")
  506.                         error()
  507.                     end
  508.                 end
  509.                 if clsTurtle.getBlockType(self, "down") == "minecraft:bedrock" then
  510.                     break
  511.                 else
  512.                     turtle.digDown()
  513.                 end
  514.             end
  515.             if turtle.down() then --move down unless mob in the way
  516.                 success = true
  517.             else -- not bedrock, could be mob or minecart
  518.                 if clsTurtle.attack(self, "down") then -- attack succeeded
  519.                     if turtle.down() then
  520.                         success = true
  521.                     end
  522.                 end
  523.             end
  524.             if success then
  525.                 self.y = self.y - 1
  526.             end
  527.         end
  528.        
  529.         return success
  530.     end
  531.    
  532.     function clsTurtle.forward(self, steps, checkDungeon)    
  533.         steps = steps or 1
  534.         if checkDungeon == nil then
  535.             checkDungeon = false
  536.         end
  537.         local result, data
  538.         local success = true
  539.         local retryMove = 10
  540.        
  541.         clsTurtle.refuel(self, steps)
  542.         turtle.select(1)
  543.         for i = 1, steps do
  544.             while turtle.detect() do -- allow for sand/gravel falling
  545.                 if checkDungeon then
  546.                     if clsTurtle.isDungeon(self, "forward") then
  547.                         clsTurtle.writeCoords(self, "DungeonCoords.txt")
  548.                         print("Mossy cobblestone found")
  549.                         error()
  550.                     end
  551.                 end
  552.                 if not clsTurtle.dig(self, "forward") then-- cannot dig. either bedrock or in server protected area
  553.                     success = false
  554.                     if clsTurtle.getBlockType(self, "forward") == "minecraft:bedrock" then
  555.                         print("Bedrock in front:function exit")
  556.                     end
  557.                     break
  558.                 end
  559.             end
  560.             success = false
  561.             if turtle.forward() then
  562.                 success = true
  563.             else
  564.                 if self.mobAttack then
  565.                     if clsTurtle.attack(self, "forward") then
  566.                         if turtle.forward() then
  567.                             success = true
  568.                         end
  569.                     else               
  570.                         result, data = turtle.forward()
  571.                         print(data..":function exit")
  572.                         break
  573.                     end
  574.                 else
  575.                     while not turtle.forward() do
  576.                         clsTurtle.saveToLog(self, "Waiting for mob to leave...", true)
  577.                         sleep(5)
  578.                         retryMove = retryMove - 1
  579.                         if retryMove <= 0 then
  580.                             break
  581.                         end
  582.                     end
  583.                     if retryMove  <= 0 then
  584.                         if clsTurtle.attack(self, "forward") then
  585.                             if turtle.forward() then
  586.                                 success = true
  587.                             end
  588.                         else               
  589.                             result, data = turtle.forward()
  590.                             print(data..":function exit")
  591.                             break
  592.                         end
  593.                     end
  594.                 end
  595.             end
  596.             if success then
  597.                 clsTurtle.changeCoords(self, "forward")
  598.             end
  599.         end
  600.         return success
  601.     end
  602.    
  603.     function clsTurtle.turnLeft(self, steps)
  604.         steps = steps or 1
  605.         for i = 1, steps do
  606.             turtle.turnLeft()
  607.             self.facing = self.facing - 1
  608.             if self.facing < 0 then
  609.                 self.facing = 3
  610.             end
  611.         end
  612.     end
  613.  
  614.     function clsTurtle.turnRight(self, steps)
  615.         steps = steps or 1
  616.         for i = 1, steps do
  617.             turtle.turnRight()
  618.             self.facing = self.facing + 1
  619.             if self.facing > 3 then
  620.                 self.facing = 0
  621.             end
  622.         end
  623.     end
  624.    
  625.     function clsTurtle.up(self, steps, checkDungeon)
  626.         steps = steps or 1
  627.         if checkDungeon == nil then
  628.             checkDungeon = false
  629.         end
  630.         local success = false
  631.         clsTurtle.refuel(self, steps)
  632.         turtle.select(1)
  633.  
  634.         for i = 1, steps do
  635.             if turtle.detectUp() then -- block above
  636.                 if checkDungeon then
  637.                     if clsTurtle.isDungeon(self, "up") then
  638.                         clsTurtle.writeCoords(self, "DungeonCoords.txt")
  639.                         print("Mossy cobblestone found")
  640.                         error()
  641.                     end
  642.                 end
  643.                 if clsTurtle.getBlockType(self, "up") == "minecraft:bedrock" then
  644.                     print("Bedrock above:function exit")
  645.                     break
  646.                 else
  647.                     clsTurtle.dig(self, "up")
  648.                 end
  649.             end
  650.             if turtle.up() then  --move up unless mob in the way
  651.                 success = true
  652.             else
  653.                 if clsTurtle.attack(self, "up") then -- attack succeeded
  654.                     if turtle.up() then
  655.                         success = true
  656.                     end
  657.                 end
  658.             end
  659.             if success then
  660.                 self.y = self.y + 1
  661.             end
  662.         end
  663.         return success
  664.     end
  665.     -- other methods
  666.     function clsTurtle.checkInventoryForItem(self, items, quantity, required)
  667.         if required == nil then
  668.             required = true
  669.         end
  670.         local isLog = false
  671.         local isStone = false
  672.         local userChoice = false
  673.         local damage = 0
  674.         for i = 1, #items do
  675.             if items[i] == "minecraft:log" then
  676.                 isLog = true
  677.             end
  678.             if items[i] == "minecraft:stone" then
  679.                 isStone = true
  680.             end
  681.             if items[i] == "userChoice" then
  682.                 userChoice = true
  683.             end
  684.         end
  685.         -- item = {"minecraft:planks", "minecraft:log", "mineraft:lava_bucket"}
  686.         -- quantity = {4, 1, 1}
  687.         local retValue = ""
  688.         local event = ""
  689.         local param1 = ""
  690.         local numOnboard = 0
  691.         local waiting = true
  692.         local index = 0
  693.         -- allow 1 user choice of block
  694.         while waiting do
  695.             if userChoice then
  696.                 index = 1
  697.                 numOnboard = 0
  698.                 print("Add your choice of block to any slot")
  699.                 for i = 1, 16 do
  700.                     if turtle.getItemCount(i) > 0 then
  701.                         numOnboard, retValue, damage = clsTurtle.getSlotContains(self, i)
  702.                        
  703.                         break
  704.                     end
  705.                 end
  706.             else
  707.                 index, retValue, numOnboard = clsTurtle.checkInventory(self, items, quantity, required, isLog, isStone)
  708.             end
  709.             if numOnboard >= quantity[index] then
  710.                 break
  711.             else
  712.                 event, param1 = os.pullEvent ()
  713.                 if event == "turtle_inventory" then
  714.                     if userChoice then
  715.                         -- find first item on board
  716.                         for i = 1, 16 do
  717.                             if turtle.getItemCount(i) > 0 then
  718.                                 numOnboard, retValue, damage = clsTurtle.getSlotContains(self, i)
  719.                                 break
  720.                             end
  721.                         end
  722.                     else
  723.                         index, retValue, numOnboard = clsTurtle.checkInventory(self, items, quantity, required, isLog, isStone)
  724.                         -- check for log2
  725.                         if numOnboard >= quantity[index] then
  726.                             break
  727.                         end
  728.                     end
  729.                 elseif event == "key"  and not required then
  730.                     if param1 == keys.enter then
  731.                         break
  732.                     end
  733.                 end
  734.             end
  735.         end
  736.         if retValue ~= "" then
  737.             if retValue == "minecraft:lava_bucket" then
  738.                 clsTurtle.refuel(self, 0)
  739.                 clsTurtle.dropItem(self, "minecraft:bucket", 0, "up")
  740.             else
  741.                 print(retValue.." accepted with thanks")
  742.             end
  743.             sleep(1.5)
  744.         end
  745.         return retValue
  746.     end
  747.    
  748.     function clsTurtle.checkInventory(self, items, quantity, required, isLog, isStone)
  749.         -- items are a list of related items eg lava_bucket, coal, planks
  750.         -- quantity is a matching list of quantities eg 1, 13, 64(1000 fuel)
  751.         local gotItemSlot = 0
  752.         local damage = 0
  753.         local count = 0
  754.         local retValue = ""
  755.         local index = 0
  756.         clsTurtle.clear(self)
  757.         for i = 1, #items do
  758.             index = i
  759.             gotItemSlot, damage, count = clsTurtle.getItemSlot(self, items[i]) -- 0 if not present return slot, damage, total
  760.             if gotItemSlot > 0 then --an item has been found, quantity is total onboard
  761.                 if count >= quantity[i] then
  762.                     retValue = items[i]
  763.                     break
  764.                 end
  765.             else
  766.                 if isLog then
  767.                     gotItemSlot, damage, count = clsTurtle.getItemSlot(self, "minecraft:log2") -- 0 if not present return slot, damage, total
  768.                     if gotItemSlot > 0 then
  769.                         retValue = "minecraft:log2"
  770.                         break
  771.                     end
  772.                 end
  773.             end
  774.             if i == 1 then
  775.                 if isStone then
  776.                     print("Add "..quantity[1] - count.." granite / andesite / diorite")
  777.                     print("(polished preferred) to any slot")
  778.                 else
  779.                     print("Add "..quantity[1] - count.." "..items[1].." to any slot(s) ")
  780.                 end
  781.             else
  782.                 print("Or add "..quantity[i] - count.." "..items[i].." to any slot(s) ")
  783.             end
  784.             if not required then
  785.                 print("(This item is not required)\n")
  786.                 if i == #items then
  787.                     print("Hit Enter to continue..")
  788.                 end
  789.             end
  790.            
  791.         end
  792.         return index, retValue, count
  793.     end
  794.    
  795.     function clsTurtle.clear(self)
  796.         term.clear()
  797.         term.setCursorPos(1,1)
  798.     end
  799.    
  800.     function clsTurtle.craft(self, item, quantity) 
  801.         local slot = turtle.getSelectedSlot()
  802.         local craftOK = false
  803.         local chestSlot = 0
  804.         local holeSlot = 0
  805.         local sourceSlot = 0
  806.         local turns = 0
  807.         local doContinue = true
  808.        
  809.         chestSlot = clsTurtle.getItemSlot(self, "minecraft:chest") --get the slot number containing a chest
  810.         if chestSlot == 0 then -- chest not found
  811.             -- digDown, drop all items into hole, then re-equip later
  812.             holeSlot = clsTurtle.getFirstEmptySlot(self)
  813.             turtle.select(holeSlot)
  814.             turtle.digDown()
  815.             turtle.dropDown()
  816.         end
  817.         if item == "minecraft:planks" then
  818.             sourceSlot = clsTurtle.getItemSlot(self,"minecraft:log") --get the slot number containing 1 or more logs
  819.             if sourceSlot == 0 then
  820.                 sourceSlot = clsTurtle.getItemSlot(self,"minecraft:log2") --get the slot number containing 1 or more logs2
  821.                 if sourceSlot == 0 then
  822.                     doContinue = false
  823.                 end
  824.             end
  825.         elseif item == "minecraft:chest" then
  826.             sourceSlot = clsTurtle.getItemSlot(self, "minecraft:planks") --get the slot number containing planks
  827.         elseif item == "minecraft:stone_stairs" then
  828.             sourceSlot = clsTurtle.getItemSlot(self, "minecraft:cobblestone") --get the slot number containing cobble
  829.         end
  830.         if doContinue then
  831.             if chestSlot > 0 then
  832.                 while turtle.detect() do --check for clear space to place chest
  833.                     clsTurtle.turnRight(self, 1)
  834.                     turns = turns + 1
  835.                     if turns == 4 then
  836.                         turns = 0
  837.                         break
  838.                     end
  839.                 end
  840.  
  841.                 turtle.select(1)
  842.                 while turtle.detect() do --clear space in front. Use loop in case of sand/gravel falling
  843.                     turtle.dig()
  844.                     sleep(.5)
  845.                 end
  846.                 turtle.select(chestSlot) --should be slot with chest
  847.                 while not turtle.place() do
  848.                     clsTurtle.attack(self)
  849.                 end
  850.             end
  851.             -- fill chest with everything except required items
  852.             for i = 1, 16 do
  853.                 if i ~= sourceSlot then
  854.                     turtle.select(i)
  855.                     if chestSlot > 0 then
  856.                         turtle.drop()
  857.                     else
  858.                         turtle.dropDown()
  859.                     end
  860.                 end
  861.             end
  862.  
  863.             turtle.select(sourceSlot)
  864.             turtle.transferTo(16) --move crafting item to 16
  865.             --ready to craft
  866.             turtle.select(16)
  867.             if item == "minecraft:planks" then -- crafting planks
  868.                 turtle.transferTo(1, quantity / 4)
  869.                 turtle.select(16)
  870.                 if chestSlot > 0 then --drop remaining resources before crafting
  871.                     turtle.drop()
  872.                 else
  873.                     turtle.dropDown()
  874.                 end
  875.             elseif item == "minecraft:chest" then  --T:craft("minecraft:chest", 1)
  876.                 --8 planks = 1 chest
  877.                 turtle.transferTo(1, 1)
  878.                 turtle.transferTo(2, 1)
  879.                 turtle.transferTo(3, 1)
  880.                 turtle.transferTo(5, 1)
  881.                 turtle.transferTo(7, 1)
  882.                 turtle.transferTo(9, 1)
  883.                 turtle.transferTo(10, 1)
  884.                 turtle.transferTo(11, 1)
  885.             elseif item == "minecraft:stone_stairs" then  --T:craft("minecraft:stone_stairs", 40)
  886.                 --6 cobblestone = 4 stairs
  887.                 turtle.transferTo(1, quantity / 4)
  888.                 turtle.transferTo(5, quantity / 4)
  889.                 turtle.transferTo(6, quantity / 4)
  890.                 turtle.transferTo(9, quantity / 4)
  891.                 turtle.transferTo(10, quantity / 4)
  892.                 turtle.transferTo(11, quantity / 4)
  893.             end
  894.             -- Attempt to craft item into slot 16
  895.             turtle.select(16)
  896.             if chestSlot > 0 then
  897.                 turtle.drop()
  898.             else
  899.                 turtle.dropDown()
  900.             end
  901.             if turtle.craft() then
  902.                 craftOK = true
  903.                 --now put crafted item in chest first, so will mix with any existing similar items
  904.                 if chestSlot > 0 then
  905.                     turtle.drop()
  906.                 end
  907.             else --crafting not successful, so empty out all items into chest
  908.                 for i = 1, 16 do
  909.                     if turtle.getItemCount(i) > 0 then
  910.                         turtle.select(i)
  911.                         if chestSlot > 0 then
  912.                             turtle.drop()
  913.                         else
  914.                             turtle.dropDown()
  915.                         end
  916.                     end
  917.                 end
  918.             end
  919.             turtle.select(1) --empty chest into slot 1 onwards
  920.             if chestSlot > 0 then
  921.                 while turtle.suck() do end
  922.                 turtle.dig() -- collect chest
  923.                 if turns > 0 then --return to original position
  924.                     clsTurtle.turnLeft(self,turns)
  925.                 end
  926.             else
  927.                 while turtle.suckUp() do end
  928.                 while turtle.suckDown() do end
  929.                 for i = 1, 4 do
  930.                     while turtle.suck() do end
  931.                     clsTurtle.turnRight(self, 1)
  932.                 end
  933.                 clsTurtle.place(self, "minecraft:dirt", -1, "down")
  934.             end
  935.         end
  936.        
  937.         turtle.select(slot)
  938.         return craftOK
  939.     end
  940.    
  941.     function clsTurtle.createTunnel(self, length, allowAbandon, checkDungeon)
  942.         if checkDungeon == nil then
  943.             checkDungeon = true
  944.         end
  945.         -- clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, checkDungeon)
  946.         -- assume at floor level at start
  947.         local leaveExisting = true
  948.         local useTorch = false
  949.         local distance  = 1
  950.         local blockAbove = ""
  951.         local aboveType = 0
  952.         local blockBelow = ""
  953.         local belowType = 0
  954.         local waterCountAbove = 0
  955.         local waterCountBelow = 0
  956.         local onGround = true
  957.         for i = 1, length do
  958.             if onGround then -- 1, 3, 5, 7 etc
  959.                 blockBelow, belowType = clsTurtle.getBlockType(self, "down")
  960.                 if blockBelow == "minecraft:lava" then
  961.                     clsTurtle.go(self, "C2L1C1R2C1L1", useTorch, 0, leaveExisting, checkDungeon)
  962.                 elseif blockBelow == "minecraft:water" then
  963.                     clsTurtle.go(self, "C2", useTorch, 0, leaveExisting, checkDungeon)
  964.                     waterCountBelow = waterCountBelow + 1
  965.                 else
  966.                     clsTurtle.go(self, "C2", useTorch, 0, leaveExisting, checkDungeon)
  967.                 end
  968.                 clsTurtle.up(self, 1, checkDungeon)
  969.                 onGround = false
  970.                 blockAbove, aboveType = clsTurtle.getBlockType(self, "up")
  971.                 if blockAbove == "minecraft:lava" then
  972.                     clsTurtle.go(self, "C0L1C1R2C1L1", useTorch, 0, leaveExisting, checkDungeon)
  973.                 elseif blockAbove == "minecraft:water" then
  974.                     clsTurtle.go(self, "C0L1C1R2C1L1", useTorch, 0, leaveExisting, checkDungeon)
  975.                     waterCountAbove = waterCountAbove + 1
  976.                 else
  977.                     clsTurtle.go(self, "C0", useTorch, 0, leaveExisting, checkDungeon)
  978.                 end
  979.                 -- if on first block check behind
  980.                 if i == 1 then
  981.                     clsTurtle.go(self, "R2C1R2", useTorch, 0, leaveExisting, checkDungeon)
  982.                 end
  983.                 if distance >= 8 then
  984.                     if distance % 8 == 0 then -- 8th or other position
  985.                         clsTurtle.go(self, "t5", useTorch, 0, false, checkDungeon)
  986.                     end
  987.                 end
  988.             else -- at ceiling 2, 4, 6, 8 etc
  989.                 blockAbove, aboveType = clsTurtle.getBlockType(self, "up")
  990.                 if blockAbove == "minecraft:lava" then
  991.                     clsTurtle.go(self, "C0L1C1R2C1L1", useTorch, 0, leaveExisting, checkDungeon)
  992.                 elseif blockAbove == "minecraft:water" then
  993.                     clsTurtle.go(self, "C0L1C1R2C1L1", useTorch, 0, leaveExisting, checkDungeon)
  994.                     waterCountAbove = waterCountAbove + 1
  995.                 else
  996.                     clsTurtle.go(self, "C0", useTorch, 0, leaveExisting, checkDungeon)
  997.                 end
  998.                 if distance == 2 then
  999.                     clsTurtle.go(self, "t1", useTorch, 0, false, checkDungeon)
  1000.                 end
  1001.                 clsTurtle.down(self, 1, checkDungeon)
  1002.                 onGround = true
  1003.                 blockBelow, belowType = clsTurtle.getBlockType(self, "down")
  1004.                 if blockBelow == "minecraft:lava" then
  1005.                     clsTurtle.go(self, "C2L1C1R2C1L1", useTorch, 0, leaveExisting, checkDungeon)
  1006.                 elseif blockBelow == "minecraft:water" then
  1007.                     clsTurtle.go(self, "C2", useTorch, 0, leaveExisting, checkDungeon)
  1008.                     waterCountBelow = waterCountBelow + 1
  1009.                 else
  1010.                     clsTurtle.go(self, "C2", useTorch, 0, leaveExisting, checkDungeon)
  1011.                 end
  1012.             end
  1013.             -- now move forward if length > 1
  1014.             if length > 1 then
  1015.                 if i < length then -- not on last iteration
  1016.                     clsTurtle.forward(self,1, checkDungeon)
  1017.                     distance = distance + 1
  1018.                 else -- on last iteration
  1019.                     if not onGround then
  1020.                         clsTurtle.go(self, "C1", useTorch, 0, leaveExisting, checkDungeon)
  1021.                         clsTurtle.down(self, 1, checkDungeon)
  1022.                         onGround = true
  1023.                     end
  1024.                 end
  1025.             else -- one unit only so move down
  1026.                 clsTurtle.down(self, 1, checkDungeon)
  1027.                 onGround = true
  1028.             end
  1029.            
  1030.             if allowAbandon then
  1031.                 if waterCountAbove + waterCountBelow >= 6 then
  1032.                     if not onGround then
  1033.                         clsTurtle.down(self, 1, checkDungeon)
  1034.                         onGround = true
  1035.                     end
  1036.                     break
  1037.                 end
  1038.             end
  1039.         end
  1040.        
  1041.         return distance -- 1 to length. cut short if 3 or more water
  1042.     end
  1043.    
  1044.     function clsTurtle.detect(self, direction)
  1045.         direction = direction or "forward"
  1046.         result = false
  1047.         if direction == "forward" then
  1048.             result = turtle.detect()
  1049.         elseif direction == "up" then
  1050.             result = turtle.detectUp()
  1051.         else -- down
  1052.             result = turtle.detectDown()
  1053.         end
  1054.         return result
  1055.     end
  1056.    
  1057.     function clsTurtle.dig(self, direction)
  1058.         direction = direction or "forward"
  1059.         local success = false
  1060.         turtle.select(1)
  1061.         if direction == "up" then
  1062.             while turtle.digUp() do
  1063.                 sleep(0.7)
  1064.                 success = true
  1065.             end
  1066.         elseif direction == "down" then
  1067.             if turtle.digDown() then
  1068.                 success = true
  1069.             end
  1070.         else -- forward by default
  1071.             while turtle.dig() do
  1072.                 sleep(0.7)
  1073.                 success = true
  1074.             end
  1075.         end
  1076.         return success
  1077.     end
  1078.    
  1079.     function clsTurtle.drop(self, slot, direction, amount)
  1080.         direction = direction or "forward"
  1081.         turtle.select(slot)
  1082.         local success = false
  1083.         if direction == "up" then
  1084.             if amount == nil then
  1085.                 if turtle.dropUp() then
  1086.                     success = true
  1087.                 end
  1088.             else
  1089.                 if turtle.dropUp(amount) then
  1090.                     success = true
  1091.                 end
  1092.             end
  1093.         elseif direction == "down" then
  1094.             if amount == nil then
  1095.                 if turtle.dropDown() then
  1096.                     success = true
  1097.                 end
  1098.             else
  1099.                 if turtle.dropDown(amount) then
  1100.                     success = true
  1101.                 end
  1102.             end
  1103.         else
  1104.             if amount == nil then
  1105.                 if turtle.drop() then
  1106.                     success = true
  1107.                 end
  1108.             else
  1109.                 if turtle.drop(amount) then
  1110.                     success = true
  1111.                 end
  1112.             end
  1113.         end
  1114.         return success
  1115.     end
  1116.    
  1117.     function clsTurtle.dropItem(self, item, keepAmount, direction)
  1118.         keepAmount = keepAmount or 0
  1119.         direction = direction or "down"
  1120.         local itemSlot = 0
  1121.         local stockData = {}
  1122.        
  1123.         if keepAmount <= 0 then -- drop everything
  1124.             itemSlot = clsTurtle.getItemSlot(self, item)
  1125.             while itemSlot > 0 do
  1126.                 clsTurtle.drop(self, itemSlot, direction)
  1127.                 itemSlot = clsTurtle.getItemSlot(self, item)
  1128.             end
  1129.         elseif keepAmount >= 64 then -- drop everything else
  1130.             stockData = clsTurtle.getStock(self, item)
  1131.             if item == "minecraft:log" then
  1132.                 if stockData.mostSlot ~= stockData.leastSlot then
  1133.                     clsTurtle.drop(self, stockData.leastSlot, direction)
  1134.                 end
  1135.             else
  1136.                 while stockData.total > keepAmount do
  1137.                     if stockData.mostSlot ~= stockData.leastSlot then
  1138.                         clsTurtle.drop(self, stockData.leastSlot, direction)
  1139.                     else --only one slot but more than required in it
  1140.                         clsTurtle.drop(self, stockData.mostSlot, direction)
  1141.                     end
  1142.                     stockData = clsTurtle.getStock(self, item)
  1143.                 end
  1144.             end
  1145.         else --store specific amount
  1146.             itemSlot = clsTurtle.getItemSlot(self, item)
  1147.             local dropCount = turtle.getItemCount(itemSlot) - keepAmount
  1148.             if itemSlot > 0 then
  1149.                 clsTurtle.drop(self, itemSlot, direction, dropCount)
  1150.             end
  1151.         end
  1152.     end
  1153.    
  1154.     function clsTurtle.dumpRefuse(self, keepCobbleStacks)
  1155.         --dump dirt, cobble, sand, gravel
  1156.         keepCobbleStacks = keepCobbleStacks or 0
  1157.         local itemlist = {}
  1158.         local blockType = ""
  1159.         local blockModifier
  1160.         local slotCount
  1161.         local cobbleCount = 0
  1162.         local dirtCount = 0
  1163.  
  1164.         itemlist[1] = "minecraft:gravel"
  1165.         itemlist[2] = "minecraft:stone"
  1166.         itemlist[3] = "minecraft:sand"
  1167.         itemlist[4] = "minecraft:flint"
  1168.         for x = 1, 15 do -- sort inventory
  1169.             for i = x + 1 , 16 do
  1170.                 if turtle.getItemCount(i) > 0 then
  1171.                     turtle.select(i)
  1172.                     if turtle.compareTo(x) then
  1173.                         turtle.transferTo(x)
  1174.                     end
  1175.                 end
  1176.             end
  1177.         end
  1178.         for i = 1, 16 do
  1179.             slotCount, blockType, blockModifier = clsTurtle.getSlotContains(self,i)
  1180.            
  1181.             if blockType == "minecraft:cobblestone" then
  1182.                 if cobbleCount > keepCobbleStacks then
  1183.                     turtle.select(i)
  1184.                     turtle.drop()
  1185.                 else
  1186.                     cobbleCount = cobbleCount + 1
  1187.                 end
  1188.             end
  1189.             if blockType == "minecraft:dirt" then
  1190.                 if dirtCount > 0 then
  1191.                     turtle.select(i)
  1192.                     turtle.drop()
  1193.                 else
  1194.                     dirtCount = dirtCount + 1
  1195.                 end
  1196.             end
  1197.             for j = 1, #itemlist do
  1198.                 if blockType == itemlist[j] then
  1199.                     turtle.select(i)
  1200.                     turtle.drop()
  1201.                     break
  1202.                 end
  1203.             end
  1204.         end
  1205.         turtle.select(1)
  1206.     end
  1207.    
  1208.     function clsTurtle.emptyTrash(self, direction)
  1209.         direction = direction or "down"
  1210.         local slotData = {}
  1211.         local item = ""
  1212.         local move = false
  1213.         local keepItems = {"minecraft:cobblestone", "minecraft:redstone", "minecraft:sand", "minecraft:planks",
  1214.                             "minecraft:chest", "minecraft:log", "minecraft:log2", "minecraft:iron_ore", "minecraft:reeds", "minecraft:sapling",
  1215.                             "minecraft:bucket", "minecraft:lava_bucket", "minecraft:water_bucket", "minecraft:torch", "minecraft:diamond",
  1216.                             "minecraft:coal", "minecraft:iron_ingot"}
  1217.                            
  1218.         local keepit = false                   
  1219.         -- empty excess cobble, dirt, all gravel, unknown minerals
  1220.         --keep max of 1 stack
  1221.         clsTurtle.sortInventory(self)
  1222.         if direction == "down" then
  1223.             if clsTurtle.down(self, 1) then
  1224.                 move = true
  1225.             end
  1226.         end
  1227.         for i = 1, 16 do
  1228.             keepit = false
  1229.             if turtle.getItemCount(i) > 0 then
  1230.                 item = clsTurtle.getItemName(self, i)
  1231.                 for _,v in pairs(keepItems) do
  1232.                     if v == item then
  1233.                         keepit = true
  1234.                         break
  1235.                     end
  1236.                 end
  1237.                 if not keepit then
  1238.                     --clsTurtle.saveToLog(self, "EmptyTrash():Dropping "..item, true)
  1239.                     turtle.select(i)
  1240.                     turtle.dropDown()
  1241.                 end
  1242.             end
  1243.         end
  1244.         clsTurtle.sortInventory(self)
  1245.         clsTurtle.emptyTrashItem(self, "down", "minecraft:cobblestone", 128)
  1246.         clsTurtle.emptyTrashItem(self, "down", "minecraft:redstone", 64)
  1247.         slotData = clsTurtle.getStock(self, "minecraft:coal", 0)
  1248.         if slotData.total > 64 then
  1249.             if slotData.mostSlot ~= slotData.leastSlot and slotData.leastSlot ~= 0 then
  1250.                 turtle.select(slotData.leastSlot)
  1251.                 turtle.refuel()
  1252.                 --clsTurtle.saveToLog(self, "EmptyTrash():xs coal used for fuel", true)
  1253.             end
  1254.         end
  1255.         if direction == "down" and move then
  1256.             clsTurtle.up(self, 1)
  1257.         end
  1258.         turtle.select(1)
  1259.     end
  1260.    
  1261.     function clsTurtle.emptyTrashItem(self, direction, item, maxAmount)
  1262.         local stockData = clsTurtle.getStock(self, item)
  1263.        
  1264.         while stockData.total > maxAmount and stockData.mostSlot > 0 do
  1265.             turtle.select(stockData.mostSlot)
  1266.             if direction == "up" then
  1267.                 if not turtle.dropUp() then
  1268.                     if not turtle.dropDown() then
  1269.                         --clsTurtle.saveToLog(self, "EmptyTrashItem():error ", true)
  1270.                         break
  1271.                     end
  1272.                 end
  1273.             else
  1274.                 if not turtle.dropDown() then
  1275.                     if not turtle.dropUp() then
  1276.                         --clsTurtle.saveToLog(self, "EmptyTrashItem():error ", true)
  1277.                         break
  1278.                     end
  1279.                 end
  1280.             end
  1281.             stockData = clsTurtle.getStock(self, item)
  1282.         end
  1283.     end
  1284.    
  1285.     function clsTurtle.equip(self, side, useItem, useDamage)
  1286.         useDamage = useDamage or 0
  1287.         local slot, damage = clsTurtle.getItemSlot(self, useItem)
  1288.         local currentSlot = turtle.getSelectedSlot()
  1289.         local success = false
  1290.         --[[
  1291.         minecraft:crafting_table
  1292.         minecraft:diamond_pickaxe
  1293.         minecraft:diamond_sword
  1294.         minecraft:diamond_shovel
  1295.         minecraft:diamond_hoe
  1296.         minecraft:diamond_axe
  1297.         wireless modem = ComputerCraft:CC-Peripheral, damage = 1
  1298.         ]]
  1299.        
  1300.         if slot > 0 and damage == useDamage then
  1301.             turtle.select(slot)
  1302.             if side == "right" then
  1303.                 if turtle.equipRight() then
  1304.                     success = true
  1305.                     self.equippedRight = useItem
  1306.                 end
  1307.             else
  1308.                 if turtle.equipLeft() then
  1309.                     success = true
  1310.                     self.equippedLeft = useItem
  1311.                 end
  1312.             end
  1313.         end
  1314.         turtle.select(currentSlot)
  1315.        
  1316.         return success
  1317.     end
  1318.    
  1319.     function clsTurtle.findBedrockTop(self, height)
  1320.         local bedrockFound = false
  1321.         repeat
  1322.             bedrockFound = false
  1323.             clsTurtle.clear(self)
  1324.             print("Checking surrounding  blocks...")
  1325.             for i = 1, 4 do
  1326.                 clsTurtle.turnLeft(self, 1)
  1327.                 if clsTurtle.getBlockType(self, "forward") == "minecraft:bedrock" then
  1328.                     bedrockFound = true
  1329.                     print("Bedrock found...")
  1330.                 end
  1331.             end
  1332.             if bedrockFound then
  1333.                 clsTurtle.up(self, 1)
  1334.                 height = height -1
  1335.                 clsTurtle.place(self, "minecraft:cobblestone", 0, "down")
  1336.                 print("Moving up...")
  1337.             end
  1338.         until not bedrockFound
  1339.         repeat
  1340.             bedrockFound = false
  1341.             local moved = 0
  1342.             for i = 1, 5 do
  1343.                 if clsTurtle.forward(self, 1) then
  1344.                     moved = moved + 1
  1345.                     for i = 1, 4 do
  1346.                         clsTurtle.turnLeft(self, 1)
  1347.                         if clsTurtle.getBlockType(self, "forward") == "minecraft:bedrock" then
  1348.                             bedrockFound = true
  1349.                             print("Bedrock found: not continuing this row")
  1350.                         end
  1351.                     end
  1352.                     if bedrockFound then
  1353.                         break
  1354.                     end
  1355.                 else -- hit bedrock
  1356.                     print("Hit bedrock in front")
  1357.                     bedrockFound = true
  1358.                     break
  1359.                 end
  1360.             end
  1361.             clsTurtle.turnLeft(self, 2)
  1362.             for i = 1, moved do
  1363.                 clsTurtle.go(self, "C2F1")
  1364.             end
  1365.             clsTurtle.go(self, "L2C1")
  1366.             if bedrockFound then
  1367.                 print("Moving up...")
  1368.                 clsTurtle.go(self, "U1C2")
  1369.                 height = height -1
  1370.             else
  1371.                 print("Area clear of bedrock...")
  1372.             end
  1373.         until bedrockFound == false
  1374.         return height
  1375.     end
  1376.    
  1377.     function clsTurtle.getBlockType(self, direction)
  1378.         -- turtle.inspect() returns two values
  1379.         -- 1) boolean (true/false) success
  1380.         -- 2) table with two values:
  1381.         --  .name (string) e.g. "minecraft:log"
  1382.         --  .metadata (integer) e.g. 0
  1383.         --  oak has metadata of 0, spruce 1, birch 2 etc
  1384.         local blockType = nil
  1385.         local blockModifier = nil
  1386.         local success = false
  1387.         local data = {} --initialise empty table variable
  1388.      
  1389.         if direction == "up" then
  1390.             success, data = turtle.inspectUp() -- store information about the block above in a table   
  1391.         elseif direction == "down" then
  1392.             success, data = turtle.inspectDown() -- store information about the block below in a table
  1393.         else
  1394.             success, data = turtle.inspect() -- store information about the block ahead in a table
  1395.         end
  1396.         if success then -- block found
  1397.             blockType = data.name -- eg "minecraft:log"
  1398.             blockModifier = data.metadata
  1399.         end
  1400.        
  1401.         return blockType, blockModifier
  1402.     end
  1403.    
  1404.     function clsTurtle.getFirstEmptySlot(self)
  1405.         local iSlot = 0
  1406.         for i = 1,16 do
  1407.             if turtle.getItemCount(i) == 0 then
  1408.                 iSlot = i
  1409.                 break
  1410.             end
  1411.         end
  1412.         return iSlot
  1413.     end
  1414.    
  1415.     function clsTurtle.getItemCount(self, item, modifier)
  1416.         local slot, damage, total, slotData = clsTurtle.getItemSlot(self, item, modifier) --return .leastSlot, .leastModifier, total, slotData
  1417.         return total
  1418.     end
  1419.    
  1420.     function clsTurtle.getItemName(self, slot)
  1421.         local data = {} --initialise empty table variable
  1422.         data.name = ""
  1423.        
  1424.         if turtle.getItemCount(slot) > 0 then
  1425.             data = turtle.getItemDetail(slot)
  1426.         end
  1427.        
  1428.         return data.name
  1429.     end
  1430.    
  1431.     function clsTurtle.getItemSlot(self, item, useDamage)
  1432.         -- return slot no with least count, damage(modifier) and total count available
  1433.         -- along with a table of mostSlot, mostCount, leastSlot, leastCount
  1434.         useDamage = useDamage or -1 -- -1 damage means is not relevant
  1435.         local data = {} --initialise empty table variable
  1436.         local slotData = {}
  1437.         local total = 0
  1438.         -- setup return table
  1439.         slotData.mostSlot = 0
  1440.         slotData.mostName = ""
  1441.         slotData.mostCount = 0
  1442.         slotData.mostModifier = 0
  1443.         slotData.leastSlot = 0
  1444.         slotData.leastName = ""
  1445.         slotData.leastCount = 0
  1446.         slotData.leastModifier = 0
  1447.         for i = 1, 16 do
  1448.             local count = turtle.getItemCount(i)
  1449.             if count > 0 then
  1450.                 data = turtle.getItemDetail(i)
  1451.                 if data.name == item and (data.damage == useDamage or useDamage == -1) then
  1452.                     total = total + count
  1453.                     if count > slotData.mostCount then--
  1454.                         slotData.mostSlot = i
  1455.                         slotData.mostName = data.name
  1456.                         slotData.mostCount = count
  1457.                         slotData.mostModifier = data.damage
  1458.                     end
  1459.                     if count < slotData.leastCount then--
  1460.                         slotData.leastSlot = i
  1461.                         slotData.leastName = data.name
  1462.                         slotData.leastCount = count
  1463.                         slotData.leastModifier = data.damage
  1464.                     end
  1465.                 end
  1466.             end
  1467.         end
  1468.         if slotData.mostSlot > 0 then
  1469.             if slotData.leastSlot == 0 then
  1470.                 slotData.leastSlot = slotData.mostSlot
  1471.                 slotData.leastName = slotData.mostName
  1472.                 slotData.leastCount = slotData.mostCount
  1473.                 slotData.leastModifier = slotData.mostModifier
  1474.             end
  1475.         end
  1476.        
  1477.         return slotData.leastSlot, slotData.leastModifier, total, slotData -- first slot no, integer, integer, table
  1478.     end
  1479.    
  1480.     function clsTurtle.getPlaceChestDirection(self)
  1481.         local facing = self.facing
  1482.         local chestDirection = "forward"
  1483.         while turtle.detect() do --check for clear space to place chest
  1484.             clsTurtle.turnRight(self, 1)
  1485.             if facing == self.facing then -- full circle
  1486.                 --check up and down
  1487.                 if turtle.detectDown() then -- no space below
  1488.                     if turtle.detectUp() then
  1489.                         if clsTurtle.dig(self, "up") then
  1490.                             chestDirection = "up"
  1491.                         end
  1492.                     else
  1493.                         chestDirection = "up"
  1494.                     end
  1495.                 else
  1496.                     chestDirection = "down"
  1497.                 end
  1498.                 break
  1499.             end
  1500.         end
  1501.         return chestDirection
  1502.     end
  1503.    
  1504.     function clsTurtle.getSlotContains(self, slotNo)
  1505.         local data = {} --initialise empty table variable
  1506.        
  1507.         local slotCount = 0
  1508.         local slotContains = ""
  1509.         local slotDamage = 0
  1510.         if turtle.getItemCount(slotNo) > 0 then
  1511.             data = turtle.getItemDetail(slotNo)
  1512.             slotCount = data.count
  1513.             slotContains = data.name
  1514.             slotDamage = data.damage
  1515.         end
  1516.        
  1517.         return slotCount, slotContains, slotDamage
  1518.     end
  1519.    
  1520.     function clsTurtle.getStock(self, item, modifier)
  1521.         -- return total units and slot numbers of max and min amounts
  1522.         local slot, damage, total, slotData = clsTurtle.getItemSlot(self, item, modifier) --return .leastSlot, .leastModifier, total, slotData
  1523.         local rt = {}
  1524.         rt.total = total
  1525.         rt.mostSlot = slotData.mostSlot
  1526.         rt.leastSlot = slotData.leastSlot
  1527.         rt.mostCount = slotData.mostCount
  1528.         rt.leastCount = slotData.leastCount
  1529.         if slot == 0 then
  1530.             if modifier == nil then
  1531.                 --clsTurtle.saveToLog(self, "getStock()"..tostring(item).."= not found", true)
  1532.             else
  1533.                 --clsTurtle.saveToLog(self, "getStock()"..tostring(item).."("..tostring(modifier)..")= not found")
  1534.             end
  1535.         end
  1536.        
  1537.         return rt --{rt.total, rt.mostSlot, rt.leastSlot, rt.mostCount, rt.leastCount}
  1538.     end
  1539.    
  1540.     function clsTurtle.getSolidBlockCount(self)
  1541.         local retValue = 0
  1542.         local slotCount, slotContains, slotDamage
  1543.         for i = 1, 16 do
  1544.             slotCount, slotContains, slotDamage = clsTurtle.getSlotContains(self, i)
  1545.             if slotContains == "minecraft:stone" or slotContains == "minecraft:cobblestone" or slotContains == "minecraft:dirt" then
  1546.                 retValue = retValue + slotCount
  1547.             end
  1548.         end
  1549.         return retValue
  1550.     end
  1551.    
  1552.     function clsTurtle.getTotalItemCount(self)
  1553.         local count = 0
  1554.        
  1555.         for i = 1, 16 do
  1556.             count = count + turtle.getItemCount(i)
  1557.         end
  1558.         return count
  1559.     end
  1560.    
  1561.     function clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, checkDungeon)
  1562.         useTorch = useTorch or false -- used in m an M to place torches in mines
  1563.         if leaveExisting == nil then
  1564.             leaveExisting = false
  1565.         end
  1566.         if checkDungeon == nil then
  1567.             checkDungeon = false
  1568.         end
  1569.         torchInterval = torchInterval or 8
  1570.         local intervalList = {1, torchInterval * 1 + 1,
  1571.                                  torchInterval * 2 + 1,
  1572.                                  torchInterval * 3 + 1,
  1573.                                  torchInterval * 4 + 1,
  1574.                                  torchInterval * 5 + 1,
  1575.                                  torchInterval * 6 + 1}
  1576.         local slot = turtle.getSelectedSlot()
  1577.         turtle.select(1)       
  1578.         local commandList = {}
  1579.         local command = ""
  1580.         -- remove spaces from path
  1581.         path = string.gsub(path, " ", "")
  1582.         -- make a list of commands from path string eg "x0F12U1" = x0, F12, U1
  1583.         for i = 1, string.len(path) do
  1584.             local character = string.sub(path, i, i) -- examine each character in the string
  1585.             if tonumber(character) == nil then -- char is NOT a number
  1586.                 if command ~= "" then -- command is NOT empty eg "x0"
  1587.                     table.insert(commandList, command) -- add to table eg "x0"
  1588.                 end
  1589.                 command = character -- replace command with new character eg "F"
  1590.             else -- char IS a number
  1591.                 command = command..character -- add eg 1 to F = F1, 2 to F1 = F12
  1592.                 if i == string.len(path) then -- last character in the string
  1593.                     table.insert(commandList, command)
  1594.                 end
  1595.             end
  1596.         end
  1597.         -- R# L# F# B# U# D# +0 -0 d0 = Right, Left, Forward, Back, Up, Down, up while detect and return, down while not detect, down and place while not detect
  1598.         -- dig:           x0,x1,x2 (up/fwd/down)
  1599.         -- suck:          s0,s1,s2
  1600.         -- place chest:   H0,H1,H2
  1601.         -- place sapling: S0,S1,S2
  1602.         -- place Torch:   T0,T1,T2
  1603.         -- place Hopper:  P0,P1,P2
  1604.         -- mine floor:    m# = mine # blocks above and below, checking for valuable items below, and filling space with cobble or dirt
  1605.         -- mine ceiling:  M# = mine # blocks, checking for valuable items above, and filling space with cobble or dirt
  1606.         -- mine ceiling:  N# same as M but not mining block below unless valuable
  1607.         -- place:         C,H,r,S,T,P,^ = Cobble / cHest / DIrT / Sapling / Torch / hoPper /stair in direction 0/1/2 (up/fwd/down) eg C2 = place cobble down
  1608.         -- place:         t = 0/1 = place behind, 2 = cobble first, up torch, forward down
  1609.         -- place:         e = ladder direction
  1610.         -- place:         @ = any block in inventory, direction
  1611.         clsTurtle.refuel(self, 15)
  1612.         turtle.select(1)
  1613.         for cmd in clsTurtle.values(self, commandList) do -- eg F12 or x1
  1614.             local move = string.sub(cmd, 1, 1)
  1615.             local modifier = tonumber(string.sub(cmd, 2))
  1616.             if move == "R" then
  1617.                 clsTurtle.turnRight(self, modifier)
  1618.             elseif move == "L" then
  1619.                 clsTurtle.turnLeft(self, modifier)
  1620.             elseif move == "B" then
  1621.                 clsTurtle.back(self, modifier)
  1622.             elseif move == "F" then
  1623.                 clsTurtle.forward(self, modifier, checkDungeon)
  1624.             elseif move == "U" then
  1625.                 clsTurtle.up(self, modifier, checkDungeon)
  1626.             elseif move == "D" then
  1627.                 clsTurtle.down(self, modifier, checkDungeon)
  1628.             elseif move == "+" then
  1629.                 local height = 0
  1630.                 while turtle.detectUp() do
  1631.                     clsTurtle.up(self, 1, checkDungeon)
  1632.                     height = height + 1
  1633.                 end
  1634.                 clsTurtle.down(self, height, checkDungeon)
  1635.             elseif move == "-" then
  1636.                 while not turtle.inspectDown() do
  1637.                     clsTurtle.down(self, 1, checkDungeon)
  1638.                 end
  1639.             elseif move == "d" then
  1640.                 if modifier == 1 then
  1641.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward", leaveExisting) then
  1642.                         if not clsTurtle.place(self, "minecraft:dirt", -1, "forward", leaveExisting) then
  1643.                             clsTurtle.place(self, "minecraft:stone", -1, "forward", leaveExisting)
  1644.                         end
  1645.                     end
  1646.                 end
  1647.                 while not turtle.detectDown() do
  1648.                     clsTurtle.down(self, 1, checkDungeon)
  1649.                     if modifier == 1 then
  1650.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward", leaveExisting) then
  1651.                             if not clsTurtle.place(self, "minecraft:dirt", -1, "forward", leaveExisting) then
  1652.                                 clsTurtle.place(self, "minecraft:stone", -1, "forward", leaveExisting)
  1653.                             end
  1654.                         end
  1655.                     end
  1656.                 end
  1657.                 if modifier == 1 then
  1658.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward", leaveExisting) then
  1659.                         if not clsTurtle.place(self, "minecraft:dirt", -1, "forward", leaveExisting) then
  1660.                             clsTurtle.place(self, "minecraft:stone", -1, "forward", leaveExisting)
  1661.                         end
  1662.                     end
  1663.                 end
  1664.             elseif move == "u" then -- move up and place forward/down
  1665.                 repeat
  1666.                     if modifier == 1 then
  1667.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward", leaveExisting) then
  1668.                             if not clsTurtle.place(self, "minecraft:dirt", -1, "forward", leaveExisting) then
  1669.                                 clsTurtle.place(self, "minecraft:stone", -1, "forward", leaveExisting)
  1670.                             end
  1671.                         end
  1672.                     end
  1673.                     clsTurtle.up(self, 1, checkDungeon)
  1674.                     if modifier == 1 then
  1675.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward", leaveExisting) then
  1676.                             if not clsTurtle.place(self, "minecraft:dirt", -1, "forward", leaveExisting) then
  1677.                                 clsTurtle.place(self, "minecraft:stone", -1, "forward", leaveExisting)
  1678.                             end
  1679.                         end
  1680.                     end
  1681.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down", leaveExisting) then
  1682.                         if not clsTurtle.place(self, "minecraft:dirt", -1, "down", leaveExisting) then
  1683.                             clsTurtle.place(self, "minecraft:stone", -1, "down", leaveExisting)
  1684.                         end
  1685.                     end
  1686.                 until not turtle.inspectUp()
  1687.                 if modifier == 1 then
  1688.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward", leaveExisting) then
  1689.                         if not clsTurtle.place(self, "minecraft:dirt", -1, "forward", leaveExisting) then
  1690.                             clsTurtle.place(self, "minecraft:stone", -1, "forward", leaveExisting)
  1691.                         end
  1692.                     end
  1693.                 end
  1694.             elseif move == "x" then
  1695.                 if modifier == 0 then
  1696.                     clsTurtle.dig(self, "up")
  1697.                 elseif modifier == 1 then
  1698.                     clsTurtle.dig(self, "forward")
  1699.                 elseif modifier == 2 then
  1700.                     while turtle.detectDown() do
  1701.                         turtle.digDown()
  1702.                     end
  1703.                 end
  1704.             elseif move == "s" then
  1705.                 if modifier == 0 then
  1706.                     while turtle.suckUp() do end
  1707.                 elseif modifier == 1 then
  1708.                     while turtle.suck() do end
  1709.                 elseif modifier == 2 then
  1710.                     while turtle.suckDown() do end
  1711.                 end
  1712.             elseif move == "m" then --mine block below and/or fill void
  1713.                 for i = 1, modifier + 1 do --eg m8 run loop 9 x
  1714.                     turtle.select(1)
  1715.                     local isValuable, blockType = clsTurtle.isValuable(self, "down")
  1716.                     if isValuable or blockType == "minecraft:gravel" then
  1717.                         turtle.digDown() -- dig if gravel
  1718.                     else --check for lava
  1719.                         if blockType == "minecraft:lava" then
  1720.                             clsTurtle.place(self, "minecraft:bucket", 0, "down")
  1721.                         end
  1722.                     end
  1723.                     clsTurtle.dig(self, "up") -- create player coridoor
  1724.                     if not turtle.detectDown() then
  1725.                         if blockType ~= "minecraft:diamond_ore" then
  1726.                             if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1727.                                 clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1728.                             end
  1729.                         end
  1730.                     end
  1731.                     if i <= modifier then -- m8 = move forward 8x
  1732.                         if useTorch then
  1733.                             if  i == intervalList[1] or
  1734.                                 i == intervalList[2] or
  1735.                                 i == intervalList[3] or
  1736.                                 i == intervalList[4] or
  1737.                                 i == intervalList[5] then
  1738.                                 clsTurtle.up(self, 1, checkDungeon)
  1739.                                 clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  1740.                                 clsTurtle.forward(self, 1, checkDungeon)
  1741.                                 clsTurtle.down(self, 1, checkDungeon)
  1742.                             else
  1743.                                 clsTurtle.forward(self, 1, checkDungeon)
  1744.                             end
  1745.                         else
  1746.                             clsTurtle.forward(self, 1, checkDungeon)
  1747.                         end
  1748.                     end
  1749.                 end
  1750.             elseif move == "n" then --mine block below and/or fill void + check left side
  1751.                 for i = 1, modifier + 1 do --eg m8 run loop 9 x
  1752.                     turtle.select(1)
  1753.                     local isValuable, blockType = clsTurtle.isValuable(self, "down")
  1754.                     if isValuable or blockType == "minecraft:gravel" then
  1755.                         turtle.digDown() -- dig if valuable or gravel
  1756.                     else --check for lava
  1757.                         if blockType == "minecraft:lava" then
  1758.                             clsTurtle.place(self, "minecraft:bucket", 0, "down")
  1759.                         end
  1760.                     end
  1761.                     clsTurtle.dig(self, "up") -- create player coridoor
  1762.                     if not turtle.detectDown() then
  1763.                         if blockType ~= "minecraft:diamond_ore" then
  1764.                             if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1765.                                 clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1766.                             end
  1767.                         end
  1768.                     end
  1769.                     clsTurtle.turnLeft(self, 1)
  1770.                     local isValuable, blockType = clsTurtle.isValuable(self, "forward")
  1771.                     if isValuable then
  1772.                         turtle.dig() -- dig if valuable
  1773.                     end
  1774.                     if not turtle.detect() then
  1775.                         if blockType ~= "minecraft:diamond_ore" then
  1776.                             if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward") then
  1777.                                 clsTurtle.place(self, "minecraft:dirt", -1, "forward")
  1778.                             end
  1779.                         end
  1780.                     end
  1781.                     clsTurtle.turnRight(self, 1)   
  1782.                     if i <= modifier then -- m8 = move forward 8x
  1783.                         if useTorch then
  1784.                             if  i == intervalList[1] or
  1785.                                 i == intervalList[2] or
  1786.                                 i == intervalList[3] or
  1787.                                 i == intervalList[4] or
  1788.                                 i == intervalList[5] then
  1789.                                 clsTurtle.up(self, 1, checkDungeon)
  1790.                                 clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  1791.                                 clsTurtle.forward(self, 1, checkDungeon)
  1792.                                 clsTurtle.down(self, 1, checkDungeon)
  1793.                             else
  1794.                                 clsTurtle.forward(self, 1, checkDungeon)
  1795.                             end
  1796.                         else
  1797.                             clsTurtle.forward(self, 1, checkDungeon)
  1798.                         end
  1799.                     end
  1800.                 end
  1801.             elseif move == "M" then --mine block above and/or fill void
  1802.                 for i = 1, modifier + 1 do
  1803.                     turtle.select(1)
  1804.                     local isValuable, blockType = clsTurtle.isValuable(self, "up")
  1805.                     if isValuable then
  1806.                         clsTurtle.dig(self, "up")
  1807.                     else --check for lava
  1808.                         if clsTurtle.getBlockType(self, "up") == "minecraft:lava" then
  1809.                             clsTurtle.place(self, "minecraft:bucket", 0, "up")
  1810.                         end
  1811.                     end
  1812.                     if not turtle.detectUp()then
  1813.                         if blockType ~= "minecraft:diamond_ore" then
  1814.                             if not clsTurtle.place(self, "minecraft:cobblestone", -1, "up") then
  1815.                                 clsTurtle.place(self, "minecraft:dirt", -1, "up")
  1816.                             end
  1817.                         end
  1818.                     end
  1819.                     if i <= modifier then -- will not move forward if modifier = 0
  1820.                         if useTorch then
  1821.                             if  i == intervalList[1] or
  1822.                                 i == intervalList[2] or
  1823.                                 i == intervalList[3] or
  1824.                                 i == intervalList[4] or
  1825.                                 i == intervalList[5] then
  1826.                                 clsTurtle.place(self, "minecraft:torch", 0, "down", false)
  1827.                             end
  1828.                         end
  1829.                         clsTurtle.forward(self, 1, checkDungeon)
  1830.                     end
  1831.                 end
  1832.             elseif move == "N" then --mine block above and/or fill void + mine block below if valuable
  1833.                 for i = 1, modifier + 1 do
  1834.                     turtle.select(1)
  1835.                     local isValuable, blockType = clsTurtle.isValuable(self, "up")
  1836.                     if isValuable then
  1837.                         clsTurtle.dig(self, "up")
  1838.                     else --check for lava
  1839.                         if clsTurtle.getBlockType(self, "up") == "minecraft:lava" then
  1840.                             clsTurtle.place(self, "minecraft:bucket", 0, "up")
  1841.                         end
  1842.                     end
  1843.                     if not turtle.detectUp() then
  1844.                         if blockType ~= "minecraft:diamond_ore" then
  1845.                             if not clsTurtle.place(self, "minecraft:cobblestone", -1, "up") then
  1846.                                 clsTurtle.place(self, "minecraft:dirt", -1, "up")
  1847.                             end
  1848.                         end
  1849.                     end
  1850.                     turtle.select(1)
  1851.                     if clsTurtle.isValuable(self, "down") then
  1852.                         turtle.digDown()
  1853.                     end
  1854.                     if i <= modifier then
  1855.                         clsTurtle.forward(self, 1, checkDungeon)
  1856.                     end
  1857.                 end
  1858.             elseif move == "Q" then --mine block above and/or fill void + mine block below if valuable + left side
  1859.                 for i = 1, modifier + 1 do
  1860.                     turtle.select(1)
  1861.                     if clsTurtle.isValuable(self, "up") then
  1862.                         clsTurtle.dig(self, "up")
  1863.                     else --check for lava
  1864.                         if clsTurtle.getBlockType(self, "up") == "minecraft:lava" then
  1865.                             clsTurtle.place(self, "minecraft:bucket", 0, "up")
  1866.                         end
  1867.                     end
  1868.                     if not turtle.detectUp() then
  1869.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "up") then
  1870.                             clsTurtle.place(self, "minecraft:dirt", -1, "up")
  1871.                         end
  1872.                     end
  1873.                     clsTurtle.turnLeft(self, 1)
  1874.                     if clsTurtle.isValuable(self, "forward") then
  1875.                         turtle.dig() -- dig if valuable
  1876.                     end
  1877.                     if not turtle.detect() then
  1878.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "forward") then
  1879.                             clsTurtle.place(self, "minecraft:dirt", -1, "forward")
  1880.                         end
  1881.                     end
  1882.                     clsTurtle.turnRight(self, 1)   
  1883.                     if clsTurtle.isValuable(self, "down") then
  1884.                         turtle.digDown()
  1885.                     end
  1886.                     if i <= modifier then
  1887.                         clsTurtle.forward(self, 1, checkDungeon)
  1888.                     end
  1889.                 end
  1890.             elseif move == "C" or move == "H" or move == "r" or move == "T" or move == "S" or move == "P" or move == "@" then --place item up/forward/down
  1891.                 -- clsTurtle.place(self, blockType, damageNo, direction, leaveExisting)
  1892.                
  1893.                 local placeItem = "minecraft:cobblestone"
  1894.                 local direction = {"up", "forward", "down"}
  1895.                 if move == "H" then
  1896.                     placeItem = "minecraft:chest"
  1897.                 elseif move == "r" then
  1898.                     placeItem = "minecraft:dirt"
  1899.                 elseif move == "T" then
  1900.                     placeItem = "minecraft:torch"
  1901.                 elseif move == "S" then
  1902.                     placeItem = "minecraft:sapling"
  1903.                 elseif move == "P" then
  1904.                     placeItem = "minecraft:hopper"
  1905.                 elseif move == "@" then -- any item in inventory
  1906.                     placeItem = ""
  1907.                 end
  1908.                 --[[
  1909.                 if modifier == 0 then
  1910.                     clsTurtle.dig(self, "up")
  1911.                 elseif modifier == 1 then
  1912.                     clsTurtle.dig(self, "forward")
  1913.                 else
  1914.                     turtle.digDown()
  1915.                 end]]
  1916.                 if move == "C" then
  1917.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, direction[modifier + 1], leaveExisting) then
  1918.                         if not clsTurtle.place(self, "minecraft:dirt", -1, direction[modifier + 1], leaveExisting) then
  1919.                             clsTurtle.place(self, "minecraft:stone", -1, direction[modifier + 1], leaveExisting)
  1920.                         end
  1921.                     end
  1922.                 else
  1923.                     clsTurtle.place(self, placeItem, -1, direction[modifier + 1], leaveExisting)
  1924.                 end
  1925.             elseif move == "t" then
  1926.                 -- 0 = placeUp does not work with os 1.8
  1927.                 -- 1 = turn round, placeForward
  1928.                 -- 2 = placeDown
  1929.                 -- 3 = turnLeft, placeUp
  1930.                 -- 4 = turnround, placeUp
  1931.                 -- 5 = place down without block
  1932.                 if modifier == 0 then -- os < 1.8
  1933.                     clsTurtle.place(self, "minecraft:torch", -1, "up", false)
  1934.                 elseif modifier == 1 then --place behind
  1935.                     clsTurtle.turnLeft(self, 2)
  1936.                     --local block, blockType = clsTurtle.isWaterOrLava(self, "forward")
  1937.                     --if block ~= "minecraft:water" and block ~= "minecraft:lava" then
  1938.                         clsTurtle.place(self, "minecraft:torch", -1, "forward", false)
  1939.                     --end
  1940.                     clsTurtle.turnLeft(self, 2)
  1941.                 elseif modifier == 2 then -- place below for 2
  1942.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1,"down") then
  1943.                         clsTurtle.place(self, "minecraft:dirt", -1, "down", leaveExisting)
  1944.                     end
  1945.                     clsTurtle.up(self, 1, checkDungeon)
  1946.                     --local block, blockType = clsTurtle.isWaterOrLava(self, "down")
  1947.                     --if block ~= "minecraft:water" and block ~= "minecraft:lava" then
  1948.                         clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  1949.                     --end
  1950.                     clsTurtle.forward(self, 1, checkDungeon)
  1951.                     clsTurtle.down(self, 1, checkDungeon)
  1952.                 elseif modifier == 3 then --turnLeft, placeUp (on ground to wall)
  1953.                     clsTurtle.turnLeft(self, 1)
  1954.                     clsTurtle.place(self, "minecraft:torch", -1, "up", false)
  1955.                     clsTurtle.turnRight(self, 1)
  1956.                 elseif modifier == 4 then --turnLeft, placeUp (on ground to wall)
  1957.                     clsTurtle.turnLeft(self, 2)
  1958.                     clsTurtle.place(self, "minecraft:torch", -1, "up", false)
  1959.                     clsTurtle.turnLeft(self, 2)
  1960.                 elseif modifier == 5 then --cobble first, then torch
  1961.                     clsTurtle.place(self, "minecraft:torch", -1, "down", false)
  1962.                 end
  1963.             elseif move == "e" then -- ladder above / in front / below
  1964.                 local direction = {"up", "forward", "down"}
  1965.                 clsTurtle.place(self, "minecraft:ladder", -1, direction[modifier + 1], false)
  1966.             elseif move == "*" then
  1967.                 local goUp = 0
  1968.                 while not turtle.inspectDown() do
  1969.                     clsTurtle.down(self, 1, checkDungeon)
  1970.                     goUp = goUp + 1
  1971.                 end
  1972.                 if goUp > 0 then
  1973.                     for i = 1, goUp do
  1974.                         clsTurtle.up(self, 1, checkDungeon)
  1975.                         if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1976.                             clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1977.                         end
  1978.                     end
  1979.                     goUp = 0
  1980.                 else
  1981.                     turtle.digDown()
  1982.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1983.                         clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1984.                     end
  1985.                 end
  1986.             elseif move == "c" then
  1987.                 if turtle.detectDown() then
  1988.                     --check if vegetation and remove
  1989.                     data = clsTurtle.getBlockType(self, "down")
  1990.                     if data.name ~= "minecraft:dirt" and data.name ~= "minecraft:stone" and data.name ~= "minecraft:cobblestone" and data.name ~= "minecraft:grass" then
  1991.                         turtle.digDown()
  1992.                     end
  1993.                 end
  1994.                 if not turtle.detectDown() then
  1995.                     if not clsTurtle.place(self, "minecraft:cobblestone", -1, "down") then
  1996.                         clsTurtle.place(self, "minecraft:dirt", -1, "down")
  1997.                     end
  1998.                 end
  1999.             elseif move == "Z" then -- mine to bedrock
  2000.                 for i = 1, modifier + 1 do 
  2001.                     turtle.select(1)
  2002.                     local goUp = 0
  2003.                     while clsTurtle.down(self, 1, checkDungeon) do
  2004.                         goUp = goUp + 1
  2005.                     end
  2006.                     for j = goUp, 1, -1 do
  2007.                         for k = 1, 4 do
  2008.                             clsTurtle.turnRight(self, 1)
  2009.                             if clsTurtle.isValuable(self, "forward") then
  2010.                                 clsTurtle.place(self, "minecraft:cobblestone", -1, "forward")
  2011.                             end
  2012.                         end
  2013.                         clsTurtle.up(self, 1, checkDungeon)
  2014.                         clsTurtle.place(self, "minecraft:cobblestone", -1, "down")
  2015.                         turtle.select(1)
  2016.                     end
  2017.                     if i <= modifier then
  2018.                         clsTurtle.forward(self, 2, checkDungeon)
  2019.                     end
  2020.                 end
  2021.             elseif move == "^" then --place stair
  2022.                 local direction = {"up", "forward", "down"}
  2023.                 if not clsTurtle.place(self, "minecraft:stone_stairs", -1, direction[modifier + 1], false) then -- ending false forces block replacement
  2024.                     print("could not place stairs")
  2025.                     clsTurtle.place(self, "minecraft:cobblestone", -1, direction[modifier + 1], false)
  2026.                 end
  2027.             end
  2028.         end
  2029.         turtle.select(slot)
  2030.     end
  2031.    
  2032.     function clsTurtle.harvestTree(self, extend, craftChest, direction)
  2033.         extend = extend or false
  2034.         craftChest = craftChest or false
  2035.         direction = direction or "forward"
  2036.         local goHeight = 0
  2037.         local addHeight = 0
  2038.         local onLeft = true
  2039.         if direction == "forward" then
  2040.             turtle.dig()       -- dig base of tree
  2041.             clsTurtle.forward(self, 1) -- go under tree with 1 log. Will refuel if needed
  2042.         end
  2043.         -- check if on r or l of double width tree
  2044.         clsTurtle.turnLeft(self, 1)
  2045.         if clsTurtle.getBlockType(self, "forward") == "minecraft:log" or clsTurtle.getBlockType(self, "forward") == "minecraft:log2" then
  2046.             onLeft = false -- placed on right side of 2 block tree
  2047.         end
  2048.         clsTurtle.turnRight(self, 1)
  2049.         if craftChest then
  2050.             clsTurtle.dig(self, "up")
  2051.             clsTurtle.up(self, 1)
  2052.             clsTurtle.dig(self, "up")
  2053.             while clsTurtle.down(self, 1) do end
  2054.             clsTurtle.craft(self, "minecraft:planks", 8)
  2055.             clsTurtle.craft(self, "minecraft:chest", 1)
  2056.             while clsTurtle.up(self, 1) do
  2057.                 goHeight = goHeight + 1
  2058.             end
  2059.         end
  2060.         -- Loop to climb up tree and harvest trunk and surrounding leaves
  2061.         while clsTurtle.dig(self, "up") do -- continue loop while block detected above
  2062.             if clsTurtle.up(self, 1) then   -- Move up
  2063.                 goHeight = goHeight + 1
  2064.             end
  2065.             -- Inner loop to check for leaves
  2066.             for i = 1, 4 do
  2067.                 if turtle.detect() then -- check if leaves in front
  2068.                     clsTurtle.dig(self, "forward") --Dig leaves
  2069.                 end
  2070.                 clsTurtle.turnRight(self, 1)
  2071.             end
  2072.         end
  2073.         -- At top of the tree. New loop to return to ground
  2074.         if extend then
  2075.             if onLeft then
  2076.                 clsTurtle.go(self, "F1R1F1R2")
  2077.             else
  2078.                 clsTurtle.go(self, "F1L1F1R2")
  2079.             end
  2080.             while turtle.detectUp() do
  2081.                 clsTurtle.up(self, 1)
  2082.                 addHeight = addHeight + 1
  2083.             end
  2084.             if addHeight > 0 then
  2085.                 clsTurtle.down(self, addHeight)
  2086.             end
  2087.         end
  2088.         for i = 1, goHeight do
  2089.             clsTurtle.down(self, 1)
  2090.         end
  2091.         if extend then
  2092.             if onLeft then
  2093.                 clsTurtle.go(self, "F1L1F1R2")
  2094.             else
  2095.                 clsTurtle.go(self, "F1R1F1R2")
  2096.             end
  2097.         end
  2098.     end
  2099.    
  2100.     function clsTurtle.harvestWholeTree(self, direction)   
  2101.         --RECURSIVE FUNCTION - BEWARE!
  2102.         local blockType, modifier
  2103.         if direction == "up" then
  2104.             clsTurtle.refuel(self, 15)
  2105.             if clsTurtle.isLog(self, "up") then
  2106.                 clsTurtle.up(self, 1)
  2107.                 if clsTurtle.isLog(self, "up") then
  2108.                     clsTurtle.harvestWholeTree(self, "up")
  2109.                 end
  2110.             end
  2111.             for i = 1, 4 do
  2112.                 -- check all round
  2113.                 if clsTurtle.isLog(self, "forward") then
  2114.                     clsTurtle.harvestWholeTree(self, "forward")
  2115.                 else
  2116.                     blockType, modifier = clsTurtle.getBlockType(self, "forward")
  2117.                     if blockType == "minecraft:leaves" then
  2118.                         clsTurtle.forward(self, 1)
  2119.                         clsTurtle.harvestWholeTree(self, "forward")
  2120.                         clsTurtle.back(self, 1)
  2121.                     end
  2122.                 end
  2123.                 clsTurtle.turnRight(self, 1)
  2124.             end
  2125.             clsTurtle.down(self, 1)
  2126.             for i = 1, 4 do
  2127.                 -- check all round
  2128.                 if clsTurtle.isLog(self, "forward") then
  2129.                     clsTurtle.harvestWholeTree(self, "forward")
  2130.                 else
  2131.                     blockType, modifier = clsTurtle.getBlockType(self, "forward")
  2132.                     if blockType == "minecraft:leaves" then
  2133.                         clsTurtle.forward(self, 1)
  2134.                         clsTurtle.harvestWholeTree(self, "forward")
  2135.                         clsTurtle.back(self, 1)
  2136.                     end
  2137.                 end
  2138.                 clsTurtle.turnRight(self, 1)
  2139.             end
  2140.         elseif direction == "forward" then
  2141.             if clsTurtle.isLog(self, "forward") then
  2142.                 clsTurtle.refuel(self, 15)
  2143.                
  2144.                 clsTurtle.forward(self, 1)
  2145.                 if turtle.detectUp() then
  2146.                     turtle.digUp()
  2147.                 end
  2148.                 if clsTurtle.isLog(self, "forward") then
  2149.                     clsTurtle.harvestWholeTree(self, "forward")
  2150.                 end
  2151.                 --check left side
  2152.                 clsTurtle.turnLeft(self, 1)
  2153.                 if clsTurtle.isLog(self, "forward") then
  2154.                     clsTurtle.harvestWholeTree(self, "forward")
  2155.                 end
  2156.                 -- check right side
  2157.                 clsTurtle.turnRight(self, 2)
  2158.                 if clsTurtle.isLog(self, "forward") then
  2159.                     clsTurtle.harvestWholeTree(self, "forward")
  2160.                 end
  2161.                 clsTurtle.turnLeft(self, 1)
  2162.                 clsTurtle.back(self, 1)
  2163.             end
  2164.         end
  2165.     end
  2166.    
  2167.     function clsTurtle.isDungeon(self, direction)
  2168.         local success = false
  2169.         local blockType, blockModifier = clsTurtle.getBlockType(self, direction)
  2170.         if blockType == "minecraft:mossy_cobblestone" or blockType == "minecraft:cobblestone" then --block found
  2171.             success = true
  2172.         end
  2173.         return success
  2174.     end
  2175.    
  2176.     function clsTurtle.isLog(self, direction)
  2177.         local success = false
  2178.         local blockType, modifier
  2179.        
  2180.         local valuableItems = "minecraft:log minecraft:log2"
  2181.  
  2182.         if direction == "up" then
  2183.             if turtle.detectUp() then
  2184.                 blockType, modifier = clsTurtle.getBlockType(self, "up")
  2185.             end
  2186.         elseif direction == "down" then
  2187.             if turtle.detectDown() then
  2188.                 blockType, modifier = clsTurtle.getBlockType(self, "down")
  2189.             end
  2190.         elseif direction == "forward" then
  2191.             if turtle.detect() then
  2192.                 blockType, modifier = clsTurtle.getBlockType(self, "forward")
  2193.             end
  2194.         end
  2195.         if blockType ~= nil then
  2196.             if string.find(valuableItems, blockType) ~= nil then
  2197.                 success = true
  2198.             end
  2199.         end
  2200.        
  2201.         return success
  2202.     end
  2203.    
  2204.     function clsTurtle.isValuable(self, direction)
  2205.         local success = false
  2206.         local blockType = ""
  2207.         local blockModifier
  2208.  
  2209.         local itemList = "minecraft:dirt,minecraft:grass,minecraft:stone,minecraft:gravel,minecraft:chest,"..
  2210.                          "minecraft:cobblestone,minecraft:sand,minecraft:torch,minecraft:bedrock,minecraft:ladder"
  2211.        
  2212.         if direction == "up" then
  2213.             if turtle.detectUp() then
  2214.                 blockType, blockModifier = clsTurtle.getBlockType(self, "up")
  2215.             end
  2216.         elseif direction == "down" then
  2217.             if turtle.detectDown() then
  2218.                 blockType, blockModifier = clsTurtle.getBlockType(self, "down")
  2219.             end
  2220.         elseif direction == "forward" then
  2221.             if turtle.detect() then
  2222.                 blockType, blockModifier = clsTurtle.getBlockType(self, "forward")
  2223.             end
  2224.         end
  2225.         if blockType ~= "" then --block found
  2226.             success = true
  2227.             if string.find(itemList, blockType) ~= nil then
  2228.                 success = false
  2229.             end
  2230.         end
  2231.         if success then
  2232.             -- check if diamond. if so ensure space in inventory
  2233.             if blockType == "minecraft:diamond_ore" then
  2234.                 clsTurtle.dumpRefuse(self)
  2235.             end
  2236.         end
  2237.         return success, blockType
  2238.     end
  2239.    
  2240.     function clsTurtle.isVegetation(self, blockName)
  2241.         blockName = blockName or ""
  2242.         local isVeg = false
  2243.         local vegList = {"minecraft:tallgrass", "minecraft:deadbush", "minecraft:cactus", "minecraft:leaves",
  2244.                          "minecraft:pumpkin", "minecraft:melon_block", "minecraft:vine", "minecraft:mycelium", "minecraft:waterliliy",
  2245.                          "minecraft:cocoa", "minecraft:double_plant", "minecraft:sponge", "minecraft:wheat"}
  2246.        
  2247.         -- check for flower, mushroom
  2248.         if string.find(blockName, "flower") ~= nil or string.find(blockName, "mushroom") ~= nil then
  2249.             isVeg = true
  2250.         end
  2251.         if not isVeg then
  2252.             for _,v in pairs(vegList) do
  2253.                 if v == blockName then
  2254.                     isVeg = true
  2255.                     break
  2256.                 end
  2257.             end
  2258.         end
  2259.        
  2260.         return isVeg
  2261.     end
  2262.    
  2263.     function clsTurtle.isWaterOrLava(self, direction)
  2264.         direction = direction or "forward"
  2265.         local block = ""
  2266.         local blockType = -1
  2267.         if not clsTurtle.detect(self, direction) then --air, water or lava
  2268.             --print("block "..direction.." is air, water or lava")
  2269.             block, blockType = clsTurtle.getBlockType(self, direction)
  2270.             --print("block "..direction.." is "..tostring(block).." metadata = "..tostring(blockType))
  2271.             if block == nil then
  2272.                 block = ""
  2273.                 blockType = -1
  2274.             elseif block == "minecraft:lava" then
  2275.                 clsTurtle.place(self, "minecraft:bucket", -1, direction, false)
  2276.             end
  2277.         end
  2278.         return block, blockType
  2279.     end
  2280.    
  2281.     function clsTurtle.menu(self, title, list)
  2282.         local retValue = 0
  2283.         response = true
  2284.         while response do
  2285.             response = false
  2286.             clsTurtle.clear(self)
  2287.             print(title.."\n")
  2288.             for i = 1, #list, 1 do
  2289.                 print("\t"..i..".  "..list[i])
  2290.             end
  2291.             print("Type number of your choice (1 to "..#list..")_")
  2292.             event, param1 = os.pullEvent ("char")
  2293.             local choice = tonumber(param1)
  2294.             if choice ~= nil then -- number typed
  2295.                 if choice >= 1 or choice <= #list then
  2296.                     retValue = choice
  2297.                 end
  2298.             else
  2299.                 print()
  2300.                 print("Incorrect input: "..param1)
  2301.                 print()
  2302.                 print("Type numbers only, from 1 to "..#list)
  2303.                 sleep(2)
  2304.                 response = true
  2305.             end
  2306.         end
  2307.         return retValue -- 1 to no of items in the list
  2308.     end
  2309.    
  2310.     function clsTurtle.place(self, blockType, damageNo, direction, leaveExisting)
  2311.         if leaveExisting == nil then
  2312.             leaveExisting = true
  2313.         end
  2314.         local success = false
  2315.         local doContinue = true
  2316.         local slot
  2317.         local dig = true
  2318.         if blockType == "" then --use any
  2319.             slot = turtle.getSelectedSlot()
  2320.             if  clsTurtle.getItemName(self, i) == "minecraft:sand" or clsTurtle.getItemName(self, i) == "minecraft:gravel" then
  2321.                 for i = 1, 16 do
  2322.                     if turtle.getItemCount(i) > 0 then
  2323.                         local name = clsTurtle.getItemName(self, i)
  2324.                         if  name ~= "minecraft:sand" and name ~= "minecraft:gravel" then
  2325.                             slot = i
  2326.                             print("debug ".. name.." found slot "..i)
  2327.                             break
  2328.                         end
  2329.                     end
  2330.                 end
  2331.             end
  2332.         else
  2333.             slot = clsTurtle.getItemSlot(self, blockType, damageNo)
  2334.         end
  2335.         local existingBlock, modifier = clsTurtle.getBlockType(self, direction)
  2336.         if leaveExisting then -- do not remove existing block unless sand gravel water or lava
  2337.             -- check if water / lava
  2338.             if clsTurtle.detect(self, direction) then -- not water or lava
  2339.                 if blockType == "" then -- place any block
  2340.                     if existingBlock ~= "minecraft:sand" and existingBlock ~= "minecraft:gravel" then --leave anything except sand/gravel      
  2341.                         print("debug existing block: "..existingBlock)
  2342.                         doContinue = false
  2343.                         success = true
  2344.                     end
  2345.                 else --place specific block
  2346.                     -- ignore dirt, grass, stone, cobble
  2347.                     if existingBlock == "minecraft:dirt" or existingBlock == "minecraft:stone" or
  2348.                        existingBlock == "minecraft:cobblestone" or existingBlock == "minecraft:grass" then         
  2349.                         doContinue = false
  2350.                         success = true
  2351.                     end
  2352.                 end
  2353.             end    
  2354.         end
  2355.         if doContinue then -- water or lava in next block or leaveExisting = false
  2356.             while clsTurtle.dig(self, direction) do
  2357.                 sleep(0.5)
  2358.             end
  2359.             if slot > 0 then
  2360.                 if direction == "down" then
  2361.                     turtle.select(slot)
  2362.                     if turtle.placeDown() then
  2363.                         if blockType == "minecraft:bucket" then
  2364.                             if turtle.refuel() then
  2365.                                 --clsTurtle.saveToLog("Refuelled with lava. Current fuel level: "..turtle.getFuelLevel())
  2366.                             end
  2367.                         end
  2368.                         success = true
  2369.                     else -- not placeDown
  2370.                         if blockType == "" then
  2371.                             local done = false
  2372.                             while not done do
  2373.                                 for i = 1, 16 do
  2374.                                     if turtle.getItemCount(i) > 0 then
  2375.                                         if  clsTurtle.getItemName(self, i) ~= "minecraft:sand" and clsTurtle.getItemName(self, i) ~= "minecraft:gravel" then
  2376.                                             turtle.select(i)
  2377.                                             if turtle.placeDown() then
  2378.                                                 done = true
  2379.                                                 success = true
  2380.                                                 break
  2381.                                             end
  2382.                                         end
  2383.                                     end
  2384.                                 end
  2385.                                 if not done then
  2386.                                     print("Out of blocks to place")
  2387.                                     sleep(10)
  2388.                                 end
  2389.                             end
  2390.                         else
  2391.                             if not clsTurtle.attack(self, "down") then
  2392.                                 print("Error placing "..blockType.." ? chest or minecart below")
  2393.                                 --clsTurtle.saveToLog("Error placing "..blockType.." ? chest or minecart below")
  2394.                             end
  2395.                         end
  2396.                     end
  2397.                 elseif direction == "up" then
  2398.                     turtle.select(slot)
  2399.                     if turtle.placeUp() then
  2400.                         if blockType == "minecraft:bucket" then
  2401.                             if turtle.refuel() then
  2402.                                 --clsTurtle.saveToLog("Refuelled with lava. Current fuel level: "..turtle.getFuelLevel())
  2403.                             end
  2404.                         end
  2405.                         success = true
  2406.                     else
  2407.                         if blockType == "" then
  2408.                             local done = false
  2409.                             while not done do
  2410.                                 for i = 1, 16 do
  2411.                                     if turtle.getItemCount(i) > 0 then
  2412.                                         if  clsTurtle.getItemName(self, i) ~= "minecraft:sand" and clsTurtle.getItemName(self, i) ~= "minecraft:gravel" then
  2413.                                             turtle.select(i)
  2414.                                             if turtle.placeUp() then
  2415.                                                 success = true
  2416.                                                 done = true
  2417.                                                 break
  2418.                                             end
  2419.                                         end
  2420.                                     end
  2421.                                 end
  2422.                                 if not done then
  2423.                                     print("Out of blocks to place")
  2424.                                     sleep(10)
  2425.                                 end
  2426.                             end
  2427.                         end
  2428.                     end
  2429.                 else -- place forward
  2430.                     turtle.select(slot)
  2431.                     if turtle.place() then
  2432.                         if blockType == "minecraft:bucket" then
  2433.                             if turtle.refuel() then
  2434.                                 print("Refuelled with lava. Current fuel level: "..turtle.getFuelLevel())
  2435.                                 --clsTurtle.saveToLog("Refuelled with lava. Current fuel level: "..turtle.getFuelLevel())
  2436.                             end
  2437.                         end
  2438.                         success = true
  2439.                     else --block not placed
  2440.                         if blockType == "" then --any block will do
  2441.                             local done = false
  2442.                             while not done do
  2443.                                 for i = 1, 16 do
  2444.                                     if turtle.getItemCount(i) > 0 then
  2445.                                         if  clsTurtle.getItemName(self, i) ~= "minecraft:sand" and clsTurtle.getItemName(self, i) ~= "minecraft:gravel" then
  2446.                                             turtle.select(i)
  2447.                                             if turtle.place() then
  2448.                                                 success = true
  2449.                                                 done = true
  2450.                                                 break
  2451.                                             end
  2452.                                         end
  2453.                                     end
  2454.                                 end
  2455.                                 if not done then
  2456.                                     print("Out of blocks to place. Remove sand and gravel")
  2457.                                     sleep(10)
  2458.                                 end
  2459.                             end
  2460.                         end
  2461.                     end
  2462.                 end
  2463.             end
  2464.         end
  2465.         return success, slot
  2466.     end
  2467.    
  2468.     function clsTurtle.refuel(self, minLevel)  
  2469.         minLevel = minLevel or 15
  2470.         local itemSlot = 0
  2471.         local slot = turtle.getSelectedSlot()
  2472.         local count = 0
  2473.         local item = ""
  2474.         local damage = 0
  2475.         local refuelOK = false
  2476.  
  2477.         if turtle.getFuelLevel() < minLevel or minLevel == 0 then
  2478.             -- check each slot for fuel item
  2479.             for i = 1, 16 do
  2480.                 count, item, damage = clsTurtle.getSlotContains(self, i)
  2481.                 if item == "minecraft:lava_bucket" then
  2482.                     turtle.select(i)
  2483.                     if turtle.refuel(1) then
  2484.                         print("refuelled with lava: "..turtle.getFuelLevel())
  2485.                         refuelOK = true
  2486.                         break
  2487.                     end
  2488.                 end
  2489.                 if item == "minecraft:coal" then
  2490.                     turtle.select(i)
  2491.                     if turtle.refuel(1) then
  2492.                         while turtle.getFuelLevel() < minLevel and turtle.getItemCount(i) > 0 do
  2493.                             turtle.refuel(1)
  2494.                         end
  2495.                         print("refuelled with coal: "..turtle.getFuelLevel())
  2496.                         refuelOK = true
  2497.                     end
  2498.                 end
  2499.             end
  2500.             if not refuelOK then
  2501.                 for i = 1, 16 do
  2502.                     count, item, damage = clsTurtle.getSlotContains(self, i)
  2503.                     if item == "minecraft:planks" then
  2504.                         turtle.select(i)
  2505.                         if turtle.refuel(1) then
  2506.                             while turtle.getFuelLevel() < minLevel and turtle.getItemCount(i) > 0 do
  2507.                                 turtle.refuel(1)
  2508.                             end
  2509.                             print("refuelled with planks: "..turtle.getFuelLevel())
  2510.                             refuelOK = true
  2511.                         end
  2512.                     end
  2513.                 end
  2514.             end
  2515.             if not refuelOK then
  2516.                 local success = false
  2517.                 for i = 1, 16 do
  2518.                     count, item, damage = clsTurtle.getSlotContains(self, i)
  2519.                     if item == "minecraft:log" or item == "minecraft:log2"  then --logs onboard
  2520.                         print("Refuelling with log slot "..tostring(i)..", crafting planks")
  2521.                         if clsTurtle.craft(self, "minecraft:planks", 4) then
  2522.                             success = true
  2523.                         else
  2524.                             print("refuel() error crafting planks")
  2525.                         end
  2526.                         if success then
  2527.                             local planksSlot, damage, count = T:getItemSlot("minecraft:planks")
  2528.                             turtle.select(planksSlot)
  2529.                             if turtle.refuel() then
  2530.                                 refuelOK = true
  2531.                             end
  2532.                         end
  2533.                     end
  2534.                 end
  2535.             end
  2536.             if not refuelOK and turtle.getFuelLevel() == 0 then
  2537.                 --term.clear()
  2538.                 term.setCursorPos(1,1)
  2539.                 print("Unable to refuel: "..turtle.getFuelLevel().." fuel remaining")
  2540.                 error()
  2541.             end
  2542.         end
  2543.         turtle.select(slot)
  2544.        
  2545.         return refuelOK
  2546.     end
  2547.    
  2548.     function clsTurtle.selectPlaceItem(self, item, useDamage)
  2549.         local success = false
  2550.         clsTurtle.getItemSlot(self, item, useDamage)
  2551.         if self.placeSlot > 0 then
  2552.             self.placeItem = item
  2553.         end
  2554.     end
  2555.    
  2556.     function clsTurtle.setEquipment(self)
  2557.         -- if contains a crafting table, puts it on the right. Any other tool on the left
  2558.         clsTurtle.clear(self)
  2559.         print("Setting up equipment...")
  2560.         local emptySlotR = clsTurtle.getFirstEmptySlot(self) -- first empty slot
  2561.         if emptySlotR == 0 then -- all slots full
  2562.             turtle.select(16)
  2563.             turtle.drop()
  2564.             emptySlotR = 16
  2565.         end
  2566.         local emptySlotL = 0 -- used later
  2567.         local eqRight = ""
  2568.         local eqLeft = ""
  2569.         local equippedRight = ""
  2570.         local equippedLeft = ""
  2571.         local count = 0
  2572.         local damage = 0
  2573.         local pickaxeSlot, damage, total = clsTurtle.getItemSlot(self, "minecraft:diamond_pickaxe")
  2574.         local craftTableSlot, damage, total = clsTurtle.getItemSlot(self, "minecraft:crafting_table")
  2575.         if emptySlotR > 0 then -- empty slot found
  2576.             turtle.select(emptySlotR)
  2577.             if turtle.equipRight() then -- remove tool on the right
  2578.                 count, eqRight, damage = clsTurtle.getSlotContains(self, emptySlotR) -- eqRight contains name of tool from right side
  2579.                 if eqRight == "minecraft:crafting_table" then
  2580.                     craftTableSlot = emptySlotR
  2581.                     eqRight = ""
  2582.                 elseif eqRight == "minecraft:diamond_pickaxe" then
  2583.                     pickaxeSlot = emptySlotR
  2584.                     eqRight = ""
  2585.                 end -- eqRight
  2586.                 emptySlotL = clsTurtle.getFirstEmptySlot(self) -- get next empty slot
  2587.                 if emptySlotL == 0 then -- all slots full
  2588.                     if emptySlotR ~= 15 then
  2589.                         turtle.select(15)
  2590.                         turtle.drop()
  2591.                         emptySlotL = 15
  2592.                     else
  2593.                         turtle.select(16)
  2594.                         turtle.drop()
  2595.                         emptySlotL = 16
  2596.                     end
  2597.                 end
  2598.             else -- nothing equipped on right side
  2599.                 emptySlotL = emptySlotR
  2600.             end
  2601.             if emptySlotL > 0 then -- empty slot found
  2602.                 turtle.select(emptySlotL)
  2603.                 if turtle.equipLeft() then -- remove tool on the left
  2604.                     count, eqLeft, damage = clsTurtle.getSlotContains(self, emptySlotL) -- eqLeft contains name of tool from left side
  2605.                     if eqLeft == "minecraft:diamond_pickaxe" then
  2606.                         pickaxeSlot = emptySlotL
  2607.                         eqLeft = ""
  2608.                     elseif eqLeft == "minecraft:crafting_table" then
  2609.                         craftTableSlot = emptySlotL
  2610.                         eqLeft = ""
  2611.                     end
  2612.                 end
  2613.             end
  2614.             if pickaxeSlot > 0 then
  2615.                 turtle.select(pickaxeSlot)
  2616.                 turtle.equipLeft()
  2617.                 equippedLeft = "minecraft:diamond_pickaxe"     
  2618.             end
  2619.             if craftTableSlot > 0 then
  2620.                 turtle.select(craftTableSlot)
  2621.                 turtle.equipRight()
  2622.                 equippedRight = "minecraft:crafting_table"     
  2623.             end
  2624.         end
  2625.         -- any tools equipped except diamond_pickaxe and crafting_table have been removed to inventory
  2626.         return equippedRight, equippedLeft
  2627.     end
  2628.        
  2629.     function clsTurtle.sortInventory(self)
  2630.         local turns = 0
  2631.         local chestSlot = clsTurtle.getItemSlot(self, "minecraft:chest", -1) --get the slot number containing a chest
  2632.         local blockType, blockModifier
  2633.         local facing = self.facing
  2634.         --clsTurtle.saveToLog(self, "clsTurtle.sortInventory(self) started chest found in slot "..chestSlot, true)
  2635.         if chestSlot > 0 then -- chest found
  2636.             -- find empty block to place it.
  2637.             local chestDirection = clsTurtle.getPlaceChestDirection(self)
  2638.             blockType, blockModifier = clsTurtle.getBlockType(self, chestDirection)
  2639.             --clsTurtle.saveToLog(self, "clsTurtle.sortInventory(self) looking "..chestDirection.." for chest...", true)
  2640.             while blockType ~= "minecraft:chest" do --check if chest placed eg mob in the way
  2641.                 if clsTurtle.place(self, "minecraft:chest", -1, chestDirection) then
  2642.                     --clsTurtle.saveToLog(self, "clsTurtle.sortInventory(self) chest placed:"..chestDirection, true)
  2643.                     break
  2644.                 else
  2645.                     --clsTurtle.saveToLog(self, "clsTurtle.sortInventory(self) chest NOT placed:"..chestDirection, true)
  2646.                     clsTurtle.dig(self, chestDirection) -- will force wait for mob
  2647.                     chestDirection = clsTurtle.getPlaceChestDirection(self)
  2648.                 end
  2649.                 blockType, blockModifier = clsTurtle.getBlockType(self, chestDirection)
  2650.             end
  2651.             -- fill chest with everything
  2652.             --clsTurtle.saveToLog(self, "clsTurtle.sortInventory(self) emptying turtle:"..chestDirection, true)
  2653.             for i = 1, 16 do
  2654.                 clsTurtle.drop(self, i, chestDirection)
  2655.             end
  2656.             -- remove everything
  2657.             --clsTurtle.saveToLog(self, "clsTurtle.sortInventory(self) refilling turtle:"..chestDirection, true)
  2658.             while clsTurtle.suck(self, chestDirection) do end
  2659.             clsTurtle.dig(self, chestDirection) -- collect chest
  2660.             --clsTurtle.saveToLog(self, "clsTurtle.sortInventory(self) chest collected("..chestDirection..")", true)
  2661.             while facing ~= self.facing do --return to original position
  2662.                 clsTurtle.turnLeft(self, 1)
  2663.             end
  2664.         end
  2665.     end
  2666.    
  2667.     function clsTurtle.suck(self, direction)
  2668.         direction = direction or "forward"
  2669.         turtle.select(1)
  2670.         local success = false
  2671.         if direction == "up" then
  2672.             if turtle.suckUp() then
  2673.                 success = true
  2674.             end
  2675.         elseif direction == "down" then
  2676.             if turtle.suckDown() then
  2677.                 success = true
  2678.             end
  2679.         else
  2680.             if turtle.suck() then
  2681.                 success = true
  2682.             end
  2683.         end
  2684.         return success
  2685.     end
  2686.        
  2687.     function clsTurtle.writeCoords(self, filename)
  2688.         -- create/overwrite e.g 'DungeonCoords.txt'
  2689.         local fileHandle = fs.open(filename, "w")
  2690.         fileHandle.writeLine("x="..self.x)
  2691.         fileHandle.writeLine("y="..self.y)
  2692.         fileHandle.writeLine("z="..self.z)
  2693.         fileHandle.writeLine("f="..self.facing)
  2694.         fileHandle.close()
  2695.         clsTurtle.saveToLog(self, filename.." file created", true)
  2696.         clsTurtle.saveToLog(self, "x = "..T:getX()..", y = "..T:getY()..", z = "..T:getZ()..", f = "..T:getFacing(), false)
  2697.     end
  2698.    
  2699.     --self.equippedRight, self.equippedLeft = clsTurtle.setEquipment(self) -- set in equipped items
  2700.    
  2701.     return self
  2702. end
  2703. --**********Functions**********
  2704. function checkFuelNeeded(quantity)
  2705.     local fuelNeeded = quantity - turtle.getFuelLevel() -- eg 600
  2706.     if fuelNeeded > 0 then
  2707.         T:checkInventoryForItem({"minecraft:lava_bucket", "minecraft:coal", "minecraft:planks"}, {1, math.ceil(fuelNeeded / 60), math.ceil(fuelNeeded / 15)}) -- 0 if not present
  2708.     end
  2709. end
  2710.  
  2711. function checkInventory(choice, size, width, length, height)
  2712.     -- run this loop 2x per second to check if player has put anything in the inventory
  2713.     -- fuel 1 coal = 60 = 4 planks. 64 planks = 16 coal = 960 units
  2714.     local retValue = ""
  2715.     local gotBirchSaplings = 0
  2716.     local gotCoal = 0
  2717.     local gotCobble = 0
  2718.     local gotDirt = 0
  2719.     local gotOakSaplings = 0
  2720.     local gotPlanks = 0
  2721.     local gotTorches = 0
  2722.     local thanks = "Thank you.\n\nPress the ESC key\n\nStand Back..\n"
  2723.    
  2724.     if choice >= 12 and choice  <= 16 then
  2725.         T:getCoords(true)
  2726.         home = createCoordinatesObject("homeLocation")
  2727.         home:setAllValues(T:getX(), T:getY(), T:getZ(), T:getFacing())
  2728.     end
  2729.     T:clear()
  2730.     if choice == 0 then --Missing pickaxe
  2731.         T:checkInventoryForItem({"minecraft:diamond_pickaxe"}, {1})
  2732.         print("Diamond Pickaxe being tested...")
  2733.         T:setEquipment()
  2734.     elseif choice == 1 then --Missing crafting table
  2735.         T:checkInventoryForItem({"minecraft:crafting_table", ""}, {1, 0}) -- 0 if not present
  2736.         print("Crafting table being tested...")
  2737.         T:setEquipment()
  2738.     elseif choice == 2 then --Missing chest
  2739.         retValue = T:checkInventoryForItem({"minecraft:chest"}, {1}) -- 0 if not present
  2740.         --print("Thanks for the "..retValue.."\n Continuing...")
  2741.         sleep(1.5)
  2742.     elseif choice == 11 then --Create Mine
  2743.         checkFuelNeeded(960)
  2744.         T:checkInventoryForItem({"minecraft:torch"}, {24}, false)
  2745.         T:checkInventoryForItem({"minecraft:cobblestone"}, {32})
  2746.         T:checkInventoryForItem({"minecraft:chest"}, {1})
  2747.         --print(thanks)
  2748.         sleep(2)
  2749.         print("CreateMine starting")
  2750.         createMine()
  2751.     elseif choice == 12 then    -- ladder to bedrock
  2752.         local level = T:getY()
  2753.         print("Current saved y level = "..level)
  2754.         print("\nIs this correct? (y/n + Enter)")
  2755.         if read() ~= "y" then
  2756.             level = getSize(true, "Current level (F3->Y coord)?_", 4, 300)
  2757.         end
  2758.         checkFuelNeeded(level * 2)
  2759.         T:checkInventoryForItem({"minecraft:ladder"}, {level})
  2760.         T:checkInventoryForItem({"minecraft:cobblestone", "minecraft:dirt"}, {64, 64})
  2761.         print(thanks)
  2762.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  2763.         print("Creating ladder to bedrock")
  2764.         createLadder("bedrock", level)
  2765.     elseif choice == 13 then    -- ladder to surface
  2766.         local level = T:getY()
  2767.         print("Current saved y level = "..level)
  2768.         print("\nIs this correct? (y/n + Enter)")
  2769.         if read() ~= "y" then
  2770.             level = getSize(true,"Current level (F3->Y coord)?_", 4, 300)
  2771.         end
  2772.         checkFuelNeeded((64 - level) * 2)
  2773.         T:checkInventoryForItem({"minecraft:ladder"}, {64 - level + 10}) -- allow 10 extra for luck
  2774.         T:checkInventoryForItem({"minecraft:cobblestone", "minecraft:dirt"}, {192, 192})
  2775.         print(thanks)
  2776.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  2777.         print("Creating ladder to surface")
  2778.         createLadder("surface", level)
  2779.     elseif choice == 14 or choice == 15 then    -- stairs to bedrock or surface
  2780.         local level = T:getY()
  2781.         print("Current saved y level = "..level)
  2782.         print("\nIs this correct? (y/n + Enter)")
  2783.         if read() ~= "y" then
  2784.             level = getSize(true,"Current level (F3->Y coord)?_", 4, 300)
  2785.         end
  2786.         if level >= 60 then --assume going down
  2787.             checkFuelNeeded(level * 10)
  2788.         else -- assume going up
  2789.             checkFuelNeeded((64 - level) * 10)
  2790.         end
  2791.         T:clear()
  2792.         print("Add any stairs already crafted")
  2793.         print("Press enter when ready")
  2794.         read()
  2795.         local numStairsNeeded = 0
  2796.         if choice == 14 then
  2797.             numStairsNeeded = math.ceil(level / 4)
  2798.         else
  2799.             numStairsNeeded = math.ceil((64 - level) / 4)
  2800.         end
  2801.         local numStairs = T:getItemCount("minecraft:stone_stairs", 0)
  2802.         local cobbleNeeded = 256
  2803.         if numStairs > 0 then
  2804.             cobbleNeeded = 192 - (math.floor((2 * numStairs) / 3))
  2805.             if cobbleNeeded < 64 then
  2806.                 cobbleNeeded = 64
  2807.             end
  2808.         end
  2809.         T:checkInventoryForItem({"minecraft:cobblestone"}, {cobbleNeeded})
  2810.         print(thanks)
  2811.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  2812.         if choice == 14 then
  2813.             print("Creating stairs to bedrock")
  2814.             createStaircase("bedrock", level)
  2815.         else
  2816.             print("Creating stairs to surface")
  2817.             createStaircase("surface", level)
  2818.         end
  2819.     elseif choice == 16 then    -- search for mob spawner
  2820.         local level = T:getY()
  2821.         print("Current saved y level = "..level)
  2822.         print("\nIs this correct? (y/n + Enter)")
  2823.         if read() ~= "y" then
  2824.             level = getSize(true,"Current level (F3->Y coord)?_", 4, 300)
  2825.         end
  2826.         checkFuelNeeded(3000)
  2827.         --T:checkInventoryForItem({"minecraft:ladder"}, {level})
  2828.         T:checkInventoryForItem({"minecraft:ladder"}, {6})  -- single level per turtle max 6 needed
  2829.         T:checkInventoryForItem({"minecraft:bucket"}, {1})  -- in case lava found          
  2830.         T:checkInventoryForItem({"minecraft:cobblestone", "minecraft:dirt"}, {192, 192})
  2831.         T:checkInventoryForItem({"minecraft:torch"}, {160}, false)
  2832.         print(thanks)
  2833.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  2834.         print("Searching for mob spawner")
  2835.         searchForSpawner(level)
  2836.     elseif choice == 17 then --Decapitate volcano
  2837.         checkFuelNeeded(width * length * 8)
  2838.         T:checkInventoryForItem({"minecraft:bucket"}, {1})  -- in case lava found
  2839.         print(thanks)
  2840.         os.sleep(2)    -- pause for 2 secs to allow time to press esc      
  2841.         print("Decapitatin volcano: size "..width.. " x "..length)
  2842.         clearArea(width, length, false)
  2843.     elseif choice == 21 or choice == 31 then --Clear area
  2844.         checkFuelNeeded(width * length * 3)
  2845.         T:checkInventoryForItem({"minecraft:dirt"}, {64})
  2846.         print(thanks)
  2847.         sleep(2)
  2848.         print("Clearing area: size "..width.. " x "..length)
  2849.         clearArea(width, length, true)
  2850.     elseif choice == 22 then --Create treefarm
  2851.         if size == 1 then
  2852.             checkFuelNeeded(300)
  2853.         else
  2854.             checkFuelNeeded(900)
  2855.         end
  2856.         T:checkInventoryForItem({"minecraft:dirt"}, {64})
  2857.         if size == 1 then
  2858.             T:checkInventoryForItem({"minecraft:torch"}, {16}, false)
  2859.         else
  2860.             T:checkInventoryForItem({"minecraft:torch"}, {64}, false)
  2861.         end
  2862.         print(thanks)
  2863.         sleep(2)
  2864.         print("CreateTreefarm starting: size "..size)
  2865.         createTreefarm(size)
  2866.     elseif choice == 23 then -- Plant treefarm
  2867.         if size == 1 then
  2868.             checkFuelNeeded(180)
  2869.         else
  2870.             checkFuelNeeded(480)
  2871.         end
  2872.         T:checkInventoryForItem({"minecraft:sapling"}, {4})
  2873.         print(thanks)
  2874.         print("plantTreefarm starting: size "..size)
  2875.         plantTreefarm(size)
  2876.     elseif choice == 24 then    -- Harvest treefarm
  2877.         print(thanks)
  2878.         os.sleep(2)
  2879.         print("Harvesting treefarm starting: size "..size)
  2880.         harvestTreeFarm(size)
  2881.     elseif choice == 25 then    -- Fell tree
  2882.         if T:isLog("forward") then
  2883.             T:checkInventoryForItem({"minecraft:chest"}, {1}, false)
  2884.             T:forward(1)
  2885.             T:harvestWholeTree("up")
  2886.             print("Press esc within 2 seconds!")
  2887.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  2888.             print("Felling tree")
  2889.         else
  2890.             print("No log in front..")
  2891.             print("Move me in front of a tree!")
  2892.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  2893.             retValue = ""
  2894.         end
  2895.     elseif choice == 26 then    -- Manage auto-treefarm
  2896.         -- if turtle in front of:
  2897.         -- empty block: assume not constructed, but check air below / chest behind
  2898.         -- sapling: wait for growth to tree
  2899.         -- tree: assume harvest
  2900.         local inFront, subType = T:getBlockType("forward")
  2901.         local createNew = false
  2902.         sleep(1.5)
  2903.         if inFront == nil then -- check if air below
  2904.             print("No sapling or tree found\nChecking block below")
  2905.             inFront, subType = T:getBlockType("down")
  2906.             if inFront == nil then -- air below
  2907.                 print("No block found below, but no sapling")
  2908.                 print("or tree in front.\n")
  2909.                 print("please repair the farm and try again")
  2910.                 retValue = ""
  2911.             else
  2912.                 createNew = true
  2913.             end
  2914.         elseif inFront == "minecraft:log" or inFront == "minecraft:log2" then
  2915.             harvestAutoTreeFarm()
  2916.             plantAutoTreeFarm()
  2917.         elseif inFront == "minecraft:sapling" then
  2918.             -- wait for trees, or player removes it
  2919.             -- if changes to log, harvest tree farm
  2920.             local timePassed = 0
  2921.             local blockType, blockModifier = T:getBlockType("forward")
  2922.             while true do
  2923.                 T:clear()
  2924.                 blockType, blockModifier = T:getBlockType("forward")
  2925.                 if blockType == "minecraft:sapling" then
  2926.                     print("Waiting for sapling to grow...")
  2927.                     print(timePassed.." seconds passed...")
  2928.                     sleep(10)
  2929.                     timePassed = timePassed + 10
  2930.                 elseif blockType == "minecraft:log" or blockType == "minecraft:log2" then
  2931.                     harvestAutoTreeFarm()
  2932.                     plantAutoTreeFarm()
  2933.                     timePassed = 0
  2934.                     -- wait for next sapling growth
  2935.                 else
  2936.                     print("No log or sapling in front..")
  2937.                     print("terminating program")
  2938.                     break
  2939.                 end
  2940.             end
  2941.         else
  2942.             createNew = true
  2943.         end
  2944.         if createNew then
  2945.             print("On ground. Creating tree farm...")
  2946.             checkFuelNeeded(300)
  2947.             T:checkInventoryForItem({"minecraft:chest"}, {3})
  2948.             T:checkInventoryForItem({"minecraft:dirt"}, {64})
  2949.             T:checkInventoryForItem({"minecraft:cobblestone"}, {128})
  2950.             T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  2951.             T:checkInventoryForItem({"minecraft:hopper"}, {1})
  2952.             T:checkInventoryForItem({"minecraft:torch"}, {6})
  2953.             T:checkInventoryForItem({"minecraft:sapling"}, {6})
  2954.             print(thanks)
  2955.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  2956.             print("Creating automatic tree farm...")
  2957.             createAutoTreeFarm()
  2958.             -- plant saplings
  2959.             -- wait for trees
  2960.             -- harvest tree farm
  2961.         end
  2962.     elseif choice == 32 then    -- Create wheat farm
  2963.         -- needs a diamond hoe and axe either in the inventory, or already equipped (NOT together)
  2964.         local itemEquipped = T:getEquipped("left") --tools already swapped to put crafting table on the right
  2965.         if itemEquipped == "minecraft:diamond_hoe" then
  2966.             if T:getItemSlot("minecraft:diamond_pickaxe", 0) == 0 then
  2967.                 T:checkInventoryForItem({"minecraft:diamond_pickaxe"}, {1})
  2968.             end
  2969.             -- ensure pickaxe is equipped
  2970.             T:equip("left", "minecraft:diamond_pickaxe", 0)
  2971.             print("\nDO NOT REMOVE THE HOE FROM MY INVENTORY!")
  2972.             sleep(2)
  2973.         end
  2974.         local clearFirst = false
  2975.         local decision  = ""
  2976.         local fuelNeeded = 0
  2977.         while decision ~= "y" and decision ~= "n" do
  2978.             T:clear()
  2979.             print("Is there a clear flat area at least\n9 x 12 in front of me? (y/n)\n\n(Area will be cleared first if not)")
  2980.             decision = read()
  2981.         end
  2982.         if decision == "n" then -- area needs clearing
  2983.             clearFirst = true
  2984.             checkFuelNeeded(480)
  2985.         else
  2986.             checkFuelNeeded(480)
  2987.             T:checkInventoryForItem({"minecraft:dirt"}, {64})
  2988.         end
  2989.         T:checkInventoryForItem({"minecraft:cobblestone"}, {40})
  2990.         T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  2991.         T:checkInventoryForItem({"minecraft:chest"}, {2})
  2992.         T:checkInventoryForItem({"minecraft:hopper"}, {1})
  2993.         print(thanks)
  2994.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  2995.         print("Creating 8x8 Wheat farm")
  2996.         createWheatFarm(clearFirst)
  2997.     elseif choice == 33 then    -- Plant wheat farm
  2998.         -- needs a diamond hoe either in the inventory, or already equipped (NOT together)
  2999.         local itemEquipped = T:getEquipped("left") --tools already swapped to put crafting table on the right
  3000.         local itemAvailable = ""
  3001.         if itemEquipped == "minecraft:diamond_pickaxe" then
  3002.             if T:getItemSlot("minecraft:diamond_hoe", 0) == 0 then
  3003.                 T:checkInventoryForItem({"minecraft:diamond_hoe"}, {1})
  3004.             end
  3005.             itemAvailable = "minecraft:diamond_hoe"
  3006.         end
  3007.         --ensure hoe is equipped
  3008.         if itemEquipped ~= "minecraft:diamond_hoe" then
  3009.             T:equip("left", "minecraft:diamond_hoe", 0)
  3010.             print("\nDO NOT REMOVE THE PICKAXE FROM MY INVENTORY!")
  3011.             sleep(2)
  3012.         end
  3013.         checkFuelNeeded(180)
  3014.         T:checkInventoryForItem({"minecraft:wheat_seeds"}, {8})
  3015.         print(thanks)
  3016.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3017.         print("Planting 8x8 Wheat farm")
  3018.         plantWheatFarm()
  3019.     elseif choice == 34 then    -- Harvest wheat farm
  3020.         checkFuelNeeded(180)
  3021.         T:checkInventoryForItem({"minecraft:bucket", "minecraft:water_bucket"}, {1, 1})
  3022.         print(thanks)
  3023.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3024.         print("Harvesting 8x8 Wheat farm")
  3025.         harvestWheatFarm()
  3026.     elseif choice == 41 then --harvest obsidian
  3027.         checkFuelNeeded(width * length * 3)
  3028.         T:checkInventoryForItem({"minecraft:cobblestone"}, {width * length})
  3029.         print(thanks)
  3030.         sleep(2)
  3031.         print("Harvesting obsidian area: size "..width.. " x "..length)
  3032.         harvestObsidian(width, length)
  3033.     elseif choice == 42 then --build nether portal
  3034.         checkFuelNeeded(20)
  3035.         T:checkInventoryForItem({"minecraft:obsidian"}, {10})
  3036.         T:checkInventoryForItem({"minecraft:cobblestone"}, {8})
  3037.         print(thanks)
  3038.         sleep(2)
  3039.         print("Building Nether portal")
  3040.         buildPortal()
  3041.     elseif choice == 43 then --demolish nether portal
  3042.         checkFuelNeeded(20)
  3043.         print("Demolishing Nether portal")
  3044.         demolishPortal()
  3045.     elseif choice == 51 then    -- bridge over void/water/lava
  3046.         checkFuelNeeded((size + 1) * 2)
  3047.         T:checkInventoryForItem({"minecraft:cobblestone",  "minecraft:dirt"}, {size * 2, size * 2})
  3048.         print(thanks)
  3049.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3050.         print("Building bridge ".. size.." blocks")
  3051.         createBridge(size)
  3052.     elseif choice == 52 then    -- covered walkway
  3053.         checkFuelNeeded((size + 1) * 2)
  3054.         T:checkInventoryForItem({"minecraft:cobblestone", "minecraft:dirt"}, {size * 2, size * 2})
  3055.         T:checkInventoryForItem({"minecraft:torch"}, {math.ceil(size / 8)})
  3056.         print(thanks)
  3057.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3058.         print("Building bridge ".. size.." blocks")
  3059.         createWalkway(size)
  3060.     elseif choice == 53 then    -- continuous path over void/water/lava
  3061.         checkFuelNeeded(512) -- allow for 512 length
  3062.         T:checkInventoryForItem({"minecraft:cobblestone",  "minecraft:dirt"}, {64, 64}, false)
  3063.         T:checkInventoryForItem({"minecraft:torch"}, {64}, false)
  3064.         print(thanks)
  3065.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3066.         print("Building continuous path")
  3067.         createPath()
  3068.     elseif choice == 54 or choice == 55 then    -- canal management
  3069.         checkFuelNeeded(1024) -- allow for 1024 length
  3070.         --T:checkInventoryForItem({"minecraft:chest"}, {1})
  3071.         T:checkInventoryForItem({"minecraft:cobblestone",  "minecraft:dirt"}, {256, 256})
  3072.         if choice == 54 then
  3073.             T:checkInventoryForItem({"minecraft:torch"}, {64}, false)
  3074.         else --right side, flood canal
  3075.             T:checkInventoryForItem({"minecraft:water_bucket"}, {3})
  3076.         end
  3077.         print(thanks)
  3078.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3079.         print("Building canal")
  3080.         createCanal(choice, size, length) -- eg 55, 312, 1 = complete a canal 312 blocks long on top of the wall
  3081.     elseif choice == 61 then    --  block path over water
  3082.         checkFuelNeeded(size + 24) -- allow for 88 moves
  3083.         T:checkInventoryForItem({"minecraft:cobblestone"}, {88})
  3084.         T:checkInventoryForItem({"minecraft:stone"}, {1})
  3085.         T:checkInventoryForItem({"minecraft:torch"}, {8}, false)
  3086.         print(thanks)
  3087.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3088.         createMobSpawnerBase(size)
  3089.     elseif choice == 62 then    -- mob spawner tower
  3090.         checkFuelNeeded(1500) -- allow for 1000 blocks +  moves
  3091.         T:checkInventoryForItem({"minecraft:chest"}, {2})
  3092.         T:checkInventoryForItem({"minecraft:hopper"}, {2})
  3093.         T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  3094.         T:checkInventoryForItem({"minecraft:cobblestone"}, {576})
  3095.         T:checkInventoryForItem({"minecraft:stone"}, {1})
  3096.         print(thanks)
  3097.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3098.         createMobSpawnerTower(size)
  3099.     elseif choice == 63 then    -- mob spawner tank
  3100.         checkFuelNeeded(1000) -- allow for 500 blocks +  moves
  3101.         T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  3102.         T:checkInventoryForItem({"minecraft:cobblestone"}, {576})
  3103.         T:checkInventoryForItem({"minecraft:stone"}, {1})
  3104.         print(thanks)
  3105.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3106.         createMobSpawnerTank()
  3107.     elseif choice == 64 then    -- mob spawner roof
  3108.         checkFuelNeeded(500) -- allow for 400 blocks +  moves
  3109.         T:checkInventoryForItem({"minecraft:cobblestone"}, {384})
  3110.         T:checkInventoryForItem({"minecraft:torch"}, {20}, false)
  3111.         print(thanks)
  3112.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3113.         createMobSpawnerRoof()
  3114.     elseif choice == 71 then --Clear rectangle
  3115.         checkFuelNeeded(width * length)
  3116.         print("Clearing rectangle: size "..width.. " x "..length)
  3117.         clearRectangle(width, length)
  3118.     elseif choice == 72 then --Clear wall
  3119.         checkFuelNeeded(length * height)
  3120.         print("Recycling wall "..height.." blocks high")
  3121.         clearWall(1, length, height)
  3122.     elseif choice == 73 then --Clear single height perimeter wall
  3123.         checkFuelNeeded((width + length) * 2)
  3124.         print("Recycling wall section "..width.." x "..length)
  3125.         clearPerimeterWall(width, length, 1)
  3126.     elseif choice == 74 then --Clear floor and perimeter walls
  3127.         checkFuelNeeded((width * length) + ((width + length) * height))
  3128.         print("Recycling building and floor "..width.." x "..length.." height: "..height)
  3129.         clearBuilding(width, length, height, false)
  3130.     elseif  choice == 76 or choice == 87 then --Hollow structure
  3131.         checkFuelNeeded(width * length * height)
  3132.         print("Creating hollow cube "..width.." x "..length.." height: "..height)
  3133.         buildHollow(width, length, height)
  3134.     elseif  choice == 77 or choice == 88 then --solid structure
  3135.         checkFuelNeeded(width * length * height)
  3136.         T:checkInventoryForItem({"minecraft:cobblestone", "minecraft:dirt"}, {width * length * height, width * length * height}, false)
  3137.         print("Creating solid cube "..width.." x "..length.." height: "..height)
  3138.         buildSolid(width, length, height)
  3139.     elseif  choice == 78 then --remove hollow structure bottom up
  3140.         checkFuelNeeded(width * length * height)
  3141.         print("Removing structure "..width.." x "..length.." height: "..height)
  3142.         clearHollow(width, length, height)
  3143.     elseif  choice == 79 then --remove solid structure bottom up
  3144.         checkFuelNeeded(width * length * height)
  3145.         print("Removing structure "..width.." x "..length.." height: "..height)
  3146.         clearSolid(width, length, height)
  3147.     elseif choice == 81 then --build containing wall in water or lava
  3148.         checkFuelNeeded(length * length)
  3149.         T:checkInventoryForItem({"minecraft:cobblestone",  "minecraft:dirt"}, {1024, 1024}, false)
  3150.         print("Building retaining wall in lava/water. length"..length)
  3151.         buildRetainingWall(length, height)
  3152.     elseif choice == 82 then --drop sand
  3153.         checkFuelNeeded(100)
  3154.         T:checkInventoryForItem({"minecraft:sand"}, {1024}, false)
  3155.         print("Building sand wall. length: "..length)
  3156.         buildSandWall(length)
  3157.     elseif choice == 83 then --decapitate and drop sand
  3158.         checkFuelNeeded(length * width)
  3159.         T:checkInventoryForItem({"minecraft:sand"}, {768}, false)
  3160.         print("Decapiating structure. length: "..length.." width: "..width)
  3161.         decapitateBuilding(width, length)
  3162.     elseif choice == 84 then --harvest sand
  3163.         checkFuelNeeded(100)
  3164.         print("Digging sand. length: "..length)
  3165.         clearSandWall(length)
  3166.     elseif choice == 85 then --remove sand cube
  3167.         checkFuelNeeded(length * width * 4)
  3168.         print("Removing sand cube. length: "..length.." width: "..width)
  3169.         clearSandCube(width, length)
  3170.     elseif choice == 86 then --remove floor and walls
  3171.         checkFuelNeeded(length * width * 4)
  3172.         print("Demolishing structure. length: "..length.." width: "..width)
  3173.         demolishBuilding(width, length)
  3174.     --elseif choice == 87 then check 76
  3175.     --elseif choice == 88 then check 77
  3176.     elseif choice == 91 then --place redstone torch level or downward slope
  3177.         checkFuelNeeded(10)
  3178.         local userChoice = T:checkInventoryForItem({"userChoice"}, {1})
  3179.         T:checkInventoryForItem({"minecraft:redstone_torch"}, {1})
  3180.         print("Placing redstone torch on ".. userChoice)
  3181.         placeRedstoneTorch("level", userChoice)
  3182.     elseif choice == 92 then --place redstone torch on upward slope
  3183.         checkFuelNeeded(10)
  3184.         local userChoice = T:checkInventoryForItem({"userChoice"}, {1})
  3185.         T:checkInventoryForItem({"minecraft:redstone_torch"}, {1})
  3186.         print("Placing redstone torch and ".. userChoice)
  3187.         placeRedstoneTorch("up", userChoice)
  3188.     elseif choice == 93 then --build downward slope
  3189.         checkFuelNeeded(height * 2)
  3190.         local userChoice = T:checkInventoryForItem({"userChoice"}, {height})
  3191.         T:checkInventoryForItem({"minecraft:redstone_torch"}, {math.ceil(height / 3)}, false)
  3192.         print("Building downward slope with ".. userChoice)
  3193.         createRailwayDown(userChoice, height)
  3194.     elseif choice == 94 then --build upward slope
  3195.         checkFuelNeeded(height * 2)
  3196.         local userChoice = T:checkInventoryForItem({"userChoice"}, {height + math.ceil(height / 3)})
  3197.         T:checkInventoryForItem({"minecraft:redstone_torch"}, {math.ceil(height / 3)}, false)
  3198.         print("Building upward slope with ".. userChoice)
  3199.         createRailwayUp(userChoice, height)
  3200.     end
  3201.     return retValue
  3202. end
  3203.  
  3204. function buildPortal()
  3205.     T:go("D1x1")
  3206.     T:place("minecraft:cobblestone", 0, "forward", true)
  3207.     for i = 1, 3 do
  3208.         T:go("U1x1")
  3209.         T:place("minecraft:obsidian", 0, "forward", true)
  3210.     end
  3211.     T:go("U1x1")
  3212.     T:place("minecraft:cobblestone", 0, "forward", true)
  3213.     for i = 1, 2 do
  3214.         T:go("R1F1L1x1")
  3215.         T:place("minecraft:obsidian", 0, "forward", true)
  3216.     end
  3217.     T:go("R1F1L1x1")
  3218.     T:place("minecraft:cobblestone", 0, "forward", true)
  3219.     for i = 1, 3 do
  3220.         T:go("D1x1")
  3221.         T:place("minecraft:obsidian", 0, "forward", true)
  3222.     end
  3223.     T:go("D1x1")
  3224.     T:place("minecraft:cobblestone", 0, "forward", true)
  3225.     for i = 1, 2 do
  3226.         T:go("L1F1R1x1")
  3227.         T:place("minecraft:obsidian", 0, "forward", true)
  3228.     end
  3229.     T:go("U1L1F1R1")
  3230. end
  3231.  
  3232. function buildHollow(width, length, height)
  3233.     --should be in bottom left corner at top of structure
  3234.     -- dig out blocks in front and place to the left side
  3235.     --go(path, useTorch, torchInterval, leaveExisting, checkDungeon)
  3236.     -- go @# = place any block up/forward/down # = 0/1/2
  3237.     for h = 1, height do
  3238.         for i = 1, length - 1 do
  3239.             T:go("L1@1R1F1", false, 0, true, false)
  3240.         end
  3241.         T:go("L1@1R2", false, 0, true, false)
  3242.         for i = 1, width - 1 do
  3243.             T:go("L1@1R1F1", false, 0, true, false)
  3244.         end
  3245.         T:go("L1@1R2", false, 0, true, false)
  3246.         for i = 1, length - 1 do
  3247.             T:go("L1@1R1F1", false, 0, true, false)
  3248.         end
  3249.         T:go("L1@1R2", false, 0, true, false)
  3250.         for i = 1, width - 1 do
  3251.             T:go("L1@1R1F1", false, 0, true, false)
  3252.         end
  3253.         T:go("L1@1R2", false, 0, true, false)
  3254.         -- hollowed out, now clear water/ blocks still present
  3255.         clearRectangle(width, length)
  3256.         if h < height then
  3257.             T:down(1)
  3258.         end
  3259.     end
  3260. end
  3261.  
  3262. function buildRetainingWall(length, height)
  3263.     if height <= 0 then
  3264.         height = 30
  3265.     end
  3266.     local y = 1
  3267.     -- go(path, useTorch, torchInterval, leaveExisting, checkDungeon)
  3268.     -- start at surface, move back 1 block
  3269.     -- each iteration completes 3 columns
  3270.     local numBlocks = T:getSolidBlockCount()
  3271.     if length == 1 then --single column
  3272.         while not turtle.detectDown() do
  3273.             T:down(1)
  3274.             y = y + 1
  3275.         end
  3276.         for i = 1, y - 1  do
  3277.             T:go("U1C2", false, 0, true, false)
  3278.         end
  3279.     elseif length == 2 then--down then up
  3280.         T:back(1)
  3281.         while not turtle.detectDown() do
  3282.             T:go("C1D1", false, 0, true, false)
  3283.             y = y + 1
  3284.         end
  3285.         T:forward(1)
  3286.         while not turtle.detectDown() do
  3287.             T:down(1)
  3288.             y = y + 1
  3289.         end
  3290.         T:go("B1C1", false, 0, true, false)
  3291.         for i = 1, y - 1 do
  3292.             T:go("U1C2", false, 0, true, false)
  3293.         end
  3294.         T:go("C1", false, 0, true, false)
  3295.     else -- length 3 or more eg 3,22; 11
  3296.         local remain = length % 3 -- 0; 1; 2 only possible results
  3297.         length = length - remain -- 3-0=3; 4-1=3; 5-2=3; 6-0=6
  3298.         for i = 3, length, 3 do -- 3, 6, 9, 12 etc
  3299.             numBlocks = T:getSolidBlockCount()
  3300.             if numBlocks < height * 3 then
  3301.                 --ask player for more
  3302.                 T:checkInventoryForItem({"minecraft:cobblestone",  "minecraft:dirt"}, {height * 3, height * 3}, false)
  3303.             end
  3304.             T:go("B1C1")
  3305.             if i > 3 then -- second iteration
  3306.                 T:go("B1C1")
  3307.             end
  3308.             -- place blocks forward while descending
  3309.             while not turtle.detectDown() do
  3310.                 T:go("C1D1", false, 0, true, false)
  3311.                 y = y + 1
  3312.             end
  3313.             -- may be higher than column in front
  3314.             T:forward(1)
  3315.             while not turtle.detectDown() do
  3316.                 T:down(1)
  3317.                 y = y + 1
  3318.             end
  3319.             while not turtle.detectUp() do 
  3320.                 T:go("U1C2")
  3321.                 y = y - 1
  3322.             end
  3323.             T:go("B1C1B1", false, 0, true, false)
  3324.             -- return to surface, placing forward and below
  3325.             for i = 1, y - 1 do
  3326.                 T:go("C1U1C2", false, 0, true, false)
  3327.             end
  3328.             -- put missing block down
  3329.             T:go("C1", false, 0, true, false)
  3330.             y = 1 -- reset counter
  3331.         end
  3332.         if remain == 1 then -- 1 more column
  3333.             y = 1
  3334.             T:back(1)          
  3335.             while not turtle.detectDown() do
  3336.                 T:down(1)
  3337.                 y = y + 1
  3338.             end
  3339.             for i = 1, y - 1 do
  3340.                 T:go("U1C2", false, 0, true, false)
  3341.             end
  3342.             -- put missing block down
  3343.             T:go("C1", false, 0, true, false)
  3344.         elseif remain == 2 then -- 2 cols
  3345.             y = 1
  3346.             T:back(1)
  3347.             while not turtle.detectDown() do
  3348.                 T:go("C1D1", false, 0, true, false)
  3349.                 y = y + 1
  3350.             end
  3351.             T:forward(1)
  3352.             while not turtle.detectDown() do
  3353.                 T:down(1)
  3354.                 y = y + 1
  3355.             end
  3356.             T:go("B1C1", false, 0, true, false)
  3357.             for i = 1, y - 1 do
  3358.                 T:go("U1C2", false, 0, true, false)
  3359.             end
  3360.             -- put missing block down
  3361.             T:go("C1", false, 0, true, false)
  3362.         end
  3363.     end
  3364. end
  3365.  
  3366. function buildSandWall(length)
  3367.     length = length or 0
  3368.     local success = true
  3369.     if length > 0 then
  3370.         for i = 1, length - 1 do
  3371.             success = dropSand()
  3372.             T:forward(1, false)
  3373.         end
  3374.         success = dropSand()
  3375.     else
  3376.         while not turtle.detectDown() do -- over water
  3377.             while not turtle.detectDown() do -- over water
  3378.                 success = dropSand()
  3379.             end
  3380.             if success then
  3381.                 T:forward(1, false)
  3382.             else -- out of sand
  3383.                 break
  3384.             end
  3385.         end
  3386.     end
  3387. end
  3388.  
  3389. function buildSolid(width, length, height)
  3390.     for i = 1, width do --width could be 1, 2, 3 etc
  3391.         buildRetainingWall(length, height)
  3392.         if i < width then --width = 2 or more
  3393.             if i == 1 or i % 2 == 1 then -- iteration 1, 3, 5
  3394.                 T:go("L1F1L2C1R1", false, 0, true, false)
  3395.             else
  3396.                 T:go("R1F1R2C1L1", false, 0, true, false)
  3397.             end
  3398.         end
  3399.     end
  3400. end
  3401.  
  3402. function clearArea(width, length, useDirt)
  3403.     if useDirt == nil then
  3404.         useDirt = true
  3405.     end
  3406.     local evenWidth = false
  3407.     local evenHeight = false
  3408.     local loopWidth
  3409.     -- go(path, useTorch, torchInterval, leaveExisting, checkDungeon)
  3410.     if width % 2 == 0 then
  3411.         evenWidth = true
  3412.         loopWidth = width / 2
  3413.     else
  3414.         loopWidth = math.ceil(width / 2)
  3415.     end
  3416.     if length % 2 == 0 then
  3417.         evenHeight = true
  3418.     end
  3419.     -- clear an area between 2 x 4 and 32 x 32
  3420.     -- if width is even no, then complete the up/down run
  3421.     -- if width odd no then finish at top of up run and reverse
  3422.     -- should be on flat ground, check voids below, harvest trees
  3423.     for x = 1, loopWidth do
  3424.         -- Clear first column (up)
  3425.         for y = 1, length do
  3426.             if useDirt then
  3427.                 if not turtle.detectDown() then
  3428.                     T:place("minecraft:dirt", -1, "down", true)
  3429.                 else --if not water, dirt, grass , stone then replace with dirt
  3430.                     blockType, blockModifier = T:getBlockType("down")
  3431.                     if blockType ~= "minecraft:grass" and blockType ~= "minecraft:dirt" and blockType ~= "minecraft:stone" and blockType ~= "minecraft:water" then
  3432.                         turtle.digDown()
  3433.                         T:place("minecraft:dirt", -1, "down", true)
  3434.                     end
  3435.                 end
  3436.             end
  3437.             blockType, blockModifier = T:getBlockType("forward")
  3438.             if blockType == "minecraft:log" or blockType == "minecraft:log2" then -- tree in front, so harvest it
  3439.                 T:harvestTree() --automatically moves forward 1 block
  3440.                 if y == length then -- move back 1 if already at max length
  3441.                     T:back(1)
  3442.                 end
  3443.             else
  3444.                 if y < length then
  3445.                     T:go("F1+1", false,0,false,true)
  3446.                 end
  3447.             end
  3448.         end
  3449.         -- clear second column (down)
  3450.         if x < loopWidth or (x == loopWidth and evenWidth) then -- go down if on width 2,4,6,8 etc
  3451.             T:go("R1F1+1R1", false,0,false,true)
  3452.             for y = 1, length do
  3453.                 if useDirt then
  3454.                     if not turtle.detectDown() then
  3455.                         T:place("minecraft:dirt", -1, "down", true)
  3456.                     else
  3457.                         blockType, blockModifier = T:getBlockType("down")
  3458.                         if blockType ~= "minecraft:grass" and blockType ~= "minecraft:dirt" and blockType ~= "minecraft:stone" and blockType ~= "minecraft:water" then
  3459.                             turtle.digDown()
  3460.                             T:place("minecraft:dirt", -1, "down", true)
  3461.                         end
  3462.                     end
  3463.                 end
  3464.                 blockType, blockModifier = T:getBlockType("forward")
  3465.                 if blockType == "minecraft:log" or blockType == "minecraft:log2" then -- tree in front, so harvest it
  3466.                     T:harvestTree()
  3467.                     if y == length then
  3468.                         T:back(1)
  3469.                     end
  3470.                 else
  3471.                     if y < length then
  3472.                         T:go("F1+1", false,0,false,true)
  3473.                     end
  3474.                 end
  3475.             end
  3476.             if x < loopWidth then
  3477.                 T:go("L1F1+1L1", false,0,false,true)
  3478.             else
  3479.                 T:turnRight(1)
  3480.                 T:forward(width - 1)
  3481.                 T:turnRight(1)
  3482.             end
  3483.         else -- equals width but is 1,3,5,7 etc
  3484.             T:turnLeft(2) --turn round 180
  3485.             T:forward(length - 1)
  3486.             T:turnRight(1)
  3487.             T:forward(width - 1)
  3488.             T:turnRight(1)
  3489.         end
  3490.     end
  3491. end
  3492.  
  3493. function clearBuilding(width, length, height, withCeiling)
  3494.     --clear floor
  3495.     clearRectangle(width, length)
  3496.     T:up(1)
  3497.     if withCeiling then
  3498.         clearPerimeterWall(width, length, height - 2)
  3499.         T:up(1)
  3500.         clearRectangle(width, length)
  3501.         T:down(1)
  3502.     else
  3503.         clearPerimeterWall(width, length, height - 1)
  3504.     end
  3505.     T:down(height - 1)
  3506. end
  3507.  
  3508. function clearHollow(width, length, height)
  3509.     if height == 0 then
  3510.         --need to check if anything above except bedrock
  3511.         local totalItemCount = 0
  3512.         repeat
  3513.             totalItemCount = T:getTotalItemCount()
  3514.             clearPerimeterWall(width, length, 1)
  3515.             T:up(1)
  3516.             height = height + 1
  3517.         until T:getTotalItemCount() == totalItemCount -- nothing collected or full inventory
  3518.     else
  3519.         clearPerimeterWall(width, length, height)
  3520.     end
  3521.     T:down(height)
  3522. end
  3523.  
  3524. function clearSolid(width, length, height)
  3525.     if height == 0 then
  3526.         --need to check if anything above except bedrock
  3527.         local totalItemCount = 0
  3528.         repeat
  3529.             totalItemCount = T:getTotalItemCount()
  3530.             clearRectangle(width, length)
  3531.             T:up(1)
  3532.             height = height + 1
  3533.         until T:getTotalItemCount() == totalItemCount -- nothing collected or full inventory
  3534.     else
  3535.         for i = 1, height do
  3536.             clearRectangle(width, length)
  3537.             T:up(1)
  3538.         end
  3539.        
  3540.     end
  3541.     T:down(height)
  3542. end
  3543.  
  3544. function clearPerimeterWall(width, length, height)
  3545.     -- go(path, useTorch, torchInterval, leaveExisting, checkDungeon)
  3546.     -- if height <= 0 then stop when nothing above
  3547.     if height > 0 then
  3548.         for i = 1, height do
  3549.             T:go("F"..tostring(length - 1)..
  3550.                  "R1F"..tostring(width - 1)..
  3551.                  "R1F"..tostring(length - 1)..
  3552.                  "R1F"..tostring(width - 1)..
  3553.                  "R1", false, 0, false, false)
  3554.             if i < height then
  3555.                 T:up(1)
  3556.             end
  3557.         end
  3558.     else
  3559.         repeat
  3560.             T:go("F"..tostring(length - 1)..
  3561.                  "R1F"..tostring(width - 1)..
  3562.                  "R1F"..tostring(length - 1)..
  3563.                  "R1F"..tostring(width - 1)..
  3564.                  "R1", false, 0, false, false)
  3565.             if turtle.detectUp() then
  3566.                 T:up(1)
  3567.             end
  3568.         until not turtle.detectUp()
  3569.     end
  3570. end
  3571.  
  3572. function clearRectangle(width, length)
  3573.     -- could be 1 wide x xx lenght (trench) up and return
  3574.     -- could be 2+ x 2+
  3575.     -- even no of runs return after last run
  3576.     -- odd no of runs forward, back, forward, reverse and return
  3577.     local directReturn = true
  3578.     if width % 2 == 1 then
  3579.         directReturn = false
  3580.     end
  3581.     if width == 1 then -- trench ahead
  3582.         T:go("F"..length - 1 .."R2F"..length - 1 .."R2")
  3583.     else
  3584.         if directReturn then -- width = 2,4,6,8 etc
  3585.             for i = 1, width, 2 do -- i = 1,3,5,7 etc
  3586.                 T:go("F"..length - 1 .."R1F1R1F"..length - 1)
  3587.                 if i < width - 2 then -- eg width = 8, i compares with 6: 1, 3, 5, 7
  3588.                     T:go("L1F1L1")
  3589.                 end
  3590.             end
  3591.             T:go("R1F"..width - 1 .."R1")
  3592.         else -- width = 3, 5, 7, 9 eg width 7
  3593.             for i = 1, width - 1, 2 do -- i = 1,3,5
  3594.                 T:go("F"..length - 1 .."R1F1R1F"..length - 1 .."L1F1L1")
  3595.             end
  3596.             -- one more run then return
  3597.             T:go("F"..length - 1 .."R2F"..length - 1 .."R1F"..width - 1 .."R1")
  3598.         end
  3599.     end
  3600. end
  3601.  
  3602. function clearSandWall(length)
  3603.     --dig down while on top of sand
  3604.     while T:getBlockType("down") == "minecraft:sand" do
  3605.         T:down(1)
  3606.     end
  3607.     -- repeat length times
  3608.     for i = 1, length do
  3609.         --if sand in front, dig
  3610.         while turtle.detect() do
  3611.             if T:getBlockType("forward") == "minecraft:sand" then
  3612.                 T:dig("forward")
  3613.             else --solid block, not sand so move up
  3614.                 T:up(1)
  3615.             end
  3616.         end
  3617.         --move forward
  3618.         T:forward(1)
  3619.         while T:getBlockType("down") == "minecraft:sand" do
  3620.             T:down(1)
  3621.         end
  3622.     end
  3623. end
  3624.  
  3625. function clearSandCube(width, length)
  3626.     --go down to bottom of sand
  3627.     while T:getBlockType("down") == "minecraft:sand" do
  3628.         T:down(1)
  3629.     end
  3630.     clearBuilding(width, length, 0, false)
  3631. end
  3632.  
  3633. function clearWall(width, length, height)
  3634.     local evenHeight = false
  3635.     local atStart = true
  3636.     local drop = height - 2
  3637.     -- go(path, useTorch, torchInterval, leaveExisting, checkDungeon)
  3638.     if height % 2 == 0 then
  3639.         evenHeight = true
  3640.     end
  3641.  
  3642.     -- dig along and up for specified length
  3643.     if evenHeight then --2, 4 , 6 etc
  3644.         for h = 2, height, 2 do
  3645.             for i = 1, length - 1 do
  3646.                 T:go("x0F1", false, 0, false, false)
  3647.             end
  3648.             if h < height then
  3649.                 T:go("R2U2", false, 0, false, false)
  3650.             end
  3651.             atStart = not atStart
  3652.         end
  3653.     else
  3654.         drop = height - 1
  3655.         for h = 1, height, 2 do
  3656.             if h == height then
  3657.                 T:go("F"..tostring(length - 1), false, 0, false, false)
  3658.             else
  3659.                 for i = 1, length - 1 do
  3660.                     T:go("x0F1", false, 0, false, false)
  3661.                 end
  3662.             end
  3663.             atStart = not atStart
  3664.             if h < height then
  3665.                 T:go("R2U2", false, 0, false, false)
  3666.             end
  3667.         end
  3668.     end
  3669.     if evenHeight then
  3670.         T:go("x0", false, 0, false, false)
  3671.     end
  3672.     T:go("R2D"..drop, false, 0, false, false)
  3673.     if not atStart then
  3674.         T:go("F"..tostring(length - 1).."R2", false, 0, false, false)
  3675.     end
  3676. end
  3677.  
  3678. function createAutoTreeFarm()
  3679.     T:clear()
  3680.     print("Clear the area first? (y/n)")
  3681.     local response = read()
  3682.     if response == "y" then
  3683.         createWheatFarm(true, 11, 14)
  3684.     else
  3685.         createWheatFarm(false)
  3686.     end
  3687.     -- flood area to collect saplings
  3688.     -- refill water buckets
  3689.     T:forward(1)
  3690.     for i = 1, 2 do
  3691.         sleep(0.5)
  3692.         T:place("minecraft:bucket", -1, "down", false)
  3693.     end
  3694.     T:go("F1U1F10R1F8R2")
  3695.     T:place("minecraft:water_bucket", -1, "down", false)
  3696.     T:forward(2)
  3697.     T:place("minecraft:water_bucket", -1, "down", false)
  3698.     T:go("F5L1F10D1")
  3699.     for i = 1, 2 do
  3700.         sleep(0.5)
  3701.         T:place("minecraft:bucket", -1, "down", false)
  3702.     end
  3703.     T:go("U1R2F10R1F3R2")
  3704.     T:place("minecraft:water_bucket", -1, "down", false)
  3705.     T:forward(2)
  3706.     T:place("minecraft:water_bucket", -1, "down", false)
  3707.     T:go("F1L1F10D1R2")
  3708.     for i = 1, 2 do
  3709.         sleep(0.5)
  3710.         T:place("minecraft:bucket", -1, "down", false)
  3711.     end
  3712.     T:go("U1F10R1")
  3713.     T:place("minecraft:water_bucket", -1, "down", false)
  3714.     T:go("F2R1U1F2")
  3715.     for i = 1, 3 do
  3716.         T:place("minecraft:dirt", -1, "down", false)
  3717.         T:up(1)
  3718.         T:place("minecraft:sapling", -1, "down", false)
  3719.         T:forward(1)
  3720.         T:down(1)
  3721.         T:place("minecraft:torch", -1, "down", false)
  3722.         T:forward(1)
  3723.     end
  3724.     T:go("L1F3L1F2")
  3725.     for i = 1, 3 do
  3726.         T:place("minecraft:dirt", -1, "down", false)
  3727.         T:up(1)
  3728.         T:place("minecraft:sapling", -1, "down", false)
  3729.         T:forward(1)
  3730.         T:down(1)
  3731.         T:place("minecraft:torch", -1, "down", false)
  3732.         T:forward(1)
  3733.     end
  3734.     T:go("L1F4L1F7L1F1R1")
  3735.     T:place("minecraft:chest", -1, "forward", false)
  3736.     T:turnLeft(2)
  3737. end
  3738.  
  3739. function createBridge(numBlocks)
  3740.     for i = 1, numBlocks do
  3741.         T:go("m1")
  3742.     end
  3743.     T:go("R1F1R1")
  3744.     for i = 1, numBlocks do
  3745.         T:go("m1")
  3746.     end
  3747. end
  3748.  
  3749. function createCanal(choice, size, length)
  3750.     -- choice = 54/55: left/right side
  3751.     -- size = 0-1024 o = continuousheight = 0/1 0 = floor, 1 = wall
  3752.     -- T:place(blockType, damageNo, direction, leaveExisting)
  3753.     -- T:go(path, useTorch, torchInterval, leaveExisting, checkDungeon)
  3754.     -- T:harvestTree(extend, craftChest, direction)
  3755.     -- start with forward run:
  3756.     local doContinue = true
  3757.     local numBlocks  = 0
  3758.     local doTunnel = false
  3759.     local requestTunnel = false
  3760.     local maxLength = 1024
  3761.     if size ~= 0 then
  3762.         maxLength = size
  3763.     end
  3764.     local blockType, modifier
  3765.     -- if height = 0 then already at correct height on canal floor
  3766.         -- check block below, block to left and block above, move forward tunnelling
  3767.         -- if entering water then move up, onto canal wall and continue pathway
  3768.         -- if 55 and tunnelling then flood canal
  3769.     -- else height = 1 then above water and on path across
  3770.         -- move forward, checking for water below
  3771.         -- if water finishes, move into canal, drop down and continue tunnelling
  3772.     if choice == 54 then -- left side
  3773.         while doContinue and numBlocks < maxLength do
  3774.             if height == 0 then -- canal floor
  3775.                 blockType, modifier = T:getBlockType("down")
  3776.                 if blockType == nil or blockType == "minecraft:lava" then -- air or lava below, so place block
  3777.                     T:place("minecraft:cobblestone", -1, "down", false)
  3778.                 end
  3779.                 -- place side block
  3780.                 T:go("L1C1R1", false , 0, true, true)
  3781.                 -- check above
  3782.                 blockType, modifier = T:getBlockType("up")
  3783.                 if blockType == "minecraft:log" or blockType == "minecraft:log2" then
  3784.                     T:harvestTree(false, false, "up")
  3785.                 elseif blockType == "minecraft:lava" or blockType == "minecraft:water" then
  3786.                     T:up(1)
  3787.                     T:place("minecraft:cobblestone", -1, "up", false)
  3788.                     T:down(1)
  3789.                 else --solid block or air above
  3790.                     if blockType ~= nil then
  3791.                         T:dig("up")
  3792.                     end
  3793.                 end
  3794.                 -- check if block in front is water source
  3795.                 blockType, modifier = T:getBlockType("forward")
  3796.                 if blockType == "minecraft:water" and modifier == 0 then -- source block in front could be lake/ocean
  3797.                     -- move up, to left and continue as height = 1
  3798.                     T:go("U1L1F1R1")
  3799.                     height = 1
  3800.                 else
  3801.                     T:forward(1, true)
  3802.                     numBlocks = numBlocks + 1
  3803.                 end
  3804.             else -- height = 1, on canal wall
  3805.                 numBlocks = numBlocks + createPath(0, true)
  3806.                 -- if path finished, then move back to canal floor and continue tunnelling
  3807.                 T:go("R1F1D1L1")
  3808.                 height = 0
  3809.             end
  3810.         end
  3811.     else -- right side
  3812.         -- assume left side already under construction
  3813.         local poolCreated = false
  3814.         while doContinue and numBlocks < maxLength do
  3815.             if height == 0 then-- canal floor
  3816.                 -- create first infinity pool
  3817.                 if not poolCreated then
  3818.                     T:up(1)
  3819.                     T:place("minecraft:water_bucket", -1, "down", false)
  3820.                     T:go("L1F1R1")
  3821.                     T:place("minecraft:water_bucket", -1, "down", false)
  3822.                     T:forward(1)
  3823.                     T:place("minecraft:water_bucket", -1, "down", false)
  3824.                     T:back(1)
  3825.                     -- refill buckets
  3826.                     for j = 1, 3 do
  3827.                         T:place("minecraft:bucket", -1, "down", false)
  3828.                         sleep(0,5)
  3829.                     end
  3830.                     T:go("R1F1L1F2", false , 0, true, false)
  3831.                     T:down(1)
  3832.                     poolCreated = true
  3833.                 end
  3834.                 blockType, modifier = T:getBlockType("down")
  3835.                 if blockType == nil or blockType == "minecraft:lava"
  3836.                    or blockType == "minecraft:water" or blockType == "minecraft:flowing_water" then -- air, water or lava below, so place block
  3837.                     T:place("minecraft:cobblestone", -1, "down", false)
  3838.                 end
  3839.                 -- place side block
  3840.                 T:go("R1C1L1", false , 0, true, false)
  3841.                 T:up(1)
  3842.                 blockType, modifier = T:getBlockType("up")
  3843.                 if blockType == "minecraft:log" or blockType == "minecraft:log2" then
  3844.                     T:harvestTree(false, false, "up")
  3845.                 elseif blockType == "minecraft:lava" or blockType == "minecraft:water" then
  3846.                     T:place("minecraft:cobblestone", -1, "up", false)
  3847.                 end
  3848.                 T:place("minecraft:water_bucket", -1, "down", false)
  3849.                 for j = 1, 2 do
  3850.                     T:forward(1)
  3851.                     blockType, modifier = T:getBlockType("up")
  3852.                     if blockType == "minecraft:log" or blockType == "minecraft:log2" then
  3853.                         T:harvestTree(false, false, "up")
  3854.                     elseif blockType == "minecraft:lava" or blockType == "minecraft:water" then
  3855.                         T:place("minecraft:cobblestone", -1, "up", false)
  3856.                     end
  3857.                     -- at ceiling level
  3858.                     T:go("D1R1C1L1", false, 0, true, false)
  3859.                     blockType, modifier = T:getBlockType("down")
  3860.                     if blockType == nil or blockType == "minecraft:lava"
  3861.                        or blockType == "minecraft:water" or blockType == "minecraft:flowing_water" then -- air, water or lava below, so place block
  3862.                         T:place("minecraft:cobblestone", -1, "down", false)
  3863.                     end
  3864.                     -- check if block in front is water source
  3865.                     blockType, modifier = T:getBlockType("forward")
  3866.                     T:up(1)
  3867.                     T:place("minecraft:water_bucket", -1, "down", false)
  3868.                     if blockType == "minecraft:water" and modifier == 0 then -- source block in front could be lake/ocean
  3869.                         -- move to right and continue as height = 1
  3870.                         T:go("R1F1L1")
  3871.                         height = 1
  3872.                         break  
  3873.                     end
  3874.                 end
  3875.                 if height == 0 then
  3876.                     T:back(2)
  3877.                     for j = 1, 3 do
  3878.                         T:place("minecraft:bucket", -1, "down", false)
  3879.                         sleep(0,5)
  3880.                     end
  3881.                     T:go("F3D1", false, 0, true, false)
  3882.                 end
  3883.             else -- height = 1: on wall
  3884.                 numBlocks = numBlocks + createPath(0, true)
  3885.                 -- if path finished, then move back to canal floor and continue tunnelling
  3886.                 T:go("L1F1L1F1") -- facing backwards, collect water
  3887.                 for j = 1, 3 do
  3888.                     T:place("minecraft:bucket", -1, "down", false)
  3889.                     sleep(0,5)
  3890.                 end
  3891.                 T:go("R2F1D1") --canal floor
  3892.                 height = 0
  3893.             end
  3894.         end
  3895.     end
  3896. end
  3897.  
  3898. function createMobSpawnerBase(pathLength)
  3899.     if pathLength > 0 then
  3900.         print("Building path to mob spawner base")
  3901.         createPath(pathLength)
  3902.         T:back(1)
  3903.     end
  3904.     T:place("minecraft:stone", -1, "down", true)
  3905.     T:go("R1F1L1")
  3906.     createPath(8)
  3907.     T:go("L1F1L1F1")
  3908.     createPath(8)
  3909.     T:go("R1F1R1F1")
  3910.     createPath(8)
  3911.     T:go("L1F1L1F1")
  3912.     createPath(8)
  3913.     T:go("L1F2L1F1")
  3914. end
  3915.  
  3916. function createMobSpawnerTower(height) 
  3917.     height = height or 2
  3918.     print("Building mob spawner base")
  3919.     -- assume placed at sea level on stone block (andesite / granite / diorite)
  3920.     --layers 2, 3 (layer 1 done at base construction)
  3921.     T:go("U1F7H2L1F1H2R1F2D1R2P1L1F1R1P1R2U1")
  3922.     for i = 1, 8 do
  3923.         T:go("C2R1C1L1F1")
  3924.     end
  3925.     T:go("L1F1L2C1R1F1R2C1R2")
  3926.     for i = 1, 8 do
  3927.         T:go("C2R1C1L1F1")
  3928.     end
  3929.     T:go("U1R2F8R1")
  3930.     T:place("minecraft:water_bucket", -1, "down", false)
  3931.     T:go("F1R1")
  3932.     T:place("minecraft:water_bucket", -1, "down", false)
  3933.     T:forward(16)
  3934.     T:go("R1F1D2")
  3935.     for i = 1, 2 do
  3936.         sleep(0.5)
  3937.         T:place("minecraft:bucket", -1, "down", false)
  3938.     end
  3939.     T:go("R1F2")
  3940.     for i = 1, 2 do
  3941.         T:go("C1R1C1R2C1R1U1")
  3942.     end
  3943.     -- height of tower
  3944.     height = math.ceil(height / 2)
  3945.     for i = 1, height do
  3946.         T:go("C1U1C1R1C1R1C1R1C1R1U1")
  3947.     end
  3948.     -- create platform for player
  3949.     T:go("R2F1L1C1R1C1R1C1U1C1L1C1L1C1L1F1L1C!R2C1L1U1F1")
  3950.     -- place stone marker
  3951.     T:place("minecraft:stone", -1, "down")
  3952.     -- will need to move back before completing
  3953. end
  3954.  
  3955. function createMobSpawnerTank()
  3956.     --layer 1 of tower + walkway
  3957.     -- move back 1 block before continuing with tower top and walkway
  3958.     T:go("R2F1R2")
  3959.     T:go("C1U2R1F1L1") -- now dropping cobble from above
  3960.     T:go("m10L1F1L1")
  3961.     T:go("m9R1F1L1F1C2F1L1F1C2L1F1")
  3962.     --layer 2
  3963.     T:go("U1F1C2R1F1C2F1L1F1m8L1F3L1m8F2L1F1L1")
  3964.     --layer 3
  3965.     T:go("U1R1F1C2L1F1C2")
  3966.     T:go("F1R1F1L1C2F1C2F1L1F1C2")
  3967.     T:go("F1C2F1L1F1C2F1C2F2C2F1")
  3968.     T:go("L1F1C2L1F2C2B1")
  3969.     --layer 4
  3970.     T:go("U1F1L1F1R2")
  3971.     for i = 1, 4 do
  3972.         T:go("F1C2F1C2F1L1")
  3973.     end
  3974.     T:go("F1R1F1R2")
  3975.     --layer 5
  3976.     T:go("U1R2F1m7L1F1L1C2F1C2F7C2F1C2")
  3977.     T:go("F1R1F1L1C2F1C2F1L1F1C2F1C2F1")
  3978.     T:go("L1F1C2F1C2F2C2L1F1L1F1C2R2F1R2")
  3979.     -- layer 6
  3980.     T:go("U1R2F9C2L1F1C2F1L1F1C2F1L1F1C2R1F8L1F2R2")
  3981.     for i = 1, 4 do
  3982.         T:go("F1C2F1C2F1L1")
  3983.     end
  3984.     T:go("F1L1F1")
  3985.     T:place("minecraft:water_bucket", -1, "down")
  3986.     T:go("R1F1L1")
  3987.     T:place("minecraft:water_bucket", -1, "down")
  3988.     T:go("R2F2R1F1R1")
  3989.     -- layer 7
  3990.     T:go("U1R2F8L1F2C2L1F1L1F1C2R1F7C2L1F2R1C2F1R1")
  3991.     for i = 1, 4 do
  3992.         T:go("F1C2F1C2F1L1")
  3993.     end
  3994.     T:go("F1R1F1R2")
  3995.     T:go("F2")
  3996.     -- place stone inside column, ready for temp water source
  3997.     T:place("minecraft:stone", -1, "down", false)
  3998.    
  3999.     -- layer 8
  4000.     -- make temp water source in centre. destroy in createMobSpawnerRoof()
  4001.     T:go("F1C2R1F1C2R1F1C2F1R1F2U1R2")
  4002.     -- spiral construction
  4003.     for j = 3, 9, 2 do
  4004.         for i = 1, 4 do
  4005.             if i < 4 then
  4006.                 T:go("m"..j.."L1")
  4007.             else
  4008.                 T:go("m"..j.."F1R1F1L2")
  4009.             end
  4010.         end
  4011.     end
  4012.     -- fill water source
  4013.     T:go("F5L1F5")
  4014.     T:place("minecraft:water_bucket", -1, "down", false)
  4015.     T:go("F1R1F1R1")
  4016.     T:place("minecraft:water_bucket", -1, "down", false)
  4017.     T:go("F5m4F2C2F1R1F1C2F1R1F1C2F1R1F1L1C2F1m4")
  4018.     T:go("F8F2m3R1F1R1m3")
  4019.     T:go("F5L1F5m3R1F1R1m3")
  4020.     T:go("F9F2m3R1F1R1m3")
  4021.     -- layer 9
  4022.     T:up(1)
  4023.     for i = 1, 4 do
  4024.         T:go("L1F1L1m3R1F1R1m3L1F1L1m3R1F1R1m3F4")
  4025.         T:go("L1F1L1m7R1F1R1m7L1F1L1m7R1F1R1m7F1L1F1R1C2F1C2R1F4")
  4026.     end
  4027.     -- now add water
  4028.     T:go("F6")
  4029.     for i = 1, 4 do
  4030.         T:down(1)
  4031.         T:place("minecraft:bucket", -1, "down", false)
  4032.         sleep(0.5)
  4033.         T:place("minecraft:bucket", -1, "down")
  4034.         T:go("U1F8R1")
  4035.         T:place("minecraft:water_bucket", -1, "down", false)
  4036.         T:go("F1R1")
  4037.         T:place("minecraft:water_bucket", -1, "down", false)
  4038.         T:go("F8L1")
  4039.     end
  4040.     for i = 1, 2 do
  4041.         T:down(1)
  4042.         T:place("minecraft:bucket", -1, "down", false)
  4043.         sleep(0.5)
  4044.         T:place("minecraft:bucket", -1, "down", false)
  4045.         T:go("U1F4L1F4L1")
  4046.         T:place("minecraft:water_bucket", -1, "down", false)
  4047.         T:go("F9")
  4048.         T:place("minecraft:water_bucket", -1, "down", false)
  4049.         T:go("L1F5L1F4L2")
  4050.     end
  4051.     T:go("F9R1F10R1")
  4052.     -- layer 10 / 11
  4053.     for j = 1, 2 do
  4054.         T:go("U1F1m8L1F1C2F1R1F1C2F1R1F1C2F1R1F1R2m8F1R1")
  4055.         for i = 1, 3 do
  4056.             T:go("F1m17F1R1")
  4057.         end
  4058.     end
  4059.     T:go("F10R1F9D4")
  4060. end
  4061.  
  4062. function createMobSpawnerRoof()
  4063.     -- destroy water source first
  4064.     T:go("x2C1R1F1x2L1F1x2L1F1x2L1F1x2L2")
  4065.     T:go("U5L1F8L1F8L2") -- top left corner facing e
  4066.     T:go("m17R1m17R1m17R1m17") -- outer ring. ends facing n
  4067.     T:go("R1F2R1F1L1") -- facing e
  4068.     for i = 1, 4 do -- outer ring - 1 (with torches) ends facing e
  4069.         T:go("m6t1m3t1m5R1F1t1")
  4070.     end
  4071.     T:go("R1F1L1") -- facing e
  4072.     for i = 1, 4 do -- outer ring - 2 ends facing e
  4073.         T:go("m13R1m13R1m13R1m13")
  4074.     end
  4075.     T:go("R1F1L1") -- ends facing e
  4076.     T:go("m11R1m11R1m11R1m11") -- ends facing e
  4077.     T:go("R1F1R1F1L1F1")
  4078.     for i = 1, 4 do
  4079.         T:go("m8R1F1t1")
  4080.     end
  4081.     T:go("R1F1L1")
  4082.     T:go("m7R1m7R1m7R1m7")
  4083.     T:go("R1F1R1F1L1")
  4084.     T:go("m5R1m5R1m5R1m5")
  4085.     T:go("R1F1R1F1L1F1")
  4086.     for i = 1, 4 do
  4087.         T:go("m2R1F1t1")
  4088.     end
  4089.     T:go("R1F1L1")
  4090.     T:go("m1R1m1R1m1R1m1")
  4091. end
  4092.  
  4093. function createPath(length, isCanal)
  4094.     length = length or 0 --allow for choice of path length
  4095.     if isCanal == nil then
  4096.         isCanal = false
  4097.     end
  4098.     local numBlocks = 1
  4099.     local path = 0
  4100.     local distance = 0
  4101.     local torch = 0
  4102.     local continue = true
  4103.     local slot = 0
  4104.     T:forward(1)
  4105.     local blockType, blockModifier = T:getBlockType("down")
  4106.     while blockType == "minecraft:water" or blockType == "minecraft:lava" or blockType == nil do
  4107.         continue = true
  4108.         if not T:place("minecraft:cobblestone", -1, "down") then
  4109.             if not T:place("minecraft:dirt", -1, "down") then
  4110.                 if not T:place("minecraft:end_stone", -1, "down") then
  4111.                     continue = false -- stop if out of cobble / dirt
  4112.                 end
  4113.             end
  4114.         end
  4115.         if continue then
  4116.             T:forward(1)
  4117.             numBlocks = numBlocks + 1
  4118.             blockType, blockModifier = T:getBlockType("down")
  4119.             distance = distance + 1
  4120.             torch = torch + 1
  4121.             slot = T:getItemSlot("minecraft:torch", -1)
  4122.             if torch == 8 and slot > 0 then
  4123.                 torch = 0
  4124.                 T:turnRight(2)
  4125.                 T:place("minecraft:torch", -1, "forward", false)
  4126.                 T:turnRight(2)
  4127.             end
  4128.         else
  4129.             break
  4130.         end
  4131.         path = path + 1
  4132.         if length > 0 and path >= length then
  4133.             break
  4134.         end
  4135.     end
  4136.     if continue and not isCanal then
  4137.         T:forward(1)
  4138.     end
  4139.     return numBlocks
  4140. end
  4141.  
  4142. function createLadder(destination, level)
  4143.     -- R# L# F# B# U# D# +0 -0 = Right, Left, Forward, Back, Up, Down, up while detect and return, down while not detect
  4144.     -- dig:           x0,x1,x2 (up/fwd/down)
  4145.     -- suck:          s0,s1,s2
  4146.     -- place chest:   H0,H1,H2
  4147.     -- place sapling: S0,S1,S2
  4148.     -- place Torch:   T0,T1,T2
  4149.     -- place Hopper:  P0,P1,P2
  4150.     -- mine floor:    m# = mine # blocks above and below, checking for valuable items below, and filling space with cobble or dirt
  4151.     -- mine ceiling:  M# = mine # blocks, checking for valuable items above, and filling space with cobble or dirt
  4152.     -- mine ceiling:  N# same as M but not mining block below unless valuable
  4153.     -- 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
  4154.     local height = 0
  4155.     local ledge = 0
  4156.     if destination == "surface" then
  4157.         T:go("C1U1C1")
  4158.         for j = level - 2, 1, -1 do
  4159.             T:up(1)
  4160.             for i = 1, 4 do
  4161.                 if i ~= 3 then
  4162.                     T:go("C1R1")
  4163.                 else
  4164.                     T:turnRight(1)
  4165.                 end
  4166.             end
  4167.             height = height + 1
  4168.         end
  4169.         -- at level 64. check if still blocks above
  4170.         while turtle.inspectUp() do
  4171.             T:up(1)
  4172.             for i = 1, 4 do
  4173.                 if i ~= 3 then
  4174.                     T:go("C1R1")
  4175.                 else
  4176.                     T:turnRight(1)
  4177.                 end
  4178.             end
  4179.             height = height + 1
  4180.         end
  4181.         -- nothing above
  4182.         T:go("U1R2F1L2") -- face wall previously built
  4183.         for i = height, 1, -1 do
  4184.             ledge = ledge + 1
  4185.             if ledge >= 3 then
  4186.                 ledge = 0
  4187.                 T:place("minecraft:cobblestone", 0, "up")
  4188.             end
  4189.             -- Place cobble on 3 sides (if required)
  4190.             for j = 1, 4 do
  4191.                 if j == 1 then -- place ladder on first side
  4192.                     T:place("minecraft:ladder", 0, "forward", false)
  4193.                 else
  4194.                     T:place("minecraft:cobblestone", 0, "forward")
  4195.                 end
  4196.                 T:turnLeft(1)
  4197.             end
  4198.             T:down(1)
  4199.         end
  4200.     else -- ladder to bedrock
  4201.         -- dig shaft to bedrock and close all sides except facing
  4202.         -- create a working area at the base
  4203.         -- Return to surface facing towards player placing ladders
  4204.         repeat
  4205.             height = height + 1
  4206.             for i = 1, 4 do
  4207.                 if i ~= 1 then
  4208.                     T:place("minecraft:cobblestone", 0, "forward")
  4209.                 end
  4210.                 T:turnRight(1)
  4211.             end
  4212.         until not T:down(1)
  4213.         -- test to check if on safe level immediately above tallest bedrock
  4214.         height = T:findBedrockTop(height)
  4215.        
  4216.         -- In shaft, facing start direction, on lowest safe level
  4217.         -- create a square space round shaft base, end facing original shaft, 1 space back
  4218.         T:go("F1R1m1R1m2R1m2R1m2R1F1R1F1C1U1C1D1R2F1R2")
  4219.         ledge = 0
  4220.         local atBedrock = true
  4221.         for i = height, 0, -1 do
  4222.             if ledge >= 3 then
  4223.                 ledge = 0
  4224.                 T:place("minecraft:cobblestone", 0, "down")
  4225.             end
  4226.             -- Place cobble on 3 sides (if required)
  4227.             for j = 1, 4 do
  4228.                 if j == 1 then -- place ladder on first side
  4229.                     if atBedrock then
  4230.                         atBedrock = false -- do not place ladder on bottom block
  4231.                     else
  4232.                         T:place("minecraft:ladder", 0, "forward", false)
  4233.                     end
  4234.                 else
  4235.                     T:place("minecraft:cobblestone", 0, "forward")
  4236.                 end
  4237.                 T:turnLeft(1)
  4238.             end
  4239.             T:up(1)
  4240.             ledge = ledge + 1
  4241.         end
  4242.     end
  4243. end
  4244.  
  4245. function createMine()
  4246.     T:clear()  
  4247.     T:go("m32U1R2M16D1", true, 8) -- mine ground level, go up, reverse and mine ceiling to mid-point, drop to ground
  4248.     T:place("minecraft:chest", -1, "down", false) --place chest in ground
  4249.     T:up(1) -- ready for emptyTrash() which moves down/up automatically
  4250.     T:emptyTrash("down")
  4251.     T:go("D1R1m16U1R2M16", true, 8) -- mine floor/ceiling of right side branch
  4252.     T:emptyTrash("down")
  4253.     T:go("D1m16U1R2M16", true, 8) -- mine floor/ceiling of left side branch
  4254.     T:emptyTrash("down")
  4255.     T:go("L1M15F1R1D1", true, 8) -- mine ceiling of entry coridoor, turn right
  4256.     T:go("n16R1n32R1n32R1n32R1n16U1", true, 8)-- mine floor of 36 x 36 square coridoor
  4257.     T:go("R1F16R2") --return to centre
  4258.     T:emptyTrash("down")
  4259.     T:go("F16R1") --return to entry shaft
  4260.     T:go("Q16R1Q32R1Q32R1Q32R1Q16x0F1R1", true, 8) --mine ceiling of 36x36 square coridoor. return to entry shaft + 1
  4261.     -- get rid of any remaining torches
  4262.     while T:getItemSlot("minecraft:torch", -1) > 0 do
  4263.         turtle.select(T:getItemSlot("minecraft:torch", -1))
  4264.         turtle.drop()
  4265.     end
  4266.     for i = 1, 8 do
  4267.         T:go("N32L1F1L1", true)
  4268.         T:dumpRefuse()
  4269.         T:go("N32R1F1R1", true)
  4270.         T:dumpRefuse()
  4271.     end
  4272.     T:go("R1F1R2C1R2F17L1") -- close gap in wall, return
  4273.     for i = 1, 8 do
  4274.         T:go("N32R1F1R1", true)
  4275.         T:dumpRefuse()
  4276.         T:go("N32L1F1L1", true)
  4277.         T:dumpRefuse() 
  4278.     end
  4279.     T:go("L1F1R2C1R2F16R1") -- close gap in wall, return
  4280.     T:clear()
  4281.     print("Mining operation complete")
  4282. end
  4283.  
  4284. function createRailwayDown(userChoice, drop)
  4285.     --make sure torch placed on lowest level
  4286.     -- 1 block not required
  4287.     -- 2 - 3 blocks 1 torch at base
  4288.     -- 4 - 6 blocks 2 torch
  4289.     --
  4290.     for i = 1, drop - 1 do
  4291.         T:go("F1D1")
  4292.         T:place(userChoice, -1, "down", false)
  4293.     end
  4294. end
  4295.  
  4296. function createRailwayUp(userChoice, up)
  4297.     for i = 1, up do
  4298.         T:place(userChoice, -1, "forward", false)
  4299.         T:go("U1F1")
  4300.     end
  4301. end
  4302.  
  4303. function createStaircase(destination, level)
  4304.     -- R# L# F# B# U# D# +0 -0 = Right, Left, Forward, Back, Up, Down, up while detect and return, down while not detect
  4305.     -- dig:           x0,x1,x2 (up/fwd/down)
  4306.     -- suck:          s0,s1,s2
  4307.     -- place chest:   H0,H1,H2
  4308.     -- place sapling: S0,S1,S2
  4309.     -- place Torch:   T0,T1,T2
  4310.     -- place Hopper:  P0,P1,P2
  4311.     -- mine floor:    m# = mine # blocks above and below, checking for valuable items below, and filling space with cobble or dirt
  4312.     -- mine ceiling:  M# = mine # blocks, checking for valuable items above, and filling space with cobble or dirt
  4313.     -- mine ceiling:  N# same as M but not mining block below unless valuable
  4314.     -- place:         C,H,r,S,T,P,^ = Cobble / cHest / DIrT / Sapling / Torch / hoPper /stair in direction 0/1/2 (up/fwd/down) eg C2 = place cobble down
  4315.    
  4316.     -- 3| |B| |
  4317.     --   - - -
  4318.     -- 2|A| |C|
  4319.     --   - - -
  4320.     -- 1|^|D| |
  4321.     --   - - -
  4322.     --   1 2 3
  4323.    
  4324.     local height = level -- eg 64 at top or 5 at bedrock
  4325.     local numStairs = T:getItemCount("minecraft:stone_stairs", 0)
  4326.     local numStairsNeeded = 0
  4327.     if destination == "bedrock" then
  4328.         numStairsNeeded = math.ceil(level / 4) * 4
  4329.     else
  4330.         numStairsNeeded = math.ceil((64 - level) / 4) * 4
  4331.     end
  4332.     numStairsNeeded = numStairsNeeded - numStairs
  4333.     if numStairsNeeded >  40 then
  4334.         T:craft("minecraft:stone_stairs", 40)   -- max 40 so repeat
  4335.         numStairsNeeded = numStairsNeeded - 40
  4336.     end
  4337.     if numStairsNeeded >  0 then
  4338.         T:craft("minecraft:stone_stairs", numStairsNeeded)
  4339.     end
  4340.     if destination == "bedrock" then -- go down to bedrock
  4341.         while T:down() do
  4342.             height = height - 1
  4343.         end
  4344.         height = T:findBedrockTop(height) -- usually around 5
  4345.         T:go("R1F1R1")
  4346.     end
  4347.     local onGround = true
  4348.     local top = (math.ceil((64 - height) / 4) * 4) + 4
  4349.  
  4350.     for i = height, top, 4 do
  4351.         for x = 1, 4 do
  4352.             -- start 1,1,1, n
  4353.             -- stage A
  4354.             T:go("L1C1R1F1L1C1R1C1R1C1L1B1^1") --start:1,1,1,n stairs A on level 1, going back to 1,1,1,n
  4355.             if not onGround then
  4356.                 -- stage A1
  4357.                 T:go("L2C1L2") -- start 1,1,1,n fix corner on level 1 end: 1,1,1,n
  4358.             end
  4359.             -- stage B
  4360.             T:go("U1L1C1") -- end  1,1,1,w layer 2
  4361.             if not onGround then
  4362.                 T:go("L1C1R1") -- end  1,1,1,w layer 2
  4363.             end
  4364.             -- stage C1
  4365.             T:go("R1F1L1C1R2C1L1B1")
  4366.             -- stage C2
  4367.             T:go("U1L1C1L1C1L2F1L1C1R2C1L1B1D1") -- end 1,1,2,n
  4368.             onGround = false
  4369.             -- stage D
  4370.             T:go("F2L1C1R1C1R1") -- 3,1,2,e
  4371.         end
  4372.     end
  4373. end
  4374.  
  4375. function createTreefarm(size)
  4376.     local blockType
  4377.     local blockModifier
  4378.     local length
  4379.     local width
  4380.    
  4381.     if size == 1 then
  4382.         length = 11
  4383.         width = 6
  4384.         clearArea(11, 11)
  4385.     else
  4386.         length = 19
  4387.         width = 10
  4388.         clearArea(19, 19)
  4389.     end
  4390.     -- now place dirt blocks and torches
  4391.     T:go("F2R1F2L1U1")
  4392.     for x = 1, (width - 2) / 2 do
  4393.         for y = 1, (length - 3) / 2 do
  4394.             T:place("minecraft:dirt", -1, "down", false)
  4395.             if y < (length - 3) / 2 then
  4396.                 T:forward(1)
  4397.                 T:place("minecraft:torch", -1, "down", false)
  4398.                 T:forward(1)
  4399.             end
  4400.         end
  4401.         T:go("R1F2R1")
  4402.         for y = 1, (length - 3) / 2 do
  4403.             T:place("minecraft:dirt", -1, "down", false)
  4404.             if y < (length - 3) / 2 then
  4405.                 T:forward(1)
  4406.                 T:place("minecraft:torch", -1, "down", false)
  4407.                 T:forward(1)
  4408.             end
  4409.         end
  4410.         if x < (width - 2) / 2 then
  4411.             T:go("L1F2L1")
  4412.         else
  4413.             T:go("R1F6")
  4414.             if size == 2 then
  4415.                 T:go("F8")
  4416.             end
  4417.             T:go("R1B1")
  4418.         end
  4419.     end
  4420. end
  4421.  
  4422. function createWalkway(length)
  4423.     local lengthParts = math.floor(length / 8) -- eg 12/8 = 1
  4424.     local lastPart = length - (lengthParts * 8) -- eg 12 - (1 * 8) = 4
  4425.     T:up(1)
  4426.     for j = 1, lengthParts do
  4427.         T:go("M8")
  4428.     end
  4429.     if lastPart > 0 then
  4430.         T:go("M"..tostring(lastPart)) -- eg m4
  4431.     end
  4432.     T:go("R2D1")
  4433.     T:place("minecraft:torch", 0, "up", false)
  4434.     for j = 1, lengthParts do
  4435.         T:go("m8", true)
  4436.         T:place("minecraft:torch", 0, "up", false)
  4437.     end
  4438.     if lastPart > 0 then
  4439.         T:go("m"..tostring(lastPart), true) -- eg m4
  4440.     end
  4441.     T:go("R2")
  4442. end
  4443.  
  4444. function createWaterSource()
  4445.     T:go("F1D1") --move to corner and drop down
  4446.     for i = 1, 4 do
  4447.         T:go("L1C1L1C1L2C2F1R1")
  4448.     end
  4449.     T:go("U1")
  4450.     for i = 1, 2 do
  4451.         T:place("minecraft:water_bucket", -1, "down", false)
  4452.         T:go("F1R1F1R1")
  4453.     end
  4454.     -- refill water buckets
  4455.     for i = 1, 2 do
  4456.         sleep(0.5)
  4457.         T:place("minecraft:bucket", -1, "down", false)
  4458.     end
  4459.     -- end facing towards farm above lower left pond
  4460. end
  4461.  
  4462. function createWheatFarm(clearFirst, width, height)
  4463.     width = width or 11
  4464.     height = height or 14
  4465.     if clearFirst then
  4466.         clearArea(width, height)
  4467.         while turtle.down() do end
  4468.     end
  4469.     createWaterSource()
  4470.     -- place chest and hopper
  4471.     T:go("F3L1F1R2D1x2")
  4472.     T:place("minecraft:chest", -1, "down", false)
  4473.     T:go("F1D1F1R2")
  4474.     T:place("minecraft:hopper", -1, "forward", false)
  4475.     -- dig trench and ensure base is solid
  4476.     T:go("U1p2R2m7U1R2")
  4477.     T:place("minecraft:water_bucket", -1, "down", false) -- collection stream
  4478.     T:go("R2F1U1R1m1R1m9R1m9m1R1F1D2")
  4479.     T:go("m7U1R2") -- dig trench and ensure base is solid
  4480.     T:place("minecraft:water_bucket", -1, "down", false) -- watering stream
  4481.     T:go("U1B1m9R2F9R1m9F1R1F9L1F3R2D1") -- back to start
  4482. end
  4483.  
  4484. function decapitateBuilding(width, length)
  4485.     --clearRectangle with sand drop
  4486.     -- could be 1 wide x xx lenght (trench) up and return
  4487.     -- could be 2+ x 2+
  4488.     -- even no of runs return after last run
  4489.     -- odd no of runs forward, back, forward, reverse and return
  4490.     local success
  4491.     local directReturn = true
  4492.     if width % 2 == 1 then
  4493.         directReturn = false
  4494.     end
  4495.     if width == 1 then -- trench ahead, so fill then return
  4496.         for i = 1, length - 1 do
  4497.             success = dropSand()
  4498.             T:forward(1, false)
  4499.         end
  4500.         success = dropSand()
  4501.         T:go("R2F"..(length - 1).."R2")
  4502.     else --2 or more columns
  4503.         if directReturn then -- width = 2,4,6,8 etc
  4504.             for i = 1, width, 2 do -- i = 1,3,5,7 etc
  4505.                 -- move along length, dropping sand
  4506.                 for j = 1, length - 1 do
  4507.                     success = dropSand()
  4508.                     T:forward(1, false)
  4509.                 end
  4510.                 success = dropSand()
  4511.                 T:go("R1F1R1") --turn right and return on next column
  4512.                 for j = 1, length - 1 do
  4513.                     success = dropSand()
  4514.                     T:forward(1, false)
  4515.                 end
  4516.                 success = dropSand()
  4517.                 if i < width - 2 then -- eg width = 8, i compares with 6: 1, 3, 5, 7
  4518.                     T:go("L1F1L1")
  4519.                 end
  4520.             end
  4521.             T:go("R1F"..width - 1 .."R1") --return home
  4522.         else
  4523.             for i = 1, width, 2 do -- i = 1,3,5,7 etc
  4524.                 -- move along length, dropping sand
  4525.                 for j = 1, length - 1 do
  4526.                     success = dropSand()
  4527.                     T:forward(1, false)
  4528.                 end
  4529.                 success = dropSand()
  4530.                 T:go("R1F1R1") --turn right and return on next column
  4531.                 for j = 1, length - 1 do
  4532.                     success = dropSand()
  4533.                     T:forward(1, false)
  4534.                 end
  4535.                 success = dropSand()
  4536.                 T:go("L1F1L1")
  4537.             end
  4538.             -- one more run then return
  4539.             for j = 1, length - 1 do
  4540.                 success = dropSand()
  4541.                 T:forward(1, false)
  4542.             end
  4543.             success = dropSand()
  4544.             T:go("R2F"..length.."R1F"..width - 1 .."R1")
  4545.         end
  4546.     end
  4547. end
  4548.  
  4549. function demolishBuilding(width, length)
  4550.     -- start bottom left
  4551.     clearBuilding(width, length, 0, false)
  4552. end
  4553.  
  4554. function demolishPortal()
  4555.     if T:getBlockType("forward") == "minecraft:obsidian" then
  4556.         T:down(1)
  4557.     end
  4558.     T:go("x1U1x1U1x1U1x1U1x1")
  4559.     for i = 1, 3 do
  4560.         T:go("R1F1L1x1")
  4561.     end
  4562.     T:go("D1x1D1x1D1x1D1x1")
  4563.     T:go("L1F1R1x1L1F1R1x1")
  4564. end
  4565.  
  4566. function dropSand()
  4567.     local success, slot
  4568.     while not turtle.detectDown() do -- over water. will be infinite loop if out of sand
  4569.         success, slot = T:place("minecraft:sand", -1, "down", false)
  4570.         if not success then
  4571.             print("Out of sand. Add more to continue...")
  4572.             sleep(2)
  4573.         end
  4574.     end
  4575.     return true --will only get to this point if turtle.detectDown() = true
  4576. end
  4577.  
  4578. function harvestObsidian(width, length)
  4579.     local heightParts = math.floor(length / 8) -- eg 12/8 = 1
  4580.     local lastPart = length - (heightParts * 8) -- eg 12 - (1 * 8) = 4
  4581.     if width % 2 ~= 0 then
  4582.         width = width + 1
  4583.     end
  4584.     for y = 1, width do
  4585.         print("Mining column "..tostring(y).." of "..tostring(width))
  4586.         for j = 1, heightParts do
  4587.             T:go("m8")
  4588.         end
  4589.         if lastPart > 0 then
  4590.             T:go("m"..tostring(lastPart)) -- eg m4
  4591.         end
  4592.         -- width = tonumber(width)
  4593.         if y < width then
  4594.             if y % 2 == 0 then
  4595.                 T:go("L1F1L1")
  4596.             else
  4597.                 T:go("R1F1R1")
  4598.             end
  4599.         end
  4600.     end
  4601. end
  4602.  
  4603. function harvestRun(runLength)
  4604.     local blockType
  4605.     local blockModifier
  4606.  
  4607.     for i = 1, runLength do
  4608.         blockType, blockModifier = T:getBlockType("forward") -- store information about the block in front in a table
  4609.         if blockType == "minecraft:log" or blockType == "minecraft:log2" then -- tree in front, so harvest it
  4610.             T:harvestTree(true, false)
  4611.         else
  4612.             T:forward(1)           
  4613.         end
  4614.     end
  4615. end
  4616.  
  4617. function harvestAutoTreeFarm()
  4618.     local blockType, blockModifier
  4619.     for  j = 1, 2 do
  4620.         for i = 1, 3 do
  4621.             blockType, blockModifier = T:getBlockType("forward")
  4622.             if  blockType == "minecraft:log" or blockType == "minecraft:log2" then
  4623.                 T:harvestTree(true, false)
  4624.                 T:forward(1)
  4625.             elseif  blockType == "minecraft:sapling" then
  4626.                 T:go("U1F2D1")
  4627.             else
  4628.                 T:forward(1)
  4629.             end
  4630.         end
  4631.         if j == 1 then
  4632.             T:go("R1F3R1")
  4633.         else
  4634.             T:go("R1F3L1")
  4635.         end
  4636.     end
  4637.     T:dropItem("minecraft:log", 0, "forward")
  4638.     T:dropItem("minecraft:log2", 0, "forward")
  4639.     T:dropItem("minecraft:apple", 0, "forward")
  4640.     T:turnRight(2)
  4641. end
  4642.  
  4643. function placeRedstoneTorch(direction, userChoice)
  4644.     if direction == "level" then
  4645.         T:go("R1F1D2L2F1R1")
  4646.         --clsTurtle.place(self, blockType, damageNo, direction, leaveExisting)
  4647.         T:place(userChoice, -1, "forward", false)
  4648.         T:back(1)
  4649.         T:place("minecraft:redstone_torch", -1, "forward", true)
  4650.         T:go("R1F1L1F1U2L1F1R1")
  4651.     elseif direction == "up" then
  4652.         T:go("R1F1D3R2F1L1")
  4653.         T:place("minecraft:redstone_torch", -1, "up", false)
  4654.         T:go("R1B1U3F1R1")
  4655.         T:place(userChoice, -1, "forward", false)
  4656.     end
  4657. end
  4658.  
  4659. function plantAutoTreeFarm()
  4660.     local blockType, blockModifier
  4661.     T:go("L1F4L1F1D3")
  4662.     while turtle.suckDown() do end
  4663.     T:go("L2U3F1R1F4L1")
  4664.     for  j = 1, 2 do
  4665.         for i = 1, 3 do
  4666.             blockType, blockModifier = T:getBlockType("forward")
  4667.             if  blockType == "minecraft:log" or blockType == "minecraft:log2" then
  4668.                 T:harvestTree(true, false)
  4669.                 T:forward(1)
  4670.             elseif  blockType == "minecraft:sapling" then
  4671.                 T:go("U1F2D1")
  4672.             else
  4673.                 T:go("U1F1")
  4674.                 T:place("minecraft:sapling", -1, "down", false)
  4675.                 T:go("F1D1")
  4676.             end
  4677.         end
  4678.         T:go("R1F3R1")
  4679.     end
  4680.     T:dropItem("minecraft:sapling", 0, "down")
  4681.     T:turnRight(2)
  4682.     T:dropItem("minecraft:log", 0, "forward")
  4683.     T:dropItem("minecraft:log2", 0, "forward")
  4684.     T:dropItem("minecraft:apple", 0, "forward")
  4685.     T:turnRight(2)
  4686. end
  4687.  
  4688. function harvestTreeFarm(size)
  4689.     local loopCount
  4690.     local blockType, blockModifier = T:getBlockType("forward") -- store information about the block in front in a table
  4691.     if size == 0 then --fell single tree
  4692.         blockType, blockModifier = T:getBlockType("forward") -- store information about the block in front in a table
  4693.         if blockType == "minecraft:log" or blockType == "minecraft:log2" then -- tree in front, so harvest it
  4694.             T:harvestTree(true, false)         
  4695.         end
  4696.     else
  4697.         if size == 1 then
  4698.             loopCount = 4
  4699.         else
  4700.             loopCount = 8
  4701.         end
  4702.         if blockType == "minecraft:dirt" or blockType == "minecraft:grass" then
  4703.             T:up(1)
  4704.         end
  4705.         for i = 1, loopCount do
  4706.             harvestRun(loopCount * 2)
  4707.             turtle.turnRight()
  4708.             harvestRun(1)
  4709.             turtle.turnRight() --now facing opposite direction
  4710.             harvestRun(loopCount * 2)
  4711.             if i < loopCount then -- turn left if not on last run
  4712.                 turtle.turnLeft()
  4713.                 harvestRun(1)
  4714.                 turtle.turnLeft()
  4715.             end
  4716.         end
  4717.         --return to starting position
  4718.         turtle.turnRight()
  4719.         harvestRun(loopCount * 2 - 1)
  4720.         turtle.turnRight()
  4721.     end
  4722. end
  4723.  
  4724. function harvestWheatFarm()
  4725.     T:forward(1)
  4726.     -- check if bucket or water bucket onboard
  4727.     --T:place(blockType, damageNo, direction, leaveExisting)
  4728.     T:place("minecraft:bucket", -1, "down", false)
  4729.     sleep(0.5)
  4730.     T:place("minecraft:bucket", -1, "down", false)
  4731.     -- assume 2x waterbuckets now onboard
  4732.     T:go("U1F9F2R1F8R2")
  4733.     for i = 1, 8 do
  4734.         T:place("minecraft:water_bucket", -1, "down", false)
  4735.         sleep(2)
  4736.         T:place("minecraft:bucket", -1, "down", false)
  4737.         if i > 1 then
  4738.             -- go back and repeat
  4739.             T:back(1)
  4740.             T:place("minecraft:water_bucket", -1, "down", false)
  4741.             sleep(2)
  4742.             T:place("minecraft:bucket", -1, "down", false)
  4743.             T:forward(1)
  4744.         end
  4745.         T:forward(1)
  4746.     end
  4747.     T:go("L1F9F3R2D1")
  4748. end
  4749.  
  4750. function plantWheatFarm()
  4751.     --player gets minecraft:wheat_seeds from hopper and are already onboard
  4752.     local turn =   {"F2U1F2R1F8L1F1L1","R1F1R1F1","L1F1L1F1","R1F1R1F1",
  4753.                     "L1F1L1F1","R1F1R1F1","L1F1L1F1","R1F1R1F1"}
  4754.     local goHome = {"", "L1F3D1F2R2", "R1F3R1F9L1F1D1F2R2", "L1F5D1F3R2", "R1F5R1F9L1F1D1F2R2", "L1F7D1F2R2", "R1F7R1F9L1F1D1F2R2",
  4755.                     "L1F9D1F2R2", "R1F9R1F9L1F1D1F2R2"}
  4756.     for i = 1, 9 do
  4757.         if T:getItemSlot("minecraft:wheat_seeds", 0) > 0 and i < 9 then -- min 8 seeds to get here
  4758.             T:go(turn[i])
  4759.             for j = 1, 8 do
  4760.                 turtle.digDown()
  4761.                 T:place("minecraft:wheat_seeds", 0, "down", false)
  4762.                 T:forward(1)
  4763.             end
  4764.         else
  4765.             T:go(goHome[i])
  4766.             break
  4767.         end
  4768.     end
  4769. end
  4770.  
  4771. function plantTreefarm(size)
  4772.     -- .name = "minecraft:sapling"
  4773.     -- .state.type = "dark_oak"
  4774.     -- .metadata = 5
  4775.     local saplings = {"oak","spruce","birch","jungle","acacia","dark oak"}
  4776.     local slot = 0
  4777.     local quantity = 0
  4778.     local id = 0
  4779.     local most = 0
  4780.     local mostID = -1
  4781.     local secondMost = 0
  4782.     local secondMostID = -1
  4783.    
  4784.     for i = 0, 5 do
  4785.         slot, id, quantity = T:getItemSlot("minecraft:sapling", i) -- eg 3xoak, 9x spruce
  4786.         if slot > 0 then -- item found
  4787.             print(quantity.." "..saplings[i + 1].." found in slot "..slot)
  4788.             if quantity > most then -- this sapling quantity is > 0
  4789.                 if most > 0 then -- another sapling already found, but quantity is greater
  4790.                     secondMost = most
  4791.                     secondMostID = mostID
  4792.                     print("second sapling choice: "..saplings[secondMostID + 1])
  4793.                 end
  4794.                 most = quantity
  4795.                 mostID = i
  4796.                 print("first sapling choice: "..saplings[mostID + 1])
  4797.             else
  4798.                 if most > 0 then
  4799.                     secondMost = quantity
  4800.                     secondMostID = i
  4801.                 end
  4802.             end
  4803.         end
  4804.     end
  4805.     if secondMostID < 0 then
  4806.         secondMost = most
  4807.         secondMostID = mostID
  4808.         print("first and second sapling choice: "..saplings[secondMostID + 1])
  4809.     end
  4810.    
  4811.     local outerCount = 4
  4812.     local innerCount = 1
  4813.     local repeatCount = 1
  4814.     if size > 1 then
  4815.         outerCount = 8
  4816.         innerCount = 5
  4817.         repeatCount = 3
  4818.     end
  4819.     -- user may have put turtle on the ground
  4820.     if T:getBlockType("forward") == "minecraft:dirt" or T:getBlockType("forward") == "minecraft:grass" then
  4821.         T:up(1)
  4822.     end
  4823.     -- start at base of first tree LL corner
  4824.     T:go("U1F1")
  4825.     for x = 1, 4 do -- place most in a ring on outside of planting area
  4826.         for i = 1, outerCount do
  4827.             T:place("minecraft:sapling", mostID, "down", false)
  4828.             if i < outerCount then
  4829.                 T:forward(1)
  4830.                 T:place("minecraft:sapling", mostID, "down", false)
  4831.                 T:forward(1)
  4832.             end
  4833.         end
  4834.         T:turnRight(1)
  4835.     end
  4836.     -- over first sapling, facing forward
  4837.     T:go("F2R1F2L1")
  4838.     -- place secondMost sapling in centre
  4839.     for x = 1, repeatCount do
  4840.         -- plant first column
  4841.         for i = 1, innerCount do
  4842.             if not T:place("minecraft:sapling", secondMostID, "down", false) then
  4843.                 T:place("minecraft:sapling", mostID, "down", false)
  4844.             end
  4845.             if i < innerCount + 1 then
  4846.                 T:forward(2)
  4847.                 if not T:place("minecraft:sapling", secondMostID, "down", false) then
  4848.                     T:place("minecraft:sapling", mostID, "down", false)
  4849.                 end
  4850.             end
  4851.         end
  4852.         -- turn round and move to next column
  4853.         T:go("R1F2R1")
  4854.         -- plant return column
  4855.         for i = 1, innerCount do
  4856.             if not T:place("minecraft:sapling", secondMostID, "down", false) then
  4857.                 T:place("minecraft:sapling", mostID, "down", false)
  4858.             end
  4859.             if i < innerCount + 1 then
  4860.                 T:forward(2)
  4861.                 if not T:place("minecraft:sapling", secondMostID, "down", false) then
  4862.                     T:place("minecraft:sapling", mostID, "down", false)
  4863.                 end
  4864.             end
  4865.         end
  4866.         if x < repeatCount then
  4867.             T:go("L1F2L1")
  4868.         end
  4869.     end
  4870.     if size == 1 then
  4871.         T:go("F1R1F3L1F2R1F1R1D2")
  4872.     else
  4873.         T:go("F1R1F9F2L1F2R1F1R1D2")
  4874.     end
  4875. end
  4876.  
  4877. function getMenu(options, numOptions)
  4878.     local errorNo = 0
  4879.     local choice = nil
  4880.     options = "Choose your option:\n"..options.."\nType number (q to quit) and Enter..."
  4881.     while choice == nil do
  4882.         T:clear()
  4883.         print(options)
  4884.         --term.write(options)
  4885.         term.setCursorPos(1, numOptions + 3)
  4886.         if errorNo == 1 then
  4887.             term.setCursorPos(1, 13)
  4888.             term.write("Incorrect input use numbers only")
  4889.             term.setCursorPos(1, numOptions + 3)
  4890.         elseif errorNo == 2 then
  4891.             term.setCursorPos(1, 13)
  4892.             term.write("Incorrect input use 1 to "..numOptions.." only")
  4893.             term.setCursorPos(1, numOptions + 3)
  4894.         end
  4895.         choice = read()
  4896.         if choice == "q" or choice == "Q" then
  4897.             choice = -1
  4898.         else
  4899.             choice = tonumber(choice)
  4900.         end
  4901.         if choice == nil then
  4902.             errorNo = 1
  4903.         elseif choice < -1 or choice > numOptions then
  4904.             errorNo = 2
  4905.             choice = nil
  4906.         end
  4907.     end
  4908.     return choice
  4909. end
  4910.  
  4911. function getDecision(choice)
  4912.     local decision = read()
  4913.     local retValue = 0
  4914.     if decision == "" or decision == "y" then -- allow for enter only
  4915.         retValue = choice
  4916.     end
  4917.     return tonumber(retValue)
  4918. end
  4919.  
  4920. function getSize(clear, prompt, lowerLimit, upperLimit)
  4921.     local retValue = -1
  4922.     while tonumber(retValue) < lowerLimit or  tonumber(retValue) > upperLimit do
  4923.         if clear then
  4924.             T:clear()
  4925.         end
  4926.         term.write(prompt)
  4927.         --io.write(prompt.."_")
  4928.         retValue = read()
  4929.         if tonumber(retValue) == nil then
  4930.             retValue = 0
  4931.         end
  4932.     end
  4933.     return tonumber(retValue)
  4934. end
  4935.  
  4936. function getTask()
  4937.     local choice = -1
  4938.     local size = 4
  4939.     local width = 0
  4940.     local length = 0
  4941.     local height = 0
  4942.     local menuOffset = 0 -- added to user choice
  4943.     local options = ""
  4944.     local mainChoice = 0
  4945.     while choice < 0 do
  4946.         options =   "\t1) Mining tools\n"..
  4947.                     "\t2) Tree management tools\n"..
  4948.                     "\t3) Land management and farming tools\n"..
  4949.                     "\t4) Obsidian and nether portal tools\n"..
  4950.                     "\t5) Canal, bridge and walkway tools\n"..
  4951.                     "\t6) Mob farm creation tools\n"..
  4952.                     "\t7) Area carving tools\n"..
  4953.                     "\t8) Lava and Water tools\n"..
  4954.                     "\t9) Railway tools"
  4955.         mainChoice = getMenu(options , 9)
  4956.        
  4957.         if mainChoice < 0 then
  4958.             choice = -1
  4959.             break
  4960.         elseif mainChoice == 1 then
  4961.             options =   "\t1) Create mine\n"..
  4962.                         "\t2) Ladder to bedrock\n"..
  4963.                         "\t3) Ladder to the surface\n"..
  4964.                         "\t4) Stairs to bedrock\n"..
  4965.                         "\t5) Stairs to the surface\n"..
  4966.                         "\t6) Search for Mob Spawner\n"..
  4967.                         "\t7) Decapitate volcano"
  4968.             choice = getMenu(options , 7)
  4969.             menuOffset = 10
  4970.         elseif mainChoice == 2 then
  4971.             options =   "\t1) Clear Field\n"..
  4972.                         "\t2) Create tree farm\n"..
  4973.                         "\t3) Plant tree farm\n"..
  4974.                         "\t4) Harvest tree farm\n"..
  4975.                         "\t5) Fell Tree\n"..
  4976.                         "\t6) Manage Auto-treeFarm"
  4977.             choice = getMenu(options , 6)
  4978.             menuOffset = 20
  4979.         elseif mainChoice == 3 then
  4980.             options =   "\t1) Clear Field\n"..
  4981.                         "\t2) Create 8x8 wheat farm\n"..
  4982.                         "\t3) Plant 8x8 wheat farm\n"..
  4983.                         "\t4) Harvest 8x8 wheat farm"
  4984.             choice = getMenu(options , 4)
  4985.             menuOffset = 30
  4986.         elseif mainChoice == 4 then
  4987.             options =   "\t1) Dig obsidian patch\n"..
  4988.                         "\t2) Build Nether Portal\n"..
  4989.                         "\t3) Demolish Nether Portal"
  4990.             choice = getMenu(options , 3)
  4991.             menuOffset = 40
  4992.         elseif mainChoice == 5 then
  4993.             options =   "\t1) Bridge over space or water\n"..
  4994.                         "\t2) Covered walkway\n"..
  4995.                         "\t3) Continuous single path\n"..
  4996.                         "\t4) Left side canal (dry passageway)\n"..
  4997.                         "\t5) Right side canal (flooded passage)"
  4998.             choice = getMenu(options , 5)
  4999.             menuOffset = 50
  5000.         elseif mainChoice == 6 then
  5001.             options =   "\t1) Spawner base & ocean path\n"..
  5002.                         "\t2) Create mob spawner tower\n"..
  5003.                         "\t3) Create mob spawner chamber\n"..
  5004.                         "\t4) Create mob spawner roof"
  5005.             choice = getMenu(options , 4)
  5006.             menuOffset = 60
  5007.         elseif mainChoice == 7 then
  5008.             options =   "\t1) Clear a rectangle\n"..
  5009.                         "\t2) Clear single wall\n"..
  5010.                         "\t3) Clear rectangular wall section\n"..
  5011.                         "\t4) Clear building floor and walls\n"..
  5012.                         "\t5) Clear building floor/walls/ceiling\n"..
  5013.                         "\t6) Hollow structure top->down\n"..
  5014.                         "\t7) Solid structure top->down\n"..
  5015.                         "\t8) Hollow structure bottom->up\n"..
  5016.                         "\t9) Solid structure bottom->up"
  5017.             choice = getMenu(options , 9)
  5018.             menuOffset = 70
  5019.         elseif mainChoice == 8 then
  5020.             options =   "\t1) Vertical wall from surface\n"..
  5021.                         "\t2) Drop sand or gravel wall\n"..
  5022.                         "\t3) Decapitate and fill with sand\n"..
  5023.                         "\t4) Clear sand wall\n"..
  5024.                         "\t5) Clear sand filled building\n"..
  5025.                         "\t6) Demolish sand filled structure\n"..
  5026.                         "\t7) Hollow structure top->down\n"..
  5027.                         "\t8) Solid structure top->down"
  5028.             choice = getMenu(options , 8)
  5029.             menuOffset = 80
  5030.         elseif mainChoice == 9 then
  5031.             options =   "\t1) Place Redstone:torch level track\n"..
  5032.                         "\t2) Place Redstone:torch upward track\n"..
  5033.                         "\t3) Build downward track\n"..
  5034.                         "\t4) Build upward track"
  5035.             choice = getMenu(options , 4)
  5036.             menuOffset = 90
  5037.         end
  5038.         if choice >= 0 then
  5039.             choice = choice + menuOffset
  5040.         end
  5041.     end
  5042.     T:clear()
  5043.     local instructions = "Enter to continue\nany other key to quit"
  5044.     if choice == 11 then --Create Mine
  5045.         print(  "Press F3 to check level. Look for 'Z'\n"..
  5046.                 "Place me down at   level 5, 9 or 13\n"..
  5047.                 "(Equivalent to eye level 6, 10 or 14)\n\n"..
  5048.                 instructions)
  5049.         choice = getDecision(choice)
  5050.     elseif choice == 12 then -- Ladder to bedrock
  5051.         print(  "Place me on the ground\n"..
  5052.                 "The ladder will start at this level\n"..
  5053.                 "and drop to bedrock\n\n"..
  5054.                 instructions)
  5055.         choice = getDecision(choice)
  5056.     elseif choice == 13 then    -- Ladder to surface
  5057.         print(  "Place me on the ground\n"..
  5058.                 "The ladder will start at this level\n"..
  5059.                 "and rise to the surface\n\n"..
  5060.                 instructions)
  5061.         choice = getDecision(choice)
  5062.     elseif choice == 14 then -- Stairs to bedrock
  5063.         print(  "Place me on the ground\n"..
  5064.                 "The stairs will start at this level\n"..
  5065.                 "and drop to bedrock in a 5x5 block\n\n"..
  5066.                 instructions)
  5067.         choice = getDecision(choice)
  5068.     elseif choice == 15 then -- Stairs to surface
  5069.         print(  "Place me on the ground\n"..
  5070.                 "The stairs will start at this level\n"..
  5071.                 "and rise to level 64 in a 5x5 block\n\n"..
  5072.                 instructions)
  5073.         choice = getDecision(choice)
  5074.     elseif choice == 16 then -- Search for mob spawner
  5075.         print(  "Place me anywhere on the ground\n"..
  5076.                 "When a spawner is found the\n"..
  5077.                 "coordinates are saved to file\n\n"..
  5078.                 instructions)
  5079.         choice = getDecision(choice)
  5080.     elseif choice == 17 then -- Decapitate volcano
  5081.         print(  "Place me on a basalt block\n"..
  5082.                 "on the left side of a volcano\n")
  5083.         width = getSize(false, "Volcano width at this level\n", 1, 64)
  5084.         length  = getSize(false, "Volcano length at this level\n", 1, 64)
  5085.     elseif choice == 21 or choice == 31 then --Clear field
  5086.         print(  "Place me on grass, lower left corner\n"..
  5087.                 "of the area\n"..
  5088.                 "To be levelled and cleared\n\n"..
  5089.                 "Provide Dirt to plug voids in the floor\n")
  5090.         width = getSize(false, "Width of the area (1-64)\n", 1, 64)
  5091.         length  = getSize(false, "Length of the area (1-64)\n", 1, 64)
  5092.     elseif choice == 22 then --Create treefarm
  5093.         print(  "Place me on grass, lower left corner\n"..
  5094.                 "of a 11x11 OR 19x19 square\n"..
  5095.                 "Trees to be grown on alternate blocks\n"..
  5096.                 "in a square 4x4 or 8x8 trees\n"..
  5097.                 "with a 2 block wide margin\n"..
  5098.                 instructions)
  5099.         choice = getDecision(choice)
  5100.         if choice > 0 then
  5101.             options =   "\t1 - 4 x 4 trees(16)\n\t2 - 8 x 8 trees(64)"
  5102.             size = getMenu(options , 2)
  5103.         end
  5104.     elseif choice == 23 then --Replant treefarm
  5105.         print("Place me in front of first tree base\n"..
  5106.         "or dirt on the lower left corner\n"..
  5107.         "of a 4x4 trees OR 8x8 trees square\n\n"..
  5108.         "Provide Birch and Oak Saplings for a\n"..
  5109.         "mixed tree farm\n\n"..
  5110.         instructions)
  5111.         choice = getDecision(choice)
  5112.         if choice > 0 then
  5113.             options =   "\t1 - 4 x 4 trees(16)\n\t2 - 8 x 8 trees(64)"
  5114.             size = getMenu(options , 2)
  5115.         end
  5116.     elseif choice == 24 then    -- Harvest treefarm
  5117.         print(  "Place me in front of first tree\n"..
  5118.                 "on the lower left corner\n"..
  5119.                 "of a 4x4 trees OR 8x8 trees square\n\n"..
  5120.                 "Fuel not required as logs will be used.\n\n"..
  5121.                 instructions)
  5122.         choice = getDecision(choice)
  5123.         if choice > 0 then
  5124.             options =   "\t1 - 4 x 4 trees(16)\n\t2 - 8 x 8 trees(64)"
  5125.             size = getMenu(options , 2)
  5126.         end
  5127.     elseif choice == 25 then    -- Fell Tree
  5128.         print(  "Place me in front of the tree\n"..
  5129.                 "you want to fell\n\n"..
  5130.                 "Fuel not required as logs will be used.\n\n"..
  5131.                 instructions)
  5132.         choice = getDecision(choice)
  5133.     elseif choice == 26 then    -- Manage Auto-TreeFarm
  5134.         print(  "For a new Auto-TreeFarm:\n"..
  5135.                 "Place me on left side of a 13x10 area\n\n"..
  5136.                 "For an existing farm:\n"..
  5137.                 "Place me in front of sapling\n"..
  5138.                 "or tree with the chest behind me\n\n"..
  5139.                 instructions)
  5140.         choice = getDecision(choice)
  5141.     elseif choice == 32 then    -- Create 8x8 wheat field farm
  5142.         print(  "Place me on left side of a cleared area\n"..
  5143.                 "or rough land if you want to use\n"..
  5144.                 "the option to clear the field first\n\n"..
  5145.                 instructions)
  5146.         choice = getDecision(choice)
  5147.     elseif choice == 33 then    -- Plant 8x8 wheat field
  5148.         print(  "Place me in front of the 2x2 pond\n"..
  5149.                 "on the left side facing the\n"..
  5150.                 "corner of the farm wall\n\n"..
  5151.                 instructions)
  5152.         choice = getDecision(choice)
  5153.     elseif choice == 34 then    -- Harvest 8x8 wheat field
  5154.         print(  "Place me in front of the 2x2 pond\n"..
  5155.                 "on the left side facing the\n"..
  5156.                 "corner of the farm wall\n\n"..
  5157.                 instructions)
  5158.         choice = getDecision(choice)
  5159.     elseif choice == 41 then    -- Harvest obsidian
  5160.         print(  "Place me on any block\n"..
  5161.                 "on the left side facing the\n"..
  5162.                 "obsidian patch.\n")
  5163.             width = getSize(false, "Width of the area (1-64)\n", 1, 64)
  5164.             length  = getSize(false, "Length of the area (1-64)\n", 1, 64)
  5165.     elseif choice == 42 then -- build Nether portal
  5166.         print(  "Place me on the ground\n"..
  5167.                 "on the left side\n"..
  5168.                 " of the portal base\n\n"..
  5169.                 instructions)
  5170.         choice = getDecision(choice)
  5171.     elseif choice == 43 then -- demolish Nether portal
  5172.         print(  "Place me on the ground\n"..
  5173.                 "on the left side\n"..
  5174.                 " of the portal base\n\n"..
  5175.                 instructions)
  5176.         choice = getDecision(choice)
  5177.     elseif choice == 51 then    --Bridge over void/water/lava
  5178.         print(  "Place me on the ground\n"..
  5179.                 "The bridge will start in front,\n"..
  5180.                 "continue for your chosen length\n"..
  5181.                 "and return\n")
  5182.         size = getSize(false, "Length of the area (1-32)\n", 1, 32)
  5183.     elseif choice == 52 then    --Covered walkway
  5184.         print(  "Place me on the ground\n"..
  5185.                 "The covered walkway will start in front,\n"..
  5186.                 "continue for your chosen length\n"..
  5187.                 "and return\n")
  5188.         size = getSize(false, "Length of the walk (1-32)\n", 1, 32)
  5189.     elseif choice == 53 then    --single path
  5190.         print(  "Place me on the ground in front\n"..
  5191.                 "of water, lava or air.\n"..
  5192.                 "Follow and supply blocks for a path\n\n"..
  5193.                 instructions)
  5194.         choice = getDecision(choice)
  5195.     elseif choice == 54 or choice == 55 then    --left/right side of new/existing canal
  5196.         local side = "left"
  5197.         if choice == 55 then
  5198.             side = "right"
  5199.         end
  5200.         print(  "I should be on either an existing canal\n"..
  5201.                 "on the "..side.." side\n"..
  5202.                 "or ready to start a new canal\n\n"..
  5203.                 "If crossing water I should be on top\n"..
  5204.                 "of a solid block making up the "..side.." wall\n")
  5205.         size = getSize(false, "Canal length? 0 = continuous\n", 0, 1024)
  5206.         length  = getSize(false, "Am I on the floor(0) or wall(1)?\n", 0, 1)
  5207.     elseif choice == 61 then -- Path to ocean base
  5208.         print(  "Place me on the ground in front\n"..
  5209.                 "of the ocean.\n"..
  5210.                 "Follow me as I create a path\n")
  5211.         size = getSize(false, "Path length (0-128)?\n", 0, 128)
  5212.     elseif choice == 62 then -- Ocean base complete. Place on polished block to start
  5213.         print(  "Place me on the stone block\n"..
  5214.                 "(granite / andesite / diorite)\n"..
  5215.                 "in the ocean base.\n"..
  5216.                 "Facing the sea\n")
  5217.         size = getSize(false, "Tower Height (32-128)?\n", 32, 128)
  5218.     elseif choice == 63 then -- Mob tower complete Place on polished block to start
  5219.         print(  "Place me on the stone block\n"..
  5220.                 "(granite / andesite / diorite)\n"..
  5221.                 "at the top of the tower.\n"..
  5222.                 "Facing the sea\n\n"..
  5223.                 instructions)
  5224.         choice = getDecision(choice)
  5225.     elseif choice == 64 then -- Mob tower roof Place on polished block to start
  5226.         print(  "Place me on the stone block\n"..
  5227.                 "(granite / andesite / diorite)\n"..
  5228.                 "at the top of the tower.\n"..
  5229.                 "Facing the sea\n\n"..
  5230.                 instructions)
  5231.         choice = getDecision(choice)
  5232.     elseif choice == 71 then -- Clear rectangle width, length
  5233.         print(  "Place me inside the lower left corner\n"..
  5234.                 "of the rectangle to be cleared.\n"..
  5235.                 "At the level to be worked on\n"..
  5236.                 "I will include this corner in\n"..
  5237.                 "the area to be cleared\n")
  5238.             width = getSize(false, "Width of the area (1-256)\n", 1, 256)
  5239.             length  = getSize(false, "Length of the area (1-256)\n", 1, 256)
  5240.     elseif choice == 72 then -- Clear wall height, length
  5241.         print(  "Place me inside the lower corner\n"..
  5242.                 "of the wall to be cleared.\n")
  5243.             width = 1
  5244.             length = getSize(false, "Length of wall (1-256)\n", 1, 256)
  5245.             height = getSize(false, "Height of wall (1-50)\n", 1, 50)
  5246.     elseif choice == 73 then -- Clear rectangle perimeter only width, length
  5247.         print(  "Place me inside the left corner\n"..
  5248.                 "of the rectangular wall to be cleared.\n"..
  5249.                 "At the level to be worked on\n"..
  5250.                 "I will include this corner in\n"..
  5251.                 "the area to be cleared\n")
  5252.             width = getSize(false, "Width of walled area (1-256)\n", 1, 256)
  5253.             length  = getSize(false, "Length of walled area (1-256)\n", 1, 256)
  5254.             height = 1
  5255.     elseif choice == 74 then -- Clear building floor/walls
  5256.         print(  "Place me inside the left corner\n"..
  5257.                 "in the floor of the building to be recycled.\n"..
  5258.                 "At the level to be worked on\n"..
  5259.                 "I will include this corner in\n"..
  5260.                 "the area to be cleared\n")
  5261.             width = getSize(false, "Ext. building width (1-256)\n", 1, 256)
  5262.             length  = getSize(false, "Ext. building length (1-256)\n", 1, 256)
  5263.             height  = getSize(false, "Ext. building height (1-256)\n", 1, 256)
  5264.     elseif choice == 75 then -- Clear building floor/walls/ceiling
  5265.         print(  "Place me inside the lower left corner\n"..
  5266.                 "in the floor of the building to be recycled.\n"..
  5267.                 "At the level to be worked on\n"..
  5268.                 "I will include this corner in\n"..
  5269.                 "the area to be cleared\n")
  5270.             width = getSize(false, "Ext. building width (1-256)\n", 1, 256)
  5271.             length  = getSize(false, "Ext. building length (1-256)\n", 1, 256)
  5272.             height  = getSize(false, "Ext. building height (1-256)\n", 1, 256)
  5273.     elseif choice == 76 or choice == 87 then -- Hollow structure top down
  5274.         print(  "Place me inside the left corner\n"..
  5275.                 "of the top of the hollow.\n")
  5276.             width = getSize(false, "Hollow section width (1-60)\n", 1, 60)
  5277.             length  = getSize(false, "Hollow section length (1-60)\n", 1, 60)
  5278.             height  = getSize(false, "Hollow section height (1-64)\n", 1, 64)
  5279.     elseif choice == 77 or choice == 88 then -- solid structure top down
  5280.         print(  "Place me inside the left corner\n"..
  5281.                 "of the top of the cube.\n")
  5282.             width = getSize(false, "Solid section width (1-60)\n", 1, 60)
  5283.             length  = getSize(false, "Solid section length (1-60)\n", 1, 60)
  5284.             height  = getSize(false, "Solid section height (1-64)\n", 1, 64)
  5285.     elseif choice == 78 or choice == 79 then -- remove hollow/solid structure bottom up
  5286.         print(  "Place me inside the left corner\n"..
  5287.                 "of the bottom of the structure.\n")
  5288.             width = getSize(false, "Structure width (1-60)\n", 1, 60)
  5289.             length  = getSize(false, "Structure length (1-60)\n", 1, 60)
  5290.             height  = getSize(false, "Structure height (1-64, 0=top)\n", 0, 64)
  5291.     elseif choice == 81 then -- build wall from water or lava surface downwards
  5292.         print(  "Place me on the surface facing wall END\n"..
  5293.                 "(Any block below will be removed)\n"..
  5294.                 "Wall will be built DOWN and BACKWARDS\n")
  5295.             width = 1
  5296.             length = getSize(false, "Length of the wall (1-60)\n", 1, 60)
  5297.             height = getSize(false, "Estimated depth (1-60) 0=default\n", 0, 60)
  5298.     elseif choice == 82 then -- drop sand into water or lava surface until solid grond reached
  5299.         print(  "Place me on the surface of water or lava\n"..
  5300.                 "Sand  will be dropped DOWN and Forwards\n")
  5301.             width = 1
  5302.             length = getSize(false, "Length of dam (0=to solid block)\n", 0, 60)
  5303.     elseif choice == 83 then -- clear rectangle on top of building and fill with sand
  5304.         print(  "Place me on top left corner of roof\n"..
  5305.                 "Sand  will be dropped into the hollow\n")
  5306.             width = getSize(false, "Width of roof (<=30)\n", 1, 30)
  5307.             length = getSize(false, "Length of of roof (<=30)\n", 1, 30)
  5308.     elseif choice == 84 then -- clear sand wall or harvest sand
  5309.         print(  "Place me on the surface of sand\n"..
  5310.                 "Sand  will be mined DOWN then forwards\n")
  5311.             width = 1
  5312.             length = getSize(false, "Length of sand \n", 1, 250)
  5313.     elseif choice == 85 then -- remove sand from cube. start at top
  5314.         print(  "Place me on top left corner of sand\n"..
  5315.                 "Sand cleared down, then left to right\n")
  5316.             width = getSize(false, "Width of sand (<=30)\n", 1, 30)
  5317.             length = getSize(false, "Length of of sand (<=30)\n", 1, 30)
  5318.     elseif choice == 86 then -- remove floor, walls (and sand) from building. start at base
  5319.         print(  "Place me on lower left corner of floor\n"..
  5320.                 "Floor + walls removed + sand cleared\n")
  5321.             width = getSize(false, "Width of floor (<=30)\n", 1, 30)
  5322.             length = getSize(false, "Length of of floor (<=30)\n", 1, 30)
  5323.     -- elseif choice == 87 then check 76 above
  5324.     -- elseif choice == 88 then check 77 above
  5325.     elseif choice == 91 then -- place redstone torch under current block
  5326.         print(  "Place me on suspended railway stone\n"..
  5327.                 "Redstone torch will go below me\n")
  5328.             width = 0
  5329.             length = 0
  5330.     elseif choice == 92 then -- place redstone torch on upward slope
  5331.         print(  "Place me on railway stone going up\n"..
  5332.                 "Redstone torch will go below me\n")
  5333.             width = 0
  5334.             length = 0
  5335.     elseif choice == 93 then -- build downward slope
  5336.         print(  "Place me on last stone\n"..
  5337.                 "Track will go down from this point\n")
  5338.             width = 0
  5339.             length = 0
  5340.             height  = getSize(false, "Drop down by how many blocks?\n", 1, 64)
  5341.     elseif choice == 94 then -- build upward slope
  5342.         print(  "Place me on last stone\n"..
  5343.                 "Track will go up from this point\n")
  5344.             width = 0
  5345.             length = 0
  5346.             height  = getSize(false, "Go up by how many blocks?\n", 1, 64)
  5347.     end
  5348.    
  5349.     return choice, size, width, length, height -- eg 86, 0, 8, 8, 4
  5350. end
  5351.  
  5352. function initialise()
  5353.     local doContinue = true
  5354.     local hasChest = false
  5355.     print("Survival Toolkit")
  5356.     print()
  5357.     if os.getComputerLabel() == nil then
  5358.         os.setComputerLabel("Survivor")
  5359.         print("Computer label set to "..os.getComputerLabel())
  5360.         print()
  5361.         os.sleep(1.5)
  5362.     end
  5363.     -- create turtle object and check tools. Ideally crafting table and diamond pickaxe
  5364.     T = createTurtleObject()
  5365.    
  5366.     --[[ debug area!
  5367.         doContinue = false
  5368.         local block, blockType = T:isWaterOrLava("up")
  5369.         print("isWaterOrLava(up) = '"..block.."', "..blockType)
  5370.         block, blockType = T:isWaterOrLava("forward")
  5371.         print("isWaterOrLava(forward) = '"..block.."', "..blockType)
  5372.         block, blockType = T:isWaterOrLava("down")
  5373.         print("isWaterOrLava(down) = '"..block.."', "..blockType)]]
  5374.    
  5375.     --[[ debug area!
  5376.         --go(path, useTorch, torchInterval, leaveExisting, checkDungeon)
  5377.         doContinue = false
  5378.         T:go("t0", true, 0, false, false)
  5379.         print("torch up")]]
  5380.  
  5381.    
  5382.     --T:getCoords(true)
  5383.     --home = createCoordinatesObject("homeLocation")
  5384.     --home:setAllValues(T:getX(), T:getY(), T:getZ(), T:getFacing())
  5385.     --make sure diamond pickaxe is equipped
  5386.     --[[while T.equippedLeft ~= "minecraft:diamond_pickaxe" do
  5387.         checkInventory(0, 0, 0, 0)
  5388.     end
  5389.     while T.equippedRight ~= "minecraft:crafting_table" do
  5390.         checkInventory(1, 0, 0, 0)
  5391.     end]]
  5392.     return doContinue
  5393. end
  5394.  
  5395. function repairWall(startAt, height, width, replaceWith)
  5396.     -- go up to startAt
  5397.    
  5398.     -- if width = 1
  5399.    
  5400.         -- for h = startAt, height, 1 do
  5401.        
  5402.             -- replace block with replaceWith ("" = any)
  5403.            
  5404.             -- move up
  5405.            
  5406.         --end
  5407.        
  5408.         -- move back to beginning
  5409.        
  5410.     -- else
  5411.    
  5412.         -- remain = height % 2
  5413.        
  5414.         -- for w = 1, width - remain do
  5415.        
  5416.             -- for h = startAt, height, 1 do
  5417.            
  5418.                 -- replace block with replaceWith ("" = any)
  5419.                
  5420.                 -- move up
  5421.                
  5422.             --end
  5423.            
  5424.             -- move to the right 1 block
  5425.            
  5426.             -- for i = height, startAt, -1 do
  5427.            
  5428.                 -- replace block with replaceWith ("" = any)
  5429.                
  5430.                 -- move down
  5431.                
  5432.             --end
  5433.            
  5434.         -- end
  5435.        
  5436.     -- end
  5437.    
  5438. end
  5439.  
  5440. function searchForSpawner(level)
  5441.     -- go down 8 with ladder above
  5442.     -- go(path, useTorch, torchInterval, leaveExisting, checkDungeon)
  5443.     -- depth = math.floor(level / 8)
  5444.    
  5445.     T:down(1)
  5446.     for i = 1, 6 do
  5447.         T:go("C1R1C1R1C1R1C1R1D1e0", false, 0, true, true)
  5448.     end
  5449.     -- go down 1 further
  5450.     T:down(1)
  5451.    
  5452.     local distance = 0
  5453.     local returnLength = 0
  5454.     local actualLength = 32
  5455.     local checkDungeon = true
  5456.     for j = 1, 4 do
  5457.         for i = 1, 3 do
  5458.             actualLength = 32
  5459.             actualLength = T:createTunnel(actualLength, true, checkDungeon) --may cut short if in ocean
  5460.             T:turnRight(1)
  5461.             T:createTunnel(9, false, checkDungeon)
  5462.             T:turnRight(1)
  5463.             T:createTunnel(actualLength, false)
  5464.             returnLength = returnLength + 8
  5465.             -- ready to cut next section
  5466.             if i < 3 then
  5467.                 T:turnLeft(1)
  5468.                 actualLength = T:createTunnel(9, true, checkDungeon) --may cut short if in ocean
  5469.                 if actualLength == 9 then
  5470.                     returnLength = returnLength + 8
  5471.                     T:turnLeft(1)
  5472.                 else
  5473.                     -- cut short, block tunnel and return
  5474.                     T:go("C2R1C1L1C1L1C1R1U1L1C1R1C1R1C1R1C0", false, 0, true, false)
  5475.                     T:go("F"..actualLength.."D1", false, 0, true, true)
  5476.                     break
  5477.                 end
  5478.             else
  5479.                 T:turnRight(1)
  5480.             end
  5481.             T:dumpRefuse(3) -- keep 4 stacks cobble
  5482.         end
  5483.         T:createTunnel(returnLength + 1, false, false)
  5484.         -- move 9 places forward and repeat
  5485.         T:createTunnel(9, false, checkDungeon)
  5486.     end
  5487. end
  5488.  
  5489. function main()
  5490.     if initialise() then
  5491.         -- crafting table equipped: continue
  5492.         local choice, size, width, length, height = getTask()
  5493.         if choice > 0 then
  5494.             checkInventory(choice, size, width, length, height)
  5495.         end
  5496.         T:clear()
  5497.         print("Thank you for using 'survival toolkit'")
  5498.     else
  5499.         print("Unable to initialise. Check code")
  5500.     end
  5501. end
  5502.  
  5503. main()
Add Comment
Please, Sign In to add comment