Inksaver

tk.lua toolkit (requires libs):2022/05/26

Apr 20th, 2020 (edited)
1,991
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 274.23 KB
  1. version = 20220526.1100
  2. --[[
  3.     **********Toolkit v2**********
  4.     https://pastebin.com/UFvjc1bw
  5.     Last edited: see version YYYYMMDD.HHMM
  6.     if NOT online:
  7.         Make sure you create a folder 'lib' and place menu.lua and clsTurtle.lua into it
  8.     else
  9.         lib folder will be created and files obtained automatically!
  10.     end
  11.     all functions are being converted to 'local' as they are revised
  12. ]]
  13.  
  14. args = {...} -- eg "farm", "tree"
  15.  
  16. local menu, T
  17. --[[
  18. Computercraft started with mc version 1.7.10 and went to 1.8.9
  19. ccTweaked started around mc 1.12 and currently at 1.18
  20. mc 1.18 has new blocks and bedrock at -64, so needs to be taken into account.
  21. _HOST = The ComputerCraft and Minecraft version of the current computer environment.
  22. For example, ComputerCraft 1.93.0 (Minecraft 1.15.2).
  23. ]]
  24. local bedrock = 0
  25. local ceiling = 255
  26. local deletesWater = false
  27. local mcMajorVersion = tonumber(_HOST:sub(_HOST:find("Minecraft") + 10, _HOST:find("\)") -3)) -- eg 1.18
  28. if mcMajorVersion < 1.7  and mcMajorVersion >= 1.18 then -- 1.12 to 1.??
  29.     bedrock = -64
  30.     ceiling = 319
  31. end
  32. if mcMajorVersion < 1.7  and mcMajorVersion <= 1.12 then -- 1.12 to 1.??
  33.     deletesWater = true
  34. end
  35.  
  36. local function attack(onPerch)
  37.     local totalHitsF = 0
  38.     local totalHitsU = 0
  39.     local totalHitsD = 0
  40.     if onPerch then
  41.         turtle.digUp()
  42.     end
  43.     while true do
  44.         local hitF = false
  45.         local hitU = false
  46.         local hitD = false
  47.         if turtle.attackUp() then
  48.             hitU = true
  49.             totalHitsU = totalHitsU + 1
  50.         end
  51.         if onPerch then
  52.             turtle.turnRight()
  53.         else
  54.             if turtle.attackDown() then
  55.                 hitD = true
  56.                 totalHitsD = totalHitsD + 1
  57.             end
  58.             if turtle.attack() then
  59.                 hitF = true
  60.                 totalHitsF = totalHitsF + 1
  61.             end
  62.         end
  63.         if hitF or hitU or hitD then
  64.             print("hits forward: "..totalHitsF..", up: "..totalHitsU..", down: "..totalHitsD)
  65.         end
  66.     end
  67. end
  68.  
  69. local function checkFuelNeeded(quantity)
  70.     local fuelNeeded = quantity - turtle.getFuelLevel() -- eg 600
  71.     if fuelNeeded > 0 then
  72.         if T:checkInventoryForItem({"minecraft:lava_bucket"}, {1}, false) == nil then  
  73.             if T:checkInventoryForItem({"coal"}, {math.ceil(fuelNeeded / 60)}, false) == nil then
  74.                 T:checkInventoryForItem({"planks"}, {math.ceil(fuelNeeded / 15)})
  75.             end
  76.         end
  77.         T:refuel(quantity, true)
  78.     end
  79. end
  80.  
  81. local function checkLabel()
  82.     if os.getComputerLabel() == nil then
  83.         os.setComputerLabel("toolkit")
  84.         print("Computer label set to "..os.getComputerLabel())
  85.     end
  86. end
  87.  
  88. function checkLibs(libDir, filename)
  89.     local fileExists = false
  90.     if fs.exists(libDir) then
  91.         if not fs.isDir(libDir) then
  92.             fs.move(libDir, libDir.."Renamed")
  93.             fs.makeDir(libDir)
  94.         end
  95.     else
  96.         fs.makeDir(libDir)
  97.     end
  98.     if fs.exists(fs.combine(libDir, filename)) or fs.exists(fs.combine(libDir, filename..".lua")) then
  99.         fileExists = true
  100.     end
  101.     return fileExists
  102. end
  103.  
  104. local function clearAndReplantTrees()
  105.     --[[ clear all trees in a rectangle area defined by walls, fences or non-dirt blocks
  106.     replant with same type of sapling. If original tree 2 blocks wide, replant 4 if possible. ]]
  107.    
  108.     local lib = {}
  109.    
  110.     function lib.getSaplingFromLogType(log)
  111.         --[[ get type of sapling to plant from log type ]]
  112.         if log:find("oak") ~= nil then
  113.             return "minecraft:oak_sapling"
  114.         elseif log:find("spruce") ~= nil then
  115.             return "minecraft:spruce_sapling"
  116.         elseif log:find("birch") ~= nil then
  117.             return "minecraft:birch_sapling"
  118.         elseif log:find("jungle") ~= nil then
  119.             return "minecraft:jungle_sapling"
  120.         elseif log:find("acacia") ~= nil then
  121.             return "minecraft:acacia_sapling"
  122.         elseif log:find("dark_oak") ~= nil then
  123.             return "minecraft:dark_oak_sapling"
  124.         end
  125.         return "sapling"
  126.     end
  127.    
  128.     function lib.plantSapling(sapling, double)
  129.         --[[ plant sapling(s) ]]
  130.         if sapling == "" or sapling == nil then sapling = "sapling" end
  131.         T:up(1)
  132.         lib.suck()
  133.         if double then  -- check if enough saplings
  134.             --slotData.lastSlot, slotData.leastModifier, total, slotData = T:getItemSlot(sapling, -1)
  135.             local a, b, total, _ = T:getItemSlot(sapling, -1)
  136.             if total >= 4 then
  137.                 for i = 1, 4 do
  138.                     T:place(sapling, -1, "down")
  139.                     T:go("F1R1")
  140.                 end
  141.                 T:forward(1)        -- above pre-planted sapling
  142.             else
  143.                 if not T:place(sapling, -1, "down") then
  144.                     T:place("sapling", -1, "down")
  145.                 end
  146.             end
  147.         else
  148.             if not T:place(sapling, -1, "down") then
  149.                 T:place("sapling", -1, "down")
  150.             end
  151.         end
  152.         turtle.select(1)
  153.     end
  154.        
  155.     function lib.suck()
  156.         --[[ Collect saplings, sticks and apples ]]
  157.         turtle.select(1)
  158.         turtle.suck()
  159.         turtle.suckUp()
  160.         turtle.suckDown()
  161.     end
  162.    
  163.     function lib.turn(direction)
  164.         --[[ change direction and return new value for direction ]]
  165.         if direction == "r" then
  166.             T:turnRight(1)
  167.             direction = "l"
  168.         else
  169.             T:turnLeft(1)
  170.             direction = "r"
  171.         end
  172.         return direction    -- will only change direction variable if return value is used
  173.     end
  174.    
  175.     function lib.emptyInventory(blockTypeD)
  176.         --[[ Empty all except 32 of each sapling and 1 chest ]]
  177.         if blockTypeD == nil then
  178.             blockTypeD = T:getBlockType("down")
  179.         end
  180.         if blockTypeD:find("chest") ~= nil or blockTypeD:find("barrel") ~= nil then
  181.             -- empty logs, apples, sticks and all but 1 stack of each sapling type
  182.             T:emptyInventorySelection("down", {"chest", "oak_sapling", "birch_sapling", "spruce_sapling", "acacia_sapling", "jungle_sapling","dark_oak_sapling"},{1, 32, 32, 32, 32, 32, 32})
  183.             return true
  184.         else
  185.             return false
  186.         end
  187.     end
  188.    
  189.     function lib.moveDown(blockTypeD)
  190.         --[[ move down until hit ground. Break leaves and continue ]]
  191.         if blockTypeD == nil then
  192.             blockTypeD = T:getBlockType("down")
  193.         end
  194.         while blockTypeD == "" or blockTypeD:find("leaves") ~= nil do   -- move down, breaking leavse
  195.             T:down(1)
  196.             lib.suck()
  197.             blockTypeD = T:getBlockType("down")
  198.         end
  199.         return blockTypeD
  200.     end
  201.    
  202.     function lib.moveForward()
  203.         --[[ Move forward 1 block only, go down to ground while air or leaves below ]]
  204.         local blockTypeF = T:getBlockType("forward")
  205.         local blockTypeD = T:getBlockType("down")
  206.         if blockTypeF == "" or blockTypeF:find("leaves") ~= nil then    -- air or leaves ahead
  207.             T:forward(1)                                                -- move forward, breaking leaves
  208.             T:dig("up")                                                 -- remove leaves / low branches above to allow space for player
  209.             lib.suck()
  210.             blockTypeD = lib.moveDown()
  211.             if not lib.emptyInventory(blockTypeD) then                  -- check if above a corner chest / barrel
  212.                 if lib.isBorder(blockTypeD) then                        -- not above chest so check if above border
  213.                     return false, blockTypeD                            -- above a border block so stop
  214.                 end
  215.             end
  216.             blockTypeF = T:getBlockType("forward")
  217.             return true, blockTypeF                                     -- moved ok, could be air or block in front
  218.         end
  219.         return false, blockTypeF                                        -- did not move, obstacle in front NOT leaves or air
  220.     end
  221.    
  222.     function lib.moveUp(blockTypeF)
  223.         --[[ Move up until air in front (dig leaves / harvest tree) ]]
  224.         if blockTypeF == nil then
  225.             blockTypeF = T:getBlockType("forward")
  226.         end
  227.         while blockTypeF:find("dirt") ~= nil or
  228.               blockTypeF:find("grass_block") ~= nil or
  229.               T:isVegetation(blockTypeF) do -- go up while dirt, grass-block or any vegetation in front
  230.             T:up(1)
  231.             blockTypeF = T:getBlockType("forward")
  232.             if blockTypeF:find("log") ~= nil then
  233.                 lib.harvestTree(blockTypeF)
  234.                 return T:getBlockType("forward")
  235.             elseif blockTypeF:find("leaves") ~= nil then
  236.                 T:dig("forward")
  237.                 return ""
  238.             end
  239.         end
  240.         return blockTypeF   -- should be "" (air) or any border block
  241.     end
  242.    
  243.     function lib.harvestTree(blockTypeF)
  244.         --[[ Fell tree, returns true if double size ]]
  245.         -- clsTurtle.harvestTree(extend, craftChest, direction)
  246.         local saplingType = lib.getSaplingFromLogType(blockTypeF)
  247.         local double = T:harvestTree(false, false, "forward")   -- assume single tree, will auto-discover
  248.         lib.plantSapling(saplingType, double)
  249.     end
  250.    
  251.     function lib.safeMove()
  252.         --[[ move forward until border reached. loop breaks at that point ]]
  253.         local blockTypeF = ""
  254.         local success = true
  255.         while success do
  256.             success, blockTypeF = lib.moveForward()             -- move forward 1 block, return block type ahead
  257.             if not success then                                 -- did not move forwards, block in the way: either log, dirt/grass, border block or vegetation
  258.                 if blockTypeF:find("log") then                  -- tree found
  259.                     lib.harvestTree(blockTypeF)
  260.                     success = true                              -- block (log) removed, try again
  261.                 else
  262.                     success = not lib.isBorder(blockTypeF)      -- Is at border?: if is at border success = false so loop stops
  263.                     if success then                             -- Not at border. Dirt/grass vegetation in front
  264.                         blockTypeF = lib.moveUp(blockTypeF)     -- move up until leaves/log/air
  265.                         success = not lib.isBorder(blockTypeF)  -- Is at border?: if is at border success = false so loop stops
  266.                         if success then                         -- keep moving forward
  267.                             if blockTypeF:find("log") then      -- tree found
  268.                                 lib.harvestTree(blockTypeF)
  269.                             end
  270.                                                                 -- else blockTypeF is air/leaves  border has been checked
  271.                         end
  272.                     end
  273.                 end
  274.             end                                                 -- else success = true, 1 block moved so continue
  275.         end
  276.     end
  277.    
  278.     function lib.isBorder(blockType)
  279.         --[[ Is the block log, dirt, grass_block, vegetation: non-border, or other:border]]
  280.         if blockType == nil then                    -- not passed as parameter
  281.             blockType = T:getBlockType("forward")
  282.         end
  283.         if blockType == "" then                     -- air ahead: not border
  284.             return false, ""
  285.         else                                        -- could be border or other
  286.             if blockType:find("dirt") ~= nil or blockType:find("grass_block") ~= nil or blockType:find("log") ~= nil then -- either dirt, grass block or log
  287.                 return false, blockType             -- dirt, grass, log: not border
  288.             end
  289.             if T:isVegetation(blockType) then       -- vegetation found: not border
  290.                 return false, blockType
  291.             end
  292.         end
  293.         return true, blockType                      -- dirt, grass_block, log and vegetation eliminated:must be border
  294.     end
  295.    
  296.     function lib.inPosition()
  297.         --[[ check if in lower left corner ]]
  298.         local inPosition = true         -- assume correct
  299.         if not turtle.detectDown() then -- hanging in mid-air
  300.             return false
  301.         end
  302.         T:turnLeft(1)
  303.         if lib.isBorder() then
  304.             -- so far so good
  305.             T:turnLeft(1)
  306.             if not lib.isBorder() then  -- not in correct place
  307.                 inPosition = false
  308.             end
  309.             T:turnRight(2)              -- return to original position
  310.         else
  311.             inPosition = false
  312.             T:turnRight(1)              -- return to original position
  313.         end
  314.         return inPosition
  315.     end
  316.    
  317.     function lib.findBorder()
  318.         --[[ assume started after reset. if log above harvest tree else return to ground. Find starting corner]]
  319.         local blockType = T:getBlockType("up")                  -- dig any logs above, return to ground
  320.         local log = "sapling"
  321.         if blockType:find("log") ~= nil then                    -- originally felling a tree so complete it
  322.             log = lib.getSaplingFromLogType(blockType)
  323.             local double = T:harvestTree(false, false, "up")    -- assume single tree, will auto-discover
  324.             lib.plantSapling(log, double)
  325.         else                                                    -- no log above so go downm
  326.             blockType = lib.moveDown()                          -- return to ground (or vegetation)
  327.         end
  328.         lib.safeMove()                                          -- move forward until border reached
  329.         T:turnRight(1)
  330.         lib.safeMove()                                          -- move forward until second border reached
  331.         T:turnRight(1)                                          -- should now be in correct position
  332.         lib.emptyInventory()                                    -- empty inventory if above a chest
  333.     end
  334.    
  335.     local direction = "r"
  336.     local blockTypeF = ""
  337.     local success = false
  338.     if not lib.inPosition() then
  339.         lib.findBorder()
  340.     end
  341.     local secondBorderFound = false
  342.     while not secondBorderFound do
  343.         lib.safeMove()                                                      -- moves forward until reaches border forward or below
  344.         lib.turn(direction)                                                 -- turn r or l. direction is not changed
  345.         success, blockTypeF = lib.isBorder()                                -- no blockType passed as parameter so will return current block in new forward direction
  346.         if success then
  347.             secondBorderFound = true                                        -- game over
  348.         elseif blockTypeF:find("log") ~= nil then                           -- tree in front
  349.             lib.harvestTree(blockTypeF)
  350.         elseif blockTypeF == "" or blockTypeF:find("leaves") ~= nil then    -- air or leaves in front
  351.             T:forward(1)                                                    -- move forward 1 block
  352.             lib.moveDown()                                                  -- go down if required
  353.         elseif  blockTypeF:find("dirt") ~= nil or
  354.                 blockTypeF:find("grass_block") ~= nil or
  355.                 T:isVegetation(blockTypeF) then                             -- dirt, grass_block or vegetation in front
  356.             blockTypeF = lib.moveUp(blockTypeF)                             -- move up until air or border ahead.
  357.             if lib.isBorder(blockTypeF) then                                -- border ahead
  358.                 secondBorderFound = true
  359.             else                                                            -- air ahead                                   
  360.                 T:forward(1)                                                -- move forward 1 block
  361.             end
  362.         end
  363.         direction = lib.turn(direction)                                     -- turn r or l. direction is changed to opposite
  364.     end
  365.     lib.moveDown()                                                          -- return to ground level
  366.     lib.emptyInventory()
  367. end
  368.  
  369. function clearArea(width, length, useDirt)
  370.     if useDirt == nil then
  371.         useDirt = true
  372.     end
  373.     local evenWidth = false
  374.     local evenHeight = false
  375.     local loopWidth
  376.     -- go(path, useTorch, torchInterval, leaveExisting)
  377.     if width % 2 == 0 then
  378.         evenWidth = true
  379.         loopWidth = width / 2
  380.     else
  381.         loopWidth = math.ceil(width / 2)
  382.     end
  383.     if length % 2 == 0 then
  384.         evenHeight = true
  385.     end
  386.     turtle.select(1)
  387.     -- clear an area between 2 x 4 and 32 x 32
  388.     -- if width is even no, then complete the up/down run
  389.     -- if width odd no then finish at top of up run and reverse
  390.     -- should be on flat ground, check voids below, harvest trees
  391.     for x = 1, loopWidth do
  392.         -- Clear first column (up)
  393.         for y = 1, length do
  394.             if useDirt then
  395.                 if not turtle.detectDown() then
  396.                     T:place("minecraft:dirt", -1, "down", true)
  397.                 else --if not water, dirt, grass , stone then replace with dirt
  398.                     blockType, blockModifier = T:getBlockType("down")
  399.                     if blockType ~= "" then
  400.                         if blockType ~= "minecraft:dirt" and blockType ~= "minecraft:grass_block" then
  401.                             turtle.digDown()
  402.                             T:place("minecraft:dirt", -1, "down", true)
  403.                         end
  404.                     end
  405.                 end
  406.             end
  407.             if y < length then
  408.                 T:go("F1+1", false,0,false)
  409.             end
  410.         end
  411.         -- clear second column (down)
  412.         if x < loopWidth or (x == loopWidth and evenWidth) then -- go down if on width 2,4,6,8 etc
  413.             T:go("R1F1+1R1", false,0,false)
  414.             for y = 1, length do
  415.                 if useDirt then
  416.                     if not turtle.detectDown() then
  417.                         T:place("minecraft:dirt", -1, "down", true)
  418.                     else
  419.                         blockType, blockModifier = T:getBlockType("down")
  420.                         if blockType ~= "" then
  421.                             if blockType ~= "minecraft:dirt" and blockType ~= "minecraft:grass_block" then
  422.                                 turtle.digDown()
  423.                                 T:place("minecraft:dirt", -1, "down", true)
  424.                             end
  425.                         end
  426.                     end
  427.                 end
  428.                 if y < length then
  429.                     T:go("F1+1", false, 0, false)
  430.                 end
  431.             end
  432.             if x < loopWidth then
  433.                 T:go("L1F1+1L1", false,0,false)
  434.             else
  435.                 T:turnRight(1)
  436.                 T:forward(width - 1)
  437.                 T:turnRight(1)
  438.             end
  439.         else -- equals width but is 1,3,5,7 etc
  440.             T:turnLeft(2) --turn round 180
  441.             T:forward(length - 1)
  442.             T:turnRight(1)
  443.             T:forward(width - 1)
  444.             T:turnRight(1)
  445.         end
  446.     end
  447. end
  448.  
  449. local function clearRectangle(width, length, up, down)
  450.     local lib = {}
  451.     function lib.UpDown(length)
  452.         for l = 1, length do
  453.             T:go("x0x2F1x0x2")
  454.         end
  455.     end
  456.    
  457.     function lib.Up(length)
  458.         for l = 1, length do
  459.             T:go("x0F1x0")
  460.         end
  461.     end
  462.    
  463.     function lib.Down(length)
  464.         for l = 1, length do
  465.             T:go("x2F1x2")
  466.         end
  467.     end
  468.    
  469.     function lib.Forward(length)
  470.         T:forward(length)
  471.     end
  472.    
  473.     if up == nil then --remove blocks above
  474.         up = false
  475.     end
  476.     if down == nil then --remove blocks below
  477.         down = false
  478.     end
  479.     -- could be 1 wide x xx length (trench) up and return
  480.     -- could be 2+ x 2+
  481.     -- even no of runs return after last run
  482.     -- odd no of runs forward, back, forward, reverse and return
  483.     turtle.select(1)
  484.     if width == 1 then                  -- single block trench ahead only
  485.         if up and down then             -- single block wide trench dig up and down = 3 blocks deep
  486.             T:up(1)
  487.             lib.UpDown(length - 1)
  488.             T:down(1)
  489.         elseif up then                  -- single block wide trench dig up = 2 blocks deep
  490.             lib.Up(length - 1)
  491.         elseif down then                -- single block wide trench dig down = 2 blocks deep
  492.             lib.Down(length - 1)
  493.         else                            -- single block wide = 1 block deep
  494.             lib.Forward(length - 1)
  495.         end
  496.         T:turnRight(2)                  -- turn at the top of the run
  497.         T:forward(length - 1)           -- return to start
  498.         T:turnRight(2)                  -- turn round to original position
  499.     else                                -- width 2 or more blocks
  500.         local iterations = 0            -- width = 2, 4, 6, 8 etc
  501.         if width % 2 == 1 then          -- width = 3, 5, 7, 9 eg width 7
  502.             iterations = (width - 1) / 2 -- iterations 1, 2, 3, 4 for widths 3, 5, 7, 9
  503.         else
  504.             iterations = width / 2      -- iterations 1, 2, 3, 4 for widths 2, 4, 6, 8
  505.         end
  506.         for i = 1, iterations do        -- eg 3 blocks wide, iterations = 1
  507.             if up and down then                         -- dig up and down
  508.                 lib.UpDown(length - 1)
  509.                 T:go("x0x2R1F1x0x2R1x0x2")              -- turn round
  510.                 lib.UpDown(length - 1)
  511.             elseif up then                              -- dig up
  512.                 lib.Up(length - 1)
  513.                 T:go("x0R1F1x0R1x0")
  514.                 lib.Up(length - 1)
  515.             elseif down then                            -- dig down
  516.                 lib.Down(length - 1)
  517.                 T:go("x2R1F1x2R1x2")
  518.                 lib.Down(length - 1)
  519.             else                                        -- no digging up or down
  520.                 lib.Forward(length - 1)
  521.                 T:go("R1F1R1")
  522.                 lib.Forward(length - 1)
  523.             end
  524.             -- if 1 less than end, reposition for next run
  525.             if i < iterations then
  526.                 T:go("L1F1L1", false, 0, false)
  527.             end
  528.         end
  529.         if width % 2 == 1 then  -- additional run and return to base needed
  530.             T:go("L1F1L1", false, 0, false)
  531.             if up and down then
  532.                 lib.UpDown(length - 1)
  533.             elseif up then
  534.                 lib.Up(length - 1)
  535.             elseif down then
  536.                 lib.Down(length - 1)
  537.             else
  538.                 lib.Forward(length - 1)
  539.             end
  540.             T:turnRight(2)
  541.             T:forward(length - 1)
  542.         end
  543.         T:go("R1F"..width - 1 .."R1", false, 0, false)
  544.     end
  545. end
  546.  
  547. local function clearPerimeter(width, length, up, down)
  548.     local lib = {}
  549.     function lib.UpDown(length)
  550.         for l = 1, length do
  551.             T:go("x0x2F1x0x2")
  552.         end
  553.     end
  554.    
  555.     function lib.Up(length)
  556.         for l = 1, length do
  557.             T:go("x0F1x0")
  558.         end
  559.     end
  560.    
  561.     function lib.Down(length)
  562.         for l = 1, length do
  563.             T:go("x2F1x2")
  564.         end
  565.     end
  566.    
  567.     function lib.Forward(length)
  568.         T:forward(length)
  569.     end
  570.    
  571.     if up and down then
  572.         for i = 1, 2 do
  573.             lib.UpDown(length - 1)
  574.             T:turnRight(1)
  575.             lib.UpDown(width - 1)
  576.             T:turnRight(1)
  577.         end
  578.     elseif up then
  579.         for i = 1, 2 do
  580.             lib.Up(length - 1)
  581.             T:turnRight(1)
  582.             lib.Up(width - 1)
  583.             T:turnRight(1)
  584.         end
  585.     elseif down then
  586.         for i = 1, 2 do
  587.             lib.Down(length - 1)
  588.             T:turnRight(1)
  589.             lib.Down(width - 1)
  590.             T:turnRight(1)
  591.         end
  592.     else
  593.         for i = 1, 2 do
  594.             lib.Forward(length - 1)
  595.             T:turnRight(1)
  596.             lib.Forward(width - 1)
  597.             T:turnRight(1)
  598.         end
  599.     end
  600. end
  601.  
  602. local function clearBuilding(width, length, height, direction, withCeiling, withFloor)
  603.     -- clearBuilding(width, length, height, size, withCeiling, withFloor) -- eg 5, 5, 6, 0, true, true
  604.     -- direction = Bottom->Top (0), Top->bottom(1)
  605.     local lib = {}
  606.    
  607.     function lib.Layer1(direction, withCeiling, withFloor, width, length)
  608.         -- 1 layer only
  609.         if withFloor or withCeiling then    -- only one layer, so clearRectangle
  610.             clearRectangle(width, length, false, false)
  611.         else
  612.             clearPerimeter(width, length, false, false) -- pass
  613.         end
  614.         return 0
  615.     end
  616.    
  617.     function lib.Layer2(direction, withCeiling, withFloor, width, length)
  618.         -- 2 layers. Stay on 1 layer and dig up / down as needed
  619.         if withFloor or withCeiling then
  620.             clearRectangle(width, length, withCeiling, withFloor)   -- clear area and dig up / down as required
  621.             --[[if direction == 0 then
  622.                 clearRectangle(width, length, true, false)  -- clear area and dig up
  623.             else
  624.                 clearRectangle(width, length, false, true)  -- clear area and dig down
  625.             end]]
  626.         else
  627.             if direction == 0 then
  628.                 clearPerimeter(width, length, true, false)  -- clear perimeter and dig up
  629.             else
  630.                 clearPerimeter(width, length, false, true)  -- clear perimeter and dig down
  631.             end
  632.         end
  633.         return 0
  634.     end
  635.    
  636.     function lib.Layer3(direction, withCeiling, withFloor, width, length)
  637.         -- move up / down 1 block and dig up and down
  638.         if direction == 0 then
  639.             T:up(1)
  640.         else
  641.             T:down(1)
  642.         end
  643.         if withFloor or withCeiling then
  644.             clearRectangle(width, length, true, true)
  645.         else
  646.             clearPerimeter(width, length, true, true)
  647.         end
  648.         return 1
  649.     end
  650.    
  651.     function lib.Layer4(direction, withCeiling, withFloor, width, length)
  652.         -- clear current level
  653.         lib.Layer1(direction, withCeiling, withFloor, width, length)
  654.         if direction == 0 then
  655.             T:up(1)
  656.             lib.Layer3(direction, withCeiling, false, width, length)
  657.         else
  658.             T:down(1)
  659.             lib.Layer3(direction, false, withFloor, width, length)
  660.         end
  661.         return 2
  662.     end
  663.    
  664.     function lib.Layer5(direction, withCeiling, withFloor, width, length)
  665.         -- clear first 2 levels, then next 3
  666.         if direction == 0 then
  667.             T:up(1)
  668.             lib.Layer2(direction, false, withFloor, width, length)
  669.             T:up(1)
  670.             lib.Layer3(direction, withCeiling, false, width, length)
  671.         else
  672.             T:down(1)
  673.             lib.Layer2(direction, withCeiling, false, width, length)
  674.             T:down(1)
  675.             lib.Layer3(direction, false, withFloor, width, length)
  676.         end
  677.         return 3
  678.     end
  679.    
  680.     function lib.Layer6(direction, withCeiling, withFloor, width, length)
  681.         -- clear first 3 levels, then next 3
  682.         if direction == 0 then
  683.             lib.Layer3(direction, false, withFloor, width, length)
  684.             T:up(2)
  685.             lib.Layer3(direction, withCeiling, false, width, length)
  686.         else
  687.             lib.Layer3(direction, withCeiling, false, width, length)
  688.             T:down(2)
  689.             lib.Layer3(direction, false, withFloor, width, length)
  690.         end
  691.         return 4
  692.     end
  693.     local travel = 0
  694.     if height == 1 then
  695.         lib.Layer1(direction, withCeiling, withFloor, width, length)
  696.     elseif height == 2 then
  697.         lib.Layer2(direction, withCeiling, withFloor, width, length)
  698.     elseif height == 3 then
  699.         travel = lib.Layer3(direction, withCeiling, withFloor, width, length)
  700.     elseif height == 4 then
  701.         travel = lib.Layer4(direction, withCeiling, withFloor, width, length)
  702.     elseif height == 5 then
  703.         travel = lib.Layer5(direction, withCeiling, withFloor, width, length)
  704.     elseif height == 6 then
  705.         travel = lib.Layer6(direction, withCeiling, withFloor, width, length)
  706.     else -- height 7 or more
  707.         -- each iteration clears 3 layers
  708.         local iterations = math.floor(height / 3)   -- eg height = 7, iterations = 2
  709.         local remaining = height % (iterations * 3) -- eg height = 7, 1 remaining
  710.         for i = 1, iterations do
  711.             travel = travel + lib.Layer3(direction, withCeiling, withFloor, width, length)
  712.             if direction == 0 then -- reset floor / ceiling once completed
  713.                 withFloor = false
  714.                 T:up(2)
  715.             else
  716.                 withCeiling = false
  717.                 T:down(2)
  718.             end
  719.             travel = travel + 2
  720.         end
  721.         if remaining == 1 then
  722.             travel = travel + lib.Layer1(direction, withCeiling, withFloor, width, length)
  723.         elseif remaining == 2 then
  724.             travel = travel + lib.Layer2(direction, withCeiling, withFloor, width, length)
  725.         elseif remaining == 3 then
  726.             travel = travel + lib.Layer3(direction, withCeiling, withFloor, width, length)
  727.         elseif remaining == 4 then
  728.             travel = travel + lib.Layer4(direction, withCeiling, withFloor, width, length)
  729.         elseif remaining == 5 then
  730.             travel = travel + lib.Layer5(direction, withCeiling, withFloor, width, length)
  731.         elseif remaining == 6 then
  732.             travel = travel + lib.Layer6(direction, withCeiling, withFloor, width, length)
  733.         end
  734.     end
  735.     if direction == 0 and travel > 0 then
  736.         T:down(travel)
  737.     else
  738.         T:up(travel)
  739.     end
  740. end
  741.  
  742. function clearMineshaft(equippedRight, equippedLeft, inInventory)
  743.     local lib = {}
  744.     function lib.checkCobweb(direction, inInventory)
  745.         if inInventory == "minecraft:diamond_sword" then -- using a sword
  746.             local side = "left"
  747.             local item = T:getBlockType(direction)
  748.             if item == "minecraft:cobweb" then
  749.                 --clsTurtle.equip(self, side, useItem, useDamage)
  750.                 if equippedRight == "minecraft:diamond_pickaxe" then
  751.                     side = "right"
  752.                 end
  753.                 T:equip(side, "minecraft:diamond_sword")
  754.                 T:dig(direction)
  755.                 T:equip(side, "minecraft:diamond_pickaxe")
  756.             else
  757.                 T:dig(direction)
  758.             end
  759.         else
  760.             T:dig(direction)
  761.         end
  762.     end
  763.  
  764.     -- check position by rotating until facing away from wall
  765.     length = 0
  766.     torch = 0
  767.     turns = 0
  768.     doContinue = true
  769.     while not turtle.detect() do
  770.         T:turnRight(1)
  771.         turns = turns + 1
  772.         if turns > 4 then
  773.             doContinue = false
  774.             print("I am not facing a wall. Unable to continue")
  775.         end
  776.     end
  777.     if doContinue then --facing wall
  778.         T:turnRight(2)
  779.         -- move forward until obstructed, digging up/down. place torches
  780.         while not turtle.detect() do
  781.             lib.checkCobweb("up", inInventory) -- dig cobweb or any other block up
  782.             lib.checkCobweb("down", inInventory) -- dig cobweb or any other block down
  783.             length = length + 1
  784.             torch = torch + 1
  785.             if torch == 8 then
  786.                 torch = 0
  787.                 T:place("minecraft:torch", -1, "down", false) ---(self, blockType, damageNo, direction, leaveExisting, signText)
  788.             end
  789.             lib.checkCobweb("forward", inInventory) -- dig cobweb or any other block in front
  790.             T:forward(1)
  791.         end
  792.         -- turn right, forward, right, return to start with up/down dig
  793.        
  794.         T:go("R1F1R1")
  795.         for i = 1, length, 1 do
  796.             lib.checkCobweb("up", inInventory) -- dig cobweb or any other block up
  797.             lib.checkCobweb("down", inInventory) -- dig cobweb or any other block down
  798.             lib.checkCobweb("forward", inInventory) -- dig cobweb or any other block in front
  799.             T:forward(1)
  800.         end
  801.         -- move to other wall and repeat.
  802.         T:go("R1F2R1")
  803.         for i = 1, length, 1 do
  804.             lib.checkCobweb("up", inInventory) -- dig cobweb or any other block up
  805.             lib.checkCobweb("down", inInventory) -- dig cobweb or any other block down
  806.             lib.checkCobweb("forward", inInventory) -- dig cobweb or any other block in front
  807.             T:forward(1)
  808.         end
  809.         lib.checkCobweb("up", inInventory) -- dig cobweb or any other block up
  810.         lib.checkCobweb("down", inInventory) -- dig cobweb or any other block down
  811.     end
  812. end
  813.  
  814. function clearMonumentLayer(width, length, size)
  815.     local up = true
  816.     local down = true
  817.     if size == 0 then
  818.         up = false
  819.         down = false
  820.     end
  821.     -- send turtle down until it hits bottom
  822.     -- then clear rectangle of given size
  823.     -- start above water, usually on cobble scaffold above monument
  824.     if T:detect("down") then -- in case not over wall
  825.         T:forward(1)
  826.     end
  827.     height = 1
  828.     -- go down until solid block detected
  829.     while clearVegetation("down") do
  830.         T:down(1)
  831.         height = height + 1
  832.     end
  833.     T:down(1)
  834.     height = height + 1
  835.     clearRectangle(width, length, up, down)
  836.     T:up(height - 1)
  837. end
  838.  
  839. function clearSeaweed(width, length)
  840.     -- move over water
  841.     turtle.select(1)
  842.     T:clear()
  843.     print("Checking water length")
  844.     while not clearVegetation("down") do
  845.         T:forward(1)
  846.     end
  847.     local odd = false
  848.     local calcLength = 0
  849.     while clearVegetation("down") do
  850.         T:forward(1)
  851.         calcLength = calcLength + 1
  852.     end
  853.     -- now check on correct side: wall to the right
  854.     print("Checking position")
  855.     T:go("R2F1R1F1") -- over ? wall
  856.     if clearVegetation("down") then -- over water, so return to start on correct side
  857.         T:go("R2F1R1F"..calcLength - 1 .."R2")
  858.     else
  859.         T:go("R2F1R1") -- over water
  860.     end
  861.     if calcLength % 2 == 1 then
  862.         odd = true
  863.     end
  864.     local forward = true
  865.     --print("calcLength:"..calcLength.. " odd:"..tostring(odd))
  866.     for w = 1, width do
  867.         for l = 1, calcLength, 2 do -- 1,3,5,7 etc length 3 runs 1, 5 runs 2 etc
  868.             local depth = 0
  869.             if l == 1 or (l % 2 == 1 and l == calcLength) then
  870.                 if forward then
  871.                     T:turnLeft(1)
  872.                 else
  873.                     T:turnRight(1)
  874.                 end
  875.             else
  876.                 T:turnLeft(2)
  877.             end
  878.             -- go down destroying vegetation until on floor, checking in front at same time
  879.             while clearVegetation("down") do
  880.                 clearVegetation("forward")
  881.                 T:down()
  882.                 depth = depth + 1
  883.             end
  884.             -- if slab at bottom, cover with solid block
  885.             if string.find(T:getBlockType("down"), "slab") then
  886.                 T:up(1)
  887.                 T:place("minecraft:sand", "down")
  888.                 depth = depth + 1
  889.             end
  890.             if l == 1 or (l % 2 == 1 and l == calcLength) then
  891.                 if forward then
  892.                     T:turnRight(1)
  893.                 else
  894.                     T:turnLeft(1)
  895.                 end
  896.             else
  897.                 T:turnLeft(2)
  898.             end
  899.             for d = depth, 1, -1 do
  900.                 clearVegetation("forward")
  901.                 T:up(1)
  902.             end
  903.             -- first corner complete, back at surface above water
  904.             if l < calcLength then
  905.                 T:forward(2)
  906.             end
  907.         end
  908.         if forward then
  909.             T:go("L1F1L1")
  910.         else
  911.             T:go("R1F1R1")
  912.         end
  913.         forward = not forward
  914.         if not clearVegetation("down") then -- reached  far wall
  915.             break
  916.         end
  917.     end
  918. end
  919.  
  920. function clearMountainSide(width, length, size)
  921.     local lib = {}
  922.     function lib.excavate(blocksFromOrigin, going, length, digDown)
  923.         local firstUp = 0
  924.         for i = 1, length do
  925.             -- record first block dug above
  926.             if turtle.digUp() then
  927.                 if firstUp == 0 then
  928.                     firstUp = i -- will record first successful dig up
  929.                 end
  930.             end
  931.             if digDown then
  932.                 turtle.digDown()
  933.             end
  934.             T:forward(1)
  935.             if going then
  936.                 blocksFromOrigin = blocksFromOrigin + 1
  937.             else
  938.                 blocksFromOrigin = blocksFromOrigin - 1
  939.             end
  940.         end
  941.        
  942.         return blocksFromOrigin, firstUp
  943.     end
  944.    
  945.     function lib.cutSection(blocksFromOrigin, going, length, firstUp)
  946.         local height = 0
  947.         local digDown = false
  948.         blocksFromOrigin, firstUp = lib.excavate(blocksFromOrigin, going, length, digDown)
  949.         -- while at least 1 block dug above do
  950.         while firstUp > 0 do
  951.             if digDown then
  952.                 turtle.digDown()
  953.             else
  954.                 digDown = true
  955.             end
  956.             T:go("R2U1x1U1x1U1x1x0") -- go up 3 turn round
  957.             going = not going
  958.             height = height + 3
  959.             if firstUp > 1 then
  960.                 length = length - firstUp + 1
  961.             end
  962.             -- go forward length digging up/down
  963.             blocksFromOrigin, firstUp = lib.excavate(blocksFromOrigin, going, length,  true)
  964.         end
  965.         T:down(height)
  966.        
  967.         return blocksFromOrigin, going
  968.     end
  969.    
  970.     local originalLength = length
  971.     local going = true
  972.     local firstUp = 0
  973.     local blocksFromOrigin = 0
  974.     --T:forward(1) -- get into position
  975.     blocksFromOrigin, going = lib.cutSection(blocksFromOrigin, going, length, firstUp)
  976.     if width > 1 then --move left/right and repeat
  977.         for i = 2, width do
  978.             if going then
  979.                 T:turnRight(2)         
  980.             end
  981.             if blocksFromOrigin > 0 then
  982.                 T:forward(blocksFromOrigin)
  983.             end
  984.             T:turnRight(2)
  985.             blocksFromOrigin = 0
  986.             if size == 0 then --Left <- Right
  987.                 T:go("L1F1R1")
  988.             else
  989.                 T:go("R1F1L1")
  990.             end
  991.             going = true
  992.             blocksFromOrigin, going = lib.cutSection(blocksFromOrigin, going, length, firstUp)
  993.         end
  994.     end
  995. end
  996.  
  997. function clearSandWall(length)
  998.     --dig down while on top of sand/soul_sand
  999.     local height = 0
  1000.     turtle.select(1)
  1001.     T:clear()
  1002.     print("Checking sand length")
  1003.     local search = 0
  1004.     local blockType = T:getBlockType("down")
  1005.     while blockType ~= "minecraft:sand" and blockType ~= "minecraft:soul_sand" do --move forward until sand detected or 3 moves
  1006.         T:forward(1)
  1007.         search = search + 1
  1008.         blockType = T:getBlockType("down")
  1009.         if search > 3 then
  1010.             break
  1011.         end
  1012.     end
  1013.     if search <= 3 then
  1014.         local calcLength = 0
  1015.         blockType = T:getBlockType("down")
  1016.         while blockType == "minecraft:sand" or blockType == "minecraft:soul_sand" do
  1017.             T:forward(1)
  1018.             calcLength = calcLength + 1
  1019.             blockType = T:getBlockType("down")
  1020.         end
  1021.         T:go("R2F1") -- over sand
  1022.         blockType = T:getBlockType("down")
  1023.         while blockType == "minecraft:sand" or blockType == "minecraft:soul_sand" do
  1024.             T:down(1)
  1025.             height = height + 1
  1026.             blockType = T:getBlockType("down")
  1027.         end
  1028.         -- repeat length times
  1029.         for i = 1, calcLength do
  1030.             --if sand in front, dig
  1031.             while turtle.detect() do
  1032.                 blockType = T:getBlockType("forward")
  1033.                 if blockType == "minecraft:sand" or blockType == "minecraft:soul_sand" then
  1034.                     T:dig("forward")
  1035.                 else --solid block, not sand so move up
  1036.                     T:up(1)
  1037.                     height = height - 1
  1038.                 end
  1039.             end
  1040.             --move forward
  1041.             if i < calcLength then
  1042.                 T:forward(1)
  1043.                 blockType = T:getBlockType("down")
  1044.                 while blockType == "minecraft:sand" or blockType == "minecraft:soul_sand" do
  1045.                     T:down(1)
  1046.                     height = height + 1
  1047.                     blockType = T:getBlockType("down")
  1048.                 end
  1049.             end
  1050.         end
  1051.         -- go up, but reverse if block above
  1052.         for i = 1, height do
  1053.             if not turtle.detectUp() then
  1054.                 T:up(1)
  1055.             else
  1056.                 T:back(1)
  1057.             end
  1058.         end
  1059.         T:go("R2")
  1060.     end
  1061. end
  1062.  
  1063. function clearSandCube(width, length)
  1064.     --go down to bottom of sand
  1065.     turtle.select(1)
  1066.     while T:getBlockType("down") == "minecraft:sand" do
  1067.         T:down(1)
  1068.     end
  1069.     clearBuilding(width, length, 0, false)
  1070. end
  1071.  
  1072. local function clearSolid(width, length, height, direction)
  1073.     -- direction = Bottom->Top (0), Top->bottom(1)
  1074.     local lib ={}
  1075.    
  1076.     function lib.level(width, length)
  1077.         clearRectangle(width, length, false, false)
  1078.     end
  1079.    
  1080.     function lib.levelUp(width, length)
  1081.         clearRectangle(width, length, true, false)
  1082.     end
  1083.    
  1084.     function lib.levelUpDown(width, length)
  1085.         clearRectangle(width, length, true, true)
  1086.     end
  1087.    
  1088.     function lib.levelDown(width, length)
  1089.         clearRectangle(width, length, false, true)
  1090.     end
  1091.    
  1092.     function lib.level1()
  1093.         lib.level(width, length)
  1094.         return 0
  1095.     end
  1096.    
  1097.     function lib.level2()
  1098.         if direction == 0 then
  1099.             lib.levelUp(width, length)
  1100.         else
  1101.             lib.levelDown(width, length)
  1102.         end
  1103.         return 0
  1104.     end
  1105.    
  1106.     function lib.level3()
  1107.         if direction == 0 then
  1108.             T:up(1)
  1109.         else
  1110.             T:down(1)
  1111.         end
  1112.         lib.levelUpDown(width, length)lib.levelUpDown(width, length)
  1113.         return 1
  1114.     end
  1115.    
  1116.     function lib.level4()
  1117.         if direction == 0 then
  1118.             T:up(1)
  1119.             lib.levelUpDown(width, length)
  1120.             T:up(2)
  1121.         else
  1122.             T:down(1)
  1123.             lib.levelUpDown(width, length)
  1124.             T:down(2)
  1125.         end
  1126.         lib.level(width, length)
  1127.         return 3
  1128.     end
  1129.    
  1130.     function lib.level5()
  1131.         if direction == 0 then
  1132.             T:up(1)
  1133.             lib.levelUpDown(width, length)
  1134.             T:up(2)
  1135.             lib.levelUp(width, length)
  1136.         else
  1137.             T:down(1)
  1138.             lib.levelUpDown(width, length)
  1139.             T:down(2)
  1140.             lib.levelDown(width, length)
  1141.         end
  1142.         return 4
  1143.     end
  1144.    
  1145.     function lib.level6()
  1146.         if direction == 0 then
  1147.             T:up(1)
  1148.             lib.levelUpDown(width, length)
  1149.             T:up(3)
  1150.             lib.levelUpDown(width, length)
  1151.         else
  1152.             T:down(1)
  1153.             lib.levelUpDown(width, length)
  1154.             T:down(3)
  1155.             lib.levelUpDown(width, length)
  1156.         end
  1157.         return 5
  1158.     end
  1159.    
  1160.     if direction == nil then
  1161.         direction = 0
  1162.     end
  1163.     if height <= 0 then --move up until no more solid
  1164.         -- starts on level 1
  1165.         if direction == 0 then
  1166.             T:up(1)
  1167.         else
  1168.             T:down(1)
  1169.         end
  1170.         local level = 2
  1171.         local itemsOnBoard = T:getTotalItemCount()
  1172.         repeat
  1173.             lib.levelUpDown()
  1174.             T:sortInventory()
  1175.             if direction == 0 then
  1176.                 T:up(3)
  1177.             else
  1178.                 T:down(3)
  1179.             end
  1180.             height = height + 3
  1181.         until T:getFirstEmptySlot() == 0  or T:getTotalItemCount() == itemsOnBoard-- nothing collected or full inventory
  1182.     elseif height == 1 then --one layer only
  1183.         height = lib.level1(width, length)
  1184.     elseif height == 2 then --2 layers only
  1185.         height = lib.level2()
  1186.     elseif height == 3 then --3 layer only
  1187.         height = lib.level3()
  1188.     elseif height == 4 then --4 layer only
  1189.         height = lib.level4()
  1190.     elseif height == 5 then --5 layer only
  1191.         height = lib.level5()
  1192.     elseif height == 6 then --6 layer only
  1193.         height = lib.level6()
  1194.     else -- 7 or more levels
  1195.         local remaining = height - 7
  1196.         if direction == 0 then
  1197.             T:up(1)
  1198.         else
  1199.             T:down(1)
  1200.         end
  1201.         for i = 1, height - 7 do
  1202.             if direction == 0 then
  1203.                 T:up(3)
  1204.             else
  1205.                 T:down(3)
  1206.             end
  1207.             lib.levelUpDown(width, length)
  1208.         end
  1209.         height = height - 7
  1210.         if remaining == 1 then
  1211.             height = height + lib.level1(width, length)
  1212.         elseif remaining == 2 then
  1213.             height = height + lib.level2(width, length)
  1214.         elseif remaining == 3 then
  1215.             height = height + lib.level3(width, length)
  1216.         elseif remaining == 4 then
  1217.             height = height + lib.level4(width, length)
  1218.         elseif remaining == 5 then
  1219.             height = height + lib.level5(width, length)
  1220.         elseif remaining == 6 then
  1221.             height = height + lib.level6(width, length)
  1222.         end
  1223.     end
  1224.     if direction == 0 then
  1225.         T:down(height)
  1226.     else
  1227.         T:up(height)
  1228.     end
  1229. end
  1230.  
  1231. function clearWall(width, length, height, direction)
  1232.     -- direction = Bottom->Top (0), Top->bottom(1)
  1233.     -- width preset to 1
  1234.     if direction == nil then direction = 0 end-- bottom to top
  1235.     local atStart = true
  1236.     local offset = height - 2
  1237.     -- go(path, useTorch, torchInterval, leaveExisting)
  1238.     local evenHeight = false
  1239.     if height % 2 == 0 then
  1240.         evenHeight = true
  1241.     end
  1242.     turtle.select(1)
  1243.     -- dig along and up/down for specified length
  1244.     if evenHeight then --2, 4 , 6 etc
  1245.         for h = 2, height, 2 do
  1246.             for i = 1, length - 1 do
  1247.                 T:go("x0F1", false, 0, false)
  1248.             end
  1249.             if h < height then
  1250.                 if direction == 0 then --bottom to top
  1251.                     T:go("R2U2", false, 0, false)
  1252.                 else
  1253.                     T:go("R2D2", false, 0, false)
  1254.                 end
  1255.             end
  1256.             atStart = not atStart
  1257.         end
  1258.     else
  1259.         offset = height - 1
  1260.         for h = 1, height, 2 do
  1261.             if h == height then
  1262.                 T:go("F"..tostring(length - 1), false, 0, false)
  1263.             else
  1264.                 for i = 1, length - 1 do
  1265.                     if direction == 0 then --bottom to top
  1266.                         T:go("x0F1", false, 0, false)
  1267.                     else
  1268.                         T:go("x2F1", false, 0, false)
  1269.                     end
  1270.                 end
  1271.             end
  1272.             atStart = not atStart
  1273.             if h < height then
  1274.                 if direction == 0 then --bottom to top
  1275.                     T:go("R2U2", false, 0, false)
  1276.                 else
  1277.                     T:go("R2D2", false, 0, false)
  1278.                 end
  1279.             end
  1280.         end
  1281.     end
  1282.     if evenHeight then
  1283.         if direction == 0 then
  1284.             T:go("x0", false, 0, false)
  1285.         else
  1286.             T:go("x2", false, 0, false)
  1287.         end
  1288.     end
  1289.     if direction == 0 then
  1290.         T:go("R2D"..offset, false, 0, false)
  1291.     else
  1292.         T:go("R2U"..offset, false, 0, false)
  1293.     end
  1294.     if not atStart then
  1295.         T:go("F"..tostring(length - 1).."R2", false, 0, false)
  1296.     end
  1297. end
  1298.  
  1299. function clearVegetation(direction)
  1300.     local isAirWaterLava = true
  1301.     -- blockType, blockModifier, data
  1302.     local blockType, blockModifier = T:getBlockType(direction)
  1303.     if blockType ~= "" then --not air
  1304.         if T:isVegetation(blockType) then
  1305.             T:dig(direction)
  1306.         elseif blockType:find("water") == nil
  1307.                and blockType:find("lava") == nil
  1308.                and blockType:find("bubble") == nil
  1309.                and blockType ~= "minecraft:ice" then
  1310.             -- NOT water, ice or lava
  1311.             isAirWaterLava = false -- solid block
  1312.         end
  1313.     end
  1314.    
  1315.     return isAirWaterLava --clears any grass or sea plants, returns true if air or water, bubble column or ice
  1316. end
  1317.  
  1318. function createAutoTreeFarm()
  1319.     lib = {}
  1320.    
  1321.     function lib.fillWaterBuckets()
  1322.         T:place("minecraft:bucket", -1, "down", false)
  1323.         sleep(0.5)
  1324.         T:place("minecraft:bucket", -1, "down", false)
  1325.     end
  1326.    
  1327.     createWaterSource(1)
  1328.     -- clsTurtle.go(path, useTorch, torchInterval, leaveExisting)
  1329.     -- place chest and hopper  
  1330.     T:go("x0F1x0F1x0F1x0F1R1")
  1331.     for i = 1, 4 do
  1332.         T:go("D1R1C1R1C1R1C1R1")
  1333.     end
  1334.     T:up(1)
  1335.     T:place("minecraft:chest", -1, "down", false)
  1336.     T:go("F1x0D1F1x0R2", false, 0, true)
  1337.     T:place("minecraft:hopper", -1, "forward", false)
  1338.     -- dig trench and ensure base is solid
  1339.     T:go("U1R2X7U1", false, 0, true)
  1340.     T:place("minecraft:water_bucket", -1, "down", false) -- collection stream
  1341.     T:go("F1X7U1", false, 0, true)
  1342.     T:place("minecraft:water_bucket", -1, "down", false) -- upper collection stream
  1343.     T:go("U1F1R1C2F1R1C2") --now on corner
  1344.     for i = 1, 14 do --place cobble
  1345.         T:go("F1C2", false, 0, false)
  1346.     end
  1347.     T:go("F4R1F2C2R2C1R2")
  1348.     for i = 1, 8 do --place cobble
  1349.         T:go("F1C2", false, 0, false)
  1350.     end
  1351.     T:turnRight(1)
  1352.     for i = 1, 18 do --place cobble
  1353.         T:go("F1C2", false, 0, false)
  1354.     end
  1355.     T:turnRight(1)
  1356.     for i = 1, 8 do --place cobble
  1357.         T:go("F1C2", false, 0, false)
  1358.     end
  1359.     T:go("R1F1R1D1") -- ready to clear ground inside cobble wall
  1360.     for i = 1, 17 do
  1361.         T:go("C2F1C2F1C2F1C2F1C2F1C2F1C2F1C2", false, 0, true)
  1362.         if i < 17 then
  1363.             if i % 2 == 1 then -- odd no
  1364.                 T:go("L1F1L1")
  1365.             else
  1366.                 T:go("R1F1R1")
  1367.             end
  1368.         end
  1369.     end
  1370.     T:go("U1R2F10R2") -- over pond
  1371.     lib.fillWaterBuckets()
  1372.     for i = 0, 16, 2 do
  1373.         T:go("F10R1")
  1374.         if i > 0 then
  1375.             T:go("F"..i)
  1376.         end
  1377.         T:place("minecraft:water_bucket", -1, "down", false)
  1378.         T:go("F1R2")
  1379.         if i < 16 then
  1380.             T:place("minecraft:water_bucket", -1, "down", false)
  1381.         end
  1382.         T:go("F"..i + 1 .."L1")
  1383.         T:go("F10R2")
  1384.         lib.fillWaterBuckets()
  1385.     end
  1386.     -- place dirt/torch/sapling
  1387.     T:go("F1U1R1F1L1")
  1388.     for i = 1, 7 do
  1389.         T:go("F6R1F1L1")
  1390.         for j = 1, 3 do
  1391.             T:place("minecraft:dirt", -1, "forward", false)
  1392.             T:up(1)
  1393.             T:place("sapling", -1, "forward", false)
  1394.             T:down(1)
  1395.             turtle.back()
  1396.             T:place("minecraft:torch", -1, "forward", false)
  1397.             turtle.back()
  1398.         end
  1399.         if i < 7 then
  1400.             T:go("R1F1L1")
  1401.         end
  1402.     end
  1403.     T:go("L1F12")
  1404.     T:place("minecraft:chest", -1, "up", false)
  1405.     T:go("R1F1L1")
  1406.     T:place("minecraft:chest", -1, "up", false)
  1407.     T:go("F1U1R1F1R1F1L1")
  1408.     T:clear()
  1409.     print("Auto TreeFarm completed")
  1410.     print("\nDO NOT PLACE ANY TORCHES OR OTHER")
  1411.     print("BLOCKS ON THE COBBLE PERIMETER!")
  1412.     print("\nUse option 5 Manage Auto Tree farm")
  1413.     print("to setup monitoring\n\nEnter to continue")
  1414.     read()
  1415. end
  1416.  
  1417. local function createBoatLift(state, side, height) -- state:0=new, size:1=extend, side:0=left, 1=right
  1418.     --[[ Legacy version (turtle deletes water source)
  1419.     Place turtles on canal floor, with sources ahead
  1420.     facing back wall preferred, but not essential
  1421.     1.14 + (turtle can be waterlogged)
  1422.     Place same as legacy but inside source blocks
  1423.     ]]
  1424.     local lib ={}
  1425.    
  1426.     function lib.checkSource()
  1427.         local isWater = false
  1428.         local isSource = false
  1429.         T:dig("forward")                        -- break frozen source block
  1430.         isWater, isSource = T:isWater("forward")
  1431.         return isSource
  1432.     end
  1433.    
  1434.     function lib.findPartner()
  1435.         local block = T:getBlockType("forward")
  1436.         while block:find("turtle") == nil do -- not found partner
  1437.              if side == 0 then
  1438.                 turtle.turnRight()
  1439.              else
  1440.                 turtle.turnLeft()
  1441.              end
  1442.              sleep(0.5)
  1443.              block = T:getBlockType("forward")
  1444.         end
  1445.     end
  1446.    
  1447.     function lib.returnToWork(level)
  1448.         if level > 0 then
  1449.             for i = 1, level do
  1450.                 T:place("minecraft:water_bucket", -1, "down")
  1451.                 sleep(0.5)
  1452.                 local _, isSource = T:isWater("down")
  1453.                 while not isSource do
  1454.                     print("Waiting for source...")
  1455.                     sleep(0.5)
  1456.                     _, isSource = T:isWater("down")
  1457.                 end
  1458.                 T:place("minecraft:bucket", -1, "down")
  1459.                 T:up(1)
  1460.             end
  1461.         end
  1462.     end
  1463.    
  1464.     function lib.getToWater()
  1465.         local level = 0
  1466.         local isWater, isSource, isIce = T:isWater("down")
  1467.         while not isSource and isWater do -- water but not source
  1468.             T:down(1)
  1469.             level = level + 1
  1470.             isWater, isSource, isIce = T:isWater("down")
  1471.         end
  1472.         if isIce then T:dig("down") end                                 -- break frozen source block
  1473.         if not isWater then
  1474.             isWater, isSource, isIce = T:isWater("up")
  1475.             if isSource then
  1476.                 T:place("minecraft:bucket", -1, "up")
  1477.             end
  1478.         else
  1479.             T:place("minecraft:bucket", -1, "down")
  1480.         end
  1481.         lib.returnToWork(level)
  1482.     end
  1483.    
  1484.     function lib.refill()
  1485.         local s1, s2, buckets = T:getItemSlot("minecraft:bucket", -1)   -- slotData.lastSlot, slotData.leastModifier, total, slotData
  1486.         local level = 0
  1487.         if buckets > 0 then                                             -- at least 1 empty bucket
  1488.             local isWater, isSource, isIce = T:isWater("down")
  1489.             if isIce then T:dig("down") end                             -- break frozen source block
  1490.             if T:place("minecraft:bucket", -1, "down") then             -- get water from below.
  1491.                 sleep(0.5)
  1492.             else
  1493.                 lib.getToWater()
  1494.             end
  1495.         end
  1496.         s1, s2, buckets = T:getItemSlot("minecraft:bucket", -1)
  1497.         if buckets > 0 then -- at least 1 empty bucket
  1498.             if isIce then T:dig("down") end                             -- break frozen source block
  1499.             if not T:place("minecraft:bucket", -1, "down") then         -- get water from below
  1500.                 lib.getToWater()
  1501.             end
  1502.         end
  1503.     end
  1504.    
  1505.     function lib.reset()
  1506.         redstone.setAnalogueOutput("front", 0)
  1507.         redstone.setOutput("front", false)
  1508.     end
  1509.    
  1510.     function lib.sendSignal()
  1511.         -- wait until turtle detected in front
  1512.         -- if detected set signal to 15 and pause 0.5 secs
  1513.         -- if recieves 15 from other turtle, continue
  1514.         -- if recieves 7 from other turtle, job done
  1515.         local block = T:getBlockType("forward")
  1516.         if block:find("turtle") == nil then -- not found partner
  1517.             print("Waiting for partner turtle...")
  1518.             print("If not facing towards partner")
  1519.             print("please restart this program")
  1520.             sleep(1)
  1521.         else
  1522.             redstone.setAnalogueOutput("front", 0)
  1523.             redstone.setOutput("front", false)
  1524.             if redstone.getAnalogueInput("front") == 15 then
  1525.                 redstone.setOutput("front", true)
  1526.                 print("Binary sent to partner turtle...")
  1527.                 sleep(0.5)
  1528.                 return true
  1529.             else
  1530.                 print("Signal 15 sent to partner turtle...")
  1531.                 redstone.setAnalogueOutput("front", 15)
  1532.                 sleep(0.5)
  1533.             end
  1534.             redstone.setAnalogueOutput("front", 0)
  1535.             if redstone.getInput("front")  or redstone.getAnalogueInput("front") == 15 then
  1536.                  return true
  1537.             end
  1538.             return false
  1539.         end
  1540.         return false
  1541.     end
  1542.    
  1543.     function lib.legacyLeft(layer)
  1544.         lib.refill()
  1545.         T:go("U1") 
  1546.         T:place("minecraft:water_bucket", -1, "down")   -- place below. facing partner
  1547.         T:go("L1F1")                                    -- move to back, facing back
  1548.         T:place("minecraft:water_bucket", -1, "down")   -- place water below
  1549.         T:go("C1")                                      -- facing back, build back wall
  1550.         T:go("L1C1")                                    -- facing side, build side
  1551.         T:go("L1F1R1C1")                                -- move towards front, build side wall
  1552.         if layer == 1 then                              -- do not replace slab on layer 1
  1553.             T:go("L2")
  1554.         else
  1555.             T:go("L1C1L1")                              -- build front wall, turn to face partner
  1556.         end
  1557.     end
  1558.    
  1559.     function lib.left(layer)
  1560.         lib.refill()
  1561.         T:go("D1") 
  1562.         T:place("minecraft:water_bucket", -1, "up") -- place above. facing partner
  1563.         T:go("L1F1")                                -- move to back, facing back
  1564.         T:place("minecraft:water_bucket", -1, "up") -- place water above
  1565.         lib.refill()
  1566.         T:go("U2C1")                                -- up 2;facing back, build back wall
  1567.         T:go("L1C1")                                -- facing side, build side
  1568.         T:go("L1F1R1C1")                            -- move towards front, build side wall
  1569.         if layer == 1 then                          -- do not replace slab on layer 1
  1570.             T:go("L2")
  1571.         else
  1572.             T:go("L1C1L1")                          -- build front wall, turn to face partner
  1573.         end
  1574.         local _, isSource, isIce = T:isWater("down")
  1575.         if isIce then T:dig("down") end             -- break frozen source block
  1576.         if not isSource then
  1577.             lib.getToWater()
  1578.         end
  1579.     end
  1580.    
  1581.     function lib.right(layer)
  1582.         lib.refill()
  1583.         T:go("D1") 
  1584.         T:place("minecraft:water_bucket", -1, "up") -- place above. facing partner
  1585.         T:go("R1F1")                                -- move to back, facing back
  1586.         T:place("minecraft:water_bucket", -1, "up") -- place water above
  1587.         lib.refill()
  1588.         T:go("U2C1")                                -- up 2;facing back, build back wall
  1589.         T:go("R1C1")                                -- facing side, build side
  1590.         T:go("R1F1L1C1")                            -- move towards front, build side wall
  1591.         if layer == 1 then                          -- do not replace slab on layer 1
  1592.             T:go("R2")
  1593.         else
  1594.             T:go("R1C1R1")                          -- build front wall, turn to face partner
  1595.         end
  1596.         local _, isSource, isIce = T:isWater("down")
  1597.         if isIce then T:dig("down") end             -- break frozen source block
  1598.         if not isSource then
  1599.             lib.getToWater()
  1600.         end
  1601.     end
  1602.    
  1603.     function lib.legacyRight(layer)
  1604.         lib.refill()
  1605.         T:go("U1") 
  1606.         T:place("minecraft:water_bucket", -1, "down")   -- place below. facing partner
  1607.         T:go("R1F1")                                    -- move to back, facing back
  1608.         T:place("minecraft:water_bucket", -1, "down")   -- place water below
  1609.         T:go("C1")                                      -- facing back, build back wall
  1610.         T:go("R1C1")                                    -- facing side, build side
  1611.         T:go("R1F1L1C1")                                -- move towards front, build side wall
  1612.         if layer == 1 then                              -- do not replace slab on layer 1
  1613.             T:go("R2")
  1614.         else
  1615.             T:go("R1C1R1")                              -- build front wall, turn to face partner
  1616.         end                                             -- up 1;turn to face partner
  1617.     end
  1618.    
  1619.     function lib.top(height)
  1620.         if side == 0 then --left side
  1621.             T:go("x0L1F1x0L2 F2R1C1C0 D1C1") -- place side block; block above, move down; side block
  1622.             T:place("sign", -1, "up", true, "Lift Exit\n<--\n<--\nEnjoy the ride...")
  1623.             T:go("L1F1L2C1 U2x1x0 L2F1x0L2")
  1624.         else
  1625.             T:go("x0R1F1x0R2 F2L1C1C0 D1C1") -- place side block, move up
  1626.             T:place("sign", -1, "up", true, "Lift Exit\n-->\n-->\nEnjoy the ride...")
  1627.             T:go("R1F1R2C1 U2x1x0 R2F1x0R2")
  1628.         end
  1629.         for i = height, 1, -1 do
  1630.             T:go("x1D1")
  1631.         end
  1632.     end
  1633.    
  1634.     local A = "R"
  1635.     local B = "L"
  1636.     if side == 1 then -- right side turtle
  1637.         A = "L"
  1638.         B = "R"
  1639.     end
  1640.     lib.findPartner()
  1641.     T:go(B.."1")
  1642.     if not lib.checkSource() then
  1643.         print("No water source ahead.\nReposition or add source")
  1644.         error()
  1645.     end
  1646.     T:go(A.."1")
  1647.     lib.reset()
  1648.     while not lib.sendSignal() do end
  1649.     lib.reset()
  1650.     -- confirmed opposite and active
  1651.     if state == 0 then -- new lift
  1652.         if side == 0 then
  1653.             T:turnLeft(1)                       -- face back
  1654.         else
  1655.             T:turnRight(1)                      -- face back
  1656.         end
  1657.         T:go(B.."2F1U1"..A.."1C1")              -- face front;forward 1;up 1; :face side ready for sign and slab placement
  1658.         T:place("slab", -1, "up")               -- slab above
  1659.         T:go("D1")                              -- down 1
  1660.         T:place("sign", -1, "up", true, "Lift Entrance\nKeep pressing\nforward key!")
  1661.         T:go(A.."1F1"..A.."2")                  -- face back; forward 1; :face front
  1662.         T:place("slab", -1, "forward")          -- slab on ground at entrance
  1663.         T:go(A.."1")                            -- face side
  1664.         T:place("minecraft:soul_sand", -1, "down", false) -- replace block below with soul sand
  1665.         T:go("C1"..A.."1F1C1"..B.."1C1")        -- block to side; forward, block at back; block to side :face side
  1666.         T:place("minecraft:soul_sand", -1, "down", false) -- replace block below with soul sand
  1667.         T:go("U1C1"..A.."1C1"..A.."2F1"..A.."1C1"..A.."2") -- up 1; block to side; forward; block to side :face other turtle
  1668.         local isWater, isSource, isIce = T:isWater("down")
  1669.         if not isSource then -- no source below
  1670.             T:place("minecraft:water_bucket", -1, "down")   -- refill source
  1671.             T:go(B.."1F1"..B.."2")
  1672.             T:place("minecraft:water_bucket", -1, "down")   -- refill source
  1673.             T:go("F1"..B.."1")
  1674.             sleep(0.5)
  1675.             isWater, isSource = T:isWater("down")
  1676.             if isSource then
  1677.                 if isIce then
  1678.                     T:dig("down")                               -- break frozen source block
  1679.                 end
  1680.                 T:place("minecraft:bucket", -1, "down")         -- refill bucket
  1681.                 sleep(0.5)
  1682.                 T:place("minecraft:bucket", -1, "down")         -- refill bucket
  1683.             end
  1684.         end
  1685.         lib.reset()
  1686.         while not lib.sendSignal() do end
  1687.         lib.reset()
  1688.         -- on layer 1  1 x source blocks below
  1689.         for layer = 1, height do
  1690.             if side == 0 then --left side
  1691.                 if deletesWater then
  1692.                     lib.legacyLeft(layer)
  1693.                 else
  1694.                     lib.left(layer)
  1695.                 end
  1696.             else
  1697.                 if deletesWater then
  1698.                     lib.legacyRight(layer)
  1699.                 else
  1700.                     lib.right(layer)
  1701.                 end
  1702.             end
  1703.             lib.reset()
  1704.             while not lib.sendSignal() do end
  1705.             lib.reset()
  1706.         end
  1707.         lib.top(height)
  1708.     else -- extend lift
  1709.         -- turtles should be at front, facing back of lift
  1710.         -- signs behind them, water sources below
  1711.         -- will face each other on startup, exactly as if finished new lift
  1712.         for layer = 1, height do
  1713.             for layer = 1, height do
  1714.                 if side == 0 then --left side
  1715.                     if deletesWater then
  1716.                         lib.legacyLeft(layer)
  1717.                     else
  1718.                         lib.left(layer)
  1719.                     end
  1720.                 else
  1721.                     if deletesWater then
  1722.                         lib.legacyRight(layer)
  1723.                     else
  1724.                         lib.right(layer)
  1725.                     end
  1726.                 end
  1727.                 lib.reset()
  1728.                 while not lib.sendSignal() do end
  1729.                 lib.reset()
  1730.             end
  1731.         end
  1732.         lib.top(height + 1) -- drop to below existing lift
  1733.         while turtle.down() do end -- drop to base canal
  1734.     end
  1735. end
  1736.  
  1737. function createBridge(numBlocks)
  1738.     for i = 1, numBlocks do
  1739.         T:go("m1", false, 0, true)
  1740.     end
  1741.     T:go("R1F1R1", false, 0, true)
  1742.     for i = 1, numBlocks do
  1743.         T:go("m1", false, 0, true)
  1744.     end
  1745. end
  1746.  
  1747. local function createBubbleLift(height)
  1748.     local lib = {}
  1749.    
  1750.     function lib.addLayer()
  1751.         T:go("F2 L1C1R1C1R1C1L1", false, 0, true)
  1752.         turtle.back()
  1753.         T:place("minecraft:water_bucket", -1, "forward")
  1754.         T:dig("up") -- clear block above so completed lift can be found
  1755.         turtle.back()
  1756.         T:dig("up") -- clear block above so completed lift can be found
  1757.         T:place("stone", -1, "forward")
  1758.     end
  1759.    
  1760.     function lib.addSign()
  1761.         turtle.back()
  1762.         T:place("minecraft:water_bucket", -1, "forward")
  1763.         T:go("L1B1")
  1764.         T:place("sign", -1, "forward")
  1765.     end
  1766.    
  1767.     function lib.buildLift(toHeight)
  1768.         local built = lib.goToWater()       -- returns lift blocks already placed, total height of drop from starting point
  1769.         local toBuild = toHeight - built    -- no of blocks remaining to increase lift size
  1770.         local water = 0
  1771.         while toBuild > 0 do                -- at least 1 block height remaining
  1772.             water = lib.fillBuckets(toBuild, false) -- no of water buckets onboard (could be more than required)
  1773.             if water > toBuild then         -- more water than required
  1774.                 water = toBuild             -- reduce to correct amount
  1775.             end
  1776.             while turtle.detect() do        -- climb to top of existing lift
  1777.                 turtle.up()
  1778.             end
  1779.             while water > 0 do
  1780.                 lib.addLayer()
  1781.                 water = water - 1
  1782.                 T:up(1)
  1783.                 toBuild = toBuild - 1
  1784.             end
  1785.             -- may still be some height to complete, but needs refill
  1786.             if toBuild > 0 then
  1787.                 built = lib.goToWater() --return to source
  1788.                 toBuild = toHeight - built
  1789.                 --lib.fillBuckets(toBuild)
  1790.             end
  1791.         end
  1792.     end
  1793.    
  1794.     function lib.cleanUp(fromHeight)
  1795.         local plug = false
  1796.         T:turnRight(2)
  1797.         for i = 1, fromHeight do
  1798.             plug = false
  1799.             if turtle.detect() then
  1800.                 plug = true
  1801.             end
  1802.             turtle.down()
  1803.             if plug then
  1804.                 T:place("stone", -1, "up")
  1805.             end
  1806.         end
  1807.     end
  1808.    
  1809.     function lib.fillBuckets(toBuild, withSort)
  1810.         local emptySlots, water = lib.stackBuckets(withSort)-- gets no of empty slots + no of water buckets
  1811.         if water < toBuild then                     -- no of water buckets onboard less than required quantity
  1812.             for i = 1, toBuild do                   -- fill required no of buckets up to max space in inventory
  1813.                 if emptySlots == 0 then             -- inventory full
  1814.                     break
  1815.                 else
  1816.                     if T:place("minecraft:bucket", -1, "down", false) then
  1817.                         water = water + 1
  1818.                         sleep(0.5)
  1819.                     end
  1820.                 end
  1821.                 emptySlots = lib.getEmptySlots()
  1822.             end
  1823.         end
  1824.        
  1825.         return water
  1826.     end
  1827.    
  1828.     function lib.getEmptySlots()
  1829.         local empty = 0
  1830.         for i = 1, 16 do
  1831.             if turtle.getItemCount(i) == 0 then
  1832.                 empty = empty + 1
  1833.             end
  1834.         end
  1835.         return empty
  1836.     end
  1837.    
  1838.     function lib.goToWater()
  1839.         local built = 0 -- measures completed lift height
  1840.         while turtle.down() do -- takes turtle to bottom of water source
  1841.             --height = height + 1
  1842.             if turtle.detect() then
  1843.                 built = built + 1
  1844.             end
  1845.         end
  1846.         T:up(1) -- above watersource assuming it is 1-1.5 blocks deep
  1847.         -- height = height - 1
  1848.         -- built = built - 1 not required as next block is water source: not detected
  1849.         return built -- , height
  1850.     end
  1851.    
  1852.     function lib.stackBuckets(withSort)
  1853.         if withSort == nil then withSort = false end
  1854.         local data = {}
  1855.         local bucketSlot = 0
  1856.         local emptySlots = 0
  1857.         local water = 0
  1858.         if withSort then
  1859.             T:sortInventory()
  1860.         end
  1861.         for i = 1, 16 do
  1862.             -- find first empty bucket
  1863.             if turtle.getItemCount(i) > 0 then
  1864.                 data = turtle.getItemDetail(i)
  1865.                 if data.name == "minecraft:bucket" then
  1866.                     if bucketSlot == 0 then
  1867.                         bucketSlot = i
  1868.                     else
  1869.                         turtle.select(i)
  1870.                         turtle.transferTo(bucketSlot)
  1871.                     end
  1872.                 elseif data.name == "minecraft:water_bucket" then
  1873.                     water = water + 1
  1874.                 end
  1875.             else
  1876.                 emptySlots = emptySlots + 1
  1877.             end
  1878.         end
  1879.         return emptySlots, water
  1880.     end
  1881.    
  1882.     -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  1883.     -- create water source
  1884.     T:go("D1 R2F1 D1C2 R1C1 R1C1 R1C1 R1", false, 0, true)  -- down 1, turn round 1 block away from stairs, down 1. blocks forward, down, left and right, face backwards
  1885.     T:go("F1C2 L1C1 R2C1 L1", false, 0, true)               -- prepare centre of water source: blocks down , left, right
  1886.     T:go("F1C2 L1C1 R1C1 R1C1 R1F1", false, 0, true)        -- prepare end of water source, move to centre, facing forward
  1887.     T:place("minecraft:water_bucket", -1, "forward")
  1888.     T:turnRight(2)                                          -- facing backward
  1889.     T:place("minecraft:water_bucket", -1, "forward")
  1890.     T:go("R2U1F1") -- facing forward
  1891.     T:place("minecraft:soul_sand", -1, "forward", false)    -- placed at end of water source
  1892.     turtle.back()                                           -- above centre of water source
  1893.     T:place("stone", -1, "forward")
  1894.     -- fill buckets and build first 2 levels
  1895.     lib.fillBuckets(height, true)   -- fill as many buckets as required or until inventory full, sort inventory as well
  1896.     T:go("U1F2 L1C1R1C1R1C1L1", false, 0, true)     -- prepare layer 1
  1897.     lib.addSign()
  1898.     T:go("U1F1R1F1 L1C1R1C1R1C1L1", false, 0, true) -- prepare layer 2
  1899.     lib.addSign()
  1900.     T:go("L1F1 R1F1R1", false, 0, true)  -- above source, level 2
  1901.     lib.buildLift(height)
  1902.     lib.cleanUp(height)
  1903. end
  1904.  
  1905. local function createDragonAttack()
  1906.     --[[
  1907.       X 0 0 0 X     X = exit site                (y = 63)
  1908.     X E O O O E X   0 = bedrock on layer above   (y = 63)
  1909.     0 O O O O O 0   O = bedrock on working layer (y = 62)
  1910.     0 O O O O O 0   E = starting position        (y = 62)
  1911.     0 O O O O O 0
  1912.     X E O O O E X
  1913.       X 0 0 0 X
  1914.     ]]
  1915.     local lib = {}
  1916.    
  1917.     function lib.upToBedrock()
  1918.         local blockTypeU = T:getBlockType("up")
  1919.         while blockTypeU ~= "minecraft:bedrock" do
  1920.             T:up(1)
  1921.             blockTypeU = T:getBlockType("up")
  1922.         end
  1923.     end
  1924.    
  1925.     function lib.toEdgeOfBedrock()
  1926.         local distance = 0
  1927.         local blockTypeU = T:getBlockType("up")
  1928.         while blockTypeU == "minecraft:bedrock" do
  1929.             T:forward(1)
  1930.             distance = distance + 1
  1931.             blockTypeU = T:getBlockType("up")
  1932.         end
  1933.         return distance
  1934.     end
  1935.    
  1936.     function lib.findStart()
  1937.         lib.toEdgeOfBedrock()               -- go outside bedrock area
  1938.         T:go("R2F1")                        -- turn round, forward 1, under bedrock again
  1939.         local width = lib.toEdgeOfBedrock() -- ended outside bedrock
  1940.  
  1941.         if width == 5 then                  -- origin in main section
  1942.             T:go("R2F3L1")                  -- now in centre of 1 axis, turned left
  1943.             width = lib.toEdgeOfBedrock()   -- ended outside bedrock, width should be 1 to 4 depending on start pos
  1944.             T:go("R2F1L1")                  -- move back under bedrock edge (3 blocks)
  1945.             lib.toEdgeOfBedrock()           -- move to corner of bedrock
  1946.         --  elseif width == 3 then          -- on outer strip of 3
  1947.         end
  1948.     end
  1949.    
  1950.     function lib.buildWall(length)
  1951.         for i = 1, length do
  1952.             if i < length then
  1953.                 T:go("C2F1", false, 0, true)
  1954.             else
  1955.                 T:go("C2", false, 0, true)
  1956.             end
  1957.         end
  1958.     end
  1959.    
  1960.     function lib.addCeiling(length)
  1961.         for i = 1, length do
  1962.             if i < length then
  1963.                 T:go("C0F1", false, 0, true)
  1964.             else
  1965.                 T:go("C0", false, 0, true)
  1966.             end
  1967.         end
  1968.     end
  1969.    
  1970.     lib.upToBedrock()                       -- go up until hit bedrock
  1971.     lib.findStart()                         -- should be on position 'E'
  1972.     T:go("F1U2L1")                          -- forward to any 'X' up 2, turn left
  1973.     local blockTypeF = T:getBlockType("forward")
  1974.     if blockTypeF == "minecraft:bedrock" then   -- exit not correct
  1975.         T:turnRight(2)  -- face correct direction
  1976.     else
  1977.         T:turnRight(1)  -- return to original direction
  1978.     end
  1979.     T:go("U2F1 L1F2L2") -- on corner outside bedrock, ready to build wall
  1980.     for i = 1, 4 do
  1981.         lib.buildWall(9)
  1982.         T:turnRight(1)
  1983.     end
  1984.     T:up(1)
  1985.     for i = 1, 4 do
  1986.         lib.buildWall(9)
  1987.         T:turnRight(1)
  1988.     end
  1989.     T:go("F1R1F1L1D1")
  1990.     -- add ceiling
  1991.     lib.addCeiling(7)
  1992.     T:go("R1F1R1")
  1993.     lib.addCeiling(7)
  1994.     T:go("L1F1L1")
  1995.     lib.addCeiling(7)
  1996.     T:go("R1F1R1")
  1997.     lib.addCeiling(3)
  1998.     T:go("L2F2")
  1999.     T:go("R1F1R1")
  2000.     lib.addCeiling(7)
  2001.     T:go("L1F1L1")
  2002.     lib.addCeiling(7)
  2003.     T:go("R1F1R1")
  2004.     lib.addCeiling(7)
  2005.     T:go("R1F3R1")
  2006.     lib.addCeiling(3)
  2007.     T:dig("up")
  2008.     attack(true)
  2009. end
  2010.  
  2011. local function createDragonTrap()
  2012.     -- build up 145 blocks with ladders
  2013.     for i = 1, 145 do
  2014.         T:go("U1C2")
  2015.         turtle.back()
  2016.         T:place("minecraft:ladder", -1, "down")
  2017.         turtle.forward()
  2018.     end
  2019.     T:go("R2F1C1 L1C1 L2C1 R1")
  2020.     for i = 1, 100 do
  2021.         T:go("F1C2")
  2022.     end
  2023.     T:forward(1)
  2024.     T:place("minecraft:obsidian", -1, "down")
  2025.     T:go("R2F1x2R2")
  2026.     T:place("minecraft:water_bucket", -1, "forward")
  2027.     T:go("R2F6R2")
  2028.     attack(false)
  2029. end
  2030.  
  2031. local function createPath(length, isCanal)
  2032.     if length == nil then length = 0 end
  2033.     if isCanal == nil then isCanal = false end
  2034.     local numBlocks = 0
  2035.     local continue = true
  2036.     for i = 1, 2 do
  2037.         T:fillVoid("down", {}, false)
  2038.         T:forward(1)
  2039.         numBlocks = numBlocks + 1
  2040.     end
  2041.     local place = clearVegetation("down")
  2042.     while place do -- while air, water, normal ice, bubble column or lava below
  2043.         if T:fillVoid("down", {}, false) then -- false if out of blocks
  2044.             T:forward(1)
  2045.             numBlocks = numBlocks + 1
  2046.             if numBlocks % 8 == 0 then
  2047.                 if T:getItemSlot("minecraft:torch", -1) > 0 then
  2048.                     T:turnRight(2)
  2049.                     T:place("minecraft:torch", -1, "forward", false)
  2050.                     T:turnRight(2)
  2051.                 end
  2052.             end
  2053.         else
  2054.             break
  2055.         end
  2056.         if length > 0 and numBlocks >= length then -- not infinite path (length = 0)
  2057.             break
  2058.         end
  2059.         place = clearVegetation("down")
  2060.     end
  2061.     return numBlocks
  2062. end
  2063.  
  2064. local function createCanal(side, length, height)
  2065.     -- go(path, useTorch, torchInterval, leaveExisting)
  2066.     -- if height = 0 then already at correct height on canal floor
  2067.         -- check block below, block to left and block above, move forward tunnelling
  2068.         -- if entering water then move up, onto canal wall and continue pathway
  2069.         -- if 55 and tunnelling then flood canal
  2070.     -- else height = 1 then above water and on path across
  2071.         -- move forward, checking for water below
  2072.         -- if water finishes, move into canal, drop down and continue tunnelling
  2073.     local lib = {}
  2074.    
  2075.     function lib.side(side, length, maxLength, height)
  2076.         local turnA = "R"
  2077.         local turnB = "L"
  2078.         local isWater = false
  2079.         local isSource = false
  2080.         local onWater = false
  2081.         local numBlocks = 0
  2082.         local doContinue = true
  2083.         if side == 1 then -- right
  2084.             turnA = "L"
  2085.             turnB = "R"
  2086.         end
  2087.         -- if starting on wall, probably already on water
  2088.         if height == 1 then -- if on wall, move to floor, turn to face opposite canal wall
  2089.             T:forward(1)
  2090.             isWater, isSource = T:isWater("down")
  2091.             if isSource then --on river/ocean so just construct walkway
  2092.                 onWater = true
  2093.                 numBlocks = createPath(length - 1, true)
  2094.                 if numBlocks < maxLength then -- continue with canal
  2095.                     T:go(turnA.."1F1D1"..turnA.."1")
  2096.                 else
  2097.                     doContinue = false
  2098.                 end
  2099.             else
  2100.                 T:go(turnA.."1F1D1")
  2101.             end
  2102.         else -- on canal floor, but could be open water
  2103.             isWater, isSource = T:isWater("forward")
  2104.             if isSource then -- water source ahead. Assume on open water   
  2105.                 T:go(turnB.."1U1F1"..turnA.."1")
  2106.                 onWater = true
  2107.                 numBlocks = createPath(length - 1, true)
  2108.                 if numBlocks < maxLength then -- continue with canal
  2109.                     T:go(turnA.."1F1D1"..turnA.."1")
  2110.                 else
  2111.                     doContinue = false
  2112.                 end
  2113.             else
  2114.                 T:go(turnA.."1")
  2115.             end    
  2116.         end
  2117.         if not onWater then
  2118.             if turtle.detect() then --block to side, check is not turtle
  2119.                 if T:getBlockType("forward"):find("turtle") == nil then --not a turtle
  2120.                     T:dig("forward") --automatically avoids turtle
  2121.                 end
  2122.             end
  2123.             T:go(turnA.."1")
  2124.             -- facing canal start wall
  2125.             if turtle.detect() then -- solid block behind: at start of canal   
  2126.                 T:go(turnB.."2C2F1"..turnB.."1C1"..turnB.."1C2x0", false, 0, true) --move forward and check base/side, face start
  2127.                 T:place("minecraft:water_bucket", -1, "forward")
  2128.             else -- air or water behind
  2129.                 -- check if water already present behind. if not create source
  2130.                 isWater, isSource = T:isWater("forward")
  2131.                 if not isSource then
  2132.                     T:place("minecraft:water_bucket", -1, "forward")
  2133.                 end
  2134.             end
  2135.         end
  2136.         -- could be over water, just need walls
  2137.         --print("Loop starting. Enter")
  2138.         --read()
  2139.         local blockType, modifier
  2140.         local torch = 0
  2141.         local sourceCount = 0
  2142.         --loop from here. Facing backwards over existing canal/start
  2143.         while doContinue and numBlocks < maxLength do
  2144.             isWater, isSource = T:isWater("forward")
  2145.             while not isSource do
  2146.                 sleep(10)
  2147.                 print("waiting for water...")
  2148.                 isWater, isSource = T:isWater("forward")
  2149.             end
  2150.             T:place("minecraft:bucket", -1, "forward") -- take water from source
  2151.             -- move forward check canal wall for block, below for block
  2152.             --T:go(turnA.."2F1C2"..turnB.."1C1", false, 0, true) -- face canal wall, repair if req
  2153.             T:go(turnA.."2F1C2", false, 0, true) --move forward, close floor
  2154.             isWater, isSource = T:isWater("forward")
  2155.             --print("Source in front: "..tostring(isSource).." Enter")
  2156.             --read()
  2157.             if isSource then --now on open water. move up and continue
  2158.                 sourceCount = sourceCount + 1
  2159.                 if sourceCount > 3 then
  2160.                     sourceCount = 0
  2161.                     T:go(turnB.."1U1F1"..turnA.."1")
  2162.                     numBlocks = numBlocks +  createPath(length - numBlocks, true) -- eg done 20/64 blocks createPath(44)
  2163.                     if numBlocks < maxLength then -- continue with canal
  2164.                         T:go(turnA.."1F1D1"..turnA.."1x1"..turnA.."2") --return to canal bottom, break any block behind
  2165.                     else
  2166.                         doContinue = false
  2167.                     end
  2168.                 end
  2169.             end
  2170.             T:go(turnB.."1C1", false, 0, true) -- face canal wall, repair if req
  2171.             --print("facing wall. Enter")
  2172.             --read()
  2173.             T:go("U1x1") --go up and remove any block
  2174.             torch = torch + 1
  2175.             numBlocks = numBlocks + 1
  2176.             if turtle.detectUp() then -- block above
  2177.                 T:go("U1x1")
  2178.                 if torch == 8 then
  2179.                     torch = 0
  2180.                     T:place("minecraft:torch", -1, "forward")
  2181.                 end
  2182.                 T:down(1)
  2183.             end
  2184.             if torch == 8 then
  2185.                 torch = 0
  2186.                 T:place("minecraft:torch", -1, "forward")
  2187.             end
  2188.             T:down(1) -- on canal floor facing wall
  2189.             T:go(turnB.."1", false, 0, true)
  2190.             -- place water behind if some water is present
  2191.             isWater, isSource = T:isWater("forward")
  2192.             if not isWater then --no flowing water behind so deploy both sources
  2193.                 T:forward(1)
  2194.                 T:place("minecraft:water_bucket", -1, "forward")
  2195.                 turtle.back()
  2196.             end
  2197.             T:place("minecraft:water_bucket", -1, "forward")
  2198.             -- check opposite canal wall
  2199.             T:go(turnB.."1")
  2200.             if turtle.detect() then --block to side, check is not turtle
  2201.                 if T:getBlockType("forward"):find("turtle") == nil then --not a turtle
  2202.                     T:dig("forward")
  2203.                 end
  2204.             end
  2205.             T:go(turnA.."1")
  2206.         end
  2207.     end
  2208.    
  2209.     function lib.leftSideLegacy(side, length, maxLength, height)
  2210.         local doContinue = true
  2211.         local numBlocks  = 0
  2212.         local doTunnel = false
  2213.         local requestTunnel = false
  2214.         local blockType, modifier
  2215.         while doContinue and numBlocks < maxLength do
  2216.             if height == 0 then -- canal floor
  2217.                 blockType, modifier = T:getBlockType("down")
  2218.                 if blockType == "" or blockType == "minecraft:lava" then -- air or lava below, so place block
  2219.                     T:place("minecraft:cobblestone", -1, "down", false)
  2220.                 end
  2221.                 -- place side block
  2222.                 T:go("L1C1R1", false , 0, true)
  2223.                 -- check above
  2224.                 blockType, modifier = T:getBlockType("up")
  2225.                 --if blockType == "minecraft:log" or blockType == "minecraft:log2" then
  2226.                 if blockType ~= "" then
  2227.                     if string.find(blockType, "log") ~= nil then
  2228.                         T:harvestTree(false, false, "up")
  2229.                     elseif blockType == "minecraft:lava" or blockType == "minecraft:water" then
  2230.                         T:up(1)
  2231.                         T:place("minecraft:cobblestone", -1, "up", false)
  2232.                         T:down(1)
  2233.                     else --solid block or air above
  2234.                         if blockType ~= "" then
  2235.                             T:dig("up")
  2236.                         end
  2237.                     end
  2238.                 end
  2239.                 -- check if block in front is water source
  2240.                 blockType, modifier = T:getBlockType("forward")
  2241.                 --if block:find("water") ~= nil then
  2242.                 if blockType == "minecraft:water" and modifier == 0 then -- source block in front could be lake/ocean
  2243.                     -- move up, to left and continue as height = 1
  2244.                     T:go("U1L1F1R1", false, 0, true)
  2245.                     height = 1
  2246.                 else
  2247.                     T:forward(1, true)
  2248.                     numBlocks = numBlocks + 1
  2249.                 end
  2250.             else -- height = 1, on canal wall
  2251.                 numBlocks = numBlocks + createPath(0, true)
  2252.                 -- if path finished, then move back to canal floor and continue tunnelling
  2253.                 T:go("R1F1D1L1", false, 0, true)
  2254.                 height = 0
  2255.             end
  2256.         end
  2257.     end
  2258.    
  2259.     function lib.rightSideLegacy(side, length, maxLength, height)
  2260.         -- assume left side already under construction
  2261.         local doContinue = true
  2262.         local numBlocks  = 0
  2263.         local doTunnel = false
  2264.         local requestTunnel = false
  2265.         local blockType, modifier
  2266.         local poolCreated = false
  2267.         while doContinue and numBlocks < maxLength do
  2268.             if height == 0 then-- canal floor
  2269.                 -- create first infinity pool
  2270.                 if not poolCreated then
  2271.                     T:up(1)
  2272.                     T:place("minecraft:water_bucket", -1, "down", false)
  2273.                     T:go("L1F1R1", false, 0, true)
  2274.                     T:place("minecraft:water_bucket", -1, "down", false)
  2275.                     T:forward(1)
  2276.                     T:place("minecraft:water_bucket", -1, "down", false)
  2277.                     T:back(1)
  2278.                     -- refill buckets
  2279.                     for j = 1, 3 do
  2280.                         T:place("minecraft:bucket", -1, "down", false)
  2281.                         sleep(0,5)
  2282.                     end
  2283.                     T:go("R1F1L1F2", false , 0, true)
  2284.                     T:down(1)
  2285.                     poolCreated = true
  2286.                 end
  2287.                 blockType, modifier = T:getBlockType("down")
  2288.                 if blockType == "" or blockType == "minecraft:lava"
  2289.                    or blockType == "minecraft:water" or blockType == "minecraft:flowing_water" then -- air, water or lava below, so place block
  2290.                     T:place("minecraft:cobblestone", -1, "down", false)
  2291.                 end
  2292.                 -- place side block
  2293.                 T:go("R1C1L1", false , 0, true)
  2294.                 T:up(1)
  2295.                 blockType, modifier = T:getBlockType("up")
  2296.                 if blockType == "minecraft:log" or blockType == "minecraft:log2" then
  2297.                     T:harvestTree(false, false, "up")
  2298.                 elseif blockType == "minecraft:lava" or blockType == "minecraft:water" then
  2299.                     T:place("minecraft:cobblestone", -1, "up", false)
  2300.                 end
  2301.                 T:place("minecraft:water_bucket", -1, "down", false)
  2302.                 for j = 1, 2 do
  2303.                     T:forward(1)
  2304.                     blockType, modifier = T:getBlockType("up")
  2305.                     --if blockType == "minecraft:log" or blockType == "minecraft:log2" then
  2306.                     if blockType ~= "" then
  2307.                         if string.find(blockType, "log") ~= nil then
  2308.                             T:harvestTree(false, false, "up")
  2309.                         elseif blockType == "minecraft:lava" or blockType == "minecraft:water" then
  2310.                             T:place("minecraft:cobblestone", -1, "up", false)
  2311.                         end
  2312.                     end
  2313.                     -- at ceiling level
  2314.                     T:go("D1R1C1L1", false, 0, true)
  2315.                     blockType, modifier = T:getBlockType("down")
  2316.                     if blockType == "" or blockType == "minecraft:lava"
  2317.                        or blockType == "minecraft:water" or blockType == "minecraft:flowing_water" then -- air, water or lava below, so place block
  2318.                         T:place("minecraft:cobblestone", -1, "down", false)
  2319.                     end
  2320.                     -- check if block in front is water source
  2321.                     blockType, modifier = T:getBlockType("forward")
  2322.                     T:up(1)
  2323.                     T:place("minecraft:water_bucket", -1, "down", false)
  2324.                     if blockType == "minecraft:water" and modifier == 0 then -- source block in front could be lake/ocean
  2325.                         -- move to right and continue as height = 1
  2326.                         T:go("R1F1L1", false, 0, true)
  2327.                         height = 1
  2328.                         break  
  2329.                     end
  2330.                 end
  2331.                 if height == 0 then
  2332.                     T:back(2)
  2333.                     for j = 1, 3 do
  2334.                         T:place("minecraft:bucket", -1, "down", false)
  2335.                         sleep(0,5)
  2336.                     end
  2337.                     T:go("F3D1", false, 0, true)
  2338.                 end
  2339.             else -- height = 1: on wall
  2340.                 numBlocks = numBlocks + createPath(0, true)
  2341.                 -- if path finished, then move back to canal floor and continue tunnelling
  2342.                 T:go("L1F1L1F1", false, 0, true) -- facing backwards, collect water
  2343.                 for j = 1, 3 do
  2344.                     T:place("minecraft:bucket", -1, "down", false)
  2345.                     sleep(0,5)
  2346.                 end
  2347.                 T:go("R2F1D1", false, 0, true) --canal floor
  2348.                 height = 0
  2349.             end
  2350.         end
  2351.     end
  2352.    
  2353.     -- side = 0/1: left/right side
  2354.     -- length = 0-1024 0 = continuous
  2355.     -- height = 0/1 0 = floor, 1 = wall
  2356.     -- T:place(blockType, damageNo, direction, leaveExisting)
  2357.     -- T:go(path, useTorch, torchInterval, leaveExisting)
  2358.    
  2359.     local maxLength = 1024
  2360.     if length ~= 0 then
  2361.         maxLength = length
  2362.     end
  2363.     if side == 0 then -- left side
  2364.         if deletesWater then -- legacy version
  2365.             lib.leftSideLegacy(side, length, maxLength, height)
  2366.         else -- new version
  2367.             lib.side(side, length, maxLength, height)
  2368.         end
  2369.     else -- right side (1)
  2370.         if deletesWater then -- legacy version
  2371.             lib.rightSideLegacy(side, length, maxLength, height)
  2372.         else -- new version
  2373.             lib.side(side, length, maxLength, height)
  2374.         end
  2375.     end
  2376. end
  2377.  
  2378. local function createCorridor(length)
  2379.     if length == nil then length = 0 end    -- continue until out of blocks
  2380.     local currentSteps = 0                  -- counter for infinite length. pause every 64 blocks
  2381.     local totalSteps = 0                    -- counter for all steps so far
  2382.     local torchInterval = 0                 -- assume no torches
  2383.     local torchSpaces = 0                   -- if torches present, counter to place every 8 blocks
  2384.     if T:getItemSlot("minecraft:torch") > 0 then
  2385.         torchInterval = 8
  2386.     end
  2387.     for steps = 1, length do
  2388.         if currentSteps >= 64 and length == 0 then
  2389.             -- request permission to continue if infinite
  2390.             T:clear()
  2391.             print("Completed "..totalSteps..". Ready for 64 more")
  2392.             print("Do you want to continue? (y/n)")
  2393.             response = read()
  2394.             if response:lower() ~= "y" then
  2395.                 break
  2396.             end
  2397.             currentSteps = 0
  2398.         end
  2399.         --go(path, useTorch, torchInterval, leaveExisting)
  2400.         T:go("F1x0C2", false, 0, true) -- forward 1; excavate above, cobble below
  2401.         currentSteps = currentSteps + 1
  2402.         totalSteps = totalSteps + 1
  2403.         torchSpaces = torchSpaces + 1
  2404.         if torchInterval > 0 and torchSpaces >= 8 then
  2405.             if T:getItemSlot("minecraft:torch") > 0 then
  2406.                 T:turnRight(2)
  2407.                 T:place("minecraft:torch", -1, "forward")
  2408.                 T:turnRight(2)
  2409.             end
  2410.             torchSpaces = 0
  2411.         end
  2412.     end
  2413. end
  2414.  
  2415. local function createEnderTower(stage)
  2416.     --[[ lower base = stage 1, upper base = 2, tower = 3 ]]
  2417.     local lib = {}
  2418.     --[[ go(path, useTorch, torchInterval, leaveExisting, preferredBlock) ]]
  2419.     function lib.getEmptySlots()
  2420.         local empty = 0
  2421.         for i = 1, 16 do
  2422.             if turtle.getItemCount(i) == 0 then
  2423.                 empty = empty + 1
  2424.             end
  2425.         end
  2426.         return empty
  2427.     end
  2428.  
  2429.     function lib.getStone(direction, stacks)
  2430.         --[[ get block user wants to use ]]
  2431.         local suck = turtle.suck   
  2432.         if direction == "down" then
  2433.             suck = turtle.suckDown
  2434.         end
  2435.         if T:getBlockType(direction) == "minecraft:chest" then
  2436.             T:sortInventory()
  2437.             local slot = T:getFirstEmptySlot() --find spare slot
  2438.             if slot > 0 then --empty slot found
  2439.                 turtle.select(1)
  2440.                 if stacks == 0 then
  2441.                     while suck() do end
  2442.                 else
  2443.                     for i = 1, stacks do -- get # stacks of stone from chest
  2444.                         suck()
  2445.                     end
  2446.                 end
  2447.                 if T:getSlotContains(slot) == "" then
  2448.                     return T:getMostItem()              -- empty chest
  2449.                 else
  2450.                     return T:getSlotContains(slot)      -- use this as default building block
  2451.                 end
  2452.             else
  2453.                 return T:getMostItem()              -- full inventory
  2454.             end
  2455.         else
  2456.             return T:getMostItem()              -- no chest
  2457.         end
  2458.     end
  2459.    
  2460.     function lib.stackBuckets()
  2461.         local data = {}
  2462.         local bucketSlot = 0
  2463.         local emptySlots = 0
  2464.         local water = 0
  2465.         T:sortInventory()
  2466.         for i = 1, 16 do
  2467.             -- find first empty bucket
  2468.             if turtle.getItemCount(i) > 0 then
  2469.                 data = turtle.getItemDetail(i)
  2470.                 if data.name == "minecraft:bucket" then
  2471.                     if bucketSlot == 0 then
  2472.                         bucketSlot = i
  2473.                     else
  2474.                         turtle.select(i)
  2475.                         turtle.transferTo(bucketSlot)
  2476.                     end
  2477.                 elseif data.name == "minecraft:water_bucket" then
  2478.                     water = water + 1
  2479.                 end
  2480.             else
  2481.                 emptySlots = emptySlots + 1
  2482.             end
  2483.         end
  2484.         return emptySlots, water
  2485.     end
  2486.    
  2487.     function lib.countWaterBuckets()
  2488.         local data = {}
  2489.         local buckets = 0
  2490.         for i = 1, 16 do
  2491.             data = turtle.getItemDetail(i)
  2492.             if data.name == "minecraft:water_bucket" then
  2493.                 buckets = buckets + 1
  2494.             end
  2495.         end
  2496.         return buckets
  2497.     end
  2498.    
  2499.     function lib.baseRun(preferredBlock, count, turn)
  2500.         for i = 1, count do
  2501.             T:go("C2F1", false, 0, false, preferredBlock)
  2502.         end
  2503.         T:go("C2"..turn, false, 0, false, preferredBlock)
  2504.     end
  2505.    
  2506.     function lib.outsideRun(preferredBlock)
  2507.         T:place("fence", -1, "down", false)
  2508.         T:forward(1)
  2509.         T:place(preferredBlock, -1, "down", false)
  2510.         T:forward(1)
  2511.         T:place(preferredBlock, -1, "down", false)
  2512.         T:forward(2)
  2513.         T:place(preferredBlock, -1, "down", false)
  2514.     end
  2515.    
  2516.     function lib.signRun(preferredBlock ,message)
  2517.         T:place(preferredBlock, -1, "down", false)
  2518.         T:forward(4)
  2519.         T:place(preferredBlock, -1, "down", false)
  2520.         turtle.back()
  2521.         turtle.back()
  2522.         T:down(1)
  2523.         T:place("sign", -1, "forward", false, message)
  2524.         T:go("U1F2")
  2525.     end
  2526.    
  2527.     function lib.goToWater(height)
  2528.         local built = 0 -- measures completed lift height
  2529.         while turtle.down() do -- takes turtle to bottom of water source
  2530.             height = height + 1
  2531.             if turtle.detect() then
  2532.                 built = built + 1
  2533.             end
  2534.         end
  2535.         T:up(1) -- above watersource assuming it is 1-1.5 blocks deep
  2536.         height = height - 1
  2537.         -- built = built - 1 not required as next block is water source: not detected
  2538.         return built, height
  2539.     end
  2540.    
  2541.     function lib.fillBuckets(toBuild)
  2542.         local emptySlots, water = lib.stackBuckets() -- gets no of empty slots + no of water buckets
  2543.         if water < toBuild then -- no of water buckets onboard less than required quantity
  2544.             for i = 1, toBuild do -- fill required no of buckets up to max space in inventory
  2545.                 emptySlots = lib.getEmptySlots()
  2546.                 if emptySlots == 0 then -- inventory full
  2547.                     break
  2548.                 else
  2549.                     if T:place("minecraft:bucket", -1, "down", false) then
  2550.                         water = water + 1
  2551.                         sleep(0.5)
  2552.                     end
  2553.                 end
  2554.             end
  2555.         end
  2556.        
  2557.         return water
  2558.     end
  2559.    
  2560.     function lib.buildLift(preferredBlock)
  2561.         local built = 0 -- measures completed lift height
  2562.         local height = 0 -- measures total height from starting position
  2563.         built, height = lib.goToWater(height) -- returns lift blocks already placed, total height of drop from starting point
  2564.         local toBuild = height - built -- no of blocks to increase lift size
  2565.         while toBuild > 0 do -- at least 1 block height remaining
  2566.             local water = lib.fillBuckets(toBuild) -- no of water buckets onboard (could be more than required)
  2567.             if water > toBuild then
  2568.                 water = toBuild
  2569.             end
  2570.             while turtle.detect() do -- climb to top of existing lift
  2571.                 turtle.up()
  2572.                 height = height - 1
  2573.             end
  2574.             T:forward(1)
  2575.             for i = 1, water do -- build lift by no of water buckets
  2576.                 if T:place("minecraft:water_bucket", -1, "forward", false) then
  2577.                     T:up(1)
  2578.                     height = height - 1
  2579.                     toBuild = toBuild - 1
  2580.                     T:place(preferredBlock, -1, "down", false)
  2581.                 end
  2582.             end
  2583.             turtle.back()
  2584.             -- may still be some height to complete, but needs refill
  2585.             if toBuild > 0 then
  2586.                 lib.goToWater(0) --return to source
  2587.                 lib.fillBuckets(toBuild)
  2588.             end
  2589.         end
  2590.         if height > 0 then -- if any remaining distance
  2591.             T:up(height)
  2592.         end
  2593.        
  2594.     end
  2595.    
  2596.     function lib.buildSection(preferredBlock, solid)
  2597.         -- builds a section without any blocks in the centre
  2598.         -- second layer of each section end walls have fence posts
  2599.         T:go("F1C2 F2C2 F1R1", false, 0, false, preferredBlock) -- first side solid row
  2600.         if solid then -- first layer of each section
  2601.             T:go("F1C2 F1R1", false, 0, false, preferredBlock) -- top side solid row
  2602.         else
  2603.             T:go("F1") -- top side solid row
  2604.             if not T:place("fence", -1, "down", false) then-- first side
  2605.                 T:place(preferredBlock, -1, "down", false)
  2606.             end
  2607.             T:go("F1R1") -- top side solid row
  2608.         end
  2609.         T:go("F1C2 F2C2 F1R1", false, 0, false, preferredBlock) -- far side solid row
  2610.         T:go("F1C2 F1R1U1", false, 0, false, preferredBlock) -- bottom side solid row
  2611.     end
  2612.     --[[
  2613.         clsTurtle methods:
  2614.         clsTurtle.place(self, blockType, damageNo, direction, leaveExisting)
  2615.         clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
  2616.     ]]
  2617.     -- remove 1 stack stone from chest
  2618.     local preferredBlock = lib.getStone("down", 1) -- use this as default building block
  2619.     if stage == 1 then
  2620.         -- build base floor
  2621.         --T:go("R2F2R1F3R1", false, 0, false, preferredBlock)
  2622.         T:go("R2F1C2R1F1C2F1C2F1C2R1", false, 0, false, preferredBlock)
  2623.         for i = 1, 2 do
  2624.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  2625.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  2626.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  2627.         end
  2628.         -- move back to centre, build water source, with soul sand at base of first source
  2629.         --T:go("R1F3L1C2F1C2F2D1", false, 0, false, preferredBlock) --just behind chest, 1 below ground level
  2630.         T:go("R1F3L1F2C2F1D1", false, 0, false, preferredBlock) --1 block behind chest, 1 below ground level
  2631.         T:place("minecraft:soul_sand", -1, "down", false) -- over block 1 of water source
  2632.         T:go("F1C2F1C2", false, 0, false, preferredBlock) -- over block 2 of water source
  2633.         T:go("F1C2U1C2", false, 0, false, preferredBlock) -- over block 4 of water source
  2634.         T:go("F1C2F1C2R2F5R2", false, 0, false, preferredBlock) -- over block 1 of water source
  2635.         T:place("minecraft:water_bucket", -1, "down", false)
  2636.         T:forward(2) -- over block 3 of water source
  2637.         T:place("minecraft:water_bucket", -1, "down", false)
  2638.         turtle.back() -- over block 2 of water source
  2639.         T:place("minecraft:bucket", -1, "down", false)
  2640.         T:go("F2D1R2C2") -- over block 4 of water source
  2641.         T:go("U1", false, 0, false, preferredBlock)
  2642.         T:place("minecraft:water_bucket", -1, "down", false)
  2643.         T:forward(4)
  2644.         lib.stackBuckets() -- put all buckets in same slot
  2645.         T:dropItem("minecraft:dirt", 0, "up") -- drop dirt up:  clsTurtle.dropItem(self, item, keepAmount, direction)
  2646.         preferredBlock = lib.getStone("down", 6)
  2647.         T:go("R1F2R1U1") -- move to start position
  2648.         for i = 1, 2 do
  2649.             -- build first level of tower: 2 x outside run, 2 x sign run
  2650.             lib.outsideRun(preferredBlock)
  2651.             if i == 1 then -- place door
  2652.                 T:go("L1F1L1F1L1D1")
  2653.                 T:place("door", -1, "forward", false)
  2654.                 T:go("U1L1F1R1F1L1")
  2655.             end
  2656.             T:go("R1F1R1")
  2657.             lib.signRun(preferredBlock, "Pint size\nzombies\nProhibited")
  2658.             T:go("L1F1L1C2", false, 0, false, preferredBlock)
  2659.             T:forward(4) -- miss out centre block
  2660.             T:place(preferredBlock, -1, "down", false)
  2661.             T:go("R1F1R1")
  2662.             lib.signRun(preferredBlock, "Pint size\nzombies\nProhibited")
  2663.             T:go("L1F1L1")
  2664.             lib.outsideRun(preferredBlock)
  2665.             if i == 1 then -- layer 1
  2666.                 T:go("R1F1R1F1R1D1") -- place door
  2667.                 T:place("door", -1, "forward", false)
  2668.                 T:go("U1 R1F1 L1F5 L1U1 F2D1  F2R2 U1") -- go over door
  2669.             else -- layer 2
  2670.                 T:go("L1F5L1F6R2U1") -- over corner of lower platform
  2671.             end
  2672.         end
  2673.         for i = 1, 2 do -- build both sides of platform, leave centre missing
  2674.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  2675.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  2676.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  2677.         end
  2678.         T:go("R1F3L1C2F1C2F1C2F4C2F1C2F1C2", false, 0, false, preferredBlock) --fill in centre row
  2679.         --T:go("R2F6R1F1R1U1") -- go to start of tower base
  2680.         T:go("R2F7R2D3") -- go to start on top of chest
  2681.         T:sortInventory()
  2682.     elseif stage == 2 then
  2683.         -- start on top of chest, should have sufficient stone in inventory
  2684.         T:go("U3L1F1R1F1U1") -- go to start of tower base
  2685.         for i = 1, 7 do -- build 14 block high tower
  2686.             lib.buildSection(preferredBlock, false)
  2687.             lib.buildSection(preferredBlock, true)
  2688.         end
  2689.         T:go("R2F4R1F4R1", false, 0, false, preferredBlock) -- build upper platform (154 blocks remaining)
  2690.         for i = 1, 2 do -- build both sides of upper platform, leave centre missing
  2691.             lib.baseRun(preferredBlock, 12, "R1F1R1")
  2692.             lib.baseRun(preferredBlock, 12, "L1F1L1")
  2693.             lib.baseRun(preferredBlock, 12, "R1F1R1")
  2694.             lib.baseRun(preferredBlock, 12, "L1F1L1")
  2695.             lib.baseRun(preferredBlock, 12, "R1F6R1")
  2696.         end
  2697.         T:go("R1F5 L1C2 F1C2 F1C2 F1C2 F1C2 F4C2 F1C2 F1C2 F1C2 F1C2 ", false, 0, false, preferredBlock) --fill in centre row
  2698.         T:go("R2F5") -- return to drop area
  2699.         lib.buildLift(preferredBlock) -- build bubble lift
  2700.         T:go("F3R1F1R1U1") -- go to start of tower base
  2701.         T:go("C2F4 C2R1F1R1", false, 0, false, preferredBlock)      -- left side layer 21
  2702.         T:go("F2C2 F2C2 L1F1L1", false, 0, false, preferredBlock)   -- centre layer 21
  2703.         T:go("C2F4 C2R2U1", false, 0, false, preferredBlock)        -- right side layer 21
  2704.         T:go("C2F4 C2R1F1R1", false, 0, false, preferredBlock)      -- right side layer 22
  2705.         T:place("fence", -1, "down", false)                         -- fence centre of bottom side layer 22
  2706.         T:go("F2C2 F2L1F1L1", false, 0, false, preferredBlock)      -- centre layer 22
  2707.         T:go("C2F4 C2R2F2L1F1R2D2", false, 0, false, preferredBlock) --ready to place ladder
  2708.         T:place("ladder", -1, "forward", false)
  2709.         T:up(1)
  2710.         T:place("ladder", -1, "forward", false)
  2711.         --T:go("U2R1F4R1F1R1") -- ready to make upper part of tower base
  2712.         T:go("U2R1F4R1F1R1") -- ready to make upper part of tower base
  2713.         for i = 1, 2 do -- build both sides of platform, leave centre missing
  2714.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  2715.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  2716.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  2717.         end
  2718.         T:go("R1F3 L1C2 F1C2 F1C2 F1", false, 0, false, preferredBlock) --fill in centre row
  2719.         T:place("minecraft:soul_sand", -1, "down", false)
  2720.         T:go("F1C2 F2C2 F1C2 F1C2", false, 0, false, preferredBlock)
  2721.         T:go("R2F6R1F1R1U1") -- go to start of tower base
  2722.         -- build 2 levels, finish signs and ladders
  2723.         T:go("C2F2 R1D2 U1", false, 0, false, preferredBlock)
  2724.         T:place("ladder", -1, "down", false)
  2725.         T:turnRight(1)
  2726.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  2727.         T:go("U1R2F2C2 R1F2C2 R1", false, 0, false, preferredBlock) --top right corner
  2728.         T:go("F4C2B2D1", false, 0, false, preferredBlock)
  2729.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  2730.         T:go("U1F2R1F1C2F1R1U1", false, 0, false, preferredBlock) --ready for second level
  2731.         T:go("C2F2 R2D1", false, 0, false, preferredBlock)
  2732.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  2733.         T:go("U1R2F2C2R1", false, 0, false, preferredBlock) --top left corner
  2734.         T:go("F1R1C2F4C2", false, 0, false, preferredBlock) --mid bottom row
  2735.         T:go("L1F1L1C2", false, 0, false, preferredBlock) -- bottom right corner
  2736.         T:go("F2R2D1", false, 0, false, preferredBlock)
  2737.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  2738.         T:go("U1R2F2C2", false, 0, false, preferredBlock) -- top right corner
  2739.         -- return to chest
  2740.         T:go("L1F1L1 F5D23R2", false, 0, false, preferredBlock) -- return to chest
  2741.         T:sortInventory()
  2742.     elseif stage == 3 then
  2743.         --[[ move to top of structure
  2744.         | 4 |
  2745.         |3 5|
  2746.         | X |
  2747.         |2 6|
  2748.         | 1 |
  2749.         ]]
  2750.         local towerHeight = 128 -- even no only suggest 128
  2751.         while turtle.detect() do
  2752.             turtle.up()
  2753.         end
  2754.         T:go("F1U1", false, 0, false, preferredBlock) -- return to finish tower
  2755.         for i = 1, towerHeight do -- 1
  2756.             T:go("C2U1", false, 0, false, preferredBlock)
  2757.         end
  2758.         T:go("F1L1F1R1D2")
  2759.         while turtle.down() do -- 2
  2760.             T:fillVoid("up", {preferredBlock})
  2761.         end
  2762.         T:go("F1R2C1R2F1D1", false, 0, false, preferredBlock)
  2763.         for i = 1, towerHeight / 2 do -- 3
  2764.             T:go("U2C2", false, 0, false, preferredBlock)
  2765.         end
  2766.         T:go("U1F1R1F1R1D1", false, 0, false, preferredBlock) -- back of tower facing front
  2767.         local deviate = false
  2768.         while turtle.down() do -- 4
  2769.             T:place("fence", -1, "up", false)
  2770.             if turtle.down() then
  2771.                 T:fillVoid("up", {preferredBlock})
  2772.             else
  2773.                 T:go("F1R2C1R1F1R1D1", false, 0, false, preferredBlock)
  2774.                 deviate = true
  2775.                 break
  2776.             end
  2777.         end
  2778.         if not deviate then
  2779.             T:go("F1L1F1R1D1", false, 0, false, preferredBlock)
  2780.         end
  2781.         for i = 1, towerHeight / 2 do -- 5
  2782.             T:go("U2C2", false, 0, false, preferredBlock)
  2783.         end
  2784.         T:go("F2R2", false, 0, false, preferredBlock) -- facing back of tower
  2785.         while turtle.down() do -- 6
  2786.             T:fillVoid("up", {preferredBlock}) --layer 129
  2787.         end
  2788.         T:go("F1L2C1U"..towerHeight)
  2789.         T:go("F4R1F3R1U1", false, 0, false, preferredBlock)
  2790.         -- add small platform at the top
  2791.         lib.baseRun(preferredBlock, 8, "R1F1R1")
  2792.         lib.baseRun(preferredBlock, 8, "L1F3L1")
  2793.         lib.baseRun(preferredBlock, 8, "L1F1L1")
  2794.         lib.baseRun(preferredBlock, 8, "R1F1R1")
  2795.         T:go("C2 F1C2 F1C2 F4C2 F1C2 F1C2 R2F3", false, 0, false, preferredBlock) --fill in centre row
  2796.         lib.buildLift(preferredBlock) -- build bubble lift
  2797.     end
  2798. end
  2799.  
  2800. function createFarm(extend)
  2801.     lib = {}
  2802.     function lib.addWaterSource(pattern)
  2803.         -- pattern = {"d","c","c","d"}
  2804.         T:go("D1x2C2")
  2805.         for i = 1, 4 do
  2806.             T:dig("forward")
  2807.             if pattern[i] == "d" then
  2808.                 T:place("minecraft:dirt", -1, "forward", false)
  2809.             elseif pattern[i] == "c" then
  2810.                 T:place("minecraft:cobblestone", -1, "forward", false)
  2811.             end
  2812.             T:turnRight(1)
  2813.         end
  2814.         T:up(1)
  2815.         T:place("minecraft:water_bucket", -1, "down")
  2816.     end
  2817.    
  2818.     function lib.placeDirt(count, atCurrent)
  2819.         if atCurrent then
  2820.             local blockType = T:getBlockType("down")
  2821.             if blockType ~= "minecraft:dirt" and blockType ~= "minecraft:grass_block" then
  2822.                 T:place("minecraft:dirt", -1, "down", false)
  2823.             end
  2824.         end
  2825.         for  i = 1, count do
  2826.             T:forward(1)
  2827.             T:dig("up")
  2828.             local blockType = T:getBlockType("down")
  2829.             if blockType ~= "minecraft:dirt" and blockType ~= "minecraft:grass_block" then
  2830.                 T:place("minecraft:dirt", -1, "down", false)
  2831.             end
  2832.         end
  2833.     end
  2834.    
  2835.     -- extend "", "right" or "forward". only adds a single new farm.
  2836.     -- right adds farm and checks for existing front extensions, dealt with separately
  2837.     -- clsTurtle.place(blockType, damageNo, direction, leaveExisting)
  2838.     if extend == nil then
  2839.         extend = ""
  2840.     end
  2841.     local blockType = ""
  2842.     -- extend = "right": placed on cobble corner of existing farm facing right side
  2843.     -- extend = "front": placed on cobble corner of existing farm facing front
  2844.     -- else placed on ground at corner of potential new farm facing front
  2845.    
  2846.     -- step 1 dig ditch round perimeter wall
  2847.     if extend == "right" then
  2848.         -- move to front corner
  2849.         T:forward(12) -- over wall of existing farm, will be empty below if not extended
  2850.         blockType = T:getBlockType("down")
  2851.         if blockType == "minecraft:cobblestone" then -- already a farm extension on left side
  2852.             T:go("R1F1D1")
  2853.         else
  2854.             T:go("D1R1F1x0")
  2855.         end
  2856.         -- cut ditch round new farm extension
  2857.         for i = 1, 11 do
  2858.             T:go("x0F1")
  2859.         end
  2860.         T:go("R1x0")
  2861.         for i = 1, 13 do
  2862.             T:go("x0F1")
  2863.         end
  2864.         T:go("R1x0")
  2865.         -- now at lower right corner. if extension below, do not cut ditch
  2866.         blockType = T:getBlockType("forward")
  2867.         if blockType == "minecraft:cobblestone" then -- already a farm extension below
  2868.             -- return to start for adding chests and walls
  2869.             T:go("U1R1F1L1F12R1")
  2870.         else -- finish ditch
  2871.             for i = 1, 12 do
  2872.                 T:go("x0F1")
  2873.             end
  2874.             T:go("R1U1F1") -- on corner of new extension
  2875.         end
  2876.     elseif extend == "forward" then
  2877.         -- cut ditch round new farm extension
  2878.         T:go("L1F1x0R1D1")
  2879.         for i = 1, 12 do
  2880.             T:go("x0F1")
  2881.         end
  2882.         T:go("R1x0")
  2883.         for i = 1, 13 do
  2884.             T:go("x0F1")
  2885.         end
  2886.         T:go("R1x0")
  2887.         for i = 1, 11 do
  2888.             T:go("x0F1")
  2889.         end
  2890.         T:go("U1x0F1R1F12R1") -- on corner of new extension
  2891.     else -- new farm. cut a groove round the entire farm base
  2892.         -- move to left side of intended wall
  2893.         T:go("L1F1x0R1")
  2894.         for j = 1, 4 do
  2895.             for i = 1, 12 do
  2896.                 T:go("x0F1")
  2897.             end
  2898.             T:go("R1x0F1")
  2899.         end
  2900.         T:go("R1F1L1U1")
  2901.     end
  2902.     -- stage 2 place sapling and double chest
  2903.     T:dig("down") --remove cobble if present
  2904.     T:place("minecraft:dirt", -1, "down", false)
  2905.     T:go("F1R2")
  2906.     T:place("sapling", -1, "forward", false) -- plant sapling
  2907.     T:go("L1")
  2908.     T:dig("down")
  2909.     T:place("minecraft:chest", -1, "down", false)-- place chest below
  2910.     T:go("L1F1R1")
  2911.     T:dig("down")
  2912.     T:place("minecraft:chest", -1, "down", false) -- place chest 2 below
  2913.     T:turnLeft(1)
  2914.     if extend == "right" then -- cobble wall exists so go forward to its end
  2915.         T:forward(9)
  2916.     else -- new farm or extend forward
  2917.         for i = 1, 9 do -- complete left wall to end of farm
  2918.             T:go("F1x0x2C2")
  2919.         end
  2920.     end
  2921.     T:go("R1F1R1x0x2C2F1D1")-- turn round ready for first dirt col
  2922.     lib.addWaterSource({"d","c","c","d"}) -- water at top of farm
  2923.     lib.placeDirt(9, false) -- place dirt back to start
  2924.     lib.addWaterSource({"c","c","d","d"}) -- water source next to chests
  2925.     T:go("U1F1R2")
  2926.     if T:getBlockType("down") ~= "minecraft:chest" then
  2927.         T:dig("down")
  2928.         T:place("minecraft:chest", -1, "down", false)
  2929.     end
  2930.     T:go("R1F1L1")
  2931.     if T:getBlockType("down") ~= "minecraft:chest" then
  2932.         T:dig("down")
  2933.         T:place("minecraft:chest", -1, "down", false)
  2934.     end
  2935.     T:go("F1D1")
  2936.     lib.placeDirt(9, true)
  2937.     local turn = "R"
  2938.     for i = 1, 7 do
  2939.         T:go("F1U1x0C2"..turn.."1F1"..turn.."1x0x2C2F1D1")
  2940.         lib.placeDirt(9, true)
  2941.         if turn == "R" then
  2942.             turn = "L"
  2943.         else
  2944.             turn = "R"
  2945.         end
  2946.     end
  2947.     T:go("F1U1x0C2"..turn.."1F1"..turn.."1x0x2C2F1D1")
  2948.     lib.addWaterSource({"d","c","c","d"})
  2949.     lib.placeDirt(9, false)
  2950.     lib.addWaterSource({"c","c","d","d"})
  2951.     T:go("F1U1R1C2x0F1x0x2C2R1")
  2952.     for i = 1, 11 do
  2953.         T:go("F1x0x2C2")
  2954.     end
  2955.     -- add chest to any existing farm extension to the right
  2956.     T:go("L1F1L1")
  2957.     if T:getBlockType("down") ~= "minecraft:cobblestone" then -- farm extension already exists to right
  2958.         T:place("minecraft:chest", -1, "down", false) --single chest marks this as an extension
  2959.     end
  2960.     T:go("L1F11")
  2961. end
  2962.  
  2963. function createFarmExtension()
  2964.     -- assume inventory contains 4 chests, 64 cobble, 128 dirt, 4 water, 1 sapling
  2965.     -- check position by rotating to face tree/sapling
  2966.     local doContinue = true
  2967.     local treePresent = false
  2968.     local blockType = T:getBlockType("down")
  2969.     local extend = "right" -- default
  2970.     if blockType ~= "minecraft:chest" then
  2971.         T:clear()
  2972.         print("Chest not present below\n")
  2973.         print("Unable to calculate position")
  2974.         print("Move me next to/front of the tree / sapling")
  2975.         print("lower left corner of the existing farm.")
  2976.         doContinue = false
  2977.     else
  2978.         for i = 1, 4 do
  2979.             blockType = T:getBlockType("forward")
  2980.             if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil then
  2981.                 treePresent = true
  2982.                 break
  2983.             end
  2984.             T:turnRight()
  2985.         end
  2986.         if not treePresent then
  2987.             T:clear()
  2988.             print("Unable to locate tree or sapling")
  2989.             print("Plant a sapling on the lower left")
  2990.             print("corner of the farm, or move me there")
  2991.             doContinue = false
  2992.         end
  2993.     end
  2994.     if doContinue then -- facing tree. check if on front or l side of farm
  2995.         T:go("R1F1D1") -- will now be over water if at front
  2996.         if T:getBlockType("down"):find("water") == nil then
  2997.             extend = "forward"
  2998.         end
  2999.         T:go("R2U1F1L1") -- facing away from tree, either to front or right
  3000.         T:forward(9)
  3001.         -- if tree or sapling in front warn and stop
  3002.         blockType = T:getBlockType("forward")
  3003.         if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil then
  3004.             doContinue = false
  3005.         else
  3006.             T:forward(1) -- on corner ? cobble
  3007.             blockType = T:getBlockType("down")
  3008.             if blockType ~= "minecraft:cobblestone" then
  3009.                 doContinue = false
  3010.             end
  3011.         end
  3012.         if doContinue then -- extend farm.
  3013.             if extend == "right" then
  3014.                 T:turnLeft(1)
  3015.             end
  3016.             createFarm(extend)
  3017.         else
  3018.             T:clear()
  3019.             print("This farm has already been extended")
  3020.             print("Move me next to/front of the tree / sapling")
  3021.             print("of the last extension in this direction.")
  3022.         end
  3023.     end
  3024. end
  3025.  
  3026. function createFloorCeiling(width, length, size ) -- size integer 1 to 4
  3027.     local useBlock = T:getSlotContains(1)
  3028.     print("Using ".. useBlock)
  3029.     -- check if block above/below
  3030.     local blockBelow = turtle.detectDown()
  3031.     local blockAbove = turtle.detectUp()
  3032.     local direction = "down"
  3033.     if size == 1 then -- Replacing current floor
  3034.         -- if no block below, assume is missing and continue
  3035.     elseif size == 2 then -- New floor over existing
  3036.         -- if no block below, assume in correct position and continue
  3037.         -- else move up 1 and continue
  3038.         if blockBelow then T:up(1) end
  3039.     elseif size == 3 then -- Replacing current ceiling
  3040.         -- if no block above, assume is missing and continue
  3041.         direction = "up"
  3042.     elseif size == 4 then -- New ceiling under existing
  3043.         -- if no block above, assume in correct position and continue
  3044.         -- else move down 1 and continue
  3045.         if blockAbove then T:down(1) end
  3046.         direction = "up"
  3047.     end
  3048.    
  3049.     local evenWidth = false
  3050.     local evenHeight = false
  3051.     local loopWidth
  3052.     -- go(path, useTorch, torchInterval, leaveExisting)
  3053.     if width % 2 == 0 then
  3054.         evenWidth = true
  3055.         loopWidth = width / 2
  3056.     else
  3057.         loopWidth = math.ceil(width / 2)
  3058.     end
  3059.     if length % 2 == 0 then
  3060.         evenHeight = true
  3061.     end
  3062.     turtle.select(1)
  3063.     -- if width is even no, then complete the up/down run
  3064.     -- if width odd no then finish at top of up run and reverse
  3065.     for x = 1, loopWidth do
  3066.         -- Clear first column (up)
  3067.         for y = 1, length do
  3068.             T:place(useBlock, -1, direction, false) -- leaveExisting = false
  3069.             if y < length then
  3070.                 T:go("F1", false, 0, false)
  3071.             end
  3072.         end
  3073.         -- clear second column (down)
  3074.         if x < loopWidth or (x == loopWidth and evenWidth) then -- go down if on width 2,4,6,8 etc
  3075.             T:go("R1F1R1", false,0,false)
  3076.             for y = 1, length do
  3077.                 T:place(useBlock, -1, direction, false) -- leaveExisting = false
  3078.                 if y < length then
  3079.                     T:go("F1", false, 0, false)
  3080.                 end
  3081.             end
  3082.             if x < loopWidth then
  3083.                 T:go("L1F1L1", false,0,false)
  3084.             else
  3085.                 T:turnRight(1)
  3086.                 T:forward(width - 1)
  3087.                 T:turnRight(1)
  3088.             end
  3089.         else -- equals width but is 1,3,5,7 etc
  3090.             T:turnLeft(2) --turn round 180
  3091.             T:forward(length - 1)
  3092.             T:turnRight(1)
  3093.             T:forward(width - 1)
  3094.             T:turnRight(1)
  3095.         end
  3096.     end
  3097. end
  3098.  
  3099. function createHollow(width, length, height)
  3100.     -- this function currently not used
  3101.     --should be in bottom left corner at top of structure
  3102.     -- dig out blocks in front and place to the left side
  3103.     --go(path, useTorch, torchInterval, leaveExisting)
  3104.     -- go @# = place any block up/forward/down # = 0/1/2
  3105.     for h = 1, height do
  3106.         for i = 1, length - 1 do
  3107.             T:go("L1@1R1F1", false, 0, true)
  3108.         end
  3109.         T:go("L1@1R2", false, 0, true, false)
  3110.         for i = 1, width - 1 do
  3111.             T:go("L1@1R1F1", false, 0, true)
  3112.         end
  3113.         T:go("L1@1R2", false, 0, true, false)
  3114.         for i = 1, length - 1 do
  3115.             T:go("L1@1R1F1", false, 0, true)
  3116.         end
  3117.         T:go("L1@1R2", false, 0, true, false)
  3118.         for i = 1, width - 1 do
  3119.             T:go("L1@1R1F1", false, 0, true)
  3120.         end
  3121.         T:go("L1@1R2", false, 0, true, false)
  3122.         -- hollowed out, now clear water/ blocks still present
  3123.         clearRectangle(width, length)
  3124.         if h < height then
  3125.             T:down(1)
  3126.         end
  3127.     end
  3128. end
  3129.  
  3130. local function createIceCanal(length)
  3131.     local placeIce = true
  3132.     local iceOnBoard = true
  3133.     local isWater, isSource, isIce = T:isWater("forward")
  3134.     if isWater then -- user put turtle inside canal water
  3135.         T:up(1)
  3136.     end
  3137.     -- place ice on alternate blocks until length reached, run out of ice or hit a solid block.
  3138.     if length == 0 then length = 1024 end
  3139.     for i = 1, length do
  3140.         if T:getBlockType("down"):find("ice") == nil then -- no ice below
  3141.             if placeIce then
  3142.                 if not T:place("ice", -1, "down", false) then -- out of ice
  3143.                     break
  3144.                 end
  3145.                 if i == length - 1 then
  3146.                     break
  3147.                 end
  3148.             else
  3149.                 T:dig("down") -- remove any other block
  3150.             end
  3151.         else -- ice already below
  3152.             placeIce = true
  3153.         end
  3154.         if not turtle.forward() then -- movement blocked or out of fuel
  3155.             break
  3156.         end
  3157.         placeIce = not placeIce -- reverse action
  3158.     end
  3159. end
  3160.  
  3161. local function createIceCanalBorder(side, length)
  3162.     --[[ Used to convert water canal to ice with trapdoor margin on one side ]]
  3163.     -- position gained from setup left = 0, right = 1
  3164.     local A = "R"
  3165.     local B = "L"
  3166.     if side == 1 then
  3167.         A = "L"
  3168.         B = "R"
  3169.     end
  3170.     -- check position. Should be facing down canal with wall on same side
  3171.     -- so wall will be detected on i = 4 (if present)
  3172.     local turns = 0
  3173.     local wallFound = false
  3174.     for i = 1, 4 do
  3175.         if turtle.detect() then
  3176.             turns = i
  3177.             wallFound = true
  3178.         end
  3179.         T:go(A.."1")
  3180.     end
  3181.     if wallFound and turns ~= 4 then -- facing towards wall or canal
  3182.         T:go(A..turns)
  3183.     end
  3184.     redstone.setOutput("bottom", true)
  3185.     -- add trapdoors to canal towpath and activate them
  3186.     for i = 1, length do
  3187.         T:go(A.."1")
  3188.         if turtle.detectDown() then
  3189.             if T:getBlockType("down") == "minecraft:torch" then
  3190.                 turtle.digDown()
  3191.             end
  3192.         end
  3193.         if not turtle.detectDown() then -- ignore previous trapdoors of slabs
  3194.             T:place("trapdoor", -1, "down", false)
  3195.         end
  3196.         T:go(B.."1F1")
  3197.     end
  3198. end
  3199.  
  3200. local function createLadder(destination, level, destLevel)
  3201.     -- createLadder("bedrock", 70, -48)
  3202.     -- go(path, useTorch, torchInterval, leaveExisting)
  3203.     -- place(blockType, damageNo, direction, leaveExisting)
  3204.     local function placeLadder(direction, ledge)
  3205.         -- 1 check both sides and behind
  3206.         local fluid = false
  3207.         local block = T:isWaterOrLava("forward", ledge)
  3208.         if block:find("water") ~= nil or block:find("lava") ~= nil then
  3209.             --[[ surround 2 block shaft with blocks ]]
  3210.             T:go("R1C1R1C1R1C1R1F1L1C1R1C1R1C1R1C1F1R2C1x1")
  3211.         else
  3212.             --[[ no water/lava so prepare ladder site]]
  3213.             T:go("F1L1C1R1C1R1C1L1B1", false, 0, true)
  3214.         end
  3215.         if not T:place("minecraft:ladder", -1, "forward", false) then
  3216.             print("Out of ladders")
  3217.             turtle.forward()
  3218.             error()
  3219.         end
  3220.         -- 3 check if ledge, torch
  3221.         if ledge == 0 then
  3222.             T:place("common", -1, direction, false) -- any common block
  3223.         elseif ledge == 1 then
  3224.             T:place("minecraft:torch", -1, direction, false)
  3225.         elseif ledge == 2 then
  3226.             ledge = -1
  3227.         end
  3228.         return ledge
  3229.     end
  3230.    
  3231.     local ledge = 0
  3232.     local height = math.abs(destLevel - level) --height of ladder
  3233.     if destination == "surface" then -- create ladder from current level to height specified
  3234.         -- check if extending an existing ladder
  3235.         for i = 1, height do -- go up, place ladder as you go
  3236.             ledge = placeLadder("down", ledge)
  3237.             T:up(1)
  3238.             ledge = ledge + 1
  3239.         end    
  3240.     else -- ladder towards bedrock     
  3241.         local success = true
  3242.         local numBlocks, errorMsg
  3243.         for i = 1, height do -- go down, place ladder as you go
  3244.             ledge = placeLadder("up", ledge)
  3245.             --success, blocksMoved, errorMsg, blockType = clsTurtle.down(self, steps, getBlockType)
  3246.             success, numBlocks, errorMsg, blockType = T:down(1, true)
  3247.             ledge = ledge + 1
  3248.             -- if looking for stronghold then check for stone_bricks
  3249.             if blockType:find("stone_bricks") ~= nil then
  3250.                 print("Stronghold discovered")
  3251.                 break
  3252.             end
  3253.         end
  3254.         if not success then --success = false when hits bedrock
  3255.             -- test to check if on safe level immediately above tallest bedrock
  3256.             print("Bedrock reached")
  3257.             T:findBedrockTop(0)
  3258.             -- In shaft, facing start direction, on lowest safe level
  3259.             -- create a square space round shaft base, end facing original shaft, 1 space back
  3260.             T:go("L1n1R1n3R1n2R1n3R1n1", false, 0, true)
  3261.             T:go("U1Q1R1Q3R1Q2R1Q3R1Q1", false, 0, true)
  3262.         end
  3263.     end
  3264. end
  3265.  
  3266. function createLadderToWater()
  3267.     -- go down to water/lava with alternaate solid/open layers
  3268.     -- create a working area at the base
  3269.     -- Return to surface facing towards player placing ladders
  3270.     local inAir = true
  3271.     local numBlocks, errorMsg
  3272.     local block, blockType
  3273.     local height = 2
  3274.     T:go("R2D2", false, 0, true) -- face player, go down 2
  3275.     while inAir do --success = false when hits water/lava
  3276.         T:go("C1R1C1R2C1R1", false, 0, true)
  3277.         T:go("D1C1", false, 0, true)
  3278.         height = height + 1
  3279.         block, blockType = T:isWaterOrLava("down")
  3280.         if string.find(block, "water") ~= nil or string.find(block, "lava") ~= nil then
  3281.             inAir = false
  3282.         else
  3283.             T:down(1)
  3284.             height = height + 1
  3285.         end
  3286.     end
  3287.     -- In shaft, facing opposite start direction, on water/lava
  3288.     -- create a square space round shaft base, end facing original shaft, 1 space back
  3289.     T:go("R2C2F1C2F1C2R1", false, 0, true)
  3290.     T:go("F1C2F1C2R1", false, 0, true)
  3291.     T:go("F1C2F1C2F1C2F1C2R1", false, 0, true)
  3292.     T:go("F1C2F1C2F1C2F1C2R1", false, 0, true)
  3293.     T:go("F1C2F1C2F1C2F1C2R1", false, 0, true)
  3294.     T:go("F2R1F1", false, 0, true) -- under the upward pillar
  3295.  
  3296.     for i = height, 0, -1 do
  3297.         T:go("C2e1U1")
  3298.     end
  3299.     T:down(1)
  3300. end
  3301.  
  3302. function createMine()
  3303.     -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  3304.     T:clear()  
  3305.     T:go("m32U1R2M16", true, 8, true) -- mine ground level, go up, reverse and mine ceiling to mid-point
  3306.     T:go("U2D2") -- create space for chest
  3307.     T:place("minecraft:chest", -1, "up", false)
  3308.     T:emptyTrash("up")
  3309.     T:go("D1R1m16U1R2M16", true, 8, true) -- mine floor/ceiling of right side branch
  3310.     T:emptyTrash("up")
  3311.     T:go("D1m16U1R2M16", true, 8, true) -- mine floor/ceiling of left side branch
  3312.     T:emptyTrash("up")
  3313.     T:go("L1M15F1R1D1", true, 8, true) -- mine ceiling of entry coridoor, turn right
  3314.     T:go("F1x0F1x0n14R1n32R1n32R1n32R1n14F1x0F1U1", true, 8, true)-- mine floor of 36 x 36 square coridoor
  3315.     T:go("R1F16R2") --return to centre
  3316.     T:emptyTrash("up")
  3317.     T:go("F16R1") --return to entry shaft
  3318.     T:go("F2Q14R1Q32R1Q32R1Q32R1Q14F2R1", true, 8, true) --mine ceiling of 36x36 square coridoor. return to entry shaft + 1
  3319.     T:go("F16R2") --return to centre
  3320.     T:emptyTrash("up")
  3321.     -- get rid of any remaining torches
  3322.     while T:getItemSlot("minecraft:torch", -1) > 0 do
  3323.         turtle.select(T:getItemSlot("minecraft:torch", -1))
  3324.         turtle.dropUp()
  3325.     end
  3326.     T:go("F16R1F1R1") --return to shaft + 1
  3327.     for i = 1, 8 do
  3328.         T:go("N32L1F1L1", true, 8, true)
  3329.         T:go("N16L1F"..(i * 2).."R2", true, 8, true)
  3330.         T:emptyTrash("up")
  3331.         if i < 8 then
  3332.             T:go("F"..(i * 2).."L1N16R1F1R1", true, 8, true)
  3333.         else
  3334.             T:go("F"..(i * 2).."L1N16L1", true, 8, true)
  3335.         end
  3336.     end
  3337.     T:go("F17L1") -- close gap in wall, return to ladder + 1
  3338.     for i = 1, 8 do
  3339.         T:go("N32R1F1R1", true, 8, true)
  3340.         T:go("N16R1F"..(i * 2).."R2", true, 8, true)
  3341.         T:emptyTrash("up")
  3342.         if i < 8 then
  3343.             T:go("F"..(i * 2).."R1N16L1F1L1", true, 8, true)
  3344.         else
  3345.             T:go("F"..(i * 2).."R1N16R1", true, 8, true)
  3346.         end
  3347.     end
  3348.     T:go("F16R1")
  3349.     T:clear()
  3350.     print("Mining operation complete")
  3351. end
  3352.  
  3353. function createMineBase()
  3354.     T:clear()
  3355.     -- check ladder:
  3356.     T:turnRight(2)
  3357.     local blockType, modifier = T:getBlockType("forward")
  3358.     while blockType == "" do
  3359.         T:forward(1)
  3360.         blockType, modifier = T:getBlockType("forward")
  3361.     end
  3362.     if blockType ~= "minecraft:ladder" then -- in correct position
  3363.         -- no ladder, move back 1
  3364.         T:back(1)
  3365.     end
  3366.     -- build pond:
  3367.     T:go("R1F1x0L1F1x0F1x0R1") -- at side wall
  3368.     T:go("F1n4R2n4U1R2Q4R2Q4R2") -- cut pond 3x1
  3369.     T:go("C2F4C2R2F1")
  3370.     T:place("minecraft:water_bucket", 0, "down", false)
  3371.     T:forward(2)
  3372.     T:place("minecraft:water_bucket", 0, "down", false)
  3373.     T:go("F2L1F2R1F1L1") -- at start position
  3374.     --[[
  3375.     T:go("m32U1R2M16D1", true, 8) -- mine ground level, go up, reverse and mine ceiling to mid-point, drop to ground
  3376.     T:go("U1R1A15D1R2m15", false, 0) -- Create roof of coridoor, turn and create lower wall + floor
  3377.     T:go("U1A15D1R2m15U1x0", false, 0) -- Create roof of coridoor, turn and create lower wall + floor
  3378.     T:place("minecraft:chest", -1, "up", false) --place chest in ceiling
  3379.     T:emptyTrash("up")
  3380.     T:go("L1M15F1R1D1", true, 8) -- mine ceiling of entry coridoor, turn right, drop down
  3381.     T:go("F2n14R1n15", true, 8)-- mine floor of first quarter of square
  3382.     T:go("L1F1x0C1R1 F1x0L1C1R1 F1x0L1C1R1C1R1 F1x0C1L1") -- make alcove
  3383.     T:go("F1x0n14R1n32R1n15", true, 8)
  3384.     T:go("L1F1x0C1R1 F1x0L1C1R1 F1x0L1C1R1C1R1 F1x0C1L1") -- make alcove
  3385.     T:go("F1x0n14R1n14F2", true, 8)-- mine floor of last quarter of square
  3386.    
  3387.     T:go("U1R1F16R2D1") --return to centre
  3388.     T:emptyTrash("up")
  3389.     T:go("U1F16R1") --return to entry shaft
  3390.     T:go("F2Q14R1Q15", true, 8) -- mine ceiling of first quarter
  3391.     T:go("L1F1C1R1 F1L1C1R1 F1L1C1R1C1R1 F1C1L1") -- make alcove
  3392.     T:go("C0F1Q14R1Q32R1Q15", true, 8) --mine ceiling of second half
  3393.     T:go("L1F1C1R1 F1L1C1R1 F1L1C1R1C1R1 F1C1L1") -- make alcove
  3394.     T:go("C0F1Q14R1Q14F2R1", true, 8) -- mine ceiling of last quarter
  3395.     T:go("F16D1") --return to centre
  3396.     T:emptyTrash("up")
  3397.     -- get rid of any remaining torches
  3398.     while T:getItemSlot("minecraft:torch", -1) > 0 do
  3399.         turtle.select(T:getItemSlot("minecraft:torch", -1))
  3400.         turtle.dropUp()
  3401.     end
  3402.    
  3403.     for i = 1, 8 do
  3404.         T:go("N32L1F1L1", true)
  3405.         T:go("N16L1F"..(i * 2).."R2", true)
  3406.         T:emptyTrash("up")
  3407.         T:go("F"..(i * 2).."L1N16R1F1R1", true)
  3408.     end
  3409.     T:go("L1F17L1") -- close gap in wall, return to ladder + 1
  3410.     for i = 1, 8 do
  3411.         T:go("N32R1F1R1", true)
  3412.         T:go("N16R1F"..(i * 2).."R2", true)
  3413.         T:emptyTrash("up")
  3414.         T:go("F"..(i * 2).."R1N16L1F1L1", true)
  3415.     end
  3416.     -- fill water buckets
  3417.     -- return to centre
  3418.     T:go("R1F16R1")]]
  3419.    
  3420.     T:clear()
  3421.     print("Mining operation complete")
  3422. end
  3423.  
  3424. function createMineEnhanced()
  3425.     T:clear()  
  3426.     T:go("m32U1R2M16D1x2", true, 8) -- mine ground level, go up, reverse and mine ceiling to mid-point, drop to ground, excavate
  3427.     T:emptyTrash("down")
  3428.     T:go("U1R1A15D1R2E13m2x2", false, 0) -- Create roof of coridoor, turn and create lower wall + remove floor
  3429.     T:emptyTrash("down")
  3430.     T:go("U1A15D1R2E13m2x2", false, 0) -- Create roof of coridoor, turn and create lower wall + remove floor
  3431.     T:emptyTrash("down")
  3432.     T:go("U1L1M15F1R1D1", true, 8) -- mine ceiling of entry coridoor, turn right, drop down
  3433.     T:go("F2n14R1n15", true, 8)-- mine floor of first quarter of square
  3434.    
  3435.     T:go("L1F1x0C1R1 F1x0L1C1R1 F1x0L1C1R1C1R1 F1x0C1L1") -- make alcove
  3436.     T:go("F1x0n14R1n32R1n15", true, 8)
  3437.     T:go("L1F1x0C1R1 F1x0L1C1R1 F1x0L1C1R1C1R1 F1x0C1L1") -- make alcove
  3438.     T:go("F1x0n14R1n14F2", true, 8)-- mine floor of last quarter of square
  3439.     T:go("U1R1F16R2D1") --return to centre
  3440.     T:emptyTrash("down")
  3441.     T:go("U1F16R1") --return to entry shaft
  3442.     T:go("F2Q14R1Q15", true, 8) -- mine ceiling of first quarter
  3443.     T:go("L1F1C1R1 F1L1C1R1 F1L1C1R1C1R1 F1C1L1") -- make alcove
  3444.     T:go("C0F1Q14R1Q32R1Q15", true, 8) --mine ceiling of second half
  3445.     T:go("L1F1C1R1 F1L1C1R1 F1L1C1R1C1R1 F1C1L1") -- make alcove
  3446.     T:go("C0F1Q14R1Q14F2R1", true, 8) -- mine ceiling of last quarter
  3447.     T:go("F16D1") --return to centre
  3448.     T:emptyTrash("down")
  3449.     -- get rid of any remaining torches
  3450.     while T:getItemSlot("minecraft:torch", -1) > 0 do
  3451.         turtle.select(T:getItemSlot("minecraft:torch", -1))
  3452.         turtle.dropDown()
  3453.     end
  3454.     --cut access coridoors
  3455.     T:go("U1F2R1F1Q14F1 R1F1L1F1R1F2R1F1L1F1R1 F1Q14F2Q14F1 R1F1L1F1R1F2R1F1L1F1R1F1 Q14F1D1") --ceiling
  3456.     T:go("F1n14F1 R1F1L1F1R1F2R1F1L1F1R1 F1n14F2n14F1 R1F1L1F1R1F2R1F1L1F1R1F1 n14F1U1") --floor, then up
  3457.     T:go("R1F2D1")
  3458.     T:go("R1F1C1B1C1L1C1L1F1C1B1C1L1C1L2")
  3459.     T:emptyTrash("down")
  3460.     T:go("U1F16R1F1R1") --return to entry shaft + 1
  3461.  
  3462.     for i = 1, 8 do
  3463.         T:go("N32L1F1L1", true)
  3464.         if i == 1 then
  3465.             T:go("N16L1F2R2", true)
  3466.             T:emptyTrash("down")
  3467.             T:go("F2L1N16R1F1R1", true)
  3468.         elseif i == 8 then
  3469.             T:go("L1F1R1N16", true)
  3470.             T:emptyTrash("down")
  3471.             T:go("N16R1F1R1", true)
  3472.         else
  3473.             T:go("N16", true)
  3474.             T:emptyTrash("down")
  3475.             T:go("N16R1F1R1", true)
  3476.         end
  3477.     end
  3478.     T:go("L1F16L1") -- return to shaft + 1
  3479.     for i = 1, 8 do
  3480.         T:go("N32R1F1R1", true)
  3481.         if i == 1 then
  3482.             T:go("N16R1F2R2", true)
  3483.             T:emptyTrash("down")
  3484.             T:go("F2R1N16L1F1L1", true)
  3485.         elseif i == 8 then
  3486.             T:go("R1F1L1N16", true)
  3487.             T:emptyTrash("down")
  3488.             T:go("N16R1F1R1", true)
  3489.         else
  3490.             T:go("N16", true)
  3491.             T:emptyTrash("down")
  3492.             T:go("N16L1F1L1", true)
  3493.         end
  3494.     end
  3495.     T:go("L1F15R1") -- return
  3496.     T:clear()
  3497.     print("Mining operation complete")
  3498. end
  3499.  
  3500. function createMobBubbleLift(size)
  3501.     -- size = 0 or 1 (left/right)
  3502.     local lib = {}
  3503.        
  3504.     function lib.down()
  3505.         local moves = 0
  3506.         while turtle.down() do
  3507.             moves = moves + 1
  3508.         end
  3509.         return moves
  3510.     end
  3511.    
  3512.     function lib.up()
  3513.         local moves = 0
  3514.         while turtle.up() do
  3515.             moves = moves + 1
  3516.         end
  3517.         return moves
  3518.     end
  3519.     -- check if dirt or soulsand below
  3520.     local turn = "R"
  3521.     if size == 1 then
  3522.         turn = "L"
  3523.     end
  3524.     local onSand = false
  3525.     local blockType = T:getBlockType("down")
  3526.     if blockType == "minecraft:soul_sand" then
  3527.         onSand = true
  3528.     elseif blockType == "minecraft:dirt" then
  3529.         T:dig("down")
  3530.         if T:place("minecraft:soul_sand", -1, "down", false) then
  3531.             onSand = true
  3532.         end
  3533.     end
  3534.     if onSand then
  3535.         -- check facing sign, rotate if not
  3536.         blockType = T:getBlockType("forward")
  3537.         while blockType:find("sign") == nil do
  3538.             T:turnRight(1)
  3539.             blockType = T:getBlockType("forward")
  3540.         end
  3541.         for i = 1, 3 do
  3542.             -- fill in back and one side, go up
  3543.             if turn == "R" then
  3544.                 T:go("R1C1R1C1R1x1R1U1", false, 0, true)
  3545.             else
  3546.                 T:go("L1C1L1C1L1x1L1U1", false, 0, true)
  3547.             end
  3548.         end
  3549.         for i = 1, 17 do
  3550.             -- tunnel up, filling 3 sides
  3551.             if turn == "R" then
  3552.                 T:go("R1C1R1C1R1x1R1C1U1", false, 0, true)
  3553.             else
  3554.                 T:go("L1C1L1C1L1x1L1C1U1", false, 0, true)
  3555.             end
  3556.         end
  3557.         -- move either left/right 8 blocks, repairing ceiling and sides
  3558.         if turn == "R" then
  3559.             T:go("C0R2C1R1F1C0C1R1C1R2C1L1F1A8", false, 0, true) -- fill top of column
  3560.         else
  3561.             T:go("C0L2C1L1F1C0C1L1C1L2C1R1F1A8", false, 0, true) -- fill top of column
  3562.         end
  3563.         -- turn round, go down 1, forward 7 blocks repairing bottom and sides
  3564.         T:go("D1C1R2X7", false, 0, true)
  3565.         -- turn round, go up, place cobble, forward 4, place cobble
  3566.         T:go("R2U1C2F4C2", false, 0, true)
  3567.         -- turn round forward 1 place water, forward 2, place water
  3568.         T:go("R2F1", false, 0, true)
  3569.         T:place("minecraft:water_bucket", -1, "down", false)
  3570.         T:forward(2)
  3571.         T:place("minecraft:water_bucket", -1, "down", false)
  3572.         T:go("R2F1")
  3573.         repeat
  3574.             -- refill both buckets
  3575.             T:place("minecraft:bucket", -1, "down", false)
  3576.             sleep(0.5)
  3577.             T:place("minecraft:bucket", -1, "down", false)
  3578.             -- back 4, down to solid, place water,
  3579.             for i = 1, 4 do
  3580.                 turtle.back()
  3581.             end
  3582.             local moves = lib.down() -- returns no of blocks descent 0 to 19
  3583.             if moves > 0 then
  3584.                 T:place("minecraft:water_bucket", -1, "forward", false)
  3585.                 T:go("U1C2")
  3586.                 if moves > 1 then
  3587.                     T:place("minecraft:water_bucket", -1, "forward", false)
  3588.                     T:go("U1C2")
  3589.                 end
  3590.             end
  3591.             lib.up() -- 0 - 19
  3592.             T:forward(4)
  3593.         until moves <= 1
  3594.         -- delete water sources and remove cobble
  3595.         T:go("R2F3C1R2F1")
  3596.         for i = 1, 7 do -- go to end of run placing cobble
  3597.             T:go("C2F1")
  3598.         end
  3599.         T:turnRight(2)
  3600.         for i = 1, 7 do -- go to end of run, down 2
  3601.             T:go("x2F1x2")
  3602.         end
  3603.         T:go("R2F7D2")
  3604.         for i = 1, 18 do
  3605.             -- tunnel down, filling all 4 sides
  3606.             T:go("R1C1R1C1R1C1R1C1D1", false, 0, true)
  3607.         end
  3608.         -- turn round, tunnel forward 6 blocks
  3609.         T:go("R2U1F1M5D1R2F1X5")-- end up under drop column
  3610.     else
  3611.         print("Unable to find or place soulsand.\nEnter to continue")
  3612.         read()
  3613.     end
  3614. end
  3615.  
  3616. local function createMobFarmCube(blaze, continue)
  3617.     if blaze == nil then blaze = false end
  3618.     if continue == nil then continue = false end
  3619.     -- continue allows for 2-part operation 1 = main cube, 2 = rails etc
  3620.     local lib = {}
  3621.     function lib.rail(move, isPowered, count)
  3622.         if move ~= "" then
  3623.             T:go(move)
  3624.         end
  3625.         for i = 1, count do
  3626.             if isPowered then
  3627.                 if not T:place("minecraft:powered_rail", -1, "down", false) then
  3628.                     T:place("minecraft:golden_rail", -1, "down", false)
  3629.                 end
  3630.             else
  3631.                 T:place("minecraft:rail", -1, "down", false)
  3632.             end
  3633.             if i < count then
  3634.                 T:forward(1)
  3635.             end
  3636.         end
  3637.     end
  3638.    
  3639.     local brick = "minecraft:nether_brick" -- pre 1.16+ name
  3640.     if mcMajorVersion < 1.7  and mcMajorVersion >= 1.16 then -- 1.12 to 1.??
  3641.         brick = "minecraft:nether_bricks"
  3642.     end
  3643.     if not continue then -- new mob cube
  3644.         -- clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
  3645.         -- determine spawner position level 4, move to top of spawner (level 6)
  3646.         local onTop = false
  3647.         local blockType = T:getBlockType("down")
  3648.         if blockType:find("spawner") ~= nil then
  3649.             onTop = true
  3650.         end
  3651.         if not onTop then
  3652.             blockType = T:getBlockType("up")
  3653.             if blockType:find("spawner") ~= nil then
  3654.                 T:go("B1U2F1")
  3655.                 onTop = true
  3656.             end
  3657.         end
  3658.         if not onTop then
  3659.             blockType = T:getBlockType("forward")
  3660.             if blockType:find("spawner") ~= nil then
  3661.                 T:go("U1F1")
  3662.                 onTop = true
  3663.             end
  3664.         end
  3665.         if onTop then
  3666.             -- place slab on top T:place(blockType, damageNo, direction, leaveExisting)
  3667.             T:up(1)
  3668.             T:place("slab", -1, "down", true)
  3669.             -- go up 2 blocks, forward 4, right, forward 4, right
  3670.             T:go("U2F4R1F4R1")
  3671.             -- clear 9x9 and plug ceiling (level 9)
  3672.             --"Q": mine block above and/or fill void + mine block below if valuable + left side
  3673.             T:go("R2C1R2Q8R1Q8R1Q8R1Q7R1F1", false, 0, false)
  3674.             -- 7x7 rectangle filling above
  3675.             for i = 1, 3 do
  3676.                 T:go("M7R1F1R1M7L1F1L1", false, 0, false)
  3677.             end
  3678.             T:go("M7R2F8R1F7R1", false, 0, false) --back to corner
  3679.             -- mine wall:     q# mine # blocks forward, check left side and patch
  3680.             for i = 1, 2 do
  3681.                 -- down 1, clear 9x9 border, checking walls (level 8, 7)
  3682.                 T:go("D1R2C1R2q8R1q8R1q8R1q7R1F1",  false, 0, false)
  3683.                 -- clear remaining 7x7 area
  3684.                 clearRectangle(7, 7, false, false)
  3685.                 T:go("R2F1R1F1R1",  false, 0, false) --back to corner
  3686.             end
  3687.             for i = 1, 2 do
  3688.                 -- down 1, clear 9x9 border (level 6, 5)
  3689.                 T:go("D1R2C1R2q8R1q8R1q8R1q7R1",  false, 0, false)
  3690.                 T:go("F7R1F6R1F6R1F5R1",  false, 0, false)
  3691.                 T:go("F5R1F4R1F4R1F6L1F2R2",  false, 0, false)
  3692.             end
  3693.             local count = 3
  3694.             if blaze then
  3695.                 count = 2
  3696.             end
  3697.             for i = 1, count do
  3698.                 -- down 1, clear 9x9 border, checking walls (level 4, 3, (2))
  3699.                 T:go("D1R2C1R2q8R1q8R1q8R1q7R1F1")
  3700.                 -- clear remaining 7x7 area
  3701.                 clearRectangle(7, 7, false, false)
  3702.                 T:go("R2F1R1F1R1", false, 0, false) --back to corner
  3703.             end
  3704.             if blaze then
  3705.                 -- strart in top right corner. border is made of slabs placed up
  3706.                 T:go("D1R2F1R1F1R1")
  3707.                 for i = 1, 3 do
  3708.                     clearRectangle(11, 11, false, false) --layer 2, 1, 0
  3709.                     T:down(1)
  3710.                 end
  3711.                
  3712.                 T:go("R2F1R1F1R1")
  3713.                 -- ready to lay floor and border
  3714.                 -- q# mine # blocks forward, check left side and patch
  3715.                 T:go("R2C1R2 n12R1 n12R1 n12R1 n11R1F1", false, 0, false)
  3716.                 --  fill in floor 11x11 rectangle below        
  3717.                
  3718.                 local a, b, numBricks = T:getItemSlot(brick)
  3719.                 for i = 2, 12 do -- 11 iterations (rows)
  3720.                     T:go("m10", false, 0, false, brick)
  3721.                     if i % 2 == 0 then -- 2, 4, 6, 8, 10
  3722.                         if i < 12 then
  3723.                             T:go("R1F1R1", false, 0, false, brick)
  3724.                         end
  3725.                     else -- 3,5,7,9,11
  3726.                         T:go("L1F1L1", false, 0, false, brick)
  3727.                     end
  3728.                 end        
  3729.                 -- move to starting point in front of spawner,
  3730.                 -- outside retaining wall' facing in, and ask for supplies
  3731.                 T:go("L1F5U6R1F2R2")
  3732.                 continue = true -- script continues below for blaze farm
  3733.             else -- not blaze
  3734.                 -- clear floor and plug holes
  3735.                 -- n# mine block below and/or fill void + check left side
  3736.                 T:down(2)
  3737.                 for j = 1, 2 do
  3738.                     T:go("R2C1R2n8R1n8R1n8R1n7R1F1",  false, 0, true)
  3739.                     -- 7x7 rectangle filling below
  3740.                     for i = 1, 4 do
  3741.                         if i < 4 then
  3742.                             T:go("m6R1F1R1m6L1F1L1", false, 0, true)
  3743.                         else
  3744.                             T:go("m6R1F1R1m6", false, 0, true)
  3745.                         end
  3746.                     end
  3747.                     if j == 1 then
  3748.                         T:go("U1F1R1F8R1")
  3749.                     end
  3750.                 end
  3751.             end
  3752.         else -- not on top
  3753.             T:clear()
  3754.             print("Spawner not found. Place me on top,")
  3755.             print("immediately below, or facing it.")
  3756.             print("\nEnter to quit")
  3757.             read()
  3758.         end
  3759.     end
  3760.     if continue then
  3761.         T:sortInventory()
  3762.         T:turnRight(2)
  3763.         T:emptyTrashItem("forward", "minecraft:netherrack", 0)
  3764.         T:emptyTrashItem("forward", brick, 128)
  3765.         T:emptyTrashItem("forward", "fence", 0)
  3766.         T:turnRight(2)
  3767.         --clsTurtle.getItemSlot(self, item, useDamage): return slotData.lastSlot, slotData.leastModifier, total, slotData
  3768.         local a, b, numBricks = T:getItemSlot(brick)
  3769.         if numBricks < 81 then -- enough for floor
  3770.             T:checkInventoryForItem({brick, "stone"}, {81 - numBricks, 81 - numBricks})
  3771.         end
  3772.         T:checkInventoryForItem({"stone"}, {339})
  3773.         T:checkInventoryForItem({"slab"}, {36})
  3774.         T:checkInventoryForItem({"minecraft:powered_rail", "minecraft:golden_rail"}, {8, 8})
  3775.         T:checkInventoryForItem({"minecraft:rail"}, {64})
  3776.         T:checkInventoryForItem({"minecraft:redstone_torch"}, {2})
  3777.         T:checkInventoryForItem({"minecraft:hopper_minecart"}, {1})
  3778.         T:checkInventoryForItem({"minecraft:stone_button"}, {1})
  3779.         print("Stand clear. Starting in 2 secs")
  3780.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  3781.         -- return to starting point. rail laid first, bricks placed over rails
  3782.         T:go("F2L1D5F4R1")
  3783.         lib.rail("", true, 2) -- lay 2 plain rail at start
  3784.         lib.rail("F1", false, 1) -- lay 1 plain rail
  3785.         lib.rail("F1", true, 3) -- lay 3 powered rail
  3786.         T:go("L1F1")
  3787.         T:place("minecraft:redstone_torch", -1, "down", false) --place redstone torch
  3788.         lib.rail("R2F1L1F1", false, 3)
  3789.         lib.rail("R1F1R1", false, 8)
  3790.         lib.rail("L1F1L1", false, 7)
  3791.         lib.rail("R1F1R1", false, 8)
  3792.         lib.rail("L1F1L1", false, 9)
  3793.         lib.rail("R1F1R1", false, 8)
  3794.         lib.rail("L1F1L1", false, 7)
  3795.         lib.rail("R1F1R1", false, 8)
  3796.         lib.rail("L1F1L1", false, 5) -- final strip
  3797.         lib.rail("F1", true, 3)
  3798.         T:go("F1C2R1F1R1F1")
  3799.         T:place("minecraft:redstone_torch", -1, "down", false)
  3800.         T:go("R2F1L1F1L1U1")
  3801.         -- lay floor 9 x 9 rectangle filling below
  3802.         for i = 2, 10 do -- repeat 9x
  3803.             T:go("m8", false, 0, false, brick)
  3804.             if i < 10 then
  3805.                 if i % 2 == 0 then
  3806.                     T:go("R1F1R1", false, 0, false, brick)
  3807.                 else
  3808.                     T:go("L1F1L1", false, 0, false, brick)
  3809.                 end
  3810.             end
  3811.         end
  3812.         -- replace first rail with cobble and button
  3813.         T:go("R1F1R2D2x1C1B1", false, 0, false)
  3814.         T:place("minecraft:stone_button", -1, "forward", false)
  3815.         T:go("U2F2L1F1x2")
  3816.         T:place("minecraft:hopper_minecart", -1, "down", false)
  3817.         T:go("L1F1D1R2C1", false, 0, false, brick) -- cover minecart
  3818.         T:go("U1R1F2L1C0F1",false, 0, false)
  3819.         -- place slabs
  3820.         for j = 1, 4 do
  3821.             for i = 1, 9 do
  3822.                 T:place("slab", -1, "up", false)
  3823.                 T:forward(1)
  3824.             end
  3825.             if j < 4 then
  3826.                 T:go("L1C0F1")
  3827.             end
  3828.         end
  3829.         T:go("L1F1L2") -- get in position
  3830.         -- build outer edge
  3831.         for j = 1, 4 do
  3832.             for i = 1, 9 do
  3833.                 turtle.back()
  3834.                 T:place("stone", -1, "forward", false)
  3835.             end
  3836.             if j < 4 then
  3837.                 T:turnLeft(1)
  3838.                 turtle.back()
  3839.                 T:place("stone", -1, "forward", false)
  3840.             end
  3841.         end
  3842.         T:go("L1F1R2C1L1U1")
  3843.         for j = 1, 4 do
  3844.             for i = 1, 11 do
  3845.                 T:go("C0x2F1")
  3846.             end
  3847.             T:go("C0x2R1F1")
  3848.         end
  3849.         T:go("R2F2R1F1R1")
  3850.         T:go("R2C1R2Q14R1Q14R1Q14R1Q13R1D1", false, 0, false)
  3851.         T:go("L1F1R1")
  3852.         T:go("R2C1R2n14R1n14R1n14R1n13R1", false, 0, false) -- now facing in on top of outer walkway
  3853.         T:go("R1 C1U1x0 F1C1U1x0 F1C1U1x0 F1C2 F1C2 F1C2 F1C2 U1L1F1") -- back at original entrance
  3854.     end
  3855. end
  3856.  
  3857. function createMobSpawnerBase(pathLength)
  3858.     if pathLength > 0 then
  3859.         print("Building path to mob spawner base")
  3860.         createPath(pathLength)
  3861.         T:back(1)
  3862.     end
  3863.     T:place("stone", -1, "down", true)
  3864.     T:go("R1F1L1", false, 0, true)
  3865.     createPath(8)
  3866.     T:go("L1F1L1F1", false, 0, true)
  3867.     createPath(8)
  3868.     T:go("R1F1R1F1", false, 0, true)
  3869.     createPath(8)
  3870.     T:go("L1F1L1F1", false, 0, true)
  3871.     createPath(8)
  3872.     T:go("L1F2L1F1", false, 0, true)
  3873. end
  3874.  
  3875. function createMobSpawnerTower(height) 
  3876.     height = height or 2
  3877.     print("Building mob spawner base")
  3878.     -- assume placed at sea level on stone block (andesite / granite / diorite)
  3879.     --layers 2, 3 (layer 1 done at base construction)
  3880.     T:go("U1F7H2L1F1H2R1F2D1R2P1L1F1R1P1R2U1", false, 0, true)
  3881.     for i = 1, 8 do
  3882.         T:go("C2R1C1L1F1", false, 0, true)
  3883.     end
  3884.     T:go("L1F1L2C1R1F1R2C1R2", false, 0, true)
  3885.     for i = 1, 8 do
  3886.         T:go("C2R1C1L1F1", false, 0, true)
  3887.     end
  3888.     T:go("U1R2F8R1", false, 0, true)
  3889.     T:place("minecraft:water_bucket", -1, "down", false)
  3890.     T:go("F1R1", false, 0, true)
  3891.     T:place("minecraft:water_bucket", -1, "down", false)
  3892.     T:forward(16)
  3893.     T:go("R1F1D2", false, 0, true)
  3894.     for i = 1, 2 do
  3895.         sleep(0.5)
  3896.         T:place("minecraft:bucket", -1, "down", false)
  3897.     end
  3898.     T:go("R1F2", false, 0, true)
  3899.     for i = 1, 2 do
  3900.         T:go("C1R1C1R2C1R1U1")
  3901.     end
  3902.     -- height of tower
  3903.     height = math.ceil(height / 2)
  3904.     for i = 1, height do
  3905.         T:go("C1U1C1R1C1R1C1R1C1R1U1")
  3906.     end
  3907.     -- create platform for player
  3908.     T:go("R2F1L1C1R1C1R1C1U1C1L1C1L1C1L1F1L1C!R2C1L1U1F1", false, 0, true)
  3909.     -- place stone marker
  3910.     T:place("stone", -1, "down")
  3911.     -- will need to move back before completing
  3912. end
  3913.  
  3914. function createMobSpawnerTank()
  3915.     --layer 1 of tower + walkway
  3916.     -- move back 1 block before continuing with tower top and walkway
  3917.     T:go("R2F1R2")
  3918.     T:go("C1U2R1F1L1") -- now dropping cobble from above
  3919.     T:go("m10L1F1L1")
  3920.     T:go("m9R1F1L1F1C2F1L1F1C2L1F1")
  3921.     --layer 2
  3922.     T:go("U1F1C2R1F1C2F1L1F1m8L1F3L1m8F2L1F1L1")
  3923.     --layer 3
  3924.     T:go("U1R1F1C2L1F1C2")
  3925.     T:go("F1R1F1L1C2F1C2F1L1F1C2")
  3926.     T:go("F1C2F1L1F1C2F1C2F2C2F1")
  3927.     T:go("L1F1C2L1F2C2B1")
  3928.     --layer 4
  3929.     T:go("U1F1L1F1R2")
  3930.     for i = 1, 4 do
  3931.         T:go("F1C2F1C2F1L1")
  3932.     end
  3933.     T:go("F1R1F1R2")
  3934.     --layer 5
  3935.     T:go("U1R2F1m7L1F1L1C2F1C2F7C2F1C2")
  3936.     T:go("F1R1F1L1C2F1C2F1L1F1C2F1C2F1")
  3937.     T:go("L1F1C2F1C2F2C2L1F1L1F1C2R2F1R2")
  3938.     -- layer 6
  3939.     T:go("U1R2F9C2L1F1C2F1L1F1C2F1L1F1C2R1F8L1F2R2")
  3940.     for i = 1, 4 do
  3941.         T:go("F1C2F1C2F1L1")
  3942.     end
  3943.     T:go("F1L1F1")
  3944.     T:place("minecraft:water_bucket", -1, "down")
  3945.     T:go("R1F1L1")
  3946.     T:place("minecraft:water_bucket", -1, "down")
  3947.     T:go("R2F2R1F1R1")
  3948.     -- layer 7
  3949.     T:go("U1R2F8L1F2C2L1F1L1F1C2R1F7C2L1F2R1C2F1R1")
  3950.     for i = 1, 4 do
  3951.         T:go("F1C2F1C2F1L1")
  3952.     end
  3953.     T:go("F1R1F1R2")
  3954.     T:go("F2")
  3955.     -- place stone inside column, ready for temp water source
  3956.     T:place("stone", -1, "down", false)
  3957.    
  3958.     -- layer 8
  3959.     -- make temp water source in centre. destroy in createMobSpawnerRoof()
  3960.     T:go("F1C2R1F1C2R1F1C2F1R1F2U1R2")
  3961.     -- spiral construction
  3962.     for j = 3, 9, 2 do
  3963.         for i = 1, 4 do
  3964.             if i < 4 then
  3965.                 T:go("m"..j.."L1")
  3966.             else
  3967.                 T:go("m"..j.."F1R1F1L2")
  3968.             end
  3969.         end
  3970.     end
  3971.     -- fill water source
  3972.     T:go("F5L1F5")
  3973.     T:place("minecraft:water_bucket", -1, "down", false)
  3974.     T:go("F1R1F1R1")
  3975.     T:place("minecraft:water_bucket", -1, "down", false)
  3976.     T:go("F5m4F2C2F1R1F1C2F1R1F1C2F1R1F1L1C2F1m4")
  3977.     T:go("F8F2m3R1F1R1m3")
  3978.     T:go("F5L1F5m3R1F1R1m3")
  3979.     T:go("F9F2m3R1F1R1m3")
  3980.     -- layer 9
  3981.     T:up(1)
  3982.     for i = 1, 4 do
  3983.         T:go("L1F1L1m3R1F1R1m3L1F1L1m3R1F1R1m3F4")
  3984.         T:go("L1F1L1m7R1F1R1m7L1F1L1m7R1F1R1m7F1L1F1R1C2F1C2R1F4")
  3985.     end
  3986.     -- now add water
  3987.     T:go("F6")
  3988.     for i = 1, 4 do
  3989.         T:down(1)
  3990.         T:place("minecraft:bucket", -1, "down", false)
  3991.         sleep(0.5)
  3992.         T:place("minecraft:bucket", -1, "down")
  3993.         T:go("U1F8R1")
  3994.         T:place("minecraft:water_bucket", -1, "down", false)
  3995.         T:go("F1R1")
  3996.         T:place("minecraft:water_bucket", -1, "down", false)
  3997.         T:go("F8L1")
  3998.     end
  3999.     for i = 1, 2 do
  4000.         T:down(1)
  4001.         T:place("minecraft:bucket", -1, "down", false)
  4002.         sleep(0.5)
  4003.         T:place("minecraft:bucket", -1, "down", false)
  4004.         T:go("U1F4L1F4L1")
  4005.         T:place("minecraft:water_bucket", -1, "down", false)
  4006.         T:go("F9")
  4007.         T:place("minecraft:water_bucket", -1, "down", false)
  4008.         T:go("L1F5L1F4L2")
  4009.     end
  4010.     T:go("F9R1F10R1")
  4011.     -- layer 10 / 11
  4012.     for j = 1, 2 do
  4013.         T:go("U1F1m8L1F1C2F1R1F1C2F1R1F1C2F1R1F1R2m8F1R1")
  4014.         for i = 1, 3 do
  4015.             T:go("F1m17F1R1")
  4016.         end
  4017.     end
  4018.     T:go("F10R1F9D4")
  4019. end
  4020.  
  4021. function createMobSpawnerRoof()
  4022.     -- destroy water source first
  4023.     T:go("x2C1R1F1x2L1F1x2L1F1x2L1F1x2L2")
  4024.     T:go("U5L1F8L1F8L2") -- top left corner facing e
  4025.     T:go("m17R1m17R1m17R1m17") -- outer ring. ends facing n
  4026.     T:go("R1F2R1F1L1") -- facing e
  4027.     for i = 1, 4 do -- outer ring - 1 (with torches) ends facing e
  4028.         T:go("m6t1m3t1m5R1F1t1")
  4029.     end
  4030.     T:go("R1F1L1") -- facing e
  4031.     for i = 1, 4 do -- outer ring - 2 ends facing e
  4032.         T:go("m13R1m13R1m13R1m13")
  4033.     end
  4034.     T:go("R1F1L1") -- ends facing e
  4035.     T:go("m11R1m11R1m11R1m11") -- ends facing e
  4036.     T:go("R1F1R1F1L1F1")
  4037.     for i = 1, 4 do
  4038.         T:go("m8R1F1t1")
  4039.     end
  4040.     T:go("R1F1L1")
  4041.     T:go("m7R1m7R1m7R1m7")
  4042.     T:go("R1F1R1F1L1")
  4043.     T:go("m5R1m5R1m5R1m5")
  4044.     T:go("R1F1R1F1L1F1")
  4045.     for i = 1, 4 do
  4046.         T:go("m2R1F1t1")
  4047.     end
  4048.     T:go("R1F1L1")
  4049.     T:go("m1R1m1R1m1R1m1")
  4050. end
  4051.  
  4052. function createPlatform(width, length)
  4053.     local forward = true
  4054.     for w = 1, width do
  4055.         for l = 1, length do
  4056.             T:go("x2C2", false, 0, true)
  4057.             if l < length then
  4058.                 T:go("F1", false, 0, true)
  4059.             end
  4060.         end
  4061.         if w < width then
  4062.             if forward then
  4063.                 T:go("R1F1R1", false, 0, true)
  4064.             else
  4065.                 T:go("L1F1L1", false, 0, true)
  4066.             end
  4067.         end
  4068.         forward = not forward
  4069.     end
  4070. end
  4071.  
  4072. function createPortal(width, height)
  4073.     T:go("D1x1", false, 0, true)
  4074.     T:place("minecraft:cobblestone", 0, "forward", true)
  4075.     for i = 1, height - 1 do
  4076.         T:go("U1x1", false, 0, true)
  4077.         T:place("minecraft:obsidian", 0, "forward", true)
  4078.     end
  4079.     T:go("U1x1", false, 0, true)
  4080.     T:place("minecraft:cobblestone", 0, "forward", true)
  4081.     for i = 1, width - 1  do
  4082.         T:go("R1F1L1x1")
  4083.         T:place("minecraft:obsidian", 0, "forward", true)
  4084.     end
  4085.     T:go("R1F1L1x1", false, 0, true)
  4086.     T:place("minecraft:cobblestone", 0, "forward", true)
  4087.     for i = 1, height - 1 do
  4088.         T:go("D1x1")
  4089.         T:place("minecraft:obsidian", 0, "forward", true)
  4090.     end
  4091.     T:go("D1x1", false, 0, true)
  4092.     T:place("minecraft:cobblestone", 0, "forward", true)
  4093.     for i = 1, width - 1 do
  4094.         T:go("L1F1R1x1")
  4095.         T:place("minecraft:obsidian", 0, "forward", true)
  4096.     end
  4097.     T:go("U1L1F1R1", false, 0, true)
  4098. end
  4099.  
  4100. local function createPortalPlatform()
  4101.     --[[ Used in End World to use minecarts to carry player through portal ]]
  4102.     local lib ={}
  4103.    
  4104.     function lib.findPortal()
  4105.         local found = false
  4106.         local onSide = false
  4107.         for i = 1, 64 do
  4108.             if not turtle.up() then -- hit block above
  4109.                 found = true
  4110.                 break
  4111.             end
  4112.         end
  4113.         if found then
  4114.             -- are we under the centre block, or one of the sides?
  4115.             if turtle.detect() then -- under a side
  4116.                 onSide = true
  4117.             else    -- nothing in front, probably under centre, or facing wrong direction so check
  4118.                 for i = 1, 4 do
  4119.                     turtle.turnRight()
  4120.                     if turtle.detect() then
  4121.                         onSide = true
  4122.                         break
  4123.                     end
  4124.                 end
  4125.             end
  4126.             if onSide then-- move to centre
  4127.                 T:go("D1F1")
  4128.             end
  4129.         end
  4130.         local height = 3 -- allows for 2 bedrock + starting space
  4131.         while turtle.down() do
  4132.             height = height + 1
  4133.         end
  4134.         return found, height
  4135.     end
  4136.    
  4137.     function lib.addFloor(length)
  4138.         for i = 1, length do
  4139.             if i < length then
  4140.                 T:go("C2F1", false, 0, true)
  4141.             else
  4142.                 T:go("C2", false, 0, true)
  4143.             end
  4144.         end
  4145.     end
  4146.    
  4147.     function lib.buildLadder(height)
  4148.         for i = 1, height do
  4149.             T:go("F1C1 R1C1 L2C1 L1F1L2", false, 0, true)
  4150.             if i > 3 then
  4151.                 T:go("C2")
  4152.             end
  4153.             T:place("minecraft:ladder", 0, "forward", true)
  4154.             T:up(1)
  4155.         end
  4156.     end
  4157.    
  4158.     local found, height = lib.findPortal()
  4159.     if found then   -- position under centre of beacon
  4160.         -- build ladder up and create platform
  4161.         T:go("L1F1L1F2L2")
  4162.         T:checkInventoryForItem({"minecraft:ladder"},{height})
  4163.         T:checkInventoryForItem({"stone"},{height * 4 + 40})
  4164.         lib.buildLadder(height)
  4165.  
  4166.         T:go("F1R1F4R2")            -- turn right, forward 4, reverse
  4167.         for i = 1, 5 do             -- build 7 x 5 platform
  4168.             lib.addFloor(7)         -- forward place block above to 7 blocks
  4169.             if i == 1 or i % 2 == 1 then -- 1,3,5,7
  4170.                 T:go("L1F1L1")
  4171.             else
  4172.                 T:go("R1F1R1")
  4173.             end
  4174.         end
  4175.         T:go("F3L1F4")          -- facing portal entrance, 1 block short
  4176.         T:place("minecraft:rail", -1, "forward", false)
  4177.         T:go("U1R2")
  4178.         T:place("minecraft:rail", -1, "down", false)
  4179.         T:forward(1)
  4180.         if not T:place("minecraft:powered_rail", -1, "down", false) then
  4181.             T:place("minecraft:golden_rail", -1, "down", false)
  4182.         end
  4183.         T:go("F1C2 U1R2C2 F1")
  4184.         T:place("minecraft:minecart", -1, "down", false)
  4185.         T:go("F1R2D1")
  4186.         T:place("minecraft:stone_button", -1, "forward", false)
  4187.     else
  4188.         print("Portal not found. Move me under\nthe centre if possible. \n(wait for purple beacon.")
  4189.     end
  4190. end
  4191.  
  4192. local function createRailwayDown(drop)
  4193.     -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4194.     if drop == 0 then
  4195.         local blockTypeD = T:getBlockType("down")
  4196.         while blockTypeD == "" do
  4197.             T:go("F1D1", false, 0, true)
  4198.             blockTypeD = T:getBlockType("down")
  4199.             if blockTypeD == "" then
  4200.                 T:go("C2", false, 0, true)
  4201.             end
  4202.         end
  4203.     else
  4204.         for i = 1, drop - 1 do
  4205.             T:go("F1D1C2", false, 0, false)
  4206.         end
  4207.     end
  4208. end
  4209.  
  4210. function createRailwayUp(up)
  4211.     for i = 1, up do
  4212.         T:go("C1U1F1", false, 0, false)
  4213.     end
  4214. end
  4215.  
  4216. function createRetainingWall(length, height)
  4217.     local place = false
  4218.     if height <= 0 then
  4219.         height = 30
  4220.     end
  4221.     local inWater = false
  4222.     for i = 1, 4 do
  4223.         if string.find(T:getBlockType("forward"), "water") ~= nil then
  4224.             inWater = true
  4225.         end
  4226.         T:turnRight(1)
  4227.     end
  4228.    
  4229.     local y = 1
  4230.     -- go(path, useTorch, torchInterval, leaveExisting)
  4231.     -- start at surface, move back 1 block
  4232.     -- each iteration completes 3 columns
  4233.     local numBlocks = T:getSolidBlockCount()
  4234.     print("Solid blocks in inventory: "..numBlocks)
  4235.    
  4236.     if not inWater then
  4237.         T:down(1)
  4238.     end
  4239.     place = clearVegetation("down") -- returns true if air, water or lava below
  4240.     if length == 1 then --single column
  4241.         local place = clearVegetation("down")
  4242.         while place do -- loop will be entered at least once
  4243.             T:down(1)
  4244.             y = y + 1
  4245.             place = clearVegetation("down")
  4246.         end
  4247.         for i = 1, y - 1  do
  4248.             T:go("U1C2", false, 0, true, false)
  4249.         end
  4250.     elseif length == 2 then--down then up
  4251.         T:back(1) -- move 1 block away from wall edge
  4252.         local place = clearVegetation("down")
  4253.         while place do -- loop will be entered at least once
  4254.             T:go("C1D1", false, 0, true, false)
  4255.             y = y + 1
  4256.             place = clearVegetation("down")
  4257.         end
  4258.         T:forward(1) -- in case col in front is deeper
  4259.         place = clearVegetation("down")
  4260.         while place do -- loop will be entered at least once
  4261.             T:down(1)
  4262.             y = y + 1
  4263.             place = clearVegetation("down")
  4264.         end
  4265.         T:go("B1C1", false, 0, true)
  4266.         for i = 1, y - 1 do
  4267.             T:go("U1C2", false, 0, true)
  4268.         end
  4269.         T:go("C1", false, 0, true, false)
  4270.     else -- length 3 or more eg 3,22; 11
  4271.         local remain = length % 3 -- 0; 1; 2 only possible results
  4272.         length = length - remain -- 3-0=3; 4-1=3; 5-2=3; 6-0=6
  4273.         for i = 3, length, 3 do -- 3, 6, 9, 12 etc
  4274.             numBlocks = T:getSolidBlockCount()
  4275.             print("Solid blocks in inventory: "..numBlocks)
  4276.             if numBlocks < height * 3 then
  4277.                 --ask player for more
  4278.                 T:checkInventoryForItem({"stone"}, {height * 3}, false)
  4279.             end
  4280.             T:go("B1C1", false, 0, true)
  4281.             if i > 3 then -- second iteration
  4282.                 T:go("B1C1")
  4283.             end
  4284.             -- place blocks forward while descending
  4285.             place = clearVegetation("down")
  4286.             while place do -- loop will be entered at least once
  4287.                 T:go("C1D1", false, 0, true)
  4288.                 y = y + 1
  4289.                 place = clearVegetation("down")
  4290.             end
  4291.             T:forward(1) -- in case col in front is deeper
  4292.             place = clearVegetation("down")
  4293.             while place do -- loop will be entered at least once
  4294.                 T:down(1)
  4295.                 y = y + 1
  4296.                 place = clearVegetation("down")
  4297.             end
  4298.             while not turtle.detectUp() do  -- go up until column base is met
  4299.                 T:go("U1C2")
  4300.                 y = y - 1
  4301.                 if y < 0 then
  4302.                     break
  4303.                 end
  4304.             end
  4305.             T:go("B1C1B1", false, 0, true)
  4306.             -- return to surface, placing forward and below
  4307.             for i = 1, y - 1 do
  4308.                 T:go("C1U1C2", false, 0, true)
  4309.             end
  4310.             -- put missing block down
  4311.             T:go("C1", false, 0, true)
  4312.             y = 1 -- reset counter
  4313.         end
  4314.         if remain == 1 then -- 1 more column
  4315.             y = 1
  4316.             T:back(1)
  4317.             place = clearVegetation("down")        
  4318.             while place do -- loop will be entered at least once
  4319.                 T:down(1)
  4320.                 y = y + 1
  4321.                 place = clearVegetation("down")
  4322.             end
  4323.             for i = 1, y - 1 do
  4324.                 T:go("U1C2", false, 0, true)
  4325.             end
  4326.             -- put missing block down
  4327.             T:go("C1", false, 0, true)
  4328.         elseif remain == 2 then -- 2 cols
  4329.             y = 1
  4330.             T:back(1)
  4331.             place = clearVegetation("down")
  4332.             while place do -- loop will be entered at least once
  4333.                 T:go("C1D1", false, 0, true)
  4334.                 y = y + 1
  4335.                 place = clearVegetation("down")
  4336.             end
  4337.             T:forward(1)
  4338.             place = clearVegetation("down")
  4339.             while place do
  4340.                 T:down(1)
  4341.                 y = y + 1
  4342.                 place = clearVegetation("down")
  4343.             end
  4344.             T:go("B1C1", false, 0, true)
  4345.             for i = 1, y - 1 do
  4346.                 T:go("U1C2", false, 0, true)
  4347.             end
  4348.             -- put missing block down
  4349.             T:go("C1", false, 0, true)
  4350.         end
  4351.     end
  4352. end
  4353.  
  4354. local function createSafeDrop(height)
  4355.     -- dig down height blocks, checking for blocks on all sides
  4356.     local drop = 0
  4357.     T:down(2)
  4358.     drop = 2
  4359.     for i = 1, height - 1 do
  4360.         for j = 1, 4 do
  4361.             -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4362.             T:go("C1R1", false, 0, true)
  4363.         end
  4364.         if T:down(1) then
  4365.              drop = drop + 1
  4366.         end
  4367.         if T:isWaterOrLava("up") ~= "" then
  4368.             T:go("C0x0", false, 0, false) -- delete water/ lava block
  4369.         end
  4370.     end
  4371.     T:go("U1R2x1")
  4372.     --place(blockType, damageNo, direction, leaveExisting, signText)
  4373.     T:place("minecraft:water_bucket", -1, "down", false)
  4374.     T:go("U1x1")
  4375.     T:up(drop - 2)
  4376. end
  4377.  
  4378. function createSandWall(length)
  4379.     length = length or 0
  4380.     local success = true
  4381.     --move above water
  4382.     local maxMove = 2
  4383.     while turtle.detectDown() and maxMove > 0 do
  4384.         T:forward(1)
  4385.         maxMove = maxMove - 1
  4386.     end
  4387.     if length > 0 then
  4388.         for i = 1, length - 1 do
  4389.             success = dropSand()
  4390.             T:forward(1, false)
  4391.         end
  4392.         success = dropSand()
  4393.     else
  4394.         while not turtle.detectDown() do -- over water
  4395.             while not turtle.detectDown() do -- nested to allow forward movement
  4396.                 success = dropSand() -- drops sand and checks supplies
  4397.             end
  4398.             if success then
  4399.                 T:forward(1, false)
  4400.             else -- out of sand
  4401.                 break
  4402.             end
  4403.         end
  4404.     end
  4405. end
  4406.  
  4407. function createSinkingPlatform(width, length, height)
  4408.     local lib = {}
  4409.     function lib.stage1a()
  4410.         for l = 1, length do
  4411.             if l == 1 then
  4412.                 T:go("L1C1R1C2U1C2D1F1C2", false, 0, true)
  4413.             elseif l < length then
  4414.                 T:go("L1C1R1C2F1C2", false, 0, true)
  4415.             else
  4416.                 T:go("L1C1R1C2C1U1C2D1", false, 0, true)
  4417.             end
  4418.         end
  4419.     end
  4420.    
  4421.     function lib.stage1b()
  4422.         for l = 1, length do
  4423.             if l == 1 then
  4424.                 T:go("R1C1L1C2U1C2D1F1C2", false, 0, true)
  4425.             elseif l < length then
  4426.                 T:go("R1C1L1C2F1C2", false, 0, true)
  4427.             else
  4428.                 T:go("R1C1L1C2C1U1C2D1", false, 0, true)
  4429.             end
  4430.         end
  4431.     end
  4432.    
  4433.     function lib.stage2(forward)
  4434.         if forward then
  4435.             T:go("C1R1F1L1C1R2", false, 0, true)
  4436.         else
  4437.             T:go("C1L1F1R1C1L2", false, 0, true)
  4438.         end
  4439.     end
  4440.        
  4441.     local forward = true
  4442.     local goingRight = true
  4443.     for h = 1, height do
  4444.         T:down(1) -- move down into existing platform
  4445.         if goingRight then -- first side
  4446.             if forward then
  4447.                 -- complete left side
  4448.                 T:go("R2C1L2", false, 0, true) -- block 1, 1
  4449.                 lib.stage1a()
  4450.                 -- turn ready for next side
  4451.                 T:go("R1F1L1C1R2C2")
  4452.             else
  4453.                 T:go("L2C1R2", false, 0, true) -- block 1, 1
  4454.                 lib.stage1b()
  4455.                 -- turn ready for next side
  4456.                 T:go("L1F1R1C1L2C2")
  4457.             end
  4458.         else -- on right side so different approach
  4459.             if forward then
  4460.                 T:go("L2C1R2", false, 0, true) -- block 1, 1
  4461.                 lib.stage1b()
  4462.                 -- turn ready for next side
  4463.                 T:go("C1L1F1R1C1L2C2")
  4464.             else
  4465.                 -- complete left side
  4466.                 T:go("R2C1L2", false, 0, true) -- block 1, 1
  4467.                 lib.stage1a()
  4468.                 -- turn ready for next side
  4469.                 T:go("C1R1F1L1C1R2C2")
  4470.             end
  4471.         end
  4472.         forward = not forward
  4473.         -- continue strips across until at far edge
  4474.         for w = 1, width - 2 do
  4475.             for l = 1, length do
  4476.                 if l < length then
  4477.                     T:go("C2F1", false, 0, true)
  4478.                 else
  4479.                     T:go("C2", false, 0, true)
  4480.                 end
  4481.             end
  4482.             if goingRight then
  4483.                 lib.stage2(forward)
  4484.             else
  4485.                 lib.stage2(not forward)
  4486.             end
  4487.             forward = not forward
  4488.         end
  4489.         -- far side
  4490.         if goingRight then
  4491.             if forward then
  4492.                 lib.stage1b()
  4493.             else
  4494.                 lib.stage1a()
  4495.             end
  4496.         else
  4497.             if forward then
  4498.                 lib.stage1a()
  4499.             else
  4500.                 lib.stage1b()
  4501.             end
  4502.         end
  4503.         goingRight = not goingRight
  4504.         T:turnRight(2)
  4505.         forward = not forward
  4506.     end
  4507. end
  4508.  
  4509. function createSolid(width, length, height)
  4510.     -- this function currently not used
  4511.     for i = 1, width do --width could be 1, 2, 3 etc
  4512.         createRetainingWall(length, height)
  4513.         if i < width then --width = 2 or more
  4514.             if i == 1 or i % 2 == 1 then -- iteration 1, 3, 5
  4515.                 T:go("L1F1L2C1R1", false, 0, true)
  4516.             else
  4517.                 T:go("R1F1R2C1L1", false, 0, true)
  4518.             end
  4519.         end
  4520.     end
  4521. end
  4522.  
  4523. local function createStaircase(destination, currentLevel, destLevel)
  4524.     -- R# L# F# B# U# D# +0 -0 = Right, Left, Forward, Back, Up, Down, up while detect and return, down while not detect
  4525.     -- dig:           x0,x1,x2 (up/fwd/down)
  4526.     -- suck:          s0,s1,s2
  4527.     -- place chest:   H0,H1,H2
  4528.     -- place sapling: S0,S1,S2
  4529.     -- place Torch:   T0,T1,T2
  4530.     -- place Hopper:  P0,P1,P2
  4531.     -- mine floor:    m# = mine # blocks above and below, checking for valuable items below, and filling space with cobble or dirt
  4532.     -- mine ceiling:  M# = mine # blocks, checking for valuable items above, and filling space with cobble or dirt
  4533.     -- mine ceiling:  N# same as M but not mining block below unless valuable
  4534.     -- 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
  4535.    
  4536.     -- 3| |B| |
  4537.     --   - - -
  4538.     -- 2|A| |C|
  4539.     --   - - -
  4540.     -- 1|^|D| |
  4541.     --   - - -
  4542.     --   1 2 3
  4543.     local function checkFluids()
  4544.         local isFluid = false
  4545.         -- check if water or lava present
  4546.         for i = 1, 4 do
  4547.             blockType = T:isWaterOrLava("forward")
  4548.             if blockType:find("lava") ~= nil or blockType:find("water") ~= nil then
  4549.                 isFluid = true
  4550.             end
  4551.         end
  4552.         return isFluid
  4553.     end
  4554.    
  4555.     local function createStaircaseSection(onGround)
  4556.         -- start 1,1,1, n
  4557.         -- stage A
  4558.         local isFluid = checkFluids()
  4559.         local blockType = ""
  4560.         local data = T:getStock("stairs")
  4561.         if data.total == 0 then
  4562.             T:craft('stairs', 4)
  4563.         end
  4564.         if onGround and isFluid then
  4565.             -- add right side and block entrance
  4566.             T:go("R1C1R1C1R2")
  4567.         end
  4568.         if isFluid then
  4569.             T:go("L1C1 R1F1C2 L1C1 R1x1 R1C1 L1C2B1 C1x1 ^1C2", false, 0, true) --start:1,1,1,n stairs A on level 1, going back to 1,1,1,n
  4570.         else
  4571.             T:go("F1x1 R1C1 L1C2B1 ^1C2", false, 0, true)
  4572.         end
  4573.         if not onGround then
  4574.             -- stage A1
  4575.             T:go("L2C1L2", false, 0, true) -- start 1,1,1,n fix corner on level 1 end: 1,1,1,n
  4576.         end
  4577.         -- stage B
  4578.         T:go("U1L1", false, 0, true) -- end  1,1,1,w layer 2
  4579.         isFluid = checkFluids()
  4580.         if isFluid then
  4581.             T:go("C1", false, 0, true) -- end  1,1,1,w layer 2
  4582.         end
  4583.         if not onGround then
  4584.             if isFluid then
  4585.                 T:go("L1C1R1", false, 0, true) -- end  1,1,1,w layer 2
  4586.             end
  4587.         end
  4588.         -- stage C1
  4589.         if isFluid then
  4590.             T:go("R1C1F1C1x1 L1C1 R2C1 L1B1", false, 0, true)
  4591.         else
  4592.             T:go("R1F1 R1C1 L1B1", false, 0, true)
  4593.         end
  4594.         -- stage C2
  4595.         T:go("U1")
  4596.         isFluid = checkFluids()
  4597.         if isFluid then
  4598.             T:go("L1C1L1 C1L2 C1F1L1 C1R2 C1L1 B1C2D1", false, 0, true) -- end 1,1,2,n
  4599.         else
  4600.             T:go("F1R1 C1L1 B1D1", false, 0, true) -- end 1,1,2,n
  4601.         end
  4602.         onGround = false
  4603.         -- stage D
  4604.         isFluid = checkFluids()
  4605.         if isFluid then
  4606.             T:go("C1F1C1F1C1x1L1 C1R1 C1R1", false, 0, true) -- 3,1,2,e
  4607.         else
  4608.             T:go("F2 C1R1", false, 0, true) -- 3,1,2,e
  4609.         end
  4610.        
  4611.         return onGround
  4612.     end
  4613.  
  4614.     --local height = currentLevel -- eg 64 at top or 5 at bedrock
  4615.     local data = T:getStock("stairs")
  4616.     --{rt.total, rt.mostSlot, rt.leastSlot, rt.mostCount, rt.leastCount}
  4617.     local numStairs = data.total
  4618.     local range = math.abs(destLevel - currentLevel)
  4619.     local numStairsNeeded = range
  4620.     numStairsNeeded = numStairsNeeded - numStairs
  4621.     if numStairsNeeded > 40 then
  4622.         print('crafting '..numStairsNeeded..' : '..numStairs.. ' in stock')
  4623.         T:craft('stairs', 40)   -- max 40 so repeat
  4624.         data = T:getStock("stairs")
  4625.         if data.total == 0 then
  4626.             data = T:getStock("stairs")
  4627.         end
  4628.         numStairs = data.total
  4629.         numStairsNeeded = numStairsNeeded - numStairs
  4630.     end
  4631.     if numStairsNeeded >  0 then
  4632.         T:craft('stairs', numStairsNeeded)
  4633.     end
  4634.     local height = 0
  4635.     if destination == "bedrock" then -- go down towards bedrock
  4636.         local atBedrock = false
  4637.         for i = 1, range do
  4638.             height = height - 1
  4639.             if not T:down() then
  4640.                 atBedrock = true
  4641.                 break
  4642.             end
  4643.         end
  4644.         if atBedrock then -- hit bedrock so get to level 5 / -59
  4645.             height = T:findBedrockTop(height)
  4646.             T:go("R1F1R1", false, 0, true)
  4647.         end
  4648.     end
  4649.     local onGround = true
  4650.     height = 0
  4651.     while height < range do
  4652.         for x = 1, 4 do
  4653.             onGround = createStaircaseSection(onGround)
  4654.         end
  4655.         height = height + 4
  4656.     end
  4657. end
  4658.  
  4659. function createTreefarm(size)
  4660.     local blockType
  4661.     local blockModifier
  4662.     local length
  4663.     local width
  4664.    
  4665.     if size == 1 then
  4666.         length = 11
  4667.         width = 6
  4668.         clearArea(11, 11)
  4669.     else
  4670.         length = 19
  4671.         width = 10
  4672.         clearArea(19, 19)
  4673.     end
  4674.     -- now place dirt blocks and torches
  4675.     T:go("F2R1F2L1U1", false, 0, true)
  4676.     for x = 1, (width - 2) / 2 do
  4677.         for y = 1, (length - 3) / 2 do
  4678.             T:place("minecraft:dirt", -1, "down", false)
  4679.             if y < (length - 3) / 2 then
  4680.                 T:forward(1)
  4681.                 T:place("minecraft:torch", -1, "down", false)
  4682.                 T:forward(1)
  4683.             end
  4684.         end
  4685.         T:go("R1F2R1", false, 0, true)
  4686.         for y = 1, (length - 3) / 2 do
  4687.             T:place("minecraft:dirt", -1, "down", false)
  4688.             if y < (length - 3) / 2 then
  4689.                 T:forward(1)
  4690.                 T:place("minecraft:torch", -1, "down", false)
  4691.                 T:forward(1)
  4692.             end
  4693.         end
  4694.         if x < (width - 2) / 2 then
  4695.             T:go("L1F2L1", false, 0, true)
  4696.         else
  4697.             T:go("R1F6", false, 0, true)
  4698.             if size == 2 then
  4699.                 T:go("F8", false, 0, true)
  4700.             end
  4701.             T:go("R1B1", false, 0, true)
  4702.         end
  4703.     end
  4704. end
  4705.  
  4706. function createWalkway(length)
  4707.     local lengthParts = math.floor(length / 8) -- eg 12/8 = 1
  4708.     local lastPart = length - (lengthParts * 8) -- eg 12 - (1 * 8) = 4
  4709.     T:up(1)
  4710.     for j = 1, lengthParts do
  4711.         T:go("M8", false, 0, true)
  4712.     end
  4713.     if lastPart > 0 then
  4714.         T:go("M"..tostring(lastPart)) -- eg m4
  4715.     end
  4716.     T:go("R2D1", false, 0, true)
  4717.     T:place("minecraft:torch", 0, "up", false)
  4718.     for j = 1, lengthParts do
  4719.         T:go("m8", true)
  4720.         T:place("minecraft:torch", 0, "up", false)
  4721.     end
  4722.     if lastPart > 0 then
  4723.         T:go("m"..tostring(lastPart), true) -- eg m4
  4724.     end
  4725.     T:go("R2", false, 0, true)
  4726. end
  4727.  
  4728. function createWaterSource(level)
  4729.     if level == nil then
  4730.         level = 0
  4731.     end
  4732.     if level > 0 then
  4733.         T:up(level)
  4734.     elseif level < 0 then
  4735.         T:down(math.abs(level))
  4736.     end
  4737.     -- assume on flat surface, but allow for blocks above
  4738.     T:go("x0C2F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2", false, 0, false)
  4739.     T:go("R1F1D1", false, 0, false) --move to corner and drop down
  4740.     T:go("C2F1R1 C2F1R1 C2F1R1 C2F1R1", false, 0, false)
  4741.     T:go("U1")
  4742.     for i = 1, 2 do
  4743.         T:place("minecraft:water_bucket", -1, "down", false)
  4744.         T:go("F1R1F1R1", false, 0, false)
  4745.     end
  4746.     -- refill water buckets
  4747.     for i = 1, 2 do
  4748.         sleep(0.5)
  4749.         T:place("minecraft:bucket", -1, "down", false)
  4750.     end
  4751.     T:go("R2F1R1F1R1")
  4752.     -- end above lower left of pond (starting point)
  4753. end
  4754.  
  4755. function decapitateBuilding(width, length)
  4756.     --clearRectangle with sand drop
  4757.     -- could be 1 wide x xx length (trench) up and return
  4758.     -- could be 2+ x 2+
  4759.     -- even no of runs return after last run
  4760.     -- odd no of runs forward, back, forward, reverse and return
  4761.     local success
  4762.     local directReturn = true
  4763.     if width % 2 == 1 then
  4764.         directReturn = false
  4765.     end
  4766.     if width == 1 then -- trench ahead, so fill then return
  4767.         for i = 1, length - 1 do
  4768.             success = dropSand()
  4769.             T:forward(1, false)
  4770.         end
  4771.         success = dropSand()
  4772.         T:go("R2F"..(length - 1).."R2", false, 0, false)
  4773.     else --2 or more columns
  4774.         if directReturn then -- width = 2,4,6,8 etc
  4775.             for i = 1, width, 2 do -- i = 1,3,5,7 etc
  4776.                 -- move along length, dropping sand
  4777.                 for j = 1, length - 1 do
  4778.                     success = dropSand()
  4779.                     T:forward(1, false)
  4780.                 end
  4781.                 success = dropSand()
  4782.                 T:go("R1F1R1") --turn right and return on next column
  4783.                 for j = 1, length - 1 do
  4784.                     success = dropSand()
  4785.                     T:forward(1, false)
  4786.                 end
  4787.                 success = dropSand()
  4788.                 if i < width - 2 then -- eg width = 8, i compares with 6: 1, 3, 5, 7
  4789.                     T:go("L1F1L1")
  4790.                 end
  4791.             end
  4792.             T:go("R1F"..width - 1 .."R1") --return home
  4793.         else
  4794.             for i = 1, width, 2 do -- i = 1,3,5,7 etc
  4795.                 -- move along length, dropping sand
  4796.                 for j = 1, length - 1 do
  4797.                     success = dropSand()
  4798.                     T:forward(1, false)
  4799.                 end
  4800.                 success = dropSand()
  4801.                 T:go("R1F1R1") --turn right and return on next column
  4802.                 for j = 1, length - 1 do
  4803.                     success = dropSand()
  4804.                     T:forward(1, false)
  4805.                 end
  4806.                 success = dropSand()
  4807.                 T:go("L1F1L1")
  4808.             end
  4809.             -- one more run then return
  4810.             for j = 1, length - 1 do
  4811.                 success = dropSand()
  4812.                 T:forward(1, false)
  4813.             end
  4814.             success = dropSand()
  4815.             T:go("R2F"..length.."R1F"..width - 1 .."R1")
  4816.         end
  4817.     end
  4818. end
  4819.  
  4820. function demolishBuilding(width, length)
  4821.     -- start bottom left
  4822.     clearBuilding(width, length, 0, false)
  4823. end
  4824.  
  4825. local function deactivateDragonTower()
  4826.     -- go up centre of tower to bedrock
  4827.     local height = 0
  4828.     --numBlocksMoved, errorMsg = clsTurtle.doMoves(self, numBlocksRequested, direction)
  4829.     local numBlocks, message = T:doMoves(1, "up")
  4830.     while message == nil do
  4831.         numBlocks, message = T:doMoves(1, "up")
  4832.         height = height + 1
  4833.     end
  4834.     -- go round bedrock and destroy crystal
  4835.     T:go("F1R2U2x1U1x1")
  4836.     -- return to start
  4837.     T:down(height + 5)
  4838. end
  4839.  
  4840. local function undermineDragonTowers()
  4841.     --[[
  4842.             -13, -40....12, -40                     NNW (4)     NNE (5)
  4843.            
  4844.         -34, -25............33, -25             NWW (2)             NEE (9)
  4845.        
  4846.     -42, -1....................42, 0        W (1)                       E (8)
  4847.    
  4848.          -34, 24............33,24               SWW (3)             SEE (10)
  4849.          
  4850.               -13,39....12, 39                      SSW (7)     SSE (6)
  4851.    
  4852.     North towers centres 25 blocks apart, 40 blocks north of axis
  4853.     Mid-North towers 67 blocks apart, 25 blocks north of axis
  4854.     W-E centres 84 blocks apart, on 0 axis
  4855.     Mid-south towers 67 blocks apart, 24 blocks south of axis
  4856.     South towers centres 25 blocks apart, 39 blocks south of axis
  4857.     ]]
  4858.    
  4859.     local lib = {}
  4860.     function lib.findNextTower(maxDistance, withMarker)
  4861.         local distance = 0
  4862.         local blockTypeF = T:getBlockType("forward")
  4863.         local blockTypeD = T:getBlockType("down")
  4864.         for i = 1, maxDistance do
  4865.             if blockTypeF ~= "minecraft:obsidian" and blockTypeD ~= "minecraft:obsidian" then -- not in a tower
  4866.                 if withMarker then -- used to mark 0 coordinate
  4867.                     T:place("cobble", -1, "down", false) -- place cobblestone or cobbled deepslate to mark zero coordinate
  4868.                 end
  4869.             else    -- obsidian found, could still be in an earlier tower
  4870.                 if i > 10 then
  4871.                     break
  4872.                 end
  4873.             end
  4874.             T:go("F1x0")
  4875.             distance = distance + 1
  4876.             blockTypeF = T:getBlockType("forward")
  4877.             blockTypeD = T:getBlockType("down")
  4878.         end
  4879.         if distance == maxDistance then -- obsidian not found ? wrong place/ direction
  4880.             print("Obsidian not found")
  4881.             error()
  4882.         end
  4883.         -- will now be at side of a tower
  4884.         lib.findCentre() -- move into tower to find the other side
  4885.         return distance
  4886.     end
  4887.    
  4888.     function lib.findCentre()
  4889.         local width = 0
  4890.         -- while obsidian in front or below (previously entered tower) measure width and return to centre
  4891.         local blockTypeF = T:getBlockType("forward")
  4892.         local blockTypeD = T:getBlockType("down")
  4893.         while blockTypeF == "minecraft:obsidian" or blockTypeD == "minecraft:obsidian" do
  4894.             T:go("F1x0")
  4895.             width = width + 1
  4896.             blockTypeF = T:getBlockType("forward")
  4897.             blockTypeD = T:getBlockType("down")
  4898.         end
  4899.         -- will always go outside the tower 1 block. width of 5 block tower = 6
  4900.         T:go("R2F"..math.ceil(width / 2)) --return to centre of tower
  4901.         T:turnLeft(1) -- now find another edge of the tower, dig forward until out of obsidian
  4902.         for i = 1, math.ceil(width) do  -- give additional loops if missed centre
  4903.             blockTypeF = T:getBlockType("forward")
  4904.             blockTypeD = T:getBlockType("down")
  4905.             if blockTypeF == "minecraft:obsidian" or blockTypeD == "minecraft:obsidian" then
  4906.                 T:go("F1x0")
  4907.             else
  4908.                 break
  4909.             end
  4910.         end
  4911.         -- now outside different edge of the tower
  4912.         -- reverse and move width/2, dig up + 1 to mark centre, face original direction
  4913.         T:go("L2F"..math.ceil(width / 2).."R1U2x1")
  4914.         T:place("minecraft:end_stone", -1, "forward", false) -- place endstone to mark facing direction
  4915.         T:down(2)
  4916.     end
  4917.    
  4918.     function lib.findPath(maxLength)
  4919.         local blockTypeD = T:getBlockType("down")
  4920.         local distance = 0
  4921.         while blockTypeD:find("cobble") == nil and distance < maxLength do
  4922.             T:go("F1x0")                            -- return to 0 axis,
  4923.             distance = distance + 1
  4924.             blockTypeD = T:getBlockType("down")
  4925.         end
  4926.         return distance
  4927.     end
  4928.    
  4929.     -- start at 0,y,0, facing West
  4930.     T:dig("up")                                 -- in case not already done
  4931.     local maxLength = 0
  4932.     local blockTypeD
  4933.     local distance = lib.findNextTower(45, true)-- find W tower (1) and mark trail with cobble
  4934.     T:turnRight(2)                     
  4935.     for i = 1, 8 do                             -- head back East 8 blocks, turn left (facing north)
  4936.         T:go("F1x0")                            -- this path may be off-axis, so dig double height
  4937.     end
  4938.     T:turnLeft(1)
  4939.     lib.findNextTower(30)                       -- find NWW tower (2)
  4940.     T:turnRight(2)
  4941.     distance =</