Inksaver

tk.lua toolkit (requires libs):2023/03/28

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