Inksaver

tk.lua toolkit (requires libs):2023/10/05

Apr 20th, 2020 (edited)
3,920
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 422.98 KB | None | 0 0
  1. version = 20231005.1900
  2.  
  3. local tkVersion = version -- otherwise over-written by clsTurtle when loaded
  4. --[[
  5.     **********Toolkit v2**********
  6.     https://pastebin.com/UFvjc1bw
  7.     Last edited: see version YYYYMMDD.HHMM
  8.     if NOT online:
  9.         Make sure you create a folder 'lib' and place menu.lua and clsTurtle.lua into it
  10.     else
  11.         lib folder will be created and files obtained automatically!
  12.     end
  13. ]]
  14.  
  15. args = {...} -- eg "farm", "tree"
  16.  
  17. local menu, T
  18. --[[
  19. Computercraft started with mc version 1.7.10 and went to 1.8.9
  20. ccTweaked started around mc 1.12.2 and currently at 1.18
  21. mc 1.18 has new blocks and bedrock at -64, so needs to be taken into account.
  22. _HOST = The ComputerCraft and Minecraft version of the current computer environment.
  23. For example, ComputerCraft 1.93.0 (Minecraft 1.15.2).
  24. ]]
  25. local dbug = false -- debug is reserved word
  26. local bedrock = 0
  27. local netherBedrock = 0
  28. local ceiling = 255
  29. local deletesWater = false
  30. local brick = "minecraft:nether_brick" -- pre 1.16+ name
  31. local ccMajorVersion = _HOST:sub(15, _HOST:find("Minecraft") - 2) --eg ComputerCraft 1.93.0 (Minecraft 1.15.2)
  32. local ccMinorVersion = 0
  33. --[[
  34. Netherite level stand on 14
  35. Chunk borders F3+G or:
  36. math.floor(x / 16) * 16 add 16 for each border. same for z
  37. ]]
  38. function string:split(sSeparator, nMax, bRegexp, noEmpty)
  39.     --[[return a table split with sSeparator. noEmpty removes empty elements
  40.         use: tblSplit = SplitTest:split('~',[nil], [nil], false) or tblSplit = string.split(SplitTest, '~')]]  
  41.     assert(sSeparator ~= '','separator must not be empty string')
  42.     assert(nMax == nil or nMax >= 1, 'nMax must be >= 1 and not nil')
  43.     if noEmpty == nil then noEmpty = true end
  44.  
  45.     local aRecord = {}
  46.     local newRecord = {}
  47.     -- self refers to the 'string' being split
  48.     if self:len() > 0 then
  49.         local bPlain = not bRegexp
  50.         nMax = nMax or -1
  51.  
  52.         local nField, nStart = 1, 1
  53.         local nFirst,nLast = self:find(sSeparator, nStart, bPlain)
  54.         while nFirst and nMax ~= 0 do
  55.             aRecord[nField] = self:sub(nStart, nFirst-1)
  56.             nField = nField+1
  57.             nStart = nLast+1
  58.             nFirst,nLast = self:find(sSeparator, nStart, bPlain)
  59.             nMax = nMax-1
  60.         end
  61.         aRecord[nField] = self:sub(nStart)
  62.        
  63.         if noEmpty then --split on newline preserves empty values
  64.             for i = 1, #aRecord do
  65.                 if aRecord[i] ~= "" then
  66.                     table.insert(newRecord, aRecord[i])
  67.                 end
  68.             end
  69.         else
  70.             newRecord = aRecord
  71.         end
  72.     end
  73.    
  74.     return newRecord
  75. end
  76.  
  77. if tonumber(ccMajorVersion) == nil then -- 1.93.0 NAN
  78.     --ccMajorVersion = ccMajorVersion:sub(1, ccMajorVersion:find(".", 3, true) - 1)
  79.     local parts = ccMajorVersion:split(".")
  80.     ccMajorVersion = parts[1]
  81.     if parts[2] ~= nil then
  82.         ccMajorVersion = ccMajorVersion.."."..parts[2]
  83.     end
  84.     ccMajorVersion = tonumber(ccMajorVersion)
  85.     if parts[3] ~= nil then
  86.         ccMinorVersion = tonumber(parts[3])
  87.     end
  88. end
  89.  
  90. local mcMajorVersion = _HOST:sub(_HOST:find("Minecraft") + 10, _HOST:find("\)") - 1) -- eg 1.18 or 1.20 -> 1.18, 1.20
  91. local mcMinorVersion = 0
  92. if tonumber(mcMajorVersion) == nil then -- 1.18.3 NAN
  93.     --mcMajorVersion = tonumber(_HOST:sub(_HOST:find("Minecraft") + 10, _HOST:find("\)") - 3)) -- eg 1.19.4 -> 1.19
  94.     local parts = mcMajorVersion:split(".")
  95.     mcMajorVersion = parts[1]
  96.     if parts[2] ~= nil then
  97.         mcMajorVersion = mcMajorVersion.."."..parts[2]
  98.     end
  99.     mcMajorVersion = tonumber(mcMajorVersion)
  100.     if parts[3] ~= nil then
  101.         mcMinorVersion = tonumber(parts[3])
  102.     end
  103. end
  104.  
  105. if mcMajorVersion < 1.7  and mcMajorVersion >= 1.18 then -- 1.12 to 1.??
  106.     bedrock = -64
  107.     ceiling = 319
  108. end
  109. if mcMajorVersion < 1.7  and mcMajorVersion >= 1.16 then -- 1.12 to 1.??
  110.     brick = "minecraft:nether_bricks"
  111. end
  112. if mcMajorVersion < 1.7  and mcMajorVersion <= 1.12 then --- turtle in source deletes it. 1.7.10 to 1.12
  113.     deletesWater = true
  114. end
  115.  
  116. local utils = {}
  117.  
  118. function utils.tableConcat(tbl, sep)
  119.     local output = ""
  120.     for i,value in pairs(tbl) do
  121.         output = output .. tostring(value)
  122.         if i ~= #tbl then
  123.             output = output .. sep
  124.         end
  125.     end
  126.  
  127.     return output
  128. end
  129.  
  130. function utils.calculateDimensions(R)
  131.     if R.data == "" then -- not being called from other functions
  132.         if R.width == 0 then -- user chose auto settings
  133.             R.length = utils.calculateDistance(R.length) -- still facing forward
  134.             print("Calculated Length = "..R.length)
  135.             T:turnRight(1) -- ready to check width
  136.             R.width = utils.calculateDistance(R.width) -- now facing right
  137.             print("Calculated width = "..R.width)
  138.             T:go("R2F"..R.width - 1 .."L1".. "F"..R.length - 1 .."R2") -- back at start. width/length confirmed
  139.         end
  140.     end
  141.     if R.height == 0 then -- use auto settings based on water detection
  142.         R.height = 64
  143.     end
  144.     return R
  145. end
  146.  
  147. function utils.calculateDistance(estDistamcMajorVersionnce)
  148.     --[[
  149.     measure length
  150.     movement stops when either solid block in front or solid below
  151.     called from utils.calculateDimensions
  152.     ]]
  153.     local moves = 1
  154.     local nonSolidBelow = utils.clearVegetation("down")
  155.     if estDistance == 0 then
  156.         while nonSolidBelow and turtle.forward() do -- while able to move and air/water below
  157.             moves = moves + 1
  158.             nonSolidBelow = utils.clearVegetation("down")
  159.         end
  160.     else
  161.         while moves < estDistance * 2 do -- loop can only run for max of double estimated distance
  162.             if turtle.forward() then -- able to move forward
  163.                 moves = moves + 1
  164.             else
  165.                 break
  166.             end
  167.             if not utils.clearVegetation("down") then -- solid below
  168.                 turtle.back()
  169.                 moves = moves - 1
  170.                 break
  171.             end
  172.         end
  173.     end
  174.     return moves
  175. end
  176.  
  177. function utils.checkFuelNeeded(quantity)
  178.     local fuelNeeded = quantity - turtle.getFuelLevel() -- eg 600
  179.     if fuelNeeded > 0 then
  180.         if T:checkInventoryForItem({"minecraft:lava_bucket"}, {1}, false) == nil then  
  181.             if T:checkInventoryForItem({"coal"}, {math.ceil(fuelNeeded / 60)}, false) == nil then
  182.                 T:checkInventoryForItem({"planks"}, {math.ceil(fuelNeeded / 15)})
  183.             end
  184.         end
  185.         T:refuel(quantity, true)
  186.     end
  187. end
  188.  
  189. function utils.clearVegetation(direction)
  190.     local isAirWaterLava = true -- default true value air/water/lava presumed
  191.     -- blockType, blockModifier, data
  192.     local blockType, blockModifier = T:getBlockType(direction)
  193.     if blockType ~= "" then --not air
  194.         if T:isVegetation(blockType) then
  195.             T:dig(direction)
  196.         elseif blockType:find("water") == nil
  197.                and blockType:find("lava") == nil
  198.                and blockType:find("bubble") == nil
  199.                and blockType:find("ice") == nil then
  200.             -- NOT water, ice or lava
  201.             isAirWaterLava = false -- solid block
  202.         end
  203.     end
  204.    
  205.     return isAirWaterLava --clears any grass or sea plants, returns true if air or water, bubble column or ice
  206. end
  207.  
  208. function utils.createPath(R) -- 51
  209.     --[[places a path in air/lava/water. R can also be of type int]]
  210.     local length = 0
  211.     local reduce = false
  212.     local torchInterval = 8
  213.     if type(R) == "table" then
  214.         length = R.length
  215.         if R.data == "reduce" then
  216.             reduce = true
  217.         end
  218.         torchInterval = R.torchInterval
  219.     else
  220.         length = R
  221.     end
  222.     local numBlocks = 0
  223.    
  224.     if reduce then
  225.         T:forward(1)
  226.         local blockType = T:getBlockType("down")
  227.         local useBlock = blockType
  228.         while blockType == useBlock do
  229.             T:go("x2F1")
  230.             numBlocks = numBlocks + 1
  231.             blockType = T:getBlockType("down")
  232.         end
  233.         utils.goBack(numBlocks + 1)
  234.     else
  235.         for i = 1, 2 do
  236.             T:fillVoid("down", {}, false)
  237.             T:forward(1)
  238.             numBlocks = numBlocks + 1
  239.         end
  240.         local place = utils.clearVegetation("down")
  241.         while place do -- while air, water, normal ice, bubble column or lava below
  242.             if T:fillVoid("down", {}, false) then -- false if out of blocks
  243.                 T:forward(1)
  244.                 numBlocks = numBlocks + 1
  245.                 if numBlocks % torchInterval == 1 or numBlocks == 0 then
  246.                     if T:getItemSlot("minecraft:torch", -1) > 0 then
  247.                         T:turnRight(2)
  248.                         T:place("minecraft:torch", -1, "forward", false)
  249.                         T:turnRight(2)
  250.                     end
  251.                 end
  252.             else
  253.                 break
  254.             end
  255.             if length > 0 and numBlocks >= length then -- not infinite path (length = 0)
  256.                 break
  257.             end
  258.             place = utils.clearVegetation("down")
  259.         end
  260.     end
  261.     return {numBlocks} -- returned as a table in case called as task 51 back to main()
  262. end
  263.  
  264. function utils.createWalledSpace(D)
  265.     --[[
  266.     D.width  = #
  267.     D.length = #
  268.     D.height = #
  269.     D.ceiling = false
  270.     D.floor = false
  271.     D.vDirection = "U" or "D"
  272.     D.hDirection = "LR" or "RL"
  273.     D.goHome = true
  274.     T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  275.     ]]
  276.     local turn  = "R1"
  277.     local oTurn = "L1"
  278.     if D.hDirection == "RL" then
  279.         turn    = "L1"
  280.         oTurn   = "R1"
  281.     end
  282.     local placeF = "C1"
  283.  
  284.     local lib = {}
  285.    
  286.     function lib.getPlace(D, start, finish)
  287.         if start then                       -- start of build
  288.             if D.vDirection == "U" then     -- bottom and going up
  289.                 if D.floor then
  290.                     return "C2"
  291.                 end
  292.             else                            -- D.vDirection == "D"
  293.                 if D.ceiling then
  294.                     return "C0"
  295.                 end
  296.             end
  297.         elseif finish then                  -- end of build
  298.             if D.vDirection == "U" then     -- bottom and going up
  299.                 if D.ceiling then
  300.                     return "C0"
  301.                 end
  302.             else
  303.                 if D.floor then
  304.                     return "C2"
  305.                 end
  306.             end
  307.         end
  308.  
  309.         return ""                           -- start and finish both false
  310.     end
  311.    
  312.     function lib.layer(D, start, finish)
  313.         local outward = true
  314.         local place = lib.getPlace(D, start, finish)
  315.         for width = 1, D.width do
  316.             for length = 1, D.length do
  317.                 if start or finish then
  318.                     T:go(place, false, 0, true)-- place floor / ceiling
  319.                 end
  320.                 if width == 1 then
  321.                     T:go(oTurn..placeF..turn, false, 0, true)       -- face wall and check if block
  322.                 elseif width == D.width then                        -- checking opposite wall
  323.                     if outward then                                 -- travelling away from start
  324.                         T:go(turn..placeF..oTurn, false, 0, true)   -- face wall and check if block
  325.                     else                                            -- travelling towards start
  326.                         T:go(oTurn..placeF..turn, false, 0, true)   -- face wall and check if block
  327.                     end                
  328.                 end
  329.                 -- move forward
  330.                 if length < D.length then
  331.                     T:forward(1)
  332.                 end
  333.             end
  334.             if width < D.width then
  335.                 -- change direction
  336.                 if outward then
  337.                     T:go(placeF..turn.."F1"..oTurn..place..placeF..turn..turn, false, 0, true)
  338.                 else
  339.                     T:go(placeF..oTurn.."F1"..turn..place..placeF..oTurn..oTurn, false, 0, true)
  340.                 end
  341.                 outward = not outward
  342.             else
  343.                 if outward then
  344.                     T:go(placeF..oTurn.."F"..D.width -1 ..oTurn.."F"..D.length - 1 .."C1R2", false, 0, true)
  345.                 else
  346.                     T:go(placeF..turn.."F"..D.width -1 ..oTurn..placeF..turn..turn, false, 0, true)
  347.                 end
  348.             end
  349.         end
  350.     end
  351.    
  352.     T:go("R2"..placeF.."R2", false, 0, true)            -- place block behind
  353.     for height = 1, D.height do
  354.         if height == 1 then
  355.             lib.layer(D, true, false)                   -- first layer, so start = true, finish = false
  356.         elseif height == D.height then     
  357.             lib.layer(D, false, true)                   -- final layer, so start = false, finish = true
  358.         else
  359.             lib.layer(D, false, false)                  -- mid build layer, so start = false, finish = false
  360.         end
  361.         if height < D.height then                       -- go up or down unless finished build
  362.             T:go(D.vDirection.."1")
  363.         end
  364.     end
  365.     if D.goHome then-- ends at starting point
  366.         if D.vDirection == "U" then
  367.             T:down(D.height - 1)
  368.         else
  369.             T:up(D.height - 1)
  370.         end
  371.     end
  372. end
  373.  
  374. function utils.createWaterSource(level)
  375.     if level == nil then
  376.         level = 0
  377.     end
  378.     if level > 0 then
  379.         T:up(level)
  380.     elseif level < 0 then
  381.         T:down(math.abs(level))
  382.     end
  383.     -- assume on flat surface, but allow for blocks above
  384.     T:go("x0C2F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2", false, 0, false)
  385.     T:go("R1F1D1", false, 0, false) --move to corner and drop down
  386.     T:go("C2F1R1 C2F1R1 C2F1R1 C2F1R1", false, 0, false)
  387.     T:go("U1")
  388.     for i = 1, 2 do
  389.         T:placeWater("down")
  390.         T:go("F1R1F1R1", false, 0, false)
  391.     end
  392.     -- refill water buckets
  393.     for i = 1, 2 do
  394.         sleep(0.5)
  395.         T:placeWater("down")
  396.     end
  397.     T:go("R2F1R1F1R1")
  398.     -- end above lower left of pond (starting point)
  399.     return {}
  400. end
  401.  
  402. function utils.drainWaterLava(R) -- 84
  403.     local lib = {}
  404.        
  405.     function lib.startCorner()
  406.         -- assume starting mid 3 high column
  407.         T:go("D1C1R1C1 U1C1 L1C1 U1C1 R1C1 L1D1 C2C0", false, 0, true)
  408.         -- finished on same mid 3 high column with wall in front and right completed
  409.     end
  410.    
  411.     function lib.midWall()
  412.         -- assume starting mid 3 high column
  413.         T:go("D1R1C1 U1C1 U1C1 L1D1 C2C0", false, 0, true)
  414.         -- finished on same mid 3 high column with wall on right completed
  415.     end
  416.    
  417.     function lib.endCorner()
  418.         -- assume starting mid 3 high column
  419.         T:go("D1R1C1 R1C1 U1C1 L1C1 U1C1 R1C1 L2D1 C2C0", false, 0, true)
  420.         -- finished on same mid 3 high column with wall behind and right completed
  421.     end
  422.    
  423.     function lib.backTurn(offset)
  424.         -- assume starting mid 3 high column with completed wall behind
  425.         T:go("L1F"..offset.."L2C1 R1D1C1 U1C1 U1C1 D1")
  426.         -- end next row along the width, facing the back, mid point
  427.         -- wall ahead completed
  428.     end
  429.    
  430.     function lib.frontTurn()
  431.         -- assume starting mid 3 high column facing back
  432.         -- next move is to turn toward previous wall and remove
  433.  
  434.         T:go("L2D1C1 U1C1 U1C1 D1R1 C2C0 F1R2C1 L1")
  435.         -- end facing back ready to remove wall
  436.     end
  437.    
  438.     function lib.placeRetainingWall(distance)
  439.         -- assume starting above 3 block high area facing front (player)
  440.         --T:down(1)
  441.         for i = 1, distance do
  442.             if i == 1 then -- start wall
  443.                 lib.startCorner()
  444.             else
  445.                 if i < distance then -- mid wall
  446.                     lib.midWall()
  447.                 else -- end of the wall
  448.                     lib.endCorner()
  449.                 end
  450.             end
  451.             if i < distance then
  452.                 if not turtle.back() then
  453.                     T:go("R2F1R2")
  454.                 end
  455.                 T:go("C1", false, 0, true)
  456.             end
  457.         end
  458.         return 1
  459.     end
  460.        
  461.     function lib.placeDam(distance)
  462.         --T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  463.         local waterPresent = false
  464.         for i = 1, distance do
  465.             if T:isWater("down") then
  466.                 waterPresent = true
  467.             end
  468.             T:go("C0C2")
  469.             if i < distance then
  470.                 if not turtle.back() then
  471.                     T:go("R2F1R2")
  472.                 end
  473.                 T:go("C1", false, 0, true)
  474.             end
  475.         end
  476.         return waterPresent
  477.     end
  478.    
  479.     function lib.removeDam(distance)
  480.         -- facing towards back, dig wall up down and ahead
  481.         for i = 1, distance do
  482.             T:go("x0x2")
  483.             if i < distance then
  484.                 T:forward(1)
  485.             end
  486.         end
  487.         T:turnRight(2)
  488.         -- end up back to retaining wall, mid point
  489.     end
  490.    
  491.     if R.data == "" then
  492.         if turtle.detectDown() then -- on solid surface
  493.             turtle.forward()
  494.         end
  495.     end
  496.     if deletesWater then --turtle replaces source so use clearSolid()
  497.         R.silent = true
  498.         R.down = true
  499.         R.up = false
  500.         clearSolid(R)
  501.     else -- mc 1.12.15+ turtle does NOT replace source blocks
  502.         -- place first stone along the length of water and measure length
  503.         R = utils.calculateDimensions(R)
  504.         local depth = 0
  505.         for h = 1, R.height do
  506.             local waterPresent = false -- resets at each level
  507.             local row = 0
  508.             T:go("R2D2", false, 0, true)    -- at start, level 2, facing towards the front, move backards
  509.             --lib.startCorner()
  510.             row = row + lib.placeRetainingWall(R.length)
  511.             lib.backTurn(1)
  512.             if lib.placeDam(R.length) then
  513.                 waterPresent = true
  514.             end
  515.             row = row + 1
  516.             -- left side wall has been built, 2 rows of walls laid. row = 2
  517.             while row < R.width - 1 do -- eg width=2, row=2, this will not run. width=5, row=2
  518.                 lib.frontTurn()
  519.                 lib.removeDam(R.length)
  520.                 lib.backTurn(2)
  521.                 if lib.placeDam(R.length) then
  522.                     waterPresent = true
  523.                 end
  524.                 row = row + 1
  525.             end
  526.             -- lay right wall
  527.             lib.frontTurn()
  528.             lib.removeDam(R.length)
  529.             lib.backTurn(2)
  530.             row = row + lib.placeRetainingWall(R.length)
  531.             lib.frontTurn()
  532.             lib.removeDam(R.length) -- faces to front on finish
  533.             T:go("L1F1R1")
  534.             lib.removeDam(R.length) -- faces to front on finish
  535.             depth = depth + 3
  536.             T:go("L1F"..R.width - 1 .."R1D1")
  537.             if depth == R.height or not waterPresent then -- still replacing water
  538.                 T:up(depth - 1) -- when h == R.height will go up
  539.                 break -- in case water dries up before loop has completed
  540.             end
  541.         end
  542.     end
  543.     return {}
  544. end
  545.  
  546. function utils.dropSand()
  547.     while not turtle.detectDown() do -- over water. will be infinite loop if out of sand
  548.         if not T:place("sand", -1, "down", false) then
  549.             print("Out of sand. Add more to continue...")
  550.             sleep(2)
  551.         end
  552.     end
  553.     return true --will only get to this point if turtle.detectDown() = true
  554. end
  555.  
  556. function utils.pause(R)
  557.     --[[
  558.     allows 2 turtles to co-operate
  559.     When they face each other and move together
  560.     R.side = "R" or "L"
  561.     ]]
  562.     local rsIn = rs.getAnalogueInput("front")
  563.     local rsOut = 1
  564.     local present = false
  565.     local confirmed = false
  566.     local timer = 0
  567.     local endTimer = 0
  568.     local finished = false
  569.     T:go(R.side.."1")
  570.     rs.setAnalogueOutput("front", 0) -- switch off output
  571.     local blockType = T:getBlockType("forward")
  572.     while blockType:find("turtle") == nil do
  573.         menu.colourWrite("Waiting for other turtle "..endTimer, colors.orange, nil, nil, false, true)
  574.         blockType = T:getBlockType("forward")
  575.         sleep(0.1)
  576.         timer = timer + 0.1
  577.         if timer >= 1 then
  578.             timer = 0
  579.             endTimer = endTimer + 1
  580.         end
  581.     end
  582.     timer = 0
  583.     endTimer = 0
  584.    
  585.     while not finished do
  586.         if endTimer == 0 then
  587.             if present then
  588.                 if confirmed then
  589.                     menu.colourWrite("Turtle confirmed: input = "..rsIn.." output = "..rsOut, colors.orange, nil, nil, false, true)
  590.                 else
  591.                     menu.colourWrite("Other turtle ok: input = "..rsIn.." output = "..rsOut, colors.orange, nil, nil, false, true)
  592.                 end
  593.             else
  594.                 menu.colourWrite("Waiting: input = "..rsIn.." output = "..rsOut, colors.orange, nil, nil, false, true)
  595.             end
  596.         end
  597.         sleep(0.1)
  598.         timer = timer + 1
  599.         if endTimer > 0 then
  600.             endTimer = endTimer + 1
  601.         end
  602.         if endTimer >= 10 then -- allows time for other computer to get ready
  603.             finished = true
  604.         end
  605.         rs.setAnalogueOutput("front", 1) -- output 1 as a signal initially
  606.         if present then
  607.             rs.setAnalogueOutput("front", rsOut) -- output 1 as a signal initially
  608.         end
  609.         rsIn = rs.getAnalogueInput("front")
  610.         if rsIn == 1 then
  611.             present = true
  612.             if not confirmed then
  613.                 rsOut = 7
  614.             end
  615.         elseif rsIn == 7 then
  616.             present = true
  617.             confirmed = true
  618.             rsOut = 15
  619.         elseif rsIn == 15 or confirmed then
  620.             menu.colourWrite("endTimer active = "..endTimer, colors.orange, nil, nil, false, true)
  621.             endTimer = endTimer + 1 -- start endTimer
  622.         end
  623.     end
  624.     T:go(R.side.."3")
  625.    
  626.     return rsIn -- 15
  627. end
  628.  
  629. function utils.startWaterFunction(inWater, onWater, maxDescent, goIn)
  630.     --[[
  631.         Use with utils.getWaterStatus
  632.         could be inWater and not onWater if on single layer of water with floor below
  633.     ]]
  634.     maxDescent = maxDescent or 1 -- prevents continuous down due to lack of water
  635.     if goIn == nil then -- turtle should submerge
  636.         goIn = true
  637.     end
  638.     local descent = 0 -- counter for going down
  639.     if inWater then -- job done
  640.         return inWater, onWater
  641.     end
  642.     if onWater and goIn then --inWater already returned so must be false
  643.         if turtle.down() then
  644.             if T:getBlockType("forward"):find("water") ~= nil or T:getBlockType("forward"):find("bubble") ~= nil then
  645.                 inWater = true
  646.                 return inWater, onWater
  647.             end
  648.         end
  649.     end
  650.     if not onWater then
  651.         T:forward(1)
  652.     end
  653.     -- should now be above water, but may be further down so onWater still false
  654.     while T:getBlockType("down"):find("water") == nil and T:getBlockType("down"):find("bubble") == nil do-- go down until water below
  655.         if turtle.down() then
  656.             descent = descent + 1
  657.             if descent >= maxDescent then -- limit descent in case no water present
  658.                 onWater = false
  659.                 return inWater, onWater -- false,false
  660.             end
  661.         else
  662.             onWater = false
  663.             return inWater, onWater -- false,false
  664.         end
  665.     end
  666.     -- now above water
  667.     if goIn then
  668.         turtle.down() -- now inside water block
  669.         inWater = true
  670.     end
  671.     return inWater, onWater
  672. end
  673.  
  674. function utils.fillBucket(direction)
  675.     if T:getWater(direction)  then
  676.         sleep(0.3)
  677.         return true
  678.     else
  679.         return false
  680.     end
  681. end
  682.  
  683. function utils.getEmptyBucketCount()
  684.     local lastSlot, leastModifier, total, slotData = T:getItemSlot("minecraft:bucket", -1)
  685.     return total
  686. end
  687.  
  688. function utils.getRoofStats(R)
  689.     local isWidthOdd = R.width % 2 == 1             -- is the width odd or even?
  690.     local isLengthOdd = R.length % 2 == 1           -- is the length odd or even?
  691.     if isWidthOdd then
  692.         R.height = math.floor(R.width / 2)          -- eg 7 x 5 roof, layers = 5 / 2 = 2
  693.     else
  694.         R.height = R.width / 2                      -- eg 17 x 8 roof, layers = 8 / 2 = 4
  695.     end
  696.    
  697.     local width = 2                                 -- assume even width with  2 block roof ridge
  698.     local length = R.length - R.height - 1          -- assume even width with  2 block roof ridge
  699.     if isWidthOdd then
  700.         width = 3                                   -- adjust to allow for single width roof ridge
  701.     end
  702.     if isLengthOdd then
  703.         length = R.length - R.height                -- adjust as 1 layer less
  704.     end
  705.    
  706.     return R, isWidthOdd, isLengthOdd, width, length
  707. end
  708.  
  709. function utils.getWater()
  710.     if deletesWater then
  711.         T:getWater("down") -- take water from source
  712.         sleep(0.2)
  713.         T:getWater("down") -- take water from source
  714.     else
  715.         if not turtle.detectDown() then
  716.             T:go("C2", false, 0, false)
  717.         end
  718.         T:getWater("forward") -- take water from source
  719.         sleep(0.2)
  720.         T:getWater("forward") -- take water from source
  721.     end
  722. end
  723.  
  724. function utils.getWaterBucketCount()
  725.     -- lastSlot, leastModifier, total, slotData  = T:getItemSlot(item, useDamage)
  726.     local lastSlot, leastModifier, total, slotData = T:getItemSlot("minecraft:water_bucket", -1)
  727.     return total
  728. end
  729.  
  730. function utils.getWaterStatus()
  731.     --[[ Usage:
  732.     local inWater, onWater = utils.getWaterStatus() -- returns turtle position near water
  733.     utils.startWaterFunction(onWater, inWater, 2, true) -- move INTO water max 2 blocks down
  734.     utils.startWaterFunction(onWater, inWater, 5, false) -- move ABOVE water max 5 blocks down
  735.     ]]
  736.     local onWater = false
  737.     local inWater = false
  738.     for i = 1, 4 do
  739.         if T:getBlockType("forward"):find("water") ~= nil  or T:getBlockType("forward"):find("bubble") ~= nil then
  740.             inWater = true
  741.         end
  742.         T:turnRight(1)
  743.     end
  744.     if T:getBlockType("down"):find("water") ~= nil or T:getBlockType("down"):find("bubble") ~= nil then
  745.         onWater = true
  746.     end
  747.     return inWater, onWater
  748. end
  749.  
  750. function utils.goBack(blocks)
  751.     blocks = blocks or 1
  752.     local success = true
  753.     for i = 1, blocks do
  754.         if not turtle.back() then
  755.             success = false
  756.             T:go("R2F1R2")
  757.         end
  758.     end
  759.    
  760.     return success
  761. end
  762.  
  763. function utils.getPrettyPrint(promptColour, menuPromptColour)
  764.     promptColour = promptColour or colors.yellow
  765.     menuPromptColour = menuPromptColour or colors.white
  766.    
  767.     local pp = {}
  768.     pp.prompt = promptColour
  769.     pp.itemColours = {}
  770.     pp.menuPrompt = menuPromptColour
  771.     pp.allowModifier = true -- can the menu return 'q' or 'h' / 'i'
  772.    
  773.     return pp
  774. end
  775.  
  776. function utils.move(R, blocks, reverse)
  777.     if reverse == nil then
  778.         reverse = false
  779.     end
  780.     if reverse then
  781.         if R.subChoice == 2 then -- reverse direction
  782.             T:up(blocks)
  783.         else
  784.             T:down(blocks)
  785.         end
  786.         return blocks * -1
  787.     else
  788.         if R.subChoice == 1 then
  789.             T:up(blocks)
  790.         else
  791.             T:down(blocks)
  792.         end
  793.         return blocks
  794.     end
  795. end
  796.  
  797. function utils.setStorageOptions()
  798.     local storage = ""
  799.     local storageBackup = ""
  800.     if T:getItemSlot("barrel") > 0 then
  801.         storage = "barrel"
  802.         storageBackup = "barrel"
  803.     end
  804.     if T:getItemSlot("chest") > 0 then
  805.         if storage == "" then
  806.             storage = "chest"
  807.         end
  808.         storageBackup = "chest"
  809.     end
  810.     return storage, storageBackup
  811. end
  812.  
  813. local pp = utils.getPrettyPrint()
  814.  
  815. local function buildWall(R)
  816.     -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  817.     local lib = {}
  818.    
  819.     function lib.singleLayer(R)
  820.         for l = 1, R.length do
  821.             if l == R.length and R.data == "house" then
  822.                 T:turnRight(1)
  823.             end
  824.             utils.goBack(1)
  825.             T:go("C1", false, 0, false, R.useBlockType)
  826.         end
  827.     end
  828.    
  829.     function lib.doubleLayer(R)
  830.         for l = 1, R.length do
  831.             T:go("C2", false, 0, false, R.useBlockType)
  832.             if l == R.length and R.data == "house" then
  833.                 T:turnRight(1)
  834.             end
  835.             utils.goBack(1)
  836.             T:go("C1", false, 0, false, R.useBlockType)
  837.         end
  838.     end
  839.    
  840.     function lib.tripleLayer(R)
  841.         for l = 1, R.length do
  842.             T:go("C2C0", false, 0, false, R.useBlockType)
  843.             if l == R.length and R.data == "house" then
  844.                 T:turnRight(1)
  845.             end
  846.             utils.goBack(1)
  847.             T:go("C1", false, 0, false, R.useBlockType)
  848.         end
  849.     end
  850.    
  851.     -- R.width preset to 1
  852.     local remaining = R.height
  853.    
  854.     if R.subChoice == 1 then
  855.         T:forward(1)            -- face forward, move over first block
  856.     end
  857.     if R.height > 1 then
  858.         T:up(1)                 -- go up 1 block
  859.     end
  860.     if R.data ~= "house" then
  861.         T:turnRight(2)              -- rotate 180
  862.     end
  863.     if R.height == 1 then       -- single block: place in front
  864.         lib.singleLayer(R)
  865.     elseif R.height == 2 then   -- 2 blocks, go backwards, place below and ahead
  866.         lib.doubleLayer(R)
  867.     else
  868.         while remaining >= 3 do
  869.             lib.tripleLayer(R)
  870.             remaining = remaining - 3
  871.             if remaining == 1 then
  872.                 T:go("U2F1R2")
  873.             elseif remaining > 1 then
  874.                 T:go("U3F1R2")
  875.             end
  876.         end
  877.         if remaining == 1 then
  878.             lib.singleLayer(R)
  879.         elseif remaining == 2 then
  880.             lib.doubleLayer(R)
  881.         end
  882.     end
  883.     if not R.silent then
  884.         while turtle.down() do end
  885.     end
  886.    
  887.     return {}
  888. end
  889.  
  890. local function buildStructure(R)
  891.     local lib = {}
  892.    
  893.     function lib.goDown(R)
  894.         --T:go("L1F1 R1F1 L1")  -- now on ground floor
  895.         if R.height > 1 then
  896.             T:down(1)
  897.         end
  898.     end
  899.     local buildHeight = R.height
  900.     local height = R.height
  901.     local width = R.width
  902.     local length = R.length
  903.    
  904.     if R.subChoice == 1 then
  905.         T:forward(1)            -- face forward, move over first block
  906.     end
  907.     if R.height > 3 then
  908.         R.height = 3
  909.     end
  910.     T:turnRight(2)
  911.     R.data = "house"
  912.     R.silent = true -- prevent return to ground after buildWall(R)
  913.     R.subChoice = 2 -- do not move forward when building walls
  914.     while height > 0 do
  915.         buildWall(R)
  916.        
  917.         lib.goDown(R)
  918.         R.length = width - 1
  919.         buildWall(R)
  920.         lib.goDown(R)
  921.        
  922.         R.length = length - 1
  923.         buildWall(R)
  924.         lib.goDown(R)
  925.        
  926.         R.length = width - 2
  927.         buildWall(R)
  928.         height = height - R.height  -- 1, 2 or 3
  929.         if height > 0 then
  930.             T:go("U2 R1F1 L1F1")
  931.             R.height = height
  932.             if height > 3 then
  933.                 R.height = 3
  934.             end
  935.             R.length = length
  936.         end
  937.     end
  938.    
  939.     T:go("U2F2")
  940.     while turtle.down() do end
  941.     T:go("R1F1R1")
  942.    
  943.     return {}
  944. end
  945.  
  946. local function buildGableRoof(R)
  947.     --[[
  948.     stairs placement:
  949.        _|   up
  950.      
  951.        T L  forward
  952.        _
  953.         |   down
  954.  
  955.     ]]
  956.     local lib = {}
  957.    
  958.     function lib.placeRoof(R, outward)
  959.         for i = 1, R.length + 2 do
  960.             if R.useBlockType:find("stairs") ~= nil then
  961.                 T:place("stairs", 0, "up")
  962.             else
  963.                 T:go("C0", false, 0, false, R.useBlockType)
  964.             end
  965.             if i < R.length + 2 then
  966.                 if outward then
  967.                     T:go("L1F1R1")
  968.                 else
  969.                     T:go("R1F1L1")
  970.                 end
  971.             end
  972.         end
  973.     end
  974.    
  975.     function lib.placeGable(R, outward)
  976.         local width = R.width
  977.         for h = 1, R.height do
  978.             for w = 1, width do
  979.                 T:go("C1")
  980.                 if w < width then
  981.                     if outward then
  982.                         T:go("L1F1R1")
  983.                     else
  984.                         T:go("R1F1L1")
  985.                     end
  986.                 end
  987.             end
  988.             if h < R.height then
  989.                 if outward then
  990.                     T:go("R1F1L1U1")
  991.                 else
  992.                     T:go("L1F1R1U1")
  993.                 end
  994.             end
  995.             width = width - 2
  996.             outward = not outward
  997.         end
  998.         return outward
  999.     end
  1000.    
  1001.     local outward = true
  1002.     -- go to centre of end wall if odd no, or half width if even
  1003.     R.height = math.floor(R.width / 2)
  1004.     local isOdd = R.width % 2 == 1
  1005.    
  1006.     utils.goBack(1)
  1007.     T:go("R1F"..R.height - 1 .."U"..R.height - 1)   -- top of roof, under top layer
  1008.     for h = 1, R.height + 1 do                      -- place tiles on left side of roof
  1009.         lib.placeRoof(R, outward)
  1010.         if h < R.height + 1 then
  1011.             utils.goBack(1)
  1012.             T:down(1)
  1013.             outward = not outward
  1014.         end
  1015.     end
  1016.     if isOdd then
  1017.         T:go("F"..R.height + 2 .."R2U"..R.height)
  1018.     else
  1019.         T:go("F"..R.height + 1 .."R2U"..R.height)
  1020.     end
  1021.     for h = 1, R.height + 1 do                      -- place tiles on right side of roof
  1022.         lib.placeRoof(R, outward)
  1023.         if h < R.height + 1 then
  1024.             utils.goBack(1)
  1025.             T:down(1)
  1026.             outward = not outward
  1027.         end
  1028.     end
  1029.     -- gable ends
  1030.     if outward then
  1031.         T:go("F1R1U1")
  1032.     else
  1033.         T:go("F1L1U1")
  1034.     end
  1035.     outward = lib.placeGable(R, outward)
  1036.     T:go("F2R2 C1R2F"..R.length - 1 .."D"..R.height - 1)
  1037.     if outward then
  1038.         T:go("R1F"..R.height - 1 .."R1")
  1039.     else
  1040.         T:go("L1F"..R.height - 1 .."L1")
  1041.     end
  1042.     outward = not outward
  1043.     outward = lib.placeGable(R, outward)
  1044.     if isOdd then
  1045.         if outward then
  1046.             T:go("L1F1R1U2F1")
  1047.         else
  1048.             T:go("R1F1L1U2F1")
  1049.         end
  1050.         for i = 1, R.length do
  1051.             T:go("C2F1", false, 0, false)
  1052.         end
  1053.         for i = 1, R.length + 2 do
  1054.             utils.goBack(1)
  1055.             T:place("slab", 0, "forward")
  1056.         end
  1057.     end
  1058.     while turtle.down() do end
  1059.    
  1060.     return {}
  1061. end
  1062.  
  1063. local function buildPitchedRoof(R)
  1064.     --[[
  1065.     stairs placement:
  1066.        _|   up
  1067.      
  1068.        T L  forward
  1069.        _
  1070.         |   down
  1071.  
  1072.     ]]
  1073.     local lib = {}
  1074.        
  1075.     function lib.placeRoofSection(length)
  1076.         -- starts facing centre of building
  1077.         for i = 1, length do
  1078.             if i < length then
  1079.                 if R.useBlockType:find("stairs") ~= nil then
  1080.                     T:place("stairs", 0, "up")
  1081.                 else
  1082.                     T:go("C0", false, 0, false, R.useBlockType)
  1083.                 end
  1084.                 T:go("L1F1R1")
  1085.             end
  1086.         end
  1087.         -- ends facing centre of building
  1088.     end
  1089.    
  1090.     function lib.placeRoof(R, width, length)
  1091.         lib.placeRoofSection(length)
  1092.         T:go("R1")
  1093.         lib.placeRoofSection(width)
  1094.         T:go("R1")
  1095.         lib.placeRoofSection(length)
  1096.         T:go("R1")
  1097.         lib.placeRoofSection(width)
  1098.     end
  1099.    
  1100.     function lib.placeSlabs(length)
  1101.         -- add slabs at top
  1102.         T:go("U2F1L1")
  1103.         if length > 1 then
  1104.             T:forward(length - 3)
  1105.             for i = 1, length - 3 do
  1106.                 T:place("slab", 0, "forward")
  1107.                 utils.goBack(1)
  1108.             end
  1109.             T:place("slab", 0, "forward")
  1110.         else
  1111.             T:place("slab", 0, "forward")
  1112.         end
  1113.         T:go("D2R1")
  1114.         utils.goBack(1)
  1115.     end
  1116.     --[[
  1117.     Turtle MUST be placed on left corner of shortest dimension
  1118.    
  1119.     ****   or T******
  1120.     ****      *******
  1121.     ****      *******
  1122.     ****
  1123.     T***
  1124.     shortest dimension is R.width
  1125.     if width is odd, ignore top layer as is only 1 block wide
  1126.     ]]
  1127.     local isWidthOdd, isLengthOdd, width, length = false, false, 0, 0
  1128.     R, isWidthOdd, isLengthOdd, width, length = utils.getRoofStats(R)
  1129.     T:go("F"..R.height - 1 .."R1F"..R.height - 1 .."U"..R.height - 1)       -- top of roof, under top layer
  1130.     if isWidthOdd then
  1131.         lib.placeSlabs(length)
  1132.     end
  1133.     for h = 1, R.height + 1 do                      -- place tiles on left side of roof
  1134.         lib.placeRoof(R, width, length)
  1135.         length = length + 2                         -- increase dimensions
  1136.         width = width + 2
  1137.         if h < R.height + 1 then
  1138.             utils.goBack(1)
  1139.             T:go("D1R1")
  1140.             utils.goBack(1)
  1141.         end
  1142.     end
  1143.     while turtle.down() do end
  1144.    
  1145.     return {}
  1146. end
  1147.  
  1148. local function clearAndReplantTrees() -- 25
  1149.     --[[ clear all trees in a rectangle area defined by walls, fences or non-dirt blocks
  1150.     replant with same type of sapling. If original tree 2 blocks wide, replant 4 if possible. ]]
  1151.    
  1152.     local lib = {}
  1153.    
  1154.     function lib.getSaplingFromLogType(log)
  1155.         --[[ get type of sapling to plant from log type ]]
  1156.         if log:find("oak") ~= nil then
  1157.             return "minecraft:oak_sapling"
  1158.         elseif log:find("spruce") ~= nil then
  1159.             return "minecraft:spruce_sapling"
  1160.         elseif log:find("birch") ~= nil then
  1161.             return "minecraft:birch_sapling"
  1162.         elseif log:find("jungle") ~= nil then
  1163.             return "minecraft:jungle_sapling"
  1164.         elseif log:find("acacia") ~= nil then
  1165.             return "minecraft:acacia_sapling"
  1166.         elseif log:find("dark_oak") ~= nil then
  1167.             return "minecraft:dark_oak_sapling"
  1168.         end
  1169.         return "sapling"
  1170.     end
  1171.    
  1172.     function lib.plantSapling(sapling, double)
  1173.         --[[ plant sapling(s) ]]
  1174.         if sapling == "" or sapling == nil then sapling = "sapling" end
  1175.         T:up(1)
  1176.         lib.suck()
  1177.         if double then  -- check if enough saplings
  1178.             --slotData.lastSlot, slotData.leastModifier, total, slotData = T:getItemSlot(sapling, -1)
  1179.             local a, b, total, _ = T:getItemSlot(sapling, -1)
  1180.             if total >= 4 then
  1181.                 for i = 1, 4 do
  1182.                     T:place(sapling, -1, "down")
  1183.                     T:go("F1R1")
  1184.                 end
  1185.                 T:forward(1)        -- above pre-planted sapling
  1186.             else
  1187.                 if not T:place(sapling, -1, "down") then
  1188.                     T:place("sapling", -1, "down")
  1189.                 end
  1190.             end
  1191.         else
  1192.             if not T:place(sapling, -1, "down") then
  1193.                 T:place("sapling", -1, "down")
  1194.             end
  1195.         end
  1196.         turtle.select(1)
  1197.     end
  1198.        
  1199.     function lib.suck()
  1200.         --[[ Collect saplings, sticks and apples ]]
  1201.         turtle.select(1)
  1202.         turtle.suck()
  1203.         turtle.suckUp()
  1204.         turtle.suckDown()
  1205.     end
  1206.    
  1207.     function lib.turn(direction)
  1208.         --[[ change direction and return new value for direction ]]
  1209.         if direction == "r" then
  1210.             T:turnRight(1)
  1211.             direction = "l"
  1212.         else
  1213.             T:turnLeft(1)
  1214.             direction = "r"
  1215.         end
  1216.         return direction    -- will only change direction variable if return value is used
  1217.     end
  1218.    
  1219.     function lib.emptyInventory(blockTypeD)
  1220.         --[[ Empty all except 32 of each sapling and 1 chest ]]
  1221.         if blockTypeD == nil then
  1222.             blockTypeD = T:getBlockType("down")
  1223.         end
  1224.         if blockTypeD:find("chest") ~= nil or blockTypeD:find("barrel") ~= nil then
  1225.             -- empty logs, apples, sticks and all but 1 stack of each sapling type
  1226.             T:emptyInventorySelection("down", {"chest", "oak_sapling", "birch_sapling", "spruce_sapling", "acacia_sapling", "jungle_sapling","dark_oak_sapling"},{1, 32, 32, 32, 32, 32, 32})
  1227.             return true
  1228.         else
  1229.             return false
  1230.         end
  1231.     end
  1232.    
  1233.     function lib.moveDown(blockTypeD)
  1234.         --[[ move down until hit ground. Break leaves and continue ]]
  1235.         if blockTypeD == nil then
  1236.             blockTypeD = T:getBlockType("down")
  1237.         end
  1238.         while blockTypeD == "" or blockTypeD:find("leaves") ~= nil do   -- move down, breaking leavse
  1239.             T:down(1)
  1240.             lib.suck()
  1241.             blockTypeD = T:getBlockType("down")
  1242.         end
  1243.         return blockTypeD
  1244.     end
  1245.    
  1246.     function lib.moveForward()
  1247.         --[[ Move forward 1 block only, go down to ground while air or leaves below ]]
  1248.         local blockTypeF = T:getBlockType("forward")
  1249.         local blockTypeD = T:getBlockType("down")
  1250.         if blockTypeF == "" or blockTypeF:find("leaves") ~= nil then    -- air or leaves ahead
  1251.             T:forward(1)                                                -- move forward, breaking leaves
  1252.             T:dig("up")                                                 -- remove leaves / low branches above to allow space for player
  1253.             lib.suck()
  1254.             blockTypeD = lib.moveDown()
  1255.             if not lib.emptyInventory(blockTypeD) then                  -- check if above a corner chest / barrel
  1256.                 if lib.isBorder(blockTypeD) then                        -- not above chest so check if above border
  1257.                     return false, blockTypeD                            -- above a border block so stop
  1258.                 end
  1259.             end
  1260.             blockTypeF = T:getBlockType("forward")
  1261.             return true, blockTypeF                                     -- moved ok, could be air or block in front
  1262.         end
  1263.         return false, blockTypeF                                        -- did not move, obstacle in front NOT leaves or air
  1264.     end
  1265.    
  1266.     function lib.moveUp(blockTypeF)
  1267.         --[[ Move up until air in front (dig leaves / harvest tree) ]]
  1268.         if blockTypeF == nil then
  1269.             blockTypeF = T:getBlockType("forward")
  1270.         end
  1271.         while blockTypeF:find("dirt") ~= nil or
  1272.               blockTypeF:find("grass_block") ~= nil or
  1273.               T:isVegetation(blockTypeF) do -- go up while dirt, grass-block or any vegetation in front
  1274.             T:up(1)
  1275.             blockTypeF = T:getBlockType("forward")
  1276.             if blockTypeF:find("log") ~= nil then
  1277.                 lib.harvestTree(blockTypeF)
  1278.                 return T:getBlockType("forward")
  1279.             elseif blockTypeF:find("leaves") ~= nil then
  1280.                 T:dig("forward")
  1281.                 return ""
  1282.             end
  1283.         end
  1284.         return blockTypeF   -- should be "" (air) or any border block
  1285.     end
  1286.    
  1287.     function lib.harvestTree(blockTypeF)
  1288.         --[[ Fell tree, returns true if double size ]]
  1289.         -- clsTurtle.harvestTree(extend, craftChest, direction)
  1290.         local saplingType = lib.getSaplingFromLogType(blockTypeF)
  1291.         local double = T:harvestTree(false, false, "forward")   -- assume single tree, will auto-discover
  1292.         lib.plantSapling(saplingType, double)
  1293.     end
  1294.    
  1295.     function lib.safeMove()
  1296.         --[[ move forward until border reached. loop breaks at that point ]]
  1297.         local blockTypeF = ""
  1298.         local success = true
  1299.         while success do
  1300.             success, blockTypeF = lib.moveForward()             -- move forward 1 block, return block type ahead
  1301.             if not success then                                 -- did not move forwards, block in the way: either log, dirt/grass, border block or vegetation
  1302.                 if blockTypeF:find("log") then                  -- tree found
  1303.                     lib.harvestTree(blockTypeF)
  1304.                     success = true                              -- block (log) removed, try again
  1305.                 else
  1306.                     success = not lib.isBorder(blockTypeF)      -- Is at border?: if is at border success = false so loop stops
  1307.                     if success then                             -- Not at border. Dirt/grass vegetation in front
  1308.                         blockTypeF = lib.moveUp(blockTypeF)     -- move up until leaves/log/air
  1309.                         success = not lib.isBorder(blockTypeF)  -- Is at border?: if is at border success = false so loop stops
  1310.                         if success then                         -- keep moving forward
  1311.                             if blockTypeF:find("log") then      -- tree found
  1312.                                 lib.harvestTree(blockTypeF)
  1313.                             end
  1314.                                                                 -- else blockTypeF is air/leaves  border has been checked
  1315.                         end
  1316.                     end
  1317.                 end
  1318.             end                                                 -- else success = true, 1 block moved so continue
  1319.         end
  1320.     end
  1321.    
  1322.     function lib.isBorder(blockType)
  1323.         --[[ Is the block log, dirt, grass_block, vegetation: non-border, or other:border]]
  1324.         if blockType == nil then                    -- not passed as parameter
  1325.             blockType = T:getBlockType("forward")
  1326.         end
  1327.         if blockType == "" then                     -- air ahead: not border
  1328.             return false, ""
  1329.         else                                        -- could be border or other
  1330.             if blockType:find("dirt") ~= nil or blockType:find("grass_block") ~= nil or blockType:find("log") ~= nil then -- either dirt, grass block or log
  1331.                 return false, blockType             -- dirt, grass, log: not border
  1332.             end
  1333.             if T:isVegetation(blockType) then       -- vegetation found: not border
  1334.                 return false, blockType
  1335.             end
  1336.         end
  1337.         return true, blockType                      -- dirt, grass_block, log and vegetation eliminated:must be border
  1338.     end
  1339.    
  1340.     function lib.inPosition()
  1341.         --[[ check if in lower left corner ]]
  1342.         local inPosition = true         -- assume correct
  1343.         if not turtle.detectDown() then -- hanging in mid-air
  1344.             return false
  1345.         end
  1346.         T:turnLeft(1)
  1347.         if lib.isBorder() then
  1348.             -- so far so good
  1349.             T:turnLeft(1)
  1350.             if not lib.isBorder() then  -- not in correct place
  1351.                 inPosition = false
  1352.             end
  1353.             T:turnRight(2)              -- return to original position
  1354.         else
  1355.             inPosition = false
  1356.             T:turnRight(1)              -- return to original position
  1357.         end
  1358.         return inPosition
  1359.     end
  1360.    
  1361.     function lib.findBorder()
  1362.         --[[ assume started after reset. if log above harvest tree else return to ground. Find starting corner]]
  1363.         local blockType = T:getBlockType("up")                  -- dig any logs above, return to ground
  1364.         local log = "sapling"
  1365.         if blockType:find("log") ~= nil then                    -- originally felling a tree so complete it
  1366.             log = lib.getSaplingFromLogType(blockType)
  1367.             local double = T:harvestTree(false, false, "up")    -- assume single tree, will auto-discover
  1368.             lib.plantSapling(log, double)
  1369.         else                                                    -- no log above so go downm
  1370.             blockType = lib.moveDown()                          -- return to ground (or vegetation)
  1371.         end
  1372.         lib.safeMove()                                          -- move forward until border reached
  1373.         T:turnRight(1)
  1374.         lib.safeMove()                                          -- move forward until second border reached
  1375.         T:turnRight(1)                                          -- should now be in correct position
  1376.         lib.emptyInventory()                                    -- empty inventory if above a chest
  1377.     end
  1378.    
  1379.     local direction = "r"
  1380.     local blockTypeF = ""
  1381.     local success = false
  1382.     if not lib.inPosition() then
  1383.         lib.findBorder()
  1384.     end
  1385.     local secondBorderFound = false
  1386.     while not secondBorderFound do
  1387.         lib.safeMove()                                                      -- moves forward until reaches border forward or below
  1388.         lib.turn(direction)                                                 -- turn r or l. direction is not changed
  1389.         success, blockTypeF = lib.isBorder()                                -- no blockType passed as parameter so will return current block in new forward direction
  1390.         if success then
  1391.             secondBorderFound = true                                        -- game over
  1392.         elseif blockTypeF:find("log") ~= nil then                           -- tree in front
  1393.             lib.harvestTree(blockTypeF)
  1394.         elseif blockTypeF == "" or blockTypeF:find("leaves") ~= nil then    -- air or leaves in front
  1395.             T:forward(1)                                                    -- move forward 1 block
  1396.             lib.moveDown()                                                  -- go down if required
  1397.         elseif  blockTypeF:find("dirt") ~= nil or
  1398.                 blockTypeF:find("grass_block") ~= nil or
  1399.                 T:isVegetation(blockTypeF) then                             -- dirt, grass_block or vegetation in front
  1400.             blockTypeF = lib.moveUp(blockTypeF)                             -- move up until air or border ahead.
  1401.             if lib.isBorder(blockTypeF) then                                -- border ahead
  1402.                 secondBorderFound = true
  1403.             else                                                            -- air ahead                                   
  1404.                 T:forward(1)                                                -- move forward 1 block
  1405.             end
  1406.         end
  1407.         direction = lib.turn(direction)                                     -- turn r or l. direction is changed to opposite
  1408.     end
  1409.     lib.moveDown()                                                          -- return to ground level
  1410.     lib.emptyInventory()
  1411.     return {}
  1412. end
  1413.  
  1414. local function clearArea(R) -- 71, called from 22
  1415.     local evenWidth = false
  1416.     local evenHeight = false
  1417.     local loopWidth
  1418.     -- go(path, useTorch, torchInterval, leaveExisting)
  1419.     if R.width % 2 == 0 then
  1420.         evenWidth = true
  1421.         loopWidth = R.width / 2
  1422.     else
  1423.         loopWidth = math.ceil(R.width / 2)
  1424.     end
  1425.     if R.length % 2 == 0 then
  1426.         evenHeight = true
  1427.     end
  1428.     turtle.select(1)
  1429.     -- clear an area between 2 x 4 and 32 x 32
  1430.     -- if R.width is even no, then complete the up/down run
  1431.     -- if R.width odd no then finish at top of up run and reverse
  1432.     -- should be on flat ground, check voids below, harvest trees
  1433.     for x = 1, loopWidth do
  1434.         -- Clear first column (up)
  1435.         for y = 1, R.length do
  1436.             if R.useBlockType == "dirt" then
  1437.                 if not turtle.detectDown() then
  1438.                     T:place("minecraft:dirt", -1, "down", true)
  1439.                 else --if not water, dirt, grass , stone then replace with dirt
  1440.                     blockType, blockModifier = T:getBlockType("down")
  1441.                     if blockType ~= "" then
  1442.                         if blockType ~= "minecraft:dirt" and blockType ~= "minecraft:grass_block" then
  1443.                             turtle.digDown()
  1444.                             T:place("minecraft:dirt", -1, "down", true)
  1445.                         end
  1446.                     end
  1447.                 end
  1448.             end
  1449.             if y < R.length then
  1450.                 T:go("F1+1", false,0,false)
  1451.             end
  1452.         end
  1453.         -- clear second column (down)
  1454.         if x < loopWidth or (x == loopWidth and evenWidth) then -- go down if on R.width 2,4,6,8 etc
  1455.             T:go("R1F1+1R1", false,0,false)
  1456.             for y = 1, R.length do
  1457.                 if R.useBlockType == "dirt" then
  1458.                     if not turtle.detectDown() then
  1459.                         T:place("minecraft:dirt", -1, "down", true)
  1460.                     else
  1461.                         blockType, blockModifier = T:getBlockType("down")
  1462.                         if blockType ~= "" then
  1463.                             if blockType ~= "minecraft:dirt" and blockType ~= "minecraft:grass_block" then
  1464.                                 turtle.digDown()
  1465.                                 T:place("minecraft:dirt", -1, "down", true)
  1466.                             end
  1467.                         end
  1468.                     end
  1469.                 end
  1470.                 if y < R.length then
  1471.                     T:go("F1+1", false, 0, false)
  1472.                 end
  1473.             end
  1474.             if x < loopWidth then
  1475.                 T:go("L1F1+1L1", false,0,false)
  1476.             else
  1477.                 T:turnRight(1)
  1478.                 T:forward(R.width - 1)
  1479.                 T:turnRight(1)
  1480.             end
  1481.         else -- equals R.width but is 1,3,5,7 etc
  1482.             T:turnLeft(2) --turn round 180
  1483.             T:forward(R.length - 1)
  1484.             T:turnRight(1)
  1485.             T:forward(R.width - 1)
  1486.             T:turnRight(1)
  1487.         end
  1488.     end
  1489.     return {}
  1490. end
  1491.  
  1492. local function clearRectangle(R) -- 72
  1493.     --local function clearRectangle(width, length, up, down)
  1494.     -- height = 0: one level, 1 = +up, 2 = +down, 3 = +up/down
  1495.     local lib = {}
  1496.     function lib.UpDown(length)
  1497.         for l = 1, length do
  1498.             T:go("x0x2F1x0x2")
  1499.         end
  1500.     end
  1501.    
  1502.     function lib.Up(length)
  1503.         for l = 1, length do
  1504.             T:go("x0F1x0")
  1505.         end
  1506.     end
  1507.    
  1508.     function lib.Down(length)
  1509.         for l = 1, length do
  1510.             T:go("x2F1x2")
  1511.         end
  1512.     end
  1513.    
  1514.     function lib.Forward(length)
  1515.         T:forward(length)
  1516.     end
  1517.    
  1518.     -- could be 1 wide x xx R.length (trench) R.up and return
  1519.     -- could be 2+ x 2+
  1520.     -- even no of runs return after last run
  1521.     -- odd no of runs forward, back, forward, reverse and return
  1522.     turtle.select(1)
  1523.     if R.width == 1 then                    -- single block trench ahead only
  1524.         if R.up and R.down then             -- single block wide trench dig R.up and R.down = 3 blocks deep
  1525.             lib.UpDown(R.length - 1)
  1526.         elseif R.up then                    -- single block wide trench dig R.up = 2 blocks deep
  1527.             lib.Up(R.length - 1)
  1528.         elseif R.down then              -- single block wide trench dig R.down = 2 blocks deep
  1529.             lib.Down(R.length - 1)
  1530.         else                            -- single block wide = 1 block deep
  1531.             lib.Forward(R.length - 1)
  1532.         end
  1533.         T:turnRight(2)                  -- turn at the top of the run
  1534.         T:forward(R.length - 1)         -- return to start
  1535.         T:turnRight(2)                  -- turn round to original position
  1536.     else                                -- R.width 2 or more blocks
  1537.         local iterations = 0            -- R.width = 2, 4, 6, 8 etc
  1538.         if R.width % 2 == 1 then        -- R.width = 3, 5, 7, 9 eg R.width 7
  1539.             iterations = (R.width - 1) / 2 -- iterations 1, 2, 3, 4 for widths 3, 5, 7, 9
  1540.         else
  1541.             iterations = R.width / 2        -- iterations 1, 2, 3, 4 for widths 2, 4, 6, 8
  1542.         end
  1543.         for i = 1, iterations do        -- eg 3 blocks wide, iterations = 1
  1544.             if R.up and R.down then                         -- dig R.up and R.down
  1545.                 lib.UpDown(R.length - 1)
  1546.                 T:go("x0x2R1F1x0x2R1x0x2")              -- turn round
  1547.                 lib.UpDown(R.length - 1)
  1548.             elseif R.up then                                -- dig R.up
  1549.                 lib.Up(R.length - 1)
  1550.                 T:go("x0R1F1x0R1x0")
  1551.                 lib.Up(R.length - 1)
  1552.             elseif R.down then                          -- dig R.down
  1553.                 lib.Down(R.length - 1)
  1554.                 T:go("x2R1F1x2R1x2")
  1555.                 lib.Down(R.length - 1)
  1556.             else                                        -- no digging R.up or R.down
  1557.                 lib.Forward(R.length - 1)
  1558.                 T:go("R1F1R1")
  1559.                 lib.Forward(R.length - 1)
  1560.             end
  1561.             -- if 1 less than end, reposition for next run
  1562.             if i < iterations then
  1563.                 T:go("L1F1L1", false, 0, false)
  1564.             end
  1565.         end
  1566.         if R.width % 2 == 1 then  -- additional run and return to base needed
  1567.             T:go("L1F1L1", false, 0, false)
  1568.             if R.up and R.down then
  1569.                 lib.UpDown(R.length - 1)
  1570.             elseif R.up then
  1571.                 lib.Up(R.length - 1)
  1572.             elseif R.down then
  1573.                 lib.Down(R.length - 1)
  1574.             else
  1575.                 lib.Forward(R.length - 1)
  1576.             end
  1577.             T:turnRight(2)
  1578.             T:forward(R.length - 1)
  1579.         end
  1580.         T:go("R1F"..R.width - 1 .."R1", false, 0, false)
  1581.     end
  1582.     return {}
  1583. end
  1584.  
  1585. local function clearPerimeter(R) -- 74
  1586.     local lib = {}
  1587.     function lib.UpDown(length)
  1588.         for l = 1, length do
  1589.             T:go("x0x2F1x0x2")
  1590.         end
  1591.     end
  1592.    
  1593.     function lib.Up(length)
  1594.         for l = 1, length do
  1595.             T:go("x0F1x0")
  1596.         end
  1597.     end
  1598.    
  1599.     function lib.Down(length)
  1600.         for l = 1, length do
  1601.             T:go("x2F1x2")
  1602.         end
  1603.     end
  1604.    
  1605.     function lib.Forward(length)
  1606.         T:forward(length)
  1607.     end
  1608.    
  1609.     if R.up and R.down then
  1610.         for i = 1, 2 do
  1611.             lib.UpDown(R.length - 1)
  1612.             T:turnRight(1)
  1613.             lib.UpDown(R.width - 1)
  1614.             T:turnRight(1)
  1615.         end
  1616.     elseif R.up then
  1617.         for i = 1, 2 do
  1618.             lib.Up(R.length - 1)
  1619.             T:turnRight(1)
  1620.             lib.Up(R.width - 1)
  1621.             T:turnRight(1)
  1622.         end
  1623.     elseif R.down then
  1624.         for i = 1, 2 do
  1625.             lib.Down(R.length - 1)
  1626.             T:turnRight(1)
  1627.             lib.Down(R.width - 1)
  1628.             T:turnRight(1)
  1629.         end
  1630.     else
  1631.         for i = 1, 2 do
  1632.             lib.Forward(R.length - 1)
  1633.             T:turnRight(1)
  1634.             lib.Forward(R.width - 1)
  1635.             T:turnRight(1)
  1636.         end
  1637.     end
  1638.     return {}
  1639. end
  1640.  
  1641. local function clearBuilding(R) -- 75, 43
  1642.     --[[
  1643.     Clear the outer shell of a building, leaving inside untouched. Optional floor/ceiling removal
  1644.     clearBuilding(R)
  1645.     R.subChoice = 1-'up' or 2-'down'
  1646.     R.data.ceiling = true / false
  1647.     R.data.floor = true / false
  1648.     ]]
  1649.     local height = 1
  1650.     local remaining = R.height -- eg 5
  1651.     local start = true
  1652.     local finish = false
  1653.     local lib = {}
  1654.    
  1655.     function lib.floorOrCeiling(R)
  1656.         T:go("F1R1 F1L1")
  1657.         R.length = R.length - 2
  1658.         R.width = R.width - 2
  1659.         clearRectangle(R)
  1660.         R.length = R.length + 2
  1661.         R.width = R.width + 2
  1662.         T:go("L1F1R1")
  1663.         utils.goBack(1)
  1664.     end
  1665.    
  1666.     function lib.singleLayer(R)
  1667.         R.up = false
  1668.         R.down = false
  1669.         if start then
  1670.             if R.data.ceiling or R.data.floor then  -- floor / ceiling to go. only one layer, so clearRectangle
  1671.                 lib.floorOrCeiling(R)
  1672.             end
  1673.             start = false
  1674.         end
  1675.         if finish then
  1676.             if R.data.ceiling or R.data.floor then  -- floor / ceiling to go. only one layer, so clearRectangle
  1677.                 lib.floorOrCeiling(R)
  1678.             end
  1679.             finish = false
  1680.         end
  1681.         clearPerimeter(R)                       -- no floor / ceiling
  1682.     end
  1683.    
  1684.     function lib.doubleLayer(R)
  1685.         R.up = false
  1686.         R.down = false
  1687.         if start then
  1688.             if R.data.floor and R.subChoice == 1 then       -- going up and floor needs removing
  1689.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1690.             elseif R.data.ceiling and R.subChoice == 2 then -- going down and ceiling needs removing
  1691.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1692.             end
  1693.             start = false
  1694.         end
  1695.         if finish then
  1696.             if R.data.ceiling and R.subChoice == 1 then     -- going down and ceiling needs removing
  1697.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1698.             elseif R.data.floor and R.subChoice == 2 then   -- going down and floor needs removing
  1699.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1700.             end
  1701.             finish = false
  1702.         end
  1703.         if R.subChoice == 1 then
  1704.             R.up = true
  1705.         else
  1706.             R.down = true
  1707.         end
  1708.         clearPerimeter(R)
  1709.     end
  1710.    
  1711.     function lib.tripleLayer(R)
  1712.         -- turtle in centre layer
  1713.         R.up = false
  1714.         R.down = false
  1715.         if start then
  1716.             if R.data.floor and R.subChoice == 1 then       -- going up and floor needs removing
  1717.                 height = height + utils.move(R, 1, true)    -- move down 1 block
  1718.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1719.                 height = height + utils.move(R, 1)      -- move up 1 block
  1720.             elseif R.data.ceiling and R.subChoice == 2 then -- going down and ceiling needs removing
  1721.                 height = height + utils.move(R, 1, true)    -- move up 1 block
  1722.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1723.                 height = height + utils.move(R, 1)      -- move down 1 block
  1724.             end
  1725.             start = false
  1726.         end
  1727.         if finish then
  1728.             if R.data.ceiling and R.subChoice == 1 then     -- going up and ceiling needs removing
  1729.                 height = height + utils.move(R, 1, true)                    -- move down 1 block
  1730.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1731.                 height = height + utils.move(R, 1)                          -- move up 1 block
  1732.             elseif R.data.floor and R.subChoice == 2 then   -- going down and floor needs removing
  1733.                 height = height + utils.move(R, 1, true)                    -- move up 1 block
  1734.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1735.                 height = height + utils.move(R, 1)                          -- move up 1 block
  1736.             end
  1737.             finish = false
  1738.         end
  1739.         R.up = true
  1740.         R.down = true
  1741.         clearPerimeter(R)
  1742.     end
  1743.     --[[
  1744.     R.data = "up" or "down" as direction of travel
  1745.     R.up = true to remove ceiling
  1746.     R.down = true to remove floor
  1747.     ]]
  1748.     R.silent = true
  1749.     if R.height < 3 then                        --1-3 layers only
  1750.         if R.height == 1 then                   --one layer only
  1751.             lib.singleLayer(R)
  1752.         elseif R.height == 2 then               --2 layers only current + dig up/down
  1753.             lib.doubleLayer(R)
  1754.         end
  1755.     else -- 3 or more levels
  1756.         height = height + utils.move(R, 1)                          -- move up/down 1 block for first layer
  1757.         while remaining >= 3 do -- min 3 levels
  1758.             lib.tripleLayer(R)
  1759.             remaining = remaining - 3
  1760.             if remaining == 0 then              -- all finished
  1761.                 break
  1762.             elseif remaining == 1 then
  1763.                 height = height + utils.move(R, 2)                  -- move up/down 2 blocks
  1764.                 lib.singleLayer(R)
  1765.             elseif remaining == 2 then
  1766.                 height = height + utils.move(R, 2)                  -- move up/down 2 blocks
  1767.                 lib.doubleLayer(R)
  1768.             else
  1769.                 height = height + utils.move(R, 3)                  -- move up/down 3 blocks
  1770.                 if remaining == 3 then
  1771.                     finish = true
  1772.                 else
  1773.                     --height = height + 3
  1774.                 end
  1775.             end
  1776.         end
  1777.     end
  1778.    
  1779.     if height > 1 then
  1780.         utils.move(R, height - 1, true) -- reverse direction
  1781.     end
  1782.    
  1783.     return {}
  1784. end
  1785.  
  1786. local function clearMineshaft(R, equippedRight, equippedLeft, inInventory) -- 19
  1787.     local lib = {}
  1788.    
  1789.     function lib.checkCobweb(directions, inInventory)
  1790.         assert(type(directions) == "table", "directions must be a table eg {'up','down'}")
  1791.         for _, direction in ipairs(directions) do
  1792.             local blockType = T:getBlockType(direction)
  1793.             if inInventory == "minecraft:diamond_sword" then -- using a sword
  1794.                 local side = "left"
  1795.                
  1796.                 if blockType:find("cobweb") ~= nil then
  1797.                     --clsTurtle.equip(self, side, useItem, useDamage)
  1798.                     if equippedRight == "minecraft:diamond_pickaxe" then
  1799.                         side = "right"
  1800.                     end
  1801.                     T:equip(side, "minecraft:diamond_sword")
  1802.                     T:dig(direction)
  1803.                     T:equip(side, "minecraft:diamond_pickaxe")
  1804.                 elseif blockType ~= "" then
  1805.                     T:dig(direction)
  1806.                 end
  1807.             else
  1808.                 T:dig(direction)
  1809.             end
  1810.         end
  1811.     end
  1812.  
  1813.     -- check position by rotating until facing away from wall
  1814.     length = 0
  1815.     torch = 0
  1816.     turns = 0
  1817.     while not turtle.detect() do
  1818.         T:turnRight(1)
  1819.         turns = turns + 1
  1820.         if turns > 4 then
  1821.             return {"I am not facing a wall. Unable to continue"}
  1822.         end
  1823.     end
  1824.     T:turnRight(2)
  1825.     -- move forward until obstructed, digging up/down. place torches
  1826.     while not turtle.detect() do
  1827.         lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1828.         length = length + 1
  1829.         torch = torch + 1
  1830.         if torch == R.torchInterval then
  1831.             torch = 0
  1832.             T:place("minecraft:torch", -1, "down", false) ---(self, blockType, damageNo, direction, leaveExisting, signText)
  1833.         end
  1834.         lib.checkCobweb({"forward"}, inInventory) -- dig cobweb or any other block in front
  1835.         T:forward(1)
  1836.     end
  1837.     -- turn right, forward, right, return to start with up/down dig
  1838.     T:go("R1")
  1839.     lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1840.     T:go("F1R1")
  1841.     for i = 1, length, 1 do
  1842.         lib.checkCobweb({"up", "down", "forward"}, inInventory) -- dig cobweb or any other block up/down/forward
  1843.         T:forward(1)
  1844.     end
  1845.     -- move to other wall and repeat.
  1846.     T:go("R1")
  1847.     lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1848.     T:go("F1")
  1849.     lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1850.     T:go("F1R1")
  1851.     lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1852.     for i = 1, length, 1 do
  1853.         lib.checkCobweb({"up", "down", "forward"}, inInventory) -- dig cobweb or any other block up/down/forward
  1854.         T:forward(1)
  1855.     end
  1856.     lib.checkCobweb({"up", "down"}, inInventory) -- dig cobweb or any other block up/down/forward
  1857.    
  1858.     return {}
  1859. end
  1860.  
  1861. local function clearMonumentLayer(R) -- 85
  1862.     R.up = true
  1863.     R.down = true
  1864.     R.silent = true
  1865.     if R.subChoice == 0 then
  1866.         R.up = false
  1867.         R.down = false
  1868.     end
  1869.     -- send turtle down until it hits bottom
  1870.     -- then clear rectangle of given size
  1871.     -- start above water, usually on cobble scaffold above monument
  1872.     if T:detect("down") then -- in case not over wall
  1873.         T:forward(1)
  1874.     end
  1875.     local height = 1
  1876.     -- go down until solid block detected
  1877.     while utils.clearVegetation("down") do
  1878.         T:down(1)
  1879.         height = height + 1
  1880.     end
  1881.     T:down(1)
  1882.     height = height + 1
  1883.     clearRectangle(R)
  1884.     T:up(height - 1)
  1885.    
  1886.     return {}
  1887. end
  1888.  
  1889. local function clearWaterPlants(R) -- 87
  1890.     local lib = {}
  1891.    
  1892.     function lib.getLength()
  1893.         local length = 1
  1894.         print("Checking water length")
  1895.         while utils.clearVegetation("forward") do
  1896.             T:forward(1)
  1897.             length = length + 1
  1898.         end
  1899.         for i = 1, length do
  1900.             turtle.back()
  1901.         end
  1902.         return length
  1903.     end
  1904.    
  1905.     function lib.clearDown(D)
  1906.         while utils.clearVegetation("down") do --clears any grass or sea plants, returns true if air or water, bubble column or ice
  1907.             T:down(1)
  1908.             D.depth = D.depth + 1
  1909.         end
  1910.         -- if slab at bottom, replace with solid block
  1911.         D.blockType = T:getBlockType("down")
  1912.         if D.blockType:find("slab") ~= nil then
  1913.             T:go("C2")
  1914.         end
  1915.         if D.depth > D.maxDepth then
  1916.             D.maxDepth = D.depth
  1917.         end
  1918.        
  1919.         return D
  1920.     end
  1921.    
  1922.     function lib.clearLength(D)
  1923.         local moves = 0
  1924.         local blockHeight = 1
  1925.         D.floorLength = 0 -- reset
  1926.         while moves < D.length - 1 do
  1927.             if utils.clearVegetation("forward") then
  1928.                 T:forward(1)
  1929.                 moves = moves + 1
  1930.                 if turtle.detectUp() then -- could be on monument going under arch, or faulty monument floor
  1931.                     if not D.monumentArchesClear then
  1932.                         D = lib.checkArches(D)
  1933.                     end
  1934.                 end
  1935.                 local temp = D.depth
  1936.                 D = lib.clearDown(D) -- go down if in water/air
  1937.                 if blockHeight == 4 and D.depth - temp == 3 then -- could be just gone over 3 block high column in ocean monument
  1938.                     if not D.monumentTopClear then
  1939.                         D = lib.checkTop(D)
  1940.                     end
  1941.                     blockHeight = 1
  1942.                 end
  1943.                 if D.useBlockType == "prismarine" then
  1944.                     if D.blockType:find("prismarine") == nil then
  1945.                         -- on monument floor so restrict forward movement to 8 blocks
  1946.                         D.floorLength = D.floorLength + 1
  1947.                         if D.floorLength == 8 then
  1948.                             D.blockType = T:getBlockType("forward")
  1949.                             while D.blockType:find("prismarine") == nil do
  1950.                                 T:up(1)
  1951.                                 D.blockType = T:getBlockType("forward")
  1952.                             end
  1953.                             D.floorLength = 0
  1954.                         end
  1955.                     end
  1956.                 end
  1957.                 if moves >= D.length - 1 then
  1958.                     D.width = D.width + 1   -- another length completed so increase width
  1959.                     return D
  1960.                 end
  1961.             else -- block in front
  1962.                 blockHeight = 1
  1963.                 local waterAbove = utils.clearVegetation("up")
  1964.                 local waterAhead = utils.clearVegetation("forward") -- true if air/water in front
  1965.                 while not waterAhead do     -- solid block in front
  1966.                     if waterAbove then      -- move up
  1967.                         T:up(1)
  1968.                         D.depth = D.depth - 1
  1969.                         blockHeight = blockHeight + 1
  1970.                         if D.depth < 1 then
  1971.                             D.width = D.width + 1   -- another length completed so increase width
  1972.                             return D
  1973.                         end
  1974.                     else                    -- block above so go back
  1975.                         while not waterAbove do
  1976.                             utils.goBack()  --  returns true if no object behind, but moves anyway
  1977.                             waterAbove = utils.clearVegetation("up")
  1978.                             moves = moves - 1
  1979.                             if moves == 0 then
  1980.                                 T:up(1)
  1981.                                 D.depth = D.depth - 1
  1982.                                 waterAbove = utils.clearVegetation("up")
  1983.                                 while not waterAbove do
  1984.                                     T:up(1)
  1985.                                     D.depth = D.depth - 1
  1986.                                 end
  1987.                             end
  1988.                         end
  1989.                         -- go up 1 to prevent loop
  1990.                         T:up(1)
  1991.                         D.depth = D.depth - 1
  1992.                     end
  1993.                     waterAbove = utils.clearVegetation("up")
  1994.                     waterAhead = utils.clearVegetation("forward")
  1995.                 end
  1996.             end
  1997.         end
  1998.         D.width = D.width + 1   -- another length completed so increase width
  1999.         D.maxDepth = D.maxDepth + 1 -- +1 to allow for starting pos in top layer
  2000.        
  2001.         return D
  2002.     end
  2003.    
  2004.     function lib.checkArches(D)
  2005.         -- gone under a block so could be monument arch (6)
  2006.         if T:getBlockType("up"):find("prismarine") ~= nil then -- confirm on monument, not previously cleared
  2007.             local direction = ""    -- initialise direction
  2008.             T:go("B1U2F1R1")
  2009.             if T:getBlockType("forward"):find("prismarine") ~= nil then -- correct guess
  2010.                 direction = "R"
  2011.             else    -- wrong direction. turn round and check other side
  2012.                 T:go("R2")
  2013.                 if T:getBlockType("forward"):find("prismarine") ~= nil then
  2014.                     direction = "L"
  2015.                 end
  2016.             end
  2017.             local path = "U1F1 U1F3 D1F1 D1R2 U2F5 D2"
  2018.             --for i = 1, 6 do
  2019.             T:go(path) -- clears arch top 1 and returns
  2020.             T:go(direction.."1F6"..direction.."1")
  2021.             T:go(path) -- clears arch top 2 and returns
  2022.             T:go(direction.."1F6"..direction.."1")
  2023.             T:go(path) -- clears arch top 3 and returns
  2024.             T:go(direction.."1F9"..direction.."1")
  2025.             T:go(path) -- clears arch top 4 and returns
  2026.             T:go(direction.."1F6"..direction.."1")
  2027.             T:go(path) -- clears arch top 5 and returns
  2028.             T:go(direction.."1F6"..direction.."1")
  2029.             T:go(path) -- clears arch top 6 and returns
  2030.            
  2031.             T:go(direction.."3F34"..direction.."2D2F1")
  2032.             D.monumentArchesClear =  true
  2033.         end
  2034.         return D
  2035.     end
  2036.    
  2037.     function lib.checkTop(D)
  2038.         -- gone over 3 block column so could be at the top of ocean monument
  2039.         if T:getBlockType("down"):find("prismarine") ~= nil then -- confirm on monument, not previously cleared
  2040.             local direction = ""    -- initialise direction
  2041.             T:go("U3R1")            -- up to top of column and try right side
  2042.             if T:getBlockType("forward"):find("prismarine") ~= nil then -- correct guess
  2043.                 direction = "L"
  2044.             else    -- wrong direction. turn round and check other side
  2045.                 T:go("R2")
  2046.                 if T:getBlockType("forward"):find("prismarine") ~= nil then
  2047.                     direction = "R"
  2048.                 end
  2049.             end
  2050.             if direction ~= "" then -- facing single block on layer 2
  2051.                 T:go("U1F6"..direction.."1F5".. direction.."1F5"..direction.."1F5"..direction.."1") -- clear 4 single blocks
  2052.                 T:go("F1U1"..direction.."1F1"..direction.."3") -- on top of monument
  2053.                 T:go("F3".. direction.."1F3"..direction.."1F3"..direction.."1F3"..direction.."3") -- clear top, face return
  2054.                 T:go("F2D5"..direction.."3B1")
  2055.             end
  2056.             D.monumentTopClear = true
  2057.         end
  2058.         return D
  2059.     end
  2060.    
  2061.     function lib.findBlockTypeEnd(D)
  2062.         D.blockType = "" -- reset
  2063.         repeat
  2064.             if utils.clearVegetation("forward") then
  2065.                 T:forward(1)
  2066.                 D = lib.clearDown(D) -- go down if in water/air, D.blockType is updated with floor type
  2067.             else -- block in front
  2068.                 local waterAbove = utils.clearVegetation("up")
  2069.                 local waterAhead = utils.clearVegetation("forward") -- true if air/water in front
  2070.                 while not waterAhead do     -- solid block in front
  2071.                     if waterAbove then      -- move up
  2072.                         T:up(1)
  2073.                     else                    -- block above so go back
  2074.                         while not waterAbove do
  2075.                             utils.goBack()  --  returns true if no object behind, but moves anyway
  2076.                             waterAbove = utils.clearVegetation("up")
  2077.                         end
  2078.                     end
  2079.                     waterAbove = utils.clearVegetation("up")
  2080.                     waterAhead = utils.clearVegetation("forward")
  2081.                 end
  2082.             end
  2083.         until D.blockType:find(D.useBlockType) == nil
  2084.         -- now above a non-prismarine block, facing away from monument
  2085.         T:turnRight(2) -- facing monument
  2086.         D.blockType = T:getBlockType("forward")
  2087.         while D.blockType:find(D.useBlockType) ~= nil do
  2088.             T:up(1)
  2089.             D.blockType = T:getBlockType("forward")
  2090.         end
  2091.         T:go("F1L1")
  2092.         D.blockType = T:getBlockType("down")
  2093.         while D.blockType:find(D.useBlockType) ~= nil do
  2094.             T:forward(1)
  2095.             D.blockType = T:getBlockType("down")
  2096.         end
  2097.         turtle.back()
  2098.         -- should now be at end of monument base
  2099.     end
  2100.    
  2101.     function lib.turn(D)
  2102.         local direction = "R"
  2103.         if not D.facingForward then
  2104.             direction = "L"
  2105.         end
  2106.         T:go(direction.. 1)
  2107.         if utils.clearVegetation("forward") then
  2108.             T:forward(1)
  2109.             --D.depth = D.depth + lib.clearDown(depth)
  2110.             D = lib.clearDown(D)
  2111.         else
  2112.             while not utils.clearVegetation("forward") do
  2113.                 T:up(1)
  2114.                 D.depth = D.depth - 1
  2115.             end
  2116.             T:forward(1)
  2117.         end
  2118.         T:go(direction.. 1)
  2119.         D.facingForward = not D.facingForward
  2120.        
  2121.         return D
  2122.     end
  2123.  
  2124.     local D = {}
  2125.     D.depth = 0
  2126.     D.maxDepth = 0
  2127.     D.blockType = ""
  2128.     D.useBlockType = R.useBlockType -- "" or "prismarine"
  2129.     D.length = 0    -- copy of R.length used in lib.clearLength
  2130.     D.width = 0     -- increased every iteration
  2131.     D.facingForward = true
  2132.     D.monumentTopClear = false
  2133.     D.monumentArchesClear = false
  2134.     D.inWater = false
  2135.     D.onWater = false
  2136.     D.inWater, D.onWater = utils.getWaterStatus()
  2137.     D.floorLength = 0 -- used on monument floor
  2138.    
  2139.     if R.data == "clearWaterPlants" then -- NOT monument corner discovery
  2140.         D.inWater, D.onWater = utils.startWaterFunction(D.onWater, D.inWater, 2, true) -- move into water
  2141.         if R.length == 0 then
  2142.             R.length = lib.getLength()
  2143.         end
  2144.         if R.width == 0 then
  2145.             T:turnRight(1)
  2146.             R.width = lib.getLength()
  2147.             T:turnLeft(1)
  2148.         end
  2149.     end
  2150.     D.length = R.length
  2151.     D = lib.clearDown(D) -- go down to floor, set depth, maxDepth, blockType
  2152.     if R.data == "clearWaterPlants" then -- NOT monument corner discovery
  2153.         if R.width == 1 then
  2154.             print("Single row clearing")
  2155.             D = lib.clearLength(D) --D.width also increased
  2156.         else
  2157.             while D.width < R.width do -- D.width starts at 0
  2158.                 -- now on floor, move along sea/river bed following contour
  2159.                 D = lib.clearLength(D) --D.width also increased
  2160.                 -- now turn and repeat
  2161.                 if D.width < R.width then  
  2162.                     D = lib.turn(D)
  2163.                     if D.depth <= 0 then
  2164.                         break
  2165.                     end
  2166.                 end
  2167.             end
  2168.         end
  2169.         -- finished so return to surface
  2170.         T:up(1) -- up 1 to check for water below
  2171.         while T:getBlockType("down"):find("water") ~= nil do
  2172.             T:up(1)
  2173.         end
  2174.         T:down(2) -- return to surface
  2175.         --[[while utils.clearVegetation("forward") do
  2176.             T:forward(1)
  2177.         end]]
  2178.     elseif R.data == "oceanMonumentColumns" then -- monument corner discovery
  2179.         -- this function used to find edge of monument base
  2180.         if D.blockType:find(D.useBlockType) ~= nil then
  2181.             lib.findBlockTypeEnd(D)
  2182.             return {""}
  2183.         else
  2184.             T:up(D.depth)
  2185.             return {"Prismarine not found on ocean floor"}
  2186.         end
  2187.     end
  2188.     if R.silent then
  2189.         return {D.maxDepth, R.length}
  2190.     else
  2191.         return {""}
  2192.     end
  2193. end
  2194.  
  2195. local function clearMountainSide(R) -- 78
  2196.     --[[
  2197.     First row              outward  l  s  f  mid    (length, start, finish, midPoint)
  2198.  
  2199.           >|*|*|           true                     lib.clearRow() moves: 7-5=2, midPoint starts at 2
  2200.           +|*|*|
  2201.           +|*|*|
  2202.           ^|*|*|        <  false    7  5  6  2      lib.clearRow() moves: 9-2=7, midPoint starts at -4 -1 = -5
  2203.            |*|*|*|      +
  2204.          |*|*|*|*|*|    +
  2205.       >  |*|*|*|*|*|    ^  true     9  2  6  -4     lib.getStartingLength(). Ends 1 block after block finish
  2206.       ^|*|*|*|*|*|*|*|*|                            starts here, moves up 1
  2207.         1 2 3 4 5 6 7 8                             block index
  2208.          
  2209.     Second row                outward l  s  f  mid
  2210.                  <            false
  2211.                  +
  2212.           |*|*|  +
  2213.        >|*|*|*|*|^            true
  2214.        +|*|*|*|*|
  2215.        +|*|*|*|*|
  2216.        ^|*|*|*|*|          <  false   6  5  6  2
  2217.         |*|*|*|*|*|*|      +
  2218.       |*|*|*|*|*|*|*|*|    +
  2219.       |*|*|*|>|*|*|*|*|    ^  true    7+5   5 -7    lib.getHalf(R); goBack(7)
  2220.     |*|*|*|*|*|*|*|*|*|*|*|                           starts at midPoint of previous row eg block 4
  2221.      0 1 2 3 4 5 6 7 8 9 10
  2222.     ]]
  2223.    
  2224.     -- variables declared before lib for them to be used within lib as is then in scope
  2225.     local turn = "R"
  2226.     local oTurn = "L"
  2227.     if R.subChoice == 1 then    -- remove left side
  2228.         turn = "L"
  2229.         oTurn = "R"
  2230.     end
  2231.     local outward = true        -- direction flag
  2232.    
  2233.     local lib = {}
  2234.    
  2235.     function lib.isAnyAbove(above)
  2236.         T:saveToLog("lib.isAnyAbove: "..utils.tableConcat(above, ", "), false)
  2237.         for k,v in ipairs(above) do
  2238.             if v then
  2239.                 T:saveToLog("lib.isAnyAbove Found: "..k , false)
  2240.                 return true
  2241.             end
  2242.         end
  2243.         return false
  2244.     end
  2245.        
  2246.     function lib.clearLevel(R, above)   -- eg 9, 2, 6, -4 from lib.getStartingLength OR 7, 5, 6, 3 from previous
  2247.         -- clearLevel always follows either lib.getStartingLength or a previous lib.clearLevel
  2248.         -- midPoint should be adjusted as turtle moves to reflect current row length
  2249.         if #above == 0 then return above, 1 end
  2250.         --local index = 0
  2251.         local minMoves = math.floor(#above / 2)
  2252.         local up, forward, down = lib.getDetect()
  2253.         if outward then                                     -- follow table indexes
  2254.             for x = 1, minMoves do                          -- clear first half
  2255.                 above[x] = up                               -- reset this with new value
  2256.                 T:go("x0x2F1")                              -- clear and move forward
  2257.                 up, forward, down = lib.getDetect()
  2258.                 --index = index + 1
  2259.             end
  2260.             for x = minMoves + 1, #above do                 -- check remaing half and clear
  2261.                 T:go("x0x2")                                -- clear above / below
  2262.                 if above[x] then                            -- is a block recorded as present?(now below)
  2263.                     above[x] = up                           -- reset this with new value
  2264.                     T:forward(1)                            -- move forward
  2265.                     up, forward, down = lib.getDetect()
  2266.                     --index = index + 1
  2267.                 else
  2268.                     break
  2269.                 end
  2270.             end
  2271.         else                                                -- iterate table in reverse
  2272.             --index = #above
  2273.             for x = #above, minMoves, -1 do                 -- clear first half
  2274.                 above[x] = up                               -- reset this with new value
  2275.                 T:go("x0x2F1")                              -- clear and move forward
  2276.                 up, forward, down = lib.getDetect()
  2277.                 --index = index - 1
  2278.             end
  2279.             for x = minMoves - 1, 1, -1 do                  -- check remaing half and clear
  2280.                 T:go("x0x2")                                -- clear up / down
  2281.                 if above[x] then                            -- is a block recorded as present?(now below)
  2282.                     above[x] = up                           -- reset this with new value
  2283.                     T:forward(1)                            -- move forward
  2284.                     up, forward, down = lib.getDetect()
  2285.                     --index = index - 1
  2286.                 else
  2287.                     break
  2288.                 end
  2289.             end
  2290.         end
  2291.         T:go("x0x2 F1R2 x0x2 F1")                           -- face opposite direction, delete blocks above and below
  2292.         outward = not outward                               -- switch direction flag
  2293.         return above                                        -- eg {false, true, true, true, false}
  2294.     end
  2295.    
  2296.     function lib.getDetect()
  2297.         return turtle.detectUp(),  turtle.detect(),  turtle.detectDown()
  2298.     end
  2299.    
  2300.     function lib.getStartingLength(R)
  2301.         --[[
  2302.             length of column by excavating blocks above, ahead or below
  2303.             Rotate 180 at end of run ready to return
  2304.             already 1 block above ground
  2305.         ]]
  2306.         local above = {}                                    -- empty table of boolean values
  2307.         local length = 0                                    -- used as counter                         
  2308.         T:forward(1)                                        -- start check 1 block ahead
  2309.         local up, forward, down = lib.getDetect()           -- check if anything around current block
  2310.         if up or forward or down then                       -- block found nearby: continue
  2311.             while up or forward or down do                  -- while blocks ahead / up / down move forward
  2312.                 table.insert(above, up)
  2313.                 T:go("x0x2F1")
  2314.                 up, forward, down = lib.getDetect()         -- check if anything around current block
  2315.                 length = length + 1
  2316.                 if length >= R.length then                  -- check if going out of range
  2317.                     T:saveToLog("lib.getStartingLength(R) : outward = "..tostring(outward).." MaxLength "..maxLength.." reached", false)
  2318.                     break
  2319.                 end
  2320.             end
  2321.             T:go("R2x0x2")                                  -- Rotate 180 and clear blocks above/below
  2322.         else                                                -- no blocks nearby: exit
  2323.             T:go("R2F1")                                    -- return to start position rotated 180
  2324.         end
  2325.         outward = not outward
  2326.  
  2327.         return above                                        -- above = {false, true, true, true, true, false, false}
  2328.     end
  2329.    
  2330.     function lib.firstRow(R)
  2331.         local height = 1                                    -- starts at ground level, but forced up 1
  2332.         T:up(1)
  2333.         local above = lib.getStartingLength(R)              -- clear the ground level and 1 above eg 9, 2, 5, 4
  2334.         if T:saveToLog("startLength: "..#above, true) then
  2335.             T:saveToLog(utils.tableConcat(above, ", "), false)
  2336.             if dbug then read() end
  2337.         end                                                 -- at end of first row as already turned 180, outward set to false in getStartingLength
  2338.         while lib.isAnyAbove(above) do
  2339.             T:go("U3")  -- go up 3
  2340.             height = height + 3
  2341.             above = lib.clearLevel(R, above)    -- returns start and finish of blocks above, rotates 180
  2342.             if T:saveToLog("checking level: "..height, true) then
  2343.                 T:saveToLog(utils.tableConcat(above, ", "), false)
  2344.                 if dbug then read() end
  2345.             end
  2346.         end                                                 -- first row all levels completed.
  2347.         T:down(height)                                      -- now on ground + 1, facing last column cleared.
  2348.        
  2349.         return above
  2350.     end
  2351.        
  2352.     function lib.deepCopy(tbl)
  2353.         local copy = {}
  2354.         for key, value in ipairs(tbl) do
  2355.             table.insert(copy, value)
  2356.         end
  2357.         return copy
  2358.     end
  2359.    
  2360.     function lib.getHalf(R, above)
  2361.         -- already 1 block above ground
  2362.         local maxLength = R.length
  2363.         local temp = {}
  2364.         local retValue = {}
  2365.         if #above > 0 then                              -- not empty table, so must be second half
  2366.             temp = lib.deepCopy(above)                  -- copy existing table
  2367.             above = {}                                  -- initialise above
  2368.         end
  2369.         local up, forward, down = lib.getDetect()
  2370.        
  2371.         while up or forward or down do                  -- while blocks ahead / up / down move forward
  2372.             T:go("x0x2F1")
  2373.             table.insert(above, up)
  2374.             up, forward, down = lib.getDetect()         -- check if anything around current block
  2375.            
  2376.             if #above >= math.floor(maxLength / 2) then -- check if going out of range
  2377.                 T:saveToLog("lib.getHalf(R) : outward = "..tostring(outward).." MaxLength "..maxLength.." reached", false)
  2378.                 T:go("x0x2")
  2379.                 break
  2380.             end
  2381.         end
  2382.         T:turnRight(2)                                  -- ready for next half or return
  2383.         outward = not outward
  2384.         if #temp > 0 then                               -- completing a second half measurement
  2385.             for i = #above, 1, -1 do
  2386.                 table.insert(retValue, above[i])        -- combine 2 tables into 1
  2387.             end
  2388.             for i = 1, #temp do
  2389.                 table.insert(retValue, temp[i])
  2390.             end
  2391.         else
  2392.             retValue = above
  2393.         end
  2394.         return retValue
  2395.     end
  2396.    
  2397.     function lib.nextRow(R)
  2398.         local height = 1
  2399.         T:saveToLog("lib.nextRow(R)", false)
  2400.         T:up(1)
  2401.         local pattern = turn.."1F1"..turn.."1"
  2402.         if not outward then
  2403.             pattern = oTurn.."1F1"..oTurn.."1"
  2404.         end
  2405.         T:go(pattern)
  2406.         T:saveToLog("    T:go("..pattern..")", false)
  2407.         outward = not outward -- reverse direction flag
  2408.         -- now in next vertical row
  2409.         local above = lib.getHalf(R, {})
  2410.         local index = 0
  2411.         if T:saveToLog("\t  first half Length: "..#above.." Enter", true) then
  2412.             T:saveToLog(utils.tableConcat(above, ", "), false)
  2413.             if dbug then read() end
  2414.         end
  2415.         lib.returnToMidPoint(#above)                    -- return to starting point
  2416.         T:forward(1)       
  2417.         above = lib.getHalf(R, above)                   -- returns length - 1 eg 5, 4
  2418.         if T:saveToLog("\t  total length: "..#above.." Enter", true) then
  2419.             T:saveToLog(utils.tableConcat(above, ", "), false)
  2420.             if dbug then read() end
  2421.         end
  2422.        
  2423.         while lib.isAnyAbove(above) do
  2424.             T:go("U3")              -- go up 3
  2425.             height = height + 3     -- increment height
  2426.             T:saveToLog("\tClear height loop: height = "..height, false)
  2427.             above = lib.clearLevel(R, above)    -- returns start and finish of blocks above
  2428.         end
  2429.         T:down(height)  -- now on ground + 1
  2430.         lib.returnToMidPoint(above)
  2431.     end
  2432.    
  2433.     function lib.returnToMidPoint(above)
  2434.         --[[ value can be integer or table]]
  2435.         if type(above) == "table" then
  2436.             T:saveToLog("lib.returnToMidPoint("..#above..")", false)
  2437.             if #above > 0 then
  2438.                 local midPoint = math.floor(#above / 2)
  2439.                 if #above % 2 == 1 and  not outward then -- length is odd no
  2440.                     midPoint = math.ceil(#above / 2)
  2441.                     T:saveToLog("    midPoint adjusted "..midPoint..")", false)
  2442.                 end
  2443.                 T:saveToLog("    T:forward("..midPoint..")", false)
  2444.                 T:forward(midPoint)
  2445.             end
  2446.         else
  2447.             T:saveToLog("lib.returnToMidPoint("..above..")", false)
  2448.             if above > 0 then
  2449.                 T:saveToLog("    T:forward("..above..")", false)
  2450.                 T:forward(above)
  2451.             end
  2452.         end
  2453.         -- now back at starting point
  2454.     end
  2455.    
  2456.     -- Start here
  2457.     -- if "tk log d.." typed instead of "tk" will start logfile and display comments. read() will be activated for debugging
  2458.     T:saveToLog("Starting function clearMountainSide", false)
  2459.     local above = lib.firstRow(R)           -- outward depends on height eg 1-2 = false, 3-5 = true, 6-8 = false
  2460.     lib.returnToMidPoint(above)             -- return to mid first row of blocks
  2461.     for row = 1, R.width -1 do
  2462.         lib.nextRow(R)
  2463.     end
  2464.    
  2465.     return {}
  2466. end
  2467.  
  2468. local function clearSandWall(R) -- 81
  2469.     --dig down while on top of sand/red_sand/soul_sand
  2470.     local lib = {}
  2471.    
  2472.     function lib.checkAbove(height)
  2473.         if turtle.detectUp() then -- moved under a ledge
  2474.             T:go("B1U1")
  2475.             height = height - 1
  2476.         end
  2477.         return height
  2478.     end
  2479.    
  2480.     function lib.moveDown(height)
  2481.         blockType = T:getBlockType("down")
  2482.         while blockType:find("sand") ~= nil do
  2483.             T:down(1)
  2484.             height = height + 1
  2485.             blockType = T:getBlockType("down")
  2486.         end
  2487.         return height
  2488.     end
  2489.    
  2490.     function lib.moveForward(length)
  2491.         lib.digForward()
  2492.         T:forward(1)
  2493.         length = length + 1
  2494.         local blockType = T:getBlockType("forward")
  2495.         return length, blockType
  2496.     end
  2497.    
  2498.     function lib.digForward()
  2499.         while T:dig("forward") do
  2500.             while T:suck("forward") do end
  2501.             while T:suck("up") do end
  2502.         end
  2503.     end
  2504.    
  2505.     local moves  = 0
  2506.     local height = 0
  2507.     local length = 0
  2508.     local search = 0
  2509.     local reverse = false
  2510.     local blockType = T:getBlockType("down")
  2511.     if R.length == 0 then
  2512.         R.length = 64
  2513.     end
  2514.    
  2515.     print("Checking for sand below")
  2516.     while blockType:find("sand") == nil do --move forward until sand detected or 3 moves
  2517.         T:forward(1)
  2518.         search = search + 1
  2519.         blockType = T:getBlockType("down")
  2520.         if search > 3 then
  2521.             T:go("B"..search)
  2522.             return {"Unable to locate sand"}
  2523.         end
  2524.     end
  2525.     -- must be sand below
  2526.     height = lib.moveDown(height)   -- go down if sand below
  2527.     -- repeat until height == 0
  2528.     repeat -- starts at bottom of sand wall
  2529.         blockType = T:getBlockType("forward")
  2530.         if blockType:find("sand") ~= nil then -- sand in front
  2531.             length, blockType = lib.moveForward(length) -- move forward 1 and dig sand
  2532.             if blockType == "" or  blockType:find("sand") ~= nil then -- sand or nothing in front
  2533.                 height = lib.moveDown(height)   -- go down if sand below
  2534.             end
  2535.         else -- solid block, air or water, not sand so move up
  2536.             if turtle.detect() then -- block in front
  2537.                 blockType = T:getBlockType("down")
  2538.                 if blockType:find("sand") ~= nil then -- sand below
  2539.                     T:dig("down")
  2540.                 end
  2541.                 T:up(1)
  2542.                 height = height - 1
  2543.             else -- air/water in front so move forward
  2544.                 if length < 60 then -- in case missing wall and in open ocean
  2545.                     length, blockType = lib.moveForward(length) -- move forward 1 and dig sand
  2546.                     height = lib.checkAbove(height)
  2547.                 else -- already > monument length of 56
  2548.                     T:up(1)
  2549.                     height = height - 1
  2550.                 end
  2551.             end
  2552.         end
  2553.     until height == 0 or length == R.length
  2554.     blockType = T:getBlockType("down")
  2555.     if blockType:find("sand") ~= nil then -- sand below
  2556.         T:dig("down")
  2557.     end
  2558.     if height > 0 then -- finished as length ran out
  2559.         T:up(height)
  2560.     end
  2561.     -- stay at end of cleared wall unless user chose to return
  2562.     if R.data == "return" then
  2563.         T:go("R2F"..length.."R2")
  2564.     end
  2565.    
  2566.     return {}
  2567. end
  2568.  
  2569. local function clearSolid(R) -- 76
  2570.     --[[ direction = R.subChoice = 1 up or 2 down ]]
  2571.     local height = 1
  2572.     local remaining = R.height
  2573.     local lib = {}
  2574.    
  2575.     function lib.singleLayer(R)
  2576.         R.up = false
  2577.         R.down = false
  2578.         clearRectangle(R)
  2579.     end
  2580.    
  2581.     function lib.doubleLayer(R)
  2582.         R.up = false
  2583.         R.down = false
  2584.         if R.subChoice == 1 then
  2585.             R.up = true
  2586.         else
  2587.             R.down = true
  2588.         end
  2589.         clearRectangle(R)
  2590.     end
  2591.        
  2592.     function lib.tripleLayer(R)
  2593.         -- turtle in centre layer
  2594.         R.up = true
  2595.         R.down = true
  2596.         clearRectangle(R)
  2597.     end
  2598.  
  2599.     R.silent = true
  2600.     if R.height < 3 then                            --1-3 layers only
  2601.         if R.height == 1 then                       --one layer only
  2602.             lib.singleLayer(R)
  2603.         elseif R.height == 2 then                   --2 layers only current + dig up/down
  2604.             lib.doubleLayer(R)
  2605.         end
  2606.     else -- 3 or more levels
  2607.         height = height + utils.move(R, 1)          -- move up/down 1 block for first layer
  2608.         while remaining >= 3 do                     -- min 3 levels
  2609.             lib.tripleLayer(R)
  2610.             remaining = remaining - 3
  2611.             if remaining == 0 then                  -- all finished
  2612.                 break
  2613.             elseif remaining == 1 then
  2614.                 height = height + utils.move(R, 2)  -- move up/down 2 blocks
  2615.                 lib.singleLayer(R)
  2616.             elseif remaining == 2 then
  2617.                 height = height + utils.move(R, 2)  -- move up/down 2 blocks
  2618.                 lib.doubleLayer(R)
  2619.             else
  2620.                 height = height + utils.move(R, 3)  -- move up/down 3 blocks
  2621.                 if remaining == 3 then
  2622.                     finish = true
  2623.                 end
  2624.             end
  2625.         end
  2626.     end
  2627.    
  2628.     if height > 1 then
  2629.         utils.move(R, height - 1, true) -- reverse direction
  2630.     end
  2631.    
  2632.     return {}
  2633. end
  2634.  
  2635. local function clearSandCube(R) -- 81
  2636.     R.data = ""
  2637.     for w = 1, R.width do
  2638.         clearSandWall(R)
  2639.         if w < R.width then
  2640.             if w % 2 == 1 then
  2641.                 T:go("R1F1R1")
  2642.             else
  2643.                 T:go("L1F1L1")
  2644.             end
  2645.         end
  2646.     end
  2647.    
  2648.     return {}
  2649. end
  2650.  
  2651. local function clearWall(R) -- 73
  2652.     local lib = {}
  2653.    
  2654.     function lib.move(direction, blocks, reverse)
  2655.         --[[ Move up or down by blocks count ]]
  2656.         if reverse == nil then
  2657.             reverse = false
  2658.         end
  2659.         if reverse then
  2660.             if direction == "down" then -- reverse direction
  2661.                 T:up(blocks)
  2662.             else
  2663.                 T:down(blocks)
  2664.             end
  2665.         else
  2666.             if direction == "up" then
  2667.                 T:up(blocks)
  2668.             else
  2669.                 T:down(blocks)
  2670.             end
  2671.         end
  2672.         return blocks
  2673.     end
  2674.    
  2675.     function lib.singleLayer(length)
  2676.         T:go("F"..length - 1)
  2677.     end
  2678.    
  2679.     function lib.doubleLayer(modifier, length)
  2680.         for i = 1, length do
  2681.             if i < length then
  2682.                 T:go("x"..modifier.."F1")
  2683.             else
  2684.                 T:go("x"..modifier)
  2685.             end
  2686.         end
  2687.     end
  2688.    
  2689.     function lib.tripleLayer(direction, length)
  2690.         for i = 1, length do
  2691.             if i < length then
  2692.                 T:go("x0x2F1")
  2693.             else
  2694.                 T:go("x0x2")
  2695.             end
  2696.         end
  2697.     end
  2698.    
  2699.    
  2700.     -- R.width preset to 1
  2701.     -- R.subChoice = 1 up / 2 down
  2702.     if R.height < 3 then
  2703.         R.silent = true
  2704.     end
  2705.     -- dig along and up/down for specified R.length
  2706.     local modifier = "0"
  2707.     local direction = "U"
  2708.     local outbound = true
  2709.     local height = 0
  2710.     if R.subChoice == 2 then
  2711.          modifier = "2"
  2712.          direction = "D"
  2713.     end
  2714.     if R.height == 1 then               -- single block so dig and return
  2715.         lib.singleLayer(R.length)
  2716.     elseif R.height == 2 then
  2717.         lib.doubleLayer(modifier, R.length)
  2718.     else                                -- 4 blocks or more. start with bulk 3 blocks
  2719.         local remaining = R.height
  2720.         T:go(direction.."1")            -- up 1 or down 1
  2721.         height = 1
  2722.         while remaining >= 3 do
  2723.             lib.tripleLayer(direction, R.length)
  2724.             remaining = remaining - 3
  2725.            
  2726.             if remaining == 0 then      -- no more, return home, already in position
  2727.                
  2728.             elseif remaining == 1 or remaining == 2 then
  2729.                 T:go(direction.."2")
  2730.                 height = height + 2
  2731.             else
  2732.                 T:go(direction.."3")
  2733.                 height = height + 3
  2734.                 if remaining >= 3 then -- another iteration
  2735.                     T:go("R2")
  2736.                     outbound = not outbound
  2737.                 end
  2738.             end
  2739.         end
  2740.         -- 0, 1 or 2 layers left
  2741.         if remaining > 0 then
  2742.             T:go("R2")
  2743.             outbound = not outbound
  2744.             if remaining == 1 then
  2745.                 lib.singleLayer(R.length)
  2746.             elseif remaining == 2 then
  2747.                 lib.doubleLayer(modifier, R.length)
  2748.             end
  2749.         end
  2750.     end
  2751.     if outbound then
  2752.         T:go("R2F"..R.length)
  2753.     else
  2754.         T:forward(1)
  2755.     end
  2756.     direction = "D" -- reverse direction
  2757.     if R.subChoice == 2 then
  2758.          direction = "U"
  2759.     end
  2760.     if height > 0 then
  2761.         T:go(direction..height.."R2")
  2762.     else
  2763.         T:go("R2")
  2764.     end
  2765.     return {}
  2766. end
  2767.  
  2768. local function convertWater(R) -- 88
  2769.     --[[
  2770.     if dry need enough buckets to place along (width + length - 1) / 2
  2771.     use 12 buckets
  2772.     start on floor + 1
  2773.     place slab down and water up along 2 edges. stay on this level
  2774.     return round same 2 edges removing slabs and and placing them 1 above
  2775.     placeUp water onto slabs on both edges
  2776.     repeat recover slabs, place 1 above , placeUp water
  2777.    
  2778.     for sloping water, place full area with slabs
  2779.     place sloping water on top of slabs
  2780.     remove slabs
  2781.    
  2782.     ]]
  2783.     local lib = {}
  2784.    
  2785.     function lib.checkStartPosition()
  2786.         --[[
  2787.         0 T             -- T=turtle, W=wall, S=source, F=flowing
  2788.         1 W|S|F|F|F|F|F -- sloping flowing water
  2789.         2 W|F|F|F|F|F|F -- blocks removed after placing flowing water above
  2790.         3 W|S|S|S|S|S|S -- original sources
  2791.         4 W|?|?|?|?|?|? -- may be sources
  2792.         ]]
  2793.         -- need to be on floor or R.height if specified
  2794.         local depth = 0
  2795.         local blockType = T:getBlockType("down")
  2796.         local isWaterUp, isSourceUp = T:isWater("up")
  2797.         local isWaterForward, isSourceForward = T:isWater("forward")
  2798.         local isWaterDown, isSourceDown = T:isWater("down")
  2799.         print("Block below is "..blockType)
  2800.         print("Water above is "..tostring(isWaterUp))
  2801.         print("Water forward is "..tostring(isWaterForward))
  2802.         print("Water below is "..tostring(isWaterDown))
  2803.         if blockType:find("water") == nil then -- on at least level 0
  2804.             print("Moving forward in 2 seconds...")
  2805.             sleep(2)
  2806.             T:forward(1)
  2807.             blockType = T:getBlockType("down")
  2808.             if blockType:find("water") ~= nil then
  2809.                 print("Water found. Going down to floor")
  2810.                 depth = -1
  2811.             else
  2812.                 T:down(1)
  2813.                 blockType = T:getBlockType("down")
  2814.                 if blockType:find("water") ~= nil then
  2815.                     depth = -2
  2816.                 else
  2817.                     return 0, "Not close to water. Aborting..."
  2818.                 end
  2819.             end
  2820.         end
  2821.         while turtle.down() do
  2822.             depth = depth + 1
  2823.         end
  2824.         local emptyBuckets = utils.getEmptyBucketCount()
  2825.         for i = depth, 0, -1 do
  2826.             if emptyBuckets > 0 then
  2827.                 lib.fillBuckets()
  2828.                 emptyBuckets = utils.getEmptyBucketCount()
  2829.             end
  2830.             turtle.up()
  2831.         end
  2832.        
  2833.         return depth, ""
  2834.     end
  2835.    
  2836.     function lib.fillBuckets()
  2837.         local emptyBuckets = utils.getEmptyBucketCount()
  2838.         local direction = "forward"-- start with forward
  2839.         local isWater, isSource, isIce = T:isWater(direction)
  2840.         if emptyBuckets > 0 then
  2841.             if not isSource then
  2842.                 direction = "down"
  2843.                 isWater, isSource, isIce = T:isWater(direction)
  2844.                 if not isSource then
  2845.                     direction = "up"
  2846.                     isWater, isSource, isIce = T:isWater(direction)
  2847.                     if not isSource then
  2848.                         direction = ""
  2849.                     end
  2850.                 end
  2851.             end
  2852.             if direction == "" then
  2853.                 print("Unable to locate water source")
  2854.             else
  2855.                 for i = 1, emptyBuckets do
  2856.                     if utils.fillBucket(direction) then
  2857.                         print("Bucket filled "..direction)
  2858.                         sleep(0.3)
  2859.                     else
  2860.                         print("Unable to fill bucket ".. i .." / "..emptyBuckets)
  2861.                     end
  2862.                 end
  2863.             end
  2864.         end
  2865.         return utils.getWaterBucketCount()
  2866.     end
  2867.    
  2868.     function lib.placeSlabs(length)
  2869.         for i = 1, length do
  2870.             T:place("slab", -1, "down", false)
  2871.             if i < length then
  2872.                 T:forward(1)
  2873.             end
  2874.         end
  2875.     end
  2876.    
  2877.     function lib.placeSources(length, place)
  2878.         local moves = 1
  2879.         local waterBuckets = utils.getWaterBucketCount()
  2880.         -- place sources alternate positions + start and finish
  2881.         while moves < length do
  2882.             if place then
  2883.                 if T:placeWater("up") then
  2884.                     print("Placed source up")
  2885.                     waterBuckets = waterBuckets - 1
  2886.                 end
  2887.             end
  2888.             place = not place
  2889.             if moves < length then
  2890.                 T:forward(1)
  2891.                 moves = moves + 1
  2892.             end
  2893.             if waterBuckets == 0 then
  2894.                 T:down(1) -- break the slab below
  2895.                 waterBuckets = lib.fillBuckets()
  2896.                 T:up(1)
  2897.                 T:place("slab", -1, "down", false)
  2898.             end
  2899.         end
  2900.         if T:placeWater("up") then -- end of length
  2901.             print("Placed final source up")
  2902.         end
  2903.         return place
  2904.     end
  2905.    
  2906.     function lib.moveSlabs(length)
  2907.         for i = 1, length do
  2908.             T:dig("down")
  2909.             T:up(1)
  2910.             T:place("slab", -1, "down", true)
  2911.             if i < length then
  2912.                 T:forward(1)
  2913.                 T:down(1)
  2914.             end
  2915.         end
  2916.     end
  2917.    
  2918.     function lib.recoverSlabs(length)
  2919.         for i = 1, length do
  2920.             T:dig("down")
  2921.             if i < length then
  2922.                 T:forward(1)
  2923.             end
  2924.         end
  2925.     end
  2926.    
  2927.     local depth, message = lib.checkStartPosition()
  2928.     if message ~= "" then
  2929.         return {message}
  2930.     end
  2931.     local maxDepth = R.height
  2932.     local buckets = utils.getWaterBucketCount()
  2933.     R = utils.calculateDimensions(R) -- if R.width or R.length == 0
  2934.     T:down(depth)
  2935.     lib.placeSlabs(R.length)
  2936.     T:go("R1")
  2937.     lib.placeSlabs(R.width)
  2938.     T:go("R2")
  2939.    
  2940.     while depth > 0 do
  2941.         local place = true
  2942.         lib.fillBuckets()
  2943.         place = lib.placeSources(R.width, place)
  2944.         T:go("L1")
  2945.         place = lib.placeSources(R.length, place)
  2946.         lib.fillBuckets()
  2947.         T:go("R2")
  2948.         lib.moveSlabs(R.length) -- dig slab from below, move up and replace below
  2949.         T:go("R1F1D1")
  2950.         lib.moveSlabs(R.width - 1)
  2951.         T:go("R2") -- now moved up 1 layer
  2952.         depth = depth - 1
  2953.         if depth == 0 then
  2954.             place = lib.placeSources(R.width, true)
  2955.             T:go("L1")
  2956.             place = lib.placeSources(R.length, place)
  2957.             T:go("R2")
  2958.             lib.recoverSlabs(R.length)
  2959.             T:go("R1")
  2960.             lib.recoverSlabs(R.width)
  2961.         end
  2962.     end
  2963.    
  2964.     return {}
  2965. end
  2966.  
  2967. local function createBoatLift(R) -- 59 state:0=new, size:1=extend, side:0=left, 1=right
  2968.     -- build stepped lift with fencing gates and soul sand
  2969.     local lib = {}
  2970.    
  2971.     function lib.getWater(backToWater, downToWater)
  2972.         if backToWater > 0 then
  2973.             utils.goBack(backToWater)
  2974.         end
  2975.         if downToWater > 0 then
  2976.             T:down(downToWater)
  2977.         end
  2978.         T:getWater("down") -- take water from source
  2979.         sleep(0.2)
  2980.         T:getWater("down") -- take water from source
  2981.         if downToWater > 0 then
  2982.             T:up(downToWater)
  2983.         end
  2984.         if backToWater > 0 then
  2985.             T:forward(backToWater)
  2986.         end
  2987.     end
  2988.    
  2989.     --T:place(blockType, damageNo, direction, leaveExisting, signText)
  2990.    
  2991.     local backToWater = 0
  2992.     local downToWater = 0
  2993.    
  2994.     T:go("R1F1L1")                                      -- over canal facing forward
  2995.     for h = 1, R.height do
  2996.         lib.getWater(backToWater, downToWater)          -- check water supplies, return to starting position
  2997.         T:go("L1C1 R1D1 L1C1 R1", false, 0, false)      -- place towpath, forward, down, place towpath, face forward
  2998.         T:place("soul", -1, "down", false)              -- place soulsand down
  2999.         T:place("soul", -1, "forward", false)           -- place soulsand forward
  3000.         T:go("R1F1C1L1", false, 0, false)               -- place right towpath face forward
  3001.         T:place("soul", -1, "down", false)              -- place soulsand down
  3002.         T:place("soul", -1, "forward", false)           -- place soulsand forward
  3003.         T:go("U1 R1C1 L1")                              -- place towpath, face forward
  3004.         T:placeWater("down")                            -- place water down
  3005.         utils.goBack(1)
  3006.         T:place("gate", -1, "forward", false)           -- place fence gate
  3007.         T:go("R1C1 U1C1 D1 L2F1 C1R1 F1 L1C1R1")        -- over left soul sand
  3008.         T:placeWater("down")                            -- place water down
  3009.         utils.goBack(1)
  3010.         T:place("gate", -1, "forward", false)           -- place fence gate
  3011.         T:go("U1 L1C1 R1F1 L1C1 R1x1")                  -- facing forward first unit complete
  3012.         T:go("R1F1 L1x1 R1C1")
  3013.         utils.goBack(1)
  3014.         T:go("L1F1")
  3015.         if backToWater == 0 then
  3016.             backToWater = 1
  3017.         end
  3018.         backToWater = backToWater + 1
  3019.         downToWater = downToWater + 1
  3020.     end
  3021.    
  3022.     -- now finish the canal
  3023.     lib.getWater(backToWater, downToWater)
  3024.     T:go("D1 L1C1 U1C1")                    -- build left towpath, facing towpath, above water level
  3025.     T:go("R1F1 L1C1 D1C1")                  -- move forward, build towpath, facing towpath ground level
  3026.     T:go("R1C1 R1F1 L1C1 R1C1 U1C1")        -- build right towpath, facing towpath, above water level
  3027.     T:go("R1F1 L1C1 D1C1 U1")               -- build right towpath next to gate, facing towpath, above water level
  3028.     T:placeWater("down")
  3029.     utils.goBack(1)
  3030.     T:go("L1F1")
  3031.     T:placeWater("down")  
  3032.    
  3033.     return {}
  3034. end
  3035.  
  3036. local function createBorehole(R)
  3037.     --[[go down to bedrock and return. Chart all blocks dug/ passed through]]
  3038.     local diary = {}
  3039.     local lib = {}
  3040.     local depth = R.height  -- eg 63 start position
  3041.     local moves = 0
  3042.     --R.height = current level
  3043.    
  3044.     function lib.addBlock(depth, blockType, diary)
  3045.         if blockType == "" then
  3046.             blockType = "air"
  3047.         end
  3048.         table.insert(diary, blockType)
  3049.        
  3050.        
  3051.         --[[if blockType ~= "" then
  3052.             local add = true
  3053.             for k,v in pairs(diary) do
  3054.                 if blockType == v then
  3055.                     add = false
  3056.                     break
  3057.                 end
  3058.             end
  3059.             if add then
  3060.                 diary[depth] = blockType
  3061.             end
  3062.         end]]
  3063.        
  3064.         return diary
  3065.     end
  3066.    
  3067.     function lib.processItem(item)
  3068.         if item:find("minecraft") ~= nil then
  3069.             return item:sub(11)
  3070.         end
  3071.         return item
  3072.     end
  3073.    
  3074.     function lib.writeReport(R, diary)
  3075.         local numLevels = #diary                        -- eg 125 levels
  3076.         local levelsPerCol = math.ceil(numLevels / 4)   -- eg 31.25 -> 32
  3077.         local lines = {}
  3078.         for l = 1, levelsPerCol do                      -- add 32 empty strings
  3079.             table.insert(lines, "")
  3080.         end
  3081.         local lineNo = 1
  3082.         for k, v in ipairs(diary) do
  3083.             local level = R.height - k                  -- eg 63 range 63 to -59
  3084.             local lev = "      "
  3085.             local item = lib.processItem(v)
  3086.             if level < -9 then
  3087.                 lev = tostring(level).."   "            -- "-10   " to "-59   "
  3088.             elseif level < 0 then              
  3089.                 lev = "-0"..math.abs(level).."   "      -- "-09   " to "-01   "
  3090.             elseif level < 10 then
  3091.                 lev = " 0"..level.."   "                -- " 01   " to " 09   "
  3092.             elseif level < 100 then
  3093.                 lev = " "..level.."   "                 -- " 10   " to " 99   "
  3094.             else
  3095.                 lev = " "..level.."  "                  -- " 100  " to " 319  "
  3096.             end
  3097.             local output = lev..item                    -- eg "-10   grass_block"
  3098.             if #output > 20 then                        -- eg "-10   some_long_block_name"  
  3099.                 output = output:sub(1, 20)              -- eg "-10   some_long_block_"
  3100.             else
  3101.                 output = menu.padRight(output, 20, " ") -- eg "-10   grass_block     "
  3102.             end
  3103.             lines[lineNo] = lines[lineNo]..output       -- add new entry to this line
  3104.             lineNo = lineNo + 1                         -- increase line no
  3105.             if lineNo > levelsPerCol then               -- past last line number
  3106.                 lineNo = 1                              -- reset to 1
  3107.             end
  3108.         end
  3109.        
  3110.         local fileName = "borehole"..os.getComputerID()..".txt"
  3111.         local handle = fs.open(fileName, "w")       --create file eg "borehole0.txt"
  3112.         handle.writeLine("Level Block         Level Block         Level Block         Level Block")
  3113.         for k,v in ipairs(lines) do
  3114.             handle.writeLine(v)
  3115.         end
  3116.        
  3117.         handle.close()
  3118.        
  3119.         return fileName
  3120.     end
  3121.    
  3122.     local blockType = T:getBlockType("down")
  3123.     while T:down(1) do
  3124.         depth = depth - 1
  3125.         moves = moves + 1
  3126.         if depth == R.depth then
  3127.             break
  3128.         end
  3129.         diary = lib.addBlock(depth, blockType, diary)
  3130.         blockType = T:getBlockType("down")
  3131.     end
  3132.     local fileName = lib.writeReport(R, diary)
  3133.     T:up(moves)
  3134.    
  3135.     return {"File '"..fileName.."' written"}
  3136. end
  3137.  
  3138. local function createBubbleLift(R) -- 15
  3139.     local lib = {}
  3140.    
  3141.     function lib.addLayer()
  3142.         T:go("F2 L1C1 R1C1 R1C1 L1", false, 0, true)
  3143.         turtle.back()
  3144.         T:dig("up") -- clear block above so completed lift can be found
  3145.         T:placeWater("forward")
  3146.         turtle.back()
  3147.         T:go("C1x0")       
  3148.     end
  3149.    
  3150.     function lib.addSign()
  3151.         turtle.back()
  3152.         T:placeWater("forward")
  3153.         T:go("L1B1")
  3154.         T:place("sign", -1, "forward")
  3155.     end
  3156.    
  3157.     function lib.buildLift(toHeight)
  3158.         local built = lib.goToWater()       -- returns lift blocks already placed, total height of drop from starting point
  3159.         local toBuild = toHeight - built    -- no of blocks remaining to increase lift size
  3160.         local water = 0
  3161.         while toBuild > 0 do                -- at least 1 block height remaining
  3162.             water = lib.fillBuckets(toBuild, false) -- no of water buckets onboard (could be more than required)
  3163.             if water > toBuild then         -- more water than required
  3164.                 water = toBuild             -- reduce to correct amount
  3165.             end
  3166.             T:up(built)                     -- climb to top of existing lift
  3167.             while water > 0 and toBuild > 0 do
  3168.                 lib.addLayer()
  3169.                 water = water - 1
  3170.                 T:up(1)
  3171.                 toBuild = toBuild - 1
  3172.             end
  3173.             -- may still be some height to complete, but needs refill
  3174.             if toBuild > 0 then
  3175.                 built = lib.goToWater() --return to source
  3176.                 toBuild = toHeight - built
  3177.                 --lib.fillBuckets(toBuild)
  3178.             end
  3179.         end
  3180.     end
  3181.    
  3182.     function lib.cleanUp(fromHeight)
  3183.         local plug = false
  3184.         T:turnRight(2)
  3185.         for i = 1, fromHeight do
  3186.             plug = false
  3187.             if turtle.detect() then
  3188.                 plug = true
  3189.             end
  3190.             turtle.down()
  3191.             if plug then
  3192.                 T:place("stone", -1, "up")
  3193.             end
  3194.         end
  3195.         T:go("D1 C1R1x1 R1C1 R1F1 R1x1 L2x1 L1C1 x1") -- delete water sources
  3196.         T:go("D1 C1R1x1 R1")
  3197.         local blockType = T:getBlockType("forward")
  3198.         if blockType:find("dirt") == nil and blockType:find("soul") == nil then -- not dirt or soul sand in front
  3199.             T:go("C1")
  3200.         end
  3201.         T:go("R1F1 R1x1 L2x1 L1C1 x1")
  3202.     end
  3203.    
  3204.     function lib.fillBuckets(toBuild, withSort)
  3205.         local emptySlots, water = lib.stackBuckets(withSort)-- gets no of empty slots + no of water buckets
  3206.         if water < toBuild then                     -- no of water buckets onboard less than required quantity
  3207.             for i = 1, toBuild do                   -- fill required no of buckets up to max space in inventory
  3208.                 if emptySlots == 0 then             -- inventory full
  3209.                     break
  3210.                 else
  3211.                     if T:getWater("down") then
  3212.                         water = water + 1
  3213.                         sleep(0.5)
  3214.                     end
  3215.                 end
  3216.                 emptySlots = lib.getEmptySlots()
  3217.             end
  3218.         end
  3219.        
  3220.         return water
  3221.     end
  3222.    
  3223.     function lib.getEmptySlots()
  3224.         local empty = 0
  3225.         for i = 1, 16 do
  3226.             if turtle.getItemCount(i) == 0 then
  3227.                 empty = empty + 1
  3228.             end
  3229.         end
  3230.         return empty
  3231.     end
  3232.    
  3233.     function lib.goToWater()
  3234.         local built = 0 -- measures completed lift height
  3235.         while turtle.down() do -- takes turtle to bottom of water source
  3236.             if turtle.detect() then
  3237.                 built = built + 1
  3238.             end
  3239.         end
  3240.         T:up(1) -- above watersource ready to fill buckets
  3241.         -- height = height - 1
  3242.         -- built = built - 1 not required as next block is water source: not detected
  3243.         return built -- , height
  3244.     end
  3245.    
  3246.     function lib.stackBuckets(withSort)
  3247.         if withSort == nil then withSort = false end
  3248.         local data = {}
  3249.         local bucketSlot = 0
  3250.         local emptySlots = 0
  3251.         local water = 0
  3252.         if withSort then
  3253.             T:sortInventory()
  3254.         end
  3255.         for i = 1, 16 do
  3256.             -- find first empty bucket
  3257.             if turtle.getItemCount(i) > 0 then
  3258.                 data = turtle.getItemDetail(i)
  3259.                 if data.name == "minecraft:bucket" then
  3260.                     if bucketSlot == 0 then
  3261.                         bucketSlot = i
  3262.                     else
  3263.                         turtle.select(i)
  3264.                         turtle.transferTo(bucketSlot)
  3265.                     end
  3266.                 elseif data.name == "minecraft:water_bucket" then
  3267.                     water = water + 1
  3268.                 end
  3269.             else
  3270.                 emptySlots = emptySlots + 1
  3271.             end
  3272.         end
  3273.         return emptySlots, water
  3274.     end
  3275.    
  3276.    
  3277.     T:go("C1R1")                                                -- place block next to ladder support block, turn right to check ladder
  3278.     local blockType = T:getBlockType("forward")                 -- Is there a ladder to the right?
  3279.     if blockType:find("ladder") == nil then
  3280.         T:go("C1L2")                                            -- Place block as ladder not present
  3281.     else                                                        -- ladder present
  3282.         T:go("L2")                                              -- ready to check other side
  3283.     end
  3284.     blockType = T:getBlockType("forward")
  3285.     if blockType:find("ladder") == nil then
  3286.         T:go("C1R1")
  3287.     else
  3288.         T:go("R1")
  3289.     end
  3290.     blockType = T:getBlockType("down")
  3291.     local dirt = "minecraft:dirt"
  3292.     if T:getItemSlot("minecraft:soul_sand") > 0 then
  3293.         dirt = "minecraft:soul_sand"
  3294.     end
  3295.     if blockType:find("bedrock") ~= nil then
  3296.         utils.goBack(1)
  3297.         T:place(dirt, -1, "forward", false)                     -- placed at end of potential water source, next to ladder
  3298.     else
  3299.         T:place(dirt, -1, "down", false)                        -- placed in ground, next to ladder
  3300.         utils.goBack(1)
  3301.         T:placeWater("forward")                             -- place extra water source
  3302.     end
  3303.     T:go("R1C1 R2C1 L1F1C2 R1C1 L2C1 R1F1C2 R1C1 L1C1 L1C1 L1F1", false, 0, true)
  3304.     -- ready for water sources to be placed
  3305.     T:placeWater("forward")                                 -- place front water source
  3306.     T:turnRight(2)                                          -- facing backward
  3307.     T:placeWater("forward")                                 -- place back water source
  3308.     T:go("R2U1")                                            -- facing forward, U1, above centre of water source
  3309.     lib.fillBuckets(R.height, true)                         -- fill as many buckets as required or until inventory full, sort inventory as well
  3310.     local nextToLadder = false
  3311.     --T:go("F2R1")
  3312.     T:go("x0F1 x0F1C1 R1")                                  -- move forward 2 taking out blocks above, plug behind soul sand
  3313.     if T:getBlockType("forward"):find("ladder") == nil then -- no ladder here
  3314.         T:turnLeft(2)
  3315.         if T:getBlockType("forward"):find("ladder") ~= nil then -- ladder here
  3316.             nextToLadder = true
  3317.         end
  3318.         T:turnRight(1)
  3319.     else
  3320.         nextToLadder = true
  3321.         T:turnLeft(1)
  3322.     end
  3323.     -- now above soul sand, facing forward
  3324.     if nextToLadder then                                -- if nextToLadder, no need for signs
  3325.         utils.goBack(2)                                 -- return to source centre
  3326.     else
  3327.         T:go("F2 L1C1R1C1R1C1L1", false, 0, true)       -- prepare layer 1
  3328.         lib.addSign()
  3329.         T:go("U1F1R1F1 L1C1R1C1R1C1L1", false, 0, true) -- prepare layer 2
  3330.         lib.addSign()
  3331.         T:go("L1F1 R1F1R1", false, 0, true)             -- above source, level 2
  3332.     end
  3333.     -- ready to build lift
  3334.     lib.buildLift(R.height - 1)
  3335.     lib.cleanUp(R.height - 1)
  3336.    
  3337.     return {"Bubble lift created", "Check correct operation", "Check exit before using" }
  3338. end
  3339.  
  3340. local function createBubbleTrap(R) -- 34
  3341.     --[[
  3342.     Replace floor of existing volume of water with soulsand
  3343.     Used in river biome for squid farm. Area should be enclosed
  3344.     with solid walls surface to floor.
  3345.     Usually 7 blocks wide
  3346.     ]]
  3347.     local lib = {}
  3348.    
  3349.     function lib.clearDown(depth)
  3350.         while utils.clearVegetation("down") do
  3351.             T:down(1)
  3352.             depth = depth + 1
  3353.         end
  3354.         T:place("soul_sand", -1, "down", false)
  3355.         return depth
  3356.     end
  3357.    
  3358.     function lib.clearLength(length, depth)
  3359.         local moves = 0
  3360.         while moves < length - 1 do
  3361.             if utils.clearVegetation("forward") then
  3362.                 T:forward(1)
  3363.                 moves = moves + 1
  3364.                 depth = lib.clearDown(depth) -- go down if in water/air
  3365.                 if moves >= length - 1 then
  3366.                     return depth
  3367.                 end
  3368.             else -- block in front
  3369.                 local waterAhead = utils.clearVegetation("forward") -- true if air/water in front
  3370.                 while not waterAhead do     -- solid block in front
  3371.                     T:up(1)
  3372.                     depth = depth - 1
  3373.                     if depth < 1 then
  3374.                         return 0
  3375.                     end
  3376.                     waterAhead = utils.clearVegetation("forward")
  3377.                 end
  3378.             end
  3379.         end
  3380.  
  3381.         return depth
  3382.     end
  3383.    
  3384.     function lib.turn(facingForward, depth)
  3385.         local direction = "R"
  3386.         if not facingForward then
  3387.             direction = "L"
  3388.         end
  3389.         T:go(direction.. 1)
  3390.         if utils.clearVegetation("forward") then
  3391.             T:forward(1)
  3392.             depth = depth + lib.clearDown(depth)
  3393.         else
  3394.             while not utils.clearVegetation("forward") do
  3395.                 T:up(1)
  3396.                 depth = depth - 1
  3397.             end
  3398.         end
  3399.         T:go(direction.. 1)
  3400.        
  3401.         return depth
  3402.     end
  3403.    
  3404.     local depth = 0
  3405.     local length = 0
  3406.     local width = 0
  3407.     local outbound = true
  3408.     local facingForward = true
  3409.     local inWater, onWater = utils.getWaterStatus()
  3410.     inWater, onWater = utils.startWaterFunction(onWater, inWater, 2 ,true) -- move into water, max descent 2
  3411.     if R.length == 0 then
  3412.         R.length = lib.getLength()
  3413.     end
  3414.     if R.width == 0 then
  3415.         T:turnRight(1)
  3416.         R.width = lib.getLength()
  3417.         T:turnLeft(1)
  3418.     end
  3419.     -- go down to floor
  3420.     depth = lib.clearDown(depth)
  3421.     while width < R.width do
  3422.         -- now on floor, move along sea/river bed following contour
  3423.         depth = lib.clearLength(R.length, depth)
  3424.         width = width + 1
  3425.         -- now turn and repeat
  3426.         if width < R.width then
  3427.             depth = lib.turn(facingForward, depth)
  3428.             facingForward = not facingForward
  3429.         end
  3430.     end
  3431.     -- finished so return to surface
  3432.     T:up(1) -- up 1 to check for water below
  3433.     while T:isWater("down") do
  3434.         T:up(1)
  3435.     end
  3436.    
  3437.     return {}
  3438. end
  3439.  
  3440. local function createCorridor(R) -- 52
  3441.     --[[create a corridoor 2 blocks high, with floor and ceiling guaranteed
  3442.     T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)]]
  3443.     local lib = {}
  3444.    
  3445.     function lib.continue(R, currentSteps, totalSteps)
  3446.         if not R.silent then
  3447.             if currentSteps >= 64 and R.length == 0 then
  3448.                 -- request permission to continue if infinite
  3449.                 T:clear()
  3450.                 print("Completed "..totalSteps..". Ready for 64 more")
  3451.                 print("Do you want to continue? (y/n)")
  3452.                 response = read()
  3453.                 if response:lower() ~= "y" then
  3454.                     return true, 0
  3455.                 else
  3456.                     return false, currentSteps
  3457.                 end
  3458.             end
  3459.         end
  3460.         return true, currentSteps
  3461.     end
  3462.    
  3463.     function lib.seal()
  3464.         local blockType = T:getBlockType("forward")
  3465.         if blockType:find("water") ~= nil then
  3466.             T:place("stone", 0, "forward", false)
  3467.             return "water"  -- water found
  3468.         elseif blockType:find("lava") ~= nil then
  3469.             T:place("stone", 0, "forward", false)
  3470.             return "lava"   -- lava found
  3471.         end
  3472.         return ""   -- no water or lava
  3473.     end
  3474.    
  3475.     function lib.checkSeal(R)
  3476.         local fluidType = ""
  3477.         if R.data == "seal" then        -- check for lava/water at the sides
  3478.             T:turnRight(1)
  3479.             fluidType = lib.seal()      -- could be "", "water", "lava"
  3480.             T:turnLeft(2)
  3481.             local blockType = lib.seal()
  3482.             if fluidType == "" then     -- no water / lava so far
  3483.                 fluidType = blockType   -- could be "", "water", "lava"
  3484.             end
  3485.             T:turnRight(1)
  3486.         end
  3487.         return fluidType                -- could be "", "water", "lava"
  3488.     end
  3489.    
  3490.     function lib.placeTorch(R, torchSpaces, totalSteps)
  3491.         if R.torchInterval > 0 then -- torches onboard
  3492.             if torchSpaces == R.torchInterval then -- time to place another torch
  3493.                 if totalSteps < R.length then -- not at end of run
  3494.                     if T:getItemSlot("minecraft:torch") > 0 then
  3495.                         T:place("minecraft:torch", -1, "down")
  3496.                     end
  3497.                     torchSpaces = 1
  3498.                 end
  3499.             end
  3500.         end
  3501.         return torchSpaces -- original value or 1
  3502.     end
  3503.    
  3504.     local currentSteps = 0                  -- counter for infinite length. pause every 64 blocks
  3505.     local totalSteps = 0                    -- counter for all steps so far
  3506.     local torchSpaces = R.torchInterval     -- if torches present, counter to place with 8 blocks between
  3507.     local fluidType = ""
  3508.     local damLength = 0
  3509.     local damStarted = false
  3510.     local doContinue = true
  3511.     if T:getItemSlot("minecraft:torch") == 0 then
  3512.         R.torchInterval = 0 -- set to default 9 in getTask()
  3513.     end
  3514.     for steps = 1, R.length do
  3515.         -- starts on floor of tunnel
  3516.         doContinue, currentSteps = lib.continue(R, currentSteps, totalSteps) -- continue tunnelling?
  3517.         if not doContinue then
  3518.             break
  3519.         end
  3520.         T:go("C2U1C0", false, 0, true)      -- place floor, up 1, place ceiling
  3521.         fluidType = lib.checkSeal(R)        -- if R.data == "seal", check for water/lava at ceiling level
  3522.         if fluidType == "" then -- either R.data ~= "seal" or no fluid found
  3523.             torchSpaces = lib.placeTorch(R, torchSpaces, totalSteps) -- original value or 1 if torch placed
  3524.             T:go("F1D1")
  3525.         elseif fluidType == "water" then
  3526.             T:go("F1R2 C1D1 C1L2", false, 0, true)
  3527.             damStarted = true
  3528.             damLength = damLength + 1
  3529.         else    --lava
  3530.             T:go("F1D1")
  3531.         end
  3532.         blockType = lib.checkSeal(R)
  3533.         if blockType ~= "" then
  3534.             fluidType = blockType
  3535.         end
  3536.         currentSteps = currentSteps + 1
  3537.         totalSteps = totalSteps + 1
  3538.         torchSpaces = torchSpaces + 1
  3539.         if damStarted and fluidType == "" then -- was in water, but no more
  3540.             T:go("R2 F"..damLength + 1 .."U1L2F"..damLength + 1 .."D1")
  3541.             damStarted = false
  3542.         end
  3543.     end
  3544.     if fluidType ~= "" then -- water or lava found while tunnelling
  3545.         T:go("U1C0", false, 0, true)
  3546.         lib.checkSeal(R)
  3547.         T:go("C1", false, 0, true)
  3548.         T:down(1)
  3549.     end
  3550.     return {}
  3551. end
  3552.  
  3553. local function createDragonTrap() -- 49
  3554.     local lib = {}
  3555.    
  3556.     function lib.attack()
  3557.         local totalHitsF = 0
  3558.         local totalHitsU = 0
  3559.         local totalHitsD = 0
  3560.         while true do
  3561.             local hitF = false
  3562.             local hitU = false
  3563.             local hitD = false
  3564.             if turtle.attackUp() then
  3565.                 hitU = true
  3566.                 totalHitsU = totalHitsU + 1
  3567.             end
  3568.             if turtle.attackDown() then
  3569.                 hitD = true
  3570.                 totalHitsD = totalHitsD + 1
  3571.             end
  3572.             if turtle.attack() then
  3573.                 hitF = true
  3574.                 totalHitsF = totalHitsF + 1
  3575.             end
  3576.             if hitF or hitU or hitD then
  3577.                 print("hits forward: "..totalHitsF..", up: "..totalHitsU..", down: "..totalHitsD)
  3578.             end
  3579.         end
  3580.     end
  3581.     -- build up 145 blocks with ladders
  3582.     T:clear()
  3583.     menu.colourPrint("Press Enter to start 1 minute delay\n", colors.red)
  3584.     menu.colourPrint("Run to island centre across the bridge\n", colors.orange)
  3585.     menu.colourPrint("You have already made the bridge?...", colors.lime)
  3586.     read()
  3587.     for t = 60, 1, -1 do
  3588.         sleep(1)
  3589.         T:clear()
  3590.         io.write("Starting in "..t.. " seconds ")
  3591.     end
  3592.     for i = 1, 145 do
  3593.         T:go("U1C2")
  3594.         turtle.back()
  3595.         T:place("minecraft:ladder", -1, "down")
  3596.         turtle.forward()
  3597.     end
  3598.     T:go("R2F1C1 L1C1 L2C1 R1")
  3599.     for i = 1, 100 do
  3600.         T:go("F1C2U1C0D1")
  3601.     end
  3602.     T:forward(1)
  3603.     T:place("minecraft:obsidian", -1, "down")
  3604.     T:go("R2F1x2R2")
  3605.     T:placeWater("forward")
  3606.     T:go("R2F6R2")
  3607.     lib.attack()
  3608.    
  3609.     return {}
  3610. end
  3611.    
  3612. local function createEnderTower(stage) -- 66
  3613.     --[[ lower base = stage 1, upper base = 2, tower = 3 ]]
  3614.     local lib = {}
  3615.     --[[ go(path, useTorch, torchInterval, leaveExisting, preferredBlock) ]]
  3616.     function lib.getEmptySlots()
  3617.         local empty = 0
  3618.         for i = 1, 16 do
  3619.             if turtle.getItemCount(i) == 0 then
  3620.                 empty = empty + 1
  3621.             end
  3622.         end
  3623.         return empty
  3624.     end
  3625.  
  3626.     function lib.getStone(direction, stacks)
  3627.         --[[ get block user wants to use ]]
  3628.         local suck = turtle.suck   
  3629.         if direction == "down" then
  3630.             suck = turtle.suckDown
  3631.         end
  3632.         if T:getBlockType(direction) == "minecraft:chest" then
  3633.             T:sortInventory()
  3634.             local slot = T:getFirstEmptySlot() --find spare slot
  3635.             if slot > 0 then --empty slot found
  3636.                 turtle.select(1)
  3637.                 if stacks == 0 then
  3638.                     while suck() do end
  3639.                 else
  3640.                     for i = 1, stacks do -- get # stacks of stone from chest
  3641.                         suck()
  3642.                     end
  3643.                 end
  3644.                 if T:getSlotContains(slot) == "" then
  3645.                     return T:getMostItem()              -- empty chest
  3646.                 else
  3647.                     return T:getSlotContains(slot)      -- use this as default building block
  3648.                 end
  3649.             else
  3650.                 return T:getMostItem()              -- full inventory
  3651.             end
  3652.         else
  3653.             return T:getMostItem()              -- no chest
  3654.         end
  3655.     end
  3656.    
  3657.     function lib.stackBuckets()
  3658.         local data = {}
  3659.         local bucketSlot = 0
  3660.         local emptySlots = 0
  3661.         local water = 0
  3662.         T:sortInventory()
  3663.         for i = 1, 16 do
  3664.             -- find first empty bucket
  3665.             if turtle.getItemCount(i) > 0 then
  3666.                 data = turtle.getItemDetail(i)
  3667.                 if data.name == "minecraft:bucket" then
  3668.                     if bucketSlot == 0 then
  3669.                         bucketSlot = i
  3670.                     else
  3671.                         turtle.select(i)
  3672.                         turtle.transferTo(bucketSlot)
  3673.                     end
  3674.                 elseif data.name == "minecraft:water_bucket" then
  3675.                     water = water + 1
  3676.                 end
  3677.             else
  3678.                 emptySlots = emptySlots + 1
  3679.             end
  3680.         end
  3681.         return emptySlots, water
  3682.     end
  3683.    
  3684.     function lib.countWaterBuckets()
  3685.         local data = {}
  3686.         local buckets = 0
  3687.         for i = 1, 16 do
  3688.             data = turtle.getItemDetail(i)
  3689.             if data.name == "minecraft:water_bucket" then
  3690.                 buckets = buckets + 1
  3691.             end
  3692.         end
  3693.         return buckets
  3694.     end
  3695.    
  3696.     function lib.baseRun(preferredBlock, count, turn)
  3697.         for i = 1, count do
  3698.             T:go("C2F1", false, 0, false, preferredBlock)
  3699.         end
  3700.         T:go("C2"..turn, false, 0, false, preferredBlock)
  3701.     end
  3702.    
  3703.     function lib.outsideRun(preferredBlock)
  3704.         T:place("fence", -1, "down", false)
  3705.         T:forward(1)
  3706.         T:place(preferredBlock, -1, "down", false)
  3707.         T:forward(1)
  3708.         T:place(preferredBlock, -1, "down", false)
  3709.         T:forward(2)
  3710.         T:place(preferredBlock, -1, "down", false)
  3711.     end
  3712.    
  3713.     function lib.signRun(preferredBlock ,message)
  3714.         T:place(preferredBlock, -1, "down", false)
  3715.         T:forward(4)
  3716.         T:place(preferredBlock, -1, "down", false)
  3717.         turtle.back()
  3718.         turtle.back()
  3719.         T:down(1)
  3720.         T:place("sign", -1, "forward", false, message)
  3721.         T:go("U1F2")
  3722.     end
  3723.    
  3724.     function lib.goToWater(height)
  3725.         local built = 0 -- measures completed lift height
  3726.         while turtle.down() do -- takes turtle to bottom of water source
  3727.             height = height + 1
  3728.             if turtle.detect() then
  3729.                 built = built + 1
  3730.             end
  3731.         end
  3732.         T:up(1) -- above watersource assuming it is 1-1.5 blocks deep
  3733.         height = height - 1
  3734.         -- built = built - 1 not required as next block is water source: not detected
  3735.         return built, height
  3736.     end
  3737.    
  3738.     function lib.fillBuckets(toBuild)
  3739.         local emptySlots, water = lib.stackBuckets() -- gets no of empty slots + no of water buckets
  3740.         if water < toBuild then -- no of water buckets onboard less than required quantity
  3741.             for i = 1, toBuild do -- fill required no of buckets up to max space in inventory
  3742.                 emptySlots = lib.getEmptySlots()
  3743.                 if emptySlots == 0 then -- inventory full
  3744.                     break
  3745.                 else
  3746.                     if T:getWater("down") then
  3747.                         water = water + 1
  3748.                         sleep(0.5)
  3749.                     end
  3750.                 end
  3751.             end
  3752.         end
  3753.        
  3754.         return water
  3755.     end
  3756.    
  3757.     function lib.buildLift(preferredBlock)
  3758.         local built = 0 -- measures completed lift height
  3759.         local height = 0 -- measures total height from starting position
  3760.         built, height = lib.goToWater(height) -- returns lift blocks already placed, total height of drop from starting point
  3761.         local toBuild = height - built -- no of blocks to increase lift size
  3762.         while toBuild > 0 do -- at least 1 block height remaining
  3763.             local water = lib.fillBuckets(toBuild) -- no of water buckets onboard (could be more than required)
  3764.             if water > toBuild then
  3765.                 water = toBuild
  3766.             end
  3767.             while turtle.detect() do -- climb to top of existing lift
  3768.                 turtle.up()
  3769.                 height = height - 1
  3770.             end
  3771.             T:forward(1)
  3772.             for i = 1, water do -- build lift by no of water buckets
  3773.                 if T:placeWater("forward")  then
  3774.                     T:up(1)
  3775.                     height = height - 1
  3776.                     toBuild = toBuild - 1
  3777.                     T:place(preferredBlock, -1, "down", false)
  3778.                 end
  3779.             end
  3780.             turtle.back()
  3781.             -- may still be some height to complete, but needs refill
  3782.             if toBuild > 0 then
  3783.                 lib.goToWater(0) --return to source
  3784.                 lib.fillBuckets(toBuild)
  3785.             end
  3786.         end
  3787.         if height > 0 then -- if any remaining distance
  3788.             T:up(height)
  3789.         end
  3790.        
  3791.     end
  3792.    
  3793.     function lib.buildSection(preferredBlock, solid)
  3794.         -- builds a section without any blocks in the centre
  3795.         -- second layer of each section end walls have fence posts
  3796.         T:go("F1C2 F2C2 F1R1", false, 0, false, preferredBlock) -- first side solid row
  3797.         if solid then -- first layer of each section
  3798.             T:go("F1C2 F1R1", false, 0, false, preferredBlock) -- top side solid row
  3799.         else
  3800.             T:go("F1") -- top side solid row
  3801.             if not T:place("fence", -1, "down", false) then-- first side
  3802.                 T:place(preferredBlock, -1, "down", false)
  3803.             end
  3804.             T:go("F1R1") -- top side solid row
  3805.         end
  3806.         T:go("F1C2 F2C2 F1R1", false, 0, false, preferredBlock) -- far side solid row
  3807.         T:go("F1C2 F1R1U1", false, 0, false, preferredBlock) -- bottom side solid row
  3808.     end
  3809.     --[[
  3810.         clsTurtle methods:
  3811.         clsTurtle.place(self, blockType, damageNo, direction, leaveExisting)
  3812.         clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
  3813.     ]]
  3814.     -- remove 1 stack stone from chest
  3815.     local preferredBlock = lib.getStone("down", 1) -- use this as default building block
  3816.     if stage == 1 then
  3817.         -- build base floor
  3818.         --T:go("R2F2R1F3R1", false, 0, false, preferredBlock)
  3819.         T:go("R2F1C2R1F1C2F1C2F1C2R1", false, 0, false, preferredBlock)
  3820.         for i = 1, 2 do
  3821.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  3822.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  3823.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  3824.         end
  3825.         -- move back to centre, build water source, with soul sand at base of first source
  3826.         --T:go("R1F3L1C2F1C2F2D1", false, 0, false, preferredBlock) --just behind chest, 1 below ground level
  3827.         T:go("R1F3L1F2C2F1D1", false, 0, false, preferredBlock) --1 block behind chest, 1 below ground level
  3828.         T:place("minecraft:soul_sand", -1, "down", false) -- over block 1 of water source
  3829.         T:go("F1C2F1C2", false, 0, false, preferredBlock) -- over block 2 of water source
  3830.         T:go("F1C2U1C2", false, 0, false, preferredBlock) -- over block 4 of water source
  3831.         T:go("F1C2F1C2R2F5R2", false, 0, false, preferredBlock) -- over block 1 of water source
  3832.         T:placeWater("down")
  3833.         T:forward(2) -- over block 3 of water source
  3834.         T:placeWater("down")
  3835.         turtle.back() -- over block 2 of water source
  3836.         T:getWater("down")
  3837.         T:go("F2D1R2C2") -- over block 4 of water source
  3838.         T:go("U1", false, 0, false, preferredBlock)
  3839.         T:placeWater("down")
  3840.         T:forward(4)
  3841.         lib.stackBuckets() -- put all buckets in same slot
  3842.         T:dropItem("minecraft:dirt", "up", 0) -- drop dirt up:  clsTurtle.dropItem(self, item, direction, keepAmount)
  3843.         preferredBlock = lib.getStone("down", 6)
  3844.         T:go("R1F2R1U1") -- move to start position
  3845.         for i = 1, 2 do
  3846.             -- build first level of tower: 2 x outside run, 2 x sign run
  3847.             lib.outsideRun(preferredBlock)
  3848.             if i == 1 then -- place door
  3849.                 T:go("L1F1L1F1L1D1")
  3850.                 T:place("door", -1, "forward", false)
  3851.                 T:go("U1L1F1R1F1L1")
  3852.             end
  3853.             T:go("R1F1R1")
  3854.             lib.signRun(preferredBlock, "Pint size\nzombies\nProhibited")
  3855.             T:go("L1F1L1C2", false, 0, false, preferredBlock)
  3856.             T:forward(4) -- miss out centre block
  3857.             T:place(preferredBlock, -1, "down", false)
  3858.             T:go("R1F1R1")
  3859.             lib.signRun(preferredBlock, "Pint size\nzombies\nProhibited")
  3860.             T:go("L1F1L1")
  3861.             lib.outsideRun(preferredBlock)
  3862.             if i == 1 then -- layer 1
  3863.                 T:go("R1F1R1F1R1D1") -- place door
  3864.                 T:place("door", -1, "forward", false)
  3865.                 T:go("U1 R1F1 L1F5 L1U1 F2D1  F2R2 U1") -- go over door
  3866.             else -- layer 2
  3867.                 T:go("L1F5L1F6R2U1") -- over corner of lower platform
  3868.             end
  3869.         end
  3870.         for i = 1, 2 do -- build both sides of platform, leave centre missing
  3871.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  3872.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  3873.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  3874.         end
  3875.         T:go("R1F3L1C2F1C2F1C2F4C2F1C2F1C2", false, 0, false, preferredBlock) --fill in centre row
  3876.         --T:go("R2F6R1F1R1U1") -- go to start of tower base
  3877.         T:go("R2F7R2D3") -- go to start on top of chest
  3878.         T:sortInventory()
  3879.     elseif stage == 2 then
  3880.         -- start on top of chest, should have sufficient stone in inventory
  3881.         T:go("U3L1F1R1F1U1") -- go to start of tower base
  3882.         for i = 1, 7 do -- build 14 block high tower
  3883.             lib.buildSection(preferredBlock, false)
  3884.             lib.buildSection(preferredBlock, true)
  3885.         end
  3886.         T:go("R2F4R1F4R1", false, 0, false, preferredBlock) -- build upper platform (154 blocks remaining)
  3887.         for i = 1, 2 do -- build both sides of upper platform, leave centre missing
  3888.             lib.baseRun(preferredBlock, 12, "R1F1R1")
  3889.             lib.baseRun(preferredBlock, 12, "L1F1L1")
  3890.             lib.baseRun(preferredBlock, 12, "R1F1R1")
  3891.             lib.baseRun(preferredBlock, 12, "L1F1L1")
  3892.             lib.baseRun(preferredBlock, 12, "R1F6R1")
  3893.         end
  3894.         T:go("R1F5 L1C2 F1C2 F1C2 F1C2 F1C2 F4C2 F1C2 F1C2 F1C2 F1C2 ", false, 0, false, preferredBlock) --fill in centre row
  3895.         T:go("R2F5") -- return to drop area
  3896.         lib.buildLift(preferredBlock) -- build bubble lift
  3897.         T:go("F3R1F1R1U1") -- go to start of tower base
  3898.         T:go("C2F4 C2R1F1R1", false, 0, false, preferredBlock)      -- left side layer 21
  3899.         T:go("F2C2 F2C2 L1F1L1", false, 0, false, preferredBlock)   -- centre layer 21
  3900.         T:go("C2F4 C2R2U1", false, 0, false, preferredBlock)        -- right side layer 21
  3901.         T:go("C2F4 C2R1F1R1", false, 0, false, preferredBlock)      -- right side layer 22
  3902.         T:place("fence", -1, "down", false)                         -- fence centre of bottom side layer 22
  3903.         T:go("F2C2 F2L1F1L1", false, 0, false, preferredBlock)      -- centre layer 22
  3904.         T:go("C2F4 C2R2F2L1F1R2D2", false, 0, false, preferredBlock) --ready to place ladder
  3905.         T:place("ladder", -1, "forward", false)
  3906.         T:up(1)
  3907.         T:place("ladder", -1, "forward", false)
  3908.         --T:go("U2R1F4R1F1R1") -- ready to make upper part of tower base
  3909.         T:go("U2R1F4R1F1R1") -- ready to make upper part of tower base
  3910.         for i = 1, 2 do -- build both sides of platform, leave centre missing
  3911.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  3912.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  3913.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  3914.         end
  3915.         T:go("R1F3 L1C2 F1C2 F1C2 F1", false, 0, false, preferredBlock) --fill in centre row
  3916.         T:place("minecraft:soul_sand", -1, "down", false)
  3917.         T:go("F1C2 F2C2 F1C2 F1C2", false, 0, false, preferredBlock)
  3918.         T:go("R2F6R1F1R1U1") -- go to start of tower base
  3919.         -- build 2 levels, finish signs and ladders
  3920.         T:go("C2F2 R1D2 U1", false, 0, false, preferredBlock)
  3921.         T:place("ladder", -1, "down", false)
  3922.         T:turnRight(1)
  3923.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  3924.         T:go("U1R2F2C2 R1F2C2 R1", false, 0, false, preferredBlock) --top right corner
  3925.         T:go("F4C2B2D1", false, 0, false, preferredBlock)
  3926.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  3927.         T:go("U1F2R1F1C2F1R1U1", false, 0, false, preferredBlock) --ready for second level
  3928.         T:go("C2F2 R2D1", false, 0, false, preferredBlock)
  3929.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  3930.         T:go("U1R2F2C2R1", false, 0, false, preferredBlock) --top left corner
  3931.         T:go("F1R1C2F4C2", false, 0, false, preferredBlock) --mid bottom row
  3932.         T:go("L1F1L1C2", false, 0, false, preferredBlock) -- bottom right corner
  3933.         T:go("F2R2D1", false, 0, false, preferredBlock)
  3934.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  3935.         T:go("U1R2F2C2", false, 0, false, preferredBlock) -- top right corner
  3936.         -- return to chest
  3937.         T:go("L1F1L1 F5D23R2", false, 0, false, preferredBlock) -- return to chest
  3938.         T:sortInventory()
  3939.     elseif stage == 3 then
  3940.         --[[ move to top of structure
  3941.         | 4 |
  3942.         |3 5|
  3943.         | X |
  3944.         |2 6|
  3945.         | 1 |
  3946.         ]]
  3947.         local towerHeight = 128 -- even no only suggest 128
  3948.         while turtle.detect() do
  3949.             turtle.up()
  3950.         end
  3951.         T:go("F1U1", false, 0, false, preferredBlock) -- return to finish tower
  3952.         for i = 1, towerHeight do -- 1
  3953.             T:go("C2U1", false, 0, false, preferredBlock)
  3954.         end
  3955.         T:go("F1L1F1R1D2")
  3956.         while turtle.down() do -- 2
  3957.             T:fillVoid("up", {preferredBlock})
  3958.         end
  3959.         T:go("F1R2C1R2F1D1", false, 0, false, preferredBlock)
  3960.         for i = 1, towerHeight / 2 do -- 3
  3961.             T:go("U2C2", false, 0, false, preferredBlock)
  3962.         end
  3963.         T:go("U1F1R1F1R1D1", false, 0, false, preferredBlock) -- back of tower facing front
  3964.         local deviate = false
  3965.         while turtle.down() do -- 4
  3966.             T:place("fence", -1, "up", false)
  3967.             if turtle.down() then
  3968.                 T:fillVoid("up", {preferredBlock})
  3969.             else
  3970.                 T:go("F1R2C1R1F1R1D1", false, 0, false, preferredBlock)
  3971.                 deviate = true
  3972.                 break
  3973.             end
  3974.         end
  3975.         if not deviate then
  3976.             T:go("F1L1F1R1D1", false, 0, false, preferredBlock)
  3977.         end
  3978.         for i = 1, towerHeight / 2 do -- 5
  3979.             T:go("U2C2", false, 0, false, preferredBlock)
  3980.         end
  3981.         T:go("F2R2", false, 0, false, preferredBlock) -- facing back of tower
  3982.         while turtle.down() do -- 6
  3983.             T:fillVoid("up", {preferredBlock}) --layer 129
  3984.         end
  3985.         T:go("F1L2C1U"..towerHeight)
  3986.         T:go("F4R1F3R1U1", false, 0, false, preferredBlock)
  3987.         -- add small platform at the top
  3988.         lib.baseRun(preferredBlock, 8, "R1F1R1")
  3989.         lib.baseRun(preferredBlock, 8, "L1F3L1")
  3990.         lib.baseRun(preferredBlock, 8, "L1F1L1")
  3991.         lib.baseRun(preferredBlock, 8, "R1F1R1")
  3992.         T:go("C2 F1C2 F1C2 F4C2 F1C2 F1C2 R2F3", false, 0, false, preferredBlock) --fill in centre row
  3993.         lib.buildLift(preferredBlock) -- build bubble lift
  3994.     end
  3995.     return {}
  3996. end
  3997.  
  3998. local function createFarm(R, extend) -- 31
  3999.     -- if extend ~= nil then this has been called from createFarmExtension()
  4000.     -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4001.     local lib = {}
  4002.     function lib.addWaterSource(R, pattern, storage)
  4003.         -- pattern = {"d","c","c","d"} t = place crafting  instead of dirt
  4004.         -- place(self, blockType, damageNo, direction, leaveExisting, signText)
  4005.         T:go("D1x2C2", false, 0, false, R.useBlockType)
  4006.         for i = 1, 4 do
  4007.             T:dig("forward")
  4008.             if pattern[i] == "d" then
  4009.                 T:place("dirt", -1, "forward", false)
  4010.             elseif pattern[i] == "t" then
  4011.                 --if not T:place("minecraft:crafting_table", -1, "forward", false) then
  4012.                 if T:place(storage, -1, "forward", false) then
  4013.                     if T:dropItem("crafting", "forward", 0) then
  4014.                         print("Crafting table -> buried storage")
  4015.                     end
  4016.                 else
  4017.                     T:place("dirt", -1, "forward", false) -- dirt if no storage available
  4018.                 end
  4019.             else
  4020.                 T:place(R.useBlockType, -1, "forward", false)
  4021.             end
  4022.             T:turnRight(1)
  4023.         end
  4024.         T:up(1)
  4025.         T:placeWater("down")
  4026.     end
  4027.    
  4028.     function lib.placeDirt(count, atCurrent)
  4029.         if atCurrent then
  4030.             local blockType = T:getBlockType("down")
  4031.             if blockType:find("dirt") == nil and blockType:find("grass_block") == nil then
  4032.                 T:place("dirt", -1, "down", false)
  4033.             end
  4034.         end
  4035.         for  i = 1, count do
  4036.             T:forward(1)
  4037.             T:dig("up")
  4038.             local blockType = T:getBlockType("down")
  4039.             if blockType:find("dirt") == nil and blockType:find("grass_block") == nil then
  4040.                 T:place("dirt", -1, "down", false)
  4041.             end
  4042.         end
  4043.     end
  4044.  
  4045.     function lib.placeStorage(storage, storageBackup)
  4046.         T:dig("down")
  4047.         if not T:place(storage, -1, "down", false) then-- place barrel/chest below
  4048.             T:place(storageBackup, -1, "down", false) -- place chest below
  4049.         end
  4050.     end
  4051.  
  4052.    
  4053.     -- extend "", "right" or "forward". only adds a single new farm.
  4054.     -- right adds farm and checks for existing front extensions, dealt with separately
  4055.     -- clsTurtle.place(blockType, damageNo, direction, leaveExisting)
  4056.     if extend == nil then
  4057.         extend = ""
  4058.     end
  4059.     local blockType = ""
  4060.     -- extend = "right": placed on cobble corner of existing farm facing right side
  4061.     -- extend = "front": placed on cobble corner of existing farm facing front
  4062.     -- else placed on ground at corner of potential new farm facing front
  4063.    
  4064.     local storage, storageBackup = utils.setStorageOptions()
  4065.     -- step 1 dig ditch round perimeter wall
  4066.     if extend == "right" then
  4067.         -- move to front corner ground ready for ditch
  4068.         T:go("F1L1F12D1R1", false, 0, false, R.useBlockType)
  4069.         -- cut ditch round new farm extension
  4070.         for i = 1, 12 do
  4071.             T:go("x0F1")
  4072.         end
  4073.         T:go("R1x0")
  4074.         for i = 1, 13 do
  4075.             T:go("x0F1")
  4076.         end
  4077.         T:go("R1x0")
  4078.         -- now at lower right corner. if extension below, do not cut ditch
  4079.         blockType = T:getBlockType("forward")
  4080.         if blockType:find("stone") ~= nil then -- already a farm extension on left side
  4081.             -- return to start for adding chests and walls
  4082.             T:go("U1R1F1L1F12", false, 0, false, R.useBlockType)
  4083.         else -- finish ditch
  4084.             for i = 1, 12 do
  4085.                 T:go("x0F1")
  4086.             end
  4087.             T:go("R1U1F1") -- on corner of new extension
  4088.         end
  4089.     elseif extend == "forward" then
  4090.         T:go("L1F2R1D1", false, 0, false, R.useBlockType)
  4091.         -- cut ditch round new farm extension
  4092.         for i = 1, 12 do
  4093.             T:go("x0F1", false, 0, false, R.useBlockType)
  4094.         end
  4095.         T:go("R1x0", false, 0, false, R.useBlockType)
  4096.         for i = 1, 13 do
  4097.             T:go("x0F1", false, 0, false, R.useBlockType)
  4098.         end
  4099.         T:go("R1x0", false, 0, false, R.useBlockType)
  4100.         for i = 1, 11 do
  4101.             T:go("x0F1", false, 0, false, R.useBlockType)
  4102.         end
  4103.         T:go("U1x0F1R1F12R1", false, 0, false, R.useBlockType) -- on corner of new extension
  4104.     else -- new farm. cut a groove round the entire farm base
  4105.         -- move to left side of intended wall
  4106.         T:go("L1F1x0R1", false, 0, false, R.useBlockType)
  4107.         for j = 1, 4 do
  4108.             for i = 1, 12 do
  4109.                 T:go("x0F1", false, 0, false, R.useBlockType)
  4110.             end
  4111.             T:go("R1x0F1", false, 0, false, R.useBlockType)
  4112.         end
  4113.         T:go("R1F1L1U1", false, 0, false, R.useBlockType)
  4114.     end
  4115.     -- stage 2 place sapling and double barrel/chest
  4116.     T:dig("down") --remove cobble if present
  4117.     T:place("dirt", -1, "down", false)
  4118.     T:go("F1R2")
  4119.     T:place("sapling", -1, "forward", false) -- plant sapling
  4120.     T:go("L1")
  4121.     lib.placeStorage(storage, storageBackup)
  4122.     T:go("L1F1R1")
  4123.     lib.placeStorage(storage, storageBackup)
  4124.     T:turnLeft(1)
  4125.     if extend == "right" then -- cobble wall exists so go forward to its end
  4126.         T:forward(9)
  4127.     else -- new farm or extend forward
  4128.         for i = 1, 9 do -- complete left wall to end of farm
  4129.             T:go("F1x0x2C2", false, 0, false, R.useBlockType)
  4130.         end
  4131.     end
  4132.     T:go("R1F1 R1x0 x2C2 F1D1", false, 0, false, R.useBlockType)-- turn round ready for first dirt col
  4133.     lib.addWaterSource(R, {"d","c","c","d"}, storage) -- water at top of farm
  4134.     lib.placeDirt(9, false) -- place dirt back to start
  4135.     lib.addWaterSource(R, {"c","c","t","d"}, storage) -- water source next to chests, includes crafting table
  4136.     T:go("U1F1R2")
  4137.     if T:getBlockType("down"):find(storage) == nil and T:getBlockType("down"):find(storageBackup) == nil then
  4138.         lib.placeStorage(storage, storageBackup)
  4139.     end
  4140.     T:go("R1F1L1")
  4141.     if T:getBlockType("down"):find(storage) == nil and T:getBlockType("down"):find(storageBackup) == nil then
  4142.         lib.placeStorage(storage, storageBackup)
  4143.     end
  4144.     T:go("F1D1")
  4145.     lib.placeDirt(9, true)
  4146.     local turn = "R"
  4147.     for i = 1, 7 do
  4148.         T:go("F1U1x0C2"..turn.."1F1"..turn.."1x0x2C2F1D1", false, 0, false, R.useBlockType)
  4149.         lib.placeDirt(9, true)
  4150.         if turn == "R" then
  4151.             turn = "L"
  4152.         else
  4153.             turn = "R"
  4154.         end
  4155.     end
  4156.     T:go("F1U1x0C2"..turn.."1F1"..turn.."1x0x2C2F1D1", false, 0, false, R.useBlockType)
  4157.     lib.addWaterSource(R, {"d","c","c","d"}, storage)
  4158.     lib.placeDirt(9, false)
  4159.     lib.addWaterSource(R, {"c","c","d","d"}, storage)
  4160.     T:go("F1U1R1C2x0F1x0x2C2R1", false, 0, false, R.useBlockType)
  4161.     for i = 1, 11 do
  4162.         T:go("F1x0x2C2", false, 0, false, R.useBlockType)
  4163.     end
  4164.     -- add barrel/chest to any existing farm extension to the right
  4165.     T:go("L1F1L1")
  4166.     if T:getBlockType("down"):find("stone") == nil then -- farm extension already exists to right
  4167.         lib.placeStorage(storage, storageBackup)
  4168.     end
  4169.     T:go("L1F11")
  4170.    
  4171.     return {"Modular farm completed"}
  4172. end
  4173.  
  4174. local function createFarmExtension(R) -- 32
  4175.     -- assume inventory contains 4 chests, 64 cobble, 128 dirt, 4 water, 1 sapling
  4176.     -- check position by rotating to face tree/sapling
  4177.     local doContinue = true
  4178.     local treePresent = false
  4179.     local extend = "right" -- default
  4180.     if R.subChoice == 1 then
  4181.         extend = "forward"
  4182.     end
  4183.     local storage, storageBackup = utils.setStorageOptions()
  4184.     local blockType = T:getBlockType("down")
  4185.     if blockType:find(storage) == nil and blockType:find(storageBackup) == nil then
  4186.         return
  4187.         {
  4188.             "Barrel or chest not present below\n",
  4189.             "Unable to calculate position",
  4190.             "Move me next to/front of the tree/sapling",
  4191.             "lower left corner of the existing farm."
  4192.         }
  4193.     else
  4194.         for i = 1, 4 do
  4195.             blockType = T:getBlockType("forward")
  4196.             if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil then
  4197.                 treePresent = true
  4198.                 break
  4199.             end
  4200.             T:turnRight()
  4201.         end
  4202.         if not treePresent then
  4203.             return
  4204.             {
  4205.                 "Unable to locate tree or sapling",
  4206.                 "Plant a sapling on the lower left",
  4207.                 "corner of the farm, or move me there"
  4208.             }
  4209.         end
  4210.     end
  4211.     if doContinue then -- facing tree. check if on front or l side of farm
  4212.         if extend == "forward" then
  4213.             T:go("R1F11") -- to other side of farm. may be stone or barrel/chest below
  4214.             blockType = T:getBlockType("down")
  4215.             if blockType:find(storage) ~= nil or blockType:find(storageBackup) ~= nil then
  4216.                 doContinue = false
  4217.             end
  4218.         else
  4219.             T:go("R2F9") -- to right of farm, may be sapling/tree in front
  4220.             blockType = T:getBlockType("forward")
  4221.             if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil then
  4222.                 doContinue = false
  4223.             end
  4224.         end
  4225.         if doContinue then -- extend farm.
  4226.             createFarm(R, extend)
  4227.         else
  4228.             return
  4229.             {
  4230.                 "This farm has already been extended",
  4231.                 "Move me next to/front of the tree / sapling",
  4232.                 "of the last extension in this direction."
  4233.             }
  4234.         end
  4235.     end
  4236.     return {"Modular crop farm extended"}
  4237. end
  4238.  
  4239. local function createFloorCeiling(R) -- 79 size integer 1 to 4
  4240.     --[[
  4241.     R.up = true for ceiling
  4242.     R.down = true for floor
  4243.     R.height = 0 for normal
  4244.     R.height combined with R.up/R.down used for remote access
  4245.     ]]
  4246.    
  4247.     local useBlock = T:getSlotContains(1)
  4248.     local waterPresent = false
  4249.    
  4250.     if R.useBlockType ~= "" then
  4251.         useBlock = R.useBlockType
  4252.     end
  4253.     print("Using ".. useBlock)
  4254.     local direction = "down"
  4255.     if R.up then
  4256.         direction = "up"
  4257.     end
  4258.     if R.height > 0 then -- remote placing. go up/down R.height first
  4259.         R.silent = true
  4260.         local depth = 0
  4261.         if R.down then -- floor could be under water
  4262.             while turtle.down() do
  4263.                 depth = depth + 1
  4264.             end
  4265.         elseif R.up then
  4266.             while turtle.up() do
  4267.                 depth = depth + 1
  4268.                 if depth > R.height + 3 then
  4269.                     break
  4270.                 end
  4271.             end
  4272.         end
  4273.         if not(R.height - depth <= 2 or depth - R.height <= 2) then
  4274.             T:up(depth)
  4275.             return {"Measured depth/height of "..depth.." > setting: "..R.height}
  4276.         end
  4277.         -- not returned so depth acceptable
  4278.     end
  4279.     -- check if block above/below
  4280.     local blockBelow = turtle.detectDown()
  4281.     local blockAbove = turtle.detectUp()
  4282.     if R.subChoice == 2 then -- New floor over existing
  4283.         -- if no block below, assume in correct position and continue
  4284.         -- else move up 1 and continue
  4285.         if blockBelow then T:up(1) end
  4286.     elseif R.subChoice == 4 then -- New ceiling under existing
  4287.         -- if no block above, assume in correct position and continue
  4288.         -- else move down 1 and continue
  4289.         if blockAbove then T:down(1) end
  4290.     end
  4291.    
  4292.     local evenWidth = false
  4293.     local evenHeight = false
  4294.     local loopWidth
  4295.     -- go(path, useTorch, torchInterval, leaveExisting)
  4296.     if R.width % 2 == 0 then
  4297.         evenWidth = true
  4298.         loopWidth = R.width / 2
  4299.     else
  4300.         loopWidth = math.ceil(R.width / 2)
  4301.     end
  4302.     if R.length % 2 == 0 then
  4303.         evenHeight = true
  4304.     end
  4305.     -- if R.width is even no, then complete the up/down run
  4306.     -- if R.width odd no then finish at top of up run and reverse
  4307.     for x = 1, loopWidth do
  4308.         -- Clear first column (up)
  4309.         local tAvailable = T:getStock(useBlock, -1)
  4310.         if tAvailable.total < R.length and not R.silent then
  4311.             return {"Insufficient resources to complete current row"}
  4312.         end
  4313.         for y = 1, R.length do
  4314.             local blockType = T:getBlockType("forward")
  4315.             if not waterPresent then
  4316.                 if blockType:find("lava") ~= nil or blockType:find("water") ~= nil then
  4317.                     waterPresent = true
  4318.                 end
  4319.             end
  4320.             T:place(useBlock, -1, direction, false) -- leaveExisting = false
  4321.             if y < R.length then
  4322.                 T:go("F1", false, 0, false)
  4323.             end
  4324.         end
  4325.         -- clear second column (down)
  4326.         if x < loopWidth or (x == loopWidth and evenWidth) then -- go down if on R.width 2,4,6,8 etc
  4327.             T:go("R1F1R1", false,0,false)
  4328.             tAvailable = T:getStock(useBlock, -1)
  4329.             if tAvailable.total < R.length and not R.silent then
  4330.                 return {"Insufficient resources to complete current row"}
  4331.             end
  4332.             for y = 1, R.length do
  4333.                 T:place(useBlock, -1, direction, false) -- leaveExisting = false
  4334.                 if y < R.length then
  4335.                     T:go("F1", false, 0, false)
  4336.                 end
  4337.             end
  4338.             if x < loopWidth then
  4339.                 T:go("L1F1L1", false,0,false)
  4340.             else
  4341.                 T:turnRight(1)
  4342.                 T:forward(R.width - 1)
  4343.                 T:turnRight(1)
  4344.             end
  4345.         else -- equals R.width but is 1,3,5,7 etc
  4346.             T:turnLeft(2) --turn round 180
  4347.             T:forward(R.length - 1)
  4348.             T:turnRight(1)
  4349.             T:forward(R.width - 1)
  4350.             T:turnRight(1)
  4351.         end
  4352.     end
  4353.     if waterPresent then
  4354.         return {"water or lava found"}
  4355.     end
  4356.     return {""}
  4357. end
  4358.  
  4359. local function createIceCanal(R) -- 55
  4360.     --[[
  4361.         R.subChoice =
  4362.         1: move right into canal, build left towpath
  4363.         2: build left towpath
  4364.         3: build right towpath
  4365.         4: move left into canal, build right towpath
  4366.         5/8: clear path 3 blocks high, place slabs/torches
  4367.         6/7: build alternating ice road / create 3 block high air gap (2 over water)
  4368.     ]]
  4369.     local oTurn = "R"
  4370.     if R.side == "R" then
  4371.         oTurn = "L"
  4372.     end
  4373.     local lib = {}
  4374.    
  4375.     function lib.convertTowpath(R)
  4376.         -- only used to convert existing water canal, so assume towpath already present
  4377.         -- starting position 1 block above existing towpath
  4378.         for i = 1, R.length do
  4379.             if turtle.detectDown() then                         -- eg existing torch
  4380.                 T:dig("down")
  4381.             end
  4382.             local placeSlab = true
  4383.             if R.torchInterval > 0 then                         -- place torches
  4384.                 if i == 1 or i % R.torchInterval == 0 then      -- ready to place torch
  4385.                     --go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4386.                     T:go("C2x0", false, 0, false, R.useBlockType)-- place solid block below
  4387.                     T:go("F1R2x0")
  4388.                     T:place("torch", 0, "forward")              -- place torch, move forward
  4389.                     T:turnRight(2)                              -- turn round
  4390.                     placeSlab = false
  4391.                 end
  4392.             end
  4393.             if placeSlab then
  4394.                 T:dig("up")
  4395.                 if not T:place("slab", 0, "down") then          -- break if out of slabs
  4396.                     break
  4397.                 end
  4398.                 if i < R.length then
  4399.                     T:forward(1)                                -- move forward
  4400.                 end
  4401.             end
  4402.         end
  4403.     end
  4404.    
  4405.     function lib.iceCanalTowpath(R)
  4406.         -- move forward placing slabs along the way. If existing water canal, ceiling will be raised by 1 block
  4407.         local torchInterval = 0
  4408.         local placeIce = true
  4409.         for i = 1, R.length do
  4410.             local addTorch = false
  4411.             if R.torchInterval > 0 then
  4412.                 if i == 1 then addTorch = true end
  4413.                 if torchInterval >= R.torchInterval then
  4414.                     addTorch = true
  4415.                     torchInterval = 0
  4416.                 end
  4417.             end
  4418.             lib.iceCanalEdge(R, addTorch, i, placeIce)
  4419.             torchInterval = torchInterval + 1
  4420.             placeIce = not placeIce
  4421.         end
  4422.         T:go(oTurn.."1")
  4423.     end
  4424.    
  4425.     function lib.iceCanalEdge(R, addTorch, numBlocks, placeIce)
  4426.         -- starting position facing canal side
  4427.         local blockType = T:getBlockType("forward")         -- ? air / slab / other
  4428.         local isWater, isSource, isIce = T:isWater("down")  -- water / ice below
  4429.         if blockType:find("slab") == nil then               -- add slab
  4430.             if addTorch then                                -- check if torch needed
  4431.                 -- T:place(blockType, damageNo, direction, leaveExisting, signText)
  4432.                 if not T:place("stone", -1, "forward", false) then
  4433.                     T:checkInventoryForItem({"stone"}, {math.ceil(R.length / R.torchInterval)}, true)
  4434.                 end
  4435.                 T:go("U1x1 U1x1 D1")                    -- water level to 2 above water level
  4436.                 if T:getItemSlot("minecraft:torch", -1) > 0 then
  4437.                     T:place("torch", -1, "forward", false)
  4438.                 end
  4439.                 T:down(1)                               -- back to above water level
  4440.                 if not isIce then                       -- break block below if NOT ice
  4441.                     T:dig("down")
  4442.                 end
  4443.             else
  4444.                 if not T:place("slab", -1, "forward", false) then
  4445.                     T:checkInventoryForItem({"slab"}, {R.length - numBlocks}, true)
  4446.                 end
  4447.                 if not isSource then                    -- NOT on water, so dig above
  4448.                     T:go("U1x1 U1x1 D2")
  4449.                 end
  4450.                 if not isIce and not isSource then
  4451.                     T:dig("down")
  4452.                 end
  4453.             end
  4454.         else -- slab already on side
  4455.             if addTorch then                            -- check if torch needed
  4456.                 T:dig("forward")
  4457.                 if not T:place("stone", -1, "forward", false) then
  4458.                     T:checkInventoryForItem({"stone"}, {math.ceil(R.length / R.torchInterval)}, true)
  4459.                 end
  4460.                 T:go("U1x1 U1x1 D1")                    -- water level to 2 above water level
  4461.                 if T:getItemSlot("minecraft:torch", -1) > 0 then
  4462.                     T:place("torch", -1, "forward", false)
  4463.                 end
  4464.                 T:down(1)                               -- back to above water level
  4465.                 if not isIce then                       -- break block below if NOT ice
  4466.                     T:dig("down")
  4467.                 end
  4468.             end
  4469.         end
  4470.         if R.data == "ice" and placeIce and not isIce then -- R.data = "ice", placeIce = true, not already ice present
  4471.             T:place("ice", -1, "down", true)
  4472.         end
  4473.         if numBlocks < R.length then
  4474.             T:go(oTurn.."1F1"..R.side.."1")
  4475.         end
  4476.     end
  4477.    
  4478.     function lib.convertIcepath(length)
  4479.         -- use only for placing ice to convert a water canal
  4480.         -- place ice on alternate blocks until length reached or run out of ice
  4481.         local placeIce = true
  4482.         for i = 1, length do
  4483.             if T:getBlockType("down"):find("ice") == nil then -- no ice below
  4484.                 T:dig("down") -- remove any existing block
  4485.                 if placeIce then
  4486.                     if not T:place("ice", -1, "down", true) then -- out of ice
  4487.                         break
  4488.                     end
  4489.                     if i == length - 1 then
  4490.                         break
  4491.                     end
  4492.                 end
  4493.             else -- ice already below
  4494.                 placeIce = true
  4495.             end
  4496.             T:go("U1x0 D1F1")
  4497.             placeIce = not placeIce -- reverse action
  4498.         end
  4499.     end
  4500.    
  4501.     function lib.convertToAir(length)
  4502.         -- use only for converting a water canal. start at ground level
  4503.         -- dig up/down/forward to clear space
  4504.         for i = 1, length + 1 do
  4505.             T:go("U1x0D1")
  4506.             if i < length + 1 then
  4507.                 T:go("x2F1")
  4508.             else
  4509.                 T:dig("down")
  4510.             end
  4511.         end
  4512.     end
  4513.    
  4514.     function lib.initialise(R)
  4515.         if R.subChoice == 1 or R.subChoice == 4 then       
  4516.             local blockType = T:getBlockType("down")        -- ? at ground/water level or on top of existing slab
  4517.             if blockType:find("slab") ~= nil then           -- slab already present
  4518.                 T:go(oTurn.."1F1D1"..R.side.."2")           -- move right/left forward, down onto ice canal top, face canal wall
  4519.             elseif blockType:find("torch") ~= nil then
  4520.                 T:go(oTurn.."1F1D2"..R.side.."2")           -- move right/left forward, down onto ice canal top, face canal wall
  4521.             else                                            -- assume on ground / water level
  4522.                 T:go(oTurn.."1F1"..R.side.."2")             -- move right/left forward onto ice canal top, face canal wall
  4523.             end
  4524.         else
  4525.             if T:isWater("forward") then                    -- player put turtle inside canal water
  4526.                 T:up(1)
  4527.             end
  4528.             T:go(R.side.."1")                               -- face canal wall
  4529.         end
  4530.     end
  4531.    
  4532.     if R.length == 0 then R.length = 1024 end
  4533.  
  4534.     if R.subChoice <= 4  then                               -- towpath 1,2,3,4
  4535.         lib.initialise(R)                                   -- reposition
  4536.         lib.iceCanalTowpath(R)                              -- build towpath
  4537.     elseif R.subChoice == 5 or R.subChoice == 8 then        -- assume placed on towpath
  4538.         if T:getBlockType("down"):find("slab") ~= nil then  -- slab already present
  4539.             T:go("F1")
  4540.         else
  4541.             T:up(1)
  4542.         end
  4543.         lib.convertTowpath(R)
  4544.     elseif R.subChoice == 6 or R.subChoice == 7 then   
  4545.         if R.data == "ice" then                         -- assume placed on existing ice or initial ice position
  4546.             lib.convertIcepath(R.length)-- place ice
  4547.         else                                            -- assume placed on empty path
  4548.             lib.convertToAir(R.length)                  -- clear 3 high area
  4549.         end
  4550.     end
  4551.    
  4552.     return {}
  4553. end
  4554.  
  4555. local function createLadder(R) -- 12
  4556.     -- createLadder(R.data ="bedrock", R.height = 70, R.depth = -48)
  4557.     -- go(path, useTorch, torchInterval, leaveExisting)
  4558.     -- place(blockType, damageNo, direction, leaveExisting)
  4559.     local lib = {}
  4560.    
  4561.     function lib.placeLadder(direction, ledge, i, height)
  4562.         -- 1 check both sides and behind
  4563.         local fluid = false
  4564.         local block = T:isWaterOrLava("forward", ledge)
  4565.         if block:find("water") ~= nil or block:find("lava") ~= nil then
  4566.             --[[ surround 2 block shaft with blocks ]]
  4567.             T:go("R1C1 R1C1 R1C1 R1F1 L1C1 R1C1 R1C1 R1C1F1 R2C1 x1")
  4568.         else
  4569.             --[[ no water/lava so prepare ladder site]]
  4570.             T:go("F1 L1C1 R1C1 R1C1 L1B1", false, 0, true)
  4571.         end
  4572.         if not T:place("ladder", -1, "forward", false) then
  4573.             T:checkInventoryForItem({"ladder"}, {height - i}, false)
  4574.         end
  4575.         -- 3 check if ledge, torch
  4576.         if ledge == 0 and i > 1 then -- place block above unless new ladder
  4577.             T:place("common", -1, direction, false) -- any common block
  4578.         elseif ledge == 1 then
  4579.             T:place("minecraft:torch", -1, direction, false)
  4580.         elseif ledge == 2 then
  4581.             ledge = -1
  4582.         end
  4583.        
  4584.         return ledge
  4585.     end
  4586.    
  4587.     local retValue = {}
  4588.     local ledge = 0
  4589.     local height = math.abs(R.depth - R.height) --height of ladder
  4590.     local blockType = T:getBlockType("forward")
  4591.     if R.up then -- create ladder from current level to height specified
  4592.         for i = 1, height do -- go up, place ladder as you go
  4593.             ledge = lib.placeLadder("down", ledge, i, height) -- ladder placed forward, stone ledge for torch placed down
  4594.             if i <  height then
  4595.                 T:up(1)
  4596.                 ledge = ledge + 1
  4597.             end
  4598.         end    
  4599.     else -- R.down = true: ladder towards bedrock      
  4600.         local success = true
  4601.         local numBlocks, errorMsg = 0, ""
  4602.         T:down(1)
  4603.         for i = 1, height do -- go down, place ladder as you go
  4604.             ledge = lib.placeLadder("up", ledge, i, heigt) -- ladder placed forward, stone torch placed up
  4605.             --success, blocksMoved, errorMsg, blockType = clsTurtle.down(self, steps, getBlockType)
  4606.             if i < height then
  4607.                 success, numBlocks, errorMsg, blockType = T:down(1, true) -- true = return blockType
  4608.                 ledge = ledge + 1
  4609.             end
  4610.             -- if looking for stronghold then check for stone_bricks
  4611.             if blockType:find("stone_bricks") ~= nil then
  4612.                 table.insert(retValue, "Stronghold discovered")
  4613.                 break -- stop descent at stronghold
  4614.             end
  4615.         end
  4616.         -- if user requested shelter create chamber at this level
  4617.         if R.data == "chamber" then -- user has chosen to build a chamber
  4618.             table.insert(retValue, "Shelter constucted at level".. R.depth)
  4619.             if blockType:find("bedrock") ~= nil then
  4620.                 T:findBedrockTop(0) -- test to check if on safe level immediately above tallest bedrock
  4621.             end
  4622.             -- In shaft, facing start direction, on lowest safe level
  4623.             -- create a square space round shaft base, end facing original shaft, 1 space back
  4624.             T:go("L1n1 R1n3 R1n2 R1n3 R1n1", false, 0, true)
  4625.             T:go("U1Q1 R1Q3 R1Q2 R1Q3 R1Q1 R1D1", false, 0, true)
  4626.         end
  4627.     end
  4628.    
  4629.     return retValue
  4630. end
  4631.  
  4632. local function createLadderToWater(R) -- 86
  4633.     -- go down to water/lava with alternaate solid/open layers
  4634.     -- create a working area at the base
  4635.     -- Return to surface facing towards player placing ladders
  4636.     local inAir = true
  4637.     local numBlocks, errorMsg = 0, ""
  4638.     local height = 2
  4639.     local blockType = T:getBlockType("down")
  4640.     if blockType ~= "" then -- not over air
  4641.         T:forward(1)
  4642.     end
  4643.     T:go("R2D1") -- face player, go down 2
  4644.     while inAir do --success = false when hits water/lava
  4645.         blockType = T:isWaterOrLava("down")
  4646.         if blockType:find("water") ~= nil or blockType:find("lava") ~= nil then
  4647.             inAir = false
  4648.         end
  4649.         T:go("C1R1 C1R2 C1R1", false, 0, false) -- surround front  and sides with cobble
  4650.         if inAir then
  4651.             T:down(1)
  4652.             height = height + 1
  4653.         end
  4654.         T:place("ladder", 0, "up")
  4655.     end
  4656.     -- In shaft, facing opposite start direction, on water/lava, ladders above
  4657.     T:go("C2", false, 0, false)
  4658.     utils.goBack(1)
  4659.     T:place("ladder", 0, "forward")
  4660.     T:up(3)
  4661.     height = height - 3
  4662.     for i = 1, height do
  4663.         if i < height then
  4664.             T:go("C2U1", false, 0, false)
  4665.         else
  4666.             T:go("C2", false, 0, false)
  4667.         end
  4668.     end
  4669.  
  4670.     return {}
  4671. end
  4672.  
  4673. local function createMine() -- 11
  4674.     -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4675.     T:clear()  
  4676.     T:go("m32U1R2M16", true, 8, true) -- mine ground level, go up, reverse and mine ceiling to mid-point
  4677.     T:go("U2D2") -- create space for chest
  4678.     T:place("minecraft:chest", -1, "up", false)
  4679.     T:emptyTrash("up")
  4680.     T:go("D1R1m16U1R2M16", true, 8, true) -- mine floor/ceiling of right side branch
  4681.     T:emptyTrash("up")
  4682.     T:go("D1m16U1R2M16", true, 8, true) -- mine floor/ceiling of left side branch
  4683.     T:emptyTrash("up")
  4684.     T:go("L1M15F1R1D1", true, 8, true) -- mine ceiling of entry corridor, turn right
  4685.     T:go("F1x0 F1x0 n14 R1n32 R1n32 R1n32 R1n14 F1x0 F1U1", true, 8, true)-- mine floor of 36 x 36 square corridor
  4686.     T:go("R1F16R2") --return to centre
  4687.     T:emptyTrash("up")
  4688.     T:go("F16R1") --return to entry shaft
  4689.     T:go("F2Q14R1Q32R1Q32R1Q32R1Q14F2R1", true, 8, true) --mine ceiling of 36x36 square corridor. return to entry shaft + 1
  4690.     T:go("F16R2") --return to centre
  4691.     T:emptyTrash("up")
  4692.     -- get rid of any remaining torches
  4693.     while T:getItemSlot("minecraft:torch", -1) > 0 do
  4694.         turtle.select(T:getItemSlot("minecraft:torch", -1))
  4695.         turtle.dropUp()
  4696.     end
  4697.     T:go("F16R1F1R1") --return to shaft + 1
  4698.     for i = 1, 8 do
  4699.         T:go("N32L1F1L1", true, 8, true)
  4700.         T:go("N16L1F"..(i * 2).."R2", true, 8, true)
  4701.         T:emptyTrash("up")
  4702.         if i < 8 then
  4703.             T:go("F"..(i * 2).."L1N16R1F1R1", true, 8, true)
  4704.         else
  4705.             T:go("F"..(i * 2).."L1N16L1", true, 8, true)
  4706.         end
  4707.     end
  4708.     T:go("F17L1") -- close gap in wall, return to ladder + 1
  4709.     for i = 1, 8 do
  4710.         T:go("N32R1F1R1", true, 8, true)
  4711.         T:go("N16R1F"..(i * 2).."R2", true, 8, true)
  4712.         T:emptyTrash("up")
  4713.         if i < 8 then
  4714.             T:go("F"..(i * 2).."R1N16L1F1L1", true, 8, true)
  4715.         else
  4716.             T:go("F"..(i * 2).."R1N16R1", true, 8, true)
  4717.         end
  4718.     end
  4719.     T:go("F16R1")
  4720.     T:clear()
  4721.     return{"Mining operation complete"}
  4722. end
  4723.  
  4724. local function createMobFarmCube(R) -- 61, 62
  4725.     --[[
  4726.     Part 1 / 3 Mob Spawner Farm
  4727.     blaze = true: blaze spawner in nether
  4728.         R.subChoice is set to:
  4729.         1 = on top of spawner
  4730.         2 = line of sight
  4731.         3 = room below
  4732.     blaze = false: overworld mob spawner
  4733.         R.subChoice is set to:
  4734.         1 = on top of spawner
  4735.         2 = bottom left corner
  4736.         3 = top left corner
  4737.         4 = bottom right, corner
  4738.         5 = top right corner
  4739.         R.width / R.length set by player (external size)
  4740.     ]]
  4741.     local blaze = true
  4742.     if R.data == "spawner" or R.data == "chest" then
  4743.         blaze = false
  4744.     end
  4745.     local continue = false
  4746.     if R.data == "restart" then
  4747.         continue = true
  4748.     end
  4749.     R.direction = "clock"       -- starting on right side
  4750.     if not blaze then
  4751.         print("R.width: "..tostring(R.width))
  4752.         R.width = R.width - 2       -- internal width
  4753.         R.length = R.length - 2     -- internal length
  4754.        
  4755.         if R.subChoice == 2 or R.subChoice == 3 then
  4756.             R.direction = "anticlock"
  4757.         end
  4758.     end
  4759.     -- R.data allows for 2-part operation "blaze" = main cube, "restart" = killzone
  4760.     T:clear()
  4761.     local lib = {}
  4762.    
  4763.     function lib.floorSection(length)
  4764.         for i = 1, length do        -- starts on top left corner
  4765.             T:go("C2")
  4766.             if i < length then
  4767.                 T:forward(1)
  4768.             else
  4769.                 T:go("R1F1")
  4770.             end
  4771.         end
  4772.     end
  4773.    
  4774.     function lib.wallSection(blaze)
  4775.         blaze = blaze or false
  4776.         for i = 1, 4 do
  4777.             for j = 1, 11 do
  4778.                 if blaze then
  4779.                     T:place("slab", 0, "up", false)
  4780.                     T:go("C2", false, 0, false)
  4781.                 else
  4782.                     T:go("C0C2", false, 0, false)
  4783.                 end
  4784.                 if j < 11 then
  4785.                     T:forward(1)
  4786.                     T:go("R2C1L2", false, 0, false)
  4787.                 else
  4788.                     T:turnRight(1)
  4789.                 end
  4790.             end
  4791.         end
  4792.     end
  4793.    
  4794.     function lib.ceiling(blaze)
  4795.         -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4796.         -- all outer walls complete, now for remaining 9x9 ceiling
  4797.         blaze = blaze or false
  4798.         for i = 1, 9 do
  4799.             for j = 1, 9 do
  4800.                 if blaze then
  4801.                     T:place("slab", 0, "up", false)
  4802.                     T:dig("down")
  4803.                 else
  4804.                     T:go("C0x2", false, 0, true)
  4805.                 end
  4806.                 if j < 9 then
  4807.                     T:forward(1)
  4808.                 else    -- end of length
  4809.                     local place = false
  4810.                     if i%2 == 1 then -- odd numbers 1,3,5,7,9
  4811.                         if i < 9 then
  4812.                             place = true
  4813.                             T:go("R1F1 R1")
  4814.                         end
  4815.                     else
  4816.                         place = true
  4817.                         T:go("L1F1 L1")
  4818.                     end
  4819.                     if place then
  4820.                         if blaze then
  4821.                             T:place("slab", 0, "up", false)
  4822.                             T:dig("down")
  4823.                         else
  4824.                             T:go("C0x2", false, 0, true)
  4825.                         end
  4826.                     end
  4827.                 end
  4828.             end
  4829.         end
  4830.     end
  4831.    
  4832.     function lib.clearWall(length)
  4833.         for i = 1, 4 do
  4834.             for j = 1, length do
  4835.                 if j < length then
  4836.                     T:go("x0x2F1")
  4837.                 else
  4838.                     T:go("x0x2R1")
  4839.                 end
  4840.             end
  4841.         end
  4842.     end
  4843.    
  4844.     function lib.isSpawner()
  4845.         local blockType = T:getBlockType("down")
  4846.         if blockType:find("spawner") ~= nil then
  4847.             return true, "top"
  4848.         end
  4849.         blockType = T:getBlockType("up")
  4850.         if blockType:find("spawner") ~= nil then
  4851.             return true, "bottom"
  4852.         end
  4853.         blockType = T:getBlockType("forward")
  4854.         if blockType:find("spawner") ~= nil then
  4855.             return true, "forward"
  4856.         end
  4857.         return false, ""
  4858.     end
  4859.    
  4860.     function lib.placeFloor(width, length, blockType)
  4861.         -- T:place(blockType, damageNo, direction, leaveExisting, signText)
  4862.         for i = 1, width do            
  4863.             for j = 1, length do
  4864.                 T:place(blockType, -1, "down", false)
  4865.                 if j < length then
  4866.                     T:forward(1)
  4867.                 else
  4868.                     if i%2 == 1 then -- odd numbers 1,3,5,7,9
  4869.                         if i < width then
  4870.                             T:go("R1F1R1", false, 0, true)
  4871.                         end
  4872.                     else
  4873.                         T:go("L1F1L1", false, 0, true)
  4874.                     end
  4875.                 end
  4876.             end
  4877.         end
  4878.     end
  4879.    
  4880.     function lib.searchStrip(distance)
  4881.         --go forward until hit either a wall or a chest
  4882.         local blocks = 1
  4883.         print("Searching strip, distance = "..distance)
  4884.         while blocks < distance do --max travel is external width/length
  4885.             if turtle.forward() then
  4886.                 blocks = blocks + 1
  4887.             else
  4888.                 print("Checking for chest")
  4889.                 if lib.isChest("forward") then
  4890.                     if turtle.forward() then
  4891.                         blocks = blocks + 1
  4892.                     end
  4893.                 else
  4894.                     break
  4895.                 end
  4896.             end
  4897.         end
  4898.     end
  4899.    
  4900.     function lib.findChests(R)
  4901.         for i = 1, 4 do
  4902.             print("Searching wall "..i)
  4903.             if i == 1 or i == 3 then
  4904.                 lib.searchStrip(R.width)    -- find and empty chests along width
  4905.             else
  4906.                 lib.searchStrip(R.length)   -- find and empty chests along length
  4907.             end
  4908.             if R.direction == "clock" then
  4909.                 T:turnRight(1)
  4910.             else
  4911.                 T:turnLeft(1)
  4912.             end
  4913.         end
  4914.  
  4915.         -- checked all walls
  4916.         T:go("F".. math.floor(R.width / 2)) -- now at mid-dungeon, next to wall
  4917.         if T:getItemSlot("chest") > 0 then
  4918.             if R.direction == "clock" then
  4919.                 T:turnLeft(1)
  4920.             else
  4921.                 T:turnRight(1)
  4922.             end
  4923.             -- now at mid-dungeon, facing wall
  4924.             -- deposit chest outside the dungeon
  4925.             while turtle.back() do end -- backing spawner
  4926.             T:go("x0 F1x0 F1x0 F1x0 F1x0 F1x0 F1x0 x1x2")
  4927.             -- place(self, blockType, damageNo, direction, leaveExisting, signText)
  4928.             T:place("chest", -1, "forward", false)
  4929.             -- empty out all except stone and slab
  4930.             T:emptyInventorySelection("forward", {"cobble", "tuff", "slab", "granite", "andesite", "diorite" }, {0,0,0,0,0,0})
  4931.             T:turnLeft(2)
  4932.             T:checkInventoryForItem({"stone"}, {512}, false, "Full cube uses ~700 blocks\nEstimate your requirements")
  4933.             while turtle.forward() do end -- facing spawner
  4934.         else
  4935.             if R.direction == "clock" then
  4936.                 T:turnRight(1)
  4937.             else
  4938.                 T:turnLeft(1)
  4939.             end
  4940.         end -- now at mid-dungeon, facing spawner
  4941.     end
  4942.    
  4943.     function lib.enterDungeon(R)
  4944.         --[[ find and empty any chests, return to dungeon wall ]]
  4945.         print("Entering dungeon")
  4946.         local blockType = T:getBlockType("forward")
  4947.         if blockType == "" then -- nothing in front.Error
  4948.             return false, "No block in front: Check position."
  4949.         else -- attempt entry into dungeon wall
  4950.             if R.subChoice == 2 then        -- bottom left
  4951.                 T:go("R1F1 L1U2 F2R1")
  4952.             elseif R.subChoice == 3 then    -- top left
  4953.                 T:go("R1F1 L1D1 F2R1")
  4954.             elseif R.subChoice == 4 then    -- bottom right
  4955.                 T:go("L1F1 R1U2 F2L1")
  4956.             elseif R.subChoice == 5 then    -- top right
  4957.                 T:go("L1F1 R1D1 F2L1")
  4958.             end
  4959.             while turtle.down() do end -- either on floor or chest
  4960.             if lib.isChest("down") then
  4961.                 turtle.down()
  4962.             end
  4963.             print("Searching for chests")
  4964.             lib.findChests(R)   -- go round inside walls  emptying chests. Finish mid-wall
  4965.         end
  4966.         return true, ""-- success, message
  4967.     end
  4968.    
  4969.     function lib.isChest(direction)
  4970.         direction = direction or "forward"
  4971.         local blockType = T:getBlockType(direction)
  4972.         if blockType:find("chest") ~= nil then -- chest found. early stages so empty and break it
  4973.             print("Chest found")
  4974.             while T:suck(direction) do end
  4975.             T:dig(direction, false) -- false prevents checking for chests
  4976.             return true
  4977.         elseif blockType:find("torch") ~= nil then
  4978.             print("Torch found")
  4979.             T:dig(direction, false) -- false prevents checking for chests
  4980.             return true
  4981.         end
  4982.         return false
  4983.     end
  4984.        
  4985.     function lib.findSpawner(blaze)
  4986.         local moves  = 0
  4987.         local quit = false
  4988.         -- assume turtle placed on centre of inside spawner wall in front of spawner
  4989.         -- or as close as possible in Nether
  4990.         print("Checking if next to spawner")
  4991.         local found, position = lib.isSpawner() -- true/false, top/bottom/nil
  4992.         if not found then -- move forward towards spawner
  4993.             print("Not close to spawner")
  4994.             while turtle.forward() and not quit do
  4995.                 moves = moves + 1
  4996.                 if moves > 16 then
  4997.                     quit = true
  4998.                 end
  4999.             end
  5000.             found, position = lib.isSpawner() -- true/false, top/bottom/nil
  5001.             if not found then
  5002.                 if blaze then -- could be behind a wall
  5003.                     print("Assuming blaze spawner behind a wall")
  5004.                     T:forward(1)
  5005.                     moves = moves + 1
  5006.                     while turtle.forward() and not quit do
  5007.                         moves = moves + 1
  5008.                         if moves > 16 then
  5009.                             quit = true
  5010.                         end
  5011.                     end
  5012.                     found, position = lib.isSpawner() -- true/false, top/bottom/nil
  5013.                     if not found then
  5014.                         T:go("R2F"..moves + 2 .."R2")
  5015.                     end
  5016.                 end
  5017.             end
  5018.         end
  5019.        
  5020.         return found, position
  5021.     end
  5022.    
  5023.    
  5024.     if not continue then -- new mob cube either dungeon or blaze
  5025.         -- clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5026.         -- determine spawner position level 4, move to top of spawner (level 6)
  5027.         print("Checking if already at spawner")
  5028.         local found, position = lib.isSpawner() -- already on spawner?
  5029.         if blaze then
  5030.             if not found then -- away from spawner
  5031.                 if R.subChoice == 3 then
  5032.                     T:go("U5")
  5033.                 end
  5034.                 found, position = lib.findSpawner(blaze)
  5035.             end
  5036.         else -- go to bottom of dungeon and empty chests
  5037.             if not found then --outside dungeon
  5038.                 local success, message = lib.enterDungeon(R)
  5039.                 if not success then
  5040.                     return {message}
  5041.                 end
  5042.                 found, position = lib.findSpawner(blaze) -- is spawner in front / above / below?
  5043.             end
  5044.         end
  5045.        
  5046.         if found then -- true: move to correct starting position
  5047.             --[[
  5048.             1 |c|c|c|c|c|c|c|c|c|c|c|
  5049.             2 |w| | | | | | | | | |w|
  5050.             3 |w| | | | | | | | | |w|
  5051.             4 |w| | | | | | | | | |w|
  5052.             5 |w| | | | | | | | | |w|
  5053.             6 |w| | | | |s| | | | |w|
  5054.             7 |w| | | | | | | | | |w|
  5055.             8 |w| | | | | | | | | |w|
  5056.             9 |w| | | | | | | | | |w|
  5057.            10 |w| | | | | | | | | |w| exit level for overworld
  5058.            11 |f|f|f|f|f|f|f|f|f|f|f|
  5059.            12 |f|f|f|f|f|f|f|f|f|f|f| sub floor for overworld
  5060.                1 2 3 4 5 6 7 8 9 1 1
  5061.                                  0 1
  5062.             ]]
  5063.             -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5064.             if position == "bottom" then
  5065.                 T:go("B1U2F1")
  5066.             elseif position == "forward" then
  5067.                 T:go("U1F1")
  5068.             end
  5069.            
  5070.             T:up(1)
  5071.             T:place("slab", -1, "down", true)               -- place slab on top T:place(blockType, damageNo, direction, leaveExisting)
  5072.             -- go up 2 blocks, forward 5, right, forward 5, right
  5073.             T:go("U2F5 R1F5 R1")                            -- Level 2: now placed 1 below ceiling inside wall, top right corner of new dungeon
  5074.             lib.wallSection(blaze)                          -- fix layers 1, 2, 3 including ceiling margin turtle at Level 2           
  5075.             T:go("F1R2 C1L1 F1R2 C1R1", false, 0, false)    -- exit wall, repair behind, still Level 2
  5076.             lib.ceiling(blaze)                              -- fix ceiling, end opposite corner to start
  5077.             T:go("R2D3")                                    -- clear the inner walls inside original dungeon
  5078.             lib.clearWall(9)                                -- clear the 9 x 9 area around the spawner
  5079.             T:go("F1R1F1L1")
  5080.             lib.clearWall(7)                                -- clear the 7 x 7 area around the spawner
  5081.             T:go("F1R1F1L1")
  5082.             lib.clearWall(5)                                -- clear the 5 x 5 area around the spawner. Also needed for cave spiders
  5083.             T:go("R2F1R1F1R1")
  5084.             T:go("F7R1 F8L1F1R2", false, 0, false)          -- return from ceiling, enter wall below previous section: Level 5
  5085.             lib.wallSection()                               -- deal with areas from spawner level up (4,5,6). walls only   
  5086.             T:go("F1R2 C1L1 F1R2 C1R1 D3", false, 0, false) -- exit wall, repair behind, embed 1 below original floor: Level 8
  5087.             clearRectangle({width = 9, length = 9, up = true, down = true}) -- clear levels 7,8,9
  5088.             T:go("L1F1 L1F1L2", false, 0, false)            -- go inside wall sectio, ready for next wall section
  5089.             lib.wallSection()                               -- deal with walls on levels 7,8,9
  5090.             T:go("F1R2 C1L1 F1R2 C1R1 D3", false, 0, false) -- exit wall, repair behind, embed 4 below original floor: Level 11
  5091.             --print("Check: about to clear 3 floors 3 below spawner") read()
  5092.             clearRectangle({width = 9, length = 9, up = true, down = true}) -- clear levels 10,11,12
  5093.            
  5094.             if blaze then
  5095.                 T:go("L1F1 L1F1L2", false, 0, false)            -- ready for next wall section
  5096.                 lib.wallSection()                               -- wall on layers 10,11,12
  5097.                 T:go("F1R2 C1L1 F1R2 C1R1 D3", false, 0, false) -- exit wall, repair behind, embed 1 below original floor: Level 8
  5098.                 clearRectangle({width = 9, length = 9, up = true, down = true}) -- clear levels 13, 14, 15
  5099.             end
  5100.            
  5101.             T:go("L1F1L1F1L2", false, 0, false) -- ready for next wall section
  5102.             --print("Check: level 11, 5 north, 5 east")
  5103.             --read()
  5104.             lib.wallSection()   -- wall on layers 10,11,12 or 12,13,14 if blaze
  5105.             T:go("F1R1 F1R2 C1R1 U1", false, 0, false) -- exit wall, repair behind: Level 10, facing entry point top right corner
  5106.             T:down(1)
  5107.             if blaze then
  5108.                 lib.placeFloor(9, 9, brick)             -- place brick floor on level 14
  5109.                 T:go("L1F4 R1F2 U4")                    -- ends facing out to lower chamber ?below staircase
  5110.                 -- now needs to build killzone
  5111.             else
  5112.                 lib.placeFloor(9, 9, "stone")           -- ends facing wall on entrance side
  5113.                 T:go("U1R2")
  5114.                 lib.placeFloor(9, 9, "stone")           -- ends facing wall on opposite side
  5115.                 -- return to mid-point front
  5116.                 T:go("R2F8 R1F4 L1F2")                  -- exit at bottom of dungeon
  5117.                 T:go("x1U1 x1U1 x1U1 x1D3 R2")          -- rise to chest, then return ready for next stage 
  5118.                 -- ends with turtle facing spawner, in front of exit hole              
  5119.             end
  5120.         else
  5121.             return
  5122.             {
  5123.                 "Spawner not found. Place me on top,",
  5124.                 "immediately below, or facing it.",
  5125.                 "\nEnter to quit"
  5126.             }
  5127.         end
  5128.     end
  5129.     if continue then
  5130.         T:clear()
  5131.         local text =
  5132. [[~yellow~Items required to continue:
  5133.  
  5134. ~lightGray~slabs            81
  5135. ~orange~nether bricks    88
  5136. ~yellow~lava buckets     4
  5137. ~brown~chest / barrel   1
  5138. ~gray~hopper           1      
  5139.  
  5140. ~red~WARNING ~yellow~Inventory ejects items if you
  5141. continue! ~orange~(Choose at next menu.)
  5142.  
  5143. ~white~Next -> Enter]]
  5144.         menu.colourText(nil, text, true)
  5145.         read()
  5146.         pp.itemColours = {colors.red, colors.lime}
  5147.         local choice = menu.new("Choose your option", {"Continue with build", "Re-start later"}, pp, "Type number + Enter") -- 1 = continue, 2= quit
  5148.         if choice == 1 then
  5149.             choice = menu.new("Choose your option", {"Turtle is above me", "Turtle is below or next to me"}, pp, "Type number + Enter") -- 1 = up, 2= down
  5150.             if choice == 1 then
  5151.                 T:emptyInventory("down")
  5152.             else
  5153.                 T:emptyInventory("up")
  5154.             end
  5155.         else
  5156.             return {"Blaze spawner partial build halted"}
  5157.         end
  5158.        
  5159.         --clsTurtle.getItemSlot(self, item, useDamage): return slotData.lastSlot, slotData.leastModifier, total, slotData
  5160.         T:checkInventoryForItem({brick}, {88})
  5161.         T:checkInventoryForItem({"slab"}, {81})
  5162.         T:checkInventoryForItem({"lava"}, {4})
  5163.         T:checkInventoryForItem({"sign"}, {1})
  5164.         T:checkInventoryForItem({"hopper"}, {1})
  5165.         T:checkInventoryForItem({"chest", "barrel"}, {1, 1})
  5166.         print("Stand clear. Starting in 2 secs")
  5167.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  5168.         -- place upper floor and slabs under it
  5169.         T:go("R2D4F2 L1F4 R1U4")   
  5170.         lib.placeFloor(9, 9, brick)             -- place brick floor on level 10
  5171.         T:down(2)
  5172.         T:place(brick, 0, "up")
  5173.         T:go("D1R2")
  5174.         lib.ceiling(true)                       -- true uses slabs
  5175.        
  5176.         -- place lava
  5177.         T:go("L1F4 L1F4 U4")                    -- through hole in ceiling
  5178.         T:go("F4 L1F4 R2")
  5179.         for i = 1, 4 do
  5180.             T:place("lava", 0 , "down")
  5181.             T:go("F8 R1")
  5182.         end
  5183.         T:go("F4 R1F4 D2 F1 R2")
  5184.         -- place sign and repair above
  5185.         T:dig("forward")
  5186.         T:place("sign", 0, true, "")
  5187.         T:down(1)
  5188.         T:place(brick, 0 , "up")
  5189.         T:forward(1)
  5190.         -- place blocks under exit hole
  5191.         for i = 1, 4 do
  5192.             T:place(brick, 0 , "forward")
  5193.             T:turnRight(1)
  5194.         end
  5195.         -- place chest and hopper
  5196.        
  5197.         T:go("D2x2")
  5198.         if not T:place("chest", 0, "down") then
  5199.             T:place("barrel", 0, "down")
  5200.         end
  5201.         T:up(1)
  5202.         T:place("hopper", 0, "down")
  5203.         utils.goBack(1)
  5204.         T:place("slab", 0, "forward")
  5205.         T:go("R2F5U3")-- return to starting point and create entrance
  5206.     end
  5207.     return {}
  5208. end
  5209.  
  5210. local function floodMobFarm(R) -- 63
  5211.     --[[Part 2 / 3 Mob Spawner Farm turtle on floor, pointing towards water source wall, single hole]]
  5212.     local lib ={}
  5213.    
  5214.     function lib.setPosition(addWater)
  5215.         local width = 0
  5216.         while turtle.forward() do end                   -- move forward until hit wall
  5217.         T:go("U1L1")
  5218.         while turtle.forward() do end                   -- move forward until hit left wall
  5219.         if addWater then
  5220.             T:placeWater("down")                        -- place water down
  5221.         end
  5222.         T:turnLeft(2)                                   -- turn round
  5223.         while turtle.forward() do
  5224.             width = width + 1
  5225.         end         -- go forward 7
  5226.         if addWater then                                -- back 1
  5227.             T:placeWater("down")                        -- place water                 
  5228.         end
  5229.         T:go("L2F".. math.floor(width / 2) .."L1")      -- turn round, go forward 3 (centre of wall), turn left
  5230.     end
  5231.  
  5232.     function lib.digFloor()
  5233.         T:go("x2F1 x2")                                 -- first block, move forward
  5234.        
  5235.         T:turnLeft(1)                                   -- left turn, go back into right side, facing left
  5236.         utils.goBack(1)
  5237.         T:go("x2 F1x2 F1x2 R1F1")                       -- go right to left dig 3 blocks, forward on left side
  5238.        
  5239.         T:turnRight(1)                                  -- right turn, go back into left side, facing right
  5240.         utils.goBack(1)
  5241.         T:go("x2 F1x2 F1x2 F1x2 F1x2 L1F1")             -- go left to right dig 5 blocks, forward on right side
  5242.        
  5243.         T:turnLeft(1)                                   -- left turn, go back into right side, facing left
  5244.         utils.goBack(1)
  5245.         T:go("x2 F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 R1F1")   -- go right to left dig 7 blocks, forward on left side
  5246.        
  5247.         T:turnRight(1)                                  -- right turn, go back into left side, facing right
  5248.         utils.goBack(1)
  5249.         T:go("x2 F1x2 F1x2 F1x2 F1x2 F1x2  F1x2  F1x2  F1x2 L1")    -- go left to right dig 5 blocks, face forward on right side
  5250.     end
  5251.    
  5252.     lib.setPosition(false)                  -- move to back of cube and verify position
  5253.     if R.subChoice == 1 then
  5254.         T:forward(3)                        -- forward 4 (centre of chamber)
  5255.     else
  5256.         T:forward(2)                        -- forward 3
  5257.     end
  5258.     T:down(1)
  5259.     lib.digFloor()
  5260.     if R.subChoice == 1 then       
  5261.         T:go("D1F1 L1F8")
  5262.         utils.goBack(4)
  5263.         T:go("L1U1")
  5264.         lib.setPosition(true)               -- place water sources
  5265.         T:go("F8D2")
  5266.         -- go down 2, check floor, up 1, place fence
  5267.         T:go("D2C2U1", false, 0, true)
  5268.         T:place("fence", -1, "down", false)
  5269.         T:go("F1D1C2U1", false, 0, true)
  5270.         T:place("fence", -1, "down", false)
  5271.         T:go("F1U1R2", false, 0, true)
  5272.         T:go("F1R1U1")
  5273.         T:place("sign", -1, "down", false)
  5274.         T:go("U1C0D1")
  5275.         T:place("slab", -1, "up", false)
  5276.         T:go("R2F1R2")
  5277.         T:place("sign", -1, "forward", false)
  5278.         T:go("R1F1R2C1R1F1D1L1") --sitting on soul sand/dirt facing spawner
  5279.         if not T:place("minecraft:soul_sand", -1, "down", false) then
  5280.             T:place("minecraft:dirt", -1, "down", false)
  5281.         end
  5282.     else
  5283.         T:go("D1F1 L1F8")
  5284.         T:go("R1F1 R1F8")
  5285.         utils.goBack(4)
  5286.         T:go("R1U1")
  5287.         lib.setPosition(true)       -- place water sources
  5288.         T:go("F8D2 F1C2C0 F1")      -- exit leaving single hole in wall, facing away from spawner
  5289.     end
  5290.    
  5291.     return {}
  5292. end
  5293.  
  5294. local function createMobBubbleLift(R) -- 64
  5295.     -- Part 3 / 3 Mob Spawner Farm
  5296.     -- R.subChoice = 1 or 2 (left/right)
  5297.     local lib = {}
  5298.    
  5299.     function lib.initialise()
  5300.         local blockType = T:getBlockType("down")
  5301.         if blockType ~= "minecraft:soul_sand" then
  5302.             T:dig("down")
  5303.             if not T:place("minecraft:soul_sand", -1, "down", false) then
  5304.                 return {"Unable to find or place soulsand."}
  5305.             end
  5306.         end
  5307.         -- check facing sign, rotate if not
  5308.         blockType = T:getBlockType("forward")
  5309.         local turns = 0
  5310.         while blockType:find("sign") == nil do
  5311.             T:turnRight(1)
  5312.             turns = turns + 1
  5313.             if turns == 4 then
  5314.                 return {"Unable to find sign."}
  5315.             end
  5316.             blockType = T:getBlockType("forward")
  5317.         end
  5318.         return {""}
  5319.     end
  5320.    
  5321.     function lib.createWaterSource(oTurn)
  5322.         T:go(oTurn.."1")            -- turn to opposite side of dropzone
  5323.         T:go("F1x0D1")
  5324.         for i = 1, 3 do
  5325.             T:go("C2 L1C1 R2C1 L1")
  5326.             if i < 3 then
  5327.                 T:go("F1x0")
  5328.             end
  5329.         end
  5330.         T:go("R2F1")                -- face column move to middle
  5331.         T:placeWater("forward")
  5332.         T:go("R2")                  -- face away
  5333.         T:placeWater("forward")
  5334.         T:go("U1x0 R2F1x0 F1x0"..oTurn.."1")    -- face column, return to soul sand, face spawner
  5335.     end
  5336.    
  5337.     function lib.goToWater(moves)
  5338.         T:down(moves)
  5339.         T:getWater("down")
  5340.         sleep(0.1)
  5341.         T:getWater("down")
  5342.     end
  5343.    
  5344.     function lib.placeCollector(turn, oTurn)
  5345.         local hopperSlot = T:getItemSlot("hopper")
  5346.         local chestSlot = T:getItemSlot("chest")
  5347.         if hopperSlot > 0 and chestSlot > 0 then
  5348.             T:dig("down")
  5349.             T:place("chest", 0, "down")
  5350.             T:go(turn.."1F1"..oTurn.."1")
  5351.             T:dig("down")
  5352.             T:place("chest", 0, "down")
  5353.             T:go(turn.."1")
  5354.             utils.goBack(3)
  5355.             T:go("D1x1")
  5356.             T:place("hopper", 0, "forward")
  5357.             T:go("U1C2F2"..oTurn.."1")
  5358.         end
  5359.     end
  5360.    
  5361.     function lib.up()
  5362.         local moves = 0
  5363.         while turtle.detect() do
  5364.             turtle.up()
  5365.             moves = moves + 1
  5366.         end
  5367.  
  5368.         return moves
  5369.     end
  5370.    
  5371.     function lib.createChamber()
  5372.         local D = {}
  5373.         D.width  = 4
  5374.         D.length = 7
  5375.         D.height = 4
  5376.         D.ceiling = true
  5377.         D.floor = true
  5378.         D.vDirection = "D"
  5379.         D.hDirection = "RL"
  5380.         D.goHome = true
  5381.  
  5382.         utils.createWalledSpace(D)
  5383.     end
  5384.    
  5385.     function lib.mobTransporter()
  5386.         for i = 1, 9 do -- fill in a solid block bar from bubble column for 8 spaces
  5387.             T:go("F1C0C2 R1C1 R1C1 R1C1 R1C1")
  5388.         end
  5389.         T:go("D1C2C1 R1C1 R2C1 L1 C0x0") -- move down column
  5390.         for i = 1, 8 do -- go under solid block bar
  5391.             T:go("F1C2 R1C1 L2C1 R1x0")
  5392.         end
  5393.     end
  5394.    
  5395.     local turn = "R"
  5396.     local oTurn = "L"
  5397.     if R.subChoice == 1 then
  5398.         turn = "L"
  5399.         oTurn = "R"
  5400.     end
  5401.    
  5402.     local data = lib.initialise()           -- check if in the right position
  5403.     if data[1] ~= "" then
  5404.         return data                         -- eg {"Unable to find sign."}
  5405.     end
  5406.     lib.createWaterSource(oTurn)            -- everything in place, build a water source, facing spawner
  5407.     for i = 1, 3 do     -- fill in back and one side, go up
  5408.         T:go(turn.."1C1"..turn.."1C1"..turn.."1x1"..turn.."1U1", false, 0, true)
  5409.     end
  5410.     -- dungeon wall, above mob exit, facing spawner
  5411.     local colHeight = 19
  5412.     for i = 1, colHeight do     -- tunnel up, filling 3 sides
  5413.         T:go(turn.."1C1"..turn.."1C1"..turn.."1x1"..turn.."1C1 U1", false, 0, true)
  5414.     end
  5415.     -- facing spawner 20 blocks up. move either left/right 8 blocks, repairing ceiling and sides
  5416.     T:go("C0"..turn.."2C1"..turn.."1F1 C0C1"..turn.."1C1"..turn.."2C1"..oTurn.."1", false, 0, true) -- fill top of column
  5417.    
  5418.     lib.mobTransporter()
  5419.     T:go("x2x0 F1x2x0 F1x2x0 R2") -- over water source
  5420.     -- now create bubble column
  5421.     T:down(colHeight + 2)
  5422.     local moves = 0
  5423.     repeat
  5424.         lib.goToWater(moves)    -- get water
  5425.         moves = lib.up()
  5426.         T:go("F1")
  5427.         T:placeWater("forward")
  5428.         T:go("U1C2")
  5429.         T:placeWater("forward")
  5430.         utils.goBack(1)
  5431.         T:go("C1")
  5432.         moves = moves + 1
  5433.     until moves >= colHeight + 1
  5434.     lib.goToWater(moves)    -- get water for last time
  5435.     lib.up()                -- finishes above lower part of the transport bar
  5436.     T:go("F2R2C1D1")        -- seal off bubble column
  5437.     utils.goBack(1)
  5438.     T:placeWater("forward") -- place source on top of bubble column
  5439.     utils.goBack(7)         -- over down shaft
  5440.     T:down(1)               -- start shaft, facing bubble column
  5441.     for i = 1, 17 do
  5442.         -- tunnel down, filling all 4 sides
  5443.         T:go("R1C1 R1C1 R1C1 R1C1 D1", false, 0, true)
  5444.     end
  5445.     lib.createChamber()
  5446.     T:go("x0")
  5447.     T:go(oTurn.."1C1".. turn.."1D1C2"..oTurn.."1C1"..turn.."1F1".. oTurn.."1F1"..oTurn.."1") -- facing end wall ready to place slabs
  5448.     for i = 1, 6 do
  5449.         T:place("slab", 0, "down")
  5450.         if i == 6 then
  5451.             T:go(oTurn.."1")
  5452.         end
  5453.         utils.goBack(1)
  5454.         T:go("C1")
  5455.     end
  5456.    
  5457.     T:go("D2F2"..turn.."1F5")
  5458.     T:placeWater("forward")
  5459.     T:go(turn.."1F1"..oTurn.."1") -- facing down mob channel floor
  5460.     for i = 1, 5 do
  5461.         T:go("C1")
  5462.         utils.goBack(1)
  5463.     end
  5464.     T:go("C1"..turn.."1F1"..turn.."1F1")
  5465.     for i = 1, 7 do
  5466.         T:go("C2x0")
  5467.         if i < 7 then
  5468.             T:forward(1)
  5469.         end
  5470.     end
  5471.     T:go("U3R2")
  5472.     for i = 1, 7 do
  5473.         T:go("F1x2")
  5474.     end
  5475.     T:go("D3")
  5476.    
  5477.     lib.placeCollector(turn, oTurn) -- if hopper / chests present
  5478.    
  5479.     return {}
  5480. end
  5481.  
  5482. local function createPlatform(R) -- 56
  5483.     -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5484.     local forward = true
  5485.     for w = 1, R.width do
  5486.         for l = 1, R.length do
  5487.             T:go("x2C2", false, 0, false, R.useBlockType)
  5488.             if R.up then
  5489.                 T:dig("up")
  5490.             end
  5491.             if l < R.length then
  5492.                 T:forward(1)
  5493.             end
  5494.         end
  5495.         if w < R.width then
  5496.             if forward then
  5497.                 if R.up then
  5498.                     T:go("R1F1 x0R1")
  5499.                 else
  5500.                     T:go("R1F1 R1")
  5501.                 end
  5502.             else
  5503.                 if R.up then
  5504.                     T:go("L1F1 x0L1")
  5505.                 else
  5506.                     T:go("L1F1 L1")
  5507.                 end
  5508.             end
  5509.         end
  5510.         forward = not forward
  5511.     end
  5512.     return {}
  5513. end
  5514.  
  5515. local function createPortal(R) -- 42
  5516.     --[[
  5517.     R.length = length of portal NOT width default 4
  5518.     R.height = height of portal default 5
  5519.     R.width = thickness of portal default 1
  5520.     R.data = "bury" to embed bottom into ground
  5521.     R.subChoice 1 = facing portal, 2 = aligned
  5522.     ]]
  5523.     local lib = {}
  5524.    
  5525.     function lib.buildBase()
  5526.         --T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5527.         T:go("C2", false, 0, false, R.useBlockType)
  5528.         T:forward(1)
  5529.         for i = 1, R.length - 2 do -- R.length = 4: place when i=1,2
  5530.             T:place("minecraft:obsidian", 0, "down", false)
  5531.             T:forward(1)
  5532.         end
  5533.         T:go("C2", false, 0, false, R.useBlockType)
  5534.     end
  5535.    
  5536.     function lib.buildLayer()
  5537.         T:place("minecraft:obsidian", 0, "down", false)
  5538.         for i = 1, R.length - 1 do -- R.length = 4: forward when i=1,2,3
  5539.             T:forward(1)
  5540.         end
  5541.         T:place("minecraft:obsidian", 0, "down", false)
  5542.     end
  5543.    
  5544.     if R.data ~= "bury" then
  5545.         T:up(1)
  5546.     end
  5547.     if R.subChoice == 1 then
  5548.         T:go("F1R1")
  5549.     end
  5550.     local out = true
  5551.     for width = 1, R.width do
  5552.         lib.buildBase()
  5553.         for i = 1, R.height - 2 do
  5554.             T:go("R2U1")
  5555.             out = not out
  5556.             lib.buildLayer()
  5557.         end
  5558.         T:go("R2U1")
  5559.         out = not out
  5560.         lib.buildBase()
  5561.         if out then
  5562.             T:go("R2F"..R.length - 1)
  5563.         end
  5564.         if width < R.width then
  5565.             T:go("R1F1D"..R.height.."R1")
  5566.             out = true
  5567.         else
  5568.             T:go("L1F"..R.width.."D"..R.height - 1 .."R2")
  5569.             if R.data ~= "bury" then
  5570.                 T:down(1)
  5571.             end
  5572.         end
  5573.     end
  5574.    
  5575.     return {}
  5576. end
  5577.  
  5578. local function createPortalPlatform() -- 48
  5579.     --[[ Used in End World to use a trapdoor to push player through portal ]]
  5580.     local lib ={}
  5581.    
  5582.     function lib.findPortal()
  5583.         local found = false
  5584.         local onSide = false
  5585.         for i = 1, 64 do
  5586.             if not turtle.up() then -- hit block above
  5587.                 found = true
  5588.                 break
  5589.             end
  5590.         end
  5591.         if found then
  5592.             -- are we under the centre block, or one of the sides?
  5593.             if turtle.detect() then -- under a side
  5594.                 onSide = true
  5595.             else    -- nothing in front, probably under centre, or facing wrong direction so check
  5596.                 for i = 1, 4 do
  5597.                     turtle.turnRight()
  5598.                     if turtle.detect() then
  5599.                         onSide = true
  5600.                         break
  5601.                     end
  5602.                 end
  5603.             end
  5604.             if onSide then-- move to centre
  5605.                 T:go("D1F1")
  5606.             end
  5607.         end
  5608.         local height = 3 -- allows for 2 bedrock + starting space
  5609.         while turtle.down() do
  5610.             height = height + 1
  5611.         end
  5612.         return found, height
  5613.     end
  5614.    
  5615.     function lib.addFloor(length)
  5616.         for i = 1, length do
  5617.             if i < length then
  5618.                 T:go("C2F1", false, 0, true)
  5619.             else
  5620.                 T:go("C2", false, 0, true)
  5621.             end
  5622.         end
  5623.     end
  5624.    
  5625.     function lib.buildLadder(height)
  5626.         for i = 1, height do
  5627.             --T:go("F1C1 R1C1 L2C1 L1F1L2", false, 0, true)
  5628.             T:go("F1C1 R1C1 L2C1 R1", false, 0, true)
  5629.             utils.goBack(1)
  5630.             if i > 3 then
  5631.                 T:go("C2")
  5632.             end
  5633.             T:place("minecraft:ladder", 0, "forward", true)
  5634.             T:up(1)
  5635.         end
  5636.     end
  5637.    
  5638.     local found, height = lib.findPortal()
  5639.     if found then   -- position under centre of beacon
  5640.         -- build ladder up and create platform
  5641.         T:go("L1F1L1F2L2")
  5642.         T:checkInventoryForItem({"minecraft:ladder"},{height})
  5643.         T:checkInventoryForItem({"stone"},{height * 4 + 18})
  5644.         T:checkInventoryForItem({"trapdoor"},{1})
  5645.         lib.buildLadder(height) -- ends facing ladder, 1 block above
  5646.        
  5647.         T:go("R1")
  5648.         utils.goBack(1)
  5649.         T:go("C2F1 C2F1 C2F1 C2")
  5650.         T:go("R1F1R1")
  5651.         T:go("C2F1 C2F1 C2F1 C2")
  5652.         utils.goBack(2)
  5653.         T:go("R1F1")            -- facing portal entrance
  5654.         T:place("trapdoor", -1, "up", false)
  5655.     else
  5656.         return {"Portal not found. Move me under","the centre if possible.", "wait for purple beacon."}
  5657.     end
  5658.     return {}
  5659. end
  5660.  
  5661. local function createRailway(R) -- 93
  5662.     -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5663.     --[[Build steps up or down ready for railtrack]]
  5664.     if R.down then
  5665.         if R.height == 0 then
  5666.             local blockType = ""
  5667.             while blockType == "" do
  5668.                 T:go("F1D1", false, 0, true)
  5669.                 blockType = T:getBlockType("down")
  5670.                 if blockType == "" then
  5671.                     T:go("C2", false, 0, true)
  5672.                 end
  5673.             end
  5674.         else
  5675.             for i = 1, R.height - 1 do
  5676.                 T:go("U1x0 D1x1 F1x0x1 D1x1 C2", false, 0, false)
  5677.             end
  5678.         end
  5679.     elseif R.up then
  5680.         for i = 1, R.height do
  5681.             T:go("C1U2 x0D1F1", false, 0, false) --put stone in front, up 2 excavate 1, down 1, forward 1
  5682.         end
  5683.     end
  5684.     return {}
  5685. end
  5686.  
  5687. local function createRectanglePath(R) -- 710, 83 direct commands
  5688.     -- allow user to control length / width of each path
  5689.     -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5690.     --local pp = utils.getPrettyPrint()
  5691.     local lib = {}
  5692.    
  5693.     function lib.forward(R)
  5694.         if R.subChoice == 1 then
  5695.             for i = 1, R.length do
  5696.                 T:go("F1x0C2", false, 0, true)
  5697.             end
  5698.         else
  5699.             for i = 1, R.length do
  5700.                 T:go("F1U1C0D1C2", false, 0, true)
  5701.             end
  5702.         end
  5703.     end
  5704.    
  5705.     function lib.back(R)
  5706.         for i = 1, R.length do
  5707.             turtle.back()
  5708.         end
  5709.     end
  5710.    
  5711.     function lib.left(R)
  5712.         T:turnLeft(R.length)
  5713.     end
  5714.    
  5715.     function lib.right(R)
  5716.         T:turnRight(R.length)
  5717.     end
  5718.    
  5719.     function lib.up(R)
  5720.         if R.subChoice == 1 then
  5721.             T:go("U2R2 x1R2 D1C2", false, 0, true)
  5722.         else
  5723.             T:go("U2R2 x1R2C0 D1C2", false, 0, true)
  5724.         end
  5725.     end
  5726.    
  5727.     function lib.down()
  5728.         T:go("D1C2", false, 0, true)
  5729.     end
  5730.    
  5731.     if R.data == "menu" then
  5732.         -- mimics direct commands using f.lua, r.lua etc with space between commands and number
  5733.         local width = 0
  5734.         local length = 0
  5735.         local choices =
  5736.         {
  5737.             "Forward 1 block",
  5738.             "Forward # blocks",
  5739.             "Back 1 block",
  5740.             "Back # blocks",
  5741.             "Turn Right",
  5742.             "Turn Left",
  5743.             "Up 1 block",
  5744.             "Down 1 block",
  5745.             "Quit"
  5746.         }
  5747.         local choice, modifier
  5748.         pp.itemColours = {colors.lime, colors.lime, colors.green, colors.green, colors.orange, colors.orange, colors.cyan, colors.cyan, colors.gray}
  5749.         while choice ~= 9 do
  5750.             choice, modifier = menu.menu("Choose next step", choices, pp, "Type number + Enter ")
  5751.             if choice == 1 then
  5752.                 R.length = 1
  5753.                 lib.forward(R)
  5754.             elseif choice == 2 then
  5755.                 -- getInteger(prompt, minValue, maxValue, row, fg, bg, default)
  5756.                 R.length = menu.getInteger("Move forward how many blocks?", 1, 250, nil, colors.lime)
  5757.                 lib.forward(R)
  5758.             elseif choice == 3 then
  5759.                 R.length = 1
  5760.                 lib.back(R)
  5761.             elseif choice == 4 then
  5762.                 R.length = menu.getInteger("Move back how many blocks?", 1, 250, nil, colors.green)
  5763.                 lib.back(R)
  5764.             elseif choice == 5 then
  5765.                 R.length = 1
  5766.                 lib.right(R)
  5767.             elseif choice == 6 then
  5768.                 R.length = 1
  5769.                 lib.left(R)
  5770.             elseif choice == 7 then
  5771.                 lib.up(R)
  5772.             elseif choice == 8 then
  5773.                 lib.down()
  5774.             end
  5775.         end
  5776.     else
  5777.         local instructions =
  5778. [[~lightGray~Commands:
  5779.  
  5780. direction + ~blue~number ~yellow~eg ~white~f2 ~yellow~= forward ~blue~2
  5781. ~lightGray~direction without number = ~blue~1
  5782.  
  5783. ~yellow~f = forward  ~orange~b = backward
  5784. ~lime~l = left     ~red~r = right
  5785. ~lightGray~u = up       ~cyan~d = down
  5786.  
  5787. ~red~q = quit
  5788.  
  5789. ]] -- Direct control
  5790.         local cmd = ""
  5791.         while cmd ~= "q" do
  5792.             local line = menu.clear()
  5793.             line = menu.colourText(line, instructions)
  5794.             -- menu.getString(prompt, withTitle, minValue, maxValue, row, fg, bg, default)
  5795.             input = menu.getString("command ", false, 1, 5, line, colors.yellow, colors.black):lower()
  5796.             -- remove spaces
  5797.             input = input:gsub( " ", "")
  5798.             cmd = input:sub(1,1)
  5799.             R.length = 1
  5800.             if #input > 1 then
  5801.                 R.length = tonumber(input:sub(2))
  5802.             end
  5803.             if cmd == "q" then
  5804.                 return{"User has quit application"}
  5805.             end
  5806.             if cmd == "f" then
  5807.                 lib.forward(R)
  5808.             elseif cmd == "b" then
  5809.                 lib.back(R)
  5810.             elseif cmd == "l" then
  5811.                 lib.left(R)
  5812.             elseif cmd == "r" then
  5813.                 lib.right(R)
  5814.             elseif cmd == "u" then
  5815.                 lib.up(R)
  5816.             elseif cmd == "d" then
  5817.                 lib.down()
  5818.             end
  5819.         end
  5820.     end
  5821.     return {}
  5822. end
  5823.  
  5824. local function createRetainingWall(R) -- 34, 82
  5825.     -- facing direction wall will take
  5826.     -- will need to rotate 180 to build
  5827.     -- if R.height > 0 then build to specified depth
  5828.     local lib = {}
  5829.        
  5830.     function lib.checkFloor()
  5831.         local newDepth = 0
  5832.         place = utils.clearVegetation("down") -- in case col in front is deeper
  5833.         while place do -- loop will be entered at least once
  5834.             T:down(1)
  5835.             newDepth = newDepth + 1
  5836.             place = utils.clearVegetation("down")
  5837.         end
  5838.         if newDepth > 0 then
  5839.             for j = 1, newDepth do  -- go up until column base is met
  5840.                 T:go("U1C2")
  5841.             end
  5842.         end
  5843.     end
  5844.    
  5845.     function lib.patchMissingBlock()
  5846.         if turtle.back() then
  5847.             T:go("C1")
  5848.         else
  5849.             T:go("B1C1")
  5850.         end
  5851.     end
  5852.    
  5853.     function lib.placeSingle(height)
  5854.         local y = 0
  5855.         if height > 0 then
  5856.             T:go("D"..height)
  5857.             y = height
  5858.         else
  5859.             local place = utils.clearVegetation("down")
  5860.             while place do -- loop will be entered at least once
  5861.                 place = utils.clearVegetation("down")
  5862.                 if place then
  5863.                     T:down(1)
  5864.                     y = y + 1
  5865.                 end
  5866.             end
  5867.         end
  5868.         -- return to surface, placing below
  5869.         for i = 1, y do
  5870.             T:go("U1C2", false, 0, true)
  5871.         end
  5872.     end
  5873.    
  5874.     function lib.placeDouble(height)
  5875.         --T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5876.         local y = 0
  5877.         if not turtle.back() then
  5878.             T:go("B1")
  5879.         end
  5880.         if height > 0 then
  5881.             for i = 1, height do
  5882.                 T:go("C1D1", false, 0, true)
  5883.             end
  5884.             T:go("C1", false, 0, true)
  5885.             y = height
  5886.         else
  5887.             local place = utils.clearVegetation("down")
  5888.             -- build back column
  5889.             while place do -- loop will be entered at least once
  5890.                 place = utils.clearVegetation("down")
  5891.                 if place then
  5892.                     T:go("C1D1", false, 0, true)
  5893.                     y = y + 1
  5894.                 end
  5895.             end
  5896.             -- reached bottom. floor in front could drop down
  5897.             T:go("F1") -- move under first column
  5898.             lib.checkFloor()
  5899.             turtle.back() -- back at starting point
  5900.             T:go("C1", false, 0, true)
  5901.         end
  5902.         -- return to surface, placing below
  5903.         for i = 1, y do
  5904.             T:go("U1C2", false, 0, true)
  5905.         end
  5906.     end
  5907.        
  5908.     function lib.placeTriple(height)
  5909.         --T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5910.         local y = 0
  5911.         if turtle.back() then
  5912.             T:go("C1")
  5913.         else
  5914.             T:go("B1C1")
  5915.         end
  5916.         if height > 0 then
  5917.             for i = 1, height do
  5918.                 T:go("C1D1", false, 0, true)
  5919.             end
  5920.             for i = 1, height do
  5921.                 T:go("C1D1", false, 0, true)
  5922.             end
  5923.             T:go("C1R2C1", false, 0, true) --fill last block, then turn 180 to build opposite side
  5924.             y = height
  5925.         else
  5926.             local place = utils.clearVegetation("down")
  5927.             -- build back column
  5928.             while place do -- loop will be entered at least once
  5929.                 place = utils.clearVegetation("down")
  5930.                 if place then
  5931.                     T:go("C1D1", false, 0, true)
  5932.                     y = y + 1
  5933.                 end
  5934.             end
  5935.             -- reached bottom. floor in front could drop down
  5936.             T:go("F1") -- move under first column
  5937.             lib.checkFloor()
  5938.             T:go("B1C1R2F1", false, 0, true)
  5939.             lib.checkFloor()
  5940.             T:go("B1C1")
  5941.             -- return to surface , placing below and to front
  5942.         end
  5943.         for i = 1, y do
  5944.             T:go("C1U1C2", false, 0, true)
  5945.         end
  5946.         T:go("F1R2C1", false, 0, true)
  5947.         -- facing back again inside edge of col 3
  5948.         return y -- depth of this run
  5949.     end
  5950.    
  5951.     local topInPlace = false -- topInPlace = true already a path across the water eg monument rectangle
  5952.     if R.data == "withPath" then
  5953.         topInPlace = true
  5954.     end
  5955.     local place = false
  5956.     local inWater = false
  5957.     local onWater = false
  5958.     if not topInPlace then
  5959.         if R.length > 1 then
  5960.             inWater, onWater = utils.getWaterStatus() -- returns whether above water, or immersed
  5961.         end
  5962.     end
  5963.    
  5964.     local maxDepth = 5 --initial estimated value
  5965.     -- start at surface, move back 1 block
  5966.     -- each iteration completes 3 columns
  5967.     local numBlocks = T:getSolidBlockCount()
  5968.     print("Solid blocks in inventory: "..numBlocks)
  5969.    
  5970.     if R.length == 1 then -- single column down to water bed
  5971.         lib.placeSingle(R.height)
  5972.     elseif R.length == 2 then--down then up: 2 cols
  5973.         inWater, onWater = utils.startWaterFunction(onWater, inWater, 2, true) -- move into water
  5974.         T:go("R2") -- move to face player
  5975.         lib.placeDouble(R.height)
  5976.         if not inWater then
  5977.             T:go("U1C2", false, 0, true)
  5978.         end
  5979.     else -- R.length 3 or more
  5980.         if topInPlace then
  5981.             T:down(1) -- break through top
  5982.         else
  5983.             inWater, onWater = utils.startWaterFunction(onWater, inWater, 2, true) -- move into water
  5984.         end
  5985.         T:go("R2") -- move to face player
  5986.         -- now at water surface
  5987.         local remain = R.length
  5988.         while remain >= 3 do
  5989.             numBlocks = T:getSolidBlockCount()
  5990.             print("Inventory blocks: "..numBlocks.." depth: "..maxDepth)
  5991.             if numBlocks < maxDepth * 3 then
  5992.                 --ask player for more
  5993.                 T:checkInventoryForItem({"stone"}, {maxDepth * remain}, false)
  5994.             end
  5995.             local y = lib.placeTriple(R.height) -- moves back, places col in front, centre and behind. R.height = 0 for auto depth
  5996.             if y > maxDepth then
  5997.                 maxDepth = y
  5998.             end
  5999.             remain = remain - 3
  6000.             if remain > 1 then
  6001.                 lib.patchMissingBlock()
  6002.             end
  6003.         end
  6004.         if remain == 1 then -- 1 more column
  6005.             lib.patchMissingBlock()
  6006.             lib.placeSingle(R.height)
  6007.         elseif remain == 2 then -- 2 cols
  6008.             lib.placeDouble(R.height)
  6009.         end
  6010.         T:go("U1C2") -- above surface
  6011.     end
  6012.     return {}
  6013. end
  6014.  
  6015. local function createSafeDrop(R) -- 14
  6016.     -- dig down height blocks, checking for blocks on all sides
  6017.     local drop = 0
  6018.     local isBedrock = false
  6019.     T:down(2)
  6020.     drop = 2
  6021.     for i = 1, R.height - 1 do
  6022.         for j = 1, 4 do
  6023.             -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  6024.             T:go("C1R1", false, 0, true)
  6025.         end
  6026.         if T:down(1) then
  6027.              drop = drop + 1
  6028.         else
  6029.             isBedrock = true
  6030.             break
  6031.         end
  6032.         if T:isWaterOrLava("up") ~= "" then
  6033.             T:go("C0x0", false, 0, false) -- delete water/ lava block
  6034.         end
  6035.     end
  6036.     if not isBedrock then -- not sitting on bedrock, so break foot level exit block
  6037.         T:go("U1R2x1")
  6038.     end
  6039.     T:placeWater("down")
  6040.     if isBedrock then
  6041.         T:go("U1x1 U1x1")
  6042.     else
  6043.         T:go("U1x1")
  6044.     end
  6045.     T:up(drop - 2)
  6046.    
  6047.     return {"Safe drop completed "..drop .. " blocks"}
  6048. end
  6049.  
  6050. local function createSlopingWater(R) -- 34, 89
  6051.     --[[
  6052.     creates a sloping water area above existing lake/river/ocean
  6053.     R.width is usually 7 with an existing wall on 8th row
  6054.     R.length  is user choice, limited to bucket/slab quantities
  6055.     Places slabs into existing surface, places row of sources
  6056.     Removes slabs
  6057.     ]]
  6058.     local lib = {}
  6059.    
  6060.     function lib.fillBuckets()
  6061.         local emptyBuckets = utils.getEmptyBucketCount()
  6062.         for i = 1, emptyBuckets do
  6063.             if utils.fillBucket("down") then
  6064.                 print("Bucket filled down")
  6065.                 sleep(0.3)
  6066.             else
  6067.                 print("Unable to fill bucket ".. i .." / "..emptyBuckets)
  6068.             end
  6069.         end
  6070.         return utils.getWaterBucketCount()
  6071.     end
  6072.    
  6073.     local outbound = true
  6074.     local inWater, onWater = utils.getWaterStatus()
  6075.     inWater, onWater = utils.startWaterFunction(onWater, inWater, 2 ,false) -- move above water, max descent 2
  6076.     local waterBuckets = lib.fillBuckets()
  6077.     for w = 1, R.width do
  6078.         for l = 1, R.length do
  6079.             T:place("slab", -1, "down", false)
  6080.             if l < R.length then
  6081.                 T:forward(1)
  6082.             end
  6083.         end
  6084.         if w < R.width then
  6085.             if outbound then
  6086.                 T:go("R1F1R1")
  6087.             else
  6088.                 T:go("L1F1L1")
  6089.             end
  6090.             outbound = not outbound
  6091.         end
  6092.     end
  6093.     if outbound then
  6094.         T:go("L1F"..R.width - 1 .."L1")
  6095.     else
  6096.         T:go("R1F"..R.width - 1 .."R1")
  6097.     end
  6098.     T:placeWater("up")  -- place in corner
  6099.     local move = true
  6100.     while move do
  6101.         move = turtle.forward()
  6102.         move = turtle.forward() -- false if at end of run
  6103.         T:placeWater("up")  -- alternate positions + end of run
  6104.     end
  6105.     T:go("R2D1")
  6106.     T:sortInventory() -- get all buckets into 1 slot
  6107.     for w = 1, R.width do
  6108.         for l = 1, R.length do
  6109.             if l < R.length then
  6110.                 T:forward(1)
  6111.             end
  6112.         end
  6113.         if w < R.width then
  6114.             if outbound then
  6115.                 T:go("R1F1R1")
  6116.             else
  6117.                 T:go("L1F1L1")
  6118.             end
  6119.             outbound = not outbound
  6120.         end
  6121.     end
  6122.     if outbound then
  6123.         T:go("L1F"..R.width - 1 .."L1")
  6124.     else
  6125.         T:go("R1F"..R.width - 1 .."R1")
  6126.     end
  6127.     T:go("U2")
  6128.    
  6129.     return {}
  6130. end
  6131.  
  6132. local function createSquidFarmBase(R) -- 34
  6133.     -- dig down to y=45. assume starting at water level (64)
  6134.     local depth = 0
  6135.     local message =
  6136. [[Place the turtle under the grid
  6137. left corner above current pit
  6138. opening.
  6139. It will descend to the base and
  6140. continue to level y=45.
  6141.  
  6142. Enter to continue...
  6143. ]]
  6144.     read()
  6145.     while turtle.down()do
  6146.         depth = depth + 1
  6147.     end
  6148.     T:down(1)
  6149.     R.height = 21 - depth
  6150.     R.width = 15
  6151.     R.length = 15
  6152.     R.silent = true
  6153.     R.data = "down"
  6154.     clearSolid(R)
  6155.     T:up(depth + 4)
  6156.     return {}
  6157. end
  6158.  
  6159. local function createSandWall(R) -- 81
  6160.     local success = true
  6161.     --move above water
  6162.     local maxMove = 2
  6163.     while turtle.detectDown() and maxMove > 0 do
  6164.         T:forward(1)
  6165.         maxMove = maxMove - 1
  6166.     end
  6167.     if R.length > 0 then
  6168.         for i = 1, R.length - 1 do
  6169.             success = utils.dropSand()
  6170.             T:forward(1, false)
  6171.         end
  6172.         success = utils.dropSand()
  6173.     else
  6174.         while not turtle.detectDown() do -- over water
  6175.             while not turtle.detectDown() do -- nested to allow forward movement
  6176.                 success = utils.dropSand() -- drops sand and checks supplies
  6177.             end
  6178.             if success then
  6179.                 T:forward(1, false)
  6180.             else -- out of sand
  6181.                 break
  6182.             end
  6183.         end
  6184.     end
  6185.     return {}
  6186. end
  6187.  
  6188. local function createSinkingPlatform(R) -- 58
  6189.     local lib = {}
  6190.    
  6191.     function lib.stage1a(R)                         -- build side wall left side
  6192.         for l = 1, R.length do                      --            | |*| |
  6193.             T:go("L1C1 R1C2", false, 0, false)      -- |*|>| | to |*|>| | place left wall
  6194.             if l == 1 then                          -- first iteration
  6195.                 T:go("U1C2 D1 F1C2", false, 0, false)-- |*|>| | to |*|*|>| up/down block to delete source at corner
  6196.             elseif l < R.length then                -- mid run
  6197.                 T:go("F1C2", false, 0, false)       -- |*|>| | to |*|*|>| move forward
  6198.             else                                    -- end of run
  6199.                 T:go("C1U1 C2D1", false, 0, false)  -- |*|>| | to |*|>|*| place end wall
  6200.             end
  6201.         end
  6202.     end
  6203.    
  6204.     function lib.stage1b(R)                         -- same as stage1a on right side
  6205.         for l = 1, R.length do
  6206.             T:go("R1C1 L1C2", false, 0, false)
  6207.             if l == 1 then
  6208.                 T:go("U1C2 D1 F1C2", false, 0, false)
  6209.             elseif l < R.length then
  6210.                 T:go("F1C2", false, 0, false)
  6211.             else
  6212.                 T:go("C1U1 C2D1", false, 0, false)
  6213.             end
  6214.         end
  6215.     end
  6216.    
  6217.     function lib.stage2(forward)
  6218.         if forward then
  6219.             T:go("C1R1 F1L1 C1R2", false, 0, false)
  6220.         else
  6221.             T:go("C1L1 F1R1 C1L2", false, 0, false)
  6222.         end
  6223.     end
  6224.        
  6225.     local forward = true
  6226.     local goingRight = true
  6227.     local blockType = T:getBlockType("down")
  6228.     if blockType:find("water") ~= nil or blockType:find("lava") ~= nil then
  6229.         T:up(1)
  6230.     end
  6231.     for h = 1, R.height do                      -- repeatedly create a platform, move down and repeat
  6232.         T:down(1)                               -- move down into existing platform
  6233.         if goingRight then                      -- first side
  6234.             if forward then                     -- complete left side
  6235.                 T:go("R2C1 L2", false, 0, false) -- | |>| | to |*|<| | to |*|>| |
  6236.                 lib.stage1a(R)                  -- build left wall
  6237.                 T:go("R1F1 L1C1 R2C2", false, 0, false)         -- turn ready for next side
  6238.             else
  6239.                 T:go("L2C1 R2", false, 0, false) -- block 1, 1
  6240.                 lib.stage1b(R)                  -- turn ready for next side
  6241.                 T:go("L1F1 R1C1 L2C2", false, 0, false)
  6242.             end
  6243.         else                                    -- on right side so different approach
  6244.             if forward then
  6245.                 T:go("L2C1 R2", false, 0, false) -- | |<| | to | |>|* | to | |<|*|
  6246.                 lib.stage1b(R)                 
  6247.                 T:go("C1L1 F1R1 C1L2 C2", false, 0, false)      -- turn ready for next side
  6248.             else                                -- complete left side
  6249.                 T:go("R2C1 L2", false, 0, false) -- block 1, 1
  6250.                 lib.stage1a(R)                  -- turn ready for next side
  6251.                 T:go("C1R1 F1L1 C1R2 C2", false, 0, false)
  6252.             end
  6253.         end
  6254.         forward = not forward                   -- continue strips across until at far edge
  6255.         for w = 1, R.width - 2 do
  6256.             for l = 1, R.length do
  6257.                 if l < R.length then
  6258.                     T:go("C2F1", false, 0, false)
  6259.                 else
  6260.                     T:go("C2", false, 0, false)
  6261.                 end
  6262.             end
  6263.             if goingRight then
  6264.                 lib.stage2(forward)
  6265.             else
  6266.                 lib.stage2(not forward)
  6267.             end
  6268.             forward = not forward
  6269.         end                                     -- far side
  6270.         if goingRight then
  6271.             if forward then
  6272.                 lib.stage1b(R)
  6273.             else
  6274.                 lib.stage1a(R)
  6275.             end
  6276.         else
  6277.             if forward then
  6278.                 lib.stage1a(R)
  6279.             else
  6280.                 lib.stage1b(R)
  6281.             end
  6282.         end
  6283.         goingRight = not goingRight
  6284.         T:turnRight(2)
  6285.         forward = not forward
  6286.     end
  6287.     return {}
  6288. end
  6289.  
  6290. local function createStaircase(R) -- 13
  6291.     -- R# L# F# B# U# D# +0 -0 = Right, Left, Forward, Back, Up, Down, up while detect and return, down while not detect
  6292.     -- dig:           x0,x1,x2 (up/fwd/down)
  6293.     -- suck:          s0,s1,s2
  6294.     -- place chest:   H0,H1,H2
  6295.     -- place sapling: S0,S1,S2
  6296.     -- place Torch:   T0,T1,T2
  6297.     -- place Hopper:  P0,P1,P2
  6298.     -- mine floor:    m# = mine # blocks above and below, checking for valuable items below, and filling space with cobble or dirt
  6299.     -- mine ceiling:  M# = mine # blocks, checking for valuable items above, and filling space with cobble or dirt
  6300.     -- mine ceiling:  N# same as M but not mining block below unless valuable
  6301.     -- place:         C,H,r,S,T,P,^ = Cobble / cHest / DIrT / Sapling / Torch / hoPper /stair in direction 0/1/2 (up/fwd/down) eg C2 = place cobble down
  6302.    
  6303.     -- 3| |B| |
  6304.     --   - - -
  6305.     -- 2|A| |C|
  6306.     --   - - -
  6307.     -- 1|^|D| |
  6308.     --   - - -
  6309.     --   1 2 3
  6310.     local lib = {}
  6311.    
  6312.     function lib.checkFluids()
  6313.         local isFluid = false
  6314.         -- check if water or lava present
  6315.         for i = 1, 4 do
  6316.             blockType = T:isWaterOrLava("forward")
  6317.             if blockType:find("lava") ~= nil or blockType:find("water") ~= nil then
  6318.                 isFluid = true
  6319.             end
  6320.         end
  6321.         return isFluid
  6322.     end
  6323.    
  6324.     function lib.createStaircaseSection(onGround, levels, level)
  6325.         -- start 1,1,1, n
  6326.         -- stage A
  6327.         local isFluid = lib.checkFluids()
  6328.         local blockType = ""
  6329.         local data = T:getStock("stairs")
  6330.         if data.total == 0 then
  6331.             T:craft('stairs', 4)
  6332.         end
  6333.         if onGround and isFluid then
  6334.             -- add right side and block entrance
  6335.             T:go("R1C1R1C1R2")
  6336.         end
  6337.         if isFluid then
  6338.             T:go("L1C1 R1F1C2 L1C1 R1x1 R1C1 L1C2B1 C1x1 ^1C2", false, 0, true) --start:1,1,1,n stairs A on level 1, going back to 1,1,1,n
  6339.         else
  6340.             T:go("F1x1 R1C1 L1C2B1 ^1C2", false, 0, true)
  6341.         end
  6342.         if not onGround then
  6343.             -- stage A1
  6344.             T:go("L2C1L2", false, 0, true) -- start 1,1,1,n fix corner on level 1 end: 1,1,1,n
  6345.         end
  6346.         -- stage B
  6347.         T:go("U1L1", false, 0, true) -- end  1,1,1,w layer 2
  6348.         level = level + 1
  6349.         isFluid = lib.checkFluids()
  6350.         if isFluid then
  6351.             T:go("C1", false, 0, true) -- end  1,1,1,w layer 2
  6352.         end
  6353.         if not onGround then
  6354.             if isFluid then
  6355.                 T:go("L1C1R1", false, 0, true) -- end  1,1,1,w layer 2
  6356.             end
  6357.         end
  6358.         -- stage C1
  6359.         if isFluid then
  6360.             T:go("R1C1F1C1x1 L1C1 R2C1 L1B1", false, 0, true)
  6361.         else
  6362.             T:go("R1F1 R1C1 L1B1", false, 0, true)
  6363.         end
  6364.         --level = level + 1
  6365.         --if level == levels then
  6366.             --return false, level
  6367.         --end
  6368.         -- stage C2
  6369.         T:go("U1")
  6370.         level = level + 1
  6371.         --if level == levels then
  6372.             --return true, level
  6373.         --end
  6374.         isFluid = lib.checkFluids()
  6375.         if isFluid then
  6376.             T:go("L1C1L1 C1L2 C1F1L1 C1R2 C1L1 B1C2 D1", false, 0, true) -- end 1,1,2,n
  6377.         else
  6378.             T:go("F1R1 C1L1 B1D1", false, 0, true) -- end 1,1,2,n
  6379.         end
  6380.         level = level - 1 -- went down in branch above
  6381.         --if level == levels then
  6382.             --return false, level
  6383.         --end
  6384.         -- stage D
  6385.         isFluid = lib.checkFluids()
  6386.         if isFluid then
  6387.             T:go("C1F1C1F1C1x1L1 C1R1 C1R1", false, 0, true) -- 3,1,2,e
  6388.         else
  6389.             T:go("F2 C1R1", false, 0, true) -- 3,1,2,e
  6390.         end
  6391.        
  6392.         return false, level
  6393.     end
  6394.  
  6395.     --local height = currentLevel -- eg 64 at top or 5 at bedrock
  6396.     local data = T:getStock("stairs")
  6397.     --{rt.total, rt.mostSlot, rt.leastSlot, rt.mostCount, rt.leastCount}
  6398.     local numStairs = data.total
  6399.     local levels = math.abs(R.depth - R.height) --height of stairs
  6400.     local numStairsNeeded = levels
  6401.     numStairsNeeded = numStairsNeeded - numStairs
  6402.     if numStairsNeeded > 40 then
  6403.         print('crafting '..numStairsNeeded..' : '..numStairs.. ' in stock')
  6404.         if T:craft('stairs', 40) then   -- max 40 so repeat
  6405.             data = T:getStock("stairs")
  6406.             if data.total == 0 then
  6407.                 data = T:getStock("stairs")
  6408.             end
  6409.             numStairs = data.total
  6410.             numStairsNeeded = numStairsNeeded - numStairs
  6411.         else
  6412.             return {"Unable to craft stairs"}
  6413.         end
  6414.     end
  6415.     if numStairsNeeded > 0 then
  6416.         T:craft('stairs', numStairsNeeded)
  6417.     end
  6418.     local level = 0
  6419.     if R.down then -- go down towards bedrock
  6420.         local atBedrock = false
  6421.         for i = 1, levels do
  6422.             level = level - 1
  6423.             if not T:down() then
  6424.                 atBedrock = true
  6425.                 break
  6426.             end
  6427.         end
  6428.         if atBedrock then -- hit bedrock so get to level 5 / -59
  6429.             level = T:findBedrockTop(level)
  6430.             T:go("R1F1R1", false, 0, true)
  6431.         end
  6432.     end
  6433.     local onGround = true
  6434.     level = 0
  6435.     while level < levels do
  6436.         onGround, level = lib.createStaircaseSection(onGround, levels, level)
  6437.     end
  6438.     if not turtle.detectDown() then
  6439.         T:go("C2")
  6440.     end
  6441.    
  6442.     return{"Staircase completed"}
  6443. end
  6444.  
  6445. local function createStripMine(R)
  6446.     --[[
  6447.     R.length should be a multiple of 16
  6448.     mine a corridoor repairing floor and ceiling
  6449.     check sides, remove valuable items
  6450.     plug if lava present
  6451.     Every 16 blocks dig a side passage 1 block deep 2 blocks long
  6452.     ]]
  6453.     local lib = {}
  6454.    
  6455.     function lib.seal(R)   
  6456.         if T:isValuable("forward") then -- valuable block in front. If debris then refuse already dumped
  6457.             T:dig("forward")
  6458.         end
  6459.         local blockType = T:getBlockType("forward")
  6460.         if blockType:find("lava") ~= nil then
  6461.             --T:place("stone", 0, "forward", false) -- place does not allow for specific blocktype
  6462.             T:go("C1", false, 0, false, R.useBlockType)
  6463.             return true
  6464.         end
  6465.        
  6466.         return false
  6467.     end
  6468.    
  6469.     function lib.checkSeal(R)
  6470.         local retValue = false
  6471.         T:turnRight(1)
  6472.         if lib.seal(R) then
  6473.             retValue = true
  6474.         end
  6475.         T:turnLeft(2)
  6476.         if lib.seal(R) then
  6477.             retValue = true
  6478.         end
  6479.         T:turnRight(1)
  6480.         return retValue
  6481.     end
  6482.        
  6483.     function lib.alcove(R)
  6484.         -- right side, starting at ceiling
  6485.         T:go("R1F1 C0", false, 0, false, R.useBlockType)-- stone ceiling, facing alcove wall (upper)
  6486.         lib.seal(R)                                     -- seal alcove wall (upper)
  6487.         T:go("D1C2", false, 0, false, "cobble")         -- cobble floor, facing alcove wall (lower)
  6488.         lib.seal(R)                                     -- seal alcove wall (lower)    
  6489.         T:go("L2 F1")                                   -- down 1, turn round, return to corridoor.
  6490.         -- left side   
  6491.         T:go("F1 C2", false, 0, false, "cobble")        -- cobble floor, facing alcove wall (lower)
  6492.         lib.seal(R)                                     -- seal alcove wall (lower)
  6493.         T:go("U1 C0", false, 0, false, R.useBlockType)  -- stone ceiling, still facing alcove wall
  6494.         lib.seal(R)                                     -- seal alcove wall (upper)                    
  6495.         T:go("L2F1L1")                                  -- return to corridoor at ceiling position
  6496.         lib.placeTorch(R)                              
  6497.     end
  6498.    
  6499.     function lib.placeTorch(R)
  6500.         if R.torchInterval > 0 then                     -- torches onboard
  6501.             if T:getItemSlot("minecraft:torch") > 0 then
  6502.                 T:place("minecraft:torch", -1, "down")
  6503.             end
  6504.         end
  6505.     end
  6506.    
  6507.     local seal = false
  6508.     if T:getItemSlot("minecraft:torch") == 0 then
  6509.         R.torchInterval = 0 -- set to default 16 above
  6510.     end
  6511.     for steps = 1, R.length do
  6512.         -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  6513.         T:go("C2U1C0", false, 0, true, R.useBlockType)      -- check and repair floor / ceiling
  6514.         if steps % 16 == 0 or steps % 16 == 1 then
  6515.             lib.alcove(R) -- enter and exit at ceiling position
  6516.         else
  6517.             seal = lib.checkSeal(R)
  6518.         end
  6519.         T:go("F1D1", false, 0, true)
  6520.         seal = lib.checkSeal(R)
  6521.     end
  6522.     if seal then -- water or lava found while tunnelling
  6523.         T:go("U1C0", false, 0, true, R.useBlockType)
  6524.         lib.checkSeal(R)
  6525.         T:go("C1", false, 0, true, R.useBlockType)
  6526.         T:down(1)
  6527.     end
  6528.     return {}
  6529. end
  6530.  
  6531. local function createTreefarm(R) -- 22
  6532.     local lib = {}
  6533.     --go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  6534.     function lib.buildWallSection(length, placePolished, useBlockType)
  6535.         for i = 1, length do
  6536.             if placePolished and i == length - 4 then
  6537.                 T:place("polished", 0, "down")
  6538.                 T:forward(1)
  6539.             else
  6540.                 if i < length then
  6541.                     T:go("C2F1", false, 0, false, useBlockType)
  6542.                 end
  6543.             end
  6544.         end
  6545.     end
  6546.    
  6547.     function lib.placeFloor(length, useBlockType)
  6548.         for i = 1, length do
  6549.             T:go("x0C2", false, 0, false, useBlockType)
  6550.             if i < length then
  6551.                 T:forward(1)
  6552.             end
  6553.         end
  6554.     end
  6555.    
  6556.     function lib.placeWater(length)
  6557.         T:placeWater("down")
  6558.         T:go("F"..length.."R1")
  6559.     end
  6560.    
  6561.     function lib.placeCorners(length, numBlocks, useBlockType)
  6562.         for i = 1, numBlocks do
  6563.             T:go("C2F1", false, 0, false, useBlockType)
  6564.         end
  6565.         -- now at 5th space
  6566.         T:forward(length - (numBlocks * 2))
  6567.         for i = 1, numBlocks do
  6568.             T:go("C2", false, 0, false, useBlockType)
  6569.             if i < numBlocks then
  6570.                 T:forward(1)
  6571.             end
  6572.         end
  6573.     end
  6574.    
  6575.     function lib.turn(outward)
  6576.         if outward then
  6577.             T:go("R1F1R1")
  6578.         else
  6579.             T:go("L1F1L1")
  6580.         end
  6581.         return not outward
  6582.     end
  6583.    
  6584.     local blockType
  6585.     local blockModifier
  6586.     -- R.data = "existing" if on existing tree farm
  6587.     -- R.up = true if clear area
  6588.     if R.up then
  6589.         clearArea(R)
  6590.     end
  6591.  
  6592.     if R.data == "existing" then
  6593.         T:go("R1F1 D1", false, 0, false) -- move 14 blocks, right, forward, down 1
  6594.         lib.buildWallSection(R.width - 1, false, R.useBlockType)
  6595.         T:turnLeft(1)
  6596.         lib.buildWallSection(R.length, false, R.useBlockType)
  6597.         T:turnLeft(1)
  6598.         lib.buildWallSection(R.width - 1, false, R.useBlockType)
  6599.         T:go("C2U1R2")
  6600.         lib.buildWallSection(R.width - 1, true, R.useBlockType)
  6601.         T:turnRight(1)
  6602.         lib.buildWallSection(R.length, true, R.useBlockType)
  6603.         T:turnRight(1)
  6604.         lib.buildWallSection(R.width, true, R.useBlockType)
  6605.         T:go("R1") -- on lower left corner facing forward
  6606.     else
  6607.         T:down(1)
  6608.         local placePolished = false
  6609.         for i = 1, 2 do
  6610.             lib.buildWallSection(R.length, placePolished, R.useBlockType)
  6611.             T:turnRight(1)
  6612.             lib.buildWallSection(R.width, placePolished, R.useBlockType)
  6613.             T:turnRight(1)
  6614.             lib.buildWallSection(R.length, placePolished, R.useBlockType)
  6615.             T:turnRight(1)
  6616.             lib.buildWallSection(R.width, placePolished, R.useBlockType)
  6617.             T:turnRight(1)
  6618.             placePolished = true
  6619.             if i == 1 then
  6620.                 T:up(1)
  6621.             end
  6622.         end -- on lower left corner facing forward
  6623.     end
  6624.     T:go("F1R1 F1L1 D2") -- over 13 x 13 internal area
  6625.     local outward = true
  6626.     for i = 1, R.width - 2 do
  6627.         lib.placeFloor(R.length - 2, R.useBlockType)
  6628.         if i < R.width - 2 then
  6629.             outward = lib.turn(outward)
  6630.         end
  6631.     end
  6632.     T:go("U1R2") -- over 13 x 13 internal area opposite corner
  6633.     -- now add corners
  6634.     lib.placeCorners(R.length - 2, 4, R.useBlockType)
  6635.     outward = lib.turn(outward)
  6636.     lib.placeCorners(R.length - 2, 3, R.useBlockType)
  6637.     outward = lib.turn(outward)
  6638.     lib.placeCorners(R.length - 2, 2, R.useBlockType)
  6639.     outward = lib.turn(outward)
  6640.     lib.placeCorners(R.length - 2, 1, R.useBlockType)
  6641.     if outward then
  6642.         T:go("R1F"..R.width - 9 .."R1")
  6643.     else
  6644.         T:go("L1F"..R.width - 9 .."L1")
  6645.     end
  6646.     outward = not outward
  6647.     lib.placeCorners(R.length - 2, 1, R.useBlockType)
  6648.     outward = lib.turn(outward)
  6649.     lib.placeCorners(R.length - 2, 2, R.useBlockType)
  6650.     outward = lib.turn(outward)
  6651.     lib.placeCorners(R.length - 2, 3, R.useBlockType)
  6652.     outward = lib.turn(outward)
  6653.     lib.placeCorners(R.length - 2, 4, R.useBlockType) -- should be back in starting corner facing front
  6654.    
  6655.     T:go("U1R1")
  6656.     lib.placeWater(R.length - 3) -- place water down then move forward, turn right
  6657.     lib.placeWater(R.width - 3)
  6658.     lib.placeWater(R.length - 3)
  6659.     lib.placeWater(R.width - 3)
  6660.     T:go("F".. math.floor((R.length - 2) / 2).."R1F".. math.floor((R.width - 2) / 2)) -- should be in centre
  6661.     T:go("D4C2 R1C1 R1C1 R1C1 R1F1 R2") -- facing back of hole ready to place water
  6662.     T:placeWater("forward")
  6663.     T:go("R2F7U4")
  6664.    
  6665.     return {"Tree farm ready for planting"}
  6666. end
  6667.  
  6668. local function createWallOrFence(R)
  6669.     local lib = {}
  6670.    
  6671.     function lib.placeBarrel(R)
  6672.         if R.data == "barrel" then
  6673.             utils.goBack(1)
  6674.             T:go("L1F1")
  6675.             T:place("barrel", 0, "down", false)
  6676.             utils.goBack(1)
  6677.             T:go("R1")
  6678.             T:forward(1)
  6679.         end
  6680.     end
  6681.    
  6682.     function lib.placeTorch(R)
  6683.         T:up(1)
  6684.         local up = 1
  6685.         local blockType = T:getBlockType("forward")
  6686.         while blockType:find(R.useBlockType) ~= nil and blockType ~= "" do -- prevent continuous upward travel
  6687.             T:up(1)
  6688.             up = up + 1
  6689.             blockType = T:getBlockType("forward")
  6690.         end
  6691.         T:place("torch", 0, "forward", true)
  6692.         T:down(up)
  6693.     end
  6694.    
  6695.     function lib.buildWall(R, length)
  6696.         -- T:place(blockType, damageNo, direction, leaveExisting, signText)
  6697.         local blockType = ""
  6698.         local blocks = 0
  6699.         lib.placeBarrel(R)
  6700.         while blocks < length do
  6701.             if turtle.back() then
  6702.                 T:place(R.useBlockType, 0, "forward", true)
  6703.                 if R.torchInterval > 0 then
  6704.                     if blocks == 0 or blocks % R.torchInterval == 0 then
  6705.                         lib.placeTorch(R)
  6706.                     end
  6707.                 end
  6708.                 blocks = blocks + 1 -- still facing start position
  6709.                 while turtle.down() do
  6710.                     T:place(R.useBlockType, 0, "up", true)
  6711.                 end
  6712.             else -- obstruction
  6713.                 T:turnRight(2) -- facing away from start
  6714.                 blockType = T:getBlockType("forward")
  6715.                 if blockType:find("torch") ~= nil then
  6716.                     T:go("F1R2")
  6717.                     T:place(R.useBlockType, 0, "forward")
  6718.                     blocks = blocks + 1 -- facing start
  6719.                 elseif blockType:find("log") ~= nil then
  6720.                     T:harvestTree()
  6721.                     T:turnRight(2)
  6722.                     T:place(R.useBlockType, 0, "forward")
  6723.                     blocks = blocks + 1 -- facing start
  6724.                 elseif T:isVegetation(blockType) then
  6725.                     T:go("F1R2")
  6726.                     T:place(R.useBlockType, 0, "forward")
  6727.                     blocks = blocks + 1 -- facing start
  6728.                 else -- cant go forward, go up instead
  6729.                     while turtle.detect() and blockType:find("torch") == nil and blockType:find("log") == nil and not T:isVegetation(blockType) do -- block ahead, but not torch or tree
  6730.                         while turtle.detectUp() do -- will only run if block above
  6731.                             utils.goBack(1)
  6732.                             blocks = blocks - 1
  6733.                         end
  6734.                         turtle.up()
  6735.                         T:place(R.useBlockType, 0, "down", true)
  6736.                         blockType = T:getBlockType("forward")
  6737.                     end
  6738.                     T:turnRight(2) -- facing start
  6739.                 end
  6740.             end
  6741.         end
  6742.     end
  6743.    
  6744.     T:turnRight(2) --facing start position
  6745.     if R.width == 0 then -- single fence
  6746.         lib.buildWall(R, R.length)
  6747.     else   
  6748.         lib.buildWall(R, R.length - 1)
  6749.         T:go("R1") -- facing start so left turn = turnRight
  6750.         lib.buildWall(R, R.width - 1)
  6751.         T:go("R1")
  6752.         lib.buildWall(R, R.length - 1)
  6753.         T:go("R1")
  6754.         lib.buildWall(R, R.width - 2)
  6755.         T:go("U1")
  6756.         T:place(R.useBlockType, 0, "down", true)
  6757.     end
  6758.    
  6759.     return {"Wall or fence completed"}
  6760. end
  6761.  
  6762. local function createWaterCanal(R) -- 53
  6763.     --[[
  6764.     designed for 4 turtles, but can be done with 2 as well
  6765.     R.data = 1 (2 turtles) or 2 (4 turtles)
  6766.     R.height = 0 (in water/ on canal floor) or 1 (at ground level)
  6767.     R.side = "R" or "L"
  6768.     R.subChoice =
  6769.         1 = left side, ground level (on towpath)
  6770.         2 = left side above canal water (new canal only)
  6771.         3 = right side above canal water (new canal only)
  6772.         4 = right side, ground level (on towpath)
  6773.         5 = left side in canal water (if present)
  6774.         6 = right side in canal water (if present)
  6775.    
  6776.     if R.height = 0 then already at correct height on canal floor
  6777.         check block below, block to left and block above, move forward tunnelling
  6778.         if entering water then move up, onto canal wall and continue pathway
  6779.         if tunnelling then flood canal
  6780.     else R.height = 1 then above water and on path across
  6781.         move forward, checking for water below
  6782.         if water finishes, move into canal, drop down and continue tunnelling
  6783.     ]]
  6784.     local lib = {}
  6785.    
  6786.     function lib.newCanalSide(oTurn)
  6787.         T:go("C1 U1x1 U1x1 D2"..oTurn.."1", false, 0, false)
  6788.     end
  6789.    
  6790.     function lib.newCanalBase(R)
  6791.         local oTurn = "R"                               -- assume R.side = "L"
  6792.         if R.side == "R" then
  6793.             oTurn = "L"
  6794.         end
  6795.         if not turtle.detectDown() then                 -- air / water below: fill floor
  6796.             T:go(oTurn.."1D1")                          -- *|>| | | to *|V| | | turn towards canal centre, go down ready to repair neighbouring canal base
  6797.             if T:getBlockType("forward"):find("turtle") ~= nil then -- turtle in similar position
  6798.                 if R.side == "L" then                   -- only left side repairs, so wait 1 second
  6799.                     sleep(1)
  6800.                     T:go("C1")                          -- repair neighbouring canal base
  6801.                 end
  6802.             else
  6803.                 T:go("C1")                              -- repair neighbouring canal base
  6804.             end
  6805.             T:go(R.side.."1")                           -- *|V| | | to *|>| | | turn to face start
  6806.             T:up(1)                                     -- *|>| | | return to canal floor
  6807.         end
  6808.         T:go("C2", false, 0, false)
  6809.     end
  6810.    
  6811.     function lib.newCanal(R)
  6812.         --  no source in front as this function called                                              -- *|<| | |  facing end wall ready for new canal canal base level
  6813.         local oTurn = "R"                                   -- assume R.side = "L"
  6814.         if R.side == "R" then
  6815.             oTurn = "L"
  6816.         end
  6817.         lib.newCanalSide(oTurn)                             -- *|<| | | wall fixed. to -- *|^| | |
  6818.         lib.newCanalSide(oTurn)                             -- *|^| | | wall fixed. to -- *|>| | |
  6819.         lib.newCanalBase(R)                                 -- *|>| | | base fixed
  6820.         T:go("F1"..R.side.."1")                             -- *|>| | | to *| |>| | to *| |^| |
  6821.         lib.newCanalSide(oTurn)                             -- *| |^| | to *| |>| |
  6822.         lib.newCanalBase(R)                                 -- *| |>| | base fixed
  6823.         T:go("F1"..R.side.."1")                             -- *| |>| | to *| | |>| to *| | |^|
  6824.         lib.newCanalSide(oTurn)                             -- *| | |^| to *| | |>|
  6825.         lib.newCanalBase(R)                                 -- *| | |>| base fixed
  6826.         T:go(R.side.."2")                                   -- *| | |>| to *| | |<|facing existing / back wall
  6827.         T:forward(1)                                        -- *| |<| |
  6828.         T:placeWater("forward")                             -- *|W|<| | placed against start wall  
  6829.         T:go("L2")                                          -- *|W|>| |
  6830.         T:placeWater("forward")                             -- *|W|>|W| placed direction of travel
  6831.         T:go("R2")                                          -- *|W|<|W| rotate
  6832.         if deletesWater then
  6833.             T:up(1)
  6834.         else
  6835.             sleep(0.2)
  6836.         end
  6837.         utils.getWater()                                    -- *|W|<|W|
  6838.         T:go(oTurn.."2F1")                                  -- *|W|<|W|  to *|W|W|>|  ready to go  
  6839.     end
  6840.    
  6841.     function lib.towpathOnly(R)
  6842.         --[[single turtle on towpath only using 4 turtles. Starts at ground level]]
  6843.         for i = 1, R.length do
  6844.             if turtle.detectDown() then                     -- eg dirt, stone
  6845.                 T:dig("down")                               -- remove block below
  6846.             end
  6847.             local placeOnly = true
  6848.             if R.torchInterval > 0 then                     -- place torches
  6849.                 if i == 1 or i % R.torchInterval == 0 then  -- ready to place torch
  6850.                     T:go("C2U1")                            -- place solid block below, up 1
  6851.                     T:place("torch", 0, "down")             -- place torch, move forward
  6852.                     T:go("F1D1")                            -- move forward, down
  6853.                     placeOnly = false      
  6854.                 end
  6855.             end
  6856.             if placeOnly then
  6857.                 T:dig("up")                                 -- clear blocks above
  6858.                 if not T:place("stone", 0, "down") then     -- place stone below
  6859.                     break
  6860.                 end
  6861.                 if i < R.length then
  6862.                     T:forward(1)                            -- move forward
  6863.                 end                        
  6864.             end
  6865.         end
  6866.     end
  6867.    
  6868.     function lib.initialiseCanal(R)
  6869.         --[[ move turtle to correct position. return moves]]
  6870.         local moves = 1
  6871.         local oTurn = "R"
  6872.         if R.side == "R" then
  6873.             oTurn = "L"
  6874.         end
  6875.         local newCanal, isWater, isSource = false, false, false
  6876.         if R.data == 1 then -- use 2 turtles only
  6877.             if R.subChoice == 1 or R.subChoice == 4 then    -- left / right side on towpath- move into canal space
  6878.                 if deletesWater then
  6879.                     T:go(oTurn.."1F1")                      -- turn to face canal centre, go forward over water
  6880.                     isWater, isSource = T:isWater("down")
  6881.                     if isSource then                        -- canal already exists
  6882.                         T:go(oTurn.."1")                    -- stay above water, face existing canal
  6883.                     else                                    -- NOT above source
  6884.                         T:go("D1"..oTurn.."1")              -- go to canal floor, face existing
  6885.                         newCanal = true                     -- flag create 6 water source blocks
  6886.                     end
  6887.                 else                                        -- NOT deletesWater
  6888.                     T:go(oTurn.."1F1D1"..oTurn.."1")        -- move into canal, face back along any existing canal
  6889.                     isWater, isSource = T:isWater("forward")
  6890.                     if isSource then
  6891.                         T:go(R.side.."2")                   -- face forward for new canal
  6892.                     else
  6893.                         newCanal = true
  6894.                     end
  6895.                 end
  6896.             elseif R.subChoice == 2 or R.subChoice == 3 then-- left / right side above canal finishing pos if deletesWater
  6897.                 if deletesWater then
  6898.                     isWater, isSource = T:isWater("down")
  6899.                     if isSource then
  6900.                         T:go(R.side.."2")                   -- face towards existing canal
  6901.                     else
  6902.                         T:go("D1"..R.side.."2")             -- go down and face existing canal                      -- no water ahead
  6903.                         newCanal = true                     -- already in newCanal starting position
  6904.                     end
  6905.                 else                                        -- NOT deletesWater
  6906.                     T:go("D1"..R.side.."2")                 -- facing existing on canal floor
  6907.                     isWater, isSource = T:isWater("forward")
  6908.                     if isSource then                        -- water ahead
  6909.                         T:go(R.side.."2")                   -- face forward for new canal
  6910.                     else                                   
  6911.                         newCanal = true
  6912.                     end
  6913.                 end
  6914.             elseif R.subChoice == 5 or R.subChoice == 6 then -- left / right  side in canal base. Assume NOT deletesWater
  6915.                 T:go(R.side.."2")                           -- check if water behind   
  6916.                 isWater, isSource = T:isWater("forward")
  6917.                 if isSource then
  6918.                     T:go(oTurn.."2")    
  6919.                 else
  6920.                     newCanal = true
  6921.                 end
  6922.             end
  6923.         else    -- use 4 turtles
  6924.             if R.subChoice == 1 or R.subChoice == 4 then    -- left / right side on towpath stays in place for 4 part canal
  6925.            
  6926.             elseif R.subChoice == 2 or R.subChoice == 3 then-- left / right side above canal finishing pos if deletesWater
  6927.            
  6928.             elseif R.subChoice == 5 or R.subChoice == 6 then -- left / right  side in canal base. Assume NOT deletesWater
  6929.            
  6930.             end
  6931.         end
  6932.         if newCanal then                                -- no water ahead, facing start wall of new canal *|<| | |
  6933.             lib.newCanal(R)                             -- start new canal, finish facing new canal 6 block water sources
  6934.             moves = 2
  6935.         end
  6936.        
  6937.         return moves                                    -- facing forward ready for new canal *|>| | |
  6938.     end
  6939.    
  6940.     function lib.side(R, maxLength)
  6941.         -- Already in position facing new canal, 2 water buckets
  6942.         local torch = R.length - maxLength                  -- start torch count at 1-2 depending on lib.initialise()
  6943.         local sourceCount = 0                               -- allow for 1 iteration of placing source blocks when changing from solid to water
  6944.         local numBlocks = 0                                 -- distance travelled
  6945.         local _, isSource = nil, false                      -- initialise variables
  6946.         local oTurn = "R"                                   -- assume R.side == "L" -> oTurn = "R"
  6947.         if R.side == "R" then                               -- R.side = "R"
  6948.             oTurn = "L"                                     -- oTurn = "L"
  6949.         end
  6950.        
  6951.         while numBlocks < maxLength do                      -- loop from here. Facing forwards to extend canal
  6952.             torch = torch + 1                               -- increase torch spacing interval
  6953.             numBlocks = numBlocks + 1                       -- inrease block count
  6954.             if deletesWater then                            -- up to and including mc 1.12.2
  6955.                 T:forward(1)                                -- move forward to extend canal  | |>|
  6956.                 _, isSource = T:isWater("down")             -- check if source water below
  6957.                 if isSource then
  6958.                     sourceCount = sourceCount + 1           -- count source blocks
  6959.                 else                                       
  6960.                     T:down(1)                               -- down to canal floor
  6961.                     sourceCount = 0                         -- reset
  6962.                     T:go("C2", false, 0, false)             -- place block below
  6963.                     T:up(1)                                 -- up to water level
  6964.                 end                                         -- still facing away from canal
  6965.                 T:go(R.side.."1F1C2", false, 0, false)      -- go above towpath, place stone down, facing out
  6966.                 if turtle.detectUp() then                   -- ? block above
  6967.                     T:go(R.side.."2U1F1D1"..R.side.."2")    -- rotate to face canal, up 1 forward over canal, back down to water level, face towpath
  6968.                 else
  6969.                     utils.goBack(1)                         -- face towpath
  6970.                 end
  6971.                 -- facing towpath
  6972.                 if R.torchInterval > 0 then                 -- Are torches required?
  6973.                     if torch == R.torchInterval  or numBlocks == 0 then     -- check if ready to place
  6974.                         torch = 0                           -- reset interval counter
  6975.                         T:go("U1F1")
  6976.                         T:place("torch", -1, "down")        -- place torch
  6977.                         utils.goBack(1)
  6978.                         T:down(1)
  6979.                     end
  6980.                 end                                         -- facing towpath, above water
  6981.                 -- facing towpath
  6982.                 if isSource and scoreCount > 0 then
  6983.                     T:go(oTurn.."1x0")                      -- face new canal direction
  6984.                 else                                        -- not source below, or first time found, ensures continous canal
  6985.                     T:go(R.side.."1x0")                     -- face back to existing canal
  6986.                     T:placeWater("down")                    -- place water
  6987.                     T:forward(1)                            -- forward 1
  6988.                     T:placeWater("down")                    -- place water
  6989.                     utils.getWater()                            -- collects water from below
  6990.                     utils.goBack(1)                         -- back 1
  6991.                     T:go(oTurn.."1x0")                      -- face new canal
  6992.                 end
  6993.             else
  6994.                 T:forward(1)                                -- move forward to extend canal
  6995.                 _, isSource = T:isWater("forward")          -- check if source water ahead
  6996.                 if isSource then                            -- ? source ahead
  6997.                     sourceCount = sourceCount + 1
  6998.                 else
  6999.                     sourceCount = 0
  7000.                     if not turtle.detectDown() then         -- air / water below, but no source in front, so fill it
  7001.                         T:go(oTurn.."1D1")                  -- ready to repair neighbouring canal base
  7002.                         if T:getBlockType("forward"):find("turtle") ~= nil then -- turtle in similar position
  7003.                             if R.side == "L" then           -- only left side repairs, so wait 1 second
  7004.                                 sleep(1)
  7005.                                 T:go("C1")                  -- repair neighbouring canal base
  7006.                             end
  7007.                             T:go(R.side.."1")               -- face forward
  7008.                         else
  7009.                             T:go("C1"..R.side.."1")         -- repair neighbouring canal base if air
  7010.                         end
  7011.                         T:up(1)
  7012.                     end
  7013.                     T:go("C2", false, 0, false)             -- place block below if not already source
  7014.                 end
  7015.                 T:go(R.side.."1C1", false, 0, false)        -- face canal wall, replace with stone
  7016.                
  7017.                 local placeTorch = false
  7018.                 if R.torchInterval > 0 then                 -- Are torches required?
  7019.                     if torch == R.torchInterval  or numBlocks == 0 then     -- check if ready to place
  7020.                         torch = 0                           -- reset interval counter
  7021.                         placeTorch = true
  7022.                     end
  7023.                 end
  7024.                 if (isSource and placeTorch) or not isSource then
  7025.                     T:go("U1x1 U1x1")                       -- up 2 and excavate blocks above tow path
  7026.                     if placeTorch then                      -- torch required
  7027.                         T:forward(1)                        -- move over towpath
  7028.                         T:place("torch", -1, "down")        -- place torch
  7029.                         utils.goBack(1)                     -- move back
  7030.                     end
  7031.                     T:down(2)                               -- return to canal base
  7032.                 end
  7033.                 if isSource and sourceCount > 1 then        -- source ahead found at least once
  7034.                     T:go(oTurn.."1")                        -- face newcanal as no water refill required
  7035.                 else                                        -- not source in front, or first time found, ensures continous canal
  7036.                     T:go(oTurn.."1C1")                      -- *| | | |>| face along new canal and block entrance
  7037.                     utils.goBack(1)                         -- *| | |>| | back 1
  7038.                     T:placeWater("forward")                 -- *| | |>|W| place water
  7039.                     T:go(oTurn.."2")                        -- *| | |<|W| face existing canal
  7040.                     _, isSource = T:isWater("forward")      -- *| |?|<|W| check if source water ahead
  7041.                     if not isSource then
  7042.                         if not T:placeWater("forward") then -- place water again *| |W|<|W|
  7043.                             while not T:getWater("forward") do -- wait for other turtle
  7044.                                 print("Out of water buckets")
  7045.                                 sleep(1)
  7046.                             end
  7047.                             sleep(0.2)
  7048.                             T:getWater("forward")
  7049.                         end
  7050.                     end
  7051.                     utils.getWater()                            -- collects water *| |W|<|W|
  7052.                     T:go(R.side.."2F1")                         -- face along new canal *| |W|>|W| to *| |W|W|>|
  7053.                 end
  7054.             end
  7055.         end
  7056.     end
  7057.        
  7058.     function lib.waterOnly(R, maxLength)
  7059.         -- Already in position facing new canal, 2 water buckets
  7060.         local torch = R.length - maxLength                  -- start torch count at 1-2 depending on lib.initialise()
  7061.         local sourceCount = 0                               -- allow for 1 iteration of placing source blocks when changing from solid to water
  7062.         local numBlocks = 0                                 -- distance travelled
  7063.         local _, isSource = nil, false                      -- initialise variables
  7064.         local oTurn = "R"                                   -- assume R.side == "L" -> oTurn = "R"
  7065.         if R.side == "R" then                               -- R.side = "R"
  7066.             oTurn = "L"                                     -- oTurn = "L"
  7067.         end
  7068.        
  7069.         while numBlocks < maxLength do                      -- loop from here. Facing forwards to extend canal
  7070.             torch = torch + 1                               -- increase torch spacing interval
  7071.             numBlocks = numBlocks + 1                       -- inrease block count
  7072.             if deletesWater then                            -- up to and including mc 1.12.2
  7073.                 T:forward(1)                                -- move forward to extend canal  | |>|
  7074.                 _, isSource = T:isWater("down")             -- check if source water below
  7075.                 if isSource then
  7076.                     sourceCount = sourceCount + 1           -- count source blocks
  7077.                 else                                       
  7078.                     T:down(1)                               -- down to canal floor
  7079.                     sourceCount = 0                         -- reset
  7080.                     T:go("C2", false, 0, false)             -- place block below
  7081.                     T:up(1)                                 -- up to water level
  7082.                 end                                         -- still facing away from canal
  7083.                 if turtle.detectUp() then                   -- ? block above
  7084.                     T:go("U1x0")                            -- break block above
  7085.                 end
  7086.                 if not isSource or scoreCount == 0 then     -- not source below, or first time found, ensures continous canal
  7087.                     T:go(R.side.."2x0")                     -- face back to existing canal
  7088.                     T:placeWater("down")                    -- place water
  7089.                     T:forward(1)                            -- forward 1
  7090.                     T:placeWater("down")                    -- place water
  7091.                     utils.getWater()                        -- collects water from below
  7092.                     utils.goBack(1)                         -- back 1
  7093.                     T:go(R.side.."2")                       -- face new canal
  7094.                 end
  7095.             else
  7096.                 T:forward(1)                                -- move forward to extend canal
  7097.                 _, isSource = T:isWater("forward")          -- check if source water ahead
  7098.                 if isSource then                            -- ? source ahead
  7099.                     sourceCount = sourceCount + 1
  7100.                 else
  7101.                     sourceCount = 0
  7102.                     if not turtle.detectDown() then         -- air / water below, but no source in front, so fill it
  7103.                         T:go(oTurn.."1D1")                  -- ready to repair neighbouring canal base
  7104.                         if T:getBlockType("forward"):find("turtle") ~= nil then -- turtle in similar position
  7105.                             if R.side == "L" then           -- only left side repairs, so wait 1 second
  7106.                                 sleep(1)
  7107.                                 T:go("C1", false, 0, true)  -- repair neighbouring canal base
  7108.                             end
  7109.                             T:go(R.side.."1")               -- face forward
  7110.                         else
  7111.                             T:go("C1"..R.side.."1",false, 0, true)  -- repair neighbouring canal base if air
  7112.                         end
  7113.                         T:up(1)
  7114.                     end
  7115.                     T:go("C2", false, 0, false)             -- place block below if not already source
  7116.                 end
  7117.                 if not isSource then
  7118.                     T:go("U1x0D1")                          -- up 1 and excavate blocks above canal. return to canal base
  7119.                 end
  7120.                 T:go(R.side.."1C1"..oTurn.."1", false, 0, true) -- face canal wall, replace with stone if empty, face forward                                      
  7121.                 if not isSource and sourceCount == 0 then   -- not source in front, or first time found, ensures continous canal                   
  7122.                     T:go("C1", false, 0, true)              -- *| | | |>| face along new canal and block entrance
  7123.                     utils.goBack(1)                         -- *| | |>| | back 1
  7124.                     T:placeWater("forward")                 -- *| | |>|W| place water
  7125.                     T:go(oTurn.."2")                        -- *| | |<|W| face existing canal
  7126.                     _, isSource = T:isWater("forward")      -- *| |?|<|W| check if source water ahead
  7127.                     if not isSource then
  7128.                         if not T:placeWater("forward") then -- place water again *| |W|<|W|
  7129.                             while not T:getWater("forward") do -- wait for other turtle
  7130.                                 print("Out of water buckets")
  7131.                                 sleep(1)
  7132.                             end
  7133.                             sleep(0.2)
  7134.                             T:placeWater("forward")
  7135.                         end
  7136.                     end
  7137.                     utils.getWater()                            -- collects 2 water *| |W|<|W|
  7138.                     T:go(R.side.."2F1")                         -- face along new canal *| |W|>|W| to *| |W|W|>|
  7139.                 end
  7140.             end
  7141.         end
  7142.     end
  7143.        
  7144.     local maxLength = 512
  7145.     if R.length ~= 0 then
  7146.         maxLength = R.length
  7147.     end
  7148.     menu.clear()
  7149.     menu.colourWrite("Building canal "..R.side.." side", colors.yellow, nil, nil, false, true)
  7150.     local moves = lib.initialiseCanal(R) -- move to correct position and/or start new canal
  7151.     if R.data == 1 then -- 2 turtles
  7152.         lib.side(R, maxLength - moves) 
  7153.     else -- 4 turtles
  7154.         if R.subChoice == 1 or R.subChoice == 4 then -- towpath
  7155.             lib.towpathOnly(R)
  7156.             --lib.waterCanalTowpath(R, maxLength - moves)
  7157.         else -- main canal only
  7158.             lib.waterOnly(R, maxLength - moves)
  7159.         end
  7160.     end
  7161.    
  7162.     return {}
  7163. end
  7164.  
  7165. local function createMobGrinder(R)
  7166.     -- go down 5 and create a cavity 9 wide, 5 long, 8 high
  7167.     -- assume facing out from spawner cube at base of exit (6 blocks above ground
  7168.     -- R.subChoice = 1 or 2 (sticky or normal pistons)
  7169.    
  7170.     local lib = {}
  7171.    
  7172.     function lib.getInventory(R)
  7173.         T:clear()
  7174.         menu.colourPrint("All blocks to be ejected. Ready? Enter", colors.red)
  7175.         read()
  7176.         T:emptyInventory("up")
  7177.         T:checkInventoryForItem({"stone"}, {20}, true, "Match existing walls?")
  7178.         if R.subChoice == 1 then -- sticky pistons
  7179.             T:checkInventoryForItem({"computercraft:computer_normal"}, {1})
  7180.             T:checkInventoryForItem({"minecraft:sticky_piston"}, {2})
  7181.         else
  7182.             T:checkInventoryForItem({"computercraft:computer_normal"}, {2})
  7183.             T:checkInventoryForItem({"minecraft:piston"}, {4})
  7184.             T:checkInventoryForItem({"computercraft:cable"}, {6})
  7185.             T:checkInventoryForItem({"computercraft:wired_modem"}, {2})
  7186.         end
  7187.         T:checkInventoryForItem({"polished"}, {23}, true, "Any polished block")
  7188.         T:checkInventoryForItem({"wall"}, {2}, true, "Any wall block ? match")
  7189.         T:checkInventoryForItem({"slab"}, {7}, true, "Any stone slab. ? polished / match")
  7190.         T:checkInventoryForItem({"minecraft:glass"}, {2})
  7191.         T:checkInventoryForItem({"minecraft:stone_pressure_plate"}, {1})
  7192.         T:checkInventoryForItem({"minecraft:dispenser"}, {1})
  7193.         T:checkInventoryForItem({"hopper"}, {1})
  7194.         T:checkInventoryForItem({"chest"}, {2})
  7195.         T:checkInventoryForItem({"minecraft:redstone"}, {9})
  7196.         T:checkInventoryForItem({"lava"}, {1})
  7197.         R.useBlockType = T:getPolishedItem("")
  7198.         if R.useBlockType == "" then
  7199.             R.useBlockType = T:getMostItem("", true)
  7200.         end
  7201.     end
  7202.    
  7203.     function lib.placeRedstone()
  7204.         T:go("D2U2")                                -- in left corner facing right
  7205.         T:place("slab", 0, "down")                  -- place slab layer 1
  7206.         T:up(2)
  7207.         T:place("slab", 0, "down")                  -- place slab layer 2
  7208.         T:up(1)
  7209.         T:place("redstone", 0, "down")
  7210.         T:go("F1D4 C2L1C1 L1U1", false, 0, false)   -- facing ground level slab
  7211.         T:place("redstone", 0, "forward")           -- redstone on ground level slab
  7212.         T:up(1)
  7213.         T:place("slab", 0, "down")                  -- slab on layer 1
  7214.         T:up(2)
  7215.         T:place("slab", 0, "down")                  -- slab on layer 3
  7216.         T:up(1)
  7217.         T:place("redstone", 0, "down")              -- redstone on layer 3 slab
  7218.         utils.goBack(1)
  7219.         T:down(3)                                   -- facing layer 1 slab
  7220.         T:place("redstone", 0, "forward")           -- redstone on layer 1 slab
  7221.         T:go("D2C2", false, 0, false)               -- under end of chest position
  7222.         T:place("redstone", 0, "forward")           -- redstone on level 0 floor
  7223.         T:go("R1C1R1", false, 0, false)             -- face right, repair back wall
  7224.         T:go("F1C2 L1C1 R1", false, 0, false)       -- under chest start
  7225.         T:go("F1C2 L1C1 R1", false, 0, false)       -- under hopper
  7226.         T:go("F1C2 L1C1 R1", false, 0, false)       -- under right side wall block
  7227.         T:go("U1L2")                                -- ready for redstone
  7228.         for i = 1, 4 do
  7229.             T:place("redstone", 0, "down")          -- redstone under chest etc
  7230.             if i < 4 then
  7231.                 T:forward(1)
  7232.             end
  7233.         end
  7234.         -- finishes facing slab at ground level, redstone below
  7235.     end
  7236.    
  7237.     function lib.placeStorage()
  7238.         -- starts facing slab at ground level, redstone below
  7239.         T:go("L1F1L2")                              -- up and out ready for chest placement
  7240.         T:place("chest", 0, "forward")              -- end chest
  7241.         T:go("R1F1 L1F1 R1U2")                      -- at above start chest position facing right
  7242.         T:place("slab", 0, "down")                  -- slab above chest
  7243.         T:turnLeft(1)
  7244.         utils.goBack(1)                            
  7245.         T:down(2)                                   -- in front of start chest position
  7246.         T:place("chest", 0, "forward")              -- start chest
  7247.         T:go("R1F2L2")                              -- at pressure plate position facing left
  7248.         T:place("wall", 0, "forward")               -- place wall
  7249.         T:up(1)
  7250.         T:place("pressure", 0, "down")              -- place pressure plate
  7251.         T:go("R1F1 L1D1")                           -- at second wall position
  7252.         T:place("hopper", 0, "forward")             -- place hopper into chest
  7253.         utils.goBack(1)
  7254.         T:place("wall", 0, "forward")               -- place second wall
  7255.         -- finishes on level 1 (ground) facing right side wall block
  7256.     end
  7257.    
  7258.     function lib.placePistons(R)
  7259.         -- starts on level 1 (ground) facing right side wall block
  7260.         T:go("U1F2 R1")                                 -- go over wall block, facing back wall layer 2
  7261.         T:place(R.useBlockType, 0, "forward", false)    -- replace back wall with polished block layer 2
  7262.         T:up(1)                                         -- layer 3
  7263.         T:place(R.useBlockType, 0, "forward", false)    -- replace back wall with polished block layer 3
  7264.         T:turnRight(1)                                  -- face right side
  7265.         if R.subChoice == 1 then                        -- use sticky pistons x 2
  7266.             T:place(R.useBlockType, 0, "forward", false)-- polished block above second wall layer 3
  7267.             T:go("R2F1")                                -- ready to place lower piston (works ok as slab already in place behind it)
  7268.         else
  7269.             T:go("F2R2")                                -- move forward 2 and face left
  7270.             T:place("piston", 0, "forward")             -- lower replacer piston placed
  7271.             T:go("U1F2D1F1")                            -- go up and over piston forward 1 ready for other piston
  7272.         end
  7273.         T:place("piston", 0, "forward")                 -- lower piston placed
  7274.         utils.goBack(1)
  7275.         T:go("U1R1")                                    -- layer 4
  7276.         T:place(R.useBlockType, 0, "forward", false)    -- polished block back wall layer 4
  7277.         T:go("L1F2R2")                                  -- head left ready for dispenser
  7278.         T:place("dispenser", 0, "forward")              -- dispenser placed
  7279.         T:dropItem("lava", "forward")                   -- drop lava bucket into dispenser
  7280.         T:go("U1F2 D1")                                 -- up and over dispenser, facing right side
  7281.         T:place("slab", 0, "down")                      -- lower piston slab placed
  7282.         if R.subChoice == 1 then
  7283.             T:place(R.useBlockType, 0, "forward", false)-- polished block above second wall layer 4
  7284.             T:turnLeft(1)                               -- facing back wall
  7285.         else
  7286.             T:go("F1L1")                                -- at second computer position, facing back wall
  7287.             utils.goBack(1)                             -- ready to place computer
  7288.             T:place("computercraft:computer_normal", 0, "forward", false)   -- place computer
  7289.             T:go("L1F1R1F1")                            -- facing back wall in mob drop, level 4
  7290.         end
  7291.         T:place(R.useBlockType, 0, "forward", false)    -- polished block back wall layer 4
  7292.         T:turnLeft(1)
  7293.         T:go("U1F3R2")                                  -- level 5 ready for upper piston
  7294.         T:place("piston", 0, "forward")                 -- upper piston placed
  7295.         T:go("U1F3D1R2")                                -- up and over piston, facing left, level 5
  7296.         T:turnRight(1)                                  -- at mob drop, facing wall, level 5
  7297.         T:place(R.useBlockType, 0, "forward", false)    -- polished block back wall layer 5
  7298.         T:turnRight(1)                                  -- facing right side
  7299.         if R.subChoice == 1 then
  7300.             T:place(R.useBlockType, 0, "forward", false)-- right side polished block layer 5, facing right side, in mob drop                            -- layer 5 facing left side, in mob drop       
  7301.         else
  7302.             T:go("F1C1")                                -- move forward, place temporary block
  7303.             utils.goBack(1)
  7304.             T:place("piston", 0, "forward")             -- upper replacer piston placed            
  7305.         end
  7306.         T:turnRight(2) 
  7307.         T:place("slab", 0, "forward")                   -- upper piston slab placed
  7308.         T:turnLeft(1)                                   -- facing away from back wall
  7309.     end
  7310.    
  7311.     function lib.placeComputer(R)
  7312.         -- starts facing away from back wall, layer 5, in mob drop         
  7313.         T:go("F1R1 F2R1 D1")                            -- move to left computerposition, facing back wall, layer 4
  7314.         T:place("computercraft:computer_normal", 0, "forward", false)       -- place computer in gap, layer 4
  7315.     end
  7316.    
  7317.     function lib.placeColumnSection(direction)
  7318.         T:place(R.useBlockType, 0, "forward", false)
  7319.         T:go(direction.."1")
  7320.         T:place(R.useBlockType, 0, "forward", false)
  7321.         T:go(direction.."1")
  7322.         T:place(R.useBlockType, 0, "forward", false)    -- facing right
  7323.     end
  7324.    
  7325.     function lib.placeColumns(R)
  7326.         -- starts facing left computer, layer 4
  7327.         T:go("R1F2 L1")                                 -- facing mob drop level 4
  7328.         T:place("glass", 0, "down", false)
  7329.         T:up(1)                                         -- facing mob drop level 5
  7330.         T:place("glass", 0, "down", false)              -- on top of glass facing back wall at dungeon base level 5
  7331.         T:up(1)
  7332.         T:place(R.useBlockType, 0, "down", false)       -- level 6 dungeon exit
  7333.         T:go("F1L1")
  7334.         lib.placeColumnSection("L")                     -- facing right
  7335.         T:up(1)
  7336.         lib.placeColumnSection("R")                     -- facing left
  7337.         T:up(1)
  7338.         lib.placeColumnSection("L")                     -- facing right
  7339.         T:up(1)
  7340.         lib.placeColumnSection("R")                     -- facing left
  7341.         T:up(1)
  7342.         T:place(R.useBlockType, 0, "forward", false)
  7343.         T:turnLeft(2)
  7344.         T:place(R.useBlockType, 0, "forward", false)    -- facing right
  7345.         T:turnLeft(1)                                   -- at top of column
  7346.         T:go("x1D1 x1D1 x1U2")                          -- open exit for mobs
  7347.         utils.goBack(2)
  7348.         T:place(R.useBlockType, 0, "forward", false)
  7349.         T:down(9)
  7350.     end
  7351.    
  7352.     function lib.placeNetwork()
  7353.         T:go("R1F2L1 F3U3 F1L1F1 L1x1")                             -- go behind second computer and remove block
  7354.         T:place("computercraft:wired_modem", 0, "forward", false)   -- place modem
  7355.         utils.goBack(1)
  7356.         T:place("computercraft:cable", 0, "forward", false)         -- place network cable
  7357.         T:place("computercraft:cable", 0, "forward", false)         -- place network cable (no need to move)
  7358.         T:go("R1F1 x2L1")                                           -- move forward, face back wall
  7359.         T:place("computercraft:cable", 0, "forward", false)
  7360.         T:go("R1F1 x2L1")
  7361.         T:place("computercraft:cable", 0, "forward", false)
  7362.         T:go("R1F1 x2L1F1 x1x2")                                    -- come behind left computer and expose back
  7363.         T:place("computercraft:wired_modem", 0, "forward", false)   -- place modem
  7364.         utils.goBack(1)
  7365.         T:place("computercraft:cable", 0, "forward", false)
  7366.         T:place("computercraft:cable", 0, "forward", false)
  7367.         T:go("L1D3 F4R1 F3U4 D4")                                   -- removes temporary block
  7368.     end
  7369.    
  7370.     local tempSubChoice = R.subChoice   -- store for later use
  7371.     R.width = 4                         -- settings for createFloorCeiling()
  7372.     R.length = 9
  7373.     R.height = 0
  7374.     R.up = true
  7375.     T:turnRight(2)
  7376.     local isWater, isSource, isIce, level, isAir = T:isWater("forward")
  7377.     if not isWater then
  7378.         T:turnRight(2)
  7379.         return{"Not in correct position. Must be water behind"}
  7380.     end
  7381.     --T:go("U1x1 U1L1 F4R2")                    -- go up to starting point
  7382.     T:go("U2L1 F4R2")                   -- go up to starting point
  7383.     local data = createFloorCeiling(R)[1]   -- place ceiling, returns to starting position. if water or lava present is returned as "water or lava found"
  7384.     if data == "water or lava found" then
  7385.         R.height = 10
  7386.         R.silent = true
  7387.         T:up(1)
  7388.         createSinkingPlatform(R)
  7389.         T:go("F4L1 U5x1 U1x1 U3R1 F4C0 R1F3C0 R1F8C0 R1F3C0 R1D9")          -- re-open exit hole, return to floor level
  7390.     else -- no water or lava found so empty out area
  7391.         R.height = 10
  7392.         R.subChoice = 2
  7393.         clearSolid(R) -- 76
  7394.         T:down(R.height - 1)
  7395.         R.width = 4                         -- settings for createFloorCeiling()
  7396.         R.length = 9
  7397.         R.height = 0
  7398.         R.down = true
  7399.         R.up = false
  7400.         R.subChoice = 1                     -- replace existing floor
  7401.         createFloorCeiling(R)
  7402.     end
  7403.    
  7404.     R.subChoice = tempSubChoice
  7405.     lib.getInventory(R)
  7406.     lib.placeRedstone()
  7407.     lib.placeStorage()
  7408.     lib.placePistons(R)
  7409.     lib.placeComputer(R)        -- ends facing computer
  7410.     lib.placeColumns(R)
  7411.     if R.subChoice == 2 then
  7412.         lib.placeNetwork()
  7413.     end
  7414.    
  7415.     return {}
  7416. end
  7417.  
  7418. local function sandFillArea(R) -- 81
  7419.     --clearRectangle with sand drop
  7420.     -- could be 1 wide x xx length (trench) up and return
  7421.     -- could be 2+ x 2+
  7422.     -- even no of runs return after last run
  7423.     -- odd no of runs forward, back, forward, reverse and return
  7424.     local success
  7425.     local directReturn = true
  7426.     if R.width % 2 == 1 then
  7427.         directReturn = false
  7428.     end
  7429.     if R.width == 1 then -- trench ahead, so fill then return
  7430.         for i = 1, R.length - 1 do
  7431.             success = utils.dropSand()
  7432.             T:forward(1, false)
  7433.         end
  7434.         success = utils.dropSand()
  7435.         T:go("R2F"..(R.length - 1).."R2", false, 0, false)
  7436.     else --2 or more columns
  7437.         if directReturn then -- R.width = 2,4,6,8 etc
  7438.             for i = 1, R.width, 2 do -- i = 1,3,5,7 etc
  7439.                 -- move along R.length, dropping sand
  7440.                 for j = 1, R.length - 1 do
  7441.                     success = utils.dropSand()
  7442.                     T:forward(1, false)
  7443.                 end
  7444.                 success = utils.dropSand()
  7445.                 T:go("R1F1R1") --turn right and return on next column
  7446.                 for j = 1, R.length - 1 do
  7447.                     success = utils.dropSand()
  7448.                     T:forward(1, false)
  7449.                 end
  7450.                 success = utils.dropSand()
  7451.                 if i < R.width - 2 then -- eg R.width = 8, i compares with 6: 1, 3, 5, 7
  7452.                     T:go("L1F1L1")
  7453.                 end
  7454.             end
  7455.             T:go("R1F"..R.width - 1 .."R1") --return home
  7456.         else
  7457.             for i = 1, R.width, 2 do -- i = 1,3,5,7 etc
  7458.                 -- move along R.length, dropping sand
  7459.                 for j = 1, R.length - 1 do
  7460.                     success = utils.dropSand()
  7461.                     T:forward(1, false)
  7462.                 end
  7463.                 success = utils.dropSand()
  7464.                 T:go("R1F1R1") --turn right and return on next column
  7465.                 for j = 1, R.length - 1 do
  7466.                     success = utils.dropSand()
  7467.                     T:forward(1, false)
  7468.                 end
  7469.                 success = utils.dropSand()
  7470.                 T:go("L1F1L1")
  7471.             end
  7472.             -- one more run then return
  7473.             for j = 1, R.length - 1 do
  7474.                 success = utils.dropSand()
  7475.                 T:forward(1, false)
  7476.             end
  7477.             success = utils.dropSand()
  7478.             T:go("R2F"..R.length.."R1F"..R.width - 1 .."R1")
  7479.         end
  7480.     end
  7481.     return {}
  7482. end
  7483.  
  7484. local function deactivateDragonTower() -- 45
  7485.     -- go up centre of tower to bedrock
  7486.     local height = 0
  7487.     --numBlocksMoved, errorMsg = clsTurtle.doMoves(self, numBlocksRequested, direction)
  7488.     local numBlocks, message = T:doMoves(1, "up")
  7489.     while message == nil do
  7490.         numBlocks, message = T:doMoves(1, "up")
  7491.         height = height + 1
  7492.     end
  7493.     -- go round bedrock and destroy crystal
  7494.     T:go("F1R2U2x1U1x1")
  7495.     -- return to start
  7496.     T:down(height + 5)
  7497.     return {}
  7498. end
  7499.  
  7500. local function undermineDragonTowers() -- 44
  7501.     --[[
  7502.             -13, -40....12, -40                     NNW (4)     NNE (5)
  7503.            
  7504.         -34, -25............33, -25             NWW (2)             NEE (9)
  7505.        
  7506.     -42, -1....................42, 0        W (1)                       E (8)
  7507.    
  7508.          -34, 24............33,24               SWW (3)             SEE (10)
  7509.          
  7510.               -13,39....12, 39                      SSW (7)     SSE (6)
  7511.    
  7512.     North towers centres 25 blocks apart, 40 blocks north of axis
  7513.     Mid-North towers 67 blocks apart, 25 blocks north of axis
  7514.     W-E centres 84 blocks apart, on 0 axis
  7515.     Mid-south towers 67 blocks apart, 24 blocks south of axis
  7516.     South towers centres 25 blocks apart, 39 blocks south of axis
  7517.     ]]
  7518.    
  7519.     local lib = {}
  7520.     function lib.findNextTower(maxDistance, withMarker)
  7521.         local distance = 0
  7522.         local blockTypeF = T:getBlockType("forward")
  7523.         local blockTypeD = T:getBlockType("down")
  7524.         for i = 1, maxDistance do
  7525.             if blockTypeF ~= "minecraft:obsidian" and blockTypeD ~= "minecraft:obsidian" then -- not in a tower
  7526.                 if withMarker and blockTypeD ~= "minecraft:obsidian" then -- used to mark 0 coordinate
  7527.                     T:place("cobble", -1, "down", false) -- place cobblestone or cobbled deepslate to mark zero coordinate
  7528.                 end
  7529.             else    -- obsidian found, could still be in an earlier tower
  7530.                 if i > 10 then
  7531.                     break
  7532.                 end
  7533.             end
  7534.             T:go("F1x0")
  7535.             distance = distance + 1
  7536.             blockTypeF = T:getBlockType("forward")
  7537.             blockTypeD = T:getBlockType("down")
  7538.         end
  7539.         if distance == maxDistance then -- obsidian not found ? wrong place/ direction
  7540.             print("Obsidian not found")
  7541.             error()
  7542.         end
  7543.         -- will now be at side of a tower
  7544.         lib.findCentre() -- move into tower to find the other side
  7545.         return distance
  7546.     end
  7547.    
  7548.     function lib.findCentre()
  7549.         local width = 0
  7550.         -- while obsidian in front or below (previously entered tower) measure width and return to centre
  7551.         local blockTypeF = T:getBlockType("forward")
  7552.         local blockTypeD = T:getBlockType("down")
  7553.         while blockTypeF == "minecraft:obsidian" or blockTypeD == "minecraft:obsidian" do
  7554.             T:go("F1x0")
  7555.             width = width + 1
  7556.             blockTypeF = T:getBlockType("forward")
  7557.             blockTypeD = T:getBlockType("down")
  7558.         end
  7559.         -- will always go outside the tower 1 block. width of 5 block tower = 6
  7560.         T:go("R2F"..math.ceil(width / 2)) --return to centre of tower
  7561.         T:turnLeft(1) -- now find another edge of the tower, dig forward until out of obsidian
  7562.         for i = 1, math.ceil(width) do  -- give additional loops if missed centre
  7563.             blockTypeF = T:getBlockType("forward")
  7564.             blockTypeD = T:getBlockType("down")
  7565.             if blockTypeF == "minecraft:obsidian" or blockTypeD == "minecraft:obsidian" then
  7566.                 T:go("F1x0")
  7567.             else
  7568.                 break
  7569.             end
  7570.         end
  7571.         -- now outside different edge of the tower
  7572.         -- reverse and move width/2, dig up + 1 to mark centre, face original direction
  7573.         T:go("L2F"..math.ceil(width / 2).."R1U2x1")
  7574.         T:place("minecraft:end_stone", -1, "forward", false) -- place endstone to mark facing direction
  7575.         T:down(2)
  7576.     end
  7577.    
  7578.     function lib.findPath(maxLength)
  7579.         local blockTypeD = T:getBlockType("down")
  7580.         local distance = 0
  7581.         while blockTypeD:find("cobble") == nil and distance < maxLength do
  7582.             T:go("F1x0")                            -- return to 0 axis,
  7583.             distance = distance + 1
  7584.             blockTypeD = T:getBlockType("down")
  7585.         end
  7586.         return distance
  7587.     end
  7588.    
  7589.     -- start at 0,y,0, facing West
  7590.     T:dig("up")                                 -- in case not already done
  7591.     local maxLength = 0
  7592.     local blockTypeD
  7593.     local distance = lib.findNextTower(45, true)-- find W tower (1) and mark trail with cobble
  7594.     T:turnRight(2)                     
  7595.     for i = 1, 8 do                             -- head back East 8 blocks, turn left (facing north)
  7596.         T:go("F1x0")                            -- this path may be off-axis, so dig double height
  7597.     end
  7598.     T:turnLeft(1)
  7599.     lib.findNextTower(30)                       -- find NWW tower (2)
  7600.     T:turnRight(2)
  7601.     distance = lib.findPath(30)
  7602.     distance = distance + lib.findNextTower(30) -- find SWW tower (3)
  7603.     T:turnRight(2)
  7604.     distance = lib.findPath(30)
  7605.     T:turnRight(1)                              -- should be on cobble path
  7606.     for i = 1, 21 do                            -- move East 21 blocks, turn left facing North
  7607.         T:go("F1x0")
  7608.     end
  7609.     T:turnLeft(1)
  7610.    
  7611.     distance = lib.findNextTower(45)        -- find NNW tower (4)
  7612.     T:turnRight(1)                         
  7613.     distance = lib.findNextTower(30)        -- find NNE tower (5)
  7614.     T:turnRight(1)
  7615.     distance = lib.findNextTower(85)        -- find SSE tower (6)
  7616.     T:turnRight(1)
  7617.  
  7618.     distance = lib.findNextTower(30)        -- find SSW tower (7)
  7619.     T:turnRight(1)
  7620.     distance = lib.findPath(40)             -- head North to 0 axis
  7621.     T:go("R1F13")                           -- return to 0,0 facing East
  7622.     distance = lib.findNextTower(45, true)  -- find E tower (8)
  7623.    
  7624.     T:turnRight(2)                     
  7625.     for i = 1, 9 do
  7626.         T:go("F1x0")                        -- this path may be off-axis, so dig double height
  7627.     end
  7628.     T:turnRight(1)
  7629.    
  7630.     distance = lib.findNextTower(30)        -- find NEE tower (9)
  7631.     T:turnRight(2)
  7632.     distance = lib.findPath(30) -- return to 0 axis
  7633.     distance = lib.findNextTower(30)        -- find SEE tower (10)
  7634.     T:turnRight(2)
  7635.     distance = lib.findPath(30)             -- return to 0 axis
  7636.     T:go("L1F33")                           -- return to 0, 0
  7637.    
  7638.     return {}
  7639. end
  7640.  
  7641. local function demolishPortal(R) -- 43
  7642.     --[[
  7643.     R.length = length of portal NOT width default 4
  7644.     R.height = height of portal default 5
  7645.     R.width = thickness of portal default 1
  7646.     R.data = "bury" to embed bottom into ground
  7647.     R.subChoice 1 = facing portal, 2 = aligned
  7648.     ]]
  7649.     local data = R.data
  7650.     if R.subChoice == 1 then -- facing portal
  7651.         T:go("F"..R.width.."R1")
  7652.     else
  7653.         T:forward(1)
  7654.     end
  7655.     if R.data == "bury" then
  7656.         T:down(1)
  7657.     end
  7658.  
  7659.     R.data = "up"
  7660.     R.silent = true
  7661.     if R.width == 1 then
  7662.         clearWall(R)
  7663.     else
  7664.         clearBuilding(R, true, true)
  7665.     end
  7666.     if data == "bury" then
  7667.         T:up(1)
  7668.     end
  7669.     if R.subChoice == 1 then -- facing portal
  7670.         T:go("R1F1L1F1L1")
  7671.     end
  7672.    
  7673.     return {}
  7674. end
  7675.  
  7676. local function digTrench(R) -- 77
  7677.     local blockType
  7678.     -- go down R.height, move forward
  7679.     if R.length == 0 then
  7680.         R.length = 4096 -- will go out of loaded chunks and stop or max 4096 on a server
  7681.     end
  7682.     for i = 1, R.length do
  7683.         local count = 0
  7684.         for down = 1, R.height do
  7685.             blockType = T:isWaterOrLava("down")
  7686.             -- go down only if no water or lava below
  7687.             if blockType:find("water") == nil and blockType:find("lava") == nil then
  7688.                 T:down(1)
  7689.                 count = count + 1
  7690.             end
  7691.         end
  7692.         T:go("C2", false, 0, true)              -- if empty below fill void
  7693.         T:go("U"..count)                        -- return to surface, continue if block above
  7694.         while turtle.detect() do                -- go up while block in front
  7695.             blockType = T:getBlockType("forward")
  7696.             if T:isVegetation(blockType) then
  7697.                 T:dig("forward")
  7698.                 break
  7699.             elseif blockType:find("log") ~= nil then
  7700.                 T:harvestTree("forward", false)
  7701.             else
  7702.                 T:up(1)
  7703.             end
  7704.         end
  7705.         T:forward(1)                            -- move forward
  7706.         while not turtle.detectDown() do        -- go down until block detected
  7707.             blockType = T:isWaterOrLava("down")
  7708.             if blockType:find("water") == nil and blockType:find("lava") == nil then
  7709.                 T:down(1)
  7710.             else
  7711.                 break
  7712.             end
  7713.         end
  7714.     end
  7715.    
  7716.     return {}
  7717. end
  7718.  
  7719. local function harvestTreeFarm(R) -- 24
  7720.     local lib = {}
  7721.    
  7722.     function lib.getLogCount()
  7723.         local count = 0
  7724.         for i = 1,16 do
  7725.             local item, itemCount = T:getSlotContains(i)
  7726.             if item:find("log") ~= nil then
  7727.                 count = count + itemCount
  7728.             end
  7729.         end
  7730.        
  7731.         return count
  7732.     end
  7733.    
  7734.     function lib.initialise()
  7735.         local blockType = T:getBlockType("forward")
  7736.         local logType = ""
  7737.         local startHeight = 0
  7738.         local range = 0
  7739.         if blockType == "" then
  7740.             while turtle.forward() do
  7741.                 range = range + 1
  7742.                 if range == 3 then
  7743.                     break
  7744.                 end
  7745.             end
  7746.         end
  7747.         blockType = T:getBlockType("forward")
  7748.         if blockType:find("dirt") ~= nil then
  7749.             T:up(1)
  7750.             startHeight = 1
  7751.         else
  7752.             if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil then
  7753.                 logType = blockType
  7754.             end
  7755.         end
  7756.        
  7757.         return logType, startHeight
  7758.     end
  7759.    
  7760.     R.silent = true
  7761.     local treeType, startHeight = lib.initialise() -- possible ID tree type + move to correct position 1 above dirt
  7762.    
  7763.     T:forward(1)    -- dig first log/sapling/ air if not planted
  7764.     clearRectangle({width = 7, length = 7, up = true, down = true})
  7765.     T:go("L1F2L1F2R2")
  7766.     local height = 0
  7767.     local pastLogCount = -1
  7768.     local currentLogCount = lib.getLogCount()
  7769.     while currentLogCount ~= pastLogCount do
  7770.         T:up(3)
  7771.         height = height + 3
  7772.         pastLogCount = currentLogCount -- 0 when loop starts
  7773.         clearRectangle({width = 12, length = 12, up = true, down = true})
  7774.         currentLogCount = lib.getLogCount() -- eg 20 logs from first round
  7775.     end
  7776.     T:down(height + startHeight)
  7777.     T:go("R1F2R1F2R2")
  7778.    
  7779.     return {}
  7780. end
  7781.  
  7782. local function harvestObsidian(R) -- 41
  7783.     local lib = {}
  7784.    
  7785.     function lib.forward(move)
  7786.         T:isWaterOrLava("forward")  -- automatically use lava ahead to refuel
  7787.         T:isWaterOrLava("down")     -- automatically use lava down to refuel
  7788.         T:go("C2", false, 0, false) -- place / replace block below
  7789.         if move then
  7790.             T:forward(1)
  7791.         end
  7792.     end
  7793.    
  7794.     function lib.home(outward)
  7795.         if outward then
  7796.             T:go("L1F"..R.width - 1 .."L1F"..R.length - 1)
  7797.         else   
  7798.             T:go("R1F"..R.width - 1 .."R1")
  7799.         end
  7800.     end
  7801.    
  7802.     function lib.start()
  7803.         local lavaSlot = T:getItemSlot("lava")
  7804.         if lavaSlot > 0 then
  7805.             turtle.select(slot)
  7806.             turtle.refuel()
  7807.         end
  7808.         T:down(1)
  7809.     end
  7810.    
  7811.     local outward = true
  7812.    
  7813.     lib.start()                     -- use lava bucket if placed, move down into block below
  7814.     for w = 1, R.width do
  7815.         for l = 1, R.length do
  7816.             if l < R.length then
  7817.                 lib.forward(true)
  7818.             else
  7819.                 lib.forward(false)
  7820.             end
  7821.         end
  7822.         if w < R.width then
  7823.             if outward then
  7824.                 T:go("R1F1R1")
  7825.             else
  7826.                 T:go("L1F1L1")
  7827.             end
  7828.             outward = not outward
  7829.         end
  7830.     end
  7831.    
  7832.     lib.home(outward)
  7833.    
  7834.     return {}
  7835. end
  7836.  
  7837. local function harvestShulkers(R)
  7838.     local lib = {}
  7839.    
  7840.     function lib.attackAll()
  7841.         return turtle.attack(), turtle.attackUp(), turtle.attackDown()
  7842.     end
  7843.  
  7844.     function lib.attack()
  7845.         local forward, up, down = lib.attackAll()
  7846.         while forward or up or down do
  7847.             forward, up, down = lib.attackAll()
  7848.             sleep(0.2)
  7849.         end
  7850.     end
  7851.    
  7852.     function lib.approach(direction, limit, dig)
  7853.         -- move forward until stopped by shulker
  7854.         limit = limit or 64
  7855.         dig = dig or false
  7856.         local count = 0
  7857.         local solidDown = false
  7858.         move = turtle.forward
  7859.         if direction == "up" then
  7860.             move = turtle.up
  7861.         elseif direction == "down" then
  7862.             move = turtle.down
  7863.         end
  7864.         local forward, up, down = lib.attackAll()
  7865.         if forward or up or down then -- attacks suceeded
  7866.             return true, 0, solidDown
  7867.         else
  7868.             while move() do
  7869.                 count = count + 1
  7870.                 if turtle.detectDown() then
  7871.                     solidDown = true
  7872.                 end
  7873.                 if count >= limit then
  7874.                     return false, count, solidDown
  7875.                 end
  7876.                 forward, up, down = lib.attackAll()
  7877.                 if forward or up or down then
  7878.                     return true, count, solidDown
  7879.                 else
  7880.                     if dig then
  7881.                         T:dig("forward")
  7882.                     end
  7883.                 end
  7884.             end
  7885.             return false, count, solidDown
  7886.         end
  7887.     end
  7888.    
  7889.     function lib.home(direction, moves)
  7890.         local move = turtle.back
  7891.         if direction == "up" then
  7892.             move = turtle.down
  7893.         elseif direction == "down" then
  7894.             move = turtle.up
  7895.         end
  7896.         for i = 1, moves do
  7897.             move()
  7898.         end
  7899.     end
  7900.    
  7901.     function lib.checkPosition()
  7902.         if T:detect("forward") then         -- wall in front
  7903.             T:turnRight(1)
  7904.             if T:detect("forward") then     -- wall to right
  7905.                 T:turnLeft(1)
  7906.                 return true                 -- position corrected
  7907.             else
  7908.                 T:turnLeft(2)
  7909.                 if T:detect("forward") then -- wall in front. position correct
  7910.                     return true
  7911.                 end
  7912.             end
  7913.         end
  7914.         return false
  7915.     end
  7916.    
  7917.     function lib.getLength()
  7918.         local count = 0
  7919.         while turtle.detectDown() do
  7920.             count = count + 1
  7921.             T:forward(1)
  7922.         end
  7923.         utils.goBack(1)
  7924.         return count
  7925.     end
  7926.    
  7927.     function lib.clearWall()
  7928.         local distance = 0
  7929.         while distance < 9 do   -- smallest external walls are 8 x 8
  7930.             local success, count = lib.approach("forward", 8 - distance)
  7931.             if success then
  7932.                 lib.attack()
  7933.             end
  7934.             distance = distance + count
  7935.         end
  7936.         T:turnLeft(1)
  7937.         if T:detect("forward") then -- larger than 8 blocks
  7938.             T:turnRight(1)
  7939.             while distance < 14 do  -- larger builds are 14 x 14
  7940.                 local success, count = lib.approach("forward", 13 - distance)
  7941.                 if success then
  7942.                     lib.attack()
  7943.                 end
  7944.                 distance = distance + count
  7945.             end
  7946.             T:go("L1x2")
  7947.         end
  7948.     end
  7949.    
  7950.     function lib.roof()
  7951.         -- check position
  7952.         local doContinue = lib.checkPosition()
  7953.        
  7954.         if doContinue then
  7955.             T:go("U2F3 R1F3 R1")
  7956.             local length = lib.getLength()
  7957.             local width = 1
  7958.             local outward = lib.turnRound(true)
  7959.             local success, count, onRoof = false, 0, true  
  7960.             while onRoof do
  7961.                 local distance = 0
  7962.                 while distance < length - 1 do
  7963.                     success, count, onRoof = lib.approach("forward", length - 1 - distance)
  7964.                     if success then
  7965.                         lib.attack()
  7966.                     end
  7967.                     if count == 0 then
  7968.                         turtle.dig()
  7969.                     end
  7970.                     distance = distance + count
  7971.                 end
  7972.                 width = width + 1
  7973.                 outward = lib.turnRound(outward)
  7974.             end
  7975.             if outward then
  7976.                 T:go("F".. 3 .."L1F"..width - 3 .."D2L1")
  7977.             else
  7978.                 T:go("F".. length - 3 .."R1F"..width - 3 .."D2L1")
  7979.             end
  7980.             return {}
  7981.         else
  7982.             return {"Turtle not in front of a wall"}
  7983.         end
  7984.     end
  7985.    
  7986.     function lib.turnRound(outward)
  7987.         if outward then
  7988.             T:go("R1F1R1")
  7989.         else
  7990.             T:go("L1F1L1")
  7991.         end
  7992.         return not outward
  7993.     end
  7994.  
  7995.     function lib.upAndOver()
  7996.         local start, height, forward = 0, 0, 0
  7997.         while turtle.detect() do
  7998.             turtle.up()
  7999.             start = start + 1
  8000.         end
  8001.         while turtle.forward() do
  8002.             forward = forward + 1
  8003.         end
  8004.         turtle.turnRight()
  8005.         while not turtle.detectUp() do
  8006.             local success, count = lib.approach("up", 64, true)
  8007.             if success then
  8008.                 lib.attack()
  8009.             end
  8010.             height = height + count
  8011.         end
  8012.         T:turnRight(2)
  8013.         while not turtle.detectDown() do
  8014.             if lib.approach("down", 64, true) then
  8015.                 lib.attack()
  8016.             end
  8017.         end
  8018.         T:turnLeft(1)
  8019.         for i = 1, forward do
  8020.             turtle.forward()
  8021.         end
  8022.         for i = 1, start do
  8023.             turtle.down()
  8024.         end
  8025.         T:turnRight(2)
  8026.     end
  8027.    
  8028.     function lib.walls()
  8029.         local doContinue = lib.checkPosition()
  8030.         if doContinue then
  8031.             T:go("F2R1 F2R2 D1x2")      -- on corner outside middle of wall, facing along its length, dig light rod
  8032.             for i = 1, 4 do
  8033.                 lib.clearWall()
  8034.             end
  8035.             T:go("F2L1 U1F2 R2")
  8036.         else
  8037.             return {"Turtle not in front of a wall"}
  8038.         end
  8039.     end
  8040.        
  8041.     local direction = "forward"
  8042.     local doContinue = false
  8043.    
  8044.     if R.subChoice == 1 then        -- Shulker is above
  8045.         direction = "up"
  8046.         doContinue = true
  8047.     elseif R.subChoice == 2 then    -- Shulker is ahead
  8048.         doContinue = true
  8049.     elseif R.subChoice == 3 then    -- Shulker is below
  8050.         direction = "down"
  8051.         doContinue = true
  8052.     else
  8053.         if R.subChoice == 4 then    -- Climb tower wall
  8054.             lib.upAndOver()
  8055.         elseif R.subChoice == 5 then    -- Clear roof above
  8056.             return lib.roof()
  8057.         elseif R.subChoice == 6 then    -- Clear outside walls
  8058.             lib.walls()
  8059.         end
  8060.    
  8061.     end
  8062.     if doContinue then
  8063.         local success, moves = lib.approach(direction, 64)
  8064.         if success then
  8065.             lib.attack()
  8066.         end
  8067.         lib.home(direction, moves)
  8068.     end
  8069.    
  8070.     return {}
  8071. end
  8072.  
  8073. local function manageFarm(R)
  8074.     local lib = {}
  8075.    
  8076.     function lib.checkEquipment()
  8077.         --[[ Needs pickaxe and hoe equipped ]]
  8078.         T:clear()
  8079.         --T:checkInventoryForItem(items{}, quantities{}, required, message)
  8080.         print("Checking equipment. Please wait...")
  8081.         local equippedRight, equippedLeft, inInventory = T:setEquipment() -- any tools equipped except diamond_pickaxe and crafting_table have been removed to inventory
  8082.         --[[if equippedRight ~= "minecraft:crafting_table" then
  8083.             T:checkInventoryForItem({"minecraft:crafting_table"}, {1})
  8084.             local equippedRight, equippedLeft = T:setEquipment()
  8085.         end]]
  8086.         T:suck("down")      -- if hoe already in storage get it out
  8087.         if inInventory ~= "minecraft:diamond_hoe" then
  8088.             if T:getItemSlot("minecraft:diamond_hoe") > 0 then
  8089.                 return true
  8090.             else
  8091.                 T:checkInventoryForItem({"minecraft:diamond_hoe"}, {1}, true, "Diamond Hoe required for planting!")
  8092.             end
  8093.         end
  8094.         if T:getItemSlot("minecraft:diamond_hoe") > 0 then
  8095.             return true
  8096.         end
  8097.  
  8098.         return false
  8099.     end
  8100.    
  8101.     function lib.checkPosition()
  8102.         --[[ first function called on start]]
  8103.         local atHome = false
  8104.         local blockType = T:getBlockType("down")
  8105.         print("Checking position "..blockType.. " below")
  8106.         if blockType:find("water") ~= nil then -- over water
  8107.             if lib.isStorage("forward") then
  8108.                 atHome = true
  8109.                 T:turnRight(1)
  8110.                 if lib.isStorage("forward") then-- confirms in correct position, back to crops
  8111.                     T:turnRight(2)
  8112.                 else -- facing crafting table
  8113.                     T:turnRight(1)
  8114.                 end
  8115.             else -- not a chest: facing crops or crafting table
  8116.                 T:turnRight(1)
  8117.                 if lib.isStorage("forward") then -- confirms was facing crops
  8118.                     atHome = true
  8119.                     T:turnLeft(1)
  8120.                 end
  8121.             end
  8122.             -- should now be facing crops. may be crafting table to left
  8123.         end
  8124.         return atHome-- now facing crops
  8125.     end
  8126.    
  8127.     function lib.crossFarm()
  8128.         -- used with goHome to find starting point
  8129.         local blockType = ""
  8130.         local isReady, cropType, status = lib.isCropReady("down")
  8131.         -- will go forward until chest or cobble detected below
  8132.         -- if detected within 1 move, this is ignored
  8133.         local numMoves = 0
  8134.         local endOfPath = false
  8135.         while not endOfPath do
  8136.             blockType = T:getBlockType("down", -1)
  8137.             if blockType == "" or cropType ~= "" then --crops or nothing below
  8138.                 turtle.forward()
  8139.             elseif  blockType:find("barrel") ~= nil or blockType:find("chest") ~= nil or blockType:find("cobble") ~= nil then
  8140.                 endOfPath = true
  8141.             end
  8142.             numMoves = numMoves + 1
  8143.         end
  8144.         return blockType -- either chest or cobble
  8145.     end
  8146.    
  8147.     function lib.farmInFront()
  8148.         --[[ facing crops on first farm. move to next farm in front ]]
  8149.         T:go("U1L1F11D1R1")                         -- on next farm, facing crops
  8150.         local crop = lib.manageTree()               -- refuel, gather seeds and other crops
  8151.         local isFarmToRight, _ = lib.harvest(crop)  -- harvest field, store crops
  8152.         return isFarmToRight
  8153.     end
  8154.    
  8155.     function lib.farmToRight()
  8156.         --[[ facing crops on first farm. move to next farm on right side ]]
  8157.         T:go("U1F11 D1")                -- on next farm, facing crops
  8158.         local crop = lib.manageTree()   -- refuel, gather seeds and other crops
  8159.         lib.harvest(crop)               -- harvest field, store crops
  8160.     end
  8161.    
  8162.     function lib.getCrops()
  8163.         T:turnRight(1)
  8164.  
  8165.         if lib.isStorage("forward") then
  8166.             lib.getSeeds("forward")
  8167.         end
  8168.         T:turnRight(1)
  8169.         if lib.isStorage("forward") then
  8170.             lib.getVeg("forward")
  8171.         end
  8172.         T:turnRight(2)
  8173.     end
  8174.    
  8175.     function lib.getSaplings(direction)
  8176.         --[[ get a single sapling from the chest ]]
  8177.         if direction == nil then
  8178.             direction = "forward"
  8179.         end
  8180.         while T:suck(direction, 1) do end -- remove saplings/ seeds
  8181.  
  8182.         T:dropItem("sapling", direction, 1) -- drop all but 1 saplings
  8183.         if not T:dropItem("seeds", direction, 0) then-- drop all seeds
  8184.             T:dropItem("seeds", "up", 0)
  8185.         end
  8186.        
  8187.         return T:getItemSlot("sapling", -1)
  8188.     end
  8189.    
  8190.     function lib.getSeeds(direction)
  8191.         --[[ get 1 stack of wheat seeds or 1 stack of beetroot seeds ]]
  8192.         print("Collecting seeds from storage")
  8193.         while T:suck(direction, 1) do end -- remove saplings/ seeds
  8194.         T:dropItem("sapling", direction, 0) -- drop all saplings
  8195.         T:dropItem("minecraft:wheat_seeds", direction, 64) -- drop all but 64 seeds
  8196.         T:dropItem("minecraft:beetroot_seeds", direction, 64)
  8197.         local crop = ""
  8198.         if T:getItemSlot("minecraft:wheat_seeds", -1) > 0 then
  8199.             crop = "wheat"
  8200.             print("Field crop = "..crop)
  8201.         elseif T:getItemSlot("minecraft:beetroot_seeds", -1) > 0 then
  8202.             crop = "beetroot"
  8203.             print("Field crop = "..crop)
  8204.         end
  8205.        
  8206.         return crop
  8207.     end
  8208.    
  8209.     function lib.getVeg(direction)
  8210.         -- assume only one type of crop per field
  8211.         print("Collecting crops from storage")
  8212.         direction = direction or "forward"
  8213.         while T:suck(direction, 1) do end -- remove carrots / potatoes / wheat / beetroot
  8214.         --clsTurtle.dropItem(self, item, direction, keepAmount)
  8215.         T:dropItem("wheat", direction, 0)       -- drop all wheat
  8216.         T:dropItem("beetroot", direction, 0)    -- drop all beetroot
  8217.         T:dropItem("carrot", direction, 64)     -- drop all but 64 carrots
  8218.         T:dropItem("potato", direction, 64)     -- drop all but 64 potato
  8219.         local crop = ""
  8220.         if T:getItemSlot("potato", -1) > 0 then
  8221.             crop = "potato"
  8222.             print("Field crop = "..crop)
  8223.         elseif T:getItemSlot("carrot", -1) > 0 then
  8224.             crop = "carrot"
  8225.             print("Field crop = "..crop)
  8226.         end
  8227.        
  8228.         --T:turnRight(2) -- face crops
  8229.         return crop
  8230.     end
  8231.    
  8232.     function lib.goHome()
  8233.         -- after a re-boot go to start
  8234.         local onTree = false
  8235.         -- is tree above or in front
  8236.         -- check if log in front
  8237.         if T:getBlockType("forward"):find("log") ~= nil then -- about to harvest tree
  8238.             lib.harvestTree("forward") -- will only harvest if fuel below half of limit
  8239.             onTree = true
  8240.         elseif T:getBlockType("up"):find("log") ~= nil then -- harvesting tree
  8241.             lib.harvestTree("up")
  8242.             onTree = true
  8243.         elseif T:getItemSlot("log", -1) > 0 then -- tree just harvested
  8244.             onTree = true
  8245.             turtle.up()
  8246.             if T:getBlockType("up"):find("log") ~= nil then -- harvesting tree
  8247.                 lib.harvestTree("up")
  8248.             else
  8249.                 while turtle.down() do end
  8250.             end
  8251.         end
  8252.        
  8253.         if onTree then -- tree harvested, but direction unknown
  8254.             local blockType = ""
  8255.             local turns = 0
  8256.             local onChest = lib.isStorage("down")
  8257.             while not onChest do
  8258.                 if turtle.forward() then
  8259.                     if lib.isStorage("down") then
  8260.                         onChest = true
  8261.                     else
  8262.                         turtle.back()
  8263.                     end
  8264.                 end
  8265.                 if not onChest then
  8266.                     T:turnRight(1)
  8267.                     turns = turns + 1
  8268.                 end
  8269.                 if turns == 4 then
  8270.                     break
  8271.                 end
  8272.             end -- should be on chest. If not should be over water
  8273.             if onChest then -- onChest and onTree, go left,down
  8274.                 T:go("R1F1D1R1")
  8275.             end
  8276.             atHome = lib.checkPosition()
  8277.             if atHome then
  8278.                 return true -- exit function
  8279.             end
  8280.         else
  8281.             while turtle.down() do end -- no tree around, no logs onboard
  8282.         end
  8283.            
  8284.         return false
  8285.     end
  8286.    
  8287.     function lib.gotoTree(logSlot)
  8288.         -- assume facing crops
  8289.         T:turnRight(1)
  8290.         print("Extracting saplings from storage")
  8291.         lib.getSaplings("forward") -- gets one sapling only (if present)
  8292.         print("Moving to tree position")
  8293.         T:go("U1F1R1")
  8294.         lib.harvestTree("forward") -- fell tree or plant sapling, ends facing tree / dirt / sapling. sticks already used for fuel. excess saplings placed
  8295.        
  8296.         if logSlot == 0 then -- no logs passed as parameter
  8297.             logSlot = T:getItemSlot("log")
  8298.         end
  8299.         T:go("R1F1D1")          -- return to base, facing buried storage
  8300.         if logSlot == 0 then    -- has logs so needs to craft and refuel
  8301.             T:turnRight(1)      -- facing crops
  8302.         end
  8303.        
  8304.         return logSlot
  8305.     end
  8306.    
  8307.     function lib.harvest(crop)
  8308.         --[[
  8309.         cover the field in a set pattern.
  8310.         harvest crops if ripe
  8311.         till soil and plant new ones
  8312.         place seeds / harvest in chests
  8313.         return farm(s) to right / front
  8314.         ]]
  8315.         T:go("U1") --ready to farm field
  8316.         local isFarmToRight = false
  8317.         local isFarmToFront = false
  8318.         local width = 9
  8319.         local length = 10
  8320.         local toRight = true
  8321.         for l = 1, length do
  8322.             for w = 1, width do
  8323.                 isReady, blockType, _ = lib.isCropReady("down") -- eg true, "minecraft:carrots", "7 / 7" or false, "", ""
  8324.                 turtle.select(1)
  8325.                 if blockType == "" then                 -- air (above water, storage or dirt)
  8326.                     --turtle.digDown("left")            -- use pickaxe
  8327.                     turtle.digDown("right")             -- use hoe
  8328.                     lib.plantCrop(crop, "down")         -- plant crop
  8329.                 elseif isReady then                     -- crop below is ready
  8330.                     turtle.digDown("left")              -- use pickaxe
  8331.                     lib.plantCrop(blockType, "down")    -- plant crop
  8332.                 end
  8333.                 T:forward(1)
  8334.                 if l == 1 and w == width then -- last block of first row at front of farm
  8335.                     T:forward(1)
  8336.                     if lib.isStorage("down") then
  8337.                         isFarmToRight = true
  8338.                     end
  8339.                     turtle.back()
  8340.                 end
  8341.             end
  8342.             -- end of the row: change direction
  8343.             if l < length then -- do not turn at final row
  8344.                 lib.plantCrop(crop, "down")
  8345.                 if toRight then
  8346.                     T:go("L1F1L1")
  8347.                 else
  8348.                     T:go("R1F1R1")
  8349.                 end
  8350.             end
  8351.             toRight = not toRight
  8352.         end
  8353.         T:go("R1F1") -- goes over chest/cobble on top wall
  8354.         if lib.isStorage("down") then
  8355.             isFarmToFront = true
  8356.         end
  8357.         T:go("R2F"..length.."D1L1") -- go straight across to seed chest 10 blocks, facing crops
  8358.         lib.storeCrops() -- rotates from start to deposit seeds and crops, ends facing crops
  8359.         return isFarmToRight, isFarmToFront
  8360.     end
  8361.    
  8362.     function lib.harvestTree(direction)
  8363.         --[[
  8364.             start in front of / during tree harvest
  8365.             Check if sapling present
  8366.             Harvest tree if present, replant sapling
  8367.             Dispose of apples. Use sticks as fuel
  8368.             Return to base
  8369.         ]]
  8370.         if turtle.getFuelLevel() < turtle.getFuelLimit() / 2 then -- only harvest tree if fuel < half max
  8371.             direction = direction or "forward"
  8372.             local inFront = T:getBlockType("forward")
  8373.             print("Checking tree")
  8374.             if inFront == "" then -- no tree or sapling
  8375.                 print("No sapling: planting sapling")
  8376.                 T:place("sapling", -1, "forward", false)
  8377.             elseif inFront:find("log") ~= nil or direction == "up" then -- tree above or in front
  8378.                 -- clsTurtle.harvestTree(self, extend, craftChest, direction)
  8379.                 print("Harvesting tree")
  8380.                 T:harvestTree(false, false, direction) --do not investigate side branches in case chunk unloaded
  8381.                 T:go("R2F1R2") -- face dirt
  8382.                 -- place(self, blockType, damageNo, direction, leaveExisting, signText)
  8383.                 T:place("sapling", -1, "forward", false)
  8384.             end
  8385.             print("Dropping saplings into storage")
  8386.             T:dropItem("sapling", "down", 0) -- drop all saplings down into chest
  8387.             print("Disposing of apples")
  8388.             T:dropItem("apple", "up", 0) -- drop any apples
  8389.             local slot = T:getItemSlot("minecraft:stick")
  8390.             if slot > 0 then -- use any sticks to refuel
  8391.                 turtle.select(slot)
  8392.                 turtle.refuel()
  8393.             end
  8394.         end
  8395.     end
  8396.    
  8397.     function lib.manageTree()
  8398.         --[[ starting position facing crops ]]
  8399.         local crop = ""
  8400.         local logSlot = T:getItemSlot("stick")
  8401.         if logSlot > 0 then
  8402.             turtle.select(logSlot)
  8403.             turtle.refuel()
  8404.         end
  8405.         logSlot = T:getItemSlot("log")
  8406.         local needsFuel = false
  8407.        
  8408.         if turtle.getFuelLevel() < turtle.getFuelLimit() / 2 then
  8409.             needsFuel = true
  8410.         end
  8411.         if needsFuel then
  8412.             print("Running Tree Manager")
  8413.             logSlot = lib.gotoTree(logSlot) -- check for sapling or harvest tree, retuns to start, ends facing buried barrel/chest if has logs, logSlot returned
  8414.         end
  8415.         if logSlot > 0 then
  8416.             if not needsFuel then           -- logs already onboard, no tree harvest, so turn towards buried chest
  8417.                 T:turnLeft(1)
  8418.             end
  8419.             T:go("F1")                      -- move to buried storage chest/barrel
  8420.             lib.refuelWithLogs(logSlot)     -- use any logs for fuel
  8421.             T:go("R2F1")                    -- facing seed chest/barrel
  8422.         else
  8423.             T:turnRight(1)                  -- facing seed chest/barrel
  8424.         end
  8425.        
  8426.         crop = lib.getSeeds("forward")      -- get 1 stack of beetroot / wheat seeds
  8427.         if crop == "" then
  8428.             print("No seeds available. Checking root veg")
  8429.             T:turnRight(1)                  -- face crop chests
  8430.             crop = lib.getVeg("forward")    -- gets any carrots / potatoes
  8431.             T:turnRight(2)                  -- face crops
  8432.         else
  8433.             T:turnLeft(1)                   -- face crops
  8434.         end
  8435.         return crop
  8436.     end
  8437.    
  8438.     function lib.isCropReady(direction)
  8439.         local isReady = false
  8440.         local status = ""
  8441.         local cropType = ""
  8442.         local success = false
  8443.         local data = {}
  8444.  
  8445.         direction = direction or "forward"
  8446.  
  8447.         if direction == "down" then
  8448.             success, data = turtle.inspectDown()
  8449.         else
  8450.             success, data = turtle.inspect()
  8451.         end
  8452.         if success then
  8453.             cropType = data.name
  8454.             --print("cropType: "..cropType) read()
  8455.             if data.name == "minecraft:carrots" then
  8456.                 status = data.state.age.." / 7"
  8457.                 --print("Carrots status: "..status) read()
  8458.                 if data.state.age == 7 then
  8459.                     isReady = true
  8460.                 end
  8461.             elseif data.name == "minecraft:potatoes" then
  8462.                 status = data.state.age.." / 7"
  8463.                 if data.state.age == 7 then
  8464.                     isReady = true
  8465.                 end
  8466.             elseif data.name == "minecraft:wheat" then
  8467.                 status = data.state.age.." / 7"
  8468.                 if data.state.age == 7 then
  8469.                     isReady = true
  8470.                 end
  8471.             elseif data.name == "minecraft:beetroots" then
  8472.                 status = data.state.age.." / 3"
  8473.                 if data.state.age == 3 then
  8474.                     isReady = true
  8475.                 end
  8476.             end
  8477.         end
  8478.         return isReady, cropType, status    -- eg true, "minecraft:carrots", "7 / 7" or false, "", ""
  8479.     end
  8480.  
  8481.     function lib.isStorage(direction)
  8482.         blockType = T:getBlockType(direction)
  8483.         if blockType:find("barrel") ~= nil then
  8484.             return true, "barrel"
  8485.         elseif blockType:find("chest") ~= nil then
  8486.             return true, "chest"
  8487.         end
  8488.        
  8489.         return false, ""
  8490.     end
  8491.    
  8492.     function lib.plantCrop(crop, direction)
  8493.         local planted = false
  8494.         --turtle.digDown("left") -- harvest existing
  8495.         --turtle.digDown("right") -- till soil
  8496.         if crop:find("potato") ~= nil then
  8497.             T:dropItem("poison", "up", 0)
  8498.         end
  8499.         planted = T:place("carrot", -1, direction)
  8500.         if not planted then
  8501.             planted = T:place("potato", -1, direction)
  8502.         end
  8503.         if not planted then
  8504.             planted = T:place("beetroot_seeds", -1, direction)
  8505.         end
  8506.         if not planted then
  8507.             planted = T:place("wheat_seeds", -1, direction)
  8508.         end
  8509.     end
  8510.    
  8511.     function lib.refuelWithLogs(logSlot)
  8512.         -- assume positioned in front of buried chest / barrel, saplings already dropped, apples dumped, sticks used as fuel
  8513.         print("Logs present: collecting crafting table")
  8514.         -- earlier versions used crafting table buried in the ground
  8515.         -- newer versions have a barrel or chest embedded in the ground, containing the crafting table
  8516.         print("Sorting Inventory")
  8517.         T:sortInventory()
  8518.         while T:suck("down") do end                 -- empty out barrel/chest to find crafting table
  8519.         if T:getItemSlot("crafting") == 0 then
  8520.             T:checkInventoryForItem({"crafting"}, {1}, true, "Crafting table required for logs->planks")
  8521.         end
  8522.         if T:equip("right", "minecraft:crafting_table") then -- swap equipment on right side
  8523.             for i = 1, 16 do                        -- drop anything except logs down into barrel/chest/pit
  8524.                 if T:getSlotContains(i):find("log") == nil then
  8525.                     T:drop("down", i)
  8526.                 else
  8527.                     logSlot = i
  8528.                 end
  8529.             end
  8530.             turtle.select(logSlot)
  8531.             turtle.transferTo(1)
  8532.             turtle.craft()                          -- craft logs to planks
  8533.             logSlot = T:getItemSlot("planks")
  8534.             while logSlot > 0 do
  8535.                 turtle.select(logSlot)
  8536.                 turtle.refuel()
  8537.                 logSlot = T:getItemSlot("planks")              
  8538.             end
  8539.                             -- refuel using planks
  8540.             while T:suck("down") do end             -- recover items from storagebelow
  8541.             if not T:equip("right", "minecraft:diamond_hoe") then       -- re-equip
  8542.                 T:equip("right", "minecraft:diamond_pickaxe")          
  8543.             end
  8544.             if T:dropItem("minecraft:crafting_table", "down") then
  8545.                 turtle.refuel() -- use any sticks
  8546.             end
  8547.         else
  8548.             print("Unable to equip crafting table.\n\nCheck turtle inventory and chest or barrel below")
  8549.             error()
  8550.         end
  8551.     end
  8552.    
  8553.     function lib.returnToBack()
  8554.         --[[ move from farm at front back to starting farm ]]
  8555.         T:go("U1R1F11D1L1")
  8556.     end
  8557.    
  8558.     function lib.returnToLeft()
  8559.         --[[ move from farm on right back to starting farm ]]
  8560.         T:go("U1R2F11D1R2")
  8561.     end
  8562.        
  8563.     function lib.storeCrops()
  8564.         -- place crops and seeds into chests
  8565.         T:turnRight(1)
  8566.         if lib.isStorage("forward") then
  8567.             lib.storeSeeds("forward")
  8568.         end
  8569.         T:turnRight(1)
  8570.         if lib.isStorage("forward") then
  8571.             lib.storeVeg("forward")
  8572.         end
  8573.         T:turnRight(2) -- facing crops again
  8574.     end
  8575.    
  8576.     function lib.storeSeeds(direction)
  8577.         direction = direction or "forward"
  8578.         if lib.isStorage(direction) then -- chest exists
  8579.             if T:getItemSlot("minecraft:wheat_seeds") > 0 then
  8580.                 if not T:dropItem("minecraft:wheat_seeds", direction, 0) then
  8581.                     T:dropItem("minecraft:wheat_seeds", "up", 0)
  8582.                 end -- drop all wheat seeds
  8583.             elseif T:getItemSlot("minecraft:beetroot_seeds") > 0 then
  8584.                 if not T:dropItem("minecraft:beetroot_seeds", direction, 0) then-- drop all beetroot seeds
  8585.                     T:dropItem("minecraft:beetroot_seeds", "up", 0)
  8586.                 end
  8587.             end
  8588.         end
  8589.     end
  8590.    
  8591.     function lib.storeVeg(direction)
  8592.         direction = direction or "forward"
  8593.         T:dropItem("apple", "up", 0) -- drop all apples
  8594.         T:dropItem("poison", "up", 0) -- drop all poison potatoes
  8595.         if lib.isStorage(direction) then
  8596.             if not T:dropItem("carrot", direction, 0) then-- drop carrots
  8597.                 --return false
  8598.             end
  8599.             T:dropItem("potato", direction, 0) -- drop potato
  8600.             T:dropItem("minecraft:wheat", direction, 0) -- drop all wheat
  8601.             T:dropItem("minecraft:beetroot", direction, 0) -- drop all beetroot
  8602.         end
  8603.     end
  8604.    
  8605.     function lib.watchFarm()
  8606.         --[[
  8607.         check status of crops in front of turtle.
  8608.         call lib.harvest when ripe
  8609.         return farm(s) found in front or to the right
  8610.         ]]
  8611.         local isReady, crop, status = lib.isCropReady("forward")        -- eg true, "minecraft:carrots", "7 / 7" or false, "", ""
  8612.         -- check state of crop in front. Harvest if ripe       
  8613.         while not isReady do
  8614.             isReady, crop, status = lib.isCropReady("forward")          -- eg true, "minecraft:carrots", "7 / 7" or false, "", ""
  8615.             if not isReady then
  8616.                 if crop == "" then
  8617.                     print("No crops found in front")
  8618.                     print("Plant seeds, carrots, potatoes")
  8619.                     error()
  8620.                 else
  8621.                     print("Waiting for "..crop.." status: "..status)
  8622.                 end
  8623.                 sleep(60)
  8624.             end
  8625.         end
  8626.         print("Local crops ripe")
  8627.        
  8628.         return lib.manageTree() -- "" or collected seeds / root crops
  8629.     end
  8630.    
  8631.     --[[
  8632.         called from args on start, or from user choice
  8633.         farm already built, needs planting and/or harvesting
  8634.         needs both pickaxe and hoe
  8635.         may start in any position if chunk unloaded while running
  8636.     ]]
  8637.     --local pp = utils.getPrettyPrint()
  8638.    
  8639.     local atHome = lib.checkPosition()-- facing crops, placed above water source
  8640.     if not atHome then
  8641.         if not lib.goHome() then -- try to find home
  8642.             return
  8643.             {
  8644.                 "Unable to determine my position.\n",
  8645.                 "Place me in the lower left corner",
  8646.                 "over water, facing the crops with",
  8647.                 "barrels or chests to my right and behind"
  8648.             }
  8649.         end
  8650.     end
  8651.     -- check equipment
  8652.     T:go("L1F1") -- over barrel
  8653.     local isStorage, storageType = lib.isStorage("down")
  8654.     if not isStorage then
  8655.         local message =
  8656. [["Farm upgrade required:
  8657. Previous designs had a crafting table
  8658. next to the water source.
  8659.  
  8660. 1. Place a barrel or chest under the turtle
  8661.    instead.
  8662.    
  8663. 2. Restart"
  8664. ]]
  8665.         print(message)
  8666.         error()
  8667.     end
  8668.     -- must be storage below to get this far
  8669.     if lib.checkEquipment() then
  8670.         T:equip("right", "minecraft:diamond_hoe", 0) -- equip hoe and put crafting chest into inventory
  8671.         T:dropItem("crafting", "down")
  8672.         utils.goBack(1)
  8673.         T:turnRight(1)
  8674.     else
  8675.         return {"Unable to equip hoe."}
  8676.     end
  8677.  
  8678.    
  8679.     -- check if crops already planted
  8680.     local isReady, crop, status = lib.isCropReady("forward")
  8681.     local watch = true  -- assume watching farm already planted
  8682.     if crop == "" then  -- nothing has been planted
  8683.         watch = false-- not watching, continue with planting
  8684.         pp.itemColours = {colors.lightGray, colors.red, colors.orange, colors.brown}
  8685.         crops = {"minecraft:wheat_seeds", "minecraft:beetroot_seeds", "minecraft:carrots", "minecraft:potatoes"}
  8686.         choices = {"wheat (seeds)", "beetroot (seeds)", "carrot", "potato"}
  8687.         choice = menu.menu("Choose preferred crop", choices, pp, "Type number of your choice")
  8688.         crop = crops[choice]
  8689.         T:checkInventoryForItem({crop}, {95}, true, "Do not mix! add as many as you want")
  8690.     end
  8691.  
  8692.     while true do -- start infinite loop of watching crops, farming all modules
  8693.         if watch then -- not already in inventory
  8694.             crop = lib.watchFarm() --waits if required, returns crop type when ripe
  8695.         end
  8696.         print("Beginning "..crop.." management")
  8697.         local isFarmToRight, isFarmToFront = lib.harvest(crop)
  8698.         if isFarmToRight then
  8699.             lib.farmToRight() -- no action if no farmToRight
  8700.             lib.returnToLeft() -- return home and continue with front
  8701.             isFarmToRight = false
  8702.         end
  8703.        
  8704.         if isFarmToFront then
  8705.             isFarmToRight = lib.farmInFront()
  8706.             if isFarmToRight then
  8707.                 lib.farmToRight() -- no action if no farmToRight
  8708.                 lib.returnToLeft() -- return home
  8709.             end
  8710.             lib.returnToBack()
  8711.         end
  8712.         if not R.auto then -- not started from startup.lua
  8713.             T:go("L1F1")
  8714.             while T:suck("down") do end                     -- recover items from storagebelow
  8715.             T:equip("right", "minecraft:crafting_table", 0) -- equip crafting_table
  8716.             T:dropItem("diamond_hoe", "down")               -- drop hoe into storage
  8717.             T:dropItem("crafting", "down")                  -- in case spare one picked by mistake
  8718.             utils.goBack(1)
  8719.             T:turnRight(1)
  8720.             return {"Crop management of all modules completed"}
  8721.         end
  8722.     end
  8723.     return {}
  8724. end
  8725.  
  8726. local function manageFarmSetup(R) -- 33
  8727.     local lib = {}
  8728.    
  8729.     function lib.disableAutostart()
  8730.         if fs.exists("start.txt") then
  8731.             fs.delete("start.txt")
  8732.         end
  8733.         if fs.exists("startup.lua") then
  8734.             fs.delete("startup.lua")
  8735.         end
  8736.     end
  8737.    
  8738.     function lib.enableAutostart()
  8739.         if not fs.exists("startup.lua") then
  8740.             local h = fs.open("startup.lua", "w")
  8741.             h.writeLine('function main()')
  8742.             h.writeLine('   if fs.exists("start.txt") then')
  8743.             h.writeLine('       local handle = fs.open("start.txt", "r")')
  8744.             h.writeLine('       local cmd = handle.readLine()')
  8745.             h.writeLine('       handle.close()')
  8746.             h.writeLine('       shell.run("tk.lua "..cmd)')
  8747.             h.writeLine('   end')
  8748.             h.writeLine('end')
  8749.             h.writeLine('main()')
  8750.             h.close()
  8751.         end
  8752.         local h = fs.open("start.txt", "w")
  8753.         if R.data == "farm" then
  8754.             h.writeLine('farm')
  8755.         end
  8756.         h.close()
  8757.         print("Startup files written")
  8758.     end
  8759.    
  8760.     T:clear()
  8761.     --local pp = utils.getPrettyPrint()
  8762.     local choices = {"Plant or harvest this farm complex"}
  8763.     local isManaged = fs.exists("start.txt")
  8764.     if isManaged then
  8765.         table.insert(choices, "Disable automatic farm management")
  8766.     else
  8767.         table.insert(choices, "Enable automatic farm management")
  8768.     end
  8769.     pp.itemColours = {colors.lime, colors.lightGray}
  8770.     local userChoice, modifier = menu.menu("Choose your option", choices, pp) -- 1 to 2
  8771.     if modifier == "q" then -- quit chosen
  8772.         return {"Player has quit"}
  8773.     end
  8774.     R.subChoice = userChoice
  8775.     if R.subChoice == 1 then -- harvest now
  8776.         R.silent = false
  8777.         R.data = "farm"
  8778.         R.auto = false
  8779.         return manageFarm(R)
  8780.     else -- enable/disable auto farm
  8781.         local line = menu.clear()
  8782.         if isManaged then
  8783.             local message = ( "This turtle has been configured to"..
  8784.                               "start automatically and run the farm"..
  8785.                               "management program.\n")
  8786.             line = menu.colourText(line, message, true, true)
  8787.             if menu.getBoolean("Do you want to disable this? (y/n)", line, colors.yellow, colors.black) then
  8788.                 lib.disableAutostart()
  8789.             end
  8790.             return {"Autostart disabled. Reboot to activate"}
  8791.         else -- not managed
  8792.             local message = ( "~yellow~This turtle can be configured to be\n"..
  8793.                               "a dedicated farm manager.\n\n"..
  8794.                               "~lightGray~It will then start automatically and\n"..
  8795.                               "monitor the farm complex:\n\n"..
  8796.                               "~green~harvesting~yellow~ and ~lime~replanting ~yellow~continuously.\n")
  8797.             line = menu.colourText(line, message, true, true)
  8798.             if menu.getBoolean("Do you want to enable this? (y/n)", line + 2, colors.orange, colors.black) then
  8799.                 lib.enableAutostart()
  8800.             else
  8801.                 return {"Player cancelled operation"}
  8802.             end
  8803.             return {"Autostart enabled. Reboot to activate"}
  8804.         end
  8805.     end
  8806.    
  8807.     return {}
  8808. end
  8809.  
  8810. local function measure(R) -- 101
  8811.     -- measure height/ depth / length
  8812.     local lib = {}
  8813.    
  8814.     function lib.checkBlocks(R, blocks)
  8815.         local dimension = "height"
  8816.         local message = ""
  8817.         local measure = ""
  8818.         local doContinue = true
  8819.         if R.choice == 102 then
  8820.             dimension = "depth"
  8821.         elseif R.choice == 103 then
  8822.             dimension = "length"
  8823.         end
  8824.         blocks = blocks + 1
  8825.         if blocks > R.size then
  8826.             message = "Max "..dimension.." of "..R.size.." stopped measurement"
  8827.             measure = ""
  8828.             doContinue = false
  8829.         else
  8830.             measure = dimension.." measured: "..blocks.." blocks"
  8831.         end
  8832.         return doContinue, blocks, measure, message
  8833.     end
  8834.    
  8835.     local blocks = 1
  8836.     local method = ""
  8837.     local measure = ""
  8838.     local message = ""
  8839.     local doContinue = true
  8840.     if R.choice == 101 then             -- height
  8841.         if R.subChoice == 1 then        -- obstruction above
  8842.             method = "Method: Until obstruction above"
  8843.             while turtle.up() and doContinue do
  8844.                 doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8845.             end
  8846.         elseif R.subChoice == 2 then    -- end of blocks in front of turtle eg cliff, wall
  8847.             method = "Method: Until no block detected in front"
  8848.             while turtle.detect() and doContinue do
  8849.                 if turtle.up() then
  8850.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8851.                 else
  8852.                     message = "Obstruction above stopped measurement"
  8853.                     measure = ""
  8854.                     doContinue = false
  8855.                 end
  8856.             end
  8857.         elseif R.subChoice == 3 then    -- search for specific block min 3 characters
  8858.             method = "Method:Until search: '"..R.data.."' met"
  8859.             while turtle.detect() and doContinue do
  8860.                 if turtle.up() then
  8861.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8862.                     if doContinue then
  8863.                         local blockType = T:getBlockType("forward")
  8864.                         if blockType:find(R.data) ~= nil then
  8865.                             measure = "Height measured: "..blocks.." blocks"
  8866.                             message = "Found "..blockType
  8867.                             doContinue = false
  8868.                         end
  8869.                     end
  8870.                 else
  8871.                     message = "Obstruction above stopped measurement"
  8872.                     measure = ""
  8873.                     doContinue = false
  8874.                 end
  8875.             end
  8876.         elseif R.subChoice == 4 then    -- When block above changes eg dragon tower height
  8877.             local blockType = T:getBlockType("up")
  8878.             local compare = blockType
  8879.             method = "Method: Until "..blockType.." changes"
  8880.             while blockType == compare and doContinue do
  8881.                 T:up(1)
  8882.                 doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8883.                 if doContinue then
  8884.                     blockType = T:getBlockType("up")
  8885.                 end
  8886.             end
  8887.             measure = "Height measured: "..blocks.." blocks"
  8888.             message = "Found "..blockType
  8889.         end
  8890.        
  8891.         for i = 1, blocks do
  8892.             turtle.down()
  8893.         end
  8894.     elseif R.choice == 102 then -- depth
  8895.         T:go("F1R2D1") -- go off the edge and face cliff/pit wall
  8896.         blocks = blocks + 1
  8897.         if R.subChoice == 1 then        -- obstruction water / lava below
  8898.             local move = true
  8899.             while move do
  8900.                 local blockType = T:getBlockType("down")
  8901.                 if blockType:find("water") ~= nil or blockType:find("lava") ~= nil then
  8902.                     message1 = blockType.." found at "..blocks
  8903.                     move = false
  8904.                 else
  8905.                     move = turtle.down()
  8906.                     if move then
  8907.                         blocks = blocks + 1
  8908.                     else
  8909.                         measure = "Depth measured: "..blocks.." blocks"
  8910.                     end
  8911.                 end
  8912.             end
  8913.             method = "Method: Until obstruction below"
  8914.         elseif R.subChoice == 2 then    -- end of wall in front`
  8915.             while turtle.detect() do
  8916.                 if turtle.down() then
  8917.                     blocks = blocks + 1
  8918.                     measure = "Depth measured: "..blocks.." blocks"
  8919.                 else
  8920.                     message1 = "Obstruction below stopped measurement"
  8921.                     break
  8922.                 end
  8923.             end
  8924.             method = "Method: Until no block detected ahead"
  8925.         elseif R.subChoice == 3 then    -- specific block detected ahead
  8926.             method = "Method:Until search: '"..R.data.."' met"
  8927.             while turtle.detect() do
  8928.                 if turtle.down() then
  8929.                     blocks = blocks + 1
  8930.                     local blockType = T:getBlockType("forward")
  8931.                     if blockType:find(R.data) ~= nil then
  8932.                         measure = "Depth measured: "..blocks.." blocks"
  8933.                         message = "Found "..blockType
  8934.                         break
  8935.                     end
  8936.                 else
  8937.                     message = "Obstruction below stopped measurement"
  8938.                     break
  8939.                 end
  8940.             end
  8941.         end
  8942.         for i = 1, blocks do
  8943.             turtle.up()
  8944.         end
  8945.         T:go("F1R2")
  8946.     elseif R.choice == 103 then -- length
  8947.         if R.subChoice == 1 then        -- obstruction ahead
  8948.             method = "Method: Until obstruction ahead"
  8949.             while turtle.forward() and doContinue  do
  8950.                 doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8951.             end
  8952.         elseif R.subChoice == 2 then    -- end of ceiling above
  8953.             method = "Method: Until no block detected above"
  8954.             while turtle.detectUp() and doContinue do
  8955.                 if turtle.forward() then
  8956.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8957.                 else
  8958.                     message = "Obstruction ahead stopped measurement"
  8959.                     measure = ""
  8960.                     doContinue = false
  8961.                 end
  8962.             end
  8963.         elseif R.subChoice == 3 then    -- end of floor below
  8964.             method = "Method: Until no block detected below"
  8965.             while turtle.detectDown() and doContinue do
  8966.                 if turtle.forward() then
  8967.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8968.                 else
  8969.                     message = "Obstruction ahead stopped measurement"
  8970.                     measure = ""
  8971.                     doContinue = false
  8972.                 end
  8973.             end
  8974.         elseif R.subChoice == 4 then    -- search for specific block up min 3 characters
  8975.             method = "Method:Until search: '"..R.data.."' above met"
  8976.             while turtle.detectUp() and doContinue do
  8977.                 if turtle.forward() then
  8978.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8979.                     if doContinue then
  8980.                         local blockType = T:getBlockType("up")
  8981.                         if blockType:find(R.data) ~= nil then
  8982.                             message = "Found "..blockType
  8983.                             measure = "Length measured: "..blocks.." blocks"
  8984.                             doContinue = false
  8985.                         end
  8986.                     end
  8987.                 else
  8988.                     message = "Obstruction ahead stopped measurement"
  8989.                     measure = ""
  8990.                     doContinue = false
  8991.                 end
  8992.             end
  8993.         elseif R.subChoice == 5 then    -- search for specific block down min 3 characters
  8994.             method = "Method:Until search: '"..R.data.."' below met"
  8995.             --while turtle.detectDown() and doContinue do
  8996.             while doContinue do
  8997.                 if turtle.forward() then
  8998.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8999.                     if doContinue then
  9000.                         local blockType = T:getBlockType("down")
  9001.                         if blockType:find(R.data) ~= nil then
  9002.                             message = "Found "..blockType
  9003.                             measure = "Length measured: "..blocks.." blocks"
  9004.                             doContinue = false
  9005.                         end
  9006.                     end
  9007.                 else
  9008.                     message = "Obstruction ahead stopped measurement"
  9009.                     measure = ""
  9010.                     doContinue = false
  9011.                 end
  9012.             end
  9013.         end
  9014.         T:turnRight(2)  -- head home
  9015.         for i = 1, blocks do
  9016.             turtle.forward()
  9017.         end
  9018.         T:turnRight(2)
  9019.     elseif R.choice == 104 then -- depth of stretch of water
  9020.         --R.length = 0 to auto calculate
  9021.         R.width = 1
  9022.         R.silent = true
  9023.         R.useBlockType = ""
  9024.         R.data = "clearWaterPlants"
  9025.         local data = clearWaterPlants(R)
  9026.         R.height = data[1]
  9027.         local length = data[2]
  9028.         T:go ("R2F"..length - 1 .."R2U1")
  9029.         return {"Greatest depth measured: ".. R.height,"Width of water: "..R.length}
  9030.     end
  9031.     if message == "" then
  9032.         return{method, measure}
  9033.     else
  9034.         return{method, measure, message}
  9035.     end
  9036. end
  9037.  
  9038. local function mineBedrockArea(R) -- 19
  9039.     --[[
  9040.     Assume on level 5 or -59
  9041.     for 1, width do
  9042.         for 1, length do
  9043.             go down until bedrock, digging/replacing all directions
  9044.             return to 5 / -59
  9045.             move forward 1 blocks
  9046.         end
  9047.         turn right/ forward 2 turn right
  9048.     end
  9049.     ]] 
  9050.     local lib = {}
  9051.    
  9052.     function lib.clearColumn(R)
  9053.         local level = 0
  9054.         --T:go("L1x1R2x1L1")
  9055.         local success = T:down(1)
  9056.         while success do
  9057.             level = level + 1
  9058.             if R.data == "leaveExposed" then
  9059.                 T:go("R1x1R1x1R1x1R1x1", false, 0, true)
  9060.             else
  9061.                 T:go("R1C1R1C1R1C1R1C1", false, 0, true)
  9062.             end
  9063.             success = T:down(1)
  9064.         end
  9065.         if R.data == "leaveExposed" then
  9066.             T:go("U"..level)
  9067.         else
  9068.             T:go("U"..level.."C2")
  9069.         end
  9070.     end
  9071.    
  9072.     local goRight = true
  9073.     for i = 1, R.width do
  9074.         for j = 1, R.length do
  9075.             lib.clearColumn(R)
  9076.             T:forward(1)
  9077.         end
  9078.         if goRight then
  9079.             T:go("R1F1R1")
  9080.         else
  9081.             T:go("L1F1L1")
  9082.         end
  9083.         goRight = not goRight
  9084.     end
  9085.     return {}
  9086. end
  9087.  
  9088. local function oceanMonumentColumns(R)
  9089.     -- utility to find corners and build columns to surface
  9090.     local lib = {}
  9091.    
  9092.     function lib.buildColumn()
  9093.         local depth = 0
  9094.         while T:isWater("forward") do
  9095.             T:go("U1C2")
  9096.             depth = depth + 1
  9097.         end
  9098.         return depth
  9099.     end
  9100.    
  9101.     function lib.buildTower()
  9102.         T:go("F1C2 F1C2 F1C2")
  9103.         T:go("L1F1 L1C2 F1C2 F1C2 F1C2")
  9104.         T:go("R1F1 R1C2 F1C2 F1C2 F1C2")
  9105.         T:go("L1F1 L1C2 F1C2 F1C2 F1C2")
  9106.        
  9107.         T:go("R2")
  9108.         for i = 1, 4 do
  9109.             T:go("U1C2")
  9110.             for j = 1, 4 do
  9111.                 T:go("F1C2 F1C2 F1C2 R1")
  9112.             end
  9113.         end
  9114.     end
  9115.    
  9116.     R.silent = true
  9117.     local blockType = T:getBlockType("down")
  9118.     while blockType:find("water") == nil do
  9119.         T:down(1) -- if on a platform will break through
  9120.         blockType = T:getBlockType("down")
  9121.     end
  9122.     --R.useBlockType = "prismarine", R.data = "oceanMonumentColumns" from getTask
  9123.     --local tempData = R.data
  9124.     --R.data = "clearWaterPlants"
  9125.     local result = clearWaterPlants(R)[1]
  9126.     if result ~= "" then
  9127.         return {result}
  9128.     else
  9129.         --on corner of monument, facing out to ocean
  9130.         local depth = lib.buildColumn()
  9131.         -- now above surface, block below at surface level
  9132.         for i = 1, 4 do
  9133.             T:turnRight(1)
  9134.             R.length = 57
  9135.             utils.createPath(R) -- roughly at next corner
  9136.             if i < 4 then
  9137.                 T:down(depth-2) -- roughly at correct depth
  9138.                 local waterBelow = utils.clearVegetation("down")
  9139.                 while waterBelow do
  9140.                     T:down(1)
  9141.                     waterBelow = utils.clearVegetation("down")
  9142.                 end
  9143.                 blockType = T:getBlockType("down")
  9144.                 while blockType:find("prismarine") ~= nil do
  9145.                     T:forward(1)
  9146.                     blockType = T:getBlockType("down")
  9147.                 end
  9148.                 turtle.back()
  9149.                 depth = lib.buildColumn()
  9150.             end
  9151.         end
  9152.         -- completed retaining paths. Build small tower for easy access
  9153.         lib.buildTower()
  9154.     end
  9155.    
  9156.     return {}
  9157. end
  9158.  
  9159. local function placeRedstoneTorch(R) -- 91, 92
  9160.     local moves = 2
  9161.     local blockType = T:getBlockType("down")
  9162.     if R.data == "level" then
  9163.         T:turnLeft(1)
  9164.         utils.goBack(1)
  9165.         if blockType:find("rail") ~= nil then
  9166.              moves = 3
  9167.         end
  9168.         T:down(moves)
  9169.         T:go("F1R1")
  9170.         --clsTurtle.place(self, blockType, damageNo, direction, leaveExisting)
  9171.         T:place(R.useBlockType, -1, "forward", false)
  9172.         utils.goBack(1)
  9173.         T:place("minecraft:redstone_torch", -1, "forward", true)
  9174.         T:turnLeft(1)
  9175.         utils.goBack(1)
  9176.         T:up(moves)
  9177.         T:go("F1R1F1")
  9178.     elseif R.data == "up" then -- sloping rail up/down is relative to dirtection facing
  9179.         moves = 3
  9180.         T:turnLeft(1)
  9181.         utils.goBack(1)
  9182.         if blockType:find("rail") ~= nil then
  9183.              moves = 4
  9184.         end
  9185.         T:down(moves)
  9186.         T:go("F1L1")
  9187.         T:place("minecraft:redstone_torch", -1, "up", false)
  9188.        
  9189.         T:turnRight(1)
  9190.         utils.goBack(1)
  9191.         T:up(moves)
  9192.         T:go("F1R1")
  9193.     end
  9194.     return {}
  9195. end
  9196.  
  9197. local function plantTreefarm(R) -- 23
  9198.     --T:place(blockType, damageNo, direction, leaveExisting, signText)
  9199.     local lib = {}
  9200.    
  9201.     function lib.checkSaplings(saplings, firstChoice, secondChoice)
  9202.         local saplingSlot, sapling, count = T:getSaplingSlot(firstChoice)
  9203.         if count < 4  and secondChoice ~= "" then
  9204.             saplingSlot, sapling, count = T:getSaplingSlot(secondChoice)
  9205.         end
  9206.         if count == 0 then
  9207.             sapling = ""
  9208.         end
  9209.        
  9210.         return sapling, count
  9211.     end
  9212.    
  9213.     function lib.getSaplingInventory()
  9214.         local saplings = {}
  9215.         saplings.oak_sapling = 0
  9216.         saplings.spruce_sapling = 0
  9217.         saplings.birch_sapling = 0
  9218.         saplings.jungle_sapling = 0
  9219.         saplings.acacia_sapling = 0
  9220.         saplings.dark_oak_sapling = 0
  9221.  
  9222.         local firstChoice = ""
  9223.         local firstCount = 0
  9224.         local secondChoice  = ""
  9225.         local secondCount = 0
  9226.         for i = 1, 16 do
  9227.             if turtle.getItemCount(i) > 0 then
  9228.                 local data = turtle.getItemDetail(i)
  9229.                 if data.name:find("sapling") ~= nil then
  9230.                     local name = data.name:sub(11) -- removes "minecraft:"
  9231.                     saplings[name] = saplings[name] + data.count
  9232.                 end
  9233.             end
  9234.         end
  9235.        
  9236.         for sapling, count in pairs(saplings) do
  9237.             if count > firstCount then
  9238.                 firstCount = count
  9239.                 firstChoice = sapling
  9240.             else
  9241.                 if count > secondCount then
  9242.                     secondCount = count
  9243.                     secondChoice = sapling
  9244.                 end
  9245.             end
  9246.         end
  9247.         return saplings, firstChoice, secondChoice -- table, "oak_sapling", "dark_oak_sapling"
  9248.     end
  9249.    
  9250.     function lib.createIsland(sapling, count, exit)
  9251.         -- place 4 dirt with saplings on all 4 unless jungle
  9252.         -- sapling count/type already checked
  9253.         T:forward(2) -- assume starting outside planting area
  9254.         for i = 1, 4 do
  9255.             T:go("R1F1")
  9256.             T:place("dirt", -1, "down", false)
  9257.         end
  9258.         T:up(1)
  9259.         if count >= 4 then
  9260.             for i = 1, 4 do
  9261.                 T:go("R1F1")
  9262.                 T:place(sapling, -1, "down", false)
  9263.             end
  9264.         else
  9265.             if sapling:find("dark") == nil and sapling ~= "" then
  9266.                 T:place(sapling, -1, "down", false)
  9267.             end
  9268.         end
  9269.         if exit == "forward" then
  9270.             T:go("F1D1")
  9271.         elseif exit == "right" then
  9272.             T:go("R1F2D1")
  9273.         elseif exit == "left" then
  9274.             T:go("L1F1D1")
  9275.         elseif exit == "back" then
  9276.             T:go("R2F2D1")
  9277.         end
  9278.     end
  9279.    
  9280.     function lib.createSingle(sapling, exit)
  9281.         -- place single dirt with sapling on top
  9282.         -- sapling count/type already checked
  9283.         T:place("dirt", -1, "down", false)
  9284.         T:up(1)
  9285.         if not T:place(sapling, -1, "down", false) then -- try specific sapling
  9286.             T:place("sapling", -1, "down", false)       -- any available sapling
  9287.         end
  9288.         if exit == "forward" then
  9289.             T:go("F1D1")
  9290.         elseif exit == "right" then
  9291.             T:go("R1F1D1")
  9292.         elseif exit == "left" then
  9293.             T:go("L1F1D1")
  9294.         elseif exit == "back" then
  9295.             T:go("R2F1D1")
  9296.         end
  9297.     end
  9298.  
  9299.     local saplings, firstChoice, secondChoice = lib.getSaplingInventory()
  9300.  
  9301.     if firstChoice ~= "" then
  9302.         print("first sapling choice: "..firstChoice .. " ("..saplings[firstChoice]..")")
  9303.     end
  9304.     if secondChoice ~= "" then
  9305.         print("second sapling choice: "..secondChoice .. " ("..saplings[secondChoice]..")")
  9306.     end
  9307.  
  9308.     -- check type/size of farm
  9309.     if R.subChoice == 1 then -- 16 single trees
  9310.         local sapling, count = lib.checkSaplings(saplings, firstChoice, secondChoice)
  9311.         T:go("U1F4") -- outside first area
  9312.         for i = 1, 3 do -- column 1/4
  9313.             lib.createSingle(sapling, "forward")
  9314.             T:forward(1)
  9315.         end
  9316.         for i = 1, 2 do
  9317.             lib.createSingle(sapling, "right") -- place 4th dirt/saling and exit to right
  9318.             T:forward(1)
  9319.         end
  9320.         for i = 1, 2 do -- column 2/4
  9321.             lib.createSingle(sapling, "forward")
  9322.             T:forward(1)
  9323.         end
  9324.         for i = 1, 2 do
  9325.             lib.createSingle(sapling, "left") -- place 4th dirt/saling and exit to right
  9326.             T:forward(1)
  9327.         end
  9328.         for i = 1, 2 do -- column 3/4
  9329.             lib.createSingle(sapling, "forward")
  9330.             T:forward(1)
  9331.         end
  9332.         for i = 1, 2 do
  9333.             lib.createSingle(sapling, "right") -- place 4th dirt/saling and exit to right
  9334.             T:forward(1)
  9335.         end
  9336.         for i = 1, 3 do -- column 4/4
  9337.             lib.createSingle(sapling, "forward")
  9338.             T:forward(1)
  9339.         end
  9340.         T:go("R1F6L1F2R2D1")   
  9341.     elseif R.subChoice == 2 then -- 4 double trees (4 saplings)
  9342.         -- assume placed 4 blocks from start
  9343.         local sapling, count = lib.checkSaplings(mostName, secondMostName)
  9344.        
  9345.         if count >= 4 then
  9346.             T:go("U1F3") -- outside first area
  9347.             lib.createIsland(sapling, count, "forward")
  9348.             sapling, count = lib.checkSaplings(mostName, secondMostName)
  9349.             T:go("F2")
  9350.             lib.createIsland(sapling, count, "right")
  9351.             sapling, count = lib.checkSaplings(mostName, secondMostName)
  9352.             T:go("F2")
  9353.             lib.createIsland(sapling, count,  "right")
  9354.             sapling, count = lib.checkSaplings(mostName, secondMostName)
  9355.             T:go("F2")
  9356.             lib.createIsland(sapling, count, "forward")
  9357.             T:go("R1D1F6L1F3R2") -- outside first area
  9358.         else
  9359.             return {"Insufficient saplings to plant"}
  9360.         end
  9361.     end
  9362.     return {}
  9363. end
  9364.  
  9365. local function quickMine(R) -- 17
  9366.     --[[
  9367.     mine valuable blocks from specified area
  9368.     if R.up set or lava/water found, ceiling is formed
  9369.     if R.down is set, or lava/water found layer is kept 1 block high
  9370.     R.subChoice
  9371.     1 At mine area start, on the floor
  9372.     2 At mine area start, on the ceiling
  9373.     3 On floor, start 1 block ahead
  9374.     4 On ceiling, start 1 block ahead
  9375.     5 On floor diagonally to left"
  9376.     ]]
  9377.     local lib = {}
  9378.    
  9379.     function lib.refuel(direction)
  9380.         if T:getWater(direction)  then
  9381.             T:refuel(1000, false)
  9382.         end
  9383.     end
  9384.    
  9385.     function lib.mine(R)
  9386.         -- starts on ceiling
  9387.         local isValuable, blockType
  9388.         for i = 1, R.length do
  9389.             local fillUp = R.up
  9390.             local fillDown = R.down
  9391.             isValuable, blockType = T:isValuable("down")
  9392.             if isValuable then
  9393.                 T:dig("down")
  9394.             elseif blockType:find("water") ~= nil then
  9395.                 fillDown = true
  9396.             elseif blockType:find("lava") ~= nil then
  9397.                 lib.refuel("down")
  9398.                 fillDown = true
  9399.             end
  9400.             isValuable, blockType = T:isValuable("up")
  9401.             if isValuable then
  9402.                 T:dig("up")
  9403.             elseif blockType:find("water") ~= nil then
  9404.                 fillUp = true
  9405.             elseif blockType:find("lava") ~= nil then
  9406.                 lib.refuel("up")
  9407.                 fillUp = true
  9408.             end
  9409.             --if not turtle.detectUp() and fillUp then
  9410.             if fillUp then
  9411.                 T:fillVoid("up")
  9412.             end
  9413.             --if not turtle.detectDown() and fillDown then
  9414.             if fillDown then
  9415.                 T:fillVoid("down")
  9416.             end
  9417.             if i < R.length then
  9418.                 T:forward(1)
  9419.             end
  9420.         end
  9421.     end
  9422.    
  9423.     local outbound = true
  9424.    
  9425.     if R.subChoice == 1 then
  9426.         T:up(1)
  9427.     elseif R.subChoice == 3 then
  9428.         T:go("U1F1")
  9429.     elseif R.subChoice == 4 then
  9430.         T:go("F1")
  9431.     elseif R.subChoice == 5 then
  9432.         T:go("U1R1 F1L1 F1")
  9433.     end
  9434.    
  9435.     for w = 1, R.width do
  9436.         lib.mine(R)
  9437.         if w < R.width then
  9438.             if outbound then
  9439.                 T:go("R1F1R1")
  9440.             else
  9441.                 T:go("L1F1L1")
  9442.             end
  9443.             outbound = not outbound
  9444.         end
  9445.         if T:getFirstEmptySlot() == 0 then
  9446.             T:dumpRefuse("forward", 1)
  9447.         end
  9448.     end
  9449.     if outbound then
  9450.         T:go("L1F"..R.width - 1 .."L1F"..R.length - 1)
  9451.     else
  9452.         T:go("R1F"..R.width - 1 .."R1")
  9453.     end
  9454.    
  9455.     return {}
  9456. end
  9457.  
  9458. local function quickMineCorridor(R) -- 16
  9459.     --[[
  9460.     R.subChoice
  9461.     1: At corridor start, on the floor
  9462.     2: At corridor start, on the ceiling
  9463.     3: On floor, start 1 block ahead
  9464.     4: On ceiling, start 1 block ahead
  9465.     ]]
  9466.     if R.subChoice == 2 then
  9467.         T:down(1)
  9468.     elseif R.subChoice == 3 then
  9469.         T:forward(1)
  9470.     elseif R.subChoice == 4 then
  9471.         T:go("D1F1")
  9472.     end
  9473.     local width = R.width - 1
  9474.     local length = R.length - 1
  9475.     R.silent = true
  9476.     R.length = length
  9477.     createCorridor(R, true) -- put floor and ceiling for R.length, place torch at start
  9478.     T:turnRight(1)
  9479.     R.length = width
  9480.     createCorridor(R, true)
  9481.     T:turnRight(1)
  9482.     R.length = length
  9483.     createCorridor(R, true)
  9484.     T:turnRight(1)
  9485.     R.length = width
  9486.     createCorridor(R, true)
  9487.     T:turnRight(1)
  9488.    
  9489.     return {}
  9490. end
  9491.  
  9492. local function repairWall(startAt, height, width, replaceWith)
  9493.     -- go up to startAt
  9494.    
  9495.     -- if width = 1
  9496.    
  9497.         -- for h = startAt, height, 1 do
  9498.        
  9499.             -- replace block with replaceWith ("" = any)
  9500.            
  9501.             -- move up
  9502.            
  9503.         --end
  9504.        
  9505.         -- move back to beginning
  9506.        
  9507.     -- else
  9508.    
  9509.         -- remain = height % 2
  9510.        
  9511.         -- for w = 1, width - remain do
  9512.        
  9513.             -- for h = startAt, height, 1 do
  9514.            
  9515.                 -- replace block with replaceWith ("" = any)
  9516.                
  9517.                 -- move up
  9518.                
  9519.             --end
  9520.            
  9521.             -- move to the right 1 block
  9522.            
  9523.             -- for i = height, startAt, -1 do
  9524.            
  9525.                 -- replace block with replaceWith ("" = any)
  9526.                
  9527.                 -- move down
  9528.                
  9529.             --end
  9530.            
  9531.         -- end
  9532.        
  9533.     -- end
  9534.    
  9535. end
  9536.  
  9537. local function getTaskItemsList()
  9538.     -- list of items required for each task
  9539.     local text = {}
  9540.     --MINING
  9541.     text[11] = {"1 ladder for each level","levels / 4 torch (optional)","levels * 4 stone"}             -- ladder to bedrock
  9542.     text[12] = {"2 stairs for each level", "6 * levels stone", "1 chest"}                               -- stairs up/down
  9543.     text[13] = {"24 torch (optional)", "1 bucket (optional)", "64 stone", "1 chest"}                    -- mine at this level
  9544.     text[14] = {"levels * 4 stone","water_bucket"}                                                      -- safe drop to water block
  9545.     text[15] = {"levels * 4 stone", "1 soul sand", "1 water bucket"}                                    -- single column bubble lift
  9546.     text[16] = {"1 bucket (optional)", "64 stone"}                                                      -- quick corridor
  9547.     text[17] = {"1 bucket (optional)", "64 stone"}                                                      -- quick mine
  9548.     text[18] = {"1 bucket (optional)"}                                                                  -- mine to bedrock
  9549.     text[19] = {"1 UNUSED diamond sword (optional)"}                                                    -- rob mineshaft
  9550.  
  9551.     -- FORESTRY
  9552.     text[21] = {"1 chest (optional)"}                                                                   -- Fell Tree
  9553.     text[22] = {"320 stone", "4 polished stone"}                                                        -- Create treefarm
  9554.     text[23] = {"min 4 saplings", "16 dirt"}                                                            -- plant treefarm
  9555.     text[24] = {"No items required"}                                                                    -- Harvest treefarm
  9556.     text[25] = {"width * length * 2 walls or fences", "torches (optional)", "4 barrels (optional)"}     -- fence or wall a forest
  9557.     text[26] = {"1 chest", " any saplings"}                                                             -- harvest and replant walled rectangle of natural forest
  9558.                
  9559.     -- FARMING         
  9560.     text[31] = {"64 stone","128 dirt (optional)", "4 water buckets","4 chests / barrels","1 sapling"}   -- Create modular crop farm
  9561.     text[32] = {"64 stone","128 dirt (optional)", "4 water buckets","5 chests/ barrels","1 sapling"}    -- extend modular farm
  9562.     text[33] = {"No items required"}                                                                    -- Manual harvest and auto setup
  9563.     text[34] = {"Walls or Fences", "Torches (optional)"}                                                -- Build a wall or fence
  9564.     text[35] = text[34]                                                                                 -- Wall or fence enclosed area
  9565.  
  9566.     -- OBSIDIAN
  9567.     text[41] = {"stone to cover area of obsidian"}                                                      -- Harvest obsidian
  9568.     text[42] = {"2 x height + width obsidian", "4 stone"}                                               -- build Nether portal
  9569.     text[43] = {"No items required"}                                                                    -- demolish Nether portal
  9570.     text[44] = {"length * 4 stone/netherrack, bucket"}                                                  -- Netherite stripping
  9571.     text[45] = {"84 stone"}                                                                             -- undermine dragon towers
  9572.     text[46] = {"No items required"}                                                                    -- deactivate dragon tower
  9573.     text[47] = {"448 stone, 145 ladders, 1 obsidian, 1 water bucket"}                                   -- dragon water trap
  9574.     text[48] = {"height * 4 stone","height * ladders", "1 trapdoor"}                                    -- build end portal platform
  9575.                
  9576.     --CANALS BRIDGES WALKWAYS
  9577.     text[51] = {"dirt or stone * length","torch (optional)"}                                            -- single path
  9578.     text[52] = {"dirt or stone 2 * length","torch (optional)"}                                          -- covered path / tunnel
  9579.     text[53] = {"2 * length stone or dirt","2 water buckets","torches (optional)"}                      -- water canal
  9580.     text[54] = {"0.5 * length Packed or blue ice","length * slabs","stone","torches (optional)"}        -- Ice canal
  9581.     text[55] = {"width * length stone"}                                                                 -- platform
  9582.     text[56] = {"width + 1 * length + 1 stone"}                                                         -- sinking platform
  9583.     text[57] = {"height * 10 stone","height * 4 + 2 soul sand, 2 water buckets"}                        -- Boat bubble lift
  9584.    
  9585.     -- MOB FARM
  9586.     text[61] = {"512 stone","1 slab"}                                                                   -- 9x9 cube round spawner
  9587.     text[62] = {"640 stone","37 slab","8 powered rail","64 rail","2 redstone torch",
  9588.                 "1 hopper minecart","1 stone button"}                                                   -- 9x9 cube round blaze spawner
  9589.     text[63] = {"2 water buckets","If using bubble lift","2 fence","2 signs","1 slab",
  9590.                 "1 soul sand (or dirt as placeholder)"}                                                 -- flood spawner chamber   
  9591.     text[64] = {"128 stone","2 water buckets","1 soul sand"}                                            --Build bubble tower kill zone
  9592.     text[65] = {"1-2 computer","2 sticky or 4 normal pistons","6 network cable + 2 wired modems",
  9593.                 "23 polished stone + 7 slabs","2 glass","1 stone pressure plate","1 dispenser",
  9594.                 "1 hopper + 2 chest", "9 redstone", "1 lava bucket"}                                    --Computercraft mob grinder
  9595.     text[66] = {"1856 stone, diorite etc (inc polished)","1 chest","10 empty buckets",
  9596.                 "2 water buckets","192 fence","8 signs","3 ladder","2 soul sand"}                       -- build endermen observation tower
  9597.                
  9598.     -- AREA CARVING
  9599.     text[71] = {"width * length dirt"}                                                                  -- Clear field
  9600.     text[72] = {"No items required"}                                                                    -- Clear rectangle width, length
  9601.     text[73] = {"No items required"}                                                                    -- Clear wall height, length
  9602.     text[74] = {"No items required"}                                                                    -- Clear rectangle perimeter only width, length
  9603.     text[75] = {"No items required"}                                                                    -- Clear structure floor/walls/ceiling
  9604.     text[76] = {"No items required"}                                                                    -- clear solid
  9605.     text[77] = {"No items required"}                                                                    -- Dig a trench
  9606.     text[78] = {"No items required"}                                                                    -- carve mountain
  9607.     text[79] = {"width * height Any material floor / ceiling"}                                          -- floor or ceiling
  9608.     text[710] = {"Blocks to add 'floor as you go'"}                                                     -- Direct control of movement
  9609.                
  9610.     -- LAVA WATER
  9611.     text[81] = {"Enough sand or gravel to fill volume"}                                                 -- sand based utilities
  9612.     text[82] = {"length * depth stone"}                                                                 -- vertical wall from surface
  9613.     text[83] = {"Blocks to add 'floor as you go'"}                                                      -- player driven path construction
  9614.     text[84] = {"width * length + extra stone"}                                                         -- water clearing by repeated block deletion
  9615.     text[85] = text[84]                                                                                 -- sinking platform
  9616.     text[86] = {"Full inventories of sand or stone"}                                                    -- Ocean monument utilities
  9617.     text[87] = {"ladder to height","stone, dirt netherrack 4 X height"}                                 -- ladder to water/lava
  9618.     text[88] = {"No items required"}                                                                    -- clear water plants
  9619.     text[89] = {"water buckets / buckets"}                                                              -- convert flowing water to source
  9620.     text[810] = {"6 buckets","slabs to cover area"}                                                     -- create sloping water
  9621.                
  9622.     -- BUILDING and MINECART
  9623.     text[91] = {"length * height stone"}                                                                -- Build a wall
  9624.     text[92] = {"length * height * 4 stone"}                                                            -- build a walled area
  9625.     text[93] = {"length * width * height stairs", "length * slabs"}                                     -- build a gable roof
  9626.     text[94] = {"length * width * height stairs", "length * slabs"}                                     -- Build a pitched roof
  9627.     text[95] = {"1 block of choice","1 redstone torch"}                                                 -- place redstone torch under current block
  9628.     text[96] = {"1 block of choice","1 redstone torch"}                                                 -- place redstone torch on upward slope
  9629.     text[97] = {"height x block of choice","height/3 x redstone torch"}                                 -- build downward slope
  9630.     text[98] = text[97]                                                                                 -- build upward slope
  9631.     return text
  9632. end
  9633.  
  9634. local function getTaskHelp(menuLevel, menuItem, noMenu, getInteger)
  9635.     -- display help about selected task
  9636.     -- terminal size = 39 x 13
  9637. --[[This line of text = 39 characters]]
  9638.     noMenu = noMenu or false
  9639.     getInteger = getInteger or false
  9640.     info = {}
  9641.     info.main = {}
  9642.     info.sub = {}
  9643.     table.insert(info.main,
  9644.     [[                ~lightGray~MINING:~white~
  9645. Can be used in over-world or nether.~brown~
  9646. Ladders and ~lightGray~stairs up/down    
  9647. Create a pre-formatted 33 x 33 blocks  
  9648. mine at chosen level.
  9649. ~blue~Bubble lift and ~cyan~safe drop to water.~magenta~  
  9650. Faster version of ~white~33x33 mine pattern  
  9651. using ~magenta~corridor and ~pink~rectangle functions.~brown~
  9652. Mine bottom layer to bedrock (not worth
  9653. the fuel and time)
  9654. ~brown~Strip resources from abandoned mines.
  9655. ]])
  9656.     table.insert(info.main,
  9657.     [[               ~lime~FORESTRY:~brown~
  9658. Fell Tree can be used in Nether as well
  9659. for cutting any size tree / branches~lime~
  9660. Create a simple 16 single tree farm
  9661. or 4 double size (Dark oak or any type)
  9662. suitable for turtle harvesting.
  9663. ~brown~ fence or wall a rectangle keeping
  9664. to contours.
  9665. ~green~Forest can be harvested and replanted.
  9666. (Must be walled off)
  9667.  
  9668. ]])
  9669.     table.insert(info.main,
  9670.     [[                ~green~FARMING:~yellow~
  9671. Farm modules can be built to fixed size
  9672. and placed next to each other in linear
  9673. or rectangular pattern.~lime~
  9674. Whole farm is managed by a dedicated
  9675. turtle, which must be equipped with a
  9676. diamond hoe as well as pickaxe.
  9677. Fuel obtained from a tree placed in the
  9678. corner of each module.
  9679. Double chests store produce and seeds.
  9680. ]])
  9681.     table.insert(info.main,
  9682.     [[               ~red~OBSIDIAN:~lightGray~
  9683. The turtle can extract obsidian from
  9684. lava areas safely.~pink~
  9685. Nether portals can be built or removed
  9686. without needing diamond pickaxes.~orange~
  9687. End World dragon towers can be
  9688. undermined ready for deactivating.
  9689. End world towers can have the crystals
  9690. destroyed.~red~
  9691. Water trapped dragon attacked from above~brown~
  9692. Minecart end portal stations built.
  9693. ]])
  9694.     table.insert(info.main,
  9695.     [[        ~brown~PATHS, BRIDGES, CANALS:~white~
  9696. Can be used in Nether and End.~lightGray~
  9697. Build pathways over air, water or lava
  9698. Optional roofed pathway for Nether use.
  9699. Tunnel through rock and place a floor
  9700. at the same time.~blue~
  9701. Build a water canal with towpath.~cyan~
  9702. Build a super-fast ice canal.~brown~
  9703. Platform for use over air, water, lava
  9704. Sinking version is removed and replaced
  9705. 1 block lower each time
  9706. ]])
  9707.     table.insert(info.main,
  9708.     [[             ~lightGray~SPAWNER FARMS:~brown~
  9709. Tools to create mob farms round
  9710. existing spawners. ~red~
  9711. Special version for Blaze farms
  9712. uses rail collection.~cyan~
  9713. Choice of bubble lift mob dropper
  9714. or ~brown~simple deep trench.~gray~
  9715. Enderman observation tower can be
  9716. built >128 above ground: is ~red~expensive.~gray~
  9717. Re-spawns new mobs when used.~red~
  9718. Suggest build only the base.
  9719. ]])
  9720.     table.insert(info.main,
  9721.     [[    ~orange~AREA CLEARING AND REFORMING:~lime~
  9722. Tools to clear a field including trees~magenta~
  9723. Clear rectangles.~pink~
  9724. Clear single walls.~brown~
  9725. Clear hollow and~orange~solid structures.~brown~
  9726. Dig a trench.~gray~
  9727. Carve away side of a mountain.~lightBlue~
  9728. Place or replace floors and ceilings
  9729.  
  9730.  
  9731.  
  9732. ]])
  9733.     table.insert(info.main,
  9734.     [[      ~blue~WATER AND LAVA TOOLS:~white~
  9735. Used to drain ocean monuments and
  9736. shipwrecks. Can also be used to make
  9737. underwater base. ~blue~Water is cleared using
  9738. sand dropping and recycling~cyan~
  9739. Destructive draining uses solid block
  9740. placing and recycling.~green~
  9741. Water plants can be removed without
  9742. damaging structures.~lightBlue~
  9743. Tools to manipulate water areas:
  9744. (convert to source, sloping water)
  9745. ]])
  9746.     table.insert(info.main,
  9747.     [[         ~cyan~BUILDING, MINECART TOOLS:~lightGray~
  9748. Build simple walls, buildings and ~gray~roofs
  9749.  
  9750. ~orange~Used to build diagonal uphill slope~brown~
  9751. and downhill slope for placing
  9752. 45 degree rail tracks.~red~
  9753. Placing Redstone torches under powered
  9754. rails when above ground level (viaduct)
  9755.  
  9756.  
  9757.  
  9758. ]])
  9759.     table.insert(info.main,
  9760.     [[           ~yellow~MEASURING TOOLS:
  9761. Used to measure
  9762.     ~red~Height
  9763.     ~purple~Depth
  9764.     ~magenta~Length~pink~
  9765.    
  9766.     Greatest depth of water
  9767.  
  9768.  
  9769.  
  9770.  
  9771. ]])
  9772.  
  9773.     info.sub[11] =
  9774. [[~yellow~Place me on the ground at ~red~^~yellow~
  9775. The ~brown~ladder ~yellow~will start at this level
  9776. and go up or down.
  9777.  
  9778. ~lightGray~| | | | | |
  9779. ~lightGray~| | |*| | | * = Ladder support block
  9780. | | |~brown~L~lightGray~| | | ~brown~L = Ladder
  9781. ~lightGray~| | |~red~^~lightGray~| | | ~red~^ = Turtle
  9782. ~lightGray~| | | | | |
  9783. | | | | | |
  9784.  
  9785. ]]-- Ladder up/down
  9786.     info.sub[12] =
  9787. [[~lightGray~Place me on the ground at ~red~^
  9788.  
  9789. ~lightGray~| | | | | | | | * = Solid block
  9790. ~lightGray~| |*|*|*|*|*| | ~cyan~^ = Stairs to back
  9791. ~lightGray~| |*|-|~cyan~>~lightGray~|-|*| | ~cyan~> = Stairs to right
  9792. ~lightGray~| |*|~cyan~^|~lightGray~*|~cyan~V~lightGray~|*| | ~cyan~V = Stairs to front
  9793. ~lightGray~| |*|-|~cyan~<~lightGray~|-|*| | ~cyan~< = Stairs to left
  9794. ~lightGray~| |*|~red~^~lightGray~|*|*|*| | - = Corner tread
  9795. ~lightGray~| | | | | | | | ~red~^ = Turtle
  9796.  
  9797. ~lightGray~Going ~blue~down~lightGray~ -> digs down then stairs up
  9798. ]] -- Stairs up/down
  9799.         info.sub[13] =
  9800. [[~yellow~Press F3 to check Y level.
  9801.  
  9802. ~lightGray~| |~red~^~lightGray~| | | ~red~^ = Turtle behind ladder
  9803. ~lightGray~| |~gray~s~lightGray~| | | ~gray~s = 1 block space
  9804. ~lightGray~| |*| | | * = Ladder support block
  9805. ~lightGray~| |~brown~L~lightGray~| | | ~brown~L = Ladder
  9806. ~lightGray~| |~brown~s~lightGray~| | | ~brown~s~gray~ = 2 spaces (inc. ladder)
  9807. ~lightGray~| |~red~V~lightGray~| | | ~red~V = Turtle ahead of ladder~yellow~
  9808.  
  9809. ]]
  9810.     if bedrock == 0 then    --pre 1.18
  9811.         info.sub[13] = info.sub[13].."Place at Y = 5, 8, 11 ~red~(11 nether)" -- Create mine at this level
  9812.     else
  9813.         info.sub[13] = info.sub[13].."Place at Y = -59, -56, -53 (11 nether)" -- Create mine at this level
  9814.     end
  9815.     info.sub[14] =
  9816. [[~yellow~Turtle goes ~blue~DOWN ~yellow~to chosen level
  9817. enclosing all sides of the column.
  9818. Water placed at bottom. Returns here.
  9819. If next to a ladder, place as below:
  9820.  
  9821. ~lightGray~| | | | | |
  9822. ~lightGray~| | |*| | | * = Ladder support block
  9823. | |~red~^~brown~|L|~red~^~lightGray~| | ~brown~L = ladder
  9824. ~lightGray~| | | | | | ~red~^ = Turtle facing forward
  9825. ~lightGray~| | | | | |
  9826.            
  9827. ]] -- safe drop
  9828.     info.sub[15] =
  9829. [[~magenta~Direction of travel = UP!
  9830. ~yellow~Place me on the ground. I will build a
  9831. 3 x 1 ~blue~water ~yellow~source and a single column
  9832. bubble lift to the chosen height.
  9833. If near a ladder, place left or right:
  9834.  
  9835. ~lightGray~| | | | | |
  9836. ~lightGray~| | |*| | | * = Ladder support block
  9837. | |~blue~^~brown~|L|~blue~^~lightGray~| | ~brown~L = ladder
  9838. ~lightGray~| | | | | | ~blue~^ = Turtle facing forward
  9839. ~lightGray~| | | | | | ~blue~^ = Bubble column above
  9840.  
  9841. ]] -- single column bubble lift
  9842.     info.sub[16] =
  9843. [[~yellow~Place me as below:
  9844.  1. On ~blue~floor   ~yellow~(feet height)
  9845.  2. On ~lime~ceiling ~yellow~(eye height)
  9846.  
  9847. ~lightGray~B|B|B|B|B|B|B    ~yellow~W I D T H
  9848. ~lightGray~B| | | | | |B               ~orange~L
  9849. ~lightGray~B| |B|B|B| |B               ~orange~E
  9850. ~lightGray~B| |B|B|B| |B               ~orange~N
  9851. ~lightGray~B| |B|B|B| |B               ~orange~G
  9852. ~lightGray~B|~red~^~lightGray~| | | | |B  ~red~^~lightGray~ = Turtle   ~orange~T
  9853. ~lightGray~B|~cyan~P~lightGray~|B|B|B|B|B  ~cyan~P~lightGray~ = Player   ~orange~H
  9854. ]] -- quick corridor system
  9855.     info.sub[17] =
  9856. [[~yellow~~yellow~Place me as below:
  9857.  1. On ~blue~floor   ~yellow~(feet height)
  9858.  2. On ~lime~ceiling ~yellow~(eye height)
  9859. ~lightGray~B|B|B|B|B|B|B
  9860. B| | | | | |B
  9861. B| |B|B|B| |B
  9862. B| |B|B|B| |B
  9863. B| |~lime~^~lightGray~|B|B| |B
  9864. B|~red~^~lightGray~|~magenta~^~lightGray~| | | |B ~white~^~lightGray~ = turtle
  9865. B|~cyan~P~lightGray~|B|B|B|B|B ~cyan~P~lightGray~ = Player
  9866. ~yellow~Note colour of ~white~^~yellow~ matches next screen->
  9867. ]] -- quick mine
  9868.         info.sub[18] =
  9869. [[~yellow~Place me level -59 / 5 on the floor to
  9870. expose bedrock ~red~(slow and inefficient)
  9871.  
  9872. ~lightGray~| | | |B| |B|     ~yellow~W I D T H
  9873. ~lightGray~|B| | | | | |B               ~orange~L
  9874. ~lightGray~| | | |B|B| |                ~orange~E
  9875. ~lightGray~| | |B| | |B|                ~orange~N
  9876. ~lightGray~|B| | | |B| |                ~orange~G
  9877. ~lightGray~| | | | | | |B               ~orange~T
  9878. ~lightGray~|~red~^~lightGray~| | | |B| |B  ~red~^~lightGray~ = Turtle   ~orange~H
  9879. ]] -- mine all blocks to bedrock pre 1.12
  9880.         info.sub[19] =
  9881. [[~yellow~Place me on the end wall of a disused
  9882. mine in the centre block, 1 block above
  9883. the floor.
  9884. Provide a ~cyan~diamond ~yellow~sword for
  9885. harvesting string from spider webs~lightGray~
  9886.  
  9887. ~gray~-------   - = Ceiling
  9888. ~lightGray~| | | |
  9889. | |~red~T~lightGray~| |  ~red~T = Turtle (facing wall)
  9890. ~lightGray~| | | |
  9891. ~gray~-------  - = Floor
  9892. ]] -- salvage mineshaft
  9893.     info.sub[21] =
  9894. [[~yellow~Place me as below.
  9895. ~brown~Chest ~yellow~ONLY required if ~blue~0 ~yellow~fuel
  9896.  
  9897. Plan view:
  9898.  
  9899. ~green~   | | | |
  9900. ~green~   | |~lime~T~green~| |  ~lime~T = Tree
  9901. ~green~   | |~red~^~green~| |  ~red~^ = Turtle
  9902. ~green~   | | | |
  9903.  
  9904.  
  9905.  
  9906. ]] -- Fell Tree
  9907.     info.sub[22] =
  9908. [[~yellow~Place me on ground as below ~red~^
  9909. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | ~brown~|D| |D|
  9910. ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | ~green~or |*|~blue~ | | | | | |
  9911. ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | ~green~or |*|~blue~ | | ~brown~|D| |D|
  9912. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9913. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9914. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9915. ~lime~|~red~^~lime~|*|*|*|~blue~M~lime~|*| | ~green~or |~red~^~green~|*|*|*|~blue~M~green~|*|*|
  9916. ~lime~4 ~brown~double ~green~       or 16 ~brown~single
  9917. ~brown~D = Dirt, ~red~^ = Turtle, ~blue~M = Marker stone
  9918. ]] -- Create treefarm
  9919.     info.sub[23] =
  9920. [[~yellow~Place me on ground as below ~red~^
  9921. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | ~brown~|D| |D|
  9922. ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | ~green~or |*|~blue~ | | | | | |
  9923. ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | ~green~or |*|~blue~ | | ~brown~|D| |D|
  9924. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9925. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9926. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9927. ~lime~|*|*|*|*|~red~^~lime~|*| | ~green~or |*|*|*|*|~red~^~green~|*|*|
  9928. ~green~4 ~brown~double ~green~       or 16 ~brown~single
  9929. ~brown~D = dirt,~red~^ = Turtle, ~yellow~Max 16 saplings
  9930. Mixed OK. ~lime~Group 4 for double trees
  9931. ]] -- Plant treefarm / Harvest treefarm
  9932.     info.sub[24] = info.sub[23]
  9933.     info.sub[25] =
  9934. [[~yellow~Place me at ~red~^
  9935.  
  9936. ~lightGray~|F|F|F|F|F|F|F| F = Fence or Wall
  9937. ~lightGray~|F|~brown~B~lime~| | | |~brown~B~lightGray~|F| ~brown~B = Barrel (corners)
  9938. ~lightGray~|F|~lime~ | | | | ~lightGray~|F|
  9939. ~lightGray~|F|~lime~ | | | |~cyan~T~lightGray~|F| ~cyan~T = Tree
  9940. ~lightGray~|F|~lime~ |~cyan~T~lime~| | | ~lightGray~|F|
  9941. ~lightGray~|F|~lime~ | | | | ~lightGray~|F|
  9942. ~lightGray~|F|~brown~B~lime~| |~cyan~T~lime~| |~brown~B~lightGray~|F|
  9943. ~lightGray~|~red~^~lightGray~|F|F|F|F|F|F| ~red~^ = Turtle
  9944. ~yellow~Fence/Wall follows land contours
  9945. ]] --
  9946.     info.sub[26] =
  9947. [[~yellow~A rectangular walled area of forest:
  9948. Place me at ~red~^
  9949.  
  9950. ~lightGray~|F|F|F|F|F|F|F| F = Fence or wall
  9951. ~lightGray~|F|~brown~B~lime~| | | |~brown~B~lightGray~|F| ~brown~B = Barrel (corners)
  9952. ~lightGray~|F|~lime~ | | | | ~lightGray~|F|
  9953. ~lightGray~|F|~lime~ | | | |~cyan~T~lightGray~|F| ~cyan~T = Tree
  9954. ~lightGray~|F|~lime~ |~cyan~T~lime~| | | ~lightGray~|F|
  9955. ~lightGray~|F|~lime~ | | | | ~lightGray~|F|
  9956. ~lightGray~|F|~red~^~lime~| |~cyan~T~lime~| |~brown~B~lightGray~|F| ~red~^ = Turtle ~brown~(on Barrel)
  9957. ~lightGray~|F|F|F|F|F|F|F|
  9958.  
  9959. ]] -- manage walled forest
  9960.     info.sub[31] =
  9961. [[~yellow~Place me on the ground as below ~red~^
  9962.  
  9963. ~lightGray~|*|~green~ | | | | | | | | ~lightGray~* = Wall
  9964. ~lightGray~|*|~green~ | | | | | | | |
  9965. ~lightGray~|*|~green~ | | | | | | | |
  9966. ~lightGray~|*|~green~ | | | | | | | |
  9967. ~lightGray~|*|~green~ | | | | | | | |
  9968. ~brown~|B|B~green~| | | | | | | | ~brown~B = Barrel or Chest
  9969. ~brown~|B|~blue~W~green~| | | | | | | | ~blue~W = Water
  9970. ~lime~|~red~^~lime~|~brown~B|B|~lightGray~*|*|*|*|*|*| ~red~^ = Turtle
  9971. ~yellow~                    Size = 13 x 13
  9972. ]] -- Create modular crop farm
  9973.     info.sub[32] =
  9974. [[~yellow~Place next to the tree as below ~red~^
  9975.  
  9976. ~lightGray~|*|~green~ | | | | | | | | ~lightGray~* = Wall
  9977. ~lightGray~|*|~green~ | | | | | | | |
  9978. ~lightGray~|*|~green~ | | | | | | | |
  9979. ~lightGray~|*|~green~ | | | | | | | |
  9980. ~lightGray~|*|~green~ | | | | | | | | ~brown~B = Barrel or Chest
  9981. ~brown~|B|B~green~| | | | | | | | ~blue~W = Water
  9982. ~brown~|B|~blue~W~green~| | | | | | | | ~orange~S = Sapling or Tree
  9983. ~orange~|S|~red~^~brown~|B|~lightGray~*|*|*|*|*|*| ~red~^ = Turtle
  9984. ~yellow~                    Size = 13 x 13
  9985. ]] -- Extend farm
  9986.     info.sub[33] =
  9987. [[~yellow~Place as below (2 choices) ~blue~> ~yellow~or ~red~<
  9988.  
  9989. ~lightGray~|*|~green~ | | | | | | | | ~lightGray~* = Wall
  9990. ~lightGray~|*|~green~ | | | | | | | |
  9991. ~lightGray~|*|~green~ | | | | | | | |
  9992. ~lightGray~|*|~green~ | | | | | | | | ~brown~B = Barrel or Chest
  9993. ~lightGray~|*|~green~ | | | | | | | | ~blue~> = turtle on Water
  9994. ~brown~|B|B~green~| | | | | | | | C = Crop (first)
  9995. ~brown~|B|~blue~>~green~|C| | | | | | | ~orange~S = Sapling or Tree
  9996. ~orange~|S|~red~<~brown~|B|~lightGray~*|*|*|*|*|*| ~red~< = Turtle on Chest
  9997. ~yellow~Options to harvest or manage to follow.
  9998. ]] -- Manual harvest and auto setup
  9999.     info.sub[34] =
  10000. [[~yellow~Build a ~brown~fence ~yellow~or ~lightGray~wall ~yellow~to chosen length.
  10001.  
  10002. Turtle goes ~orange~BACKWARDS ~yellow~when started.
  10003.  
  10004. Start: length = 6, Turtle facing right
  10005.  
  10006. ~lightGray~| |~red~>~lightGray~| | | | | | | ~red~> = Turtle
  10007.  
  10008. Finish:
  10009.  
  10010. ~lightGray~| |F|F|F|F|F|F| | F = Fence or Wall
  10011. ]] -- build fence or wall
  10012.     info.sub[35] =
  10013. [[~yellow~Build a ~brown~fence ~yellow~or ~lightGray~wall ~yellow~
  10014. rectangular area.
  10015.  
  10016. ~lightGray~| | | | | | | | ~brown~F = Fence or Wall
  10017. ~lightGray~| ~brown~|F|F|F|F|F~lightGray~| |
  10018. ~lightGray~| ~brown~|F| | | |F~lightGray~| |
  10019. ~lightGray~| ~brown~|F| | | |F~lightGray~| |
  10020. ~lightGray~| ~brown~|F| | | |F~lightGray~| |
  10021. ~lightGray~| |~red~^~brown~|F|F|F|F| | ~red~^ = Turtle
  10022. ~lightGray~| | | | | | | |
  10023.  
  10024. ]] -- build rectangular fence or wall
  10025.     info.sub[41] =
  10026. [[~yellow~Place me on any block on the left
  10027. side facing the obsidian field.
  10028.  
  10029. ~gray~|O|O|O|O|O| O = Obsidian
  10030. |O|O|O|O|O|
  10031. |O|O|O|O|O|
  10032. |O|O|O|O|O|
  10033. |~red~^~gray~|O|O|O|O| ~red~^ = Turtle
  10034. |~red~^~gray~| | | | |
  10035.  
  10036. ]] -- Harvest obsidian
  10037.     info.sub[42] =
  10038. [[~yellow~Place me on the ground as below ~red~> ~pink~^
  10039. ~yellow~Start ~red~> ~yellow~(facing right) or ~pink~^ ~yellow~ahead
  10040.  
  10041. ~lightGray~| |~red~>~lightGray~|O|O|*| | |    |*|O|O|*| face view            
  10042.    ~pink~^~lightGray~               |O|~purple~+ +~lightGray~|O|
  10043.                    |O|~purple~+ +~lightGray~|O|
  10044. ~yellow~Result (plan)      ~lightGray~|O|~purple~+ +~lightGray~|O|
  10045. ~lightGray~| |O|O|O|O| | |    |*|O|O|*|
  10046.                    ~green~--------- ground
  10047. ~yellow~width=4, ~orange~height=5 ~red~(frame size)
  10048. ]] -- build Nether portal
  10049.     info.sub[43] = info.sub[42] -- Demolish Nether portal
  10050.     info.sub[44] =
  10051. [[~yellow~Press F3+G for chunk boundaries
  10052. Netherite stripmine plan view
  10053.                
  10054. ~lightGray~|*|*|*~lime~N~lightGray~*|*|*|
  10055. ~lightGray~|*|*|*~lime~|~lightGray~*|*|*| ~lime~-| = Chunk Boundaries
  10056. ~lightGray~|*|~red~^~lightGray~|*~lime~|~lightGray~*|~red~^~lightGray~|*|  ~red~^ = Turtle
  10057. ~lime~W*-*-*~blue~+~lime~*-*-*E  ~blue~+ = Boundaries junction
  10058. ~lightGray~|*|*|*~lime~|~lightGray~*|*|*|
  10059. ~lightGray~|*|*|*~lime~|~lightGray~*|*|*|  ~yellow~North of WE
  10060. ~lightGray~|*|*|*~lime~S~lightGray~*|*|*|  ~yellow~1 block from NS
  10061. Most generate close to chunk boundaries
  10062. ]] -- Netherite stripping
  10063.     info.sub[45] =
  10064. [[~yellow~Place me on the ground ~red~<~yellow~ facing ~red~West.
  10065.  
  10066. ~lime~x
  10067.                  ~lightGray~N
  10068. ~lime~a~lightGray~   -1        | | | |  
  10069. ~lime~x~lightGray~    0       ~red~W~lightGray~| |~red~<~lightGray~| |E  ~red~< = Turtle
  10070. ~lime~i~lightGray~    1        | | | |  
  10071. ~lime~s~lightGray~                S
  10072.     ~green~z axis    ~lightGray~-1 0 1
  10073.  
  10074. Centre of the dragon arena ~lime~X = 0, ~green~Z = 0
  10075. ~yellow~                           facing ~red~West
  10076. ]] -- Find dragon tower centres
  10077.     info.sub[46] =
  10078. [[~yellow~Place turtle in ceiling facing endstone
  10079.  
  10080. Plan view    Side view
  10081. ~gray~             |*|*|*|*|*|
  10082.     |*|      |*|*|*|*|*|
  10083.   |*|*|*|    |*|*|*|*|*|
  10084. |*|*|*|*|*|  |*|*|*|*|*|  * ~lightGray~= Obsidian
  10085. ~gray~|*|*|~yellow~E~gray~|*|*|  |*|*|*|*|*|  ~yellow~E ~lightGray~= Endstone
  10086. ~gray~  |*|~red~^~gray~|*|    |*|*|~red~T~gray~|*|*|~red~ ^T ~lightGray~= Turtle
  10087. ~gray~    |*|      |*|*| |*|*|
  10088.              |*|*| |*|*|
  10089. ]] -- deactivate dragon tower
  10090.     info.sub[47] =
  10091. [[~yellow~Place turtle on the ground at 100,49,0
  10092.  
  10093. |*|*|*|*|*|*|*|*|*|   ~lightGray~= Dragon Island
  10094.  
  10095.  
  10096. ~yellow~    Facing WEST
  10097. ~gray~    |*|*|*|*|*|     * ~lightGray~= Obsidian plate
  10098. ~gray~    |*|*|*|*|*|
  10099. ~yellow~  S ~gray~|*|*|~red~T~gray~|*|*| ~yellow~N   ~red~T ~lightGray~= Turtle
  10100. ~gray~    |*|*|*|*|*|
  10101.     |*|*|*|*|*|
  10102. ~yellow~         E]] -- build dragon water trap
  10103.     info.sub[48] =
  10104. [[~yellow~Place turtle under end world portal
  10105.  
  10106. ~gray~        |B|     B ~lightGray~= Bedrock
  10107. ~gray~      |B|B|B|
  10108.         ~purple~|P|     P ~lightGray~= Portal
  10109. ~gray~      |B|B|B|
  10110.         |B|
  10111.          ~green~|      
  10112.          ~green~|      ~lime~Height measured first     
  10113.          ~green~|      
  10114. ~red~         T      T ~lightGray~= Turtle 
  10115. ~yellow~  |*|*|*|*|*|*| ~red~Inventory AFTER height
  10116. ]] -- build end portal minecart
  10117.    
  10118.     info.sub[491] =
  10119. [[~yellow~Place turtle <64 blocks from shulker
  10120. Directly below or 1 block in front
  10121. ~lightGray~|*|*|*|*|*|*|*|
  10122.      ~gray~> ~lime~S ~gray~<       > T < = kill positions
  10123.        ~gray~T
  10124.  
  10125.  
  10126.  
  10127.      ~red~> T <       Attacks ahead / above
  10128. ~lightGray~|*|*|*|*|*|*|*|
  10129.  
  10130. ~red~> T <~lightGray~ = Turtle   ~lime~S~lightGray~ = Shulker]] -- Shulker is above
  10131.  
  10132.     info.sub[492] =
  10133. [[~yellow~Place turtle <64 blocks from shulker
  10134. Same level, or 1 block above/below
  10135. Plan view:
  10136.    ~red~>~lightGray~ | | | | | |~lime~S~lightGray~|
  10137.  
  10138. ~yellow~Side view:
  10139.    ~red~T~lightGray~ | | | | | |~gray~T~lightGray~|
  10140.    ~red~T~lightGray~ | | | | |~gray~T~lightGray~|~lime~S~lightGray~|   ~gray~T = kill positions
  10141.    ~red~T~lightGray~ | | | | | |~gray~T~lightGray~|
  10142.    
  10143.  ~red~> T~lightGray~ = Turtle   ~lime~S~lightGray~ = Shulker]] -- Shulker is ahead
  10144.    
  10145.     info.sub[493] =
  10146. [[~yellow~Place turtle <64 blocks from shulker
  10147. Directly above or 1 block in front
  10148. ~lightGray~|*|*|*|*|*|*|*|
  10149.      ~red~> T <       Attacks ahead / below
  10150.  
  10151.  
  10152.  
  10153.        ~gray~T
  10154.      ~gray~> ~lime~S ~gray~<       > T < = kill positions
  10155. ~lightGray~|*|*|*|*|*|*|*|
  10156.  
  10157. ~red~> T <~lightGray~ = Turtle   ~lime~S~lightGray~ = Shulker]] -- Shulker is below
  10158.  
  10159.     info.sub[494] =
  10160. [[~yellow~Place turtle in entry pit centre wall
  10161.  
  10162. ~lightGray~|*|~orange~+~lightGray~| | |~red~+~lightGray~| | |~lime~S~lightGray~|*| ~lime~S~lightGray~ = Shulker
  10163. ~lightGray~|*|~orange~+~lightGray~| |~lime~S|~red~+~lightGray~| | |~blue~+~lightGray~|*| T = turtle places
  10164. ~lightGray~|*|~orange~+~lightGray~| | |~red~+~lightGray~| | |~blue~+~lightGray~|*|
  10165. ~lightGray~|*|~orange~+~lightGray~| | |~red~+~lightGray~| | |~blue~+~lightGray~|*|     ~yellow~Plan view
  10166. ~lightGray~|*|~orange~+|+|+|~red~+|~blue~+|+|+~lightGray~|*|    |*|*|*|*|*|
  10167. ~lightGray~|*|*|*|~orange~+|~red~+|~blue~+~lightGray~|*|*|*|    |*| |~red~T~lightGray~| |*|
  10168. ~lightGray~|*|*|*|~orange~T|~red~T|~blue~T~lightGray~|*|*|*|    |*|~orange~T~lightGray~| |~blue~T~lightGray~|*|
  10169. ~lightGray~|*|*|*| | | |*|*|*|    |*| |~red~T~lightGray~| |*|
  10170.                        |*|*|*|*|*|]] -- Climb tower wall
  10171.  
  10172.     info.sub[495] =
  10173. [[~yellow~Place turtle in corner against ceiling
  10174. Face ~red~direction ~yellow~shown. It will exit up,
  10175. clear the roof above and return
  10176.  
  10177. ~lightGray~|*|*|*|*|*|*|*|*|*|*|  ~yellow~Clears 15x15
  10178. ~lightGray~|*|~red~<~lightGray~| | | | | | |~red~^~lightGray~|*|  ~yellow~area regardless
  10179. ~lightGray~|*| | | | | | | | |*|  ~yellow~of actual size
  10180.  
  10181. ~lightGray~|*| | | | | | | | |*|
  10182. ~lightGray~|*|~red~V~lightGray~| | | | | | |~red~>~lightGray~|*|
  10183. ~lightGray~|*|*|*|*|*|*|*|*|*|*|]] -- Clear roof above
  10184.  
  10185.     info.sub[496] =
  10186. [[~yellow~Place turtle in corner against ceiling
  10187. Face ~red~direction ~yellow~shown. It will exit out,
  10188. clear 4 outside walls and return.
  10189.  
  10190. ~lightGray~|*|*|*|*|*|*|*|*|*|*|  ~yellow~Size calculated
  10191. ~lightGray~|*|~red~<~lightGray~| | | | | | |~red~^~lightGray~|*|  ~yellow~automatically.
  10192. ~lightGray~|*| | | | | | | | |*|
  10193.  
  10194. ~lightGray~|*| | | | | | | | |*|
  10195. ~lightGray~|*|~red~V~lightGray~| | | | | | |~red~>~lightGray~|*|
  10196. ~lightGray~|*|*|*|*|*|*|*|*|*|*|]] -- Clear outside wall
  10197.  
  10198.     info.sub[51] =
  10199. [[~yellow~Place me on the ground as below ~red~^
  10200.  
  10201. ~yellow~Start:~blue~  |-|-|-|    - = air/water
  10202. ~orange~        |-|-|-|    - = lava
  10203. ~blue~        |-|-|-|
  10204. ~lightGray~        |*|~red~^~lightGray~|*|    ~red~^ = Turtle
  10205.  
  10206. ~yellow~Result:~blue~ |-|~lightGray~*|~blue~-|    - = air/water
  10207. ~orange~        |-|~lightGray~*|~orange~-|    - = lava
  10208. ~blue~        |-|~lightGray~*|~blue~-|
  10209. ~lightGray~        |*|*|*|    * = Solid block
  10210. ]] -- Single path
  10211.     info.sub[52] =
  10212. [[~yellow~Place ~red~^ T~yellow~ at start of path or tunnel
  10213.  
  10214. ~yellow~Plan view    Face view
  10215.  
  10216. ~lightGray~|*|~green~*~lightGray~|*|      *|*|*|*|*   ~green~* = new block
  10217. ~lightGray~|*|~green~*~lightGray~|*|      *|*|~green~*~lightGray~|*|*
  10218. ~lightGray~|*|~green~*~lightGray~|*|      *|*| |*|*
  10219. ~lightGray~|*|~green~*~lightGray~|*|      *|*|~red~T~lightGray~|*|*   ~red~^ T = Turtle
  10220.    ~red~^~lightGray~         ~green~- - * - -   ground
  10221.  
  10222. ~green~Floor + ceiling ~yellow~placed for your safety!
  10223. ]] -- Covered walkway / tunnel
  10224.     info.sub[53] =
  10225. [[~yellow~plan view
  10226.  
  10227. ~lightGray~|*|~blue~-|-~lightGray~|*|
  10228. ~lightGray~|*|~blue~-|-~lightGray~|*|    ~yellow~Cross section view
  10229. ~lightGray~|*|~blue~-|-~lightGray~|*|     ~lime~1 ~orange~2 ~brown~3 ~green~4  ~lightGray~= on ground
  10230. ~lightGray~|~lime~^~lightGray~|~blue~^~lightGray~|~cyan~^~lightGray~|~green~^~lightGray~|    |*|~blue~5~lightGray~|~cyan~6~lightGray~|*| ~lightGray~= in water
  10231.  
  10232. ~yellow~New canal       ~lime~1 ~orange~2 ~brown~3 ~green~4 ~yellow~ground level-63
  10233. ~yellow~Extend existing ~lime~1     ~green~4 ~yellow~ground level-63
  10234. ~yellow~Extend existing   ~blue~5 ~cyan~6   ~yellow~water  level-62
  10235. ]] -- new/existing canal
  10236.     info.sub[54] =
  10237. [[~lime~New ~yellow~ice canal or ~lightBlue~convert ~yellow~existing water
  10238.  
  10239. ~lightGray~ |*| | |*|    * = Slab
  10240. ~lightGray~ |~orange~T~lightGray~|~blue~I~lightGray~| |*|    ~blue~I = Ice (packed or blue)
  10241. ~lightGray~ |*| | |*|   | | = Air (empty block)
  10242. ~lightGray~ |*|~blue~I~lightGray~| |~orange~T~lightGray~|   ~orange~T = Torch (optional)
  10243. ~lime~  1 2 3 4    New ice canal
  10244. ~lightBlue~  5 6 7 8    Convert water canal
  10245.  
  10246. ~red~All turtles placed at ground level!
  10247. ~lime~1-4 ~lightGray~for ~lime~new ~lightGray~canal ~lightBlue~5-8 ~lightGray~to ~lightBlue~convert ~lightGray~water
  10248. ]] -- ice canal
  10249.     info.sub[55] =
  10250. [[~yellow~Place ~red~^~yellow~ any level air, water or lava.~lightGray~
  10251.  
  10252. | | | | | | | |
  10253. | |*|*|*|*|*| |  * = Block
  10254. | |*|*|*|*|*| |
  10255. | |*|*|*|*|*| |
  10256. | |*|*|*|*|*| |
  10257. | |~red~^~lightGray~|*|*|*|*| |  ~red~^ = Turtle~lightGray~
  10258. | | | | | | | |
  10259.  
  10260. Blocks placed under the turtle
  10261. ]] -- Platform
  10262.     info.sub[56] =
  10263. [[~yellow~Place ~red~^~yellow~ above water.~lightGray~
  10264. Existing platform replaced below
  10265.  
  10266. | |*|*|*|*|*| |  * = Block
  10267. | |*|*|*|*|*| |
  10268. | |*|*|*|*|*| |
  10269. | |*|*|*|*|*| |
  10270. | |~red~^~lightGray~|*|*|*|*| |  ~red~^ = Turtle~lightGray~
  10271. | | | | | | | |
  10272.  
  10273. Blocks placed under the turtle
  10274. ]] -- Sinking platform
  10275.     info.sub[57] =
  10276. [[~yellow~Boat Lift (Ice or Water)
  10277. Place turtle left side. ~blue~Source~yellow~ to right
  10278.  
  10279. Start~lightGray~        |*|~blue~ | ~lightGray~|*| ~yellow~Finish
  10280. ~lightGray~             |*|~blue~ | ~lightGray~|*|
  10281.              |*|~cyan~S|S|~lightGray~*| ~cyan~S ~lightGray~= Soul sand
  10282. |*|*|*|*|    |*|~brown~S|S~lightGray~|*| ~brown~S = ~lightGray~Sand + gate
  10283. |~red~^~lightGray~|~blue~W|W~lightGray~|*|    |*~blue~|W|W|~lightGray~*| ~red~^ ~lightGray~= Turtle
  10284. |*|~blue~W|W~lightGray~|*|    |*|~blue~W|W~lightGray~|*|
  10285. |*|~blue~ | ~lightGray~|*|    |*|~blue~ | ~lightGray~|*| ~yellow~Ice canal needs
  10286. ~lightGray~|*|~blue~ | ~lightGray~|*|    |*|~blue~ | ~lightGray~|*| ~yellow~2x2 water source
  10287. ]] -- boat bubble lift
  10288.     info.sub[61] =
  10289. [[~red~NOT ~yellow~for Blaze spawners!
  10290. Plan view          Side view~lightGray~
  10291.     T       T      T = Outside dungeon
  10292.  |*|*|*|*|*|*|*|   |*|~brown~1~lightGray~|*|*|*|~yellow~2~lightGray~|*| Top
  10293. T|*| | | | | |*|T  |*| | | | | |*|
  10294.  |*| | |~magenta~5~lightGray~| | |*|   |*| | |~magenta~5~lightGray~| | |*|
  10295.  |*| |~magenta~5~lightGray~|~orange~S~lightGray~|~magenta~5~lightGray~| |*|   |*|~lime~3~lightGray~|~magenta~5|~orange~S~lightGray~|~magenta~5|~green~4~lightGray~|*| Base
  10296.  |*| | |~magenta~5~lightGray~| | |*|
  10297. T|*| | | | | |*|T  * = Dungeon Wall
  10298.  |*|*|*|*|*|*|*|   ~orange~S = Spawner
  10299. ~lightGray~    T       T      T = Turtle ~brown~1 ~yellow~2 ~lime~3 ~green~4
  10300. ~magenta~5~lightGray~ = On top or adjacent (0 chests only)
  10301. ]] -- 9x9 cube round spawner
  10302.     info.sub[62] =
  10303. [[~yellow~Place turtle as indicated:
  10304. Plan view          Side view
  10305.  
  10306. ~lightGray~|*|*|*|*|*|*|*|*|  ~lime~> T = Continue build
  10307. ~lightGray~|*| | | | | | | |  ~red~< T = New build
  10308. ~lightGray~|*| | | | | | | |
  10309. |*| | | |~purple~S~lightGray~| | | |~lime~>~red~<          T
  10310. ~lightGray~|*| | | | | | | |   |*| | | |~purple~S~lightGray~| | | |~red~T
  10311. ~lightGray~|*| | | | | | | |   |*| | | | | | | |
  10312. ~lightGray~|*| | | | | | | |   |*| | | | | | | |
  10313. ~lightGray~|*|*|*|*|*|*|*|*|   |*| | | | | | | |~lime~T
  10314.                                      ~red~T]] -- 9x9 cube round blaze spawner
  10315.     info.sub[63] =
  10316. [[~yellow~ Plan view (truncated)    Side view
  10317.  
  10318. ~lightGray~ |*| | | | | | | | | |*|  |*| | | | | |
  10319. ~red~>~lightGray~|*| | | | |~purple~S~lightGray~| | | | |*|~red~<~lightGray~ |*| | | | |~purple~S~lightGray~|
  10320.  |*| | | | | | | | | |*|  |*| | | | | |
  10321.  |*| | | | | | | | | |*|  |*| | | | | |
  10322.  |*| | | | | | | | | |*|  |*| | | | | |
  10323.  |*| | | | | | | | | |*|  |*| | | | | |
  10324.  |*|*|*|*|*|*|*|*|*|*|*| ~red~T~lightGray~|*|*|*|*|*|*|
  10325.             ~red~^
  10326. ~purple~S ~lightGray~= Spawner ~red~<> ^ T ~lightGray~= Turtle
  10327. ]] -- Flood spawner chamber
  10328.     info.sub[64] =
  10329. [[~yellow~Bubble lift: Plan view at start~lightGray~
  10330.  |*| | | | | | | | | |*|
  10331.  |*| | | | |~brown~F~lightGray~| | | | |*|
  10332.  |*|*|*|*|*|~brown~F~lightGray~|*|*|*|*|*|  ~brown~F ~lightGray~= Fence
  10333.            ~brown~|~red~^~brown~|~lightGray~= Turtle on ~brown~Soul Sand
  10334.            
  10335. ~yellow~Plan view completed~lightGray~         
  10336.  |*| | | | |~brown~F~lightGray~| | | | |*|
  10337.  |*|*|*|*|*|~brown~F~lightGray~|*|*|*|*|*|  ~brown~F ~lightGray~= Fence
  10338. ~yellow~kill zone~lightGray~|*|~blue~S~lightGray~|*|~yellow~kill zone ~lightGray~Left / Right
  10339.            ~lightGray~|*|        ~blue~S ~lightGray~= Bubble lift
  10340. ]] -- Build bubble tower kill zone
  10341.     info.sub[65] =
  10342. [[~yellow~Computercraft mob grinder
  10343.  
  10344. Plan view~lightGray~ |*~blue~| | | | | | | | | |~lightGray~*|
  10345.           |*~blue~| | | | | | | | | |~lightGray~*|
  10346.           |*|*|*|*|*~blue~| |~lightGray~*|*|*|*|*| Front
  10347. ~red~T~yellow~urtle facing out    ~red~V~lightGray~              
  10348.                          
  10349. ~yellow~Side view ~lightGray~|*|*|*|*|*|*|*|*|*|*|*|
  10350.           |*|*|*|*|*|*|*|*|*|*|*|
  10351.           |*|*|*|*|*|*|*|*|*|*|*|
  10352. ~red~E~yellow~xit hole ~lightGray~|*|*|*|*|*|~red~T~lightGray~|*|*|*|*|*|
  10353.           ~gray~|*|*|*|*|*|*|*|*|*|*|*| Base
  10354. ]] -- Computercraft mob grinder
  10355.     info.sub[66] =
  10356. [[This is a 3 stage process:
  10357. 1.New tower lower base: place me on
  10358. flat ground in open plain.
  10359.  
  10360. 2.Upper base: place me in front of
  10361. the existing chest at tower base.
  10362.  
  10363. 3.Main tower, only needed to respawn
  10364. mobs. Expensive, not recommended.
  10365. Place me in front of chest in ground.
  10366. ]] -- Build endermen observation tower
  10367.  
  10368.     info.sub[71] =
  10369. [[~yellow~Clear field
  10370.  
  10371. ~lightGray~| | | | | |  Remove ~lime~trees ~lightGray~and ~pink~flowers
  10372. ~lightGray~| | | | | |  Fill ~gray~holes
  10373. ~lightGray~| | | | | |  Remove blocks > ground
  10374. | | | | | |
  10375. | | | | | |
  10376. |~red~^~lightGray~| | | | |  ~red~^ ~lightGray~= Turtle position
  10377.  
  10378. ~yellow~Optional use ~brown~dirt ~yellow~as surface
  10379.  
  10380. ]] -- Clear field
  10381.     info.sub[72] =
  10382. [[~yellow~Clear rectangle
  10383.  
  10384. ~lightGray~| | | | | |  Remove all blocks
  10385. ~lightGray~| | | | | |  Optional dig ~lime~up
  10386. ~lightGray~| | | | | |  Optional dig ~blue~down
  10387. ~lightGray~| | | | | |
  10388. | | | | | |
  10389. |~red~^~lightGray~| | | | |  ~red~^ ~lightGray~= Turtle position
  10390.  ~red~^
  10391.  
  10392. ~yellow~Can be used to clear 3 layers at a time
  10393.  
  10394. ]] -- Clear rectangle
  10395.  
  10396.     info.sub[73] =
  10397. [[~yellow~Clear wall
  10398. Plan view         Side view
  10399.                   ~gray~T ~lightBlue~T
  10400. ~red~>~lightGray~|~orange~>~lightGray~|*|*|*|*|*|    ~cyan~T~lightGray~|~blue~T~lightGray~|*|*|*|*|*| Top
  10401. ~lightGray~                   |*|*|*|*|*|*|
  10402.                    |*|*|*|*|*|*|
  10403.                    |*|*|*|*|*|*|
  10404.                    |*|*|*|*|*|*|
  10405.                   ~lime~T~lightGray~|~green~T~lightGray~|*|*|*|*|*| Base
  10406.                  
  10407. T = Turtle top / bottom/ inside / out
  10408. ~yellow~Bottom to top or top to bottom
  10409. ]] -- Clear wall
  10410.     info.sub[74] =
  10411. [[~yellow~Clear rectangle ~red~perimeter only
  10412.  
  10413. ~yellow~Plan view
  10414. ~lightGray~| | | | | |  Remove all blocks
  10415. ~lightGray~| |*|*|*| |  Optional dig ~lime~up
  10416. ~lightGray~| |*|*|*| |  Optional dig ~blue~down
  10417. ~lightGray~| |*|*|*| |
  10418. | |*|*|*| |
  10419. |~red~^~lightGray~| | | | |  ~red~^ ~lightGray~= Turtle position
  10420. ~red~ ^
  10421. ~yellow~Can be used to clear 3 layers at a time
  10422.  
  10423. ]] -- Clear rectangle (perimeter only)
  10424.     info.sub[75] =
  10425. [[~yellow~Demolish cube structure
  10426. Plan view        Side view
  10427.                ~gray~T ~lightBlue~T
  10428. ~lightGray~|*|*|*|*|*|*|  ~cyan~T~lightGray~|~blue~T~lightGray~|*|*|*|*|*|
  10429. |*|*|*|*|*|*|   |*|*|*|*|*|*|
  10430. |*|*|*|*|*|*|   |*|*|*|*|*|*|
  10431. |*|*|*|*|*|*|   |*|*|*|*|*|*|
  10432. |*|*|*|*|*|*|   |*|*|*|*|*|*|
  10433. |~lime~^~lightGray~|*|*|*|*|*|  ~lime~T~lightGray~|~green~T~lightGray~|*|*|*|*|*|
  10434.  ~green~^
  10435. ~lightGray~^ T = Turtle (top/base in/out)
  10436. ]] -- Clear structure floor/walls/ceiling hollow and solid
  10437.     info.sub[76] = info.sub[75]
  10438.     info.sub[77] =
  10439. [[~yellow~Dig a trench (Plan view)
  10440.  
  10441. ~lightGray~      |~red~>~lightGray~| | | | | | |
  10442.  
  10443. | |    ~red~>~lightGray~ = Turtle
  10444. | |    
  10445. | |
  10446. | |
  10447. | |    
  10448. |~red~^~lightGray~|    ~red~^~lightGray~ = Turtle
  10449. ]] -- Dig a trench
  10450.     info.sub[78] =
  10451. [[~yellow~Mountain carving     ~red~T ^ = Turtle
  10452. ~yellow~Side view            Plan view
  10453.  
  10454. ~lightGray~        |*|              |*|*|      ~yellow~L
  10455. ~gray~      |*~lightGray~|*|            ~gray~|*~lightGray~|*|*|*|    ~yellow~E
  10456. ~gray~      |*~lightGray~|*|*|*|      ~gray~|*|*~lightGray~|*|*|*|*|  ~yellow~N
  10457. ~gray~      |*~lightGray~|*|*|*|      ~gray~|*|*~lightGray~|*|*|*|*|  ~yellow~G
  10458. ~gray~      |*~lightGray~|*|*|*|       ~red~^~gray~|*~lightGray~|*|*|*|    ~yellow~T
  10459. ~gray~    |*|*~lightGray~|*|*|*|*|        |*|*|      ~yellow~H
  10460.    ~red~T~gray~|*|*~lightGray~|*|*|*|*|
  10461.     ~yellow~<--> no. of rows <-->
  10462. ]] -- Carve mountain
  10463.     info.sub[79] =
  10464. [[~yellow~Place / Replace floor or ceiling
  10465.  
  10466. Plan view      Side view
  10467. ~lightGray~| | | | | |    |*|*|*|*|*|
  10468. | | | | | |     T          Ceiling
  10469. | | | | | |
  10470. | | | | | |
  10471. | | | | | |     T          Floor
  10472. |~red~^~lightGray~| | | | |    |*|*|*|*|*|
  10473.  
  10474. ~red~^ ~lightGray~T = Turtle position
  10475.  
  10476. ]] -- (Re)place floor or ceiling
  10477.     info.sub[710] =
  10478. [[~yellow~Place me anywhere!
  10479. Menu or direct command interface.
  10480.  
  10481. ~lightGray~Commands:
  10482.  
  10483. direction + ~blue~number ~yellow~eg ~white~f2 ~yellow~= forward ~blue~2
  10484.  
  10485. ~yellow~f = forward  ~orange~b = backward
  10486. ~lime~l = left     ~red~r = right
  10487. ~lightGray~u = up       ~cyan~d = down
  10488.  
  10489. ]] -- Direct control
  10490.     info.sub[81] =
  10491. [[~blue~1.Drop sand or gravel wall
  10492.   ~yellow~Place me on water/lava surface
  10493.  
  10494. ~lightBlue~2.Fill area with sand
  10495.   ~yellow~Place  on left corner of area
  10496.  
  10497. ~yellow~3.Clear ~blue~(1) sand wall
  10498.   ~yellow~Place me on the surface of sand.
  10499.  
  10500. ~yellow~4.Clear ~lightBlue~(2) sand filled area
  10501.   ~yellow~Place on left corner of sand field
  10502. ]] -- Sand based utilities
  10503.     info.sub[82] =
  10504. [[~yellow~Turtle position ~red~> T ~gray~(~red~V ~gray~to enclose)
  10505. ~yellow~Plan view                      ~gray~Start:~red~V
  10506. ~blue~|~red~>~blue~| | | | | | ~yellow~to ~lightGray~|*|*|*|*|*|~red~V~lightGray~|~gray~ enclose
  10507.                             ~gray~*  area
  10508. ~yellow~Side view
  10509.  ~red~T
  10510. ~blue~| | | | | | | ~yellow~to ~lightGray~|*|*|*|*|*|*|
  10511. ~blue~| | | | | | |    ~lightGray~|*|*|*|*|*|*|
  10512. ~blue~| | | | | | |    ~lightGray~|*|*|*|*|*|*|
  10513. ~yellow~|S|~blue~ | | |~yellow~S|S|    |S|~lightGray~*|*|*|~yellow~S|S|
  10514. ~yellow~|S|S|S|S|S|S|    |S|S|S|S|S|S|
  10515. ]] -- build wall from water or lava surface downwards  
  10516.     info.sub[83] =
  10517. [[~yellow~Build a walled rectangle
  10518.  
  10519.  
  10520. ~yellow~L ~lightGray~|*|*|*|*|*|*|
  10521. ~yellow~e ~lightGray~|*| | | | |*|
  10522. ~yellow~n ~lightGray~|*| | | | |*|
  10523. ~yellow~g ~lightGray~|*| | | | |*|
  10524. ~yellow~t ~lightGray~|*|*|*|*|*|*|
  10525. ~yellow~h  ~red~^
  10526. ~yellow~   W i d t h      ~red~^ ~lightGray~= Turtle
  10527.  
  10528.  
  10529. ]] -- Create enclosed area
  10530.     info.sub[84] =
  10531. [[~yellow~Clear volume of water
  10532.  
  10533. Plan view
  10534. ~lightGray~|*|*|*|*|*|*|*|*|  * = Stone
  10535. |*|*~blue~| | |~lightGray~*|*~blue~| |~lightGray~*|  ~blue~| ~lightGray~= Water
  10536. |*~blue~| | | | | | |~lightGray~*|
  10537. |*~blue~| | | | | | |~lightGray~*|
  10538. |*~blue~| | | | | | |~lightGray~*|
  10539. |*~blue~| | | | | |~lightGray~*|*|
  10540. |*|~red~^~lightGray~|*~blue~| | | | |~lightGray~*|  ~red~^ ~lightGray~= Turtle
  10541. |*|*|*|*|*|*|*|*|  ~yellow~Width~blue~: ~yellow~6, ~orange~length~blue~:~orange~ 6
  10542.  
  10543. ]] -- Clear volume of water
  10544.     info.sub[85] = info.sub[56] -- Sinking platform
  10545.     info.sub[861] =
  10546. [[~yellow~Turtle placement  ~red~V~lime~ < ^ > ~yellow~over monument
  10547.  
  10548. ~red~******    ******  * ~lightGray~= Avoid this area
  10549. ~red~******    ******  V do not face front
  10550. ******    ******  ~lime~< ^ > ~lightGray~Ideal facing~lightGray~
  10551. ******    ******
  10552. ~green~******~lime~++++~green~******  ~lime~+ ~lightGray~= Ideal position~green~
  10553. ******~lime~++++~green~******  ~green~* ~lightGray~= Good position
  10554. ~green~****************
  10555. ****************  Or any corner < 12
  10556. ****************  blocks from edge
  10557. ]]-- Ocean monument 85 subChoice 1: 4 corner pillars
  10558.  
  10559.     info.sub[862] =
  10560. [[~yellow~Turtle positions ~red~> ^ < V
  10561.  
  10562. ~lightGray~|*|~red~>~lightGray~|*|*|*|*|*|~red~<~lightGray~|*|  ~red~NOT ~lightGray~corner blocks!
  10563. |~red~V~lightGray~|             |~red~V~lightGray~|
  10564. |*|             |*|
  10565. |*|             |*|
  10566. |*|             |*|
  10567. |*|             |*|
  10568. |*|             |*|  ~yellow~Fill inventory~lightGray~
  10569. |~red~^~lightGray~|             |~red~^~lightGray~|  ~yellow~with stone.~lightGray~
  10570. |*|~red~>~lightGray~|*|*|*|*|*|~red~<~lightGray~|*|  ~yellow~Add when asked
  10571. ]] -- Ocean monument build retaining walls
  10572.  
  10573.     info.sub[863] =
  10574. [[~yellow~Turtle ~red~> < ~yellow~on side walls only
  10575.  
  10576. ~lightGray~|*|*|*|*|*|*|*|*|*|*|
  10577. ~lightGray~|~red~>~cyan~| *****   ***** |~red~<~lightGray~|
  10578. ~lightGray~|~red~>~cyan~| *****   ***** |~red~<~lightGray~|
  10579. ~lightGray~|~red~>~cyan~| *****   ***** |~red~<~lightGray~|
  10580. ~lightGray~|~red~>~cyan~| *****+++***** |~red~<~lightGray~|
  10581. ~lightGray~|~red~>~cyan~| *****+++***** |~red~<~lightGray~|
  10582. ~lightGray~|~red~>~cyan~| ************* |~red~<~lightGray~|
  10583. ~lightGray~|~red~>~cyan~| ************* |~red~<~lightGray~|
  10584. |*|*|*|*|*|*|*|*|*|*|
  10585. ]] -- clear plants before sand draining
  10586.     info.sub[864] = info.sub[863]
  10587.     info.sub[865] = info.sub[863]
  10588.     info.sub[866] = info.sub[56]
  10589.     info.sub[867] =
  10590. [[~yellow~Turtle positions ~red~> ^ < V
  10591. ~green~|*|*|*|*|*~brown~|*|*|*|~red~V~brown~|*|
  10592. ~green~|~red~>~green~|- - - - ~brown~- - - -|*|
  10593. ~green~|*|- - - - ~brown~- - - -|*| ~lightGray~1 Turtle removes
  10594. ~green~|*|- - - - ~brown~- - - -|*| ~lightGray~1 coloured area
  10595. ~green~|*|- - - - ~brown~- - - -|*|
  10596. ~orange~|*|- - - - ~lime~- - - -|*| ~lightGray~6 chests / area
  10597. ~orange~|*|- - - - ~lime~- - - -|*| ~lightGray~Follow turtle
  10598. ~orange~|*|- - - - ~lime~- - - -|*|
  10599. ~orange~|*|- - - - ~lime~- - - -|~red~<~lime~| ~lightGray~30,000 fuel each!
  10600. ~orange~|*|~red~^~orange~|*|*|*~lime~|*|*|*|*|*| ~lightGray~3,000 stone each!
  10601. ]] -- Ocean monument drain and remove 1 of 4 quarters
  10602.     info.sub[87] =
  10603. [[~yellow~Ladder to water / lava: Plan view
  10604.  
  10605.  ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~-    ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~-
  10606.  ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~-    ~red~- ~blue~- ~red~-~lightGray~|*|- ~blue~- ~red~-
  10607.  ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~-    ~blue~- ~red~-~lightGray~|*|~brown~L~lightGray~|*|~red~- ~blue~- ~~lightGray~
  10608. |*|*|*|~red~^~lightGray~|*|*|*|  |*|*|*|*|*|*|*|
  10609. |*|*|*|*|*|*|*|  |*|*|*|*|*|*|*|
  10610. |*|*|*|*|*|*|*|  |*|*|*|*|*|*|*|
  10611.  
  10612. ~red~^ ~lightGray~= Turtle facing water / lava
  10613. ~brown~L ~lightGray~= Ladder
  10614.  
  10615. ]] -- Ladder to water/lava 
  10616.     info.sub[88] =
  10617. [[~yellow~Place ~red~T~yellow~urtle at water edge.
  10618. Returns max ~blue~d~yellow~epth. ~yellow~Water ~green~p~yellow~lants~yellow~ removed
  10619.  
  10620.    ~red~T                       T
  10621. ~lightGray~|*|*| ~blue~| | | | | | | | | | ~lightGray~|*|
  10622. |*|*| ~blue~| | | | | | | | | ~lightGray~|*|*|
  10623. |*|*| ~blue~| | | | | | | ~lightGray~|*|*|*|*|
  10624. |*|*|*| ~blue~| | |~green~p~blue~| | ~lightGray~|*|*|*|*|*|
  10625. |*|*|*| ~blue~| | |~green~p~lightGray~|*|*|*|*|*|*|*|
  10626. |*|*|*|*~blue~|d~lightGray~|*|*|*|*|*|*|*|*|*|
  10627. |*|*|*|*|*|*|*|*|*|*|*|*|*|*|
  10628. ]] -- Clear water plants from enclosed area
  10629.     info.sub[89] =
  10630. [[Place me on the left corner of the top
  10631. of retaining wall facing water
  10632. ]] -- Convert all water to source
  10633.     info.sub[810] =
  10634. [[Place me on the left corner of the top
  10635. of retaining wall facing water.
  10636. The source blocks are placed ahead to
  10637. selected length
  10638. ]] -- Create sloping water
  10639.  
  10640. -- Building and railway
  10641.     info.sub[91] =
  10642. [[~yellow~Build a wall
  10643.  
  10644. Plan view        Side view
  10645.  
  10646. ~red~>~lightGray~| | | | | | |   |*|*|*|*|*|*|
  10647.                  |*|*|*|*|*|*|
  10648.                  |*|*|*|*|*|*|
  10649.                  |*|*|*|*|*|*|
  10650.                 ~red~T~lightGray~|~red~T~lightGray~|*|*|*|*|*|
  10651.  
  10652. ~red~> T~lightGray~ = Turtle
  10653.                  
  10654. ]] -- Build a wall
  10655.     info.sub[92] =
  10656. [[~yellow~Build a walled rectangle / house
  10657.  
  10658. Plan view         Side view
  10659.  
  10660. ~yellow~L ~lightGray~|*|*|*|*|*|*|   |*|*|*|*|*|*|
  10661. ~yellow~e ~lightGray~|*| | | | |*|   |*|*|*|*|*|*|
  10662. ~yellow~n ~lightGray~|*| | | | |*|   |*|*|*|*|*|*|
  10663. ~yellow~g ~lightGray~|*| | | | |*|   |*|*|*|*|*|*|
  10664. ~yellow~t ~lightGray~|~red~^~lightGray~|*|*|*|*|*|  ~red~T~lightGray~|~red~T~lightGray~|*|*|*|*|*|
  10665. ~yellow~h  ~red~^
  10666. ~yellow~   W i d t h      ~red~^ T ~lightGray~= Turtle
  10667.  
  10668. ]] -- Build a rectangular structure
  10669.     info.sub[93] =
  10670. [[~yellow~Build a gable roof
  10671. Gable built on right side of turtle
  10672. Plan view       End view (width)
  10673.                      ~gray~+      gable top
  10674. ~yellow~L ~lightGray~|*|*|*|*|*|      ~gray~+ + +    gable end
  10675. ~yellow~e ~lightGray~|*| | | |*|    ~red~T~gray~ + + + +  gable end
  10676. ~yellow~n ~lightGray~|*| | | |*|   |*|*|*|*|*| top of wall
  10677. ~yellow~g ~lightGray~|*| | | |*|   |*|*|*|*|*|
  10678. ~yellow~t ~lightGray~|*| | | |*|   |*|*|*|*|*|
  10679. ~yellow~h ~lightGray~|~red~^~lightGray~|*|*|*|*|   |*|*|*|*|*|
  10680. ~yellow~  W i d t h     W i d t h   ~red~^T ~lightGray~= Turtle
  10681. ]] -- Build a gable end roof
  10682.     info.sub[94] =
  10683. [[~yellow~Build a pitched roof
  10684. Width ~red~MUST ~yellow~be ~red~<= ~yellow~Length eg ~red~4~yellow~ x 6
  10685. Plan view        End view (width)
  10686.  
  10687.                   ~red~T ~lightGray~on top of building
  10688. ~yellow~L ~lightGray~|*|*|*|*|      |*|*|*|*|
  10689. ~yellow~e ~lightGray~|*| | |*|      |*|*|*|*|
  10690. ~yellow~n ~lightGray~|*| | |*|      |*|*|*|*|
  10691. ~yellow~g ~lightGray~|*| | |*|      |*|*|*|*|
  10692. ~yellow~t ~lightGray~|*| | |*|
  10693. ~yellow~h ~lightGray~|~red~^~lightGray~|*|*|*|
  10694. ~yellow~  W i d t h     ~red~^ T ~lightGray~= Turtle
  10695. ]]-- Build a pitched roof
  10696.     info.sub[95] =
  10697. [[~yellow~Place me on suspended railway stone
  10698. Redstone torch will go below me
  10699.  
  10700. ~lightGray~_____
  10701. ~lightGray~|*|*|\                           ~red~>~lightGray~|*|
  10702.     |*|~red~<                       ~lightGray~/|*|
  10703.       ~lightGray~|*|______~red~T~lightGray~_________    /~lightGray~|*|~red~!
  10704.        ~red~!~lightGray~|*|*|*|*|*|*|*|*|\ /|*|
  10705.                ~red~!        ~lightGray~|*|*|
  10706.  
  10707. ~red~T < > ~lightGray~= Turtle ~red~! ~lightGray~= Redstone Torch
  10708. On block or above rail, face up slope
  10709. ]] -- Place redstone torch under block
  10710.     info.sub[96] = info.sub[95]
  10711.     info.sub[97] =
  10712. [[~yellow~Place me on last block before up/down
  10713.  
  10714. Build down            Build up~lightGray~
  10715.  
  10716. _____~red~T~lightGray~                        ___
  10717. |*|*|*|_                     _|*|
  10718.       |*|_                 _|*|
  10719.         |*|_             _|*|
  10720.           |*|__________~red~T~lightGray~|*|
  10721.             |*|*|*|*|*|*|      
  10722. ~red~T~lightGray~ = Turtle on block, not above rail
  10723. ]] -- build down
  10724.     info.sub[98] =  info.sub[97]
  10725.  
  10726. --Measurement tools
  10727.     info.sub[101] =
  10728. [[~yellow~Place me on floor.~lightGray~
  10729.             Measured Height:
  10730. |~lightBlue~*~lightGray~|*|*|*|   ~lightBlue~7. Overhead obstruction
  10731.             ~cyan~7. ~red~NOT ~cyan~detect() ~gray~7. Change~lightGray~
  10732.   |*|*|*|
  10733.   |*|*|*|
  10734.   |~lime~S~lightGray~|*|*|   ~lime~4. Specific block found~lightGray~
  10735.   |*|*|*|
  10736.   |*|*|*|
  10737.   |*|*|*|
  10738.  ~red~T~lightGray~|*|*|~red~T~lightGray~|   ~red~T~lightGray~ = Turtle
  10739. ]] -- measure height
  10740.     info.sub[102] =
  10741. [[~yellow~Depth measurement
  10742. Place me on the floor above pit / edge
  10743.  
  10744.     ~red~T~lightGray~
  10745. 1|*|*|
  10746. 2|*|*|
  10747. 3|*|*|
  10748. 4|*|*|         Measured depth:
  10749. 5|*|~lime~S~lightGray~|         ~lime~5. Specific block found
  10750. ~lightGray~6              ~cyan~6. ~red~NOT ~cyan~turtle.detect()~lightGray~
  10751. 7|*|*|~lightBlue~*~lightGray~|*| |   ~lightBlue~6. Obstruction below
  10752. ]] -- measure depth
  10753.     info.sub[103] =
  10754. [[~yellow~Length measurement
  10755.  
  10756. ~lightGray~1 2 3 4 ~lime~5~lightGray~ 6 ~lime~7 ~cyan~8 ~lightBlue~9~lightGray~ 10
  10757.                       ~cyan~8. No block up
  10758. ~lightGray~*|*|*|*|*|*|~lime~S~lightGray~| |*|*|  ~lime~7. Search block
  10759. ~red~T~lightGray~                |*|  ~lightBlue~9. Obstruction
  10760. ~lightGray~*|*|*|*|~lime~S~lightGray~|*|*| |*|*|  ~lime~5. Search block
  10761.                       ~cyan~8. No block down
  10762.  
  10763. ~red~T ~lightGray~= Turtle
  10764.  
  10765. ]] -- measure length
  10766.     info.sub[104] = info.sub[88] -- measure deepest section of water
  10767.     info.sub[105] =
  10768. [[~yellow~Place turtle anywhere:
  10769.  
  10770.  1. make a ~blue~borehole~yellow~ to chosen level.
  10771.  
  10772.  2. Write a report called:
  10773.  
  10774.  3. ~lime~borehole~blue~X~lime~.txt ~yellow~( ~blue~X ~yellow~= computer ID )
  10775.  
  10776.  4. ~orange~Return home
  10777.  
  10778. ]] -- Borehole: Analyse blocks below
  10779.     info.sub[110] =
  10780. [[~yellow~How many turtles?:
  10781.  
  10782. ~yellow~1.~lightGray~ Alternative positions for ~lime~2 ~lightGray~turtles
  10783. ~lightGray~| |~lime~1~lightGray~|~lime~2~lightGray~| |  |~lime~1~lightGray~| | |~lime~2~lightGray~| | | | | | ground 2
  10784. ~lightGray~|*|~blue~W|W~lightGray~|*|  |*|~blue~W|W~lightGray~|*| |*|~blue~1~lightGray~|~blue~2~lightGray~|*| water  2
  10785.  
  10786. ~yellow~2.~lightGray~ Alternative positions for ~orange~4 ~lightGray~turtles
  10787. ~lightGray~|~orange~1~lightGray~|~orange~2~lightGray~|~orange~3~lightGray~|~orange~4~lightGray~|                      ground 4
  10788. ~lightGray~|*|~blue~W|W~lightGray~|*|                      water  0
  10789.  
  10790. ~yellow~Enter 1 to use ~lime~2 ~yellow~turtles or 2 to use ~orange~4]]  -- initial menu for water canal
  10791.     local line = menu.clear()
  10792.     if menuLevel == 1 then -- general help
  10793.         line = menu.colourText(line, info.main[menuItem], true, true)
  10794.         term.write("Enter to continue ")
  10795.         read()
  10796.         return ""
  10797.     else -- item specific help
  10798.         if info.sub[menuItem] ~= nil then -- help file exists
  10799.             line = menu.colourText(line, info.sub[menuItem], true, true)
  10800.             if noMenu then
  10801.                
  10802.  
  10803.                 if getInteger then
  10804.                     return line -- ready for further input
  10805.                 else
  10806.                     term.setCursorPos(1, 13)
  10807.                     menu.enterToContinue()
  10808.                 end
  10809.             else
  10810.                 term.setCursorPos(1, 13)
  10811.                 term.write("Enter=exit, Any key + Enter=more ")
  10812.                 return read()
  10813.             end
  10814.         end
  10815.     end
  10816. end
  10817.  
  10818. local function getTaskOptions()
  10819.     local options = {}
  10820.     options.main =
  10821.     {
  10822.         "Mining (includes Nether)",
  10823.         "Forestry",
  10824.         "Farming",
  10825.         "Obsidian, Nether & End",
  10826.         "Canal, bridge and walkway",
  10827.         "Spawner farm tools",
  10828.         "Area shaping and clearing",
  10829.         "Lava and Water",
  10830.         "Building and minecart",
  10831.         "Measuring tools"
  10832.     }
  10833.     table.insert(options,
  10834.     {
  10835.         "Ladder up or down",
  10836.         "Stairs up or down",
  10837.         "Create mine at this level",
  10838.         "Safe drop to water block",
  10839.         "Single column bubble lift",
  10840.         "QuickMine corridor system",
  10841.         "QuickMine rectangle",
  10842.         "Mine bedrock level",
  10843.         "Rob disused mineshaft"
  10844.     })
  10845.     table.insert(options,
  10846.     {
  10847.         "Fell Tree",
  10848.         "Create tree farm",
  10849.         "Plant tree farm",
  10850.         "Harvest tree farm",
  10851.         "Fence or wall a forest",
  10852.         "Harvest and replant forest"
  10853.     })
  10854.     table.insert(options,
  10855.     {
  10856.         "Create modular crop farm",
  10857.         "Extend modular crop farm",
  10858.         "Plant, harvest or manage crop farm",
  10859.         "Build a wall or fence",
  10860.         "Fence or wall an enclosure"
  10861.     }) 
  10862.     table.insert(options,                  
  10863.     {
  10864.         "Dig obsidian field",
  10865.         "Build Nether Portal",
  10866.         "Demolish Nether Portal",
  10867.         "Stripmine Netherite",
  10868.         "Undermine Dragon Towers",
  10869.         "Deactivate Dragon Tower",
  10870.         "Build dragon water trap",
  10871.         "Build portal ladder & platform",
  10872.         "Shulker harvester"
  10873.     })
  10874.     table.insert(options,
  10875.     {
  10876.         "Simple path on air, water or lava",
  10877.         "Covered path or tunnel",
  10878.         "Water canal (mulitple options)",
  10879.         "Ice canal (multiple options)",
  10880.         "Platform",
  10881.         "Sinking platform",
  10882.         "Boat bubble lift",
  10883.     })
  10884.     table.insert(options,
  10885.     {
  10886.         "Cube around spawner (NOT blaze)",
  10887.         "Cube around Blaze spawner",
  10888.         "Flood mob farm floor",
  10889.         "Create mob bubble lift",
  10890.         "Computercraft mob grinder",
  10891.         "Build Endermen observation tower"
  10892.     })
  10893.     table.insert(options,
  10894.     {
  10895.         "Clear field (inc trees)",
  10896.         "Clear a rectangle (+ u/d opt)",
  10897.         "Clear single wall up/down",
  10898.         "Clear rectangular wall section",
  10899.         "Clear hollow structure up/down",
  10900.         "Clear solid structure up/down",
  10901.         "Dig a trench",
  10902.         "Carve mountain side",
  10903.         "Place a floor or ceiling",
  10904.         "Direct control of movement"
  10905.     })
  10906.     table.insert(options,
  10907.     {
  10908.         "Sand based utilities",
  10909.         "Vertical wall from surface",
  10910.         "Create enclosed area",
  10911.         "Clear volume of water",
  10912.         "Sinking platform",
  10913.         "Ocean monument utilities",
  10914.         "Ladder down to water/lava",
  10915.         "Clear water plants",
  10916.         "Convert all water to source",
  10917.         "Create sloping water"
  10918.     })
  10919.     table.insert(options,
  10920.     {
  10921.         "Build a wall",
  10922.         "Build a walled area / house",
  10923.         "Build a gable end roof",
  10924.         "Build a pitched roof",
  10925.         "Place Redstone:torch level track",
  10926.         "Place Redstone:torch upward track",
  10927.         "Build downward track",
  10928.         "Build upward track"
  10929.     })
  10930.     table.insert(options,
  10931.     {
  10932.         "Measure height",
  10933.         "Measure depth",
  10934.         "Measure length",
  10935.         "Measure greatest depth",
  10936.         "Borehole: Analyse blocks below"
  10937.     })
  10938.    
  10939.     return options
  10940. end
  10941.  
  10942. local function getTaskColours()
  10943.     local options = {}
  10944.     options.main =
  10945.     {
  10946.         colors.lightGray,   -- Mining (includes Nether)
  10947.         colors.lime,        -- Forestry
  10948.         colors.green,       -- Farming
  10949.         colors.red,         -- Obsidian, Nether & End Portal
  10950.         colors.brown,       -- Canal, bridge and walkway
  10951.         colors.lightGray,   -- Mob farm tools
  10952.         colors.orange,      -- Area shaping and clearing
  10953.         colors.blue,        -- Lava and Water
  10954.         colors.cyan,        -- Railway
  10955.         colors.purple       -- Measuring tools
  10956.     }
  10957.     table.insert(options,
  10958.     {
  10959.         colors.brown,       -- Ladder up or down
  10960.         colors.lightGray,   -- Stairs up or down
  10961.         colors.lightGray,   -- Create mine at this level
  10962.         colors.blue,        -- Safe drop to water block
  10963.         colors.blue,        -- Single column bubble lift
  10964.         colors.magenta,     -- QuickMine corridor system
  10965.         colors.pink,        -- QuickMine rectangle
  10966.         colors.gray,        -- Mine bedrock level
  10967.         colors.brown        -- Rob disused mineshaft
  10968.     })
  10969.     table.insert(options,
  10970.     {
  10971.         colors.brown,       -- Fell Tree
  10972.         colors.lightGray,   -- Create tree farm
  10973.         colors.lime,        -- Plant tree farm
  10974.         colors.green,       -- Harvest tree farm
  10975.         colors.brown,       -- Fence or wall an enclosure
  10976.         colors.lime         -- Harvest and replant forest
  10977.     })
  10978.     table.insert(options,
  10979.     {
  10980.         colors.yellow,      -- Create modular crop farm
  10981.         colors.green,       -- Extend modular crop farm
  10982.         colors.lime,        -- Manage modular crop farm
  10983.         colors.brown,       -- Build wall or fence
  10984.         colors.brown        -- Build rectangle wall or fence
  10985.     }) 
  10986.     table.insert(options,                  
  10987.     {
  10988.         colors.lightGray,   -- Dig obsidian field
  10989.         colors.purple,      -- Build Nether Portal
  10990.         colors.gray,        -- Demolish Nether Portal
  10991.         colors.red,         -- Netherite stripping
  10992.         colors.orange,      -- Undermine Dragon Towers
  10993.         colors.orange,      -- Deactivate Dragon Tower
  10994.         colors.blue,        -- Build dragon water trap
  10995.         colors.lightGray,   -- Build portal minecart station
  10996.         colors.red          -- Shulker harvesting
  10997.     })
  10998.     table.insert(options,
  10999.     {
  11000.         colors.lightGray,   -- Continuous path
  11001.         colors.gray,        -- Covered walkway / tunnel
  11002.         colors.blue,        -- Water canal
  11003.         colors.lightBlue,   -- Ice canal (4 options)
  11004.         colors.brown,       -- Platform
  11005.         colors.blue,        -- Sinking platform for oceans
  11006.         colors.cyan         -- Boat bubble lift
  11007.     })
  11008.     table.insert(options,
  11009.     {
  11010.         colors.brown,       -- Cube around spawner (NOT blaze)
  11011.         colors.red,         -- Cube around Blaze spawner
  11012.         colors.cyan,        -- Flood mob farm floor
  11013.         colors.blue,        -- Create mob bubble lift
  11014.         colors.brown,       -- Dig mob drop trench
  11015.         colors.gray         -- Build Endermen observation tower
  11016.     })
  11017.     table.insert(options,
  11018.     {
  11019.         colors.lime,        -- Clear field (inc trees)
  11020.         colors.magenta,     -- Clear a rectangle (+ u/d opt)
  11021.         colors.pink,        -- Clear single wall up/down
  11022.         colors.purple,      -- Clear rectangular wall section
  11023.         colors.brown,       -- Clear hollow structure up/down
  11024.         colors.orange,      -- Clear solid structure up/down
  11025.         colors.brown,       -- Dig a trench
  11026.         colors.gray,        -- Carve mountain side
  11027.         colors.lightBlue,   -- Place a floor or ceiling
  11028.         colors.red          -- Direct control of movement
  11029.     })
  11030.     table.insert(options,
  11031.     {
  11032.         colors.yellow,      -- Sand based utilities
  11033.         colors.blue,        -- Vertical wall from surface
  11034.         colors.blue,        -- Create enclosed area
  11035.         colors.cyan,        -- Clear volume of water
  11036.         colors.lightGray,   -- Sinking platform
  11037.         colors.orange,      -- Ocean monument utilities
  11038.         colors.brown,       -- Ladder down to water/lava
  11039.         colors.green,       -- Clear water plants
  11040.         colors.lightBlue,   -- Convert all water to source
  11041.         colors.blue         -- Create sloping water
  11042.     })
  11043.     table.insert(options,
  11044.     {
  11045.         colors.yellow,      -- build a wall
  11046.         colors.orange,      -- build rectangular structure
  11047.         colors.lightGray,   -- gable end roof
  11048.         colors.gray,        -- pitched roof
  11049.         colors.red,         -- Place Redstone:torch level track
  11050.         colors.red,         -- Place Redstone:torch upward track
  11051.         colors.orange,      -- Build downward track
  11052.         colors.brown        -- Build upward track
  11053.     })
  11054.     table.insert(options,
  11055.     {
  11056.         colors.red,         -- Measure height
  11057.         colors.purple,      -- Measure depth
  11058.         colors.magenta,     -- Measure length
  11059.         colors.pink,        -- Measure greatest depth
  11060.         colors.lightBlue    -- Borehole: Analyse blocks below
  11061.     })
  11062.    
  11063.     return options
  11064. end
  11065.  
  11066. local function chooseTask(R)
  11067. --[[
  11068.     called from main()
  11069.     R = chooseTask(R)
  11070.     coloured menu: 
  11071.     local pp =
  11072.     {
  11073.         prompt = colors.green,
  11074.         itemColours = {colors.white, colors.red, ... one for each item},
  11075.         menuPrompt = colors.yellow
  11076.     }
  11077.     choice, modifier = menu.menu or menu.new("Choose your option", options, pp)
  11078.     ]]
  11079.     local lib = {}
  11080.    
  11081.     function lib.getHelp(choice, itemsRequired, pp)
  11082.         local listOfItems = itemsRequired[choice]
  11083.         local result = getTaskHelp(2, choice)
  11084.         if result ~= "" then -- any key + enter = more
  11085.             lib.showItems(listOfItems)
  11086.         end
  11087.         T:clear()
  11088.         pp.itemColours = {colors.green, colors.yellow, colors.orange, colors.red}
  11089.         local options ={"Continue with selected task", "return to menu", "Return to main menu","Quit application"}
  11090.         local option = menu.menu("Choose your option", options, pp, "Type number + Enter ")
  11091.         if option == 2 then
  11092.             choice = -2 -- return to subMenu
  11093.         elseif option == 3 then
  11094.             choice = 0 -- return to main menu
  11095.         elseif option == 4 then
  11096.             choice = -1 -- quit
  11097.         -- else return original value of choice
  11098.         end
  11099.        
  11100.         return choice -- if R.choice reset to 0, then re-starts, -1 == quit
  11101.     end
  11102.    
  11103.     function lib.showItems(listOfItems)
  11104.         T:clear()
  11105.         if next(listOfItems) ~= nil then
  11106.             menu.colourPrint("Items required:", colors.lime)
  11107.             for k,v in pairs(listOfItems) do
  11108.                 menu.colourPrint("  "..v, colors.lightGray)
  11109.             end
  11110.         else
  11111.             menu.colourPrint("No items required", colors.lime)
  11112.         end
  11113.         menu.colourWrite("Enter to continue", colors.yellow, colors.black, nil, true)
  11114.         read()
  11115.     end
  11116.    
  11117.     function lib.getItemList(subChoice, itemsRequired)
  11118.         local listOfItems = itemsRequired[subChoice]
  11119.         lib.showItems(listOfItems)
  11120.     end
  11121.    
  11122.     function lib.getChoice(choice, subChoice)
  11123.         if subChoice > 9 then -- need more than 9 sub-options
  11124.             choice = subChoice + (choice * 100) -- 10 = 10 + 1000 = 1100
  11125.         else -- eg main option 1 (mining), sub-option 1 (create mine) = 1 + 10 = 11
  11126.             choice = subChoice + (choice * 10) -- 9 = 9 + 9 * 10 = 99, 1 + 10*10 = 101
  11127.         end
  11128.         return choice
  11129.     end
  11130.    
  11131.     local modifier = ""
  11132.     local subChoice = 0
  11133.     local prompt = "Choose an option"
  11134.     local mainPrompt = "Choose option (+h = help eg 3h):"
  11135.     local subPrompt = "Choose (+h = help +i = items eg 3h):"
  11136.     local options = getTaskOptions()
  11137.     local menuColours = getTaskColours()
  11138.     local itemsRequired = getTaskItemsList()
  11139.     local menuState = 0 -- use main menu
  11140.     -- local pp = utils.getPrettyPrint(colors.cyan, colors.magenta) -- specify menu title and prompt colours
  11141.     --local pp = utils.getPrettyPrint()-- uses default colours
  11142.    
  11143.     while menuState >= 0 do -- menuState has to be -1 to exit loop
  11144.         --[[
  11145.         menu returns choice=nil if user enters just q or h
  11146.         menu returns choice=2, modifier = "h" if 2h entered
  11147.         Mining (includes Nether)        white
  11148.         Forestry                        lime
  11149.         Farming                         lime
  11150.         Obsidian, Nether & End Portal   brown
  11151.         Canal, bridge and walkway       pink   
  11152.         Mob farm tools                  gray
  11153.         Area shaping and clearing       purple 
  11154.         Lava and Water                  blue
  11155.         Railway                         magenta
  11156.         Measuring tools                 cyan       
  11157.         ]]
  11158.        
  11159.         if menuState == 0 then
  11160.             pp.itemColours = menuColours.main
  11161.             local mainChoice, modifier = menu.menu(mainPrompt, options.main, pp) -- open main menu options
  11162.             if modifier == "q" then
  11163.                 R.choice = -1
  11164.                 return R -- quit application
  11165.             elseif modifier == "h" then -- get help on main menu items
  11166.                 getTaskHelp(1, mainChoice) -- "" or any return string for more
  11167.                 R.choice = 0
  11168.                 return R -- quit task system so it re-starts as help menu chosen R.choice = 0
  11169.             else
  11170.                 menuState = 1 -- next level so use sub-menu
  11171.                 R.choice = mainChoice -- 1-10
  11172.             end
  11173.         else
  11174.             pp.prompt = colors.yellow
  11175.             pp.itemColours = menuColours[R.choice]
  11176.             subChoice, modifier = menu.menu(subPrompt, options[R.choice], pp, "Back = 'q' or number + Enter: ") -- open submenu options
  11177.             if modifier == "q" then
  11178.                 R.choice = 0    -- return to root menu. change this to -1 if quit application preferred
  11179.                 return R -- quit task system so it re-starts first menu
  11180.             elseif modifier == "i" then -- get list of items
  11181.                 local index = lib.getChoice(R.choice, subChoice)
  11182.                 lib.getItemList(index, itemsRequired) -- list of items shown
  11183.                 subChoice = nil -- allow menu to continue
  11184.             elseif modifier == "h" then -- get help on main menu items
  11185.                 local index = lib.getChoice(R.choice, subChoice)
  11186.                 index = lib.getHelp(index, itemsRequired, pp)
  11187.                 --R = lib.getHelp(R, itemsRequired, pp) -- if R.choice reset to 0 then will continue
  11188.                 if index == -2 then -- redraw sub-menu
  11189.                     subChoice = nil -- allow menu to continue
  11190.                 elseif index == -1 then -- if R.choice reset to 0 then will continue
  11191.                     R.choice = -1
  11192.                     return R
  11193.                 elseif index == 0 then
  11194.                     R.choice = 0
  11195.                     menuState = 0 -- if R.choice reset to 0 then back to main menu
  11196.                 end
  11197.             end
  11198.             if subChoice ~= nil then
  11199.                 R.choice = lib.getChoice(R.choice, subChoice)
  11200.                 return R -- exit loop
  11201.             end
  11202.         end
  11203.     end
  11204.     return R
  11205. end
  11206.  
  11207. local function getTask(R)
  11208.     -- Called from main(): R = getTask(R)
  11209.     local lib = {}
  11210.    
  11211.     function lib.isAutoHelp(choice, noAutoHelp)
  11212.         for _, v in ipairs(noAutoHelp) do
  11213.             if choice == v then
  11214.                 return true
  11215.             end
  11216.         end
  11217.         return false
  11218.     end
  11219.    
  11220.     local prompt = "Choose an option"
  11221.     local noAutoHelp = {24, 47, 49, 53, 54, 81, 85}
  11222.     if not lib.isAutoHelp(R.choice, noAutoHelp) then -- exclude Water canal, ice canal, sand utilities, monument utilities, dragon trap
  11223.         getTaskHelp(2, R.choice, true)
  11224.         menu.clear()
  11225.     end
  11226. -- 01. MINING
  11227.     if R.choice >= 11 and  R.choice <= 13 then  -- createLadder, createStaircase, createMine)
  11228.         --getTaskHelp(2, R.choice, true)
  11229.         --menu.clear()
  11230.     elseif R.choice == 14 then  -- safe drop to water
  11231.         local currentLevel = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.lightGray)
  11232.         local destLevel = menu.getInteger("Go down to level? ("..currentLevel - 2 .." to "..bedrock + 5 ..")", bedrock + 5 , currentLevel - 2, nil, colors.blue, nil, bedrock + 5)
  11233.         R.height    = math.abs(destLevel - currentLevel)
  11234.     elseif R.choice == 15 then  -- bubble lift
  11235.         local currentLevel = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5 , ceiling, nil, colors.blue, nil, bedrock + 5)
  11236.         local destLevel = menu.getInteger("Go up to level? ("..currentLevel + 2 .." to "..ceiling ..") ", currentLevel + 2, ceiling, nil, colors.lightGray)
  11237.         --[[if currentLevel <= bedrock + 5 then
  11238.             if menu.getBoolean("Confirm close to bedrock (y / n) ", nil, colors.yellow, colors.black) then
  11239.                 R.data = "bedrock"
  11240.             end
  11241.         end]]
  11242.         R.height    = math.abs(destLevel - currentLevel)
  11243.     elseif R.choice == 16 then -- create mining corridor system default: square 17 x 17
  11244.         local choices = {"At corridor start, on the floor",
  11245.                          "At corridor start, on the ceiling",
  11246.                          "On floor, move forward to start",
  11247.                          "On ceiling, move forward to start"}
  11248.         pp.itemColours = {colors.lime, colors.green, colors.magenta, colors.pink}
  11249.         local userChoice, modifier = menu.menu("Starting position?", choices, pp, "Type number + Enter ") -- 1 to 4
  11250.         if modifier == "q" then -- quit chosen
  11251.             R.data = "quit"
  11252.             return R
  11253.         end
  11254.         R.width     = menu.getInteger("Width (2-64 default 17) ", 2, 64, nil, colors.yellow, nil, 17)
  11255.         R.length    = menu.getInteger("Length (2-64 default 17) ", 2, 64, nil, colors.orange, nil, 17)
  11256.         R.torchInterval = 9 -- 8 spaces between torches
  11257.         if mcMajorVersion >= 1.18 then
  11258.             R.torchInterval = 17 -- 16 spaces between torches
  11259.         end
  11260.         R.subChoice = userChoice
  11261.     elseif R.choice == 17 then -- clear a rectangle, fill empty spaces above
  11262.         local choices = {"At mine area start, on the floor",
  11263.                          "At mine area start, on the ceiling",
  11264.                          "On floor, move forward to start",
  11265.                          "On ceiling, move forward to start",
  11266.                          "On floor diagonally to left"} -- just finished corridor
  11267.         pp.itemColours = {colors.lime, colors.green, colors.magenta, colors.pink, colors.red}
  11268.         local userChoice, modifier = menu.menu("Starting position?", choices, pp, "Type number + Enter ") -- 1 to 4
  11269.         if modifier == "q" then -- quit chosen
  11270.             R.data = "quit"
  11271.             return R
  11272.         end
  11273.         R.width     = menu.getInteger("Width (2-64 default 15) ", 2, 64, nil, colors.yellow, nil, 15)
  11274.         R.length    = menu.getInteger("Length (2-64 default 15) ", 2, 64, nil, colors.orange, nil, 15)
  11275.         R.subChoice = userChoice
  11276.     elseif R.choice == 18 then -- Mine bedrock area
  11277.         --getTaskHelp(2, R.choice, true)
  11278.         --menu.clear()
  11279.         R.width     = menu.getInteger("Width (2-64 default 17) ", 2, 64, nil, colors.yellow, nil,  17)
  11280.         R.length    = menu.getInteger("Length (2-64 default 17) ", 2, 64, nil, colors.orange, nil,  17)
  11281.         if menu.getBoolean("Leave bedrock exposed? (y/n) ", nil, colors.yellow) then
  11282.             R.data = "leaveExposed"
  11283.         end
  11284.     elseif R.choice == 19 then -- salvage mine shaft
  11285.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11286. -- 02. FORESTRY
  11287.     elseif R.choice == 22 then --Create treefarm
  11288.         R.width = 15
  11289.         R.length = 15
  11290.         pp.itemColours = {colors.lightGray, colors.green}
  11291.         choices = {"New tree farm. Start here", "On right side of existing farm" }
  11292.         local choice = menu.menu(prompt, choices, pp, "Type number + Enter ")
  11293.         if choice == 2 then
  11294.             R.data = "existing"
  11295.         end
  11296.         R.up = menu.getBoolean({"Any blocks/trees above current level","in a 15 x 15 block area (y/n) "}, nil, {colors.yellow, colors.orange}, colors.black)
  11297.     elseif R.choice == 23 then -- plant treefarm
  11298.         local choices   = {"16 single trees", "4 double trees any type"}
  11299.         pp.itemColours = {colors.lime, colors.green}
  11300.         R.subChoice = menu.menu(prompt, choices, pp, "Type number + Enter ")
  11301.     --elseif R.choice == 24 then -- Harvest treefarm
  11302.    
  11303.     elseif R.choice == 25 then -- Build wall or fence
  11304.         R.width     = menu.getInteger("Width of the area (1-64)", 1, 64, nil, colors.yellow)
  11305.         R.length    = menu.getInteger("Length of the area (1-64)", 1, 64, nil, colors.orange)
  11306.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11307.         if menu.getBoolean("Storage barrels in corners? (y/n)", nil, colors.brown) then
  11308.             R.data = "barrel"
  11309.         end
  11310.     elseif R.choice == 26 then -- Harvest and replant natural forest
  11311.  
  11312.        
  11313. -- 03. FARMING
  11314.     elseif R.choice == 31 then -- new crop farm
  11315.  
  11316.     elseif R.choice == 32 then -- extend crop farm
  11317.         local choices   = {"Add a farm at the back", "Add a farm to the right"}
  11318.         pp.itemColours = {colors.lime, colors.green}
  11319.         R.subChoice = menu.menu(prompt, choices, pp, "Type number + Enter ")
  11320.     elseif R.choice == 33 then -- manage crop farm
  11321.  
  11322.     elseif R.choice == 34 then -- fence or wall
  11323.         R.length    = menu.getInteger("Length of wall / fence (1-256)", 1, 256, nil, colors.orange)
  11324.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11325.     elseif R.choice == 35 then -- rectangle fence or wall
  11326.         R.width     = menu.getInteger("Width of the area (1-64)", 1, 64, nil, colors.yellow)
  11327.         R.length    = menu.getInteger("Length of the area (1-64)", 1, 64, nil, colors.orange)
  11328.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11329.    
  11330. -- 04. OBSIDIAN
  11331.     elseif R.choice == 41 then  -- Harvest obsidian
  11332.         R.width     = menu.getInteger("Width of the area (1-64) ", 1, 64, nil, colors.yellow)
  11333.         R.length    = menu.getInteger("Length of the area (1-64) ", 1, 64, nil, colors.orange)
  11334.     elseif R.choice == 42 or R.choice == 43 then -- build Nether portal / demolish Nether portal
  11335.         local choices = {"Facing portal: forward, turn right",
  11336.                          "Aligned with portal: start ahead"}
  11337.         pp.itemColours = {colors.pink, colors.red}
  11338.         local userChoice, modifier = menu.menu("Starting position?", choices, pp, "Type number + Enter ") -- 1 to 2
  11339.         R.subChoice = userChoice
  11340.         if modifier == "q" then -- quit chosen
  11341.             R.data = "quit"
  11342.             return R
  11343.         end
  11344.         R.length    = menu.getInteger("Portal width", 1, 64, nil, colors.yellow, nil, 4)
  11345.         R.height    = menu.getInteger("Portal height (inc. buried base)", 1, 64, nil, colors.lightGray, nil, 5)
  11346.         R.width     = menu.getInteger("Thickness (Usually 1) Enter = 1)", 1, 64, nil, colors.red, nil, 1)
  11347.         if menu.getBoolean("Base below surface (y/n)", nil, colors.orange) then
  11348.             R.data = "bury"
  11349.         end
  11350.     elseif R.choice == 44 then -- Netherite stripping
  11351.         R.width     = 1
  11352.         while R.length == 0 or R.length % 16 > 0 do
  11353.             R.length = menu.getInteger("Strip length (divisible by 16) ", 16, 512, 1, colors.orange)
  11354.             if R.length % 16 > 0 then
  11355.                 menu.colourText(1, "~red~Must be multiple of 16")
  11356.             end
  11357.         end
  11358.         R.torchInterval = 16
  11359.         R.data = "seal"
  11360.     elseif R.choice == 45 then -- undermine dragon towers
  11361.  
  11362.     elseif R.choice == 46 then -- deactivate dragon tower
  11363.    
  11364.     elseif R.choice == 47 then -- build dragon water trap
  11365.         local text =
  11366. [[~yellow~You ~red~MUST ~yellow~have already constructed a
  11367. bridge / tunnel into the dragon island
  11368. to allow for safe construction of the
  11369. dragon trap.
  11370.  
  11371. If not use toolkit:
  11372.   ~brown~5.~gray~2 Covered path or tunnel~yellow~ length 100
  11373.  
  11374. start centre of obsidian platform:
  11375.   100,49,0 facing west]]
  11376.         menu.colourText(1, text)
  11377.         if menu.getBoolean("Bridge already made? (y/n)", 12, colors.orange) then
  11378.             getTaskHelp(2, R.choice, true)
  11379.             menu.clear()
  11380.         else
  11381.             R.data = "quit"
  11382.             return R
  11383.         end
  11384.     elseif R.choice == 48 then -- build end portal minecart station
  11385.     elseif R.choice == 49 then -- Shulker harvesting
  11386.         local items =
  11387.         {
  11388.             "Shulker is above",
  11389.             "Shulker is ahead",
  11390.             "Shulker is below",
  11391.             "Climb tower wall",
  11392.             "Clear roof above",
  11393.             "Clear outside walls"
  11394.         }
  11395.         pp.itemColours = {colors.lightGray, colors.brown, colors.blue, colors.yellow, colors.orange, colors.lightGray}
  11396.         R.subChoice = menu.menu("Which utility? ", items, pp)
  11397.         getTaskHelp(2, R.choice * 10 + R.subChoice, true)  -- eg 490 + 1 = 491
  11398.         menu.clear()   
  11399.        
  11400. -- 05. CANAL BRIDGE
  11401.     elseif R.choice == 51 then  --single path
  11402.         if menu.getBoolean("Shorten an existing path? (y/n)", nil, colors.brown) then
  11403.             R.data = "reduce"
  11404.         end
  11405.         if R.data == "reduce" then
  11406.             R.length = menu.getInteger("Reduce by? 0 = here to end", 0, 1024, nil, colors.orange, nil, 64)
  11407.         else
  11408.             R.length = menu.getInteger("Path length? 0 = continuous ", 0, 1024, nil, colors.orange, nil, 64)
  11409.             R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, line, colors.red, nil, 0)
  11410.         end
  11411.     elseif R.choice == 52 then  -- 2 block corridor / covered walkway
  11412.         R.length    = menu.getInteger("Corridor length?", 1, 1024, nil, colors.orange, nil, 64)
  11413.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11414.         if menu.getBoolean("Seal off water or lava? (y/n)", nil, colors.brown) then
  11415.             R.data = "seal"
  11416.         end
  11417.     elseif R.choice == 53 then  --left/right side of new/existing canal
  11418.         local line = getTaskHelp(2, 110, true, true) -- request line no of help display if needed for getInteger
  11419.         R.data = menu.getInteger("Choose method 1 or 2", 1, 2, line + 1, colors.white)  -- 2 or 4 turtles
  11420.         menu.clear()
  11421.         line = getTaskHelp(2, R.choice, true, true) -- request line no of help display if needed for getInteger
  11422.         R.subChoice = menu.getInteger("Type position of this turtle", 1, 6, line + 1, colors.white)
  11423.         local position = "on ground"
  11424.         local side = "left"
  11425.         local colour = colors.lime
  11426.         if R.subChoice == 1 then
  11427.             R.side = "L"
  11428.             R.height = 1
  11429.             position = "on ground"
  11430.             colour = colors.lime
  11431.         elseif R.subChoice == 2 then
  11432.             R.side = "L"
  11433.             R.height = 1
  11434.             position = "above canal"
  11435.             colour = colors.orange
  11436.         elseif R.subChoice == 3 then
  11437.             R.side = "R"
  11438.             side = "right"
  11439.             R.height = 1
  11440.             position = "above canal"
  11441.             colour = colors.brown
  11442.         elseif R.subChoice == 4 then
  11443.             R.side = "R"
  11444.             side = "right"
  11445.             R.height = 1
  11446.             colour = colors.green
  11447.         elseif R.subChoice == 5 then
  11448.             R.side = "L"
  11449.             R.height = 0
  11450.             position = "on canal base"
  11451.             colour = colors.blue
  11452.         elseif R.subChoice == 6 then
  11453.             R.side = "R"
  11454.             side = "right"
  11455.             R.height = 0
  11456.             position = "on canal base"
  11457.             colour = colors.cyan
  11458.         end
  11459.         line = menu.clear()
  11460.         if R.data == 1 or (R.data == 2 and (R.subChoice == 1 or R.subChoice == 4)) then
  11461.             R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, line, colors.red, nil, 0)
  11462.         end
  11463.         -- menu.colourPrint(text, fg, bg, width)
  11464.         -- menu.colourText(row, text, reset)
  11465.         menu.colourPrint("Turtle placed "..side.." "..position, colour)
  11466.         R.length    = menu.getInteger("Canal length? 0 = continuous ", 0, 512, line + 2, colors.orange, nil, 64)
  11467.     elseif R.choice == 54 then  --ice canal 4 sections: edge+torch, edge, centre+ice, centre no ice
  11468.         local line = getTaskHelp(2, R.choice, true, true) -- request line no of help display if needed for getInteger
  11469.         R.subChoice = menu.getInteger("Type turtle position", 1, 8, line, colors.white)
  11470.         R.side = "L"
  11471.         local position = "on towpath"
  11472.         local side = "left"
  11473.         local colour = colors.lime
  11474.         line = menu.clear()
  11475.         --[[
  11476.             new canal
  11477.             1 = left towpath- move to centre left
  11478.             2 = centre left ice or hollow
  11479.             3 = centre right ice or hollow
  11480.             4 = right side - move to centre right
  11481.             convert water canal
  11482.             5 = left towpath
  11483.             6 = centre left ice or air
  11484.             7 = centre right ice or air
  11485.             8 = right towpath
  11486.         ]]
  11487.         if R.subChoice == 1 or R.subChoice == 4 or R.subChoice == 5 or R.subChoice == 8 then
  11488.             -- on towpath r/l
  11489.             R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, line, colors.red, nil, 0)
  11490.             if R.subChoice == 4 or R.subChoice == 8 then
  11491.                 side = "right"
  11492.                 R.side = "R"
  11493.             end
  11494.             if R.subChoice <= 4 then -- 1 or 4 only
  11495.                 if menu.getBoolean("Place Ice as well? (y/n)", line + 1, colors.blue) then
  11496.                     R.data = "ice"
  11497.                 end
  11498.             end
  11499.         else -- on canal centre r/l
  11500.             if R.subChoice == 3 or R.subChoice == 7 then
  11501.                 side = "right"
  11502.                 R.side = "R"
  11503.             end
  11504.             if R.subChoice == 2 or R.subChoice == 3 then -- new canal
  11505.                 R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, line, colors.red, nil, 0)
  11506.                 position = "above air/ice"
  11507.             end
  11508.             if menu.getBoolean("Place Ice as well? (y/n)", line + 1, colors.blue) then
  11509.                 R.data = "ice"
  11510.                 if R.subChoice == 6 or R.subChoice == 7 then   
  11511.                     position = "alternate air/ice"
  11512.                     colour = colors.lightBlue
  11513.                 end
  11514.             else
  11515.                 if R.subChoice == 6 or R.subChoice == 7 then   
  11516.                     position = "on air spaces"
  11517.                     colour = colors.lighGray
  11518.                     if R.subChoice == 7 then
  11519.                         side = "right"
  11520.                         R.side = "R"
  11521.                     end
  11522.                 end
  11523.             end
  11524.         end
  11525.         R.length    = menu.getInteger("Canal length? 0 = continuous ", 0, 1024, line + 2, colors.orange, nil, 64)
  11526.         menu.colourPrint("Turtle on "..side.." side "..position, colour)
  11527.         sleep(2)
  11528.     elseif R.choice == 55 then  --platform
  11529.         R.width     = menu.getInteger("Platform width", 1, 256, 1, colors.yellow)
  11530.         R.length    = menu.getInteger("Platform length", 1, 256, 2, colors.orange)
  11531.         if menu.getBoolean("Remove blocks above? (y/n)",3, colours.red) then
  11532.             R.up = true
  11533.         end
  11534.        
  11535.     elseif R.choice == 56 then  --sinking platform
  11536.         R.width     = menu.getInteger("Width (excluding retaining wall)? ", 1, 1024, nil, colors.yellow)
  11537.         R.length    = menu.getInteger("Length (excluding retaining wall)? ", 1, 1024 / R.width, nil, colors.orange)
  11538.         R.height    = menu.getInteger("Levels to go down?", 1, 1024 / R.width * R.length, nil, colors.blue)
  11539.     elseif R.choice == 57 then  --boat bubble lift
  11540.         R.height    = menu.getInteger("Levels to go up?", 1, ceiling - 2, nil, colors.lightBlue)
  11541.        
  11542. -- 06. MOB SPAWNER TOOLS
  11543.     elseif R.choice == 61 then -- create cube round mob spawner
  11544.         local text =
  11545. [[~yellow~Turtle placement options:
  11546.  
  11547. ~lime~1. On top or in front of the spawner
  11548.    ~green~(cave spider OR no chests around)
  11549. ~lightGray~2. Outside the dungeon at floor or
  11550.    ceiling level ~red~1 block from corner
  11551. ~yellow~Make sure you have access to the block
  11552. facing the spawner, as any chests
  11553. found inside will be placed outside
  11554. the new dungeon wall at this height
  11555.  
  11556. ~white~Enter to continue
  11557. ]]
  11558.         menu.colourText(nil, text, true)
  11559.         read()
  11560.         menu.clear()
  11561.         R.data = "spawner"
  11562.         if menu.getBoolean("Any chests around spawner? (y/n)",1, colours.red) then
  11563.             R.data = "chest"
  11564.         end
  11565.         local choices = {"Turtle on spawner (no chests)",
  11566.                          "Outside wall: left side, floor",
  11567.                          "Outside wall: left side, ceiling",
  11568.                          "Outside wall: right side, floor",
  11569.                          "Outside wall: right side, ceiling"}
  11570.         pp.itemColours = {colors.red, colors.lime, colors.orange, colors.green, colors.yellow}
  11571.         local userChoice, modifier = menu.new("Select turtle position", choices, pp) -- 1 to 5
  11572.        
  11573.         if modifier == "q" then -- quit chosen
  11574.             R.data = "quit"
  11575.             return R
  11576.         end
  11577.         R.subChoice     = userChoice
  11578.         if R.subChoice > 1 then -- get dungeon wall dimensions
  11579.             R.width     = menu.getInteger("Dungeon external width ", 0, 11, nil, colors.yellow, nil, 11)
  11580.             R.length    = menu.getInteger("Dungeon external length ", 0, 11, nil, colors.orange, nil, 11)
  11581.         end
  11582.        
  11583.     elseif R.choice == 62 then -- Blaze spawner
  11584.         local text =
  11585. [[~yellow~Turtle placement options:
  11586.  
  11587. ~red~1a On top of the spawner
  11588.  
  11589. ~red~1b ~orange~At the same level in direct line of
  11590. spawner.~yellow~ (can be behind a safety wall)
  11591.  
  11592. ~red~1c~lightGray~ Room below spawner (via stairs)
  11593.  
  11594. ~lime~2 Finish build: In brick floor outside
  11595.   existing cube. (facing player)
  11596.  
  11597. ~white~Enter to continue]]
  11598.         menu.colourText(nil, text, true)
  11599.         read()
  11600.         pp.itemColours = {colors.red, colors.lime}
  11601.         R.subChoice = menu.new("Choose your option", {"New Blaze spawner", "Complete part build (killzone)"}, pp, "Type number + Enter") -- 1 = new, 2= continue
  11602.         R.data = "blaze"            -- default
  11603.         if R.subChoice == 1 then    -- new blaze spawner
  11604.             text =
  11605. [[~yellow~Turtle placement options:
  11606. ~red~1. On top of the spawner
  11607. ~orange~2. In direct sight (safety wall ok)
  11608. ~lightGray~3. Room below spawner (via stairs)
  11609.    |*|*|*|*|*|   Ceiling
  11610.    |*|*|~red~T~lightGray~|*|*|   Turtle under ceiling
  11611.    |*|~brown~+~lightGray~|*|~brown~+~lightGray~|*|   Top of fence
  11612.    |*|~brown~+~lightGray~|*|~brown~+~lightGray~|*|
  11613.    |*|~brown~+~lightGray~|*|~brown~+~lightGray~|*|   Bottom of fence
  11614.    |*|*|*|*|*|   Floor level]]
  11615.             --R.subChoice = menu.new("Choose your position", {"On top of spawner", "In direct sight (safety wall ok)", "Room below spawner"}, pp, "Type number + Enter")
  11616.             --getInteger(prompt, minValue, maxValue, row, fg, bg, default)
  11617.             T:clear()
  11618.             menu.colourText(nil, text, true)
  11619.             R.subChoice = menu.getInteger("Enter position number", 1, 3, 12, colors.white)
  11620.         else
  11621.             R.data = "restart"      -- complete part build
  11622.         end
  11623.     elseif R.choice == 63 then -- flood spawner cube
  11624.         local choices = {"Bubble lift", "Computercraft mob softener"}
  11625.         pp.itemColours = {colors.lime, colors.orange}
  11626.         local userChoice = menu.menu("Flood for Mob grinder type?", choices, pp, "Type number + Enter ")
  11627.         R.subChoice = userChoice -- 1 bubble, 2 computercraft
  11628.     elseif R.choice == 64 then -- create bubble lift at mob spawner
  11629.         local choices = {"Dropzone on left", "Dropzone on right"}
  11630.         pp.itemColours = {colors.lime, colors.orange}
  11631.         local userChoice = menu.menu("Which side do you want the mobs?", choices, pp, "Type number + Enter")
  11632.         R.subChoice = userChoice -- 1 left, 2 right
  11633.     elseif R.choice == 65 then -- Computercraft mob grinder
  11634.         local choices = {"Use Sticky pistons", "Use non-sticky pistons"}
  11635.         pp.itemColours = {colors.lime, colors.orange}
  11636.         local userChoice = menu.menu("Which type of pistons?", choices, pp, "Type number + Enter ")
  11637.         R.subChoice = userChoice -- 1 sticky, 2 normal
  11638.    
  11639. -- 07. AREA CARVING
  11640.     elseif R.choice == 71 then --Clear field
  11641.         R.width     = menu.getInteger("Width of the area (1-64)", 1, 64, nil, colors.yellow)
  11642.         R.length    = menu.getInteger("Length of the area (1-64)", 1, 64, nil, colors.orange)
  11643.         if menu.getBoolean("Dirt on the surface (y/n)", nil, colors.brown) then
  11644.             R.useBlockType = "dirt"
  11645.         end
  11646.     elseif R.choice == 72 then -- Clear solid rectangle R.width, R.length
  11647.         R.width     = menu.getInteger("Rectangle width (1-256)", 1, 256, nil, colors.yellow)
  11648.         R.length    = menu.getInteger("Rectangle length (1-256)", 1, 256, nil, colors.orange)
  11649.         R.up        = menu.getBoolean("Remove blocks above?", nil, colors.yellow)
  11650.         R.down      = menu.getBoolean("Remove blocks below?", nil, colors.orange)
  11651.         if menu.getBoolean("Am I outside clearing zone (y/n)?", nil, colors.yellow) then
  11652.             T:forward(1)
  11653.         end
  11654.     elseif R.choice == 73 then -- Clear wall
  11655.         R.width     = 1
  11656.         R.length    = menu.getInteger("Length of wall (1-256) ", 1, 256, nil, colors.orange)
  11657.         R.height    = menu.getInteger("Height of wall (1-50) ", 1, 50, nil, colors.lightGray)
  11658.         pp.itemColours = {colors.lime, colors.orange}
  11659.         R.subChoice = menu.menu("Which direction?", {"Bottom -> Top", "Top -> Bottom"}, pp, "Type number + Enter ") -- open direction menu options
  11660.         if R.subChoice == 1 then
  11661.             if menu.getBoolean("Am I outside clearing zone (y/n)?", nil, colors.yellow) then
  11662.                 T:forward(1)
  11663.             end
  11664.         else
  11665.             pp.itemColours = {colors.lightBlue, colors.cyan, colors.blue, colors.gray}
  11666.             local choice = menu.menu("Exact position?", {"On top of clearing zone", "In front of clearing zone", "Inside clearing zone","Above AND outside"}, pp, "Type number + Enter ")
  11667.             if choice == 1 then
  11668.                 T:down(1)
  11669.             elseif choice == 2 then
  11670.                 T:forward(1)
  11671.             elseif choice == 4 then
  11672.                 T:go("D1F1")
  11673.             end
  11674.         end
  11675.     elseif R.choice == 74 then -- Clear rectangle perimeter only R.width, R.length
  11676.         R.width     = menu.getInteger("Perimeter width (1-256) ", 1, 256, nil, colors.yellow)
  11677.         R.length    = menu.getInteger("Perimeter length (1-256) ", 1, 256, nil, colors.orange)
  11678.         R.height    = 1
  11679.         if menu.getBoolean("Remove blocks above? (y/n)", 3, colours.red) then
  11680.             R.up = true
  11681.         end
  11682.         if menu.getBoolean("Remove blocks below? (y/n)", 4, colours.red) then
  11683.             R.down = true
  11684.         end
  11685.         if menu.getBoolean("Am I outside clearing zone (y/n)?", 5, colors.yellow) then
  11686.             T:forward(1)
  11687.         end
  11688.     elseif R.choice == 75 or R.choice == 76 then -- Clear hollow building floor/walls/ceiling OR clear solid object
  11689.         R.width     = menu.getInteger("Structure width (1-256)", 1, 256, nil, colors.yellow)
  11690.         R.length    = menu.getInteger("Structure length (1-256)", 1, 256, nil, colors.orange)
  11691.         R.height    = menu.getInteger("Depth/Height (1-256)", 1, 256, nil, colors.lightGray)
  11692.         if R.choice == 75 then -- hollow building so need to check if floors/ceilings to be removed
  11693.             R.data = {}
  11694.             R.data.ceiling = false
  11695.             R.data.floor = false
  11696.             if menu.getBoolean("Remove ceiling? (y/n)", nil, colors.yellow, colors.black) then
  11697.                 R.data.ceiling = true
  11698.             end
  11699.             if menu.getBoolean("Remove floor? (y/n)", nil, colors.orange, colors.black) then
  11700.                 R.data.floor = true
  11701.             end
  11702.         end
  11703.         pp.itemColours = {colors.lime, colors.orange}
  11704.         R.subChoice = menu.menu("Which direction?", {"Bottom -> Top", "Top -> Bottom"}, pp, "Type number + Enter ") -- open direction menu options
  11705.         if R.subChoice == 1 then
  11706.             if menu.getBoolean("Am I outside clearing zone (y/n)?", nil, colors.yellow) then
  11707.                 T:forward(1)
  11708.             end
  11709.         else
  11710.             pp.itemColours = {colors.lightBlue, colors.cyan, colors.blue, colors.gray}
  11711.             local choice = menu.menu("Exact position?", {"On top of clearing zone", "Outside clearing zone", "Inside clearing zone","Above AND outside"}, pp, "Type number + Enter ")
  11712.             if choice == 1 then
  11713.                 T:down(1)
  11714.             elseif choice == 2 then
  11715.                 T:forward(1)
  11716.             elseif choice == 4 then
  11717.                 T:go("D1F1")
  11718.             end
  11719.         end
  11720.     elseif R.choice == 77 then  -- Dig a trench
  11721.         R.height    = menu.getInteger("Depth of the trench (1-64) ", 1, 64, nil, colors.blue)
  11722.         R.length    = menu.getInteger("Trench length? 0 = continuous ", 0, 1024, nil, colors.orange)
  11723.     elseif R.choice == 78 then  -- Carve side of mountain
  11724.         pp.itemColours = {colors.lime, colors.orange}
  11725.         R.subChoice = menu.menu("Remove blocks on which side?", {"Left", "Right"}, pp, "Type number + Enter ") -- open direction menu options
  11726.         R.width     = menu.getInteger("Remove how many vertical rows? ", 1, 1024, nil, colors.yellow)
  11727.         R.length    = menu.getInteger({"Max length of each row?"," - Prevents cutting too wide","1 to 255 default 64"}, 1, 255, nil, {colors.orange, colors.red, colors.white}, colors.black, 64)
  11728.     elseif R.choice == 79 then  -- Place a floor or ceiling
  11729.         local items = { "Replacing current floor",
  11730.                         "New floor over existing",
  11731.                         "Replacing current ceiling",
  11732.                         "New ceiling under existing"}
  11733.         pp.itemColours = {colors.lime, colors.orange, colors.green, colors.yellow}
  11734.         R.subChoice = menu.menu("Laying what?", items, pp, "Type number + Enter ")
  11735.         R.height = menu.getInteger({"Enter 0 for on-site placement",
  11736.                                     "If in deep water or above reach",
  11737.                                     "Enter approx depth/height"}, 0, 64, nil, {colors.yellow, colors.blue, colors.cyan} )
  11738.         if R.subChoice < 3 then
  11739.             R.down = true
  11740.             R.width     = menu.getInteger("Width of floor (1-64) ", 1, 64, nil, colors.yellow)
  11741.             R.length    = menu.getInteger("Length of floor (1-64) ", 1, 64, nil, colors.orange)
  11742.         else
  11743.             R.up = true
  11744.             R.width     = menu.getInteger("Width of ceiling (1-64) ", 1, 64, nil, colors.yellow)
  11745.             R.length    = menu.getInteger("Length of ceiling (1-64) ", 1, 64, nil, colors.orange)
  11746.         end
  11747.     elseif R.choice == 710 or R.choice == 83 then -- Direct movement
  11748.         local choices = {"Simple path", "Covered 2 block high path"}
  11749.         pp.itemColours = {colors.lime, colors.orange}
  11750.         local userChoice = menu.menu("Choose your path option", choices, pp, "Type number + Enter ")
  11751.         R.subChoice = userChoice -- 1 open, 2 covered
  11752.         choices = {"Command driven", "Menu driven"}
  11753.         userChoice = menu.menu("Choose your preference", choices, pp, "Type number + Enter ")
  11754.         if userChoice == 1 then
  11755.             R.data = "cmd"
  11756.         else
  11757.             R.data = "menu"
  11758.         end
  11759.        
  11760. -- 08. WATER LAVA
  11761.     elseif R.choice == 81 then -- Sand based utilities
  11762.         local line = getTaskHelp(2, R.choice, true, true) -- request line no of help display if needed for getInteger
  11763.         R.subChoice = menu.getInteger("Type number of choice", 1, 4, line, colors.white)
  11764.         T:clear()
  11765.         if R.subChoice == 1 then -- drop sand into water or lava surface until solid ground reached
  11766.             R.width   = 1
  11767.             R.length  = menu.getInteger("Length of sand wall (0=to block) ", 0, 60, nil, colors.orange)
  11768.         elseif R.subChoice == 2 then    -- clear rectangle on top of building and fill with sand
  11769.             R.width   = menu.getInteger("Width of area (<=30) ", 1, 30, nil, colors.yellow)
  11770.             R.length  = menu.getInteger("Length of of area (<=30) ", 1, 30, nil, colors.orange)
  11771.         elseif R.subChoice == 3 then    -- clear sand wall or harvest sand
  11772.             R.width   = 1
  11773.             R.length  = menu.getInteger("Length of sand (0=auto-detect)", 0, 60, nil, colors.orange)
  11774.             choices = {"Stay at end of wall", "Return home"}
  11775.             pp.itemColours = {colors.lime, colors.orange}
  11776.             userChoice = menu.menu("Choose your preference", choices, pp, "Type number + Enter ")
  11777.             if userChoice == 2 then
  11778.                 R.data = "return"
  11779.             end
  11780.         elseif R.subChoice == 4 then    -- remove sand from cube. start at top
  11781.             R.width   = menu.getInteger("Width of sand (<=30) ", 1, 30, nil, colors.yellow)
  11782.             R.length  = menu.getInteger("Length of of sand (<=30) ", 1, 30, nil, colors.orange)
  11783.             R.height  = 0
  11784.             R.data = "down" -- always starts at the top
  11785.         end
  11786.         if menu.getBoolean("Am I outside the active zone (y/n)?", nil, colors.yellow) then
  11787.             T:forward(1)
  11788.         end
  11789.     elseif R.choice == 82 then -- build wall from water or lava surface downwards
  11790.         R.width     = 1
  11791.         if menu.getBoolean("Going 90 deg. from existing? (y/n)", nil, colors.yellow, colors.black) then
  11792.             getTaskHelp(2, 852, true)
  11793.             menu.clear()   
  11794.             R.length = 56
  11795.             R.data = "withPath" -- ensures turtle will break through path
  11796.             R.length = menu.getInteger({"Wall length minus corners","(Ocean monument default 56)","Number -> Enter or Enter only (56)"},
  11797.                                         1, 64, nil, {colors.yellow, colors.orange, colors.green}, colors.black, 56)
  11798.         else
  11799.             R.length    = menu.getInteger("Length of the wall (1-60) ", 1, 60, nil, colors.yellow)
  11800.             R.height    = menu.getInteger("Fixed depth or 0 = to floor ", 0, 60, nil, colors.yellow)
  11801.         end
  11802.     -- for 83 see 710
  11803.     elseif R.choice == 84 then -- Clear area of water bounded by blocks
  11804.         R.width     = menu.getInteger("Width of water (0=autodetect) ", 0, 64, nil, colors.yellow)
  11805.         if R.width > 0 then
  11806.             R.length = menu.getInteger("Length of water", 1, 64, nil, colors.orange)
  11807.         end
  11808.         R.height    = menu.getInteger("Depth of water (0=autodetect)", 0, 64, nil, colors.blue)
  11809.     elseif R.choice == 85 then -- Sinking platform
  11810.         R.width     = menu.getInteger("Width (excluding retaining wall)? ", 1, 1024, nil, colors.yellow)
  11811.         R.length    = menu.getInteger("Length (excluding retaining wall)? ", 1, 1024 / R.width, nil, colors.orange)
  11812.         R.height    = menu.getInteger("Levels to go down?", 1, 1024 / R.width * R.length, nil, colors.blue)
  11813.     elseif R.choice == 86 then -- ocean monument utilities
  11814.         local items =
  11815.         {
  11816.             "Build 4 corner marker columns",
  11817.             "Retaining wall beween 2 columns",
  11818.             "Clear plants pre sand draining",
  11819.             "Drop sand wall",
  11820.             "Recover sand wall",
  11821.             "Sinking platform",
  11822.             "Drain and remove structure"   
  11823.         }
  11824.         pp.itemColours = {colors.lightGray, colors.brown, colors.blue, colors.yellow, colors.orange, colors.lightGray, colors.gray}
  11825.         R.subChoice = menu.menu("Which utility? ", items, pp)
  11826.         if R.subChoice ~= nil then
  11827.             getTaskHelp(2, R.choice * 10 + R.subChoice, true)
  11828.         end
  11829.         menu.clear()   
  11830.         if R.subChoice == 1 then -- Build 4 corner marker columns          
  11831.             R.useBlockType = "prismarine"
  11832.             R.data = "oceanMonumentColumns"
  11833.         elseif R.subChoice == 2 then -- Retaining wall beween 2 columns
  11834.             R.length = 56
  11835.             R.data = "withPath" -- ensures turtle will break through path
  11836.             T:clear()
  11837.             R.length = menu.getInteger({"Wall length minus corners","(Ocean monument default 56)","Number -> Enter or Enter only (56)"},
  11838.                                          1, 64, nil, {colors.yellow, colors.orange, colors.green}, colors.black, 56)
  11839.         elseif R.subChoice == 3 then -- Clear plants pre sand draining
  11840.             R.useBlockType = "prismarine"
  11841.             R.data = "clearWaterPlants"
  11842.             R.silent = true
  11843.             R.width     = menu.getInteger("water width (0=auto detect) ", 0, 64, nil, colors.yellow)
  11844.             R.length    = menu.getInteger("water length (0=auto detect) ", 0, 64, nil, colors.orange)
  11845.         elseif R.subChoice == 4 then -- Drain using sand utilities
  11846.             R.width   = 1
  11847.             R.length  = 0
  11848.         elseif R.subChoice == 5 then -- remove sand wall using sand utilities
  11849.             R.width   = 1
  11850.             R.length  = 0
  11851.         elseif R.subChoice == 6 then -- sinking platform
  11852.             R.width = menu.getInteger("Width (excluding retaining wall)? ", 1, 1024, nil, colors.yellow)
  11853.             R.length = menu.getInteger("Length (excluding retaining wall)? ", 1, 1024 / R.width, nil, colors.orange)
  11854.             R.height = menu.getInteger("Levels to go down?", 1, 1024 / R.width * R.length, nil, colors.blue)
  11855.         elseif R.subChoice == 7 then -- Drain and remove structure
  11856.             R.width = 28
  11857.             R.length = 28
  11858.             R.height = menu.getInteger("Go down how far from current", 1, 64, nil, colors.blue)
  11859.         end
  11860.     elseif R.choice == 87 then -- Ladder to water/lava 
  11861.         R.height    = menu.getInteger("est. height above (?F3) ", 1, 256, nil, colors.blue)
  11862.     elseif R.choice == 88 then -- Clear water plants from enclosed area
  11863.         R.data      = "clearWaterPlants"
  11864.         R.width     = menu.getInteger("water width (0=auto detect) ", 0, 64, nil, colors.yellow)
  11865.         R.length    = menu.getInteger("water length (0=auto detect) ", 0, 64, nil, colors.orange)
  11866.     elseif R.choice == 89 then -- convert flowing water to source
  11867.         R.width     = menu.getInteger("water width  (0=auto detect) ", 0, 64, nil, colors.yellow)
  11868.         if R.width > 0 then
  11869.             R.length = menu.getInteger("water length (0=auto detect) ", 0, 64, nil, colors.orange)
  11870.         end
  11871.         R.height    = menu.getInteger("water depth (0=auto detect) ", 0, 64, nil, colors.blue)
  11872.     elseif R.choice == 810 then -- create sloping water
  11873.         R.width     = menu.getInteger("water slope width (usually 7/8) ", 1, 8, nil, colors.yellow)
  11874.         R.length    = menu.getInteger("water slope length ", 1, 64, nil, colors.orange)
  11875.    
  11876. -- 09. BUILDING & RAILWAY
  11877.     elseif R.choice == 91 then -- Build wall
  11878.         R.width     = 1
  11879.         R.length    = menu.getInteger("Length of wall (1-256) ", 1, 256, nil, colors.orange)
  11880.         R.height    = menu.getInteger("Height of wall (1-50) ", 1, 50, nil, colors.lightGray)
  11881.         pp.itemColours = {colors.lime, colors.magenta}
  11882.         R.subChoice = menu.menu("What is my current position?", {"End of wall: Start ahead","Within the wall: start here"}, pp, "Type number + Enter")
  11883.     elseif R.choice == 92 then -- Build rectangular structure
  11884.         R.width     = menu.getInteger("Building width (1-256)", 1, 256, nil, colors.yellow)
  11885.         R.length    = menu.getInteger("Building length (1-256) ", 1, 256, nil, colors.orange)
  11886.         R.height    = menu.getInteger("Building Height(1-50) ", 1, 50, nil, colors.lightGray)
  11887.         pp.itemColours = {colors.lime, colors.magenta}
  11888.         R.subChoice = menu.menu("What is my current position?", {"Outside building: Start ahead","Within the walls: start here"}, pp, "Type number + Enter")
  11889.     elseif R.choice == 93 or R.choice == 94 then -- Build gable roof / pitched roof
  11890.         R.width     = menu.getInteger("Building width (1-256)", 1, 256, nil, colors.yellow)
  11891.         R.length    = menu.getInteger("Building length (1-256) ", 1, 256, nil, colors.orange)
  11892.     elseif R.choice == 97 then -- build downward slope
  11893.         R.height    = menu.getInteger("How many blocks down (0=to ground)?", 0, 256, nil, colors.blue)
  11894.         R.down = true
  11895.     elseif R.choice == 98 then -- build upward slope
  11896.         R.height    = menu.getInteger("Go up by how many blocks?", 1, 256, nil, colors.lightGray)
  11897.         R.up = true
  11898.        
  11899. -- 10. MEASURING TOOLS
  11900.     elseif R.choice == 101 then -- measure height
  11901.         pp.itemColours = {colors.lightBlue, colors.cyan, colors.lime, colors.gray}
  11902.         R.subChoice = menu.menu("Measure using?", {"Obstruction above", "No further blocks in front", "Detect specific block in front", "Until block above changes" }, pp, "Type number + Enter ") -- open direction menu options
  11903.         if R.subChoice == 3 then
  11904.             R.data = menu.getString({"Search for? eg 'ore', 'obsidian'",">"}, false, 3, 20, nil, {colors.lime, colors.yellow})
  11905.         end
  11906.         R.size = menu.getInteger("Max distance before abort?", 1, 1024, nil, colors.red, nil, 64)
  11907.     elseif R.choice == 102 then -- measure depth
  11908.         pp.itemColours = {colors.lime, colors.orange, colors.green}
  11909.         R.subChoice = menu.menu("Measure using?", {"Water/Lava/Obstruction below", "No further blocks ahead", "Detect specific block ahead"}, pp, "Type number + Enter") -- open direction menu options
  11910.         if R.subChoice == 3 then
  11911.             R.data = menu.getString({"Search for? eg 'ore', 'obsidian'",">"}, false, 3, 20, nil, {colors.lime, colors.yellow})
  11912.         end
  11913.     elseif R.choice == 103 then -- measure length
  11914.         pp.itemColours = {colors.gray, colors.lime, colors.green, colors.blue, colors.cyan}
  11915.         R.subChoice = menu.menu("Measure using?", {"Obstruction ahead",
  11916.                                                     "No further blocks above",
  11917.                                                     "No further blocks below",
  11918.                                                     "Detect specific block above",
  11919.                                                     "Detect specific block below"}, pp, "Type number + Enter") -- open direction menu options
  11920.         if R.subChoice == 4 or R.subChoice == 5 then
  11921.             R.data = menu.getString({"Search for? eg 'ore', 'obsidian'",">"}, false, 3, 20, nil, {colors.lime, colors.yellow})
  11922.         end
  11923.         R.size = menu.getInteger("Max distance before abort?", 1, 1024, nil, colors.red, nil, 64)
  11924.     elseif R.choice == 104 then -- measure greatest depth of water body
  11925.         pp.itemColours = {colors.lime, colors.orange}
  11926.         R.subChoice = menu.menu("Measure using?", {"Player entered", "No further water below"}, pp, "Type number + Enter ") -- open direction menu options
  11927.         -- 1 = player entry, 2 = water length
  11928.         if R.subChoice == 1 then
  11929.             R.length = menu.getInteger("water length (0=auto detect) ", 0, 256)
  11930.         end
  11931.     elseif R.choice == 105 then -- drill borehole and write borhole.txt to file
  11932.         R.height = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.lightGray)
  11933.         R.depth = menu.getInteger("Go down to level? ("..R.height - 2 .." to "..bedrock + 5 ..")", bedrock + 5 ,R.height - 2, nil, colors.blue, nil, bedrock + 5)
  11934.     end
  11935.    
  11936.     return R
  11937. end
  11938.  
  11939. local function getTaskInventoryTo30(R)
  11940.     local retValue = {}
  11941.     local thanks = "Thank you.\n\nPress the ESC key\n\nStand Back..\n"
  11942.     --local pp = utils.getPrettyPrint()
  11943.    
  11944.     if R.choice == 0 then --Missing pickaxe
  11945.         T:checkInventoryForItem({"minecraft:diamond_pickaxe"}, {1})
  11946.         print("Diamond Pickaxe being tested...")
  11947.         T:setEquipment()
  11948.     elseif R.choice == 1 then --Missing crafting table
  11949.         T:checkInventoryForItem({"minecraft:crafting_table"}, {1}) -- 0 if not present
  11950.         print("Crafting table being tested...")
  11951.         T:setEquipment()
  11952.     elseif R.choice == 2 then --Missing chest
  11953.         T:checkInventoryForItem({"minecraft:chest"}, {1}) -- 0 if not present
  11954.         sleep(1.5)
  11955.        
  11956.     -- MINING
  11957.    
  11958.     elseif R.choice == 11 or R.choice == 12 then            -- ladder down / up / stairs down / stairs up
  11959.         local description = "Creating ladder going down"    -- default action description
  11960.         pp.itemColours = {colors.blue, colors.lightGray}
  11961.         pp.allowModifier = false -- only allow numbers to be returned
  11962.         local inAir = false
  11963.         local inNether = menu.getBoolean("Are you in the nether? (y/n) ", nil, colors.yellow, colors.black)
  11964.        
  11965.         if inNether then
  11966.             bedrock = 0
  11967.             inAir = true
  11968.         end
  11969.         local option = menu.menu("Which direction?", {"Going down","Going up"}, pp)
  11970.         if option == 1 then
  11971.             R.down = true
  11972.             R.height = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.lightGray)
  11973.             R.depth = menu.getInteger("Go down to level? ("..R.height - 2 .." to "..bedrock + 5 ..") ", bedrock + 5 , R.height - 2, nil, colors.blue)
  11974.             if R.choice == 11 then
  11975.                 if menu.getBoolean("Build a shelter at base? (y/n) ", nil, colors.yellow, colors.black) then
  11976.                     R.data = "chamber"
  11977.                 end
  11978.             end
  11979.             if R.choice == 13 then
  11980.                 description = "Creating stairs going down"
  11981.             end
  11982.         else
  11983.             R.up = true
  11984.             --R.depth = utils.getSize(true,"Current level (F3->Y coord)? ", bedrock + 5, ceiling)
  11985.             --R.height = utils.getSize(true, "Go up to level? ("..R.depth + 2 .." to "..ceiling ..")", R.depth + 2, ceiling)
  11986.             R.depth = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.blue)
  11987.             R.height = menu.getInteger("Go up to level? ("..R.depth + 2 .." to "..ceiling ..") ", R.depth + 2, ceiling, nil, colors.lightGray)
  11988.             if R.choice == 11 then
  11989.                 description = "Creating ladder going up"
  11990.             else
  11991.                 description = "Creating stairs going up"
  11992.             end
  11993.         end
  11994.         local range = math.abs(R.height - R.depth)
  11995.        
  11996.         if not inAir then
  11997.             inAir = menu.getBoolean("Are you in air (add blocks)? (y/n) ", nil, colors.yellow, colors.black)
  11998.         end
  11999.         --[[
  12000.         range examples
  12001.         -50 to -59 = -59 -(-50) = -9   down
  12002.         -59 to -50 = -50 -(-59) = 9    up
  12003.          70 to -48 = -48 -   70 = -118 down
  12004.           5 to  64 =  64 -   5  = 59   up
  12005.         ]]
  12006.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12007.         if R.choice == 11 then -- ladders
  12008.             utils.checkFuelNeeded(range * 2)
  12009.             T:checkInventoryForItem({"minecraft:ladder"}, {range})
  12010.             T:checkInventoryForItem({"minecraft:torch"}, {math.floor(range / 3)}, false)
  12011.             if inAir then
  12012.                 range = range * 4 -- more blocks needed
  12013.             end
  12014.             T:checkInventoryForItem({"stone"}, {range})
  12015.         else -- stairs
  12016.             utils.checkFuelNeeded(range * 10) -- stairs: each layer needs 10 moves
  12017.             local numStairsNeeded = range
  12018.             local data = T:getStock("stairs")
  12019.             local numStairs = data.total
  12020.             local cobbleNeeded = math.min(range * 6, 256)
  12021.             if inAir then
  12022.                 cobbleNeeded = range * 6 -- 5 blocks / layer unless in water or lava
  12023.             end
  12024.             if numStairs < numStairsNeeded then
  12025.                 cobbleNeeded = cobbleNeeded + (math.floor((2 * (numStairsNeeded - numStairs)) / 3))
  12026.             end
  12027.             T:checkInventoryForItem({"stairs"}, {numStairsNeeded}, false)
  12028.             T:checkInventoryForItem({"stone"}, {cobbleNeeded})
  12029.             T:checkInventoryForItem({"minecraft:chest"}, {1})   -- needed for crafting
  12030.         end
  12031.         menu.colourPrint(description, colors.lightBlue)
  12032.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12033.         if R.choice == 11 then
  12034.             retValue = createLadder(R) -- "bedrock", 70, -48
  12035.         else
  12036.             retValue = createStaircase(R)
  12037.         end
  12038.     elseif R.choice == 13 then --Create Mine at this level
  12039.         utils.checkFuelNeeded(960)
  12040.         T:checkInventoryForItem({"minecraft:torch"}, {24}, false)
  12041.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12042.         T:checkInventoryForItem({"stone"}, {64})
  12043.         T:checkInventoryForItem({"minecraft:chest"}, {1})
  12044.         menu.colourPrint("CreateMine starting", colors.lightBlue)
  12045.         sleep(2)
  12046.         retValue = createMine()
  12047.     elseif R.choice == 14 then  -- safe drop to water
  12048.         utils.checkFuelNeeded(R.height * 2)
  12049.         T:checkInventoryForItem({"minecraft:water_bucket"}, {1})
  12050.         T:checkInventoryForItem({"stone"}, {R.height * 2}, false) -- estimate only partial cloaking needed
  12051.         menu.colourPrint("Creating safe drop ".. R.height.. " blocks deep", colors.lightBlue)
  12052.         menu.colourPrint("Wait for my return!", colors.yellow)
  12053.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12054.         retValue = createSafeDrop(R)
  12055.     elseif R.choice == 15 then  -- single column bubble lift
  12056.         local needSigns = true
  12057.         utils.checkFuelNeeded(R.height * 6)
  12058.         --print(text, fg, bg, width)
  12059.         menu.colourPrint("Checking if near ladder", colors.red)
  12060.         T:turnRight(1)
  12061.         local blockType = T:getBlockType("forward")
  12062.         if blockType:find("ladder") == nil then
  12063.             T:turnLeft(2)
  12064.             blockType = T:getBlockType("forward")
  12065.             if blockType:find("ladder") == nil then
  12066.                 needSigns = false
  12067.             end
  12068.             T:turnRight(1)
  12069.         else
  12070.             needSigns = false
  12071.             T:turnLeft(1)
  12072.         end
  12073.         sleep(1)
  12074.         if needSigns then
  12075.             T:checkInventoryForItem({"sign"}, {2}, true, "Ladder not found")
  12076.         else
  12077.             menu.colourPrint("Ladder found, signs not required", colors.orange)
  12078.             sleep(1)
  12079.         end
  12080.         if T:getBlockType("down"):find("bedrock") == nil then -- NOT bedrock below
  12081.             T:checkInventoryForItem({"minecraft:water_bucket"}, {3})
  12082.         else
  12083.             T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12084.         end
  12085.         T:checkInventoryForItem({"minecraft:soul_sand", "minecraft:dirt"}, {1, 1}, true, "? use dirt as soul sand placeholder")
  12086.         T:checkInventoryForItem({"stone"}, {R.height * 2}, false) -- estimate only partial cloaking needed
  12087.         local _, slots = T:getFirstEmptySlot() -- returns first empty slot, no of empty slots
  12088.         T:checkInventoryForItem({"minecraft:bucket"}, {slots}, false, "Add empty buckets for speed!")
  12089.         menu.colourPrint("Creating bubble lift ".. R.height.. " blocks high", colors.lime)
  12090.         if not needSigns then -- ladder present as signs not required
  12091.             menu.colourPrint("Wait at the top via ladder...", colors.orange)
  12092.         end
  12093.         menu.colourPrint("\nSTAND ON THE LADDER FOR SAFETY!", colors.red)
  12094.         menu.colourPrint("\nEnter to continue", colors.yellow)
  12095.         read()
  12096.         retValue = createBubbleLift(R)
  12097.     elseif R.choice == 16 then --QuickMine corridor
  12098.         utils.checkFuelNeeded((R.width * 2 + R.length * 2) * 2)
  12099.         T:checkInventoryForItem({"stone"}, {R.width * 2 + R.length * 2}, false)
  12100.         T:checkInventoryForItem({"minecraft:torch"}, {math.floor((R.width * 2 + R.length * 2) / R.torchInterval)}, false)
  12101.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12102.         menu.colourPrint("QuickMine corridor: R.subChoice "..R.width.. " x "..R.length, colors.lightBlue)
  12103.         retValue = quickMineCorridor(R)
  12104.     elseif R.choice == 17 then --QuickMine
  12105.         utils.checkFuelNeeded(R.width * R.length)
  12106.         T:checkInventoryForItem({"stone"}, {64})
  12107.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12108.         menu.colourPrint("QuickMine rectangle: R.subChoice "..R.width.. " x "..R.length, colors.lightBlue)
  12109.         retValue = quickMine(R)
  12110.     elseif R.choice == 18 then --Mine bedrock area
  12111.         utils.checkFuelNeeded(R.width * R.length)
  12112.         T:checkInventoryForItem({"stone"}, {64})
  12113.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12114.         retValue = mineBedrockArea(R) -- R.data = "leaveExposed" or ""
  12115.     elseif R.choice == 19 then  -- salvage mineshaft
  12116.         local equippedRight, equippedLeft, inInventory = T:setEquipment() -- check for crafting table, sword, pickaxe, Put sword in spare slot
  12117.         if equippedLeft ~= "minecraft:diamond_pickaxe" and equippedRight ~= "minecraft:diamond_pickaxe" then
  12118.             T:checkInventoryForItem({"minecraft:diamond_pickaxe"}, {1}, true)
  12119.             equippedRight, equippedLeft, inInventory = T:setEquipment() -- check for crafting table, sword, pickaxe, Put sword in spare slot
  12120.         end
  12121.         if inInventory ~= "minecraft:diamond_sword" then
  12122.             T:checkInventoryForItem({"minecraft:diamond_sword"}, {1}, false, "To harvest spider webs\nyou need a diamond sword.") --checkInventoryForItem(self, items, quantities, required, message, name)
  12123.         end
  12124.         if T:getItemSlot("minecraft:diamond_sword") > 0 then
  12125.             inInventory = "minecraft:diamond_sword"
  12126.         end
  12127.         T:checkInventoryForItem({"minecraft:torch"}, {R.torchInterval}, false)
  12128.         if inInventory == "minecraft:diamond_sword" then
  12129.             menu.colourPrint("Clearing Mineshaft and cobwebs", colors.orange)
  12130.         else
  12131.             menu.colourPrint("Clearing Mineshaft", colors.yellow)
  12132.         end
  12133.         retValue = clearMineshaft(R, equippedRight, equippedLeft, inInventory) -- pass whether the sword is present
  12134.        
  12135.     -- FORESTRY
  12136.     elseif R.choice == 21 then  -- Fell tree
  12137.         if T:isLog("forward") then
  12138.             if turtle.getFuelLevel() < 30 then
  12139.                 T:checkInventoryForItem({"minecraft:chest"}, {1}, false,"Fuel level critical: "..turtle.getFuelLevel())
  12140.                 turtle.select(1)
  12141.                 T:dig("forward")
  12142.                 T:craft("planks", 4)
  12143.                 T:refuel()
  12144.                 T:forward(1)
  12145.                 T:up(2)
  12146.                 T:craft("chest", 1)
  12147.             else
  12148.                 T:forward(1)
  12149.             end
  12150.             menu.colourPrint("Felling tree", colors.lime)
  12151.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12152.             T:harvestWholeTree("up")
  12153.             while turtle.down() do end
  12154.             retValue = {"Tree Harvested"}
  12155.         else
  12156.             retValue =
  12157.             {
  12158.                 "No log in front..",
  12159.                 "Move me in front of a tree!"
  12160.             }
  12161.         end
  12162.     elseif R.choice == 22 then --Create treefarm
  12163.         utils.checkFuelNeeded(900)
  12164.         --T:checkInventoryForItem({"minecraft:dirt"}, {16})
  12165.         T:checkInventoryForItem({"stone"}, {320})
  12166.         T:checkInventoryForItem({"polished"}, {4}) -- used to mark launch positions
  12167.         T:checkInventoryForItem({"minecraft:water_bucket"}, {5})
  12168.         R.useBlockType = T:getMostItem("", true)
  12169.         menu.colourPrint("Creating Tree Farm with "..R.useBlockType, colors.lime)
  12170.         sleep(2)
  12171.         retValue = createTreefarm(R)
  12172.     elseif R.choice == 23 then -- Plant treefarm
  12173.         if R.subChoice == 1 then
  12174.             utils.checkFuelNeeded(180)
  12175.             T:checkInventoryForItem({"dirt"}, {16})
  12176.             T:checkInventoryForItem({"sapling"}, {16}, false, "Max 16. NOT dark oak")
  12177.         elseif R.subChoice == 2 then
  12178.             utils.checkFuelNeeded(180)
  12179.             T:checkInventoryForItem({"dirt"}, {16})
  12180.             T:checkInventoryForItem({"sapling"}, {16}, false, "Max 16. 4 saplings / tree")
  12181.         end
  12182.         menu.colourPrint("plantTreefarm starting: size "..R.subChoice, colors.lime)
  12183.         retValue = plantTreefarm(R)
  12184.     elseif R.choice == 24 then  -- Harvest treefarm
  12185.         print(thanks)
  12186.         os.sleep(2)
  12187.         menu.colourPrint("Harvesting treefarm starting", colors.lime)
  12188.         retValue = harvestTreeFarm(R)
  12189.     elseif R.choice == 25 then  -- Build wall / fence
  12190.         utils.checkFuelNeeded(R.width * R.length * 2)
  12191.         local quantity = math.ceil((R.width + R.length) * 2.3)
  12192.         T:checkInventoryForItem({"wall", "fence"}, {quantity, quantity})
  12193.         if R.torchInterval > 0 then
  12194.             T:checkInventoryForItem({"minecraft:torch"}, {math.floor(quantity / R.torchInterval)}, false)
  12195.         end
  12196.         if R.data == "barrel" then
  12197.             T:checkInventoryForItem({"barrel"}, {4}, false)
  12198.         end
  12199.         R.useBlockType = T:getMostItem("", false) -- no excluded blocks, any block type
  12200.         menu.colourPrint("Creating "..R.width.." x "..R.length.." walled enclosure", colors.yellow)
  12201.         menu.colourPrint("Using: "..R.useBlockType, colors.orange)
  12202.         retValue = createWallOrFence(R)
  12203.     elseif R.choice == 26 then  -- clear natural forest
  12204.         T:checkInventoryForItem({"minecraft:chest"}, {1})
  12205.         T:checkInventoryForItem({"sapling"}, {64}, false)
  12206.         menu.colourPrint("Clearing and replanting trees", colors.lime)
  12207.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12208.         retValue = clearAndReplantTrees()
  12209.     end
  12210.     return retValue
  12211. end
  12212.  
  12213. local function getTaskInventoryTo70(R)
  12214.     local retValue = {}
  12215.     local thanks = "Thank you.\n\nPress the ESC key\n\nStand Back..\n"
  12216.     -- FARMING
  12217.     if R.choice == 31 then  -- Create modular farm
  12218.         utils.checkFuelNeeded(300)
  12219.         T:checkInventoryForItem({"cobble"}, {64})
  12220.         T:checkInventoryForItem({"dirt"}, {128}, false)
  12221.         T:checkInventoryForItem({"water_bucket"}, {4})
  12222.         T:checkInventoryForItem({"chest", "barrel"}, {5,5})
  12223.         T:checkInventoryForItem({"sapling"}, {1})
  12224.         R.useBlockType = T:getMostItem("dirt", true) -- exclude dirt from count
  12225.         print(thanks)
  12226.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12227.         print("Creating modular farm with "..R.useBlockType)
  12228.         retValue = createFarm(R, false)
  12229.     elseif R.choice == 32 then  -- Extend modular farm
  12230.         utils.checkFuelNeeded(300)
  12231.         T:checkInventoryForItem({"cobble"}, {64})
  12232.         T:checkInventoryForItem({"dirt"}, {128}, false)
  12233.         T:checkInventoryForItem({"water_bucket"}, {4})
  12234.         T:checkInventoryForItem({"chest", "barrel"}, {5,5})
  12235.         T:checkInventoryForItem({"sapling"}, {1})
  12236.         T:checkInventoryForItem({"crafting"}, {1}) -- will be placed inside barrel / chest next to water source
  12237.         R.useBlockType = T:getMostItem("dirt", true) -- exclude dirt from count
  12238.         menu.colourPrint("Checking position...\n", colors.green)
  12239.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12240.         retValue = createFarmExtension(R) -- subChoice = 1 for ahead, 2 for to the right
  12241.     elseif R.choice == 33 then  -- manage modular farm
  12242.         -- inventory checked in function depending on option taken
  12243.         R.data = "farm"
  12244.         retValue = manageFarmSetup(R)
  12245.     elseif R.choice == 34 then  -- build single fence
  12246.         utils.checkFuelNeeded(R.length)
  12247.         T:checkInventoryForItem({"wall", "fence"}, {R.length, R.length})
  12248.         if R.torchInterval > 0 then
  12249.             T:checkInventoryForItem({"minecraft:torch"}, {math.ceil(R.length / R.torchInterval)}, false)
  12250.         end
  12251.         R.useBlockType = T:getMostItem("minecraft:torch") -- exclude torch
  12252.         menu.colourPrint("Creating "..R.length.." wall or fence", colors.green)
  12253.         menu.colourPrint("Using: "..R.useBlockType, colors.orange)
  12254.         retValue = createWallOrFence(R) -- barrels not included in R.data, R.width = 0 so only single length
  12255.     elseif R.choice == 35 then  -- build fence
  12256.         utils.checkFuelNeeded(R.width * R.length * 2)
  12257.         local quantity = math.ceil((R.width + R.length) * 2.3)
  12258.         T:checkInventoryForItem({"wall", "fence"}, {quantity, quantity})
  12259.         if R.torchInterval > 0 then
  12260.             T:checkInventoryForItem({"minecraft:torch"}, {math.floor(quantity / R.torchInterval)}, false)
  12261.         end
  12262.         R.useBlockType = T:getMostItem("minecraft:torch") -- exclude torch
  12263.         menu.colourPrint("Creating "..R.width.." x "..R.length.." walled enclosure", colors.green)
  12264.         menu.colourPrint("Using: "..R.useBlockType, colors.orange)
  12265.         retValue = createWallOrFence(R) -- barrels not included in R.data
  12266.     -- OBSIDIAN
  12267.     elseif R.choice == 41 then --harvest obsidian
  12268.         utils.checkFuelNeeded(R.width * R.length * 3)
  12269.         T:checkInventoryForItem({"stone"}, {R.width * R.length})
  12270.         T:checkInventoryForItem({"minecraft:bucket", "minecraft:lava_bucket"}, {1, 1}, false, "Get extra fuel as well!")
  12271.         menu.colourPrint("Harvesting obsidian area: size "..R.width.. " x "..R.length, colors.orange)
  12272.         sleep(2)
  12273.         retValue = harvestObsidian(R)
  12274.     elseif R.choice == 42 then --build nether portal
  12275.         utils.checkFuelNeeded(R.length * R.height * R.width)    -- length = width when facing standard = 5 high 4 length 1 width
  12276.         T:checkInventoryForItem({"minecraft:obsidian"}, {((R.length - 2 + R.height - 2) * R.width * 2)})
  12277.         T:checkInventoryForItem({"stone"}, {R.width * 4})
  12278.         R.useBlockType = T:getMostItem("obsidian", true) -- exclude obsidian from count
  12279.         menu.colourPrint("Building Nether portal", colors.orange)
  12280.         sleep(2)
  12281.         retValue = createPortal(R)
  12282.     elseif R.choice == 43 then --demolish nether portal
  12283.         utils.checkFuelNeeded(20)
  12284.         print("Demolishing Nether portal")
  12285.         retValue = demolishPortal(R)
  12286.     elseif R.choice == 44 then -- Strip mine Netherite
  12287.         utils.checkFuelNeeded(R.length * 2)
  12288.         T:checkInventoryForItem({"stone"}, {R.length * 4})
  12289.         R.useBlockType = T:getMostItem("", true) -- exclude none, use stone only/netherrack
  12290.         T:checkInventoryForItem({"cobble"}, {math.floor(R.length / 16) * 4}, true, "For marking Chunk boundaries")
  12291.         T:checkInventoryForItem({"minecraft:bucket", "minecraft:lava_bucket"}, {1, 1})
  12292.         T:checkInventoryForItem({"minecraft:torch"}, {math.floor(R.length / 16)}, false)
  12293.         retValue = createStripMine(R)
  12294.     elseif R.choice == 45 then --undermine dragon towers
  12295.         utils.checkFuelNeeded(500)
  12296.         T:checkInventoryForItem({"minecraft:cobblestone", "minecraft:cobbled_deepslate"}, {84, 84})
  12297.         print("Undermining dragon towers")
  12298.         retValue = undermineDragonTowers()
  12299.     elseif R.choice == 46 then --deactivate dragon tower
  12300.         utils.checkFuelNeeded(50)
  12301.         print("Deactivating dragon tower")
  12302.         retValue = deactivateDragonTower()
  12303.     elseif R.choice == 47 then --build dragon water trap
  12304.         utils.checkFuelNeeded(256)
  12305.         T:checkInventoryForItem({"stone"}, {356})
  12306.         T:checkInventoryForItem({"minecraft:obsidian"}, {1})
  12307.         T:checkInventoryForItem({"minecraft:ladder"}, {145})
  12308.         T:checkInventoryForItem({"minecraft:water_bucket"}, {1})
  12309.         print("Building dragon water trap")
  12310.         retValue = createDragonTrap()
  12311.     elseif R.choice == 48 then --build portal minecart station
  12312.         utils.checkFuelNeeded(200)
  12313.         menu.colourPrint("Inventory after height measurement", colors.red)
  12314.         menu.colourPrint("Enter to start measurement.", colors.lime)
  12315.         read()
  12316.         print("Building portal platform")
  12317.         retValue = createPortalPlatform()
  12318.     elseif R.choice == 49 then -- shulker harvesting
  12319.         retValue = harvestShulkers(R)
  12320.        
  12321.     -- CANAL BRIDGE
  12322.     elseif R.choice == 51 then  -- continuous path over void/water/lava
  12323.         utils.checkFuelNeeded(R.length) -- allow for R.length
  12324.         if R.data ~= "reduce" then
  12325.             T:checkInventoryForItem({"stone"}, {R.length}, false)
  12326.             if R.torchInterval > 0 then
  12327.                 T:checkInventoryForItem({"minecraft:torch"}, {math.floor(R.length/R.torchInterval)}, false)
  12328.             end
  12329.             print("Building continuous path")
  12330.         end
  12331.         retValue = utils.createPath(R) -- returns {numBlocks}
  12332.     elseif R.choice == 52 then  -- simple 2 block corridor
  12333.         utils.checkFuelNeeded(R.length)
  12334.         T:checkInventoryForItem({"stone"}, {R.length * 2}, false)
  12335.         if R.torchInterval > 0 then
  12336.             T:checkInventoryForItem({"minecraft:torch"}, {math.ceil(R.length / R.torchInterval)}, false)
  12337.         end
  12338.         print(thanks)
  12339.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12340.         print("Building simple corridor")
  12341.         retValue = createCorridor(R)
  12342.     elseif R.choice == 53 then  -- canal management
  12343.         local torches = 0
  12344.         local length = R.length
  12345.         if length > 0 then
  12346.             utils.checkFuelNeeded(length * 4) -- allow for 1024 R.length
  12347.             if R.torchInterval > 0 then
  12348.                 torches = math.floor(length / R.torchInterval)
  12349.             end
  12350.         else
  12351.             utils.checkFuelNeeded(2048) -- allow for 1024 R.length
  12352.             length = 256
  12353.         end
  12354.         T:checkInventoryForItem({"stone"}, {length})
  12355.         R.useBlockType = T:getMostItem("", true)
  12356.         if R.data == 1 or (R.data == 2 and (R.subChoice == 2 or R.subChoice == 3 or R.subChoice == 5 or R.subChoice == 6)) then
  12357.             T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12358.         end
  12359.         if torches > 0 then
  12360.             T:checkInventoryForItem({"minecraft:torch"}, {torches}, false)
  12361.         end
  12362.         retValue = createWaterCanal(R)
  12363.     elseif R.choice == 54 then  -- ice canal
  12364.         local default = R.length
  12365.         if R.length > 0 then
  12366.             utils.checkFuelNeeded(R.length)
  12367.         else
  12368.             default = 64
  12369.             utils.checkFuelNeeded(default * 2) -- allow for 128 min R.length
  12370.         end
  12371.         --[[
  12372.             new canal
  12373.             1 = left towpath- move to centre left
  12374.             2 = centre left ice or hollow
  12375.             3 = centre right ice or hollow
  12376.             4 = right side - move to centre right
  12377.             convert water canal
  12378.             5 = left towpath
  12379.             6 = centre left ice or air
  12380.             7 = centre right ice or air
  12381.             8 = right towpath
  12382.         ]]
  12383.         if R.subChoice <= 5 or R.subChoice == 8 then    -- towpath
  12384.             T:checkInventoryForItem({"slab"}, {default}, true, "Add slabs to length required")
  12385.         end
  12386.         if R.torchInterval > 0 then
  12387.             --checkInventoryForItem(items, quantities, required, message)
  12388.             T:checkInventoryForItem({"stone"}, {math.ceil(default / R.torchInterval)}, true, "NOT bricks!")
  12389.             R.useBlockType = T:getMostItem("", true)
  12390.             T:checkInventoryForItem({"torch"}, {math.ceil(default / R.torchInterval)}, false)
  12391.         end
  12392.         if R.data == "ice" then -- ice canal with 2 spaces above
  12393.             T:checkInventoryForItem({"minecraft:packed_ice", "minecraft:blue_ice"}, {math.ceil(R.length / 2), math.ceil(R.length / 2)}, false)
  12394.         end
  12395.         print(thanks)
  12396.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12397.         print("Building ice canal")
  12398.         retValue = createIceCanal(R)
  12399.     elseif R.choice == 55 then -- platform
  12400.         local volume = R.width * R.length
  12401.         utils.checkFuelNeeded(volume)
  12402.         T:checkInventoryForItem({"stone", "dirt"}, {volume, volume})
  12403.         R.useBlockType = T:getMostItem("", true)
  12404.         print(thanks)
  12405.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12406.         print("Building platform")
  12407.         retValue = createPlatform(R)
  12408.     elseif R.choice == 56 then -- sinking platform
  12409.         local volume = (R.width + 1) * (R.length + 1)
  12410.         utils.checkFuelNeeded(volume * (R.height + 1))
  12411.         T:checkInventoryForItem({"stone"}, {volume + ((R.length * 2) + (R.width * 2) * R.height) + 1})
  12412.         print(thanks)
  12413.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12414.         print("Building sinking platform")
  12415.         retValue = createSinkingPlatform(R)
  12416.     elseif R.choice == 57 then -- boat bubble lift
  12417.         utils.checkFuelNeeded(R.height * 20)
  12418.         T:checkInventoryForItem({"minecraft:bucket","minecraft:water_bucket"}, {2, 2})
  12419.         T:checkInventoryForItem({"stone"}, {R.height * 10})
  12420.         T:checkInventoryForItem({"gate"}, {R.height * 2})
  12421.         T:checkInventoryForItem({"minecraft:soul_sand"}, {R.height * 2 + 2})
  12422.         print(thanks)
  12423.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12424.         print("Building boat bubble lift")
  12425.         retValue = createBoatLift(R)
  12426.         --retValue = createBoatLift(R) -- R.subChoice:0=new, R.subChoice:1=extend, R.length:0=left, 1=right
  12427.        
  12428.     -- MOB SPAWNER
  12429.     elseif R.choice == 61 then  --  9x9 hollow cube cobble lined
  12430.         utils.checkFuelNeeded(600) -- allow for 600 moves
  12431.         T:checkInventoryForItem({"slab","stone"}, {1, 3}, true, "Slab can be crafted from 3 stone")
  12432.         if T:getItemSlot("stone") > 0 and T:getItemSlot("slab") == 0 then -- no slabs, but is stone
  12433.             local craftOK, message = T:craft("slab")
  12434.         end
  12435.         if R.data == "chest" then
  12436.             menu.colourText(nil, "~yellow~Chest(s) will be emptied first\nWait for me to exit and request\n~orange~around 700 stone!\n\n~lightGray~Enter to continue", true)
  12437.             read()
  12438.         else
  12439.             T:checkInventoryForItem({"stone"}, {512}, false, "Full cube uses ~700 blocks\nEstimate your requirements")
  12440.         end
  12441.         print(thanks)
  12442.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12443.         retValue = createMobFarmCube(R) -- R.data = "spawner" or "chest": not blaze
  12444.     elseif R.choice == 62 then  -- Blaze spawner
  12445.         utils.checkFuelNeeded(2500) -- allow for 2500 moves
  12446.         if R.data == "blaze" then
  12447.             T:checkInventoryForItem({"slab"}, {122}, true)
  12448.             T:checkInventoryForItem({"stone"}, {576})
  12449.             print("You will be asked for more assets later")
  12450.             print("Enter to continue")
  12451.             read()
  12452.         end  -- else R.data == "restart"
  12453.         retValue = createMobFarmCube(R) --R.data = "blaze" or R.data = "restart"
  12454.     elseif R.choice == 63 then  --  flood mob spawner
  12455.         utils.checkFuelNeeded(60) -- allow for 60 moves
  12456.         T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12457.         if R.subChoice == 1 then
  12458.             T:checkInventoryForItem({"fence"}, {2})
  12459.             T:checkInventoryForItem({"sign"}, {2})
  12460.             T:checkInventoryForItem({"slab"}, {1})
  12461.             T:checkInventoryForItem({"minecraft:soul_sand", "minecraft:dirt"}, {1, 1}, true)
  12462.         end
  12463.         print(thanks)
  12464.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12465.         retValue = floodMobFarm(R)
  12466.     elseif R.choice == 64 then -- build bubble lift on top of soul sand
  12467.         utils.checkFuelNeeded(200) -- allow for 200 moves
  12468.         T:checkInventoryForItem({"slab","stone"}, {6, 3}, true, "Slabs can be crafted from 3 stone")
  12469.         if T:getItemSlot("stone") > 0 and T:getItemSlot("slab") == 0 then -- no slabs, but is stone
  12470.             local craftOK, message = T:craft("slab")
  12471.         end
  12472.         T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12473.         T:checkInventoryForItem({"stone"}, {256})
  12474.         if T:getBlockType("down") ~= "minecraft:soul_sand" then
  12475.             T:checkInventoryForItem({"minecraft:soul_sand"}, {1})
  12476.         end
  12477.         T:checkInventoryForItem({"hopper"}, {1}, false)
  12478.         if T:getItemSlot("hopper") > 0 then
  12479.             T:checkInventoryForItem({"chest"}, {2})
  12480.         end
  12481.         print(thanks)
  12482.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12483.         retValue = createMobBubbleLift(R)
  12484.     elseif R.choice == 65 then -- computercraft mob grinder
  12485.         utils.checkFuelNeeded(1000) -- allow for 1000 moves
  12486.         T:checkInventoryForItem({"stone"}, {256}) -- for ceiling, walls and floor of area
  12487.         R.useBlockType = T:getMostItem("", true) -- stone only, no exclusions
  12488.         print(thanks)
  12489.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12490.         retValue = createMobGrinder(R)
  12491.     elseif R.choice == 66 then -- build endermen tower
  12492.         -- build in 3 sections, base, tower, top
  12493.         getTaskHelp(2, 66) -- compulsory help display
  12494.         read() -- pause until user ready
  12495.         local numFuel = 700
  12496.         local choices =
  12497.         {
  12498.             "New tower lower base",
  12499.             "Add tower upper base + killzone",
  12500.             "128 block tower to existing base"
  12501.         }
  12502.         pp.itemColours = {colors.lime, colors.orange, colors.green}
  12503.         local option, modifier = menu.menu("Select build stage:", choices, pp)
  12504.         if option == 1 then --lower base
  12505.             T:checkInventoryForItem({"minecraft:chest"}, {1})
  12506.             T:place("chest", -1, "down", false)
  12507.             T:emptyInventory("up")
  12508.             utils.checkFuelNeeded(320) -- allow for 320 moves
  12509.             T:checkInventoryForItem({"stone"}, {144}) -- <3 stacks
  12510.             T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12511.             T:checkInventoryForItem({"fence"}, {4})
  12512.             T:checkInventoryForItem({"sign"}, {4})
  12513.             T:checkInventoryForItem({"door"}, {2})
  12514.             T:checkInventoryForItem({"minecraft:soul_sand"}, {1})
  12515.         elseif option == 2 then -- upper base
  12516.             utils.checkFuelNeeded(710) -- allow for 703 moves
  12517.             T:checkInventoryForItem({"stone"}, {384}) -- 6 stacks
  12518.             T:checkInventoryForItem({"minecraft:bucket"}, {4})
  12519.             T:checkInventoryForItem({"fence"}, {15})
  12520.             T:checkInventoryForItem({"sign"}, {4})
  12521.             T:checkInventoryForItem({"ladder"}, {3})
  12522.             T:checkInventoryForItem({"minecraft:soul_sand"}, {1})
  12523.         else -- main tower
  12524.             utils.checkFuelNeeded(3000) -- allow for 3000 moves
  12525.             if T:getBlockType("down") ~= "minecraft:chest" then
  12526.                 T:checkInventoryForItem({"minecraft:chest"}, {1})
  12527.                 T:place("chest", -1, "down", false)
  12528.             end
  12529.             T:checkInventoryForItem({"stone"}, {768}) -- 12 stacks
  12530.             T:checkInventoryForItem({"minecraft:bucket"}, {10})
  12531.             T:checkInventoryForItem({"fence"}, {64})    -- 1 stacks    
  12532.         end
  12533.         print(thanks)
  12534.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12535.         retValue = createEnderTower(option) -- 1, 2, or 3
  12536.     end
  12537.     return retValue
  12538. end
  12539.  
  12540. local function getTaskInventory(R)
  12541.     -- run this loop 2x per second to check if player has put anything in the inventory
  12542.     -- fuel 1 coal = 60 = 4 planks. 64 planks = 16 coal = 960 units
  12543.     local retValue = {}
  12544.     local thanks = "Thank you.\n\nPress the ESC key\n\nStand Back..\n"
  12545.    
  12546.     if R.choice < 31 then
  12547.         return getTaskInventoryTo30(R) -- Mining, Forestry
  12548.     elseif R.choice < 71 then
  12549.         return getTaskInventoryTo70(R) -- Farming, Obsidian, Canal / Bridge
  12550.     elseif R.choice > 500 and R.choice < 700 then
  12551.         return getTaskInventoryTo70(R)
  12552.     else -- Area carving, Lava/Water, Railway
  12553.         -- AREA CARVING
  12554.         if R.choice == 71 then--Clear area
  12555.             utils.checkFuelNeeded(R.width * R.length * 3)
  12556.             if R.useBlockType == "dirt" then
  12557.                 T:checkInventoryForItem({"minecraft:dirt"}, {R.width * R.length})
  12558.             end
  12559.             print(thanks)
  12560.             sleep(2)
  12561.             print("Clearing area: size "..R.width.. " x "..R.length)
  12562.             retValue = clearArea(R)
  12563.         elseif R.choice == 72 then --Clear rectangle
  12564.             -- R.choice, R.width(R.subChoice), R.length(R.width), up(R.length), down(R.height) from getTask()
  12565.             utils.checkFuelNeeded(R.width * R.length)
  12566.             print("Clearing rectangle: size "..R.width.. " x "..R.length)
  12567.             retValue = clearRectangle(R)
  12568.         elseif R.choice == 73 then --Clear wall
  12569.             utils.checkFuelNeeded(R.length * R.height)
  12570.             print("Removing wall "..R.length.." long x "..R.height.." high")
  12571.             retValue = clearWall(R)
  12572.         elseif R.choice == 74 then --Clear single R.height perimeter wall
  12573.             utils.checkFuelNeeded((R.width + R.length) * 2)
  12574.             print("Recycling wall section "..R.width.." x "..R.length)
  12575.             retValue = clearPerimeter(R)
  12576.         elseif R.choice == 75 then --Clear hollow structure
  12577.             utils.checkFuelNeeded((R.width * R.length) + ((R.width + R.length) * R.height))
  12578.             print("Recycling hollow object "..R.width.." x "..R.length.." height: "..R.height)
  12579.             retValue = clearBuilding(R)
  12580.         elseif R.choice == 76 then --Clear solid structure / extend water pool
  12581.             utils.checkFuelNeeded((R.width * R.length) + ((R.width + R.length) * R.height))
  12582.             print("Recycling solid object w:"..R.width..", l:"..R.length..", h:"..R.height)
  12583.             retValue = clearSolid(R)
  12584.         elseif R.choice == 77 then  -- Dig trench
  12585.             utils.checkFuelNeeded(R.height * R.length * 2)
  12586.             print(thanks)
  12587.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12588.             if R.length == 0 then
  12589.                 print("Digging continuous trench "..R.height.." blocks deep")
  12590.             else
  12591.                 print("Digging trench "..R.length.." blocks long, "..R.height.." blocks deep")
  12592.             end
  12593.             retValue = digTrench(R)
  12594.         elseif R.choice == 78 then --Carve mountain
  12595.             utils.checkFuelNeeded(R.length * R.width * 10)
  12596.             print("Carving mountain side "..R.width.." x "..R.length)
  12597.             retValue = clearMountainSide(R)
  12598.         elseif R.choice == 79 then -- Place floor or Ceiling
  12599.             local blocks = R.width * R.length
  12600.             utils.checkFuelNeeded(blocks)
  12601.             T:checkInventoryForItem({"stone", "log", "planks"}, {blocks, blocks, blocks}, false)
  12602.             R.useBlockType = T:getMostItem()
  12603.             retValue = createFloorCeiling(R) -- R.subChoice integer 1 to 4
  12604.         elseif R.choice == 710 then -- direct commands
  12605.             utils.checkFuelNeeded(200)
  12606.             createRectanglePath(R)
  12607.            
  12608. -- LAVA WATER
  12609.         elseif R.choice == 81 then -- Sand based utilities
  12610.             if R.subChoice == 1 then    -- Drop sand or gravel wall
  12611.                 utils.checkFuelNeeded(100)
  12612.                 T:checkInventoryForItem({"sand", "gravel"}, {1024, 1024}, false)
  12613.                 if R.length == 0 then
  12614.                     print("Building sand wall. Auto length: ")
  12615.                 else
  12616.                     print("Building sand wall. length: "..R.length)
  12617.                 end
  12618.                 retValue = createSandWall(R)
  12619.             elseif R.subChoice == 2 then    -- Fill area with sand
  12620.                 utils.checkFuelNeeded(R.length * R.width)
  12621.                 T:checkInventoryForItem({"sand"}, {1024}, false)
  12622.                 print("Filling area with sand. length: "..R.length.." width: "..R.width)
  12623.                 retValue = sandFillArea(R)
  12624.             elseif R.subChoice == 3 then -- Clear sand wall
  12625.                 utils.checkFuelNeeded(200)
  12626.                 if R.length == 0 then
  12627.                     print("Digging sand. Auto length")
  12628.                 else
  12629.                     print("Digging sand. length: "..R.length)
  12630.                 end
  12631.                 retValue = clearSandWall(R)
  12632.             elseif R.subChoice == 4 then    -- Clear sand filled area
  12633.                 utils.checkFuelNeeded(R.length * R.width * 4)
  12634.                 print("Removing sand cube. length: "..R.length.." width: "..R.width)
  12635.                 retValue = clearSandCube(R)
  12636.             end
  12637.        
  12638.         elseif R.choice == 82 then --build containing wall in water or lava
  12639.             utils.checkFuelNeeded(R.length * R.length)
  12640.             local depth = R.height
  12641.             if depth == 0 then
  12642.                 depth = 20
  12643.             end
  12644.             T:checkInventoryForItem({"stone"}, {R.length * depth}, false)
  12645.             print("Building retaining wall in lava/water. length "..R.length)
  12646.             retValue = createRetainingWall(R)          
  12647.         elseif R.choice == 83 then -- create a rectangle path in water/lava
  12648.             utils.checkFuelNeeded(200)
  12649.             createRectanglePath(R)
  12650.         elseif  R.choice == 84 then -- Delete water/lava
  12651.             if R.width == 0 then
  12652.                 utils.checkFuelNeeded(2000)
  12653.                 T:checkInventoryForItem({"stone"}, {256}, false)
  12654.                 print("Deleting water using auto-detection")
  12655.             else
  12656.                 if R.height == 0 then
  12657.                     utils.checkFuelNeeded(2000)
  12658.                     T:checkInventoryForItem({"stone"}, {256}, false)
  12659.                 else
  12660.                     utils.checkFuelNeeded(R.width * R.length * R.height)
  12661.                     T:checkInventoryForItem({"stone"}, {math.max(R.length, R.width) * 2}, false)
  12662.                 end
  12663.                 print("Deleting enclosed water "..R.width.." x "..R.length.." x ".. R.height)
  12664.             end
  12665.             retValue = utils.drainWaterLava(R)
  12666.         elseif  R.choice == 85 then -- Sinking platform
  12667.             local volume = (R.width + 1) * (R.length + 1)
  12668.             utils.checkFuelNeeded(volume * (R.height + 1))
  12669.             T:checkInventoryForItem({"stone"}, {volume + ((R.length * 2) + (R.width * 2) * R.height) + 1})
  12670.             print(thanks)
  12671.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12672.             print("Building sinking platform")
  12673.             retValue = createSinkingPlatform(R)
  12674.         elseif R.choice == 86 then -- ocean monument utilities
  12675.             if R.subChoice == 1 then    -- Build 4 corner marker columns
  12676.                 --R.useBlockType = "prismarine", R.data = "oceanMonumentColumns"
  12677.                 T:checkInventoryForItem({"stone"}, {448})
  12678.                 retValue = oceanMonumentColumns(R)
  12679.             elseif R.subChoice == 2 then    -- Retaining wall beween 2 columns
  12680.                 T:checkInventoryForItem({"stone"}, {1024})
  12681.                 retValue = createRetainingWall(R)
  12682.             elseif R.subChoice == 3 then    -- Clear plants pre sand draining
  12683.                 retValue = clearWaterPlants(R)
  12684.             elseif R.subChoice == 4 then    -- Use sand draining
  12685.                 utils.checkFuelNeeded(100)
  12686.                 T:checkInventoryForItem({"sand", "gravel"}, {1024, 1024}, false)
  12687.                 if R.length == 0 then
  12688.                     print("Building sand wall. Auto length: ")
  12689.                 else
  12690.                     print("Building sand wall. length: "..R.length)
  12691.                 end
  12692.                 retValue = createSandWall(R)
  12693.             elseif R.subChoice == 5 then    -- remove sand wall
  12694.                 utils.checkFuelNeeded(200)
  12695.                 print("Digging sand from ocean monument")
  12696.                 retValue = clearSandWall(R)
  12697.             elseif R.subChoice == 6 then    -- Drain and remove structure
  12698.                 T:checkInventoryForItem({"stone"}, {1024})
  12699.                 retValue = utils.drainWaterLava(R)
  12700.             end
  12701.         elseif R.choice == 87 then --ladder to water/lava
  12702.             utils.checkFuelNeeded(R.height * 2)
  12703.             T:checkInventoryForItem({"minecraft:ladder"}, {R.height}, true, "Add more to be safe!")
  12704.             local cobble = R.height * 3 + 10
  12705.             T:checkInventoryForItem({"stone"}, {cobble})
  12706.             print(thanks)
  12707.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12708.             print("Creating ladder to bedrock")
  12709.             retValue = createLadderToWater()
  12710.         elseif R.choice == 88 then --remove plants
  12711.             utils.checkFuelNeeded(R.length * R.width * 4)
  12712.             T:checkInventoryForItem({"sand", "stone"}, {64, 64})
  12713.             local width = R.width
  12714.             local length = R.length
  12715.             if width == 0 then
  12716.                 width = "auto"
  12717.             end
  12718.             if length == 0 then
  12719.                 length = "auto"
  12720.             end
  12721.             print("Removing water plants. length: "..length.." width: "..width)
  12722.             retValue = clearWaterPlants(R)
  12723.         elseif R.choice == 89 then -- convert flowing water to source
  12724.             --utils.checkFuelNeeded(R.length * R.width * 4) -- unknown as size not calculated
  12725.             T:checkInventoryForItem({"water_bucket", "bucket"}, {12, 12})
  12726.             T:checkInventoryForItem({"slab"}, {128})
  12727.             print("Converting water to source "..R.width.." x "..R.length.." x ".. R.height)
  12728.             retValue = convertWater(R)
  12729.         elseif R.choice == 810 then -- create sloping water
  12730.             utils.checkFuelNeeded(R.length * R.width * 3)
  12731.             local buckets = math.floor(R.length / 2) + 1
  12732.             T:checkInventoryForItem({"water_bucket", "bucket"}, {buckets, buckets})
  12733.             T:checkInventoryForItem({"slab"}, {R.length * R.width})
  12734.             print("Creating sloping water field "..R.width.." x "..R.length.." x ".. R.height)
  12735.             retValue = createSlopingWater(R)
  12736.         -- BUILDING & RAILWAY
  12737.         elseif R.choice == 91 then -- Build a wall
  12738.             local blocks = R.height * R.length
  12739.             utils.checkFuelNeeded(blocks)
  12740.             T:checkInventoryForItem({"stone", "planks", "bricks"}, {blocks, blocks, blocks})
  12741.             R.useBlockType = T:getMostItem()
  12742.             print("Building a wall using "..R.useBlockType)
  12743.             sleep(2)
  12744.             retValue = buildWall(R)
  12745.         elseif R.choice == 92 then -- Build a rectangular structure
  12746.             local blocks = (R.height * R.length * 2) + (R.height * R.width * 2)
  12747.             utils.checkFuelNeeded(blocks)
  12748.             T:checkInventoryForItem({"stone", "planks", "bricks"}, {blocks, blocks, blocks})
  12749.             R.useBlockType = T:getMostItem()
  12750.             print("Building a house using "..R.useBlockType)
  12751.             sleep(2)
  12752.             retValue = buildStructure(R)
  12753.         elseif R.choice == 93 or R.choice == 94 then -- Build a gable end roof / pitched roof
  12754.             local blocks = ((R.width + 2) * (R.length + 2))
  12755.             utils.checkFuelNeeded(blocks)
  12756.             if menu.getBoolean("Using stairs / planks for roof (y/n)", nil, colors.yellow) then
  12757.                 T:checkInventoryForItem({"planks", "stairs"}, {blocks, blocks})
  12758.             else
  12759.                 T:checkInventoryForItem({"stone"}, {blocks})
  12760.             end
  12761.            
  12762.             R.useBlockType = T:getMostItem()
  12763.             if R.choice == 93 then              -- Build a gableroof
  12764.                 if R.width % 2 == 1 then
  12765.                     T:checkInventoryForItem({"slab"}, {R.length + 2}, false, "Match slabs with roof blocks")
  12766.                 end
  12767.                 blocks = (R.width * 6)
  12768.                 T:checkInventoryForItem({"stone", "planks", "bricks"}, {blocks, blocks, blocks}, true, "Match gable with existing building")
  12769.             else
  12770.                 local isWidthOdd, isLengthOdd, width, length = false, false, 0, 0
  12771.                 R, isWidthOdd, isLengthOdd, width, length = utils.getRoofStats(R)
  12772.                 if isWidthOdd then
  12773.                     T:checkInventoryForItem({"slab"}, {length - 2}, false, "Match slabs with roof blocks")
  12774.                 end
  12775.             end
  12776.             print("Building a roof using "..R.useBlockType)
  12777.             sleep(2)
  12778.             if R.choice == 93 then              -- Build a gableroof
  12779.                 retValue = buildGableRoof(R)
  12780.             else                                -- Build a pitched roof
  12781.                 retValue = buildPitchedRoof(R)
  12782.             end
  12783.         elseif R.choice == 95 or R.choice == 96 then --place redstone torch level or downward slope
  12784.             utils.checkFuelNeeded(10)
  12785.             if R.choice == 95 then
  12786.                 R.data = "level"
  12787.             else
  12788.                 R.data = "up"
  12789.             end
  12790.             T:checkInventoryForItem({"stone"}, {1})
  12791.             R.useBlockType = T:getMostItem("", true)
  12792.             T:checkInventoryForItem({"minecraft:redstone_torch"}, {1})
  12793.             print("Placing redstone torch on ".. R.useBlockType)
  12794.             retValue = placeRedstoneTorch(R)
  12795.         elseif R.choice == 97 or R.choice == 98 then --build downward/upward slope
  12796.             local blocks = R.height * 2
  12797.             if R.height == 0 then
  12798.                 blocks = 64
  12799.             end
  12800.             utils.checkFuelNeeded(blocks)
  12801.             T:checkInventoryForItem({"stone"}, {blocks})
  12802.             print("Building slope")
  12803.             sleep(2)
  12804.             retValue = createRailway(R)
  12805.         elseif R.choice == 101 or R.choice == 102 or R.choice == 103 or R.choice == 104 then -- measure height/depth/length
  12806.             retValue = measure(R)
  12807.         elseif R.choice == 105 then--Borehole
  12808.             retValue = createBorehole(R)
  12809.         end
  12810.     end
  12811.     return retValue
  12812. end
  12813.  
  12814. local function test(R)
  12815.     local lib = {}
  12816.    
  12817.     function lib.dig(direction, bypass, slot)
  12818.         direction = direction or "forward"
  12819.         slot = slot or 1
  12820.         bypass = bypass or true
  12821.        
  12822.         print("direction: "..direction)
  12823.         print("bypass: "..tostring(bypass))
  12824.         print("slot: "..slot)
  12825.        
  12826.     end
  12827.     lib.dig("down")
  12828.     read()
  12829. end
  12830.  
  12831. local function main()
  12832.     local lib = {}
  12833.    
  12834.     function lib.checkLabel()
  12835.         if os.getComputerLabel() == nil then
  12836.             os.setComputerLabel("toolkit")
  12837.             print("Computer label set to "..os.getComputerLabel())
  12838.         end
  12839.     end
  12840.    
  12841.     function lib.checkLibs(libDir, filename)
  12842.         local fileExists = false
  12843.         if fs.exists(libDir) then
  12844.             if not fs.isDir(libDir) then
  12845.                 fs.move(libDir, libDir.."Renamed")
  12846.                 fs.makeDir(libDir)
  12847.             end
  12848.         else
  12849.             fs.makeDir(libDir)
  12850.         end
  12851.         if fs.exists(fs.combine(libDir, filename)) or fs.exists(fs.combine(libDir, filename..".lua")) then
  12852.             fileExists = true
  12853.         end
  12854.         return fileExists
  12855.     end
  12856.    
  12857.     local doContinue = true
  12858.     lib.checkLabel() -- make sure turtle label is set
  12859.     --check if lib folder exists
  12860.     if not lib.checkLibs("lib", "clsTurtle") then
  12861.         -- use pastebin get to download clsTurtle to libs folder
  12862.         print("Missing clsTurtle.lua in libs directory")
  12863.         print("Attempting to obtain from Pastebin...")
  12864.         if shell.run("pastebin","get","tvfj90gK","lib/clsTurtle.lua") then
  12865.             print("clsTurtle.lua installed from Pastebin")
  12866.         else
  12867.             print("failed to install clsTurtle.lua from Pastebin")
  12868.             doContinue = false
  12869.         end
  12870.     end
  12871.     if not lib.checkLibs("lib", "menu") then
  12872.         -- use pastebin get to download menu.lua to libs folder
  12873.         print("Missing menu.lua in libs directory")
  12874.         print("Attempting to obtain from Pastebin...")
  12875.         if shell.run("pastebin","get","BhjbYsw4","lib/menu.lua") then
  12876.             print("menu.lua installed from Pastebin")
  12877.         else
  12878.             print("failed to install menu.lua from Pastebin")
  12879.             doContinue = false
  12880.         end
  12881.     end
  12882.     if doContinue then
  12883.         local result = {}
  12884.         local R =
  12885.         {
  12886.             choice = 0,
  12887.             subChoice = 0,
  12888.             size = 0,
  12889.             width = 0,
  12890.             length = 0,
  12891.             height = 0,
  12892.             depth = 0,
  12893.             up = false,
  12894.             down = false,
  12895.             silent = false,
  12896.             data = "",
  12897.             torchInterval = 0,
  12898.             useBlockType = "",
  12899.             auto = false,
  12900.             side = ""
  12901.         }
  12902.         menu = require("lib.menu")
  12903.         T = require("lib.clsTurtle").new(false) -- true enables logfile to log.txt note dot NOT colon
  12904.         T:clear()
  12905.         doContinue = false  -- reset
  12906.         if args[1] ~= nil then
  12907.             if args[1]:sub(1,1) == "h" then
  12908. local help =
  12909. [[... = any following characters
  12910.  
  12911. tk v...     = mc/ccTweaked versions
  12912. tk log      = enable logging
  12913. tk log d... = enable logging + debug
  12914. tk find     = writes locate.txt
  12915. tk test     = runs test(R)
  12916. tk farm     = runs manageFarm(R)
  12917.  
  12918.  
  12919.  
  12920. Enter to exit]]
  12921.                 menu.colourPrint(help, colours.yellow)
  12922.                 read()
  12923.             elseif args[1] == "log" then
  12924.                 if args[2] ~= nil then
  12925.                     if args[2]:sub(1,1) == "d" then
  12926.                         dbug = true -- set dbug flag
  12927.                         menu.colourPrint("Logging and debugging enabled", colors.lime)
  12928.                     end
  12929.                 else
  12930.                     menu.colourPrint("Logging enabled", colors.lime)
  12931.                 end
  12932.                 if T:getLogExists() then
  12933.                     if menu.getBoolean("Delete existing log file? (y/n)", 3, colors.orange) then
  12934.                         T:deleteLog()
  12935.                         menu.colourPrint("Log file deleted", colors.yellow)
  12936.                     end
  12937.                 end
  12938.                 T:setUseLog(true)
  12939.                 doContinue = true
  12940.                 if dbug then
  12941.                     menu.colourPrint("Enter to continue...", colors.lightBlue)
  12942.                     read()
  12943.                 end
  12944.             elseif args[1] == "farm" then
  12945.                 R.silent = true
  12946.                 R.data = "farm"
  12947.                 R.auto = true
  12948.                 manageFarm(R)
  12949.             --elseif args[1] == "tree" then
  12950.                 --manageTreeFarm() -- use file to read status
  12951.             elseif args[1] == "find" then
  12952.                 -- missing turtle: player used 'tk find'
  12953.                 T:setUseLog(true)
  12954.                 T:setLogFileName("locate.txt")
  12955.                 T:appendLine("Booting succeeded")
  12956.                 T:appendLine("Block ahead: "..T:getBlockType("forward"))
  12957.                 T:appendLine("Block above: "..T:getBlockType("up"))
  12958.                 T:appendLine("Block below: "..T:getBlockType("down"))
  12959.             elseif args[1] == "test" then
  12960.                 test(R)
  12961.             elseif args[1]:find("v") ~= nil then
  12962.                 print("_HOST:")
  12963.                 print()
  12964.                 print(_HOST)
  12965.                 print()
  12966.                 print("Minecraft major version: "..mcMajorVersion)
  12967.                 print("Minecraft minor version: "..mcMinorVersion)
  12968.                 print("ccTweaked major version: "..ccMajorVersion)
  12969.                 print("ccTweaked minor version: "..ccMinorVersion)
  12970.                 print("tk version:              "..tkVersion)
  12971.                 print("clsTurtle version:       "..version)
  12972.                 print("\nEnter to exit")
  12973.                 read()
  12974.             end
  12975.         else
  12976.             doContinue = true
  12977.         end
  12978.         if doContinue then
  12979.             print("Minecraft major version: "..mcMajorVersion)
  12980.             print("Bedrock level: "..bedrock)
  12981.             if T:getUseLog() then
  12982.                 if T:saveToLog("Started with logging enabled", true) then
  12983.                     menu.colourPrint("\nEnter to continue...", colors.lightBlue)
  12984.                     read()
  12985.                 end
  12986.             else
  12987.                 print("Logging disabled")
  12988.             end
  12989.             sleep(1)
  12990.             while R.choice == 0 do
  12991.                 R = chooseTask(R)
  12992.             end
  12993.             if R.choice > 0 then
  12994.                 R = getTask(R)
  12995.                 if R.data ~= "quit" then
  12996.                     result = getTaskInventory(R) -- table of comments
  12997.                 end
  12998.             end
  12999.         end
  13000.         T:clear()
  13001.         table.insert(result, "Thank you for using 'survival toolkit'")
  13002.         local clr = {colors.yellow, colors.orange, colors.green, colors.lightBlue}
  13003.         local count = 1
  13004.         for _, value in ipairs(result) do
  13005.             --print(value)
  13006.             --.print(text, fg, bg, width)
  13007.             menu.colourPrint(tostring(value), clr[count])
  13008.             count = count + 1
  13009.             if count > #clr then
  13010.                 count = 1
  13011.             end
  13012.         end
  13013.     else
  13014.         print("Add missing files and restart")
  13015.     end
  13016. end
  13017.  
  13018. main()
Add Comment
Please, Sign In to add comment