Sedrowow

SurvivalKit FIxed

Jan 13th, 2024 (edited)
46
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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 quantity = tonumber(quantity)
  179.     local fuelNeeded = quantity - tonumber(turtle.getFuelLevel()) -- eg 600
  180.     if fuelNeeded > 0 then
  181.         if T:checkInventoryForItem({"minecraft:lava_bucket"}, {1}, false) == nil then  
  182.             if T:checkInventoryForItem({"coal"}, {math.ceil(fuelNeeded / 60)}, false) == nil then
  183.                 T:checkInventoryForItem({"planks"}, {math.ceil(fuelNeeded / 15)})
  184.             end
  185.         end
  186.         T:refuel(quantity, true)
  187.     end
  188. end
  189.  
  190. function utils.clearVegetation(direction)
  191.     local isAirWaterLava = true -- default true value air/water/lava presumed
  192.     -- blockType, blockModifier, data
  193.     local blockType, blockModifier = T:getBlockType(direction)
  194.     if blockType ~= "" then --not air
  195.         if T:isVegetation(blockType) then
  196.             T:dig(direction)
  197.         elseif blockType:find("water") == nil
  198.                and blockType:find("lava") == nil
  199.                and blockType:find("bubble") == nil
  200.                and blockType:find("ice") == nil then
  201.             -- NOT water, ice or lava
  202.             isAirWaterLava = false -- solid block
  203.         end
  204.     end
  205.    
  206.     return isAirWaterLava --clears any grass or sea plants, returns true if air or water, bubble column or ice
  207. end
  208.  
  209. function utils.createPath(R) -- 51
  210.     --[[places a path in air/lava/water. R can also be of type int]]
  211.     local length = 0
  212.     local reduce = false
  213.     local torchInterval = 8
  214.     if type(R) == "table" then
  215.         length = R.length
  216.         if R.data == "reduce" then
  217.             reduce = true
  218.         end
  219.         torchInterval = R.torchInterval
  220.     else
  221.         length = R
  222.     end
  223.     local numBlocks = 0
  224.    
  225.     if reduce then
  226.         T:forward(1)
  227.         local blockType = T:getBlockType("down")
  228.         local useBlock = blockType
  229.         while blockType == useBlock do
  230.             T:go("x2F1")
  231.             numBlocks = numBlocks + 1
  232.             blockType = T:getBlockType("down")
  233.         end
  234.         utils.goBack(numBlocks + 1)
  235.     else
  236.         for i = 1, 2 do
  237.             T:fillVoid("down", {}, false)
  238.             T:forward(1)
  239.             numBlocks = numBlocks + 1
  240.         end
  241.         local place = utils.clearVegetation("down")
  242.         while place do -- while air, water, normal ice, bubble column or lava below
  243.             if T:fillVoid("down", {}, false) then -- false if out of blocks
  244.                 T:forward(1)
  245.                 numBlocks = numBlocks + 1
  246.                 if numBlocks % torchInterval == 1 or numBlocks == 0 then
  247.                     if T:getItemSlot("minecraft:torch", -1) > 0 then
  248.                         T:turnRight(2)
  249.                         T:place("minecraft:torch", -1, "forward", false)
  250.                         T:turnRight(2)
  251.                     end
  252.                 end
  253.             else
  254.                 break
  255.             end
  256.             if length > 0 and numBlocks >= length then -- not infinite path (length = 0)
  257.                 break
  258.             end
  259.             place = utils.clearVegetation("down")
  260.         end
  261.     end
  262.     return {numBlocks} -- returned as a table in case called as task 51 back to main()
  263. end
  264.  
  265. function utils.createWalledSpace(D)
  266.     --[[
  267.     D.width  = #
  268.     D.length = #
  269.     D.height = #
  270.     D.ceiling = false
  271.     D.floor = false
  272.     D.vDirection = "U" or "D"
  273.     D.hDirection = "LR" or "RL"
  274.     D.goHome = true
  275.     T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  276.     ]]
  277.     local turn  = "R1"
  278.     local oTurn = "L1"
  279.     if D.hDirection == "RL" then
  280.         turn    = "L1"
  281.         oTurn   = "R1"
  282.     end
  283.     local placeF = "C1"
  284.  
  285.     local lib = {}
  286.    
  287.     function lib.getPlace(D, start, finish)
  288.         if start then                       -- start of build
  289.             if D.vDirection == "U" then     -- bottom and going up
  290.                 if D.floor then
  291.                     return "C2"
  292.                 end
  293.             else                            -- D.vDirection == "D"
  294.                 if D.ceiling then
  295.                     return "C0"
  296.                 end
  297.             end
  298.         elseif finish then                  -- end of build
  299.             if D.vDirection == "U" then     -- bottom and going up
  300.                 if D.ceiling then
  301.                     return "C0"
  302.                 end
  303.             else
  304.                 if D.floor then
  305.                     return "C2"
  306.                 end
  307.             end
  308.         end
  309.  
  310.         return ""                           -- start and finish both false
  311.     end
  312.    
  313.     function lib.layer(D, start, finish)
  314.         local outward = true
  315.         local place = lib.getPlace(D, start, finish)
  316.         for width = 1, D.width do
  317.             for length = 1, D.length do
  318.                 if start or finish then
  319.                     T:go(place, false, 0, true)-- place floor / ceiling
  320.                 end
  321.                 if width == 1 then
  322.                     T:go(oTurn..placeF..turn, false, 0, true)       -- face wall and check if block
  323.                 elseif width == D.width then                        -- checking opposite wall
  324.                     if outward then                                 -- travelling away from start
  325.                         T:go(turn..placeF..oTurn, false, 0, true)   -- face wall and check if block
  326.                     else                                            -- travelling towards start
  327.                         T:go(oTurn..placeF..turn, false, 0, true)   -- face wall and check if block
  328.                     end                
  329.                 end
  330.                 -- move forward
  331.                 if length < D.length then
  332.                     T:forward(1)
  333.                 end
  334.             end
  335.             if width < D.width then
  336.                 -- change direction
  337.                 if outward then
  338.                     T:go(placeF..turn.."F1"..oTurn..place..placeF..turn..turn, false, 0, true)
  339.                 else
  340.                     T:go(placeF..oTurn.."F1"..turn..place..placeF..oTurn..oTurn, false, 0, true)
  341.                 end
  342.                 outward = not outward
  343.             else
  344.                 if outward then
  345.                     T:go(placeF..oTurn.."F"..D.width -1 ..oTurn.."F"..D.length - 1 .."C1R2", false, 0, true)
  346.                 else
  347.                     T:go(placeF..turn.."F"..D.width -1 ..oTurn..placeF..turn..turn, false, 0, true)
  348.                 end
  349.             end
  350.         end
  351.     end
  352.    
  353.     T:go("R2"..placeF.."R2", false, 0, true)            -- place block behind
  354.     for height = 1, D.height do
  355.         if height == 1 then
  356.             lib.layer(D, true, false)                   -- first layer, so start = true, finish = false
  357.         elseif height == D.height then     
  358.             lib.layer(D, false, true)                   -- final layer, so start = false, finish = true
  359.         else
  360.             lib.layer(D, false, false)                  -- mid build layer, so start = false, finish = false
  361.         end
  362.         if height < D.height then                       -- go up or down unless finished build
  363.             T:go(D.vDirection.."1")
  364.         end
  365.     end
  366.     if D.goHome then-- ends at starting point
  367.         if D.vDirection == "U" then
  368.             T:down(D.height - 1)
  369.         else
  370.             T:up(D.height - 1)
  371.         end
  372.     end
  373. end
  374.  
  375. function utils.createWaterSource(level)
  376.     if level == nil then
  377.         level = 0
  378.     end
  379.     if level > 0 then
  380.         T:up(level)
  381.     elseif level < 0 then
  382.         T:down(math.abs(level))
  383.     end
  384.     -- assume on flat surface, but allow for blocks above
  385.     T:go("x0C2F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2F1 x0C2R1 F1 x0C2F1 x0C2", false, 0, false)
  386.     T:go("R1F1D1", false, 0, false) --move to corner and drop down
  387.     T:go("C2F1R1 C2F1R1 C2F1R1 C2F1R1", false, 0, false)
  388.     T:go("U1")
  389.     for i = 1, 2 do
  390.         T:placeWater("down")
  391.         T:go("F1R1F1R1", false, 0, false)
  392.     end
  393.     -- refill water buckets
  394.     for i = 1, 2 do
  395.         sleep(0.5)
  396.         T:placeWater("down")
  397.     end
  398.     T:go("R2F1R1F1R1")
  399.     -- end above lower left of pond (starting point)
  400.     return {}
  401. end
  402.  
  403. function utils.drainWaterLava(R) -- 84
  404.     local lib = {}
  405.        
  406.     function lib.startCorner()
  407.         -- assume starting mid 3 high column
  408.         T:go("D1C1R1C1 U1C1 L1C1 U1C1 R1C1 L1D1 C2C0", false, 0, true)
  409.         -- finished on same mid 3 high column with wall in front and right completed
  410.     end
  411.    
  412.     function lib.midWall()
  413.         -- assume starting mid 3 high column
  414.         T:go("D1R1C1 U1C1 U1C1 L1D1 C2C0", false, 0, true)
  415.         -- finished on same mid 3 high column with wall on right completed
  416.     end
  417.    
  418.     function lib.endCorner()
  419.         -- assume starting mid 3 high column
  420.         T:go("D1R1C1 R1C1 U1C1 L1C1 U1C1 R1C1 L2D1 C2C0", false, 0, true)
  421.         -- finished on same mid 3 high column with wall behind and right completed
  422.     end
  423.    
  424.     function lib.backTurn(offset)
  425.         -- assume starting mid 3 high column with completed wall behind
  426.         T:go("L1F"..offset.."L2C1 R1D1C1 U1C1 U1C1 D1")
  427.         -- end next row along the width, facing the back, mid point
  428.         -- wall ahead completed
  429.     end
  430.    
  431.     function lib.frontTurn()
  432.         -- assume starting mid 3 high column facing back
  433.         -- next move is to turn toward previous wall and remove
  434.  
  435.         T:go("L2D1C1 U1C1 U1C1 D1R1 C2C0 F1R2C1 L1")
  436.         -- end facing back ready to remove wall
  437.     end
  438.    
  439.     function lib.placeRetainingWall(distance)
  440.         -- assume starting above 3 block high area facing front (player)
  441.         --T:down(1)
  442.         for i = 1, distance do
  443.             if i == 1 then -- start wall
  444.                 lib.startCorner()
  445.             else
  446.                 if i < distance then -- mid wall
  447.                     lib.midWall()
  448.                 else -- end of the wall
  449.                     lib.endCorner()
  450.                 end
  451.             end
  452.             if i < distance then
  453.                 if not turtle.back() then
  454.                     T:go("R2F1R2")
  455.                 end
  456.                 T:go("C1", false, 0, true)
  457.             end
  458.         end
  459.         return 1
  460.     end
  461.        
  462.     function lib.placeDam(distance)
  463.         --T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  464.         local waterPresent = false
  465.         for i = 1, distance do
  466.             if T:isWater("down") then
  467.                 waterPresent = true
  468.             end
  469.             T:go("C0C2")
  470.             if i < distance then
  471.                 if not turtle.back() then
  472.                     T:go("R2F1R2")
  473.                 end
  474.                 T:go("C1", false, 0, true)
  475.             end
  476.         end
  477.         return waterPresent
  478.     end
  479.    
  480.     function lib.removeDam(distance)
  481.         -- facing towards back, dig wall up down and ahead
  482.         for i = 1, distance do
  483.             T:go("x0x2")
  484.             if i < distance then
  485.                 T:forward(1)
  486.             end
  487.         end
  488.         T:turnRight(2)
  489.         -- end up back to retaining wall, mid point
  490.     end
  491.    
  492.     if R.data == "" then
  493.         if turtle.detectDown() then -- on solid surface
  494.             turtle.forward()
  495.         end
  496.     end
  497.     if deletesWater then --turtle replaces source so use clearSolid()
  498.         R.silent = true
  499.         R.down = true
  500.         R.up = false
  501.         clearSolid(R)
  502.     else -- mc 1.12.15+ turtle does NOT replace source blocks
  503.         -- place first stone along the length of water and measure length
  504.         R = utils.calculateDimensions(R)
  505.         local depth = 0
  506.         for h = 1, R.height do
  507.             local waterPresent = false -- resets at each level
  508.             local row = 0
  509.             T:go("R2D2", false, 0, true)    -- at start, level 2, facing towards the front, move backards
  510.             --lib.startCorner()
  511.             row = row + lib.placeRetainingWall(R.length)
  512.             lib.backTurn(1)
  513.             if lib.placeDam(R.length) then
  514.                 waterPresent = true
  515.             end
  516.             row = row + 1
  517.             -- left side wall has been built, 2 rows of walls laid. row = 2
  518.             while row < R.width - 1 do -- eg width=2, row=2, this will not run. width=5, row=2
  519.                 lib.frontTurn()
  520.                 lib.removeDam(R.length)
  521.                 lib.backTurn(2)
  522.                 if lib.placeDam(R.length) then
  523.                     waterPresent = true
  524.                 end
  525.                 row = row + 1
  526.             end
  527.             -- lay right wall
  528.             lib.frontTurn()
  529.             lib.removeDam(R.length)
  530.             lib.backTurn(2)
  531.             row = row + lib.placeRetainingWall(R.length)
  532.             lib.frontTurn()
  533.             lib.removeDam(R.length) -- faces to front on finish
  534.             T:go("L1F1R1")
  535.             lib.removeDam(R.length) -- faces to front on finish
  536.             depth = depth + 3
  537.             T:go("L1F"..R.width - 1 .."R1D1")
  538.             if depth == R.height or not waterPresent then -- still replacing water
  539.                 T:up(depth - 1) -- when h == R.height will go up
  540.                 break -- in case water dries up before loop has completed
  541.             end
  542.         end
  543.     end
  544.     return {}
  545. end
  546.  
  547. function utils.dropSand()
  548.     while not turtle.detectDown() do -- over water. will be infinite loop if out of sand
  549.         if not T:place("sand", -1, "down", false) then
  550.             print("Out of sand. Add more to continue...")
  551.             sleep(2)
  552.         end
  553.     end
  554.     return true --will only get to this point if turtle.detectDown() = true
  555. end
  556.  
  557. function utils.pause(R)
  558.     --[[
  559.     allows 2 turtles to co-operate
  560.     When they face each other and move together
  561.     R.side = "R" or "L"
  562.     ]]
  563.     local rsIn = rs.getAnalogueInput("front")
  564.     local rsOut = 1
  565.     local present = false
  566.     local confirmed = false
  567.     local timer = 0
  568.     local endTimer = 0
  569.     local finished = false
  570.     T:go(R.side.."1")
  571.     rs.setAnalogueOutput("front", 0) -- switch off output
  572.     local blockType = T:getBlockType("forward")
  573.     while blockType:find("turtle") == nil do
  574.         menu.colourWrite("Waiting for other turtle "..endTimer, colors.orange, nil, nil, false, true)
  575.         blockType = T:getBlockType("forward")
  576.         sleep(0.1)
  577.         timer = timer + 0.1
  578.         if timer >= 1 then
  579.             timer = 0
  580.             endTimer = endTimer + 1
  581.         end
  582.     end
  583.     timer = 0
  584.     endTimer = 0
  585.    
  586.     while not finished do
  587.         if endTimer == 0 then
  588.             if present then
  589.                 if confirmed then
  590.                     menu.colourWrite("Turtle confirmed: input = "..rsIn.." output = "..rsOut, colors.orange, nil, nil, false, true)
  591.                 else
  592.                     menu.colourWrite("Other turtle ok: input = "..rsIn.." output = "..rsOut, colors.orange, nil, nil, false, true)
  593.                 end
  594.             else
  595.                 menu.colourWrite("Waiting: input = "..rsIn.." output = "..rsOut, colors.orange, nil, nil, false, true)
  596.             end
  597.         end
  598.         sleep(0.1)
  599.         timer = timer + 1
  600.         if endTimer > 0 then
  601.             endTimer = endTimer + 1
  602.         end
  603.         if endTimer >= 10 then -- allows time for other computer to get ready
  604.             finished = true
  605.         end
  606.         rs.setAnalogueOutput("front", 1) -- output 1 as a signal initially
  607.         if present then
  608.             rs.setAnalogueOutput("front", rsOut) -- output 1 as a signal initially
  609.         end
  610.         rsIn = rs.getAnalogueInput("front")
  611.         if rsIn == 1 then
  612.             present = true
  613.             if not confirmed then
  614.                 rsOut = 7
  615.             end
  616.         elseif rsIn == 7 then
  617.             present = true
  618.             confirmed = true
  619.             rsOut = 15
  620.         elseif rsIn == 15 or confirmed then
  621.             menu.colourWrite("endTimer active = "..endTimer, colors.orange, nil, nil, false, true)
  622.             endTimer = endTimer + 1 -- start endTimer
  623.         end
  624.     end
  625.     T:go(R.side.."3")
  626.    
  627.     return rsIn -- 15
  628. end
  629.  
  630. function utils.startWaterFunction(inWater, onWater, maxDescent, goIn)
  631.     --[[
  632.         Use with utils.getWaterStatus
  633.         could be inWater and not onWater if on single layer of water with floor below
  634.     ]]
  635.     maxDescent = maxDescent or 1 -- prevents continuous down due to lack of water
  636.     if goIn == nil then -- turtle should submerge
  637.         goIn = true
  638.     end
  639.     local descent = 0 -- counter for going down
  640.     if inWater then -- job done
  641.         return inWater, onWater
  642.     end
  643.     if onWater and goIn then --inWater already returned so must be false
  644.         if turtle.down() then
  645.             if T:getBlockType("forward"):find("water") ~= nil or T:getBlockType("forward"):find("bubble") ~= nil then
  646.                 inWater = true
  647.                 return inWater, onWater
  648.             end
  649.         end
  650.     end
  651.     if not onWater then
  652.         T:forward(1)
  653.     end
  654.     -- should now be above water, but may be further down so onWater still false
  655.     while T:getBlockType("down"):find("water") == nil and T:getBlockType("down"):find("bubble") == nil do-- go down until water below
  656.         if turtle.down() then
  657.             descent = descent + 1
  658.             if descent >= maxDescent then -- limit descent in case no water present
  659.                 onWater = false
  660.                 return inWater, onWater -- false,false
  661.             end
  662.         else
  663.             onWater = false
  664.             return inWater, onWater -- false,false
  665.         end
  666.     end
  667.     -- now above water
  668.     if goIn then
  669.         turtle.down() -- now inside water block
  670.         inWater = true
  671.     end
  672.     return inWater, onWater
  673. end
  674.  
  675. function utils.fillBucket(direction)
  676.     if T:getWater(direction)  then
  677.         sleep(0.3)
  678.         return true
  679.     else
  680.         return false
  681.     end
  682. end
  683.  
  684. function utils.getEmptyBucketCount()
  685.     local lastSlot, leastModifier, total, slotData = T:getItemSlot("minecraft:bucket", -1)
  686.     return total
  687. end
  688.  
  689. function utils.getRoofStats(R)
  690.     local isWidthOdd = R.width % 2 == 1             -- is the width odd or even?
  691.     local isLengthOdd = R.length % 2 == 1           -- is the length odd or even?
  692.     if isWidthOdd then
  693.         R.height = math.floor(R.width / 2)          -- eg 7 x 5 roof, layers = 5 / 2 = 2
  694.     else
  695.         R.height = R.width / 2                      -- eg 17 x 8 roof, layers = 8 / 2 = 4
  696.     end
  697.    
  698.     local width = 2                                 -- assume even width with  2 block roof ridge
  699.     local length = R.length - R.height - 1          -- assume even width with  2 block roof ridge
  700.     if isWidthOdd then
  701.         width = 3                                   -- adjust to allow for single width roof ridge
  702.     end
  703.     if isLengthOdd then
  704.         length = R.length - R.height                -- adjust as 1 layer less
  705.     end
  706.    
  707.     return R, isWidthOdd, isLengthOdd, width, length
  708. end
  709.  
  710. function utils.getWater()
  711.     if deletesWater then
  712.         T:getWater("down") -- take water from source
  713.         sleep(0.2)
  714.         T:getWater("down") -- take water from source
  715.     else
  716.         if not turtle.detectDown() then
  717.             T:go("C2", false, 0, false)
  718.         end
  719.         T:getWater("forward") -- take water from source
  720.         sleep(0.2)
  721.         T:getWater("forward") -- take water from source
  722.     end
  723. end
  724.  
  725. function utils.getWaterBucketCount()
  726.     -- lastSlot, leastModifier, total, slotData  = T:getItemSlot(item, useDamage)
  727.     local lastSlot, leastModifier, total, slotData = T:getItemSlot("minecraft:water_bucket", -1)
  728.     return total
  729. end
  730.  
  731. function utils.getWaterStatus()
  732.     --[[ Usage:
  733.     local inWater, onWater = utils.getWaterStatus() -- returns turtle position near water
  734.     utils.startWaterFunction(onWater, inWater, 2, true) -- move INTO water max 2 blocks down
  735.     utils.startWaterFunction(onWater, inWater, 5, false) -- move ABOVE water max 5 blocks down
  736.     ]]
  737.     local onWater = false
  738.     local inWater = false
  739.     for i = 1, 4 do
  740.         if T:getBlockType("forward"):find("water") ~= nil  or T:getBlockType("forward"):find("bubble") ~= nil then
  741.             inWater = true
  742.         end
  743.         T:turnRight(1)
  744.     end
  745.     if T:getBlockType("down"):find("water") ~= nil or T:getBlockType("down"):find("bubble") ~= nil then
  746.         onWater = true
  747.     end
  748.     return inWater, onWater
  749. end
  750.  
  751. function utils.goBack(blocks)
  752.     blocks = blocks or 1
  753.     local success = true
  754.     for i = 1, blocks do
  755.         if not turtle.back() then
  756.             success = false
  757.             T:go("R2F1R2")
  758.         end
  759.     end
  760.    
  761.     return success
  762. end
  763.  
  764. function utils.getPrettyPrint(promptColour, menuPromptColour)
  765.     promptColour = promptColour or colors.yellow
  766.     menuPromptColour = menuPromptColour or colors.white
  767.    
  768.     local pp = {}
  769.     pp.prompt = promptColour
  770.     pp.itemColours = {}
  771.     pp.menuPrompt = menuPromptColour
  772.     pp.allowModifier = true -- can the menu return 'q' or 'h' / 'i'
  773.    
  774.     return pp
  775. end
  776.  
  777. function utils.move(R, blocks, reverse)
  778.     if reverse == nil then
  779.         reverse = false
  780.     end
  781.     if reverse then
  782.         if R.subChoice == 2 then -- reverse direction
  783.             T:up(blocks)
  784.         else
  785.             T:down(blocks)
  786.         end
  787.         return blocks * -1
  788.     else
  789.         if R.subChoice == 1 then
  790.             T:up(blocks)
  791.         else
  792.             T:down(blocks)
  793.         end
  794.         return blocks
  795.     end
  796. end
  797.  
  798. function utils.setStorageOptions()
  799.     local storage = ""
  800.     local storageBackup = ""
  801.     if T:getItemSlot("barrel") > 0 then
  802.         storage = "barrel"
  803.         storageBackup = "barrel"
  804.     end
  805.     if T:getItemSlot("chest") > 0 then
  806.         if storage == "" then
  807.             storage = "chest"
  808.         end
  809.         storageBackup = "chest"
  810.     end
  811.     return storage, storageBackup
  812. end
  813.  
  814. local pp = utils.getPrettyPrint()
  815.  
  816. local function buildWall(R)
  817.     -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  818.     local lib = {}
  819.    
  820.     function lib.singleLayer(R)
  821.         for l = 1, R.length do
  822.             if l == R.length and R.data == "house" then
  823.                 T:turnRight(1)
  824.             end
  825.             utils.goBack(1)
  826.             T:go("C1", false, 0, false, R.useBlockType)
  827.         end
  828.     end
  829.    
  830.     function lib.doubleLayer(R)
  831.         for l = 1, R.length do
  832.             T:go("C2", false, 0, false, R.useBlockType)
  833.             if l == R.length and R.data == "house" then
  834.                 T:turnRight(1)
  835.             end
  836.             utils.goBack(1)
  837.             T:go("C1", false, 0, false, R.useBlockType)
  838.         end
  839.     end
  840.    
  841.     function lib.tripleLayer(R)
  842.         for l = 1, R.length do
  843.             T:go("C2C0", false, 0, false, R.useBlockType)
  844.             if l == R.length and R.data == "house" then
  845.                 T:turnRight(1)
  846.             end
  847.             utils.goBack(1)
  848.             T:go("C1", false, 0, false, R.useBlockType)
  849.         end
  850.     end
  851.    
  852.     -- R.width preset to 1
  853.     local remaining = R.height
  854.    
  855.     if R.subChoice == 1 then
  856.         T:forward(1)            -- face forward, move over first block
  857.     end
  858.     if R.height > 1 then
  859.         T:up(1)                 -- go up 1 block
  860.     end
  861.     if R.data ~= "house" then
  862.         T:turnRight(2)              -- rotate 180
  863.     end
  864.     if R.height == 1 then       -- single block: place in front
  865.         lib.singleLayer(R)
  866.     elseif R.height == 2 then   -- 2 blocks, go backwards, place below and ahead
  867.         lib.doubleLayer(R)
  868.     else
  869.         while remaining >= 3 do
  870.             lib.tripleLayer(R)
  871.             remaining = remaining - 3
  872.             if remaining == 1 then
  873.                 T:go("U2F1R2")
  874.             elseif remaining > 1 then
  875.                 T:go("U3F1R2")
  876.             end
  877.         end
  878.         if remaining == 1 then
  879.             lib.singleLayer(R)
  880.         elseif remaining == 2 then
  881.             lib.doubleLayer(R)
  882.         end
  883.     end
  884.     if not R.silent then
  885.         while turtle.down() do end
  886.     end
  887.    
  888.     return {}
  889. end
  890.  
  891. local function buildStructure(R)
  892.     local lib = {}
  893.    
  894.     function lib.goDown(R)
  895.         --T:go("L1F1 R1F1 L1")  -- now on ground floor
  896.         if R.height > 1 then
  897.             T:down(1)
  898.         end
  899.     end
  900.     local buildHeight = R.height
  901.     local height = R.height
  902.     local width = R.width
  903.     local length = R.length
  904.    
  905.     if R.subChoice == 1 then
  906.         T:forward(1)            -- face forward, move over first block
  907.     end
  908.     if R.height > 3 then
  909.         R.height = 3
  910.     end
  911.     T:turnRight(2)
  912.     R.data = "house"
  913.     R.silent = true -- prevent return to ground after buildWall(R)
  914.     R.subChoice = 2 -- do not move forward when building walls
  915.     while height > 0 do
  916.         buildWall(R)
  917.        
  918.         lib.goDown(R)
  919.         R.length = width - 1
  920.         buildWall(R)
  921.         lib.goDown(R)
  922.        
  923.         R.length = length - 1
  924.         buildWall(R)
  925.         lib.goDown(R)
  926.        
  927.         R.length = width - 2
  928.         buildWall(R)
  929.         height = height - R.height  -- 1, 2 or 3
  930.         if height > 0 then
  931.             T:go("U2 R1F1 L1F1")
  932.             R.height = height
  933.             if height > 3 then
  934.                 R.height = 3
  935.             end
  936.             R.length = length
  937.         end
  938.     end
  939.    
  940.     T:go("U2F2")
  941.     while turtle.down() do end
  942.     T:go("R1F1R1")
  943.    
  944.     return {}
  945. end
  946.  
  947. local function buildGableRoof(R)
  948.     --[[
  949.     stairs placement:
  950.        _|   up
  951.      
  952.        T L  forward
  953.        _
  954.         |   down
  955.  
  956.     ]]
  957.     local lib = {}
  958.    
  959.     function lib.placeRoof(R, outward)
  960.         for i = 1, R.length + 2 do
  961.             if R.useBlockType:find("stairs") ~= nil then
  962.                 T:place("stairs", 0, "up")
  963.             else
  964.                 T:go("C0", false, 0, false, R.useBlockType)
  965.             end
  966.             if i < R.length + 2 then
  967.                 if outward then
  968.                     T:go("L1F1R1")
  969.                 else
  970.                     T:go("R1F1L1")
  971.                 end
  972.             end
  973.         end
  974.     end
  975.    
  976.     function lib.placeGable(R, outward)
  977.         local width = R.width
  978.         for h = 1, R.height do
  979.             for w = 1, width do
  980.                 T:go("C1")
  981.                 if w < width then
  982.                     if outward then
  983.                         T:go("L1F1R1")
  984.                     else
  985.                         T:go("R1F1L1")
  986.                     end
  987.                 end
  988.             end
  989.             if h < R.height then
  990.                 if outward then
  991.                     T:go("R1F1L1U1")
  992.                 else
  993.                     T:go("L1F1R1U1")
  994.                 end
  995.             end
  996.             width = width - 2
  997.             outward = not outward
  998.         end
  999.         return outward
  1000.     end
  1001.    
  1002.     local outward = true
  1003.     -- go to centre of end wall if odd no, or half width if even
  1004.     R.height = math.floor(R.width / 2)
  1005.     local isOdd = R.width % 2 == 1
  1006.    
  1007.     utils.goBack(1)
  1008.     T:go("R1F"..R.height - 1 .."U"..R.height - 1)   -- top of roof, under top layer
  1009.     for h = 1, R.height + 1 do                      -- place tiles on left side of roof
  1010.         lib.placeRoof(R, outward)
  1011.         if h < R.height + 1 then
  1012.             utils.goBack(1)
  1013.             T:down(1)
  1014.             outward = not outward
  1015.         end
  1016.     end
  1017.     if isOdd then
  1018.         T:go("F"..R.height + 2 .."R2U"..R.height)
  1019.     else
  1020.         T:go("F"..R.height + 1 .."R2U"..R.height)
  1021.     end
  1022.     for h = 1, R.height + 1 do                      -- place tiles on right side of roof
  1023.         lib.placeRoof(R, outward)
  1024.         if h < R.height + 1 then
  1025.             utils.goBack(1)
  1026.             T:down(1)
  1027.             outward = not outward
  1028.         end
  1029.     end
  1030.     -- gable ends
  1031.     if outward then
  1032.         T:go("F1R1U1")
  1033.     else
  1034.         T:go("F1L1U1")
  1035.     end
  1036.     outward = lib.placeGable(R, outward)
  1037.     T:go("F2R2 C1R2F"..R.length - 1 .."D"..R.height - 1)
  1038.     if outward then
  1039.         T:go("R1F"..R.height - 1 .."R1")
  1040.     else
  1041.         T:go("L1F"..R.height - 1 .."L1")
  1042.     end
  1043.     outward = not outward
  1044.     outward = lib.placeGable(R, outward)
  1045.     if isOdd then
  1046.         if outward then
  1047.             T:go("L1F1R1U2F1")
  1048.         else
  1049.             T:go("R1F1L1U2F1")
  1050.         end
  1051.         for i = 1, R.length do
  1052.             T:go("C2F1", false, 0, false)
  1053.         end
  1054.         for i = 1, R.length + 2 do
  1055.             utils.goBack(1)
  1056.             T:place("slab", 0, "forward")
  1057.         end
  1058.     end
  1059.     while turtle.down() do end
  1060.    
  1061.     return {}
  1062. end
  1063.  
  1064. local function buildPitchedRoof(R)
  1065.     --[[
  1066.     stairs placement:
  1067.        _|   up
  1068.      
  1069.        T L  forward
  1070.        _
  1071.         |   down
  1072.  
  1073.     ]]
  1074.     local lib = {}
  1075.        
  1076.     function lib.placeRoofSection(length)
  1077.         -- starts facing centre of building
  1078.         for i = 1, length do
  1079.             if i < length then
  1080.                 if R.useBlockType:find("stairs") ~= nil then
  1081.                     T:place("stairs", 0, "up")
  1082.                 else
  1083.                     T:go("C0", false, 0, false, R.useBlockType)
  1084.                 end
  1085.                 T:go("L1F1R1")
  1086.             end
  1087.         end
  1088.         -- ends facing centre of building
  1089.     end
  1090.    
  1091.     function lib.placeRoof(R, width, length)
  1092.         lib.placeRoofSection(length)
  1093.         T:go("R1")
  1094.         lib.placeRoofSection(width)
  1095.         T:go("R1")
  1096.         lib.placeRoofSection(length)
  1097.         T:go("R1")
  1098.         lib.placeRoofSection(width)
  1099.     end
  1100.    
  1101.     function lib.placeSlabs(length)
  1102.         -- add slabs at top
  1103.         T:go("U2F1L1")
  1104.         if length > 1 then
  1105.             T:forward(length - 3)
  1106.             for i = 1, length - 3 do
  1107.                 T:place("slab", 0, "forward")
  1108.                 utils.goBack(1)
  1109.             end
  1110.             T:place("slab", 0, "forward")
  1111.         else
  1112.             T:place("slab", 0, "forward")
  1113.         end
  1114.         T:go("D2R1")
  1115.         utils.goBack(1)
  1116.     end
  1117.     --[[
  1118.     Turtle MUST be placed on left corner of shortest dimension
  1119.    
  1120.     ****   or T******
  1121.     ****      *******
  1122.     ****      *******
  1123.     ****
  1124.     T***
  1125.     shortest dimension is R.width
  1126.     if width is odd, ignore top layer as is only 1 block wide
  1127.     ]]
  1128.     local isWidthOdd, isLengthOdd, width, length = false, false, 0, 0
  1129.     R, isWidthOdd, isLengthOdd, width, length = utils.getRoofStats(R)
  1130.     T:go("F"..R.height - 1 .."R1F"..R.height - 1 .."U"..R.height - 1)       -- top of roof, under top layer
  1131.     if isWidthOdd then
  1132.         lib.placeSlabs(length)
  1133.     end
  1134.     for h = 1, R.height + 1 do                      -- place tiles on left side of roof
  1135.         lib.placeRoof(R, width, length)
  1136.         length = length + 2                         -- increase dimensions
  1137.         width = width + 2
  1138.         if h < R.height + 1 then
  1139.             utils.goBack(1)
  1140.             T:go("D1R1")
  1141.             utils.goBack(1)
  1142.         end
  1143.     end
  1144.     while turtle.down() do end
  1145.    
  1146.     return {}
  1147. end
  1148.  
  1149. local function clearAndReplantTrees() -- 25
  1150.     --[[ clear all trees in a rectangle area defined by walls, fences or non-dirt blocks
  1151.     replant with same type of sapling. If original tree 2 blocks wide, replant 4 if possible. ]]
  1152.    
  1153.     local lib = {}
  1154.    
  1155.     function lib.getSaplingFromLogType(log)
  1156.         --[[ get type of sapling to plant from log type ]]
  1157.         if log:find("oak") ~= nil then
  1158.             return "minecraft:oak_sapling"
  1159.         elseif log:find("spruce") ~= nil then
  1160.             return "minecraft:spruce_sapling"
  1161.         elseif log:find("birch") ~= nil then
  1162.             return "minecraft:birch_sapling"
  1163.         elseif log:find("jungle") ~= nil then
  1164.             return "minecraft:jungle_sapling"
  1165.         elseif log:find("acacia") ~= nil then
  1166.             return "minecraft:acacia_sapling"
  1167.         elseif log:find("dark_oak") ~= nil then
  1168.             return "minecraft:dark_oak_sapling"
  1169.         end
  1170.         return "sapling"
  1171.     end
  1172.    
  1173.     function lib.plantSapling(sapling, double)
  1174.         --[[ plant sapling(s) ]]
  1175.         if sapling == "" or sapling == nil then sapling = "sapling" end
  1176.         T:up(1)
  1177.         lib.suck()
  1178.         if double then  -- check if enough saplings
  1179.             --slotData.lastSlot, slotData.leastModifier, total, slotData = T:getItemSlot(sapling, -1)
  1180.             local a, b, total, _ = T:getItemSlot(sapling, -1)
  1181.             if total >= 4 then
  1182.                 for i = 1, 4 do
  1183.                     T:place(sapling, -1, "down")
  1184.                     T:go("F1R1")
  1185.                 end
  1186.                 T:forward(1)        -- above pre-planted sapling
  1187.             else
  1188.                 if not T:place(sapling, -1, "down") then
  1189.                     T:place("sapling", -1, "down")
  1190.                 end
  1191.             end
  1192.         else
  1193.             if not T:place(sapling, -1, "down") then
  1194.                 T:place("sapling", -1, "down")
  1195.             end
  1196.         end
  1197.         turtle.select(1)
  1198.     end
  1199.        
  1200.     function lib.suck()
  1201.         --[[ Collect saplings, sticks and apples ]]
  1202.         turtle.select(1)
  1203.         turtle.suck()
  1204.         turtle.suckUp()
  1205.         turtle.suckDown()
  1206.     end
  1207.    
  1208.     function lib.turn(direction)
  1209.         --[[ change direction and return new value for direction ]]
  1210.         if direction == "r" then
  1211.             T:turnRight(1)
  1212.             direction = "l"
  1213.         else
  1214.             T:turnLeft(1)
  1215.             direction = "r"
  1216.         end
  1217.         return direction    -- will only change direction variable if return value is used
  1218.     end
  1219.    
  1220.     function lib.emptyInventory(blockTypeD)
  1221.         --[[ Empty all except 32 of each sapling and 1 chest ]]
  1222.         if blockTypeD == nil then
  1223.             blockTypeD = T:getBlockType("down")
  1224.         end
  1225.         if blockTypeD:find("chest") ~= nil or blockTypeD:find("barrel") ~= nil then
  1226.             -- empty logs, apples, sticks and all but 1 stack of each sapling type
  1227.             T:emptyInventorySelection("down", {"chest", "oak_sapling", "birch_sapling", "spruce_sapling", "acacia_sapling", "jungle_sapling","dark_oak_sapling"},{1, 32, 32, 32, 32, 32, 32})
  1228.             return true
  1229.         else
  1230.             return false
  1231.         end
  1232.     end
  1233.    
  1234.     function lib.moveDown(blockTypeD)
  1235.         --[[ move down until hit ground. Break leaves and continue ]]
  1236.         if blockTypeD == nil then
  1237.             blockTypeD = T:getBlockType("down")
  1238.         end
  1239.         while blockTypeD == "" or blockTypeD:find("leaves") ~= nil do   -- move down, breaking leavse
  1240.             T:down(1)
  1241.             lib.suck()
  1242.             blockTypeD = T:getBlockType("down")
  1243.         end
  1244.         return blockTypeD
  1245.     end
  1246.    
  1247.     function lib.moveForward()
  1248.         --[[ Move forward 1 block only, go down to ground while air or leaves below ]]
  1249.         local blockTypeF = T:getBlockType("forward")
  1250.         local blockTypeD = T:getBlockType("down")
  1251.         if blockTypeF == "" or blockTypeF:find("leaves") ~= nil then    -- air or leaves ahead
  1252.             T:forward(1)                                                -- move forward, breaking leaves
  1253.             T:dig("up")                                                 -- remove leaves / low branches above to allow space for player
  1254.             lib.suck()
  1255.             blockTypeD = lib.moveDown()
  1256.             if not lib.emptyInventory(blockTypeD) then                  -- check if above a corner chest / barrel
  1257.                 if lib.isBorder(blockTypeD) then                        -- not above chest so check if above border
  1258.                     return false, blockTypeD                            -- above a border block so stop
  1259.                 end
  1260.             end
  1261.             blockTypeF = T:getBlockType("forward")
  1262.             return true, blockTypeF                                     -- moved ok, could be air or block in front
  1263.         end
  1264.         return false, blockTypeF                                        -- did not move, obstacle in front NOT leaves or air
  1265.     end
  1266.    
  1267.     function lib.moveUp(blockTypeF)
  1268.         --[[ Move up until air in front (dig leaves / harvest tree) ]]
  1269.         if blockTypeF == nil then
  1270.             blockTypeF = T:getBlockType("forward")
  1271.         end
  1272.         while blockTypeF:find("dirt") ~= nil or
  1273.               blockTypeF:find("grass_block") ~= nil or
  1274.               T:isVegetation(blockTypeF) do -- go up while dirt, grass-block or any vegetation in front
  1275.             T:up(1)
  1276.             blockTypeF = T:getBlockType("forward")
  1277.             if blockTypeF:find("log") ~= nil then
  1278.                 lib.harvestTree(blockTypeF)
  1279.                 return T:getBlockType("forward")
  1280.             elseif blockTypeF:find("leaves") ~= nil then
  1281.                 T:dig("forward")
  1282.                 return ""
  1283.             end
  1284.         end
  1285.         return blockTypeF   -- should be "" (air) or any border block
  1286.     end
  1287.    
  1288.     function lib.harvestTree(blockTypeF)
  1289.         --[[ Fell tree, returns true if double size ]]
  1290.         -- clsTurtle.harvestTree(extend, craftChest, direction)
  1291.         local saplingType = lib.getSaplingFromLogType(blockTypeF)
  1292.         local double = T:harvestTree(false, false, "forward")   -- assume single tree, will auto-discover
  1293.         lib.plantSapling(saplingType, double)
  1294.     end
  1295.    
  1296.     function lib.safeMove()
  1297.         --[[ move forward until border reached. loop breaks at that point ]]
  1298.         local blockTypeF = ""
  1299.         local success = true
  1300.         while success do
  1301.             success, blockTypeF = lib.moveForward()             -- move forward 1 block, return block type ahead
  1302.             if not success then                                 -- did not move forwards, block in the way: either log, dirt/grass, border block or vegetation
  1303.                 if blockTypeF:find("log") then                  -- tree found
  1304.                     lib.harvestTree(blockTypeF)
  1305.                     success = true                              -- block (log) removed, try again
  1306.                 else
  1307.                     success = not lib.isBorder(blockTypeF)      -- Is at border?: if is at border success = false so loop stops
  1308.                     if success then                             -- Not at border. Dirt/grass vegetation in front
  1309.                         blockTypeF = lib.moveUp(blockTypeF)     -- move up until leaves/log/air
  1310.                         success = not lib.isBorder(blockTypeF)  -- Is at border?: if is at border success = false so loop stops
  1311.                         if success then                         -- keep moving forward
  1312.                             if blockTypeF:find("log") then      -- tree found
  1313.                                 lib.harvestTree(blockTypeF)
  1314.                             end
  1315.                                                                 -- else blockTypeF is air/leaves  border has been checked
  1316.                         end
  1317.                     end
  1318.                 end
  1319.             end                                                 -- else success = true, 1 block moved so continue
  1320.         end
  1321.     end
  1322.    
  1323.     function lib.isBorder(blockType)
  1324.         --[[ Is the block log, dirt, grass_block, vegetation: non-border, or other:border]]
  1325.         if blockType == nil then                    -- not passed as parameter
  1326.             blockType = T:getBlockType("forward")
  1327.         end
  1328.         if blockType == "" then                     -- air ahead: not border
  1329.             return false, ""
  1330.         else                                        -- could be border or other
  1331.             if blockType:find("dirt") ~= nil or blockType:find("grass_block") ~= nil or blockType:find("log") ~= nil then -- either dirt, grass block or log
  1332.                 return false, blockType             -- dirt, grass, log: not border
  1333.             end
  1334.             if T:isVegetation(blockType) then       -- vegetation found: not border
  1335.                 return false, blockType
  1336.             end
  1337.         end
  1338.         return true, blockType                      -- dirt, grass_block, log and vegetation eliminated:must be border
  1339.     end
  1340.    
  1341.     function lib.inPosition()
  1342.         --[[ check if in lower left corner ]]
  1343.         local inPosition = true         -- assume correct
  1344.         if not turtle.detectDown() then -- hanging in mid-air
  1345.             return false
  1346.         end
  1347.         T:turnLeft(1)
  1348.         if lib.isBorder() then
  1349.             -- so far so good
  1350.             T:turnLeft(1)
  1351.             if not lib.isBorder() then  -- not in correct place
  1352.                 inPosition = false
  1353.             end
  1354.             T:turnRight(2)              -- return to original position
  1355.         else
  1356.             inPosition = false
  1357.             T:turnRight(1)              -- return to original position
  1358.         end
  1359.         return inPosition
  1360.     end
  1361.    
  1362.     function lib.findBorder()
  1363.         --[[ assume started after reset. if log above harvest tree else return to ground. Find starting corner]]
  1364.         local blockType = T:getBlockType("up")                  -- dig any logs above, return to ground
  1365.         local log = "sapling"
  1366.         if blockType:find("log") ~= nil then                    -- originally felling a tree so complete it
  1367.             log = lib.getSaplingFromLogType(blockType)
  1368.             local double = T:harvestTree(false, false, "up")    -- assume single tree, will auto-discover
  1369.             lib.plantSapling(log, double)
  1370.         else                                                    -- no log above so go downm
  1371.             blockType = lib.moveDown()                          -- return to ground (or vegetation)
  1372.         end
  1373.         lib.safeMove()                                          -- move forward until border reached
  1374.         T:turnRight(1)
  1375.         lib.safeMove()                                          -- move forward until second border reached
  1376.         T:turnRight(1)                                          -- should now be in correct position
  1377.         lib.emptyInventory()                                    -- empty inventory if above a chest
  1378.     end
  1379.    
  1380.     local direction = "r"
  1381.     local blockTypeF = ""
  1382.     local success = false
  1383.     if not lib.inPosition() then
  1384.         lib.findBorder()
  1385.     end
  1386.     local secondBorderFound = false
  1387.     while not secondBorderFound do
  1388.         lib.safeMove()                                                      -- moves forward until reaches border forward or below
  1389.         lib.turn(direction)                                                 -- turn r or l. direction is not changed
  1390.         success, blockTypeF = lib.isBorder()                                -- no blockType passed as parameter so will return current block in new forward direction
  1391.         if success then
  1392.             secondBorderFound = true                                        -- game over
  1393.         elseif blockTypeF:find("log") ~= nil then                           -- tree in front
  1394.             lib.harvestTree(blockTypeF)
  1395.         elseif blockTypeF == "" or blockTypeF:find("leaves") ~= nil then    -- air or leaves in front
  1396.             T:forward(1)                                                    -- move forward 1 block
  1397.             lib.moveDown()                                                  -- go down if required
  1398.         elseif  blockTypeF:find("dirt") ~= nil or
  1399.                 blockTypeF:find("grass_block") ~= nil or
  1400.                 T:isVegetation(blockTypeF) then                             -- dirt, grass_block or vegetation in front
  1401.             blockTypeF = lib.moveUp(blockTypeF)                             -- move up until air or border ahead.
  1402.             if lib.isBorder(blockTypeF) then                                -- border ahead
  1403.                 secondBorderFound = true
  1404.             else                                                            -- air ahead                                   
  1405.                 T:forward(1)                                                -- move forward 1 block
  1406.             end
  1407.         end
  1408.         direction = lib.turn(direction)                                     -- turn r or l. direction is changed to opposite
  1409.     end
  1410.     lib.moveDown()                                                          -- return to ground level
  1411.     lib.emptyInventory()
  1412.     return {}
  1413. end
  1414.  
  1415. local function clearArea(R) -- 71, called from 22
  1416.     local evenWidth = false
  1417.     local evenHeight = false
  1418.     local loopWidth
  1419.     -- go(path, useTorch, torchInterval, leaveExisting)
  1420.     if R.width % 2 == 0 then
  1421.         evenWidth = true
  1422.         loopWidth = R.width / 2
  1423.     else
  1424.         loopWidth = math.ceil(R.width / 2)
  1425.     end
  1426.     if R.length % 2 == 0 then
  1427.         evenHeight = true
  1428.     end
  1429.     turtle.select(1)
  1430.     -- clear an area between 2 x 4 and 32 x 32
  1431.     -- if R.width is even no, then complete the up/down run
  1432.     -- if R.width odd no then finish at top of up run and reverse
  1433.     -- should be on flat ground, check voids below, harvest trees
  1434.     for x = 1, loopWidth do
  1435.         -- Clear first column (up)
  1436.         for y = 1, R.length do
  1437.             if R.useBlockType == "dirt" then
  1438.                 if not turtle.detectDown() then
  1439.                     T:place("minecraft:dirt", -1, "down", true)
  1440.                 else --if not water, dirt, grass , stone then replace with dirt
  1441.                     blockType, blockModifier = T:getBlockType("down")
  1442.                     if blockType ~= "" then
  1443.                         if blockType ~= "minecraft:dirt" and blockType ~= "minecraft:grass_block" then
  1444.                             turtle.digDown()
  1445.                             T:place("minecraft:dirt", -1, "down", true)
  1446.                         end
  1447.                     end
  1448.                 end
  1449.             end
  1450.             if y < R.length then
  1451.                 T:go("F1+1", false,0,false)
  1452.             end
  1453.         end
  1454.         -- clear second column (down)
  1455.         if x < loopWidth or (x == loopWidth and evenWidth) then -- go down if on R.width 2,4,6,8 etc
  1456.             T:go("R1F1+1R1", false,0,false)
  1457.             for y = 1, R.length do
  1458.                 if R.useBlockType == "dirt" then
  1459.                     if not turtle.detectDown() then
  1460.                         T:place("minecraft:dirt", -1, "down", true)
  1461.                     else
  1462.                         blockType, blockModifier = T:getBlockType("down")
  1463.                         if blockType ~= "" then
  1464.                             if blockType ~= "minecraft:dirt" and blockType ~= "minecraft:grass_block" then
  1465.                                 turtle.digDown()
  1466.                                 T:place("minecraft:dirt", -1, "down", true)
  1467.                             end
  1468.                         end
  1469.                     end
  1470.                 end
  1471.                 if y < R.length then
  1472.                     T:go("F1+1", false, 0, false)
  1473.                 end
  1474.             end
  1475.             if x < loopWidth then
  1476.                 T:go("L1F1+1L1", false,0,false)
  1477.             else
  1478.                 T:turnRight(1)
  1479.                 T:forward(R.width - 1)
  1480.                 T:turnRight(1)
  1481.             end
  1482.         else -- equals R.width but is 1,3,5,7 etc
  1483.             T:turnLeft(2) --turn round 180
  1484.             T:forward(R.length - 1)
  1485.             T:turnRight(1)
  1486.             T:forward(R.width - 1)
  1487.             T:turnRight(1)
  1488.         end
  1489.     end
  1490.     return {}
  1491. end
  1492.  
  1493. local function clearRectangle(R) -- 72
  1494.     --local function clearRectangle(width, length, up, down)
  1495.     -- height = 0: one level, 1 = +up, 2 = +down, 3 = +up/down
  1496.     local lib = {}
  1497.     function lib.UpDown(length)
  1498.         for l = 1, length do
  1499.             T:go("x0x2F1x0x2")
  1500.         end
  1501.     end
  1502.    
  1503.     function lib.Up(length)
  1504.         for l = 1, length do
  1505.             T:go("x0F1x0")
  1506.         end
  1507.     end
  1508.    
  1509.     function lib.Down(length)
  1510.         for l = 1, length do
  1511.             T:go("x2F1x2")
  1512.         end
  1513.     end
  1514.    
  1515.     function lib.Forward(length)
  1516.         T:forward(length)
  1517.     end
  1518.    
  1519.     -- could be 1 wide x xx R.length (trench) R.up and return
  1520.     -- could be 2+ x 2+
  1521.     -- even no of runs return after last run
  1522.     -- odd no of runs forward, back, forward, reverse and return
  1523.     turtle.select(1)
  1524.     if R.width == 1 then                    -- single block trench ahead only
  1525.         if R.up and R.down then             -- single block wide trench dig R.up and R.down = 3 blocks deep
  1526.             lib.UpDown(R.length - 1)
  1527.         elseif R.up then                    -- single block wide trench dig R.up = 2 blocks deep
  1528.             lib.Up(R.length - 1)
  1529.         elseif R.down then              -- single block wide trench dig R.down = 2 blocks deep
  1530.             lib.Down(R.length - 1)
  1531.         else                            -- single block wide = 1 block deep
  1532.             lib.Forward(R.length - 1)
  1533.         end
  1534.         T:turnRight(2)                  -- turn at the top of the run
  1535.         T:forward(R.length - 1)         -- return to start
  1536.         T:turnRight(2)                  -- turn round to original position
  1537.     else                                -- R.width 2 or more blocks
  1538.         local iterations = 0            -- R.width = 2, 4, 6, 8 etc
  1539.         if R.width % 2 == 1 then        -- R.width = 3, 5, 7, 9 eg R.width 7
  1540.             iterations = (R.width - 1) / 2 -- iterations 1, 2, 3, 4 for widths 3, 5, 7, 9
  1541.         else
  1542.             iterations = R.width / 2        -- iterations 1, 2, 3, 4 for widths 2, 4, 6, 8
  1543.         end
  1544.         for i = 1, iterations do        -- eg 3 blocks wide, iterations = 1
  1545.             if R.up and R.down then                         -- dig R.up and R.down
  1546.                 lib.UpDown(R.length - 1)
  1547.                 T:go("x0x2R1F1x0x2R1x0x2")              -- turn round
  1548.                 lib.UpDown(R.length - 1)
  1549.             elseif R.up then                                -- dig R.up
  1550.                 lib.Up(R.length - 1)
  1551.                 T:go("x0R1F1x0R1x0")
  1552.                 lib.Up(R.length - 1)
  1553.             elseif R.down then                          -- dig R.down
  1554.                 lib.Down(R.length - 1)
  1555.                 T:go("x2R1F1x2R1x2")
  1556.                 lib.Down(R.length - 1)
  1557.             else                                        -- no digging R.up or R.down
  1558.                 lib.Forward(R.length - 1)
  1559.                 T:go("R1F1R1")
  1560.                 lib.Forward(R.length - 1)
  1561.             end
  1562.             -- if 1 less than end, reposition for next run
  1563.             if i < iterations then
  1564.                 T:go("L1F1L1", false, 0, false)
  1565.             end
  1566.         end
  1567.         if R.width % 2 == 1 then  -- additional run and return to base needed
  1568.             T:go("L1F1L1", false, 0, false)
  1569.             if R.up and R.down then
  1570.                 lib.UpDown(R.length - 1)
  1571.             elseif R.up then
  1572.                 lib.Up(R.length - 1)
  1573.             elseif R.down then
  1574.                 lib.Down(R.length - 1)
  1575.             else
  1576.                 lib.Forward(R.length - 1)
  1577.             end
  1578.             T:turnRight(2)
  1579.             T:forward(R.length - 1)
  1580.         end
  1581.         T:go("R1F"..R.width - 1 .."R1", false, 0, false)
  1582.     end
  1583.     return {}
  1584. end
  1585.  
  1586. local function clearPerimeter(R) -- 74
  1587.     local lib = {}
  1588.     function lib.UpDown(length)
  1589.         for l = 1, length do
  1590.             T:go("x0x2F1x0x2")
  1591.         end
  1592.     end
  1593.    
  1594.     function lib.Up(length)
  1595.         for l = 1, length do
  1596.             T:go("x0F1x0")
  1597.         end
  1598.     end
  1599.    
  1600.     function lib.Down(length)
  1601.         for l = 1, length do
  1602.             T:go("x2F1x2")
  1603.         end
  1604.     end
  1605.    
  1606.     function lib.Forward(length)
  1607.         T:forward(length)
  1608.     end
  1609.    
  1610.     if R.up and R.down then
  1611.         for i = 1, 2 do
  1612.             lib.UpDown(R.length - 1)
  1613.             T:turnRight(1)
  1614.             lib.UpDown(R.width - 1)
  1615.             T:turnRight(1)
  1616.         end
  1617.     elseif R.up then
  1618.         for i = 1, 2 do
  1619.             lib.Up(R.length - 1)
  1620.             T:turnRight(1)
  1621.             lib.Up(R.width - 1)
  1622.             T:turnRight(1)
  1623.         end
  1624.     elseif R.down then
  1625.         for i = 1, 2 do
  1626.             lib.Down(R.length - 1)
  1627.             T:turnRight(1)
  1628.             lib.Down(R.width - 1)
  1629.             T:turnRight(1)
  1630.         end
  1631.     else
  1632.         for i = 1, 2 do
  1633.             lib.Forward(R.length - 1)
  1634.             T:turnRight(1)
  1635.             lib.Forward(R.width - 1)
  1636.             T:turnRight(1)
  1637.         end
  1638.     end
  1639.     return {}
  1640. end
  1641.  
  1642. local function clearBuilding(R) -- 75, 43
  1643.     --[[
  1644.     Clear the outer shell of a building, leaving inside untouched. Optional floor/ceiling removal
  1645.     clearBuilding(R)
  1646.     R.subChoice = 1-'up' or 2-'down'
  1647.     R.data.ceiling = true / false
  1648.     R.data.floor = true / false
  1649.     ]]
  1650.     local height = 1
  1651.     local remaining = R.height -- eg 5
  1652.     local start = true
  1653.     local finish = false
  1654.     local lib = {}
  1655.    
  1656.     function lib.floorOrCeiling(R)
  1657.         T:go("F1R1 F1L1")
  1658.         R.length = R.length - 2
  1659.         R.width = R.width - 2
  1660.         clearRectangle(R)
  1661.         R.length = R.length + 2
  1662.         R.width = R.width + 2
  1663.         T:go("L1F1R1")
  1664.         utils.goBack(1)
  1665.     end
  1666.    
  1667.     function lib.singleLayer(R)
  1668.         R.up = false
  1669.         R.down = false
  1670.         if start then
  1671.             if R.data.ceiling or R.data.floor then  -- floor / ceiling to go. only one layer, so clearRectangle
  1672.                 lib.floorOrCeiling(R)
  1673.             end
  1674.             start = false
  1675.         end
  1676.         if finish then
  1677.             if R.data.ceiling or R.data.floor then  -- floor / ceiling to go. only one layer, so clearRectangle
  1678.                 lib.floorOrCeiling(R)
  1679.             end
  1680.             finish = false
  1681.         end
  1682.         clearPerimeter(R)                       -- no floor / ceiling
  1683.     end
  1684.    
  1685.     function lib.doubleLayer(R)
  1686.         R.up = false
  1687.         R.down = false
  1688.         if start then
  1689.             if R.data.floor and R.subChoice == 1 then       -- going up and floor needs removing
  1690.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1691.             elseif R.data.ceiling and R.subChoice == 2 then -- going down and ceiling needs removing
  1692.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1693.             end
  1694.             start = false
  1695.         end
  1696.         if finish then
  1697.             if R.data.ceiling and R.subChoice == 1 then     -- going down and ceiling needs removing
  1698.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1699.             elseif R.data.floor and R.subChoice == 2 then   -- going down and floor needs removing
  1700.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1701.             end
  1702.             finish = false
  1703.         end
  1704.         if R.subChoice == 1 then
  1705.             R.up = true
  1706.         else
  1707.             R.down = true
  1708.         end
  1709.         clearPerimeter(R)
  1710.     end
  1711.    
  1712.     function lib.tripleLayer(R)
  1713.         -- turtle in centre layer
  1714.         R.up = false
  1715.         R.down = false
  1716.         if start then
  1717.             if R.data.floor and R.subChoice == 1 then       -- going up and floor needs removing
  1718.                 height = height + utils.move(R, 1, true)    -- move down 1 block
  1719.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1720.                 height = height + utils.move(R, 1)      -- move up 1 block
  1721.             elseif R.data.ceiling and R.subChoice == 2 then -- going down and ceiling needs removing
  1722.                 height = height + utils.move(R, 1, true)    -- move up 1 block
  1723.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1724.                 height = height + utils.move(R, 1)      -- move down 1 block
  1725.             end
  1726.             start = false
  1727.         end
  1728.         if finish then
  1729.             if R.data.ceiling and R.subChoice == 1 then     -- going up and ceiling needs removing
  1730.                 height = height + utils.move(R, 1, true)                    -- move down 1 block
  1731.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1732.                 height = height + utils.move(R, 1)                          -- move up 1 block
  1733.             elseif R.data.floor and R.subChoice == 2 then   -- going down and floor needs removing
  1734.                 height = height + utils.move(R, 1, true)                    -- move up 1 block
  1735.                 lib.floorOrCeiling(R)                       -- remove floor/ceiling
  1736.                 height = height + utils.move(R, 1)                          -- move up 1 block
  1737.             end
  1738.             finish = false
  1739.         end
  1740.         R.up = true
  1741.         R.down = true
  1742.         clearPerimeter(R)
  1743.     end
  1744.     --[[
  1745.     R.data = "up" or "down" as direction of travel
  1746.     R.up = true to remove ceiling
  1747.     R.down = true to remove floor
  1748.     ]]
  1749.     R.silent = true
  1750.     if R.height < 3 then                        --1-3 layers only
  1751.         if R.height == 1 then                   --one layer only
  1752.             lib.singleLayer(R)
  1753.         elseif R.height == 2 then               --2 layers only current + dig up/down
  1754.             lib.doubleLayer(R)
  1755.         end
  1756.     else -- 3 or more levels
  1757.         height = height + utils.move(R, 1)                          -- move up/down 1 block for first layer
  1758.         while remaining >= 3 do -- min 3 levels
  1759.             lib.tripleLayer(R)
  1760.             remaining = remaining - 3
  1761.             if remaining == 0 then              -- all finished
  1762.                 break
  1763.             elseif remaining == 1 then
  1764.                 height = height + utils.move(R, 2)                  -- move up/down 2 blocks
  1765.                 lib.singleLayer(R)
  1766.             elseif remaining == 2 then
  1767.                 height = height + utils.move(R, 2)                  -- move up/down 2 blocks
  1768.                 lib.doubleLayer(R)
  1769.             else
  1770.                 height = height + utils.move(R, 3)                  -- move up/down 3 blocks
  1771.                 if remaining == 3 then
  1772.                     finish = true
  1773.                 else
  1774.                     --height = height + 3
  1775.                 end
  1776.             end
  1777.         end
  1778.     end
  1779.    
  1780.     if height > 1 then
  1781.         utils.move(R, height - 1, true) -- reverse direction
  1782.     end
  1783.    
  1784.     return {}
  1785. end
  1786.  
  1787. local function clearMineshaft(R, equippedRight, equippedLeft, inInventory) -- 19
  1788.     local lib = {}
  1789.    
  1790.     function lib.checkCobweb(directions, inInventory)
  1791.         assert(type(directions) == "table", "directions must be a table eg {'up','down'}")
  1792.         for _, direction in ipairs(directions) do
  1793.             local blockType = T:getBlockType(direction)
  1794.             if inInventory == "minecraft:diamond_sword" then -- using a sword
  1795.                 local side = "left"
  1796.                
  1797.                 if blockType:find("cobweb") ~= nil then
  1798.                     --clsTurtle.equip(self, side, useItem, useDamage)
  1799.                     if equippedRight == "minecraft:diamond_pickaxe" then
  1800.                         side = "right"
  1801.                     end
  1802.                     T:equip(side, "minecraft:diamond_sword")
  1803.                     T:dig(direction)
  1804.                     T:equip(side, "minecraft:diamond_pickaxe")
  1805.                 elseif blockType ~= "" then
  1806.                     T:dig(direction)
  1807.                 end
  1808.             else
  1809.                 T:dig(direction)
  1810.             end
  1811.         end
  1812.     end
  1813.  
  1814.     -- check position by rotating until facing away from wall
  1815.     length = 0
  1816.     torch = 0
  1817.     turns = 0
  1818.     while not turtle.detect() do
  1819.         T:turnRight(1)
  1820.         turns = turns + 1
  1821.         if turns > 4 then
  1822.             return {"I am not facing a wall. Unable to continue"}
  1823.         end
  1824.     end
  1825.     T:turnRight(2)
  1826.     -- move forward until obstructed, digging up/down. place torches
  1827.     while not turtle.detect() do
  1828.         lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1829.         length = length + 1
  1830.         torch = torch + 1
  1831.         if torch == R.torchInterval then
  1832.             torch = 0
  1833.             T:place("minecraft:torch", -1, "down", false) ---(self, blockType, damageNo, direction, leaveExisting, signText)
  1834.         end
  1835.         lib.checkCobweb({"forward"}, inInventory) -- dig cobweb or any other block in front
  1836.         T:forward(1)
  1837.     end
  1838.     -- turn right, forward, right, return to start with up/down dig
  1839.     T:go("R1")
  1840.     lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1841.     T:go("F1R1")
  1842.     for i = 1, length, 1 do
  1843.         lib.checkCobweb({"up", "down", "forward"}, inInventory) -- dig cobweb or any other block up/down/forward
  1844.         T:forward(1)
  1845.     end
  1846.     -- move to other wall and repeat.
  1847.     T:go("R1")
  1848.     lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1849.     T:go("F1")
  1850.     lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1851.     T:go("F1R1")
  1852.     lib.checkCobweb({"up","down"}, inInventory) -- dig cobweb or any other block up/down
  1853.     for i = 1, length, 1 do
  1854.         lib.checkCobweb({"up", "down", "forward"}, inInventory) -- dig cobweb or any other block up/down/forward
  1855.         T:forward(1)
  1856.     end
  1857.     lib.checkCobweb({"up", "down"}, inInventory) -- dig cobweb or any other block up/down/forward
  1858.    
  1859.     return {}
  1860. end
  1861.  
  1862. local function clearMonumentLayer(R) -- 85
  1863.     R.up = true
  1864.     R.down = true
  1865.     R.silent = true
  1866.     if R.subChoice == 0 then
  1867.         R.up = false
  1868.         R.down = false
  1869.     end
  1870.     -- send turtle down until it hits bottom
  1871.     -- then clear rectangle of given size
  1872.     -- start above water, usually on cobble scaffold above monument
  1873.     if T:detect("down") then -- in case not over wall
  1874.         T:forward(1)
  1875.     end
  1876.     local height = 1
  1877.     -- go down until solid block detected
  1878.     while utils.clearVegetation("down") do
  1879.         T:down(1)
  1880.         height = height + 1
  1881.     end
  1882.     T:down(1)
  1883.     height = height + 1
  1884.     clearRectangle(R)
  1885.     T:up(height - 1)
  1886.    
  1887.     return {}
  1888. end
  1889.  
  1890. local function clearWaterPlants(R) -- 87
  1891.     local lib = {}
  1892.    
  1893.     function lib.getLength()
  1894.         local length = 1
  1895.         print("Checking water length")
  1896.         while utils.clearVegetation("forward") do
  1897.             T:forward(1)
  1898.             length = length + 1
  1899.         end
  1900.         for i = 1, length do
  1901.             turtle.back()
  1902.         end
  1903.         return length
  1904.     end
  1905.    
  1906.     function lib.clearDown(D)
  1907.         while utils.clearVegetation("down") do --clears any grass or sea plants, returns true if air or water, bubble column or ice
  1908.             T:down(1)
  1909.             D.depth = D.depth + 1
  1910.         end
  1911.         -- if slab at bottom, replace with solid block
  1912.         D.blockType = T:getBlockType("down")
  1913.         if D.blockType:find("slab") ~= nil then
  1914.             T:go("C2")
  1915.         end
  1916.         if D.depth > D.maxDepth then
  1917.             D.maxDepth = D.depth
  1918.         end
  1919.        
  1920.         return D
  1921.     end
  1922.    
  1923.     function lib.clearLength(D)
  1924.         local moves = 0
  1925.         local blockHeight = 1
  1926.         D.floorLength = 0 -- reset
  1927.         while moves < D.length - 1 do
  1928.             if utils.clearVegetation("forward") then
  1929.                 T:forward(1)
  1930.                 moves = moves + 1
  1931.                 if turtle.detectUp() then -- could be on monument going under arch, or faulty monument floor
  1932.                     if not D.monumentArchesClear then
  1933.                         D = lib.checkArches(D)
  1934.                     end
  1935.                 end
  1936.                 local temp = D.depth
  1937.                 D = lib.clearDown(D) -- go down if in water/air
  1938.                 if blockHeight == 4 and D.depth - temp == 3 then -- could be just gone over 3 block high column in ocean monument
  1939.                     if not D.monumentTopClear then
  1940.                         D = lib.checkTop(D)
  1941.                     end
  1942.                     blockHeight = 1
  1943.                 end
  1944.                 if D.useBlockType == "prismarine" then
  1945.                     if D.blockType:find("prismarine") == nil then
  1946.                         -- on monument floor so restrict forward movement to 8 blocks
  1947.                         D.floorLength = D.floorLength + 1
  1948.                         if D.floorLength == 8 then
  1949.                             D.blockType = T:getBlockType("forward")
  1950.                             while D.blockType:find("prismarine") == nil do
  1951.                                 T:up(1)
  1952.                                 D.blockType = T:getBlockType("forward")
  1953.                             end
  1954.                             D.floorLength = 0
  1955.                         end
  1956.                     end
  1957.                 end
  1958.                 if moves >= D.length - 1 then
  1959.                     D.width = D.width + 1   -- another length completed so increase width
  1960.                     return D
  1961.                 end
  1962.             else -- block in front
  1963.                 blockHeight = 1
  1964.                 local waterAbove = utils.clearVegetation("up")
  1965.                 local waterAhead = utils.clearVegetation("forward") -- true if air/water in front
  1966.                 while not waterAhead do     -- solid block in front
  1967.                     if waterAbove then      -- move up
  1968.                         T:up(1)
  1969.                         D.depth = D.depth - 1
  1970.                         blockHeight = blockHeight + 1
  1971.                         if D.depth < 1 then
  1972.                             D.width = D.width + 1   -- another length completed so increase width
  1973.                             return D
  1974.                         end
  1975.                     else                    -- block above so go back
  1976.                         while not waterAbove do
  1977.                             utils.goBack()  --  returns true if no object behind, but moves anyway
  1978.                             waterAbove = utils.clearVegetation("up")
  1979.                             moves = moves - 1
  1980.                             if moves == 0 then
  1981.                                 T:up(1)
  1982.                                 D.depth = D.depth - 1
  1983.                                 waterAbove = utils.clearVegetation("up")
  1984.                                 while not waterAbove do
  1985.                                     T:up(1)
  1986.                                     D.depth = D.depth - 1
  1987.                                 end
  1988.                             end
  1989.                         end
  1990.                         -- go up 1 to prevent loop
  1991.                         T:up(1)
  1992.                         D.depth = D.depth - 1
  1993.                     end
  1994.                     waterAbove = utils.clearVegetation("up")
  1995.                     waterAhead = utils.clearVegetation("forward")
  1996.                 end
  1997.             end
  1998.         end
  1999.         D.width = D.width + 1   -- another length completed so increase width
  2000.         D.maxDepth = D.maxDepth + 1 -- +1 to allow for starting pos in top layer
  2001.        
  2002.         return D
  2003.     end
  2004.    
  2005.     function lib.checkArches(D)
  2006.         -- gone under a block so could be monument arch (6)
  2007.         if T:getBlockType("up"):find("prismarine") ~= nil then -- confirm on monument, not previously cleared
  2008.             local direction = ""    -- initialise direction
  2009.             T:go("B1U2F1R1")
  2010.             if T:getBlockType("forward"):find("prismarine") ~= nil then -- correct guess
  2011.                 direction = "R"
  2012.             else    -- wrong direction. turn round and check other side
  2013.                 T:go("R2")
  2014.                 if T:getBlockType("forward"):find("prismarine") ~= nil then
  2015.                     direction = "L"
  2016.                 end
  2017.             end
  2018.             local path = "U1F1 U1F3 D1F1 D1R2 U2F5 D2"
  2019.             --for i = 1, 6 do
  2020.             T:go(path) -- clears arch top 1 and returns
  2021.             T:go(direction.."1F6"..direction.."1")
  2022.             T:go(path) -- clears arch top 2 and returns
  2023.             T:go(direction.."1F6"..direction.."1")
  2024.             T:go(path) -- clears arch top 3 and returns
  2025.             T:go(direction.."1F9"..direction.."1")
  2026.             T:go(path) -- clears arch top 4 and returns
  2027.             T:go(direction.."1F6"..direction.."1")
  2028.             T:go(path) -- clears arch top 5 and returns
  2029.             T:go(direction.."1F6"..direction.."1")
  2030.             T:go(path) -- clears arch top 6 and returns
  2031.            
  2032.             T:go(direction.."3F34"..direction.."2D2F1")
  2033.             D.monumentArchesClear =  true
  2034.         end
  2035.         return D
  2036.     end
  2037.    
  2038.     function lib.checkTop(D)
  2039.         -- gone over 3 block column so could be at the top of ocean monument
  2040.         if T:getBlockType("down"):find("prismarine") ~= nil then -- confirm on monument, not previously cleared
  2041.             local direction = ""    -- initialise direction
  2042.             T:go("U3R1")            -- up to top of column and try right side
  2043.             if T:getBlockType("forward"):find("prismarine") ~= nil then -- correct guess
  2044.                 direction = "L"
  2045.             else    -- wrong direction. turn round and check other side
  2046.                 T:go("R2")
  2047.                 if T:getBlockType("forward"):find("prismarine") ~= nil then
  2048.                     direction = "R"
  2049.                 end
  2050.             end
  2051.             if direction ~= "" then -- facing single block on layer 2
  2052.                 T:go("U1F6"..direction.."1F5".. direction.."1F5"..direction.."1F5"..direction.."1") -- clear 4 single blocks
  2053.                 T:go("F1U1"..direction.."1F1"..direction.."3") -- on top of monument
  2054.                 T:go("F3".. direction.."1F3"..direction.."1F3"..direction.."1F3"..direction.."3") -- clear top, face return
  2055.                 T:go("F2D5"..direction.."3B1")
  2056.             end
  2057.             D.monumentTopClear = true
  2058.         end
  2059.         return D
  2060.     end
  2061.    
  2062.     function lib.findBlockTypeEnd(D)
  2063.         D.blockType = "" -- reset
  2064.         repeat
  2065.             if utils.clearVegetation("forward") then
  2066.                 T:forward(1)
  2067.                 D = lib.clearDown(D) -- go down if in water/air, D.blockType is updated with floor type
  2068.             else -- block in front
  2069.                 local waterAbove = utils.clearVegetation("up")
  2070.                 local waterAhead = utils.clearVegetation("forward") -- true if air/water in front
  2071.                 while not waterAhead do     -- solid block in front
  2072.                     if waterAbove then      -- move up
  2073.                         T:up(1)
  2074.                     else                    -- block above so go back
  2075.                         while not waterAbove do
  2076.                             utils.goBack()  --  returns true if no object behind, but moves anyway
  2077.                             waterAbove = utils.clearVegetation("up")
  2078.                         end
  2079.                     end
  2080.                     waterAbove = utils.clearVegetation("up")
  2081.                     waterAhead = utils.clearVegetation("forward")
  2082.                 end
  2083.             end
  2084.         until D.blockType:find(D.useBlockType) == nil
  2085.         -- now above a non-prismarine block, facing away from monument
  2086.         T:turnRight(2) -- facing monument
  2087.         D.blockType = T:getBlockType("forward")
  2088.         while D.blockType:find(D.useBlockType) ~= nil do
  2089.             T:up(1)
  2090.             D.blockType = T:getBlockType("forward")
  2091.         end
  2092.         T:go("F1L1")
  2093.         D.blockType = T:getBlockType("down")
  2094.         while D.blockType:find(D.useBlockType) ~= nil do
  2095.             T:forward(1)
  2096.             D.blockType = T:getBlockType("down")
  2097.         end
  2098.         turtle.back()
  2099.         -- should now be at end of monument base
  2100.     end
  2101.    
  2102.     function lib.turn(D)
  2103.         local direction = "R"
  2104.         if not D.facingForward then
  2105.             direction = "L"
  2106.         end
  2107.         T:go(direction.. 1)
  2108.         if utils.clearVegetation("forward") then
  2109.             T:forward(1)
  2110.             --D.depth = D.depth + lib.clearDown(depth)
  2111.             D = lib.clearDown(D)
  2112.         else
  2113.             while not utils.clearVegetation("forward") do
  2114.                 T:up(1)
  2115.                 D.depth = D.depth - 1
  2116.             end
  2117.             T:forward(1)
  2118.         end
  2119.         T:go(direction.. 1)
  2120.         D.facingForward = not D.facingForward
  2121.        
  2122.         return D
  2123.     end
  2124.  
  2125.     local D = {}
  2126.     D.depth = 0
  2127.     D.maxDepth = 0
  2128.     D.blockType = ""
  2129.     D.useBlockType = R.useBlockType -- "" or "prismarine"
  2130.     D.length = 0    -- copy of R.length used in lib.clearLength
  2131.     D.width = 0     -- increased every iteration
  2132.     D.facingForward = true
  2133.     D.monumentTopClear = false
  2134.     D.monumentArchesClear = false
  2135.     D.inWater = false
  2136.     D.onWater = false
  2137.     D.inWater, D.onWater = utils.getWaterStatus()
  2138.     D.floorLength = 0 -- used on monument floor
  2139.    
  2140.     if R.data == "clearWaterPlants" then -- NOT monument corner discovery
  2141.         D.inWater, D.onWater = utils.startWaterFunction(D.onWater, D.inWater, 2, true) -- move into water
  2142.         if R.length == 0 then
  2143.             R.length = lib.getLength()
  2144.         end
  2145.         if R.width == 0 then
  2146.             T:turnRight(1)
  2147.             R.width = lib.getLength()
  2148.             T:turnLeft(1)
  2149.         end
  2150.     end
  2151.     D.length = R.length
  2152.     D = lib.clearDown(D) -- go down to floor, set depth, maxDepth, blockType
  2153.     if R.data == "clearWaterPlants" then -- NOT monument corner discovery
  2154.         if R.width == 1 then
  2155.             print("Single row clearing")
  2156.             D = lib.clearLength(D) --D.width also increased
  2157.         else
  2158.             while D.width < R.width do -- D.width starts at 0
  2159.                 -- now on floor, move along sea/river bed following contour
  2160.                 D = lib.clearLength(D) --D.width also increased
  2161.                 -- now turn and repeat
  2162.                 if D.width < R.width then  
  2163.                     D = lib.turn(D)
  2164.                     if D.depth <= 0 then
  2165.                         break
  2166.                     end
  2167.                 end
  2168.             end
  2169.         end
  2170.         -- finished so return to surface
  2171.         T:up(1) -- up 1 to check for water below
  2172.         while T:getBlockType("down"):find("water") ~= nil do
  2173.             T:up(1)
  2174.         end
  2175.         T:down(2) -- return to surface
  2176.         --[[while utils.clearVegetation("forward") do
  2177.             T:forward(1)
  2178.         end]]
  2179.     elseif R.data == "oceanMonumentColumns" then -- monument corner discovery
  2180.         -- this function used to find edge of monument base
  2181.         if D.blockType:find(D.useBlockType) ~= nil then
  2182.             lib.findBlockTypeEnd(D)
  2183.             return {""}
  2184.         else
  2185.             T:up(D.depth)
  2186.             return {"Prismarine not found on ocean floor"}
  2187.         end
  2188.     end
  2189.     if R.silent then
  2190.         return {D.maxDepth, R.length}
  2191.     else
  2192.         return {""}
  2193.     end
  2194. end
  2195.  
  2196. local function clearMountainSide(R) -- 78
  2197.     --[[
  2198.     First row              outward  l  s  f  mid    (length, start, finish, midPoint)
  2199.  
  2200.           >|*|*|           true                     lib.clearRow() moves: 7-5=2, midPoint starts at 2
  2201.           +|*|*|
  2202.           +|*|*|
  2203.           ^|*|*|        <  false    7  5  6  2      lib.clearRow() moves: 9-2=7, midPoint starts at -4 -1 = -5
  2204.            |*|*|*|      +
  2205.          |*|*|*|*|*|    +
  2206.       >  |*|*|*|*|*|    ^  true     9  2  6  -4     lib.getStartingLength(). Ends 1 block after block finish
  2207.       ^|*|*|*|*|*|*|*|*|                            starts here, moves up 1
  2208.         1 2 3 4 5 6 7 8                             block index
  2209.          
  2210.     Second row                outward l  s  f  mid
  2211.                  <            false
  2212.                  +
  2213.           |*|*|  +
  2214.        >|*|*|*|*|^            true
  2215.        +|*|*|*|*|
  2216.        +|*|*|*|*|
  2217.        ^|*|*|*|*|          <  false   6  5  6  2
  2218.         |*|*|*|*|*|*|      +
  2219.       |*|*|*|*|*|*|*|*|    +
  2220.       |*|*|*|>|*|*|*|*|    ^  true    7+5   5 -7    lib.getHalf(R); goBack(7)
  2221.     |*|*|*|*|*|*|*|*|*|*|*|                           starts at midPoint of previous row eg block 4
  2222.      0 1 2 3 4 5 6 7 8 9 10
  2223.     ]]
  2224.    
  2225.     -- variables declared before lib for them to be used within lib as is then in scope
  2226.     local turn = "R"
  2227.     local oTurn = "L"
  2228.     if R.subChoice == 1 then    -- remove left side
  2229.         turn = "L"
  2230.         oTurn = "R"
  2231.     end
  2232.     local outward = true        -- direction flag
  2233.    
  2234.     local lib = {}
  2235.    
  2236.     function lib.isAnyAbove(above)
  2237.         T:saveToLog("lib.isAnyAbove: "..utils.tableConcat(above, ", "), false)
  2238.         for k,v in ipairs(above) do
  2239.             if v then
  2240.                 T:saveToLog("lib.isAnyAbove Found: "..k , false)
  2241.                 return true
  2242.             end
  2243.         end
  2244.         return false
  2245.     end
  2246.        
  2247.     function lib.clearLevel(R, above)   -- eg 9, 2, 6, -4 from lib.getStartingLength OR 7, 5, 6, 3 from previous
  2248.         -- clearLevel always follows either lib.getStartingLength or a previous lib.clearLevel
  2249.         -- midPoint should be adjusted as turtle moves to reflect current row length
  2250.         if #above == 0 then return above, 1 end
  2251.         --local index = 0
  2252.         local minMoves = math.floor(#above / 2)
  2253.         local up, forward, down = lib.getDetect()
  2254.         if outward then                                     -- follow table indexes
  2255.             for x = 1, minMoves do                          -- clear first half
  2256.                 above[x] = up                               -- reset this with new value
  2257.                 T:go("x0x2F1")                              -- clear and move forward
  2258.                 up, forward, down = lib.getDetect()
  2259.                 --index = index + 1
  2260.             end
  2261.             for x = minMoves + 1, #above do                 -- check remaing half and clear
  2262.                 T:go("x0x2")                                -- clear above / below
  2263.                 if above[x] then                            -- is a block recorded as present?(now below)
  2264.                     above[x] = up                           -- reset this with new value
  2265.                     T:forward(1)                            -- move forward
  2266.                     up, forward, down = lib.getDetect()
  2267.                     --index = index + 1
  2268.                 else
  2269.                     break
  2270.                 end
  2271.             end
  2272.         else                                                -- iterate table in reverse
  2273.             --index = #above
  2274.             for x = #above, minMoves, -1 do                 -- clear first half
  2275.                 above[x] = up                               -- reset this with new value
  2276.                 T:go("x0x2F1")                              -- clear and move forward
  2277.                 up, forward, down = lib.getDetect()
  2278.                 --index = index - 1
  2279.             end
  2280.             for x = minMoves - 1, 1, -1 do                  -- check remaing half and clear
  2281.                 T:go("x0x2")                                -- clear up / down
  2282.                 if above[x] then                            -- is a block recorded as present?(now below)
  2283.                     above[x] = up                           -- reset this with new value
  2284.                     T:forward(1)                            -- move forward
  2285.                     up, forward, down = lib.getDetect()
  2286.                     --index = index - 1
  2287.                 else
  2288.                     break
  2289.                 end
  2290.             end
  2291.         end
  2292.         T:go("x0x2 F1R2 x0x2 F1")                           -- face opposite direction, delete blocks above and below
  2293.         outward = not outward                               -- switch direction flag
  2294.         return above                                        -- eg {false, true, true, true, false}
  2295.     end
  2296.    
  2297.     function lib.getDetect()
  2298.         return turtle.detectUp(),  turtle.detect(),  turtle.detectDown()
  2299.     end
  2300.    
  2301.     function lib.getStartingLength(R)
  2302.         --[[
  2303.             length of column by excavating blocks above, ahead or below
  2304.             Rotate 180 at end of run ready to return
  2305.             already 1 block above ground
  2306.         ]]
  2307.         local above = {}                                    -- empty table of boolean values
  2308.         local length = 0                                    -- used as counter                         
  2309.         T:forward(1)                                        -- start check 1 block ahead
  2310.         local up, forward, down = lib.getDetect()           -- check if anything around current block
  2311.         if up or forward or down then                       -- block found nearby: continue
  2312.             while up or forward or down do                  -- while blocks ahead / up / down move forward
  2313.                 table.insert(above, up)
  2314.                 T:go("x0x2F1")
  2315.                 up, forward, down = lib.getDetect()         -- check if anything around current block
  2316.                 length = length + 1
  2317.                 if length >= R.length then                  -- check if going out of range
  2318.                     T:saveToLog("lib.getStartingLength(R) : outward = "..tostring(outward).." MaxLength "..maxLength.." reached", false)
  2319.                     break
  2320.                 end
  2321.             end
  2322.             T:go("R2x0x2")                                  -- Rotate 180 and clear blocks above/below
  2323.         else                                                -- no blocks nearby: exit
  2324.             T:go("R2F1")                                    -- return to start position rotated 180
  2325.         end
  2326.         outward = not outward
  2327.  
  2328.         return above                                        -- above = {false, true, true, true, true, false, false}
  2329.     end
  2330.    
  2331.     function lib.firstRow(R)
  2332.         local height = 1                                    -- starts at ground level, but forced up 1
  2333.         T:up(1)
  2334.         local above = lib.getStartingLength(R)              -- clear the ground level and 1 above eg 9, 2, 5, 4
  2335.         if T:saveToLog("startLength: "..#above, true) then
  2336.             T:saveToLog(utils.tableConcat(above, ", "), false)
  2337.             if dbug then read() end
  2338.         end                                                 -- at end of first row as already turned 180, outward set to false in getStartingLength
  2339.         while lib.isAnyAbove(above) do
  2340.             T:go("U3")  -- go up 3
  2341.             height = height + 3
  2342.             above = lib.clearLevel(R, above)    -- returns start and finish of blocks above, rotates 180
  2343.             if T:saveToLog("checking level: "..height, true) then
  2344.                 T:saveToLog(utils.tableConcat(above, ", "), false)
  2345.                 if dbug then read() end
  2346.             end
  2347.         end                                                 -- first row all levels completed.
  2348.         T:down(height)                                      -- now on ground + 1, facing last column cleared.
  2349.        
  2350.         return above
  2351.     end
  2352.        
  2353.     function lib.deepCopy(tbl)
  2354.         local copy = {}
  2355.         for key, value in ipairs(tbl) do
  2356.             table.insert(copy, value)
  2357.         end
  2358.         return copy
  2359.     end
  2360.    
  2361.     function lib.getHalf(R, above)
  2362.         -- already 1 block above ground
  2363.         local maxLength = R.length
  2364.         local temp = {}
  2365.         local retValue = {}
  2366.         if #above > 0 then                              -- not empty table, so must be second half
  2367.             temp = lib.deepCopy(above)                  -- copy existing table
  2368.             above = {}                                  -- initialise above
  2369.         end
  2370.         local up, forward, down = lib.getDetect()
  2371.        
  2372.         while up or forward or down do                  -- while blocks ahead / up / down move forward
  2373.             T:go("x0x2F1")
  2374.             table.insert(above, up)
  2375.             up, forward, down = lib.getDetect()         -- check if anything around current block
  2376.            
  2377.             if #above >= math.floor(maxLength / 2) then -- check if going out of range
  2378.                 T:saveToLog("lib.getHalf(R) : outward = "..tostring(outward).." MaxLength "..maxLength.." reached", false)
  2379.                 T:go("x0x2")
  2380.                 break
  2381.             end
  2382.         end
  2383.         T:turnRight(2)                                  -- ready for next half or return
  2384.         outward = not outward
  2385.         if #temp > 0 then                               -- completing a second half measurement
  2386.             for i = #above, 1, -1 do
  2387.                 table.insert(retValue, above[i])        -- combine 2 tables into 1
  2388.             end
  2389.             for i = 1, #temp do
  2390.                 table.insert(retValue, temp[i])
  2391.             end
  2392.         else
  2393.             retValue = above
  2394.         end
  2395.         return retValue
  2396.     end
  2397.    
  2398.     function lib.nextRow(R)
  2399.         local height = 1
  2400.         T:saveToLog("lib.nextRow(R)", false)
  2401.         T:up(1)
  2402.         local pattern = turn.."1F1"..turn.."1"
  2403.         if not outward then
  2404.             pattern = oTurn.."1F1"..oTurn.."1"
  2405.         end
  2406.         T:go(pattern)
  2407.         T:saveToLog("    T:go("..pattern..")", false)
  2408.         outward = not outward -- reverse direction flag
  2409.         -- now in next vertical row
  2410.         local above = lib.getHalf(R, {})
  2411.         local index = 0
  2412.         if T:saveToLog("\t  first half Length: "..#above.." Enter", true) then
  2413.             T:saveToLog(utils.tableConcat(above, ", "), false)
  2414.             if dbug then read() end
  2415.         end
  2416.         lib.returnToMidPoint(#above)                    -- return to starting point
  2417.         T:forward(1)       
  2418.         above = lib.getHalf(R, above)                   -- returns length - 1 eg 5, 4
  2419.         if T:saveToLog("\t  total length: "..#above.." Enter", true) then
  2420.             T:saveToLog(utils.tableConcat(above, ", "), false)
  2421.             if dbug then read() end
  2422.         end
  2423.        
  2424.         while lib.isAnyAbove(above) do
  2425.             T:go("U3")              -- go up 3
  2426.             height = height + 3     -- increment height
  2427.             T:saveToLog("\tClear height loop: height = "..height, false)
  2428.             above = lib.clearLevel(R, above)    -- returns start and finish of blocks above
  2429.         end
  2430.         T:down(height)  -- now on ground + 1
  2431.         lib.returnToMidPoint(above)
  2432.     end
  2433.    
  2434.     function lib.returnToMidPoint(above)
  2435.         --[[ value can be integer or table]]
  2436.         if type(above) == "table" then
  2437.             T:saveToLog("lib.returnToMidPoint("..#above..")", false)
  2438.             if #above > 0 then
  2439.                 local midPoint = math.floor(#above / 2)
  2440.                 if #above % 2 == 1 and  not outward then -- length is odd no
  2441.                     midPoint = math.ceil(#above / 2)
  2442.                     T:saveToLog("    midPoint adjusted "..midPoint..")", false)
  2443.                 end
  2444.                 T:saveToLog("    T:forward("..midPoint..")", false)
  2445.                 T:forward(midPoint)
  2446.             end
  2447.         else
  2448.             T:saveToLog("lib.returnToMidPoint("..above..")", false)
  2449.             if above > 0 then
  2450.                 T:saveToLog("    T:forward("..above..")", false)
  2451.                 T:forward(above)
  2452.             end
  2453.         end
  2454.         -- now back at starting point
  2455.     end
  2456.    
  2457.     -- Start here
  2458.     -- if "tk log d.." typed instead of "tk" will start logfile and display comments. read() will be activated for debugging
  2459.     T:saveToLog("Starting function clearMountainSide", false)
  2460.     local above = lib.firstRow(R)           -- outward depends on height eg 1-2 = false, 3-5 = true, 6-8 = false
  2461.     lib.returnToMidPoint(above)             -- return to mid first row of blocks
  2462.     for row = 1, R.width -1 do
  2463.         lib.nextRow(R)
  2464.     end
  2465.    
  2466.     return {}
  2467. end
  2468.  
  2469. local function clearSandWall(R) -- 81
  2470.     --dig down while on top of sand/red_sand/soul_sand
  2471.     local lib = {}
  2472.    
  2473.     function lib.checkAbove(height)
  2474.         if turtle.detectUp() then -- moved under a ledge
  2475.             T:go("B1U1")
  2476.             height = height - 1
  2477.         end
  2478.         return height
  2479.     end
  2480.    
  2481.     function lib.moveDown(height)
  2482.         blockType = T:getBlockType("down")
  2483.         while blockType:find("sand") ~= nil do
  2484.             T:down(1)
  2485.             height = height + 1
  2486.             blockType = T:getBlockType("down")
  2487.         end
  2488.         return height
  2489.     end
  2490.    
  2491.     function lib.moveForward(length)
  2492.         lib.digForward()
  2493.         T:forward(1)
  2494.         length = length + 1
  2495.         local blockType = T:getBlockType("forward")
  2496.         return length, blockType
  2497.     end
  2498.    
  2499.     function lib.digForward()
  2500.         while T:dig("forward") do
  2501.             while T:suck("forward") do end
  2502.             while T:suck("up") do end
  2503.         end
  2504.     end
  2505.    
  2506.     local moves  = 0
  2507.     local height = 0
  2508.     local length = 0
  2509.     local search = 0
  2510.     local reverse = false
  2511.     local blockType = T:getBlockType("down")
  2512.     if R.length == 0 then
  2513.         R.length = 64
  2514.     end
  2515.    
  2516.     print("Checking for sand below")
  2517.     while blockType:find("sand") == nil do --move forward until sand detected or 3 moves
  2518.         T:forward(1)
  2519.         search = search + 1
  2520.         blockType = T:getBlockType("down")
  2521.         if search > 3 then
  2522.             T:go("B"..search)
  2523.             return {"Unable to locate sand"}
  2524.         end
  2525.     end
  2526.     -- must be sand below
  2527.     height = lib.moveDown(height)   -- go down if sand below
  2528.     -- repeat until height == 0
  2529.     repeat -- starts at bottom of sand wall
  2530.         blockType = T:getBlockType("forward")
  2531.         if blockType:find("sand") ~= nil then -- sand in front
  2532.             length, blockType = lib.moveForward(length) -- move forward 1 and dig sand
  2533.             if blockType == "" or  blockType:find("sand") ~= nil then -- sand or nothing in front
  2534.                 height = lib.moveDown(height)   -- go down if sand below
  2535.             end
  2536.         else -- solid block, air or water, not sand so move up
  2537.             if turtle.detect() then -- block in front
  2538.                 blockType = T:getBlockType("down")
  2539.                 if blockType:find("sand") ~= nil then -- sand below
  2540.                     T:dig("down")
  2541.                 end
  2542.                 T:up(1)
  2543.                 height = height - 1
  2544.             else -- air/water in front so move forward
  2545.                 if length < 60 then -- in case missing wall and in open ocean
  2546.                     length, blockType = lib.moveForward(length) -- move forward 1 and dig sand
  2547.                     height = lib.checkAbove(height)
  2548.                 else -- already > monument length of 56
  2549.                     T:up(1)
  2550.                     height = height - 1
  2551.                 end
  2552.             end
  2553.         end
  2554.     until height == 0 or length == R.length
  2555.     blockType = T:getBlockType("down")
  2556.     if blockType:find("sand") ~= nil then -- sand below
  2557.         T:dig("down")
  2558.     end
  2559.     if height > 0 then -- finished as length ran out
  2560.         T:up(height)
  2561.     end
  2562.     -- stay at end of cleared wall unless user chose to return
  2563.     if R.data == "return" then
  2564.         T:go("R2F"..length.."R2")
  2565.     end
  2566.    
  2567.     return {}
  2568. end
  2569.  
  2570. local function clearSolid(R) -- 76
  2571.     --[[ direction = R.subChoice = 1 up or 2 down ]]
  2572.     local height = 1
  2573.     local remaining = R.height
  2574.     local lib = {}
  2575.    
  2576.     function lib.singleLayer(R)
  2577.         R.up = false
  2578.         R.down = false
  2579.         clearRectangle(R)
  2580.     end
  2581.    
  2582.     function lib.doubleLayer(R)
  2583.         R.up = false
  2584.         R.down = false
  2585.         if R.subChoice == 1 then
  2586.             R.up = true
  2587.         else
  2588.             R.down = true
  2589.         end
  2590.         clearRectangle(R)
  2591.     end
  2592.        
  2593.     function lib.tripleLayer(R)
  2594.         -- turtle in centre layer
  2595.         R.up = true
  2596.         R.down = true
  2597.         clearRectangle(R)
  2598.     end
  2599.  
  2600.     R.silent = true
  2601.     if R.height < 3 then                            --1-3 layers only
  2602.         if R.height == 1 then                       --one layer only
  2603.             lib.singleLayer(R)
  2604.         elseif R.height == 2 then                   --2 layers only current + dig up/down
  2605.             lib.doubleLayer(R)
  2606.         end
  2607.     else -- 3 or more levels
  2608.         height = height + utils.move(R, 1)          -- move up/down 1 block for first layer
  2609.         while remaining >= 3 do                     -- min 3 levels
  2610.             lib.tripleLayer(R)
  2611.             remaining = remaining - 3
  2612.             if remaining == 0 then                  -- all finished
  2613.                 break
  2614.             elseif remaining == 1 then
  2615.                 height = height + utils.move(R, 2)  -- move up/down 2 blocks
  2616.                 lib.singleLayer(R)
  2617.             elseif remaining == 2 then
  2618.                 height = height + utils.move(R, 2)  -- move up/down 2 blocks
  2619.                 lib.doubleLayer(R)
  2620.             else
  2621.                 height = height + utils.move(R, 3)  -- move up/down 3 blocks
  2622.                 if remaining == 3 then
  2623.                     finish = true
  2624.                 end
  2625.             end
  2626.         end
  2627.     end
  2628.    
  2629.     if height > 1 then
  2630.         utils.move(R, height - 1, true) -- reverse direction
  2631.     end
  2632.    
  2633.     return {}
  2634. end
  2635.  
  2636. local function clearSandCube(R) -- 81
  2637.     R.data = ""
  2638.     for w = 1, R.width do
  2639.         clearSandWall(R)
  2640.         if w < R.width then
  2641.             if w % 2 == 1 then
  2642.                 T:go("R1F1R1")
  2643.             else
  2644.                 T:go("L1F1L1")
  2645.             end
  2646.         end
  2647.     end
  2648.    
  2649.     return {}
  2650. end
  2651.  
  2652. local function clearWall(R) -- 73
  2653.     local lib = {}
  2654.    
  2655.     function lib.move(direction, blocks, reverse)
  2656.         --[[ Move up or down by blocks count ]]
  2657.         if reverse == nil then
  2658.             reverse = false
  2659.         end
  2660.         if reverse then
  2661.             if direction == "down" then -- reverse direction
  2662.                 T:up(blocks)
  2663.             else
  2664.                 T:down(blocks)
  2665.             end
  2666.         else
  2667.             if direction == "up" then
  2668.                 T:up(blocks)
  2669.             else
  2670.                 T:down(blocks)
  2671.             end
  2672.         end
  2673.         return blocks
  2674.     end
  2675.    
  2676.     function lib.singleLayer(length)
  2677.         T:go("F"..length - 1)
  2678.     end
  2679.    
  2680.     function lib.doubleLayer(modifier, length)
  2681.         for i = 1, length do
  2682.             if i < length then
  2683.                 T:go("x"..modifier.."F1")
  2684.             else
  2685.                 T:go("x"..modifier)
  2686.             end
  2687.         end
  2688.     end
  2689.    
  2690.     function lib.tripleLayer(direction, length)
  2691.         for i = 1, length do
  2692.             if i < length then
  2693.                 T:go("x0x2F1")
  2694.             else
  2695.                 T:go("x0x2")
  2696.             end
  2697.         end
  2698.     end
  2699.    
  2700.    
  2701.     -- R.width preset to 1
  2702.     -- R.subChoice = 1 up / 2 down
  2703.     if R.height < 3 then
  2704.         R.silent = true
  2705.     end
  2706.     -- dig along and up/down for specified R.length
  2707.     local modifier = "0"
  2708.     local direction = "U"
  2709.     local outbound = true
  2710.     local height = 0
  2711.     if R.subChoice == 2 then
  2712.          modifier = "2"
  2713.          direction = "D"
  2714.     end
  2715.     if R.height == 1 then               -- single block so dig and return
  2716.         lib.singleLayer(R.length)
  2717.     elseif R.height == 2 then
  2718.         lib.doubleLayer(modifier, R.length)
  2719.     else                                -- 4 blocks or more. start with bulk 3 blocks
  2720.         local remaining = R.height
  2721.         T:go(direction.."1")            -- up 1 or down 1
  2722.         height = 1
  2723.         while remaining >= 3 do
  2724.             lib.tripleLayer(direction, R.length)
  2725.             remaining = remaining - 3
  2726.            
  2727.             if remaining == 0 then      -- no more, return home, already in position
  2728.                
  2729.             elseif remaining == 1 or remaining == 2 then
  2730.                 T:go(direction.."2")
  2731.                 height = height + 2
  2732.             else
  2733.                 T:go(direction.."3")
  2734.                 height = height + 3
  2735.                 if remaining >= 3 then -- another iteration
  2736.                     T:go("R2")
  2737.                     outbound = not outbound
  2738.                 end
  2739.             end
  2740.         end
  2741.         -- 0, 1 or 2 layers left
  2742.         if remaining > 0 then
  2743.             T:go("R2")
  2744.             outbound = not outbound
  2745.             if remaining == 1 then
  2746.                 lib.singleLayer(R.length)
  2747.             elseif remaining == 2 then
  2748.                 lib.doubleLayer(modifier, R.length)
  2749.             end
  2750.         end
  2751.     end
  2752.     if outbound then
  2753.         T:go("R2F"..R.length)
  2754.     else
  2755.         T:forward(1)
  2756.     end
  2757.     direction = "D" -- reverse direction
  2758.     if R.subChoice == 2 then
  2759.          direction = "U"
  2760.     end
  2761.     if height > 0 then
  2762.         T:go(direction..height.."R2")
  2763.     else
  2764.         T:go("R2")
  2765.     end
  2766.     return {}
  2767. end
  2768.  
  2769. local function convertWater(R) -- 88
  2770.     --[[
  2771.     if dry need enough buckets to place along (width + length - 1) / 2
  2772.     use 12 buckets
  2773.     start on floor + 1
  2774.     place slab down and water up along 2 edges. stay on this level
  2775.     return round same 2 edges removing slabs and and placing them 1 above
  2776.     placeUp water onto slabs on both edges
  2777.     repeat recover slabs, place 1 above , placeUp water
  2778.    
  2779.     for sloping water, place full area with slabs
  2780.     place sloping water on top of slabs
  2781.     remove slabs
  2782.    
  2783.     ]]
  2784.     local lib = {}
  2785.    
  2786.     function lib.checkStartPosition()
  2787.         --[[
  2788.         0 T             -- T=turtle, W=wall, S=source, F=flowing
  2789.         1 W|S|F|F|F|F|F -- sloping flowing water
  2790.         2 W|F|F|F|F|F|F -- blocks removed after placing flowing water above
  2791.         3 W|S|S|S|S|S|S -- original sources
  2792.         4 W|?|?|?|?|?|? -- may be sources
  2793.         ]]
  2794.         -- need to be on floor or R.height if specified
  2795.         local depth = 0
  2796.         local blockType = T:getBlockType("down")
  2797.         local isWaterUp, isSourceUp = T:isWater("up")
  2798.         local isWaterForward, isSourceForward = T:isWater("forward")
  2799.         local isWaterDown, isSourceDown = T:isWater("down")
  2800.         print("Block below is "..blockType)
  2801.         print("Water above is "..tostring(isWaterUp))
  2802.         print("Water forward is "..tostring(isWaterForward))
  2803.         print("Water below is "..tostring(isWaterDown))
  2804.         if blockType:find("water") == nil then -- on at least level 0
  2805.             print("Moving forward in 2 seconds...")
  2806.             sleep(2)
  2807.             T:forward(1)
  2808.             blockType = T:getBlockType("down")
  2809.             if blockType:find("water") ~= nil then
  2810.                 print("Water found. Going down to floor")
  2811.                 depth = -1
  2812.             else
  2813.                 T:down(1)
  2814.                 blockType = T:getBlockType("down")
  2815.                 if blockType:find("water") ~= nil then
  2816.                     depth = -2
  2817.                 else
  2818.                     return 0, "Not close to water. Aborting..."
  2819.                 end
  2820.             end
  2821.         end
  2822.         while turtle.down() do
  2823.             depth = depth + 1
  2824.         end
  2825.         local emptyBuckets = utils.getEmptyBucketCount()
  2826.         for i = depth, 0, -1 do
  2827.             if emptyBuckets > 0 then
  2828.                 lib.fillBuckets()
  2829.                 emptyBuckets = utils.getEmptyBucketCount()
  2830.             end
  2831.             turtle.up()
  2832.         end
  2833.        
  2834.         return depth, ""
  2835.     end
  2836.    
  2837.     function lib.fillBuckets()
  2838.         local emptyBuckets = utils.getEmptyBucketCount()
  2839.         local direction = "forward"-- start with forward
  2840.         local isWater, isSource, isIce = T:isWater(direction)
  2841.         if emptyBuckets > 0 then
  2842.             if not isSource then
  2843.                 direction = "down"
  2844.                 isWater, isSource, isIce = T:isWater(direction)
  2845.                 if not isSource then
  2846.                     direction = "up"
  2847.                     isWater, isSource, isIce = T:isWater(direction)
  2848.                     if not isSource then
  2849.                         direction = ""
  2850.                     end
  2851.                 end
  2852.             end
  2853.             if direction == "" then
  2854.                 print("Unable to locate water source")
  2855.             else
  2856.                 for i = 1, emptyBuckets do
  2857.                     if utils.fillBucket(direction) then
  2858.                         print("Bucket filled "..direction)
  2859.                         sleep(0.3)
  2860.                     else
  2861.                         print("Unable to fill bucket ".. i .." / "..emptyBuckets)
  2862.                     end
  2863.                 end
  2864.             end
  2865.         end
  2866.         return utils.getWaterBucketCount()
  2867.     end
  2868.    
  2869.     function lib.placeSlabs(length)
  2870.         for i = 1, length do
  2871.             T:place("slab", -1, "down", false)
  2872.             if i < length then
  2873.                 T:forward(1)
  2874.             end
  2875.         end
  2876.     end
  2877.    
  2878.     function lib.placeSources(length, place)
  2879.         local moves = 1
  2880.         local waterBuckets = utils.getWaterBucketCount()
  2881.         -- place sources alternate positions + start and finish
  2882.         while moves < length do
  2883.             if place then
  2884.                 if T:placeWater("up") then
  2885.                     print("Placed source up")
  2886.                     waterBuckets = waterBuckets - 1
  2887.                 end
  2888.             end
  2889.             place = not place
  2890.             if moves < length then
  2891.                 T:forward(1)
  2892.                 moves = moves + 1
  2893.             end
  2894.             if waterBuckets == 0 then
  2895.                 T:down(1) -- break the slab below
  2896.                 waterBuckets = lib.fillBuckets()
  2897.                 T:up(1)
  2898.                 T:place("slab", -1, "down", false)
  2899.             end
  2900.         end
  2901.         if T:placeWater("up") then -- end of length
  2902.             print("Placed final source up")
  2903.         end
  2904.         return place
  2905.     end
  2906.    
  2907.     function lib.moveSlabs(length)
  2908.         for i = 1, length do
  2909.             T:dig("down")
  2910.             T:up(1)
  2911.             T:place("slab", -1, "down", true)
  2912.             if i < length then
  2913.                 T:forward(1)
  2914.                 T:down(1)
  2915.             end
  2916.         end
  2917.     end
  2918.    
  2919.     function lib.recoverSlabs(length)
  2920.         for i = 1, length do
  2921.             T:dig("down")
  2922.             if i < length then
  2923.                 T:forward(1)
  2924.             end
  2925.         end
  2926.     end
  2927.    
  2928.     local depth, message = lib.checkStartPosition()
  2929.     if message ~= "" then
  2930.         return {message}
  2931.     end
  2932.     local maxDepth = R.height
  2933.     local buckets = utils.getWaterBucketCount()
  2934.     R = utils.calculateDimensions(R) -- if R.width or R.length == 0
  2935.     T:down(depth)
  2936.     lib.placeSlabs(R.length)
  2937.     T:go("R1")
  2938.     lib.placeSlabs(R.width)
  2939.     T:go("R2")
  2940.    
  2941.     while depth > 0 do
  2942.         local place = true
  2943.         lib.fillBuckets()
  2944.         place = lib.placeSources(R.width, place)
  2945.         T:go("L1")
  2946.         place = lib.placeSources(R.length, place)
  2947.         lib.fillBuckets()
  2948.         T:go("R2")
  2949.         lib.moveSlabs(R.length) -- dig slab from below, move up and replace below
  2950.         T:go("R1F1D1")
  2951.         lib.moveSlabs(R.width - 1)
  2952.         T:go("R2") -- now moved up 1 layer
  2953.         depth = depth - 1
  2954.         if depth == 0 then
  2955.             place = lib.placeSources(R.width, true)
  2956.             T:go("L1")
  2957.             place = lib.placeSources(R.length, place)
  2958.             T:go("R2")
  2959.             lib.recoverSlabs(R.length)
  2960.             T:go("R1")
  2961.             lib.recoverSlabs(R.width)
  2962.         end
  2963.     end
  2964.    
  2965.     return {}
  2966. end
  2967.  
  2968. local function createBoatLift(R) -- 59 state:0=new, size:1=extend, side:0=left, 1=right
  2969.     -- build stepped lift with fencing gates and soul sand
  2970.     local lib = {}
  2971.    
  2972.     function lib.getWater(backToWater, downToWater)
  2973.         if backToWater > 0 then
  2974.             utils.goBack(backToWater)
  2975.         end
  2976.         if downToWater > 0 then
  2977.             T:down(downToWater)
  2978.         end
  2979.         T:getWater("down") -- take water from source
  2980.         sleep(0.2)
  2981.         T:getWater("down") -- take water from source
  2982.         if downToWater > 0 then
  2983.             T:up(downToWater)
  2984.         end
  2985.         if backToWater > 0 then
  2986.             T:forward(backToWater)
  2987.         end
  2988.     end
  2989.    
  2990.     --T:place(blockType, damageNo, direction, leaveExisting, signText)
  2991.    
  2992.     local backToWater = 0
  2993.     local downToWater = 0
  2994.    
  2995.     T:go("R1F1L1")                                      -- over canal facing forward
  2996.     for h = 1, R.height do
  2997.         lib.getWater(backToWater, downToWater)          -- check water supplies, return to starting position
  2998.         T:go("L1C1 R1D1 L1C1 R1", false, 0, false)      -- place towpath, forward, down, place towpath, face forward
  2999.         T:place("soul", -1, "down", false)              -- place soulsand down
  3000.         T:place("soul", -1, "forward", false)           -- place soulsand forward
  3001.         T:go("R1F1C1L1", false, 0, false)               -- place right towpath face forward
  3002.         T:place("soul", -1, "down", false)              -- place soulsand down
  3003.         T:place("soul", -1, "forward", false)           -- place soulsand forward
  3004.         T:go("U1 R1C1 L1")                              -- place towpath, face forward
  3005.         T:placeWater("down")                            -- place water down
  3006.         utils.goBack(1)
  3007.         T:place("gate", -1, "forward", false)           -- place fence gate
  3008.         T:go("R1C1 U1C1 D1 L2F1 C1R1 F1 L1C1R1")        -- over left soul sand
  3009.         T:placeWater("down")                            -- place water down
  3010.         utils.goBack(1)
  3011.         T:place("gate", -1, "forward", false)           -- place fence gate
  3012.         T:go("U1 L1C1 R1F1 L1C1 R1x1")                  -- facing forward first unit complete
  3013.         T:go("R1F1 L1x1 R1C1")
  3014.         utils.goBack(1)
  3015.         T:go("L1F1")
  3016.         if backToWater == 0 then
  3017.             backToWater = 1
  3018.         end
  3019.         backToWater = backToWater + 1
  3020.         downToWater = downToWater + 1
  3021.     end
  3022.    
  3023.     -- now finish the canal
  3024.     lib.getWater(backToWater, downToWater)
  3025.     T:go("D1 L1C1 U1C1")                    -- build left towpath, facing towpath, above water level
  3026.     T:go("R1F1 L1C1 D1C1")                  -- move forward, build towpath, facing towpath ground level
  3027.     T:go("R1C1 R1F1 L1C1 R1C1 U1C1")        -- build right towpath, facing towpath, above water level
  3028.     T:go("R1F1 L1C1 D1C1 U1")               -- build right towpath next to gate, facing towpath, above water level
  3029.     T:placeWater("down")
  3030.     utils.goBack(1)
  3031.     T:go("L1F1")
  3032.     T:placeWater("down")  
  3033.    
  3034.     return {}
  3035. end
  3036.  
  3037. local function createBorehole(R)
  3038.     --[[go down to bedrock and return. Chart all blocks dug/ passed through]]
  3039.     local diary = {}
  3040.     local lib = {}
  3041.     local depth = R.height  -- eg 63 start position
  3042.     local moves = 0
  3043.     --R.height = current level
  3044.    
  3045.     function lib.addBlock(depth, blockType, diary)
  3046.         if blockType == "" then
  3047.             blockType = "air"
  3048.         end
  3049.         table.insert(diary, blockType)
  3050.        
  3051.        
  3052.         --[[if blockType ~= "" then
  3053.             local add = true
  3054.             for k,v in pairs(diary) do
  3055.                 if blockType == v then
  3056.                     add = false
  3057.                     break
  3058.                 end
  3059.             end
  3060.             if add then
  3061.                 diary[depth] = blockType
  3062.             end
  3063.         end]]
  3064.        
  3065.         return diary
  3066.     end
  3067.    
  3068.     function lib.processItem(item)
  3069.         if item:find("minecraft") ~= nil then
  3070.             return item:sub(11)
  3071.         end
  3072.         return item
  3073.     end
  3074.    
  3075.     function lib.writeReport(R, diary)
  3076.         local numLevels = #diary                        -- eg 125 levels
  3077.         local levelsPerCol = math.ceil(numLevels / 4)   -- eg 31.25 -> 32
  3078.         local lines = {}
  3079.         for l = 1, levelsPerCol do                      -- add 32 empty strings
  3080.             table.insert(lines, "")
  3081.         end
  3082.         local lineNo = 1
  3083.         for k, v in ipairs(diary) do
  3084.             local level = R.height - k                  -- eg 63 range 63 to -59
  3085.             local lev = "      "
  3086.             local item = lib.processItem(v)
  3087.             if level < -9 then
  3088.                 lev = tostring(level).."   "            -- "-10   " to "-59   "
  3089.             elseif level < 0 then              
  3090.                 lev = "-0"..math.abs(level).."   "      -- "-09   " to "-01   "
  3091.             elseif level < 10 then
  3092.                 lev = " 0"..level.."   "                -- " 01   " to " 09   "
  3093.             elseif level < 100 then
  3094.                 lev = " "..level.."   "                 -- " 10   " to " 99   "
  3095.             else
  3096.                 lev = " "..level.."  "                  -- " 100  " to " 319  "
  3097.             end
  3098.             local output = lev..item                    -- eg "-10   grass_block"
  3099.             if #output > 20 then                        -- eg "-10   some_long_block_name"  
  3100.                 output = output:sub(1, 20)              -- eg "-10   some_long_block_"
  3101.             else
  3102.                 output = menu.padRight(output, 20, " ") -- eg "-10   grass_block     "
  3103.             end
  3104.             lines[lineNo] = lines[lineNo]..output       -- add new entry to this line
  3105.             lineNo = lineNo + 1                         -- increase line no
  3106.             if lineNo > levelsPerCol then               -- past last line number
  3107.                 lineNo = 1                              -- reset to 1
  3108.             end
  3109.         end
  3110.        
  3111.         local fileName = "borehole"..os.getComputerID()..".txt"
  3112.         local handle = fs.open(fileName, "w")       --create file eg "borehole0.txt"
  3113.         handle.writeLine("Level Block         Level Block         Level Block         Level Block")
  3114.         for k,v in ipairs(lines) do
  3115.             handle.writeLine(v)
  3116.         end
  3117.        
  3118.         handle.close()
  3119.        
  3120.         return fileName
  3121.     end
  3122.    
  3123.     local blockType = T:getBlockType("down")
  3124.     while T:down(1) do
  3125.         depth = depth - 1
  3126.         moves = moves + 1
  3127.         if depth == R.depth then
  3128.             break
  3129.         end
  3130.         diary = lib.addBlock(depth, blockType, diary)
  3131.         blockType = T:getBlockType("down")
  3132.     end
  3133.     local fileName = lib.writeReport(R, diary)
  3134.     T:up(moves)
  3135.    
  3136.     return {"File '"..fileName.."' written"}
  3137. end
  3138.  
  3139. local function createBubbleLift(R) -- 15
  3140.     local lib = {}
  3141.    
  3142.     function lib.addLayer()
  3143.         T:go("F2 L1C1 R1C1 R1C1 L1", false, 0, true)
  3144.         turtle.back()
  3145.         T:dig("up") -- clear block above so completed lift can be found
  3146.         T:placeWater("forward")
  3147.         turtle.back()
  3148.         T:go("C1x0")       
  3149.     end
  3150.    
  3151.     function lib.addSign()
  3152.         turtle.back()
  3153.         T:placeWater("forward")
  3154.         T:go("L1B1")
  3155.         T:place("sign", -1, "forward")
  3156.     end
  3157.    
  3158.     function lib.buildLift(toHeight)
  3159.         local built = lib.goToWater()       -- returns lift blocks already placed, total height of drop from starting point
  3160.         local toBuild = toHeight - built    -- no of blocks remaining to increase lift size
  3161.         local water = 0
  3162.         while toBuild > 0 do                -- at least 1 block height remaining
  3163.             water = lib.fillBuckets(toBuild, false) -- no of water buckets onboard (could be more than required)
  3164.             if water > toBuild then         -- more water than required
  3165.                 water = toBuild             -- reduce to correct amount
  3166.             end
  3167.             T:up(built)                     -- climb to top of existing lift
  3168.             while water > 0 and toBuild > 0 do
  3169.                 lib.addLayer()
  3170.                 water = water - 1
  3171.                 T:up(1)
  3172.                 toBuild = toBuild - 1
  3173.             end
  3174.             -- may still be some height to complete, but needs refill
  3175.             if toBuild > 0 then
  3176.                 built = lib.goToWater() --return to source
  3177.                 toBuild = toHeight - built
  3178.                 --lib.fillBuckets(toBuild)
  3179.             end
  3180.         end
  3181.     end
  3182.    
  3183.     function lib.cleanUp(fromHeight)
  3184.         local plug = false
  3185.         T:turnRight(2)
  3186.         for i = 1, fromHeight do
  3187.             plug = false
  3188.             if turtle.detect() then
  3189.                 plug = true
  3190.             end
  3191.             turtle.down()
  3192.             if plug then
  3193.                 T:place("stone", -1, "up")
  3194.             end
  3195.         end
  3196.         T:go("D1 C1R1x1 R1C1 R1F1 R1x1 L2x1 L1C1 x1") -- delete water sources
  3197.         T:go("D1 C1R1x1 R1")
  3198.         local blockType = T:getBlockType("forward")
  3199.         if blockType:find("dirt") == nil and blockType:find("soul") == nil then -- not dirt or soul sand in front
  3200.             T:go("C1")
  3201.         end
  3202.         T:go("R1F1 R1x1 L2x1 L1C1 x1")
  3203.     end
  3204.    
  3205.     function lib.fillBuckets(toBuild, withSort)
  3206.         local emptySlots, water = lib.stackBuckets(withSort)-- gets no of empty slots + no of water buckets
  3207.         if water < toBuild then                     -- no of water buckets onboard less than required quantity
  3208.             for i = 1, toBuild do                   -- fill required no of buckets up to max space in inventory
  3209.                 if emptySlots == 0 then             -- inventory full
  3210.                     break
  3211.                 else
  3212.                     if T:getWater("down") then
  3213.                         water = water + 1
  3214.                         sleep(0.5)
  3215.                     end
  3216.                 end
  3217.                 emptySlots = lib.getEmptySlots()
  3218.             end
  3219.         end
  3220.        
  3221.         return water
  3222.     end
  3223.    
  3224.     function lib.getEmptySlots()
  3225.         local empty = 0
  3226.         for i = 1, 16 do
  3227.             if turtle.getItemCount(i) == 0 then
  3228.                 empty = empty + 1
  3229.             end
  3230.         end
  3231.         return empty
  3232.     end
  3233.    
  3234.     function lib.goToWater()
  3235.         local built = 0 -- measures completed lift height
  3236.         while turtle.down() do -- takes turtle to bottom of water source
  3237.             if turtle.detect() then
  3238.                 built = built + 1
  3239.             end
  3240.         end
  3241.         T:up(1) -- above watersource ready to fill buckets
  3242.         -- height = height - 1
  3243.         -- built = built - 1 not required as next block is water source: not detected
  3244.         return built -- , height
  3245.     end
  3246.    
  3247.     function lib.stackBuckets(withSort)
  3248.         if withSort == nil then withSort = false end
  3249.         local data = {}
  3250.         local bucketSlot = 0
  3251.         local emptySlots = 0
  3252.         local water = 0
  3253.         if withSort then
  3254.             T:sortInventory()
  3255.         end
  3256.         for i = 1, 16 do
  3257.             -- find first empty bucket
  3258.             if turtle.getItemCount(i) > 0 then
  3259.                 data = turtle.getItemDetail(i)
  3260.                 if data.name == "minecraft:bucket" then
  3261.                     if bucketSlot == 0 then
  3262.                         bucketSlot = i
  3263.                     else
  3264.                         turtle.select(i)
  3265.                         turtle.transferTo(bucketSlot)
  3266.                     end
  3267.                 elseif data.name == "minecraft:water_bucket" then
  3268.                     water = water + 1
  3269.                 end
  3270.             else
  3271.                 emptySlots = emptySlots + 1
  3272.             end
  3273.         end
  3274.         return emptySlots, water
  3275.     end
  3276.    
  3277.    
  3278.     T:go("C1R1")                                                -- place block next to ladder support block, turn right to check ladder
  3279.     local blockType = T:getBlockType("forward")                 -- Is there a ladder to the right?
  3280.     if blockType:find("ladder") == nil then
  3281.         T:go("C1L2")                                            -- Place block as ladder not present
  3282.     else                                                        -- ladder present
  3283.         T:go("L2")                                              -- ready to check other side
  3284.     end
  3285.     blockType = T:getBlockType("forward")
  3286.     if blockType:find("ladder") == nil then
  3287.         T:go("C1R1")
  3288.     else
  3289.         T:go("R1")
  3290.     end
  3291.     blockType = T:getBlockType("down")
  3292.     local dirt = "minecraft:dirt"
  3293.     if T:getItemSlot("minecraft:soul_sand") > 0 then
  3294.         dirt = "minecraft:soul_sand"
  3295.     end
  3296.     if blockType:find("bedrock") ~= nil then
  3297.         utils.goBack(1)
  3298.         T:place(dirt, -1, "forward", false)                     -- placed at end of potential water source, next to ladder
  3299.     else
  3300.         T:place(dirt, -1, "down", false)                        -- placed in ground, next to ladder
  3301.         utils.goBack(1)
  3302.         T:placeWater("forward")                             -- place extra water source
  3303.     end
  3304.     T:go("R1C1 R2C1 L1F1C2 R1C1 L2C1 R1F1C2 R1C1 L1C1 L1C1 L1F1", false, 0, true)
  3305.     -- ready for water sources to be placed
  3306.     T:placeWater("forward")                                 -- place front water source
  3307.     T:turnRight(2)                                          -- facing backward
  3308.     T:placeWater("forward")                                 -- place back water source
  3309.     T:go("R2U1")                                            -- facing forward, U1, above centre of water source
  3310.     lib.fillBuckets(R.height, true)                         -- fill as many buckets as required or until inventory full, sort inventory as well
  3311.     local nextToLadder = false
  3312.     --T:go("F2R1")
  3313.     T:go("x0F1 x0F1C1 R1")                                  -- move forward 2 taking out blocks above, plug behind soul sand
  3314.     if T:getBlockType("forward"):find("ladder") == nil then -- no ladder here
  3315.         T:turnLeft(2)
  3316.         if T:getBlockType("forward"):find("ladder") ~= nil then -- ladder here
  3317.             nextToLadder = true
  3318.         end
  3319.         T:turnRight(1)
  3320.     else
  3321.         nextToLadder = true
  3322.         T:turnLeft(1)
  3323.     end
  3324.     -- now above soul sand, facing forward
  3325.     if nextToLadder then                                -- if nextToLadder, no need for signs
  3326.         utils.goBack(2)                                 -- return to source centre
  3327.     else
  3328.         T:go("F2 L1C1R1C1R1C1L1", false, 0, true)       -- prepare layer 1
  3329.         lib.addSign()
  3330.         T:go("U1F1R1F1 L1C1R1C1R1C1L1", false, 0, true) -- prepare layer 2
  3331.         lib.addSign()
  3332.         T:go("L1F1 R1F1R1", false, 0, true)             -- above source, level 2
  3333.     end
  3334.     -- ready to build lift
  3335.     lib.buildLift(R.height - 1)
  3336.     lib.cleanUp(R.height - 1)
  3337.    
  3338.     return {"Bubble lift created", "Check correct operation", "Check exit before using" }
  3339. end
  3340.  
  3341. local function createBubbleTrap(R) -- 34
  3342.     --[[
  3343.     Replace floor of existing volume of water with soulsand
  3344.     Used in river biome for squid farm. Area should be enclosed
  3345.     with solid walls surface to floor.
  3346.     Usually 7 blocks wide
  3347.     ]]
  3348.     local lib = {}
  3349.    
  3350.     function lib.clearDown(depth)
  3351.         while utils.clearVegetation("down") do
  3352.             T:down(1)
  3353.             depth = depth + 1
  3354.         end
  3355.         T:place("soul_sand", -1, "down", false)
  3356.         return depth
  3357.     end
  3358.    
  3359.     function lib.clearLength(length, depth)
  3360.         local moves = 0
  3361.         while moves < length - 1 do
  3362.             if utils.clearVegetation("forward") then
  3363.                 T:forward(1)
  3364.                 moves = moves + 1
  3365.                 depth = lib.clearDown(depth) -- go down if in water/air
  3366.                 if moves >= length - 1 then
  3367.                     return depth
  3368.                 end
  3369.             else -- block in front
  3370.                 local waterAhead = utils.clearVegetation("forward") -- true if air/water in front
  3371.                 while not waterAhead do     -- solid block in front
  3372.                     T:up(1)
  3373.                     depth = depth - 1
  3374.                     if depth < 1 then
  3375.                         return 0
  3376.                     end
  3377.                     waterAhead = utils.clearVegetation("forward")
  3378.                 end
  3379.             end
  3380.         end
  3381.  
  3382.         return depth
  3383.     end
  3384.    
  3385.     function lib.turn(facingForward, depth)
  3386.         local direction = "R"
  3387.         if not facingForward then
  3388.             direction = "L"
  3389.         end
  3390.         T:go(direction.. 1)
  3391.         if utils.clearVegetation("forward") then
  3392.             T:forward(1)
  3393.             depth = depth + lib.clearDown(depth)
  3394.         else
  3395.             while not utils.clearVegetation("forward") do
  3396.                 T:up(1)
  3397.                 depth = depth - 1
  3398.             end
  3399.         end
  3400.         T:go(direction.. 1)
  3401.        
  3402.         return depth
  3403.     end
  3404.    
  3405.     local depth = 0
  3406.     local length = 0
  3407.     local width = 0
  3408.     local outbound = true
  3409.     local facingForward = true
  3410.     local inWater, onWater = utils.getWaterStatus()
  3411.     inWater, onWater = utils.startWaterFunction(onWater, inWater, 2 ,true) -- move into water, max descent 2
  3412.     if R.length == 0 then
  3413.         R.length = lib.getLength()
  3414.     end
  3415.     if R.width == 0 then
  3416.         T:turnRight(1)
  3417.         R.width = lib.getLength()
  3418.         T:turnLeft(1)
  3419.     end
  3420.     -- go down to floor
  3421.     depth = lib.clearDown(depth)
  3422.     while width < R.width do
  3423.         -- now on floor, move along sea/river bed following contour
  3424.         depth = lib.clearLength(R.length, depth)
  3425.         width = width + 1
  3426.         -- now turn and repeat
  3427.         if width < R.width then
  3428.             depth = lib.turn(facingForward, depth)
  3429.             facingForward = not facingForward
  3430.         end
  3431.     end
  3432.     -- finished so return to surface
  3433.     T:up(1) -- up 1 to check for water below
  3434.     while T:isWater("down") do
  3435.         T:up(1)
  3436.     end
  3437.    
  3438.     return {}
  3439. end
  3440.  
  3441. local function createCorridor(R) -- 52
  3442.     --[[create a corridoor 2 blocks high, with floor and ceiling guaranteed
  3443.     T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)]]
  3444.     local lib = {}
  3445.    
  3446.     function lib.continue(R, currentSteps, totalSteps)
  3447.         if not R.silent then
  3448.             if currentSteps >= 64 and R.length == 0 then
  3449.                 -- request permission to continue if infinite
  3450.                 T:clear()
  3451.                 print("Completed "..totalSteps..". Ready for 64 more")
  3452.                 print("Do you want to continue? (y/n)")
  3453.                 response = read()
  3454.                 if response:lower() ~= "y" then
  3455.                     return true, 0
  3456.                 else
  3457.                     return false, currentSteps
  3458.                 end
  3459.             end
  3460.         end
  3461.         return true, currentSteps
  3462.     end
  3463.    
  3464.     function lib.seal()
  3465.         local blockType = T:getBlockType("forward")
  3466.         if blockType:find("water") ~= nil then
  3467.             T:place("stone", 0, "forward", false)
  3468.             return "water"  -- water found
  3469.         elseif blockType:find("lava") ~= nil then
  3470.             T:place("stone", 0, "forward", false)
  3471.             return "lava"   -- lava found
  3472.         end
  3473.         return ""   -- no water or lava
  3474.     end
  3475.    
  3476.     function lib.checkSeal(R)
  3477.         local fluidType = ""
  3478.         if R.data == "seal" then        -- check for lava/water at the sides
  3479.             T:turnRight(1)
  3480.             fluidType = lib.seal()      -- could be "", "water", "lava"
  3481.             T:turnLeft(2)
  3482.             local blockType = lib.seal()
  3483.             if fluidType == "" then     -- no water / lava so far
  3484.                 fluidType = blockType   -- could be "", "water", "lava"
  3485.             end
  3486.             T:turnRight(1)
  3487.         end
  3488.         return fluidType                -- could be "", "water", "lava"
  3489.     end
  3490.    
  3491.     function lib.placeTorch(R, torchSpaces, totalSteps)
  3492.         if R.torchInterval > 0 then -- torches onboard
  3493.             if torchSpaces == R.torchInterval then -- time to place another torch
  3494.                 if totalSteps < R.length then -- not at end of run
  3495.                     if T:getItemSlot("minecraft:torch") > 0 then
  3496.                         T:place("minecraft:torch", -1, "down")
  3497.                     end
  3498.                     torchSpaces = 1
  3499.                 end
  3500.             end
  3501.         end
  3502.         return torchSpaces -- original value or 1
  3503.     end
  3504.    
  3505.     local currentSteps = 0                  -- counter for infinite length. pause every 64 blocks
  3506.     local totalSteps = 0                    -- counter for all steps so far
  3507.     local torchSpaces = R.torchInterval     -- if torches present, counter to place with 8 blocks between
  3508.     local fluidType = ""
  3509.     local damLength = 0
  3510.     local damStarted = false
  3511.     local doContinue = true
  3512.     if T:getItemSlot("minecraft:torch") == 0 then
  3513.         R.torchInterval = 0 -- set to default 9 in getTask()
  3514.     end
  3515.     for steps = 1, R.length do
  3516.         -- starts on floor of tunnel
  3517.         doContinue, currentSteps = lib.continue(R, currentSteps, totalSteps) -- continue tunnelling?
  3518.         if not doContinue then
  3519.             break
  3520.         end
  3521.         T:go("C2U1C0", false, 0, true)      -- place floor, up 1, place ceiling
  3522.         fluidType = lib.checkSeal(R)        -- if R.data == "seal", check for water/lava at ceiling level
  3523.         if fluidType == "" then -- either R.data ~= "seal" or no fluid found
  3524.             torchSpaces = lib.placeTorch(R, torchSpaces, totalSteps) -- original value or 1 if torch placed
  3525.             T:go("F1D1")
  3526.         elseif fluidType == "water" then
  3527.             T:go("F1R2 C1D1 C1L2", false, 0, true)
  3528.             damStarted = true
  3529.             damLength = damLength + 1
  3530.         else    --lava
  3531.             T:go("F1D1")
  3532.         end
  3533.         blockType = lib.checkSeal(R)
  3534.         if blockType ~= "" then
  3535.             fluidType = blockType
  3536.         end
  3537.         currentSteps = currentSteps + 1
  3538.         totalSteps = totalSteps + 1
  3539.         torchSpaces = torchSpaces + 1
  3540.         if damStarted and fluidType == "" then -- was in water, but no more
  3541.             T:go("R2 F"..damLength + 1 .."U1L2F"..damLength + 1 .."D1")
  3542.             damStarted = false
  3543.         end
  3544.     end
  3545.     if fluidType ~= "" then -- water or lava found while tunnelling
  3546.         T:go("U1C0", false, 0, true)
  3547.         lib.checkSeal(R)
  3548.         T:go("C1", false, 0, true)
  3549.         T:down(1)
  3550.     end
  3551.     return {}
  3552. end
  3553.  
  3554. local function createDragonTrap() -- 49
  3555.     local lib = {}
  3556.    
  3557.     function lib.attack()
  3558.         local totalHitsF = 0
  3559.         local totalHitsU = 0
  3560.         local totalHitsD = 0
  3561.         while true do
  3562.             local hitF = false
  3563.             local hitU = false
  3564.             local hitD = false
  3565.             if turtle.attackUp() then
  3566.                 hitU = true
  3567.                 totalHitsU = totalHitsU + 1
  3568.             end
  3569.             if turtle.attackDown() then
  3570.                 hitD = true
  3571.                 totalHitsD = totalHitsD + 1
  3572.             end
  3573.             if turtle.attack() then
  3574.                 hitF = true
  3575.                 totalHitsF = totalHitsF + 1
  3576.             end
  3577.             if hitF or hitU or hitD then
  3578.                 print("hits forward: "..totalHitsF..", up: "..totalHitsU..", down: "..totalHitsD)
  3579.             end
  3580.         end
  3581.     end
  3582.     -- build up 145 blocks with ladders
  3583.     T:clear()
  3584.     menu.colourPrint("Press Enter to start 1 minute delay\n", colors.red)
  3585.     menu.colourPrint("Run to island centre across the bridge\n", colors.orange)
  3586.     menu.colourPrint("You have already made the bridge?...", colors.lime)
  3587.     read()
  3588.     for t = 60, 1, -1 do
  3589.         sleep(1)
  3590.         T:clear()
  3591.         io.write("Starting in "..t.. " seconds ")
  3592.     end
  3593.     for i = 1, 145 do
  3594.         T:go("U1C2")
  3595.         turtle.back()
  3596.         T:place("minecraft:ladder", -1, "down")
  3597.         turtle.forward()
  3598.     end
  3599.     T:go("R2F1C1 L1C1 L2C1 R1")
  3600.     for i = 1, 100 do
  3601.         T:go("F1C2U1C0D1")
  3602.     end
  3603.     T:forward(1)
  3604.     T:place("minecraft:obsidian", -1, "down")
  3605.     T:go("R2F1x2R2")
  3606.     T:placeWater("forward")
  3607.     T:go("R2F6R2")
  3608.     lib.attack()
  3609.    
  3610.     return {}
  3611. end
  3612.    
  3613. local function createEnderTower(stage) -- 66
  3614.     --[[ lower base = stage 1, upper base = 2, tower = 3 ]]
  3615.     local lib = {}
  3616.     --[[ go(path, useTorch, torchInterval, leaveExisting, preferredBlock) ]]
  3617.     function lib.getEmptySlots()
  3618.         local empty = 0
  3619.         for i = 1, 16 do
  3620.             if turtle.getItemCount(i) == 0 then
  3621.                 empty = empty + 1
  3622.             end
  3623.         end
  3624.         return empty
  3625.     end
  3626.  
  3627.     function lib.getStone(direction, stacks)
  3628.         --[[ get block user wants to use ]]
  3629.         local suck = turtle.suck   
  3630.         if direction == "down" then
  3631.             suck = turtle.suckDown
  3632.         end
  3633.         if T:getBlockType(direction) == "minecraft:chest" then
  3634.             T:sortInventory()
  3635.             local slot = T:getFirstEmptySlot() --find spare slot
  3636.             if slot > 0 then --empty slot found
  3637.                 turtle.select(1)
  3638.                 if stacks == 0 then
  3639.                     while suck() do end
  3640.                 else
  3641.                     for i = 1, stacks do -- get # stacks of stone from chest
  3642.                         suck()
  3643.                     end
  3644.                 end
  3645.                 if T:getSlotContains(slot) == "" then
  3646.                     return T:getMostItem()              -- empty chest
  3647.                 else
  3648.                     return T:getSlotContains(slot)      -- use this as default building block
  3649.                 end
  3650.             else
  3651.                 return T:getMostItem()              -- full inventory
  3652.             end
  3653.         else
  3654.             return T:getMostItem()              -- no chest
  3655.         end
  3656.     end
  3657.    
  3658.     function lib.stackBuckets()
  3659.         local data = {}
  3660.         local bucketSlot = 0
  3661.         local emptySlots = 0
  3662.         local water = 0
  3663.         T:sortInventory()
  3664.         for i = 1, 16 do
  3665.             -- find first empty bucket
  3666.             if turtle.getItemCount(i) > 0 then
  3667.                 data = turtle.getItemDetail(i)
  3668.                 if data.name == "minecraft:bucket" then
  3669.                     if bucketSlot == 0 then
  3670.                         bucketSlot = i
  3671.                     else
  3672.                         turtle.select(i)
  3673.                         turtle.transferTo(bucketSlot)
  3674.                     end
  3675.                 elseif data.name == "minecraft:water_bucket" then
  3676.                     water = water + 1
  3677.                 end
  3678.             else
  3679.                 emptySlots = emptySlots + 1
  3680.             end
  3681.         end
  3682.         return emptySlots, water
  3683.     end
  3684.    
  3685.     function lib.countWaterBuckets()
  3686.         local data = {}
  3687.         local buckets = 0
  3688.         for i = 1, 16 do
  3689.             data = turtle.getItemDetail(i)
  3690.             if data.name == "minecraft:water_bucket" then
  3691.                 buckets = buckets + 1
  3692.             end
  3693.         end
  3694.         return buckets
  3695.     end
  3696.    
  3697.     function lib.baseRun(preferredBlock, count, turn)
  3698.         for i = 1, count do
  3699.             T:go("C2F1", false, 0, false, preferredBlock)
  3700.         end
  3701.         T:go("C2"..turn, false, 0, false, preferredBlock)
  3702.     end
  3703.    
  3704.     function lib.outsideRun(preferredBlock)
  3705.         T:place("fence", -1, "down", false)
  3706.         T:forward(1)
  3707.         T:place(preferredBlock, -1, "down", false)
  3708.         T:forward(1)
  3709.         T:place(preferredBlock, -1, "down", false)
  3710.         T:forward(2)
  3711.         T:place(preferredBlock, -1, "down", false)
  3712.     end
  3713.    
  3714.     function lib.signRun(preferredBlock ,message)
  3715.         T:place(preferredBlock, -1, "down", false)
  3716.         T:forward(4)
  3717.         T:place(preferredBlock, -1, "down", false)
  3718.         turtle.back()
  3719.         turtle.back()
  3720.         T:down(1)
  3721.         T:place("sign", -1, "forward", false, message)
  3722.         T:go("U1F2")
  3723.     end
  3724.    
  3725.     function lib.goToWater(height)
  3726.         local built = 0 -- measures completed lift height
  3727.         while turtle.down() do -- takes turtle to bottom of water source
  3728.             height = height + 1
  3729.             if turtle.detect() then
  3730.                 built = built + 1
  3731.             end
  3732.         end
  3733.         T:up(1) -- above watersource assuming it is 1-1.5 blocks deep
  3734.         height = height - 1
  3735.         -- built = built - 1 not required as next block is water source: not detected
  3736.         return built, height
  3737.     end
  3738.    
  3739.     function lib.fillBuckets(toBuild)
  3740.         local emptySlots, water = lib.stackBuckets() -- gets no of empty slots + no of water buckets
  3741.         if water < toBuild then -- no of water buckets onboard less than required quantity
  3742.             for i = 1, toBuild do -- fill required no of buckets up to max space in inventory
  3743.                 emptySlots = lib.getEmptySlots()
  3744.                 if emptySlots == 0 then -- inventory full
  3745.                     break
  3746.                 else
  3747.                     if T:getWater("down") then
  3748.                         water = water + 1
  3749.                         sleep(0.5)
  3750.                     end
  3751.                 end
  3752.             end
  3753.         end
  3754.        
  3755.         return water
  3756.     end
  3757.    
  3758.     function lib.buildLift(preferredBlock)
  3759.         local built = 0 -- measures completed lift height
  3760.         local height = 0 -- measures total height from starting position
  3761.         built, height = lib.goToWater(height) -- returns lift blocks already placed, total height of drop from starting point
  3762.         local toBuild = height - built -- no of blocks to increase lift size
  3763.         while toBuild > 0 do -- at least 1 block height remaining
  3764.             local water = lib.fillBuckets(toBuild) -- no of water buckets onboard (could be more than required)
  3765.             if water > toBuild then
  3766.                 water = toBuild
  3767.             end
  3768.             while turtle.detect() do -- climb to top of existing lift
  3769.                 turtle.up()
  3770.                 height = height - 1
  3771.             end
  3772.             T:forward(1)
  3773.             for i = 1, water do -- build lift by no of water buckets
  3774.                 if T:placeWater("forward")  then
  3775.                     T:up(1)
  3776.                     height = height - 1
  3777.                     toBuild = toBuild - 1
  3778.                     T:place(preferredBlock, -1, "down", false)
  3779.                 end
  3780.             end
  3781.             turtle.back()
  3782.             -- may still be some height to complete, but needs refill
  3783.             if toBuild > 0 then
  3784.                 lib.goToWater(0) --return to source
  3785.                 lib.fillBuckets(toBuild)
  3786.             end
  3787.         end
  3788.         if height > 0 then -- if any remaining distance
  3789.             T:up(height)
  3790.         end
  3791.        
  3792.     end
  3793.    
  3794.     function lib.buildSection(preferredBlock, solid)
  3795.         -- builds a section without any blocks in the centre
  3796.         -- second layer of each section end walls have fence posts
  3797.         T:go("F1C2 F2C2 F1R1", false, 0, false, preferredBlock) -- first side solid row
  3798.         if solid then -- first layer of each section
  3799.             T:go("F1C2 F1R1", false, 0, false, preferredBlock) -- top side solid row
  3800.         else
  3801.             T:go("F1") -- top side solid row
  3802.             if not T:place("fence", -1, "down", false) then-- first side
  3803.                 T:place(preferredBlock, -1, "down", false)
  3804.             end
  3805.             T:go("F1R1") -- top side solid row
  3806.         end
  3807.         T:go("F1C2 F2C2 F1R1", false, 0, false, preferredBlock) -- far side solid row
  3808.         T:go("F1C2 F1R1U1", false, 0, false, preferredBlock) -- bottom side solid row
  3809.     end
  3810.     --[[
  3811.         clsTurtle methods:
  3812.         clsTurtle.place(self, blockType, damageNo, direction, leaveExisting)
  3813.         clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
  3814.     ]]
  3815.     -- remove 1 stack stone from chest
  3816.     local preferredBlock = lib.getStone("down", 1) -- use this as default building block
  3817.     if stage == 1 then
  3818.         -- build base floor
  3819.         --T:go("R2F2R1F3R1", false, 0, false, preferredBlock)
  3820.         T:go("R2F1C2R1F1C2F1C2F1C2R1", false, 0, false, preferredBlock)
  3821.         for i = 1, 2 do
  3822.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  3823.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  3824.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  3825.         end
  3826.         -- move back to centre, build water source, with soul sand at base of first source
  3827.         --T:go("R1F3L1C2F1C2F2D1", false, 0, false, preferredBlock) --just behind chest, 1 below ground level
  3828.         T:go("R1F3L1F2C2F1D1", false, 0, false, preferredBlock) --1 block behind chest, 1 below ground level
  3829.         T:place("minecraft:soul_sand", -1, "down", false) -- over block 1 of water source
  3830.         T:go("F1C2F1C2", false, 0, false, preferredBlock) -- over block 2 of water source
  3831.         T:go("F1C2U1C2", false, 0, false, preferredBlock) -- over block 4 of water source
  3832.         T:go("F1C2F1C2R2F5R2", false, 0, false, preferredBlock) -- over block 1 of water source
  3833.         T:placeWater("down")
  3834.         T:forward(2) -- over block 3 of water source
  3835.         T:placeWater("down")
  3836.         turtle.back() -- over block 2 of water source
  3837.         T:getWater("down")
  3838.         T:go("F2D1R2C2") -- over block 4 of water source
  3839.         T:go("U1", false, 0, false, preferredBlock)
  3840.         T:placeWater("down")
  3841.         T:forward(4)
  3842.         lib.stackBuckets() -- put all buckets in same slot
  3843.         T:dropItem("minecraft:dirt", "up", 0) -- drop dirt up:  clsTurtle.dropItem(self, item, direction, keepAmount)
  3844.         preferredBlock = lib.getStone("down", 6)
  3845.         T:go("R1F2R1U1") -- move to start position
  3846.         for i = 1, 2 do
  3847.             -- build first level of tower: 2 x outside run, 2 x sign run
  3848.             lib.outsideRun(preferredBlock)
  3849.             if i == 1 then -- place door
  3850.                 T:go("L1F1L1F1L1D1")
  3851.                 T:place("door", -1, "forward", false)
  3852.                 T:go("U1L1F1R1F1L1")
  3853.             end
  3854.             T:go("R1F1R1")
  3855.             lib.signRun(preferredBlock, "Pint size\nzombies\nProhibited")
  3856.             T:go("L1F1L1C2", false, 0, false, preferredBlock)
  3857.             T:forward(4) -- miss out centre block
  3858.             T:place(preferredBlock, -1, "down", false)
  3859.             T:go("R1F1R1")
  3860.             lib.signRun(preferredBlock, "Pint size\nzombies\nProhibited")
  3861.             T:go("L1F1L1")
  3862.             lib.outsideRun(preferredBlock)
  3863.             if i == 1 then -- layer 1
  3864.                 T:go("R1F1R1F1R1D1") -- place door
  3865.                 T:place("door", -1, "forward", false)
  3866.                 T:go("U1 R1F1 L1F5 L1U1 F2D1  F2R2 U1") -- go over door
  3867.             else -- layer 2
  3868.                 T:go("L1F5L1F6R2U1") -- over corner of lower platform
  3869.             end
  3870.         end
  3871.         for i = 1, 2 do -- build both sides of platform, leave centre missing
  3872.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  3873.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  3874.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  3875.         end
  3876.         T:go("R1F3L1C2F1C2F1C2F4C2F1C2F1C2", false, 0, false, preferredBlock) --fill in centre row
  3877.         --T:go("R2F6R1F1R1U1") -- go to start of tower base
  3878.         T:go("R2F7R2D3") -- go to start on top of chest
  3879.         T:sortInventory()
  3880.     elseif stage == 2 then
  3881.         -- start on top of chest, should have sufficient stone in inventory
  3882.         T:go("U3L1F1R1F1U1") -- go to start of tower base
  3883.         for i = 1, 7 do -- build 14 block high tower
  3884.             lib.buildSection(preferredBlock, false)
  3885.             lib.buildSection(preferredBlock, true)
  3886.         end
  3887.         T:go("R2F4R1F4R1", false, 0, false, preferredBlock) -- build upper platform (154 blocks remaining)
  3888.         for i = 1, 2 do -- build both sides of upper platform, leave centre missing
  3889.             lib.baseRun(preferredBlock, 12, "R1F1R1")
  3890.             lib.baseRun(preferredBlock, 12, "L1F1L1")
  3891.             lib.baseRun(preferredBlock, 12, "R1F1R1")
  3892.             lib.baseRun(preferredBlock, 12, "L1F1L1")
  3893.             lib.baseRun(preferredBlock, 12, "R1F6R1")
  3894.         end
  3895.         T:go("R1F5 L1C2 F1C2 F1C2 F1C2 F1C2 F4C2 F1C2 F1C2 F1C2 F1C2 ", false, 0, false, preferredBlock) --fill in centre row
  3896.         T:go("R2F5") -- return to drop area
  3897.         lib.buildLift(preferredBlock) -- build bubble lift
  3898.         T:go("F3R1F1R1U1") -- go to start of tower base
  3899.         T:go("C2F4 C2R1F1R1", false, 0, false, preferredBlock)      -- left side layer 21
  3900.         T:go("F2C2 F2C2 L1F1L1", false, 0, false, preferredBlock)   -- centre layer 21
  3901.         T:go("C2F4 C2R2U1", false, 0, false, preferredBlock)        -- right side layer 21
  3902.         T:go("C2F4 C2R1F1R1", false, 0, false, preferredBlock)      -- right side layer 22
  3903.         T:place("fence", -1, "down", false)                         -- fence centre of bottom side layer 22
  3904.         T:go("F2C2 F2L1F1L1", false, 0, false, preferredBlock)      -- centre layer 22
  3905.         T:go("C2F4 C2R2F2L1F1R2D2", false, 0, false, preferredBlock) --ready to place ladder
  3906.         T:place("ladder", -1, "forward", false)
  3907.         T:up(1)
  3908.         T:place("ladder", -1, "forward", false)
  3909.         --T:go("U2R1F4R1F1R1") -- ready to make upper part of tower base
  3910.         T:go("U2R1F4R1F1R1") -- ready to make upper part of tower base
  3911.         for i = 1, 2 do -- build both sides of platform, leave centre missing
  3912.             lib.baseRun(preferredBlock, 8, "R1F1R1")
  3913.             lib.baseRun(preferredBlock, 8, "L1F1L1")
  3914.             lib.baseRun(preferredBlock, 8, "R1F4R1")
  3915.         end
  3916.         T:go("R1F3 L1C2 F1C2 F1C2 F1", false, 0, false, preferredBlock) --fill in centre row
  3917.         T:place("minecraft:soul_sand", -1, "down", false)
  3918.         T:go("F1C2 F2C2 F1C2 F1C2", false, 0, false, preferredBlock)
  3919.         T:go("R2F6R1F1R1U1") -- go to start of tower base
  3920.         -- build 2 levels, finish signs and ladders
  3921.         T:go("C2F2 R1D2 U1", false, 0, false, preferredBlock)
  3922.         T:place("ladder", -1, "down", false)
  3923.         T:turnRight(1)
  3924.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  3925.         T:go("U1R2F2C2 R1F2C2 R1", false, 0, false, preferredBlock) --top right corner
  3926.         T:go("F4C2B2D1", false, 0, false, preferredBlock)
  3927.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  3928.         T:go("U1F2R1F1C2F1R1U1", false, 0, false, preferredBlock) --ready for second level
  3929.         T:go("C2F2 R2D1", false, 0, false, preferredBlock)
  3930.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  3931.         T:go("U1R2F2C2R1", false, 0, false, preferredBlock) --top left corner
  3932.         T:go("F1R1C2F4C2", false, 0, false, preferredBlock) --mid bottom row
  3933.         T:go("L1F1L1C2", false, 0, false, preferredBlock) -- bottom right corner
  3934.         T:go("F2R2D1", false, 0, false, preferredBlock)
  3935.         T:place("sign", -1, "forward", false, "UP\n^\n|\n|")
  3936.         T:go("U1R2F2C2", false, 0, false, preferredBlock) -- top right corner
  3937.         -- return to chest
  3938.         T:go("L1F1L1 F5D23R2", false, 0, false, preferredBlock) -- return to chest
  3939.         T:sortInventory()
  3940.     elseif stage == 3 then
  3941.         --[[ move to top of structure
  3942.         | 4 |
  3943.         |3 5|
  3944.         | X |
  3945.         |2 6|
  3946.         | 1 |
  3947.         ]]
  3948.         local towerHeight = 128 -- even no only suggest 128
  3949.         while turtle.detect() do
  3950.             turtle.up()
  3951.         end
  3952.         T:go("F1U1", false, 0, false, preferredBlock) -- return to finish tower
  3953.         for i = 1, towerHeight do -- 1
  3954.             T:go("C2U1", false, 0, false, preferredBlock)
  3955.         end
  3956.         T:go("F1L1F1R1D2")
  3957.         while turtle.down() do -- 2
  3958.             T:fillVoid("up", {preferredBlock})
  3959.         end
  3960.         T:go("F1R2C1R2F1D1", false, 0, false, preferredBlock)
  3961.         for i = 1, towerHeight / 2 do -- 3
  3962.             T:go("U2C2", false, 0, false, preferredBlock)
  3963.         end
  3964.         T:go("U1F1R1F1R1D1", false, 0, false, preferredBlock) -- back of tower facing front
  3965.         local deviate = false
  3966.         while turtle.down() do -- 4
  3967.             T:place("fence", -1, "up", false)
  3968.             if turtle.down() then
  3969.                 T:fillVoid("up", {preferredBlock})
  3970.             else
  3971.                 T:go("F1R2C1R1F1R1D1", false, 0, false, preferredBlock)
  3972.                 deviate = true
  3973.                 break
  3974.             end
  3975.         end
  3976.         if not deviate then
  3977.             T:go("F1L1F1R1D1", false, 0, false, preferredBlock)
  3978.         end
  3979.         for i = 1, towerHeight / 2 do -- 5
  3980.             T:go("U2C2", false, 0, false, preferredBlock)
  3981.         end
  3982.         T:go("F2R2", false, 0, false, preferredBlock) -- facing back of tower
  3983.         while turtle.down() do -- 6
  3984.             T:fillVoid("up", {preferredBlock}) --layer 129
  3985.         end
  3986.         T:go("F1L2C1U"..towerHeight)
  3987.         T:go("F4R1F3R1U1", false, 0, false, preferredBlock)
  3988.         -- add small platform at the top
  3989.         lib.baseRun(preferredBlock, 8, "R1F1R1")
  3990.         lib.baseRun(preferredBlock, 8, "L1F3L1")
  3991.         lib.baseRun(preferredBlock, 8, "L1F1L1")
  3992.         lib.baseRun(preferredBlock, 8, "R1F1R1")
  3993.         T:go("C2 F1C2 F1C2 F4C2 F1C2 F1C2 R2F3", false, 0, false, preferredBlock) --fill in centre row
  3994.         lib.buildLift(preferredBlock) -- build bubble lift
  3995.     end
  3996.     return {}
  3997. end
  3998.  
  3999. local function createFarm(R, extend) -- 31
  4000.     -- if extend ~= nil then this has been called from createFarmExtension()
  4001.     -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4002.     local lib = {}
  4003.     function lib.addWaterSource(R, pattern, storage)
  4004.         -- pattern = {"d","c","c","d"} t = place crafting  instead of dirt
  4005.         -- place(self, blockType, damageNo, direction, leaveExisting, signText)
  4006.         T:go("D1x2C2", false, 0, false, R.useBlockType)
  4007.         for i = 1, 4 do
  4008.             T:dig("forward")
  4009.             if pattern[i] == "d" then
  4010.                 T:place("dirt", -1, "forward", false)
  4011.             elseif pattern[i] == "t" then
  4012.                 --if not T:place("minecraft:crafting_table", -1, "forward", false) then
  4013.                 if T:place(storage, -1, "forward", false) then
  4014.                     if T:dropItem("crafting", "forward", 0) then
  4015.                         print("Crafting table -> buried storage")
  4016.                     end
  4017.                 else
  4018.                     T:place("dirt", -1, "forward", false) -- dirt if no storage available
  4019.                 end
  4020.             else
  4021.                 T:place(R.useBlockType, -1, "forward", false)
  4022.             end
  4023.             T:turnRight(1)
  4024.         end
  4025.         T:up(1)
  4026.         T:placeWater("down")
  4027.     end
  4028.    
  4029.     function lib.placeDirt(count, atCurrent)
  4030.         if atCurrent then
  4031.             local blockType = T:getBlockType("down")
  4032.             if blockType:find("dirt") == nil and blockType:find("grass_block") == nil then
  4033.                 T:place("dirt", -1, "down", false)
  4034.             end
  4035.         end
  4036.         for  i = 1, count do
  4037.             T:forward(1)
  4038.             T:dig("up")
  4039.             local blockType = T:getBlockType("down")
  4040.             if blockType:find("dirt") == nil and blockType:find("grass_block") == nil then
  4041.                 T:place("dirt", -1, "down", false)
  4042.             end
  4043.         end
  4044.     end
  4045.  
  4046.     function lib.placeStorage(storage, storageBackup)
  4047.         T:dig("down")
  4048.         if not T:place(storage, -1, "down", false) then-- place barrel/chest below
  4049.             T:place(storageBackup, -1, "down", false) -- place chest below
  4050.         end
  4051.     end
  4052.  
  4053.    
  4054.     -- extend "", "right" or "forward". only adds a single new farm.
  4055.     -- right adds farm and checks for existing front extensions, dealt with separately
  4056.     -- clsTurtle.place(blockType, damageNo, direction, leaveExisting)
  4057.     if extend == nil then
  4058.         extend = ""
  4059.     end
  4060.     local blockType = ""
  4061.     -- extend = "right": placed on cobble corner of existing farm facing right side
  4062.     -- extend = "front": placed on cobble corner of existing farm facing front
  4063.     -- else placed on ground at corner of potential new farm facing front
  4064.    
  4065.     local storage, storageBackup = utils.setStorageOptions()
  4066.     -- step 1 dig ditch round perimeter wall
  4067.     if extend == "right" then
  4068.         -- move to front corner ground ready for ditch
  4069.         T:go("F1L1F12D1R1", false, 0, false, R.useBlockType)
  4070.         -- cut ditch round new farm extension
  4071.         for i = 1, 12 do
  4072.             T:go("x0F1")
  4073.         end
  4074.         T:go("R1x0")
  4075.         for i = 1, 13 do
  4076.             T:go("x0F1")
  4077.         end
  4078.         T:go("R1x0")
  4079.         -- now at lower right corner. if extension below, do not cut ditch
  4080.         blockType = T:getBlockType("forward")
  4081.         if blockType:find("stone") ~= nil then -- already a farm extension on left side
  4082.             -- return to start for adding chests and walls
  4083.             T:go("U1R1F1L1F12", false, 0, false, R.useBlockType)
  4084.         else -- finish ditch
  4085.             for i = 1, 12 do
  4086.                 T:go("x0F1")
  4087.             end
  4088.             T:go("R1U1F1") -- on corner of new extension
  4089.         end
  4090.     elseif extend == "forward" then
  4091.         T:go("L1F2R1D1", false, 0, false, R.useBlockType)
  4092.         -- cut ditch round new farm extension
  4093.         for i = 1, 12 do
  4094.             T:go("x0F1", false, 0, false, R.useBlockType)
  4095.         end
  4096.         T:go("R1x0", false, 0, false, R.useBlockType)
  4097.         for i = 1, 13 do
  4098.             T:go("x0F1", false, 0, false, R.useBlockType)
  4099.         end
  4100.         T:go("R1x0", false, 0, false, R.useBlockType)
  4101.         for i = 1, 11 do
  4102.             T:go("x0F1", false, 0, false, R.useBlockType)
  4103.         end
  4104.         T:go("U1x0F1R1F12R1", false, 0, false, R.useBlockType) -- on corner of new extension
  4105.     else -- new farm. cut a groove round the entire farm base
  4106.         -- move to left side of intended wall
  4107.         T:go("L1F1x0R1", false, 0, false, R.useBlockType)
  4108.         for j = 1, 4 do
  4109.             for i = 1, 12 do
  4110.                 T:go("x0F1", false, 0, false, R.useBlockType)
  4111.             end
  4112.             T:go("R1x0F1", false, 0, false, R.useBlockType)
  4113.         end
  4114.         T:go("R1F1L1U1", false, 0, false, R.useBlockType)
  4115.     end
  4116.     -- stage 2 place sapling and double barrel/chest
  4117.     T:dig("down") --remove cobble if present
  4118.     T:place("dirt", -1, "down", false)
  4119.     T:go("F1R2")
  4120.     T:place("sapling", -1, "forward", false) -- plant sapling
  4121.     T:go("L1")
  4122.     lib.placeStorage(storage, storageBackup)
  4123.     T:go("L1F1R1")
  4124.     lib.placeStorage(storage, storageBackup)
  4125.     T:turnLeft(1)
  4126.     if extend == "right" then -- cobble wall exists so go forward to its end
  4127.         T:forward(9)
  4128.     else -- new farm or extend forward
  4129.         for i = 1, 9 do -- complete left wall to end of farm
  4130.             T:go("F1x0x2C2", false, 0, false, R.useBlockType)
  4131.         end
  4132.     end
  4133.     T:go("R1F1 R1x0 x2C2 F1D1", false, 0, false, R.useBlockType)-- turn round ready for first dirt col
  4134.     lib.addWaterSource(R, {"d","c","c","d"}, storage) -- water at top of farm
  4135.     lib.placeDirt(9, false) -- place dirt back to start
  4136.     lib.addWaterSource(R, {"c","c","t","d"}, storage) -- water source next to chests, includes crafting table
  4137.     T:go("U1F1R2")
  4138.     if T:getBlockType("down"):find(storage) == nil and T:getBlockType("down"):find(storageBackup) == nil then
  4139.         lib.placeStorage(storage, storageBackup)
  4140.     end
  4141.     T:go("R1F1L1")
  4142.     if T:getBlockType("down"):find(storage) == nil and T:getBlockType("down"):find(storageBackup) == nil then
  4143.         lib.placeStorage(storage, storageBackup)
  4144.     end
  4145.     T:go("F1D1")
  4146.     lib.placeDirt(9, true)
  4147.     local turn = "R"
  4148.     for i = 1, 7 do
  4149.         T:go("F1U1x0C2"..turn.."1F1"..turn.."1x0x2C2F1D1", false, 0, false, R.useBlockType)
  4150.         lib.placeDirt(9, true)
  4151.         if turn == "R" then
  4152.             turn = "L"
  4153.         else
  4154.             turn = "R"
  4155.         end
  4156.     end
  4157.     T:go("F1U1x0C2"..turn.."1F1"..turn.."1x0x2C2F1D1", false, 0, false, R.useBlockType)
  4158.     lib.addWaterSource(R, {"d","c","c","d"}, storage)
  4159.     lib.placeDirt(9, false)
  4160.     lib.addWaterSource(R, {"c","c","d","d"}, storage)
  4161.     T:go("F1U1R1C2x0F1x0x2C2R1", false, 0, false, R.useBlockType)
  4162.     for i = 1, 11 do
  4163.         T:go("F1x0x2C2", false, 0, false, R.useBlockType)
  4164.     end
  4165.     -- add barrel/chest to any existing farm extension to the right
  4166.     T:go("L1F1L1")
  4167.     if T:getBlockType("down"):find("stone") == nil then -- farm extension already exists to right
  4168.         lib.placeStorage(storage, storageBackup)
  4169.     end
  4170.     T:go("L1F11")
  4171.    
  4172.     return {"Modular farm completed"}
  4173. end
  4174.  
  4175. local function createFarmExtension(R) -- 32
  4176.     -- assume inventory contains 4 chests, 64 cobble, 128 dirt, 4 water, 1 sapling
  4177.     -- check position by rotating to face tree/sapling
  4178.     local doContinue = true
  4179.     local treePresent = false
  4180.     local extend = "right" -- default
  4181.     if R.subChoice == 1 then
  4182.         extend = "forward"
  4183.     end
  4184.     local storage, storageBackup = utils.setStorageOptions()
  4185.     local blockType = T:getBlockType("down")
  4186.     if blockType:find(storage) == nil and blockType:find(storageBackup) == nil then
  4187.         return
  4188.         {
  4189.             "Barrel or chest not present below\n",
  4190.             "Unable to calculate position",
  4191.             "Move me next to/front of the tree/sapling",
  4192.             "lower left corner of the existing farm."
  4193.         }
  4194.     else
  4195.         for i = 1, 4 do
  4196.             blockType = T:getBlockType("forward")
  4197.             if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil then
  4198.                 treePresent = true
  4199.                 break
  4200.             end
  4201.             T:turnRight()
  4202.         end
  4203.         if not treePresent then
  4204.             return
  4205.             {
  4206.                 "Unable to locate tree or sapling",
  4207.                 "Plant a sapling on the lower left",
  4208.                 "corner of the farm, or move me there"
  4209.             }
  4210.         end
  4211.     end
  4212.     if doContinue then -- facing tree. check if on front or l side of farm
  4213.         if extend == "forward" then
  4214.             T:go("R1F11") -- to other side of farm. may be stone or barrel/chest below
  4215.             blockType = T:getBlockType("down")
  4216.             if blockType:find(storage) ~= nil or blockType:find(storageBackup) ~= nil then
  4217.                 doContinue = false
  4218.             end
  4219.         else
  4220.             T:go("R2F9") -- to right of farm, may be sapling/tree in front
  4221.             blockType = T:getBlockType("forward")
  4222.             if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil then
  4223.                 doContinue = false
  4224.             end
  4225.         end
  4226.         if doContinue then -- extend farm.
  4227.             createFarm(R, extend)
  4228.         else
  4229.             return
  4230.             {
  4231.                 "This farm has already been extended",
  4232.                 "Move me next to/front of the tree / sapling",
  4233.                 "of the last extension in this direction."
  4234.             }
  4235.         end
  4236.     end
  4237.     return {"Modular crop farm extended"}
  4238. end
  4239.  
  4240. local function createFloorCeiling(R) -- 79 size integer 1 to 4
  4241.     --[[
  4242.     R.up = true for ceiling
  4243.     R.down = true for floor
  4244.     R.height = 0 for normal
  4245.     R.height combined with R.up/R.down used for remote access
  4246.     ]]
  4247.    
  4248.     local useBlock = T:getSlotContains(1)
  4249.     local waterPresent = false
  4250.    
  4251.     if R.useBlockType ~= "" then
  4252.         useBlock = R.useBlockType
  4253.     end
  4254.     print("Using ".. useBlock)
  4255.     local direction = "down"
  4256.     if R.up then
  4257.         direction = "up"
  4258.     end
  4259.     if R.height > 0 then -- remote placing. go up/down R.height first
  4260.         R.silent = true
  4261.         local depth = 0
  4262.         if R.down then -- floor could be under water
  4263.             while turtle.down() do
  4264.                 depth = depth + 1
  4265.             end
  4266.         elseif R.up then
  4267.             while turtle.up() do
  4268.                 depth = depth + 1
  4269.                 if depth > R.height + 3 then
  4270.                     break
  4271.                 end
  4272.             end
  4273.         end
  4274.         if not(R.height - depth <= 2 or depth - R.height <= 2) then
  4275.             T:up(depth)
  4276.             return {"Measured depth/height of "..depth.." > setting: "..R.height}
  4277.         end
  4278.         -- not returned so depth acceptable
  4279.     end
  4280.     -- check if block above/below
  4281.     local blockBelow = turtle.detectDown()
  4282.     local blockAbove = turtle.detectUp()
  4283.     if R.subChoice == 2 then -- New floor over existing
  4284.         -- if no block below, assume in correct position and continue
  4285.         -- else move up 1 and continue
  4286.         if blockBelow then T:up(1) end
  4287.     elseif R.subChoice == 4 then -- New ceiling under existing
  4288.         -- if no block above, assume in correct position and continue
  4289.         -- else move down 1 and continue
  4290.         if blockAbove then T:down(1) end
  4291.     end
  4292.    
  4293.     local evenWidth = false
  4294.     local evenHeight = false
  4295.     local loopWidth
  4296.     -- go(path, useTorch, torchInterval, leaveExisting)
  4297.     if R.width % 2 == 0 then
  4298.         evenWidth = true
  4299.         loopWidth = R.width / 2
  4300.     else
  4301.         loopWidth = math.ceil(R.width / 2)
  4302.     end
  4303.     if R.length % 2 == 0 then
  4304.         evenHeight = true
  4305.     end
  4306.     -- if R.width is even no, then complete the up/down run
  4307.     -- if R.width odd no then finish at top of up run and reverse
  4308.     for x = 1, loopWidth do
  4309.         -- Clear first column (up)
  4310.         local tAvailable = T:getStock(useBlock, -1)
  4311.         if tAvailable.total < R.length and not R.silent then
  4312.             return {"Insufficient resources to complete current row"}
  4313.         end
  4314.         for y = 1, R.length do
  4315.             local blockType = T:getBlockType("forward")
  4316.             if not waterPresent then
  4317.                 if blockType:find("lava") ~= nil or blockType:find("water") ~= nil then
  4318.                     waterPresent = true
  4319.                 end
  4320.             end
  4321.             T:place(useBlock, -1, direction, false) -- leaveExisting = false
  4322.             if y < R.length then
  4323.                 T:go("F1", false, 0, false)
  4324.             end
  4325.         end
  4326.         -- clear second column (down)
  4327.         if x < loopWidth or (x == loopWidth and evenWidth) then -- go down if on R.width 2,4,6,8 etc
  4328.             T:go("R1F1R1", false,0,false)
  4329.             tAvailable = T:getStock(useBlock, -1)
  4330.             if tAvailable.total < R.length and not R.silent then
  4331.                 return {"Insufficient resources to complete current row"}
  4332.             end
  4333.             for y = 1, R.length do
  4334.                 T:place(useBlock, -1, direction, false) -- leaveExisting = false
  4335.                 if y < R.length then
  4336.                     T:go("F1", false, 0, false)
  4337.                 end
  4338.             end
  4339.             if x < loopWidth then
  4340.                 T:go("L1F1L1", false,0,false)
  4341.             else
  4342.                 T:turnRight(1)
  4343.                 T:forward(R.width - 1)
  4344.                 T:turnRight(1)
  4345.             end
  4346.         else -- equals R.width but is 1,3,5,7 etc
  4347.             T:turnLeft(2) --turn round 180
  4348.             T:forward(R.length - 1)
  4349.             T:turnRight(1)
  4350.             T:forward(R.width - 1)
  4351.             T:turnRight(1)
  4352.         end
  4353.     end
  4354.     if waterPresent then
  4355.         return {"water or lava found"}
  4356.     end
  4357.     return {""}
  4358. end
  4359.  
  4360. local function createIceCanal(R) -- 55
  4361.     --[[
  4362.         R.subChoice =
  4363.         1: move right into canal, build left towpath
  4364.         2: build left towpath
  4365.         3: build right towpath
  4366.         4: move left into canal, build right towpath
  4367.         5/8: clear path 3 blocks high, place slabs/torches
  4368.         6/7: build alternating ice road / create 3 block high air gap (2 over water)
  4369.     ]]
  4370.     local oTurn = "R"
  4371.     if R.side == "R" then
  4372.         oTurn = "L"
  4373.     end
  4374.     local lib = {}
  4375.    
  4376.     function lib.convertTowpath(R)
  4377.         -- only used to convert existing water canal, so assume towpath already present
  4378.         -- starting position 1 block above existing towpath
  4379.         for i = 1, R.length do
  4380.             if turtle.detectDown() then                         -- eg existing torch
  4381.                 T:dig("down")
  4382.             end
  4383.             local placeSlab = true
  4384.             if R.torchInterval > 0 then                         -- place torches
  4385.                 if i == 1 or i % R.torchInterval == 0 then      -- ready to place torch
  4386.                     --go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4387.                     T:go("C2x0", false, 0, false, R.useBlockType)-- place solid block below
  4388.                     T:go("F1R2x0")
  4389.                     T:place("torch", 0, "forward")              -- place torch, move forward
  4390.                     T:turnRight(2)                              -- turn round
  4391.                     placeSlab = false
  4392.                 end
  4393.             end
  4394.             if placeSlab then
  4395.                 T:dig("up")
  4396.                 if not T:place("slab", 0, "down") then          -- break if out of slabs
  4397.                     break
  4398.                 end
  4399.                 if i < R.length then
  4400.                     T:forward(1)                                -- move forward
  4401.                 end
  4402.             end
  4403.         end
  4404.     end
  4405.    
  4406.     function lib.iceCanalTowpath(R)
  4407.         -- move forward placing slabs along the way. If existing water canal, ceiling will be raised by 1 block
  4408.         local torchInterval = 0
  4409.         local placeIce = true
  4410.         for i = 1, R.length do
  4411.             local addTorch = false
  4412.             if R.torchInterval > 0 then
  4413.                 if i == 1 then addTorch = true end
  4414.                 if torchInterval >= R.torchInterval then
  4415.                     addTorch = true
  4416.                     torchInterval = 0
  4417.                 end
  4418.             end
  4419.             lib.iceCanalEdge(R, addTorch, i, placeIce)
  4420.             torchInterval = torchInterval + 1
  4421.             placeIce = not placeIce
  4422.         end
  4423.         T:go(oTurn.."1")
  4424.     end
  4425.    
  4426.     function lib.iceCanalEdge(R, addTorch, numBlocks, placeIce)
  4427.         -- starting position facing canal side
  4428.         local blockType = T:getBlockType("forward")         -- ? air / slab / other
  4429.         local isWater, isSource, isIce = T:isWater("down")  -- water / ice below
  4430.         if blockType:find("slab") == nil then               -- add slab
  4431.             if addTorch then                                -- check if torch needed
  4432.                 -- T:place(blockType, damageNo, direction, leaveExisting, signText)
  4433.                 if not T:place("stone", -1, "forward", false) then
  4434.                     T:checkInventoryForItem({"stone"}, {math.ceil(R.length / R.torchInterval)}, true)
  4435.                 end
  4436.                 T:go("U1x1 U1x1 D1")                    -- water level to 2 above water level
  4437.                 if T:getItemSlot("minecraft:torch", -1) > 0 then
  4438.                     T:place("torch", -1, "forward", false)
  4439.                 end
  4440.                 T:down(1)                               -- back to above water level
  4441.                 if not isIce then                       -- break block below if NOT ice
  4442.                     T:dig("down")
  4443.                 end
  4444.             else
  4445.                 if not T:place("slab", -1, "forward", false) then
  4446.                     T:checkInventoryForItem({"slab"}, {R.length - numBlocks}, true)
  4447.                 end
  4448.                 if not isSource then                    -- NOT on water, so dig above
  4449.                     T:go("U1x1 U1x1 D2")
  4450.                 end
  4451.                 if not isIce and not isSource then
  4452.                     T:dig("down")
  4453.                 end
  4454.             end
  4455.         else -- slab already on side
  4456.             if addTorch then                            -- check if torch needed
  4457.                 T:dig("forward")
  4458.                 if not T:place("stone", -1, "forward", false) then
  4459.                     T:checkInventoryForItem({"stone"}, {math.ceil(R.length / R.torchInterval)}, true)
  4460.                 end
  4461.                 T:go("U1x1 U1x1 D1")                    -- water level to 2 above water level
  4462.                 if T:getItemSlot("minecraft:torch", -1) > 0 then
  4463.                     T:place("torch", -1, "forward", false)
  4464.                 end
  4465.                 T:down(1)                               -- back to above water level
  4466.                 if not isIce then                       -- break block below if NOT ice
  4467.                     T:dig("down")
  4468.                 end
  4469.             end
  4470.         end
  4471.         if R.data == "ice" and placeIce and not isIce then -- R.data = "ice", placeIce = true, not already ice present
  4472.             T:place("ice", -1, "down", true)
  4473.         end
  4474.         if numBlocks < R.length then
  4475.             T:go(oTurn.."1F1"..R.side.."1")
  4476.         end
  4477.     end
  4478.    
  4479.     function lib.convertIcepath(length)
  4480.         -- use only for placing ice to convert a water canal
  4481.         -- place ice on alternate blocks until length reached or run out of ice
  4482.         local placeIce = true
  4483.         for i = 1, length do
  4484.             if T:getBlockType("down"):find("ice") == nil then -- no ice below
  4485.                 T:dig("down") -- remove any existing block
  4486.                 if placeIce then
  4487.                     if not T:place("ice", -1, "down", true) then -- out of ice
  4488.                         break
  4489.                     end
  4490.                     if i == length - 1 then
  4491.                         break
  4492.                     end
  4493.                 end
  4494.             else -- ice already below
  4495.                 placeIce = true
  4496.             end
  4497.             T:go("U1x0 D1F1")
  4498.             placeIce = not placeIce -- reverse action
  4499.         end
  4500.     end
  4501.    
  4502.     function lib.convertToAir(length)
  4503.         -- use only for converting a water canal. start at ground level
  4504.         -- dig up/down/forward to clear space
  4505.         for i = 1, length + 1 do
  4506.             T:go("U1x0D1")
  4507.             if i < length + 1 then
  4508.                 T:go("x2F1")
  4509.             else
  4510.                 T:dig("down")
  4511.             end
  4512.         end
  4513.     end
  4514.    
  4515.     function lib.initialise(R)
  4516.         if R.subChoice == 1 or R.subChoice == 4 then       
  4517.             local blockType = T:getBlockType("down")        -- ? at ground/water level or on top of existing slab
  4518.             if blockType:find("slab") ~= nil then           -- slab already present
  4519.                 T:go(oTurn.."1F1D1"..R.side.."2")           -- move right/left forward, down onto ice canal top, face canal wall
  4520.             elseif blockType:find("torch") ~= nil then
  4521.                 T:go(oTurn.."1F1D2"..R.side.."2")           -- move right/left forward, down onto ice canal top, face canal wall
  4522.             else                                            -- assume on ground / water level
  4523.                 T:go(oTurn.."1F1"..R.side.."2")             -- move right/left forward onto ice canal top, face canal wall
  4524.             end
  4525.         else
  4526.             if T:isWater("forward") then                    -- player put turtle inside canal water
  4527.                 T:up(1)
  4528.             end
  4529.             T:go(R.side.."1")                               -- face canal wall
  4530.         end
  4531.     end
  4532.    
  4533.     if R.length == 0 then R.length = 1024 end
  4534.  
  4535.     if R.subChoice <= 4  then                               -- towpath 1,2,3,4
  4536.         lib.initialise(R)                                   -- reposition
  4537.         lib.iceCanalTowpath(R)                              -- build towpath
  4538.     elseif R.subChoice == 5 or R.subChoice == 8 then        -- assume placed on towpath
  4539.         if T:getBlockType("down"):find("slab") ~= nil then  -- slab already present
  4540.             T:go("F1")
  4541.         else
  4542.             T:up(1)
  4543.         end
  4544.         lib.convertTowpath(R)
  4545.     elseif R.subChoice == 6 or R.subChoice == 7 then   
  4546.         if R.data == "ice" then                         -- assume placed on existing ice or initial ice position
  4547.             lib.convertIcepath(R.length)-- place ice
  4548.         else                                            -- assume placed on empty path
  4549.             lib.convertToAir(R.length)                  -- clear 3 high area
  4550.         end
  4551.     end
  4552.    
  4553.     return {}
  4554. end
  4555.  
  4556. local function createLadder(R) -- 12
  4557.     -- createLadder(R.data ="bedrock", R.height = 70, R.depth = -48)
  4558.     -- go(path, useTorch, torchInterval, leaveExisting)
  4559.     -- place(blockType, damageNo, direction, leaveExisting)
  4560.     local lib = {}
  4561.    
  4562.     function lib.placeLadder(direction, ledge, i, height)
  4563.         -- 1 check both sides and behind
  4564.         local fluid = false
  4565.         local block = T:isWaterOrLava("forward", ledge)
  4566.         if block:find("water") ~= nil or block:find("lava") ~= nil then
  4567.             --[[ surround 2 block shaft with blocks ]]
  4568.             T:go("R1C1 R1C1 R1C1 R1F1 L1C1 R1C1 R1C1 R1C1F1 R2C1 x1")
  4569.         else
  4570.             --[[ no water/lava so prepare ladder site]]
  4571.             T:go("F1 L1C1 R1C1 R1C1 L1B1", false, 0, true)
  4572.         end
  4573.         if not T:place("ladder", -1, "forward", false) then
  4574.             T:checkInventoryForItem({"ladder"}, {height - i}, false)
  4575.         end
  4576.         -- 3 check if ledge, torch
  4577.         if ledge == 0 and i > 1 then -- place block above unless new ladder
  4578.             T:place("common", -1, direction, false) -- any common block
  4579.         elseif ledge == 1 then
  4580.             T:place("minecraft:torch", -1, direction, false)
  4581.         elseif ledge == 2 then
  4582.             ledge = -1
  4583.         end
  4584.        
  4585.         return ledge
  4586.     end
  4587.    
  4588.     local retValue = {}
  4589.     local ledge = 0
  4590.     local height = math.abs(R.depth - R.height) --height of ladder
  4591.     local blockType = T:getBlockType("forward")
  4592.     if R.up then -- create ladder from current level to height specified
  4593.         for i = 1, height do -- go up, place ladder as you go
  4594.             ledge = lib.placeLadder("down", ledge, i, height) -- ladder placed forward, stone ledge for torch placed down
  4595.             if i <  height then
  4596.                 T:up(1)
  4597.                 ledge = ledge + 1
  4598.             end
  4599.         end    
  4600.     else -- R.down = true: ladder towards bedrock      
  4601.         local success = true
  4602.         local numBlocks, errorMsg = 0, ""
  4603.         T:down(1)
  4604.         for i = 1, height do -- go down, place ladder as you go
  4605.             ledge = lib.placeLadder("up", ledge, i, heigt) -- ladder placed forward, stone torch placed up
  4606.             --success, blocksMoved, errorMsg, blockType = clsTurtle.down(self, steps, getBlockType)
  4607.             if i < height then
  4608.                 success, numBlocks, errorMsg, blockType = T:down(1, true) -- true = return blockType
  4609.                 ledge = ledge + 1
  4610.             end
  4611.             -- if looking for stronghold then check for stone_bricks
  4612.             if blockType:find("stone_bricks") ~= nil then
  4613.                 table.insert(retValue, "Stronghold discovered")
  4614.                 break -- stop descent at stronghold
  4615.             end
  4616.         end
  4617.         -- if user requested shelter create chamber at this level
  4618.         if R.data == "chamber" then -- user has chosen to build a chamber
  4619.             table.insert(retValue, "Shelter constucted at level".. R.depth)
  4620.             if blockType:find("bedrock") ~= nil then
  4621.                 T:findBedrockTop(0) -- test to check if on safe level immediately above tallest bedrock
  4622.             end
  4623.             -- In shaft, facing start direction, on lowest safe level
  4624.             -- create a square space round shaft base, end facing original shaft, 1 space back
  4625.             T:go("L1n1 R1n3 R1n2 R1n3 R1n1", false, 0, true)
  4626.             T:go("U1Q1 R1Q3 R1Q2 R1Q3 R1Q1 R1D1", false, 0, true)
  4627.         end
  4628.     end
  4629.    
  4630.     return retValue
  4631. end
  4632.  
  4633. local function createLadderToWater(R) -- 86
  4634.     -- go down to water/lava with alternaate solid/open layers
  4635.     -- create a working area at the base
  4636.     -- Return to surface facing towards player placing ladders
  4637.     local inAir = true
  4638.     local numBlocks, errorMsg = 0, ""
  4639.     local height = 2
  4640.     local blockType = T:getBlockType("down")
  4641.     if blockType ~= "" then -- not over air
  4642.         T:forward(1)
  4643.     end
  4644.     T:go("R2D1") -- face player, go down 2
  4645.     while inAir do --success = false when hits water/lava
  4646.         blockType = T:isWaterOrLava("down")
  4647.         if blockType:find("water") ~= nil or blockType:find("lava") ~= nil then
  4648.             inAir = false
  4649.         end
  4650.         T:go("C1R1 C1R2 C1R1", false, 0, false) -- surround front  and sides with cobble
  4651.         if inAir then
  4652.             T:down(1)
  4653.             height = height + 1
  4654.         end
  4655.         T:place("ladder", 0, "up")
  4656.     end
  4657.     -- In shaft, facing opposite start direction, on water/lava, ladders above
  4658.     T:go("C2", false, 0, false)
  4659.     utils.goBack(1)
  4660.     T:place("ladder", 0, "forward")
  4661.     T:up(3)
  4662.     height = height - 3
  4663.     for i = 1, height do
  4664.         if i < height then
  4665.             T:go("C2U1", false, 0, false)
  4666.         else
  4667.             T:go("C2", false, 0, false)
  4668.         end
  4669.     end
  4670.  
  4671.     return {}
  4672. end
  4673.  
  4674. local function createMine() -- 11
  4675.     -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4676.     T:clear()  
  4677.     T:go("m32U1R2M16", true, 8, true) -- mine ground level, go up, reverse and mine ceiling to mid-point
  4678.     T:go("U2D2") -- create space for chest
  4679.     T:place("minecraft:chest", -1, "up", false)
  4680.     T:emptyTrash("up")
  4681.     T:go("D1R1m16U1R2M16", true, 8, true) -- mine floor/ceiling of right side branch
  4682.     T:emptyTrash("up")
  4683.     T:go("D1m16U1R2M16", true, 8, true) -- mine floor/ceiling of left side branch
  4684.     T:emptyTrash("up")
  4685.     T:go("L1M15F1R1D1", true, 8, true) -- mine ceiling of entry corridor, turn right
  4686.     T:go("F1x0 F1x0 n14 R1n32 R1n32 R1n32 R1n14 F1x0 F1U1", true, 8, true)-- mine floor of 36 x 36 square corridor
  4687.     T:go("R1F16R2") --return to centre
  4688.     T:emptyTrash("up")
  4689.     T:go("F16R1") --return to entry shaft
  4690.     T:go("F2Q14R1Q32R1Q32R1Q32R1Q14F2R1", true, 8, true) --mine ceiling of 36x36 square corridor. return to entry shaft + 1
  4691.     T:go("F16R2") --return to centre
  4692.     T:emptyTrash("up")
  4693.     -- get rid of any remaining torches
  4694.     while T:getItemSlot("minecraft:torch", -1) > 0 do
  4695.         turtle.select(T:getItemSlot("minecraft:torch", -1))
  4696.         turtle.dropUp()
  4697.     end
  4698.     T:go("F16R1F1R1") --return to shaft + 1
  4699.     for i = 1, 8 do
  4700.         T:go("N32L1F1L1", true, 8, true)
  4701.         T:go("N16L1F"..(i * 2).."R2", true, 8, true)
  4702.         T:emptyTrash("up")
  4703.         if i < 8 then
  4704.             T:go("F"..(i * 2).."L1N16R1F1R1", true, 8, true)
  4705.         else
  4706.             T:go("F"..(i * 2).."L1N16L1", true, 8, true)
  4707.         end
  4708.     end
  4709.     T:go("F17L1") -- close gap in wall, return to ladder + 1
  4710.     for i = 1, 8 do
  4711.         T:go("N32R1F1R1", true, 8, true)
  4712.         T:go("N16R1F"..(i * 2).."R2", true, 8, true)
  4713.         T:emptyTrash("up")
  4714.         if i < 8 then
  4715.             T:go("F"..(i * 2).."R1N16L1F1L1", true, 8, true)
  4716.         else
  4717.             T:go("F"..(i * 2).."R1N16R1", true, 8, true)
  4718.         end
  4719.     end
  4720.     T:go("F16R1")
  4721.     T:clear()
  4722.     return{"Mining operation complete"}
  4723. end
  4724.  
  4725. local function createMobFarmCube(R) -- 61, 62
  4726.     --[[
  4727.     Part 1 / 3 Mob Spawner Farm
  4728.     blaze = true: blaze spawner in nether
  4729.         R.subChoice is set to:
  4730.         1 = on top of spawner
  4731.         2 = line of sight
  4732.         3 = room below
  4733.     blaze = false: overworld mob spawner
  4734.         R.subChoice is set to:
  4735.         1 = on top of spawner
  4736.         2 = bottom left corner
  4737.         3 = top left corner
  4738.         4 = bottom right, corner
  4739.         5 = top right corner
  4740.         R.width / R.length set by player (external size)
  4741.     ]]
  4742.     local blaze = true
  4743.     if R.data == "spawner" or R.data == "chest" then
  4744.         blaze = false
  4745.     end
  4746.     local continue = false
  4747.     if R.data == "restart" then
  4748.         continue = true
  4749.     end
  4750.     R.direction = "clock"       -- starting on right side
  4751.     if not blaze then
  4752.         print("R.width: "..tostring(R.width))
  4753.         R.width = R.width - 2       -- internal width
  4754.         R.length = R.length - 2     -- internal length
  4755.        
  4756.         if R.subChoice == 2 or R.subChoice == 3 then
  4757.             R.direction = "anticlock"
  4758.         end
  4759.     end
  4760.     -- R.data allows for 2-part operation "blaze" = main cube, "restart" = killzone
  4761.     T:clear()
  4762.     local lib = {}
  4763.    
  4764.     function lib.floorSection(length)
  4765.         for i = 1, length do        -- starts on top left corner
  4766.             T:go("C2")
  4767.             if i < length then
  4768.                 T:forward(1)
  4769.             else
  4770.                 T:go("R1F1")
  4771.             end
  4772.         end
  4773.     end
  4774.    
  4775.     function lib.wallSection(blaze)
  4776.         blaze = blaze or false
  4777.         for i = 1, 4 do
  4778.             for j = 1, 11 do
  4779.                 if blaze then
  4780.                     T:place("slab", 0, "up", false)
  4781.                     T:go("C2", false, 0, false)
  4782.                 else
  4783.                     T:go("C0C2", false, 0, false)
  4784.                 end
  4785.                 if j < 11 then
  4786.                     T:forward(1)
  4787.                     T:go("R2C1L2", false, 0, false)
  4788.                 else
  4789.                     T:turnRight(1)
  4790.                 end
  4791.             end
  4792.         end
  4793.     end
  4794.    
  4795.     function lib.ceiling(blaze)
  4796.         -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  4797.         -- all outer walls complete, now for remaining 9x9 ceiling
  4798.         blaze = blaze or false
  4799.         for i = 1, 9 do
  4800.             for j = 1, 9 do
  4801.                 if blaze then
  4802.                     T:place("slab", 0, "up", false)
  4803.                     T:dig("down")
  4804.                 else
  4805.                     T:go("C0x2", false, 0, true)
  4806.                 end
  4807.                 if j < 9 then
  4808.                     T:forward(1)
  4809.                 else    -- end of length
  4810.                     local place = false
  4811.                     if i%2 == 1 then -- odd numbers 1,3,5,7,9
  4812.                         if i < 9 then
  4813.                             place = true
  4814.                             T:go("R1F1 R1")
  4815.                         end
  4816.                     else
  4817.                         place = true
  4818.                         T:go("L1F1 L1")
  4819.                     end
  4820.                     if place then
  4821.                         if blaze then
  4822.                             T:place("slab", 0, "up", false)
  4823.                             T:dig("down")
  4824.                         else
  4825.                             T:go("C0x2", false, 0, true)
  4826.                         end
  4827.                     end
  4828.                 end
  4829.             end
  4830.         end
  4831.     end
  4832.    
  4833.     function lib.clearWall(length)
  4834.         for i = 1, 4 do
  4835.             for j = 1, length do
  4836.                 if j < length then
  4837.                     T:go("x0x2F1")
  4838.                 else
  4839.                     T:go("x0x2R1")
  4840.                 end
  4841.             end
  4842.         end
  4843.     end
  4844.    
  4845.     function lib.isSpawner()
  4846.         local blockType = T:getBlockType("down")
  4847.         if blockType:find("spawner") ~= nil then
  4848.             return true, "top"
  4849.         end
  4850.         blockType = T:getBlockType("up")
  4851.         if blockType:find("spawner") ~= nil then
  4852.             return true, "bottom"
  4853.         end
  4854.         blockType = T:getBlockType("forward")
  4855.         if blockType:find("spawner") ~= nil then
  4856.             return true, "forward"
  4857.         end
  4858.         return false, ""
  4859.     end
  4860.    
  4861.     function lib.placeFloor(width, length, blockType)
  4862.         -- T:place(blockType, damageNo, direction, leaveExisting, signText)
  4863.         for i = 1, width do            
  4864.             for j = 1, length do
  4865.                 T:place(blockType, -1, "down", false)
  4866.                 if j < length then
  4867.                     T:forward(1)
  4868.                 else
  4869.                     if i%2 == 1 then -- odd numbers 1,3,5,7,9
  4870.                         if i < width then
  4871.                             T:go("R1F1R1", false, 0, true)
  4872.                         end
  4873.                     else
  4874.                         T:go("L1F1L1", false, 0, true)
  4875.                     end
  4876.                 end
  4877.             end
  4878.         end
  4879.     end
  4880.    
  4881.     function lib.searchStrip(distance)
  4882.         --go forward until hit either a wall or a chest
  4883.         local blocks = 1
  4884.         print("Searching strip, distance = "..distance)
  4885.         while blocks < distance do --max travel is external width/length
  4886.             if turtle.forward() then
  4887.                 blocks = blocks + 1
  4888.             else
  4889.                 print("Checking for chest")
  4890.                 if lib.isChest("forward") then
  4891.                     if turtle.forward() then
  4892.                         blocks = blocks + 1
  4893.                     end
  4894.                 else
  4895.                     break
  4896.                 end
  4897.             end
  4898.         end
  4899.     end
  4900.    
  4901.     function lib.findChests(R)
  4902.         for i = 1, 4 do
  4903.             print("Searching wall "..i)
  4904.             if i == 1 or i == 3 then
  4905.                 lib.searchStrip(R.width)    -- find and empty chests along width
  4906.             else
  4907.                 lib.searchStrip(R.length)   -- find and empty chests along length
  4908.             end
  4909.             if R.direction == "clock" then
  4910.                 T:turnRight(1)
  4911.             else
  4912.                 T:turnLeft(1)
  4913.             end
  4914.         end
  4915.  
  4916.         -- checked all walls
  4917.         T:go("F".. math.floor(R.width / 2)) -- now at mid-dungeon, next to wall
  4918.         if T:getItemSlot("chest") > 0 then
  4919.             if R.direction == "clock" then
  4920.                 T:turnLeft(1)
  4921.             else
  4922.                 T:turnRight(1)
  4923.             end
  4924.             -- now at mid-dungeon, facing wall
  4925.             -- deposit chest outside the dungeon
  4926.             while turtle.back() do end -- backing spawner
  4927.             T:go("x0 F1x0 F1x0 F1x0 F1x0 F1x0 F1x0 x1x2")
  4928.             -- place(self, blockType, damageNo, direction, leaveExisting, signText)
  4929.             T:place("chest", -1, "forward", false)
  4930.             -- empty out all except stone and slab
  4931.             T:emptyInventorySelection("forward", {"cobble", "tuff", "slab", "granite", "andesite", "diorite" }, {0,0,0,0,0,0})
  4932.             T:turnLeft(2)
  4933.             T:checkInventoryForItem({"stone"}, {512}, false, "Full cube uses ~700 blocks\nEstimate your requirements")
  4934.             while turtle.forward() do end -- facing spawner
  4935.         else
  4936.             if R.direction == "clock" then
  4937.                 T:turnRight(1)
  4938.             else
  4939.                 T:turnLeft(1)
  4940.             end
  4941.         end -- now at mid-dungeon, facing spawner
  4942.     end
  4943.    
  4944.     function lib.enterDungeon(R)
  4945.         --[[ find and empty any chests, return to dungeon wall ]]
  4946.         print("Entering dungeon")
  4947.         local blockType = T:getBlockType("forward")
  4948.         if blockType == "" then -- nothing in front.Error
  4949.             return false, "No block in front: Check position."
  4950.         else -- attempt entry into dungeon wall
  4951.             if R.subChoice == 2 then        -- bottom left
  4952.                 T:go("R1F1 L1U2 F2R1")
  4953.             elseif R.subChoice == 3 then    -- top left
  4954.                 T:go("R1F1 L1D1 F2R1")
  4955.             elseif R.subChoice == 4 then    -- bottom right
  4956.                 T:go("L1F1 R1U2 F2L1")
  4957.             elseif R.subChoice == 5 then    -- top right
  4958.                 T:go("L1F1 R1D1 F2L1")
  4959.             end
  4960.             while turtle.down() do end -- either on floor or chest
  4961.             if lib.isChest("down") then
  4962.                 turtle.down()
  4963.             end
  4964.             print("Searching for chests")
  4965.             lib.findChests(R)   -- go round inside walls  emptying chests. Finish mid-wall
  4966.         end
  4967.         return true, ""-- success, message
  4968.     end
  4969.    
  4970.     function lib.isChest(direction)
  4971.         direction = direction or "forward"
  4972.         local blockType = T:getBlockType(direction)
  4973.         if blockType:find("chest") ~= nil then -- chest found. early stages so empty and break it
  4974.             print("Chest found")
  4975.             while T:suck(direction) do end
  4976.             T:dig(direction, false) -- false prevents checking for chests
  4977.             return true
  4978.         elseif blockType:find("torch") ~= nil then
  4979.             print("Torch found")
  4980.             T:dig(direction, false) -- false prevents checking for chests
  4981.             return true
  4982.         end
  4983.         return false
  4984.     end
  4985.        
  4986.     function lib.findSpawner(blaze)
  4987.         local moves  = 0
  4988.         local quit = false
  4989.         -- assume turtle placed on centre of inside spawner wall in front of spawner
  4990.         -- or as close as possible in Nether
  4991.         print("Checking if next to spawner")
  4992.         local found, position = lib.isSpawner() -- true/false, top/bottom/nil
  4993.         if not found then -- move forward towards spawner
  4994.             print("Not close to spawner")
  4995.             while turtle.forward() and not quit do
  4996.                 moves = moves + 1
  4997.                 if moves > 16 then
  4998.                     quit = true
  4999.                 end
  5000.             end
  5001.             found, position = lib.isSpawner() -- true/false, top/bottom/nil
  5002.             if not found then
  5003.                 if blaze then -- could be behind a wall
  5004.                     print("Assuming blaze spawner behind a wall")
  5005.                     T:forward(1)
  5006.                     moves = moves + 1
  5007.                     while turtle.forward() and not quit do
  5008.                         moves = moves + 1
  5009.                         if moves > 16 then
  5010.                             quit = true
  5011.                         end
  5012.                     end
  5013.                     found, position = lib.isSpawner() -- true/false, top/bottom/nil
  5014.                     if not found then
  5015.                         T:go("R2F"..moves + 2 .."R2")
  5016.                     end
  5017.                 end
  5018.             end
  5019.         end
  5020.        
  5021.         return found, position
  5022.     end
  5023.    
  5024.    
  5025.     if not continue then -- new mob cube either dungeon or blaze
  5026.         -- clsTurtle.go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5027.         -- determine spawner position level 4, move to top of spawner (level 6)
  5028.         print("Checking if already at spawner")
  5029.         local found, position = lib.isSpawner() -- already on spawner?
  5030.         if blaze then
  5031.             if not found then -- away from spawner
  5032.                 if R.subChoice == 3 then
  5033.                     T:go("U5")
  5034.                 end
  5035.                 found, position = lib.findSpawner(blaze)
  5036.             end
  5037.         else -- go to bottom of dungeon and empty chests
  5038.             if not found then --outside dungeon
  5039.                 local success, message = lib.enterDungeon(R)
  5040.                 if not success then
  5041.                     return {message}
  5042.                 end
  5043.                 found, position = lib.findSpawner(blaze) -- is spawner in front / above / below?
  5044.             end
  5045.         end
  5046.        
  5047.         if found then -- true: move to correct starting position
  5048.             --[[
  5049.             1 |c|c|c|c|c|c|c|c|c|c|c|
  5050.             2 |w| | | | | | | | | |w|
  5051.             3 |w| | | | | | | | | |w|
  5052.             4 |w| | | | | | | | | |w|
  5053.             5 |w| | | | | | | | | |w|
  5054.             6 |w| | | | |s| | | | |w|
  5055.             7 |w| | | | | | | | | |w|
  5056.             8 |w| | | | | | | | | |w|
  5057.             9 |w| | | | | | | | | |w|
  5058.            10 |w| | | | | | | | | |w| exit level for overworld
  5059.            11 |f|f|f|f|f|f|f|f|f|f|f|
  5060.            12 |f|f|f|f|f|f|f|f|f|f|f| sub floor for overworld
  5061.                1 2 3 4 5 6 7 8 9 1 1
  5062.                                  0 1
  5063.             ]]
  5064.             -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5065.             if position == "bottom" then
  5066.                 T:go("B1U2F1")
  5067.             elseif position == "forward" then
  5068.                 T:go("U1F1")
  5069.             end
  5070.            
  5071.             T:up(1)
  5072.             T:place("slab", -1, "down", true)               -- place slab on top T:place(blockType, damageNo, direction, leaveExisting)
  5073.             -- go up 2 blocks, forward 5, right, forward 5, right
  5074.             T:go("U2F5 R1F5 R1")                            -- Level 2: now placed 1 below ceiling inside wall, top right corner of new dungeon
  5075.             lib.wallSection(blaze)                          -- fix layers 1, 2, 3 including ceiling margin turtle at Level 2           
  5076.             T:go("F1R2 C1L1 F1R2 C1R1", false, 0, false)    -- exit wall, repair behind, still Level 2
  5077.             lib.ceiling(blaze)                              -- fix ceiling, end opposite corner to start
  5078.             T:go("R2D3")                                    -- clear the inner walls inside original dungeon
  5079.             lib.clearWall(9)                                -- clear the 9 x 9 area around the spawner
  5080.             T:go("F1R1F1L1")
  5081.             lib.clearWall(7)                                -- clear the 7 x 7 area around the spawner
  5082.             T:go("F1R1F1L1")
  5083.             lib.clearWall(5)                                -- clear the 5 x 5 area around the spawner. Also needed for cave spiders
  5084.             T:go("R2F1R1F1R1")
  5085.             T:go("F7R1 F8L1F1R2", false, 0, false)          -- return from ceiling, enter wall below previous section: Level 5
  5086.             lib.wallSection()                               -- deal with areas from spawner level up (4,5,6). walls only   
  5087.             T:go("F1R2 C1L1 F1R2 C1R1 D3", false, 0, false) -- exit wall, repair behind, embed 1 below original floor: Level 8
  5088.             clearRectangle({width = 9, length = 9, up = true, down = true}) -- clear levels 7,8,9
  5089.             T:go("L1F1 L1F1L2", false, 0, false)            -- go inside wall sectio, ready for next wall section
  5090.             lib.wallSection()                               -- deal with walls on levels 7,8,9
  5091.             T:go("F1R2 C1L1 F1R2 C1R1 D3", false, 0, false) -- exit wall, repair behind, embed 4 below original floor: Level 11
  5092.             --print("Check: about to clear 3 floors 3 below spawner") read()
  5093.             clearRectangle({width = 9, length = 9, up = true, down = true}) -- clear levels 10,11,12
  5094.            
  5095.             if blaze then
  5096.                 T:go("L1F1 L1F1L2", false, 0, false)            -- ready for next wall section
  5097.                 lib.wallSection()                               -- wall on layers 10,11,12
  5098.                 T:go("F1R2 C1L1 F1R2 C1R1 D3", false, 0, false) -- exit wall, repair behind, embed 1 below original floor: Level 8
  5099.                 clearRectangle({width = 9, length = 9, up = true, down = true}) -- clear levels 13, 14, 15
  5100.             end
  5101.            
  5102.             T:go("L1F1L1F1L2", false, 0, false) -- ready for next wall section
  5103.             --print("Check: level 11, 5 north, 5 east")
  5104.             --read()
  5105.             lib.wallSection()   -- wall on layers 10,11,12 or 12,13,14 if blaze
  5106.             T:go("F1R1 F1R2 C1R1 U1", false, 0, false) -- exit wall, repair behind: Level 10, facing entry point top right corner
  5107.             T:down(1)
  5108.             if blaze then
  5109.                 lib.placeFloor(9, 9, brick)             -- place brick floor on level 14
  5110.                 T:go("L1F4 R1F2 U4")                    -- ends facing out to lower chamber ?below staircase
  5111.                 -- now needs to build killzone
  5112.             else
  5113.                 lib.placeFloor(9, 9, "stone")           -- ends facing wall on entrance side
  5114.                 T:go("U1R2")
  5115.                 lib.placeFloor(9, 9, "stone")           -- ends facing wall on opposite side
  5116.                 -- return to mid-point front
  5117.                 T:go("R2F8 R1F4 L1F2")                  -- exit at bottom of dungeon
  5118.                 T:go("x1U1 x1U1 x1U1 x1D3 R2")          -- rise to chest, then return ready for next stage 
  5119.                 -- ends with turtle facing spawner, in front of exit hole              
  5120.             end
  5121.         else
  5122.             return
  5123.             {
  5124.                 "Spawner not found. Place me on top,",
  5125.                 "immediately below, or facing it.",
  5126.                 "\nEnter to quit"
  5127.             }
  5128.         end
  5129.     end
  5130.     if continue then
  5131.         T:clear()
  5132.         local text =
  5133. [[~yellow~Items required to continue:
  5134.  
  5135. ~lightGray~slabs            81
  5136. ~orange~nether bricks    88
  5137. ~yellow~lava buckets     4
  5138. ~brown~chest / barrel   1
  5139. ~gray~hopper           1      
  5140.  
  5141. ~red~WARNING ~yellow~Inventory ejects items if you
  5142. continue! ~orange~(Choose at next menu.)
  5143.  
  5144. ~white~Next -> Enter]]
  5145.         menu.colourText(nil, text, true)
  5146.         read()
  5147.         pp.itemColours = {colors.red, colors.lime}
  5148.         local choice = menu.new("Choose your option", {"Continue with build", "Re-start later"}, pp, "Type number + Enter") -- 1 = continue, 2= quit
  5149.         if choice == 1 then
  5150.             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
  5151.             if choice == 1 then
  5152.                 T:emptyInventory("down")
  5153.             else
  5154.                 T:emptyInventory("up")
  5155.             end
  5156.         else
  5157.             return {"Blaze spawner partial build halted"}
  5158.         end
  5159.        
  5160.         --clsTurtle.getItemSlot(self, item, useDamage): return slotData.lastSlot, slotData.leastModifier, total, slotData
  5161.         T:checkInventoryForItem({brick}, {88})
  5162.         T:checkInventoryForItem({"slab"}, {81})
  5163.         T:checkInventoryForItem({"lava"}, {4})
  5164.         T:checkInventoryForItem({"sign"}, {1})
  5165.         T:checkInventoryForItem({"hopper"}, {1})
  5166.         T:checkInventoryForItem({"chest", "barrel"}, {1, 1})
  5167.         print("Stand clear. Starting in 2 secs")
  5168.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  5169.         -- place upper floor and slabs under it
  5170.         T:go("R2D4F2 L1F4 R1U4")   
  5171.         lib.placeFloor(9, 9, brick)             -- place brick floor on level 10
  5172.         T:down(2)
  5173.         T:place(brick, 0, "up")
  5174.         T:go("D1R2")
  5175.         lib.ceiling(true)                       -- true uses slabs
  5176.        
  5177.         -- place lava
  5178.         T:go("L1F4 L1F4 U4")                    -- through hole in ceiling
  5179.         T:go("F4 L1F4 R2")
  5180.         for i = 1, 4 do
  5181.             T:place("lava", 0 , "down")
  5182.             T:go("F8 R1")
  5183.         end
  5184.         T:go("F4 R1F4 D2 F1 R2")
  5185.         -- place sign and repair above
  5186.         T:dig("forward")
  5187.         T:place("sign", 0, true, "")
  5188.         T:down(1)
  5189.         T:place(brick, 0 , "up")
  5190.         T:forward(1)
  5191.         -- place blocks under exit hole
  5192.         for i = 1, 4 do
  5193.             T:place(brick, 0 , "forward")
  5194.             T:turnRight(1)
  5195.         end
  5196.         -- place chest and hopper
  5197.        
  5198.         T:go("D2x2")
  5199.         if not T:place("chest", 0, "down") then
  5200.             T:place("barrel", 0, "down")
  5201.         end
  5202.         T:up(1)
  5203.         T:place("hopper", 0, "down")
  5204.         utils.goBack(1)
  5205.         T:place("slab", 0, "forward")
  5206.         T:go("R2F5U3")-- return to starting point and create entrance
  5207.     end
  5208.     return {}
  5209. end
  5210.  
  5211. local function floodMobFarm(R) -- 63
  5212.     --[[Part 2 / 3 Mob Spawner Farm turtle on floor, pointing towards water source wall, single hole]]
  5213.     local lib ={}
  5214.    
  5215.     function lib.setPosition(addWater)
  5216.         local width = 0
  5217.         while turtle.forward() do end                   -- move forward until hit wall
  5218.         T:go("U1L1")
  5219.         while turtle.forward() do end                   -- move forward until hit left wall
  5220.         if addWater then
  5221.             T:placeWater("down")                        -- place water down
  5222.         end
  5223.         T:turnLeft(2)                                   -- turn round
  5224.         while turtle.forward() do
  5225.             width = width + 1
  5226.         end         -- go forward 7
  5227.         if addWater then                                -- back 1
  5228.             T:placeWater("down")                        -- place water                 
  5229.         end
  5230.         T:go("L2F".. math.floor(width / 2) .."L1")      -- turn round, go forward 3 (centre of wall), turn left
  5231.     end
  5232.  
  5233.     function lib.digFloor()
  5234.         T:go("x2F1 x2")                                 -- first block, move forward
  5235.        
  5236.         T:turnLeft(1)                                   -- left turn, go back into right side, facing left
  5237.         utils.goBack(1)
  5238.         T:go("x2 F1x2 F1x2 R1F1")                       -- go right to left dig 3 blocks, forward on left side
  5239.        
  5240.         T:turnRight(1)                                  -- right turn, go back into left side, facing right
  5241.         utils.goBack(1)
  5242.         T:go("x2 F1x2 F1x2 F1x2 F1x2 L1F1")             -- go left to right dig 5 blocks, forward on right side
  5243.        
  5244.         T:turnLeft(1)                                   -- left turn, go back into right side, facing left
  5245.         utils.goBack(1)
  5246.         T:go("x2 F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 R1F1")   -- go right to left dig 7 blocks, forward on left side
  5247.        
  5248.         T:turnRight(1)                                  -- right turn, go back into left side, facing right
  5249.         utils.goBack(1)
  5250.         T:go("x2 F1x2 F1x2 F1x2 F1x2 F1x2  F1x2  F1x2  F1x2 L1")    -- go left to right dig 5 blocks, face forward on right side
  5251.     end
  5252.    
  5253.     lib.setPosition(false)                  -- move to back of cube and verify position
  5254.     if R.subChoice == 1 then
  5255.         T:forward(3)                        -- forward 4 (centre of chamber)
  5256.     else
  5257.         T:forward(2)                        -- forward 3
  5258.     end
  5259.     T:down(1)
  5260.     lib.digFloor()
  5261.     if R.subChoice == 1 then       
  5262.         T:go("D1F1 L1F8")
  5263.         utils.goBack(4)
  5264.         T:go("L1U1")
  5265.         lib.setPosition(true)               -- place water sources
  5266.         T:go("F8D2")
  5267.         -- go down 2, check floor, up 1, place fence
  5268.         T:go("D2C2U1", false, 0, true)
  5269.         T:place("fence", -1, "down", false)
  5270.         T:go("F1D1C2U1", false, 0, true)
  5271.         T:place("fence", -1, "down", false)
  5272.         T:go("F1U1R2", false, 0, true)
  5273.         T:go("F1R1U1")
  5274.         T:place("sign", -1, "down", false)
  5275.         T:go("U1C0D1")
  5276.         T:place("slab", -1, "up", false)
  5277.         T:go("R2F1R2")
  5278.         T:place("sign", -1, "forward", false)
  5279.         T:go("R1F1R2C1R1F1D1L1") --sitting on soul sand/dirt facing spawner
  5280.         if not T:place("minecraft:soul_sand", -1, "down", false) then
  5281.             T:place("minecraft:dirt", -1, "down", false)
  5282.         end
  5283.     else
  5284.         T:go("D1F1 L1F8")
  5285.         T:go("R1F1 R1F8")
  5286.         utils.goBack(4)
  5287.         T:go("R1U1")
  5288.         lib.setPosition(true)       -- place water sources
  5289.         T:go("F8D2 F1C2C0 F1")      -- exit leaving single hole in wall, facing away from spawner
  5290.     end
  5291.    
  5292.     return {}
  5293. end
  5294.  
  5295. local function createMobBubbleLift(R) -- 64
  5296.     -- Part 3 / 3 Mob Spawner Farm
  5297.     -- R.subChoice = 1 or 2 (left/right)
  5298.     local lib = {}
  5299.    
  5300.     function lib.initialise()
  5301.         local blockType = T:getBlockType("down")
  5302.         if blockType ~= "minecraft:soul_sand" then
  5303.             T:dig("down")
  5304.             if not T:place("minecraft:soul_sand", -1, "down", false) then
  5305.                 return {"Unable to find or place soulsand."}
  5306.             end
  5307.         end
  5308.         -- check facing sign, rotate if not
  5309.         blockType = T:getBlockType("forward")
  5310.         local turns = 0
  5311.         while blockType:find("sign") == nil do
  5312.             T:turnRight(1)
  5313.             turns = turns + 1
  5314.             if turns == 4 then
  5315.                 return {"Unable to find sign."}
  5316.             end
  5317.             blockType = T:getBlockType("forward")
  5318.         end
  5319.         return {""}
  5320.     end
  5321.    
  5322.     function lib.createWaterSource(oTurn)
  5323.         T:go(oTurn.."1")            -- turn to opposite side of dropzone
  5324.         T:go("F1x0D1")
  5325.         for i = 1, 3 do
  5326.             T:go("C2 L1C1 R2C1 L1")
  5327.             if i < 3 then
  5328.                 T:go("F1x0")
  5329.             end
  5330.         end
  5331.         T:go("R2F1")                -- face column move to middle
  5332.         T:placeWater("forward")
  5333.         T:go("R2")                  -- face away
  5334.         T:placeWater("forward")
  5335.         T:go("U1x0 R2F1x0 F1x0"..oTurn.."1")    -- face column, return to soul sand, face spawner
  5336.     end
  5337.    
  5338.     function lib.goToWater(moves)
  5339.         T:down(moves)
  5340.         T:getWater("down")
  5341.         sleep(0.1)
  5342.         T:getWater("down")
  5343.     end
  5344.    
  5345.     function lib.placeCollector(turn, oTurn)
  5346.         local hopperSlot = T:getItemSlot("hopper")
  5347.         local chestSlot = T:getItemSlot("chest")
  5348.         if hopperSlot > 0 and chestSlot > 0 then
  5349.             T:dig("down")
  5350.             T:place("chest", 0, "down")
  5351.             T:go(turn.."1F1"..oTurn.."1")
  5352.             T:dig("down")
  5353.             T:place("chest", 0, "down")
  5354.             T:go(turn.."1")
  5355.             utils.goBack(3)
  5356.             T:go("D1x1")
  5357.             T:place("hopper", 0, "forward")
  5358.             T:go("U1C2F2"..oTurn.."1")
  5359.         end
  5360.     end
  5361.    
  5362.     function lib.up()
  5363.         local moves = 0
  5364.         while turtle.detect() do
  5365.             turtle.up()
  5366.             moves = moves + 1
  5367.         end
  5368.  
  5369.         return moves
  5370.     end
  5371.    
  5372.     function lib.createChamber()
  5373.         local D = {}
  5374.         D.width  = 4
  5375.         D.length = 7
  5376.         D.height = 4
  5377.         D.ceiling = true
  5378.         D.floor = true
  5379.         D.vDirection = "D"
  5380.         D.hDirection = "RL"
  5381.         D.goHome = true
  5382.  
  5383.         utils.createWalledSpace(D)
  5384.     end
  5385.    
  5386.     function lib.mobTransporter()
  5387.         for i = 1, 9 do -- fill in a solid block bar from bubble column for 8 spaces
  5388.             T:go("F1C0C2 R1C1 R1C1 R1C1 R1C1")
  5389.         end
  5390.         T:go("D1C2C1 R1C1 R2C1 L1 C0x0") -- move down column
  5391.         for i = 1, 8 do -- go under solid block bar
  5392.             T:go("F1C2 R1C1 L2C1 R1x0")
  5393.         end
  5394.     end
  5395.    
  5396.     local turn = "R"
  5397.     local oTurn = "L"
  5398.     if R.subChoice == 1 then
  5399.         turn = "L"
  5400.         oTurn = "R"
  5401.     end
  5402.    
  5403.     local data = lib.initialise()           -- check if in the right position
  5404.     if data[1] ~= "" then
  5405.         return data                         -- eg {"Unable to find sign."}
  5406.     end
  5407.     lib.createWaterSource(oTurn)            -- everything in place, build a water source, facing spawner
  5408.     for i = 1, 3 do     -- fill in back and one side, go up
  5409.         T:go(turn.."1C1"..turn.."1C1"..turn.."1x1"..turn.."1U1", false, 0, true)
  5410.     end
  5411.     -- dungeon wall, above mob exit, facing spawner
  5412.     local colHeight = 19
  5413.     for i = 1, colHeight do     -- tunnel up, filling 3 sides
  5414.         T:go(turn.."1C1"..turn.."1C1"..turn.."1x1"..turn.."1C1 U1", false, 0, true)
  5415.     end
  5416.     -- facing spawner 20 blocks up. move either left/right 8 blocks, repairing ceiling and sides
  5417.     T:go("C0"..turn.."2C1"..turn.."1F1 C0C1"..turn.."1C1"..turn.."2C1"..oTurn.."1", false, 0, true) -- fill top of column
  5418.    
  5419.     lib.mobTransporter()
  5420.     T:go("x2x0 F1x2x0 F1x2x0 R2") -- over water source
  5421.     -- now create bubble column
  5422.     T:down(colHeight + 2)
  5423.     local moves = 0
  5424.     repeat
  5425.         lib.goToWater(moves)    -- get water
  5426.         moves = lib.up()
  5427.         T:go("F1")
  5428.         T:placeWater("forward")
  5429.         T:go("U1C2")
  5430.         T:placeWater("forward")
  5431.         utils.goBack(1)
  5432.         T:go("C1")
  5433.         moves = moves + 1
  5434.     until moves >= colHeight + 1
  5435.     lib.goToWater(moves)    -- get water for last time
  5436.     lib.up()                -- finishes above lower part of the transport bar
  5437.     T:go("F2R2C1D1")        -- seal off bubble column
  5438.     utils.goBack(1)
  5439.     T:placeWater("forward") -- place source on top of bubble column
  5440.     utils.goBack(7)         -- over down shaft
  5441.     T:down(1)               -- start shaft, facing bubble column
  5442.     for i = 1, 17 do
  5443.         -- tunnel down, filling all 4 sides
  5444.         T:go("R1C1 R1C1 R1C1 R1C1 D1", false, 0, true)
  5445.     end
  5446.     lib.createChamber()
  5447.     T:go("x0")
  5448.     T:go(oTurn.."1C1".. turn.."1D1C2"..oTurn.."1C1"..turn.."1F1".. oTurn.."1F1"..oTurn.."1") -- facing end wall ready to place slabs
  5449.     for i = 1, 6 do
  5450.         T:place("slab", 0, "down")
  5451.         if i == 6 then
  5452.             T:go(oTurn.."1")
  5453.         end
  5454.         utils.goBack(1)
  5455.         T:go("C1")
  5456.     end
  5457.    
  5458.     T:go("D2F2"..turn.."1F5")
  5459.     T:placeWater("forward")
  5460.     T:go(turn.."1F1"..oTurn.."1") -- facing down mob channel floor
  5461.     for i = 1, 5 do
  5462.         T:go("C1")
  5463.         utils.goBack(1)
  5464.     end
  5465.     T:go("C1"..turn.."1F1"..turn.."1F1")
  5466.     for i = 1, 7 do
  5467.         T:go("C2x0")
  5468.         if i < 7 then
  5469.             T:forward(1)
  5470.         end
  5471.     end
  5472.     T:go("U3R2")
  5473.     for i = 1, 7 do
  5474.         T:go("F1x2")
  5475.     end
  5476.     T:go("D3")
  5477.    
  5478.     lib.placeCollector(turn, oTurn) -- if hopper / chests present
  5479.    
  5480.     return {}
  5481. end
  5482.  
  5483. local function createPlatform(R) -- 56
  5484.     -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5485.     local forward = true
  5486.     for w = 1, R.width do
  5487.         for l = 1, R.length do
  5488.             T:go("x2C2", false, 0, false, R.useBlockType)
  5489.             if R.up then
  5490.                 T:dig("up")
  5491.             end
  5492.             if l < R.length then
  5493.                 T:forward(1)
  5494.             end
  5495.         end
  5496.         if w < R.width then
  5497.             if forward then
  5498.                 if R.up then
  5499.                     T:go("R1F1 x0R1")
  5500.                 else
  5501.                     T:go("R1F1 R1")
  5502.                 end
  5503.             else
  5504.                 if R.up then
  5505.                     T:go("L1F1 x0L1")
  5506.                 else
  5507.                     T:go("L1F1 L1")
  5508.                 end
  5509.             end
  5510.         end
  5511.         forward = not forward
  5512.     end
  5513.     return {}
  5514. end
  5515.  
  5516. local function createPortal(R) -- 42
  5517.     --[[
  5518.     R.length = length of portal NOT width default 4
  5519.     R.height = height of portal default 5
  5520.     R.width = thickness of portal default 1
  5521.     R.data = "bury" to embed bottom into ground
  5522.     R.subChoice 1 = facing portal, 2 = aligned
  5523.     ]]
  5524.     local lib = {}
  5525.    
  5526.     function lib.buildBase()
  5527.         --T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5528.         T:go("C2", false, 0, false, R.useBlockType)
  5529.         T:forward(1)
  5530.         for i = 1, R.length - 2 do -- R.length = 4: place when i=1,2
  5531.             T:place("minecraft:obsidian", 0, "down", false)
  5532.             T:forward(1)
  5533.         end
  5534.         T:go("C2", false, 0, false, R.useBlockType)
  5535.     end
  5536.    
  5537.     function lib.buildLayer()
  5538.         T:place("minecraft:obsidian", 0, "down", false)
  5539.         for i = 1, R.length - 1 do -- R.length = 4: forward when i=1,2,3
  5540.             T:forward(1)
  5541.         end
  5542.         T:place("minecraft:obsidian", 0, "down", false)
  5543.     end
  5544.    
  5545.     if R.data ~= "bury" then
  5546.         T:up(1)
  5547.     end
  5548.     if R.subChoice == 1 then
  5549.         T:go("F1R1")
  5550.     end
  5551.     local out = true
  5552.     for width = 1, R.width do
  5553.         lib.buildBase()
  5554.         for i = 1, R.height - 2 do
  5555.             T:go("R2U1")
  5556.             out = not out
  5557.             lib.buildLayer()
  5558.         end
  5559.         T:go("R2U1")
  5560.         out = not out
  5561.         lib.buildBase()
  5562.         if out then
  5563.             T:go("R2F"..R.length - 1)
  5564.         end
  5565.         if width < R.width then
  5566.             T:go("R1F1D"..R.height.."R1")
  5567.             out = true
  5568.         else
  5569.             T:go("L1F"..R.width.."D"..R.height - 1 .."R2")
  5570.             if R.data ~= "bury" then
  5571.                 T:down(1)
  5572.             end
  5573.         end
  5574.     end
  5575.    
  5576.     return {}
  5577. end
  5578.  
  5579. local function createPortalPlatform() -- 48
  5580.     --[[ Used in End World to use a trapdoor to push player through portal ]]
  5581.     local lib ={}
  5582.    
  5583.     function lib.findPortal()
  5584.         local found = false
  5585.         local onSide = false
  5586.         for i = 1, 64 do
  5587.             if not turtle.up() then -- hit block above
  5588.                 found = true
  5589.                 break
  5590.             end
  5591.         end
  5592.         if found then
  5593.             -- are we under the centre block, or one of the sides?
  5594.             if turtle.detect() then -- under a side
  5595.                 onSide = true
  5596.             else    -- nothing in front, probably under centre, or facing wrong direction so check
  5597.                 for i = 1, 4 do
  5598.                     turtle.turnRight()
  5599.                     if turtle.detect() then
  5600.                         onSide = true
  5601.                         break
  5602.                     end
  5603.                 end
  5604.             end
  5605.             if onSide then-- move to centre
  5606.                 T:go("D1F1")
  5607.             end
  5608.         end
  5609.         local height = 3 -- allows for 2 bedrock + starting space
  5610.         while turtle.down() do
  5611.             height = height + 1
  5612.         end
  5613.         return found, height
  5614.     end
  5615.    
  5616.     function lib.addFloor(length)
  5617.         for i = 1, length do
  5618.             if i < length then
  5619.                 T:go("C2F1", false, 0, true)
  5620.             else
  5621.                 T:go("C2", false, 0, true)
  5622.             end
  5623.         end
  5624.     end
  5625.    
  5626.     function lib.buildLadder(height)
  5627.         for i = 1, height do
  5628.             --T:go("F1C1 R1C1 L2C1 L1F1L2", false, 0, true)
  5629.             T:go("F1C1 R1C1 L2C1 R1", false, 0, true)
  5630.             utils.goBack(1)
  5631.             if i > 3 then
  5632.                 T:go("C2")
  5633.             end
  5634.             T:place("minecraft:ladder", 0, "forward", true)
  5635.             T:up(1)
  5636.         end
  5637.     end
  5638.    
  5639.     local found, height = lib.findPortal()
  5640.     if found then   -- position under centre of beacon
  5641.         -- build ladder up and create platform
  5642.         T:go("L1F1L1F2L2")
  5643.         T:checkInventoryForItem({"minecraft:ladder"},{height})
  5644.         T:checkInventoryForItem({"stone"},{height * 4 + 18})
  5645.         T:checkInventoryForItem({"trapdoor"},{1})
  5646.         lib.buildLadder(height) -- ends facing ladder, 1 block above
  5647.        
  5648.         T:go("R1")
  5649.         utils.goBack(1)
  5650.         T:go("C2F1 C2F1 C2F1 C2")
  5651.         T:go("R1F1R1")
  5652.         T:go("C2F1 C2F1 C2F1 C2")
  5653.         utils.goBack(2)
  5654.         T:go("R1F1")            -- facing portal entrance
  5655.         T:place("trapdoor", -1, "up", false)
  5656.     else
  5657.         return {"Portal not found. Move me under","the centre if possible.", "wait for purple beacon."}
  5658.     end
  5659.     return {}
  5660. end
  5661.  
  5662. local function createRailway(R) -- 93
  5663.     -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5664.     --[[Build steps up or down ready for railtrack]]
  5665.     if R.down then
  5666.         if R.height == 0 then
  5667.             local blockType = ""
  5668.             while blockType == "" do
  5669.                 T:go("F1D1", false, 0, true)
  5670.                 blockType = T:getBlockType("down")
  5671.                 if blockType == "" then
  5672.                     T:go("C2", false, 0, true)
  5673.                 end
  5674.             end
  5675.         else
  5676.             for i = 1, R.height - 1 do
  5677.                 T:go("U1x0 D1x1 F1x0x1 D1x1 C2", false, 0, false)
  5678.             end
  5679.         end
  5680.     elseif R.up then
  5681.         for i = 1, R.height do
  5682.             T:go("C1U2 x0D1F1", false, 0, false) --put stone in front, up 2 excavate 1, down 1, forward 1
  5683.         end
  5684.     end
  5685.     return {}
  5686. end
  5687.  
  5688. local function createRectanglePath(R) -- 710, 83 direct commands
  5689.     -- allow user to control length / width of each path
  5690.     -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5691.     --local pp = utils.getPrettyPrint()
  5692.     local lib = {}
  5693.    
  5694.     function lib.forward(R)
  5695.         if R.subChoice == 1 then
  5696.             for i = 1, R.length do
  5697.                 T:go("F1x0C2", false, 0, true)
  5698.             end
  5699.         else
  5700.             for i = 1, R.length do
  5701.                 T:go("F1U1C0D1C2", false, 0, true)
  5702.             end
  5703.         end
  5704.     end
  5705.    
  5706.     function lib.back(R)
  5707.         for i = 1, R.length do
  5708.             turtle.back()
  5709.         end
  5710.     end
  5711.    
  5712.     function lib.left(R)
  5713.         T:turnLeft(R.length)
  5714.     end
  5715.    
  5716.     function lib.right(R)
  5717.         T:turnRight(R.length)
  5718.     end
  5719.    
  5720.     function lib.up(R)
  5721.         if R.subChoice == 1 then
  5722.             T:go("U2R2 x1R2 D1C2", false, 0, true)
  5723.         else
  5724.             T:go("U2R2 x1R2C0 D1C2", false, 0, true)
  5725.         end
  5726.     end
  5727.    
  5728.     function lib.down()
  5729.         T:go("D1C2", false, 0, true)
  5730.     end
  5731.    
  5732.     if R.data == "menu" then
  5733.         -- mimics direct commands using f.lua, r.lua etc with space between commands and number
  5734.         local width = 0
  5735.         local length = 0
  5736.         local choices =
  5737.         {
  5738.             "Forward 1 block",
  5739.             "Forward # blocks",
  5740.             "Back 1 block",
  5741.             "Back # blocks",
  5742.             "Turn Right",
  5743.             "Turn Left",
  5744.             "Up 1 block",
  5745.             "Down 1 block",
  5746.             "Quit"
  5747.         }
  5748.         local choice, modifier
  5749.         pp.itemColours = {colors.lime, colors.lime, colors.green, colors.green, colors.orange, colors.orange, colors.cyan, colors.cyan, colors.gray}
  5750.         while choice ~= 9 do
  5751.             choice, modifier = menu.menu("Choose next step", choices, pp, "Type number + Enter ")
  5752.             if choice == 1 then
  5753.                 R.length = 1
  5754.                 lib.forward(R)
  5755.             elseif choice == 2 then
  5756.                 -- getInteger(prompt, minValue, maxValue, row, fg, bg, default)
  5757.                 R.length = menu.getInteger("Move forward how many blocks?", 1, 250, nil, colors.lime)
  5758.                 lib.forward(R)
  5759.             elseif choice == 3 then
  5760.                 R.length = 1
  5761.                 lib.back(R)
  5762.             elseif choice == 4 then
  5763.                 R.length = menu.getInteger("Move back how many blocks?", 1, 250, nil, colors.green)
  5764.                 lib.back(R)
  5765.             elseif choice == 5 then
  5766.                 R.length = 1
  5767.                 lib.right(R)
  5768.             elseif choice == 6 then
  5769.                 R.length = 1
  5770.                 lib.left(R)
  5771.             elseif choice == 7 then
  5772.                 lib.up(R)
  5773.             elseif choice == 8 then
  5774.                 lib.down()
  5775.             end
  5776.         end
  5777.     else
  5778.         local instructions =
  5779. [[~lightGray~Commands:
  5780.  
  5781. direction + ~blue~number ~yellow~eg ~white~f2 ~yellow~= forward ~blue~2
  5782. ~lightGray~direction without number = ~blue~1
  5783.  
  5784. ~yellow~f = forward  ~orange~b = backward
  5785. ~lime~l = left     ~red~r = right
  5786. ~lightGray~u = up       ~cyan~d = down
  5787.  
  5788. ~red~q = quit
  5789.  
  5790. ]] -- Direct control
  5791.         local cmd = ""
  5792.         while cmd ~= "q" do
  5793.             local line = menu.clear()
  5794.             line = menu.colourText(line, instructions)
  5795.             -- menu.getString(prompt, withTitle, minValue, maxValue, row, fg, bg, default)
  5796.             input = menu.getString("command ", false, 1, 5, line, colors.yellow, colors.black):lower()
  5797.             -- remove spaces
  5798.             input = input:gsub( " ", "")
  5799.             cmd = input:sub(1,1)
  5800.             R.length = 1
  5801.             if #input > 1 then
  5802.                 R.length = tonumber(input:sub(2))
  5803.             end
  5804.             if cmd == "q" then
  5805.                 return{"User has quit application"}
  5806.             end
  5807.             if cmd == "f" then
  5808.                 lib.forward(R)
  5809.             elseif cmd == "b" then
  5810.                 lib.back(R)
  5811.             elseif cmd == "l" then
  5812.                 lib.left(R)
  5813.             elseif cmd == "r" then
  5814.                 lib.right(R)
  5815.             elseif cmd == "u" then
  5816.                 lib.up(R)
  5817.             elseif cmd == "d" then
  5818.                 lib.down()
  5819.             end
  5820.         end
  5821.     end
  5822.     return {}
  5823. end
  5824.  
  5825. local function createRetainingWall(R) -- 34, 82
  5826.     -- facing direction wall will take
  5827.     -- will need to rotate 180 to build
  5828.     -- if R.height > 0 then build to specified depth
  5829.     local lib = {}
  5830.        
  5831.     function lib.checkFloor()
  5832.         local newDepth = 0
  5833.         place = utils.clearVegetation("down") -- in case col in front is deeper
  5834.         while place do -- loop will be entered at least once
  5835.             T:down(1)
  5836.             newDepth = newDepth + 1
  5837.             place = utils.clearVegetation("down")
  5838.         end
  5839.         if newDepth > 0 then
  5840.             for j = 1, newDepth do  -- go up until column base is met
  5841.                 T:go("U1C2")
  5842.             end
  5843.         end
  5844.     end
  5845.    
  5846.     function lib.patchMissingBlock()
  5847.         if turtle.back() then
  5848.             T:go("C1")
  5849.         else
  5850.             T:go("B1C1")
  5851.         end
  5852.     end
  5853.    
  5854.     function lib.placeSingle(height)
  5855.         local y = 0
  5856.         if height > 0 then
  5857.             T:go("D"..height)
  5858.             y = height
  5859.         else
  5860.             local place = utils.clearVegetation("down")
  5861.             while place do -- loop will be entered at least once
  5862.                 place = utils.clearVegetation("down")
  5863.                 if place then
  5864.                     T:down(1)
  5865.                     y = y + 1
  5866.                 end
  5867.             end
  5868.         end
  5869.         -- return to surface, placing below
  5870.         for i = 1, y do
  5871.             T:go("U1C2", false, 0, true)
  5872.         end
  5873.     end
  5874.    
  5875.     function lib.placeDouble(height)
  5876.         --T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5877.         local y = 0
  5878.         if not turtle.back() then
  5879.             T:go("B1")
  5880.         end
  5881.         if height > 0 then
  5882.             for i = 1, height do
  5883.                 T:go("C1D1", false, 0, true)
  5884.             end
  5885.             T:go("C1", false, 0, true)
  5886.             y = height
  5887.         else
  5888.             local place = utils.clearVegetation("down")
  5889.             -- build back column
  5890.             while place do -- loop will be entered at least once
  5891.                 place = utils.clearVegetation("down")
  5892.                 if place then
  5893.                     T:go("C1D1", false, 0, true)
  5894.                     y = y + 1
  5895.                 end
  5896.             end
  5897.             -- reached bottom. floor in front could drop down
  5898.             T:go("F1") -- move under first column
  5899.             lib.checkFloor()
  5900.             turtle.back() -- back at starting point
  5901.             T:go("C1", false, 0, true)
  5902.         end
  5903.         -- return to surface, placing below
  5904.         for i = 1, y do
  5905.             T:go("U1C2", false, 0, true)
  5906.         end
  5907.     end
  5908.        
  5909.     function lib.placeTriple(height)
  5910.         --T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  5911.         local y = 0
  5912.         if turtle.back() then
  5913.             T:go("C1")
  5914.         else
  5915.             T:go("B1C1")
  5916.         end
  5917.         if height > 0 then
  5918.             for i = 1, height do
  5919.                 T:go("C1D1", false, 0, true)
  5920.             end
  5921.             for i = 1, height do
  5922.                 T:go("C1D1", false, 0, true)
  5923.             end
  5924.             T:go("C1R2C1", false, 0, true) --fill last block, then turn 180 to build opposite side
  5925.             y = height
  5926.         else
  5927.             local place = utils.clearVegetation("down")
  5928.             -- build back column
  5929.             while place do -- loop will be entered at least once
  5930.                 place = utils.clearVegetation("down")
  5931.                 if place then
  5932.                     T:go("C1D1", false, 0, true)
  5933.                     y = y + 1
  5934.                 end
  5935.             end
  5936.             -- reached bottom. floor in front could drop down
  5937.             T:go("F1") -- move under first column
  5938.             lib.checkFloor()
  5939.             T:go("B1C1R2F1", false, 0, true)
  5940.             lib.checkFloor()
  5941.             T:go("B1C1")
  5942.             -- return to surface , placing below and to front
  5943.         end
  5944.         for i = 1, y do
  5945.             T:go("C1U1C2", false, 0, true)
  5946.         end
  5947.         T:go("F1R2C1", false, 0, true)
  5948.         -- facing back again inside edge of col 3
  5949.         return y -- depth of this run
  5950.     end
  5951.    
  5952.     local topInPlace = false -- topInPlace = true already a path across the water eg monument rectangle
  5953.     if R.data == "withPath" then
  5954.         topInPlace = true
  5955.     end
  5956.     local place = false
  5957.     local inWater = false
  5958.     local onWater = false
  5959.     if not topInPlace then
  5960.         if R.length > 1 then
  5961.             inWater, onWater = utils.getWaterStatus() -- returns whether above water, or immersed
  5962.         end
  5963.     end
  5964.    
  5965.     local maxDepth = 5 --initial estimated value
  5966.     -- start at surface, move back 1 block
  5967.     -- each iteration completes 3 columns
  5968.     local numBlocks = T:getSolidBlockCount()
  5969.     print("Solid blocks in inventory: "..numBlocks)
  5970.    
  5971.     if R.length == 1 then -- single column down to water bed
  5972.         lib.placeSingle(R.height)
  5973.     elseif R.length == 2 then--down then up: 2 cols
  5974.         inWater, onWater = utils.startWaterFunction(onWater, inWater, 2, true) -- move into water
  5975.         T:go("R2") -- move to face player
  5976.         lib.placeDouble(R.height)
  5977.         if not inWater then
  5978.             T:go("U1C2", false, 0, true)
  5979.         end
  5980.     else -- R.length 3 or more
  5981.         if topInPlace then
  5982.             T:down(1) -- break through top
  5983.         else
  5984.             inWater, onWater = utils.startWaterFunction(onWater, inWater, 2, true) -- move into water
  5985.         end
  5986.         T:go("R2") -- move to face player
  5987.         -- now at water surface
  5988.         local remain = R.length
  5989.         while remain >= 3 do
  5990.             numBlocks = T:getSolidBlockCount()
  5991.             print("Inventory blocks: "..numBlocks.." depth: "..maxDepth)
  5992.             if numBlocks < maxDepth * 3 then
  5993.                 --ask player for more
  5994.                 T:checkInventoryForItem({"stone"}, {maxDepth * remain}, false)
  5995.             end
  5996.             local y = lib.placeTriple(R.height) -- moves back, places col in front, centre and behind. R.height = 0 for auto depth
  5997.             if y > maxDepth then
  5998.                 maxDepth = y
  5999.             end
  6000.             remain = remain - 3
  6001.             if remain > 1 then
  6002.                 lib.patchMissingBlock()
  6003.             end
  6004.         end
  6005.         if remain == 1 then -- 1 more column
  6006.             lib.patchMissingBlock()
  6007.             lib.placeSingle(R.height)
  6008.         elseif remain == 2 then -- 2 cols
  6009.             lib.placeDouble(R.height)
  6010.         end
  6011.         T:go("U1C2") -- above surface
  6012.     end
  6013.     return {}
  6014. end
  6015.  
  6016. local function createSafeDrop(R) -- 14
  6017.     -- dig down height blocks, checking for blocks on all sides
  6018.     local drop = 0
  6019.     local isBedrock = false
  6020.     T:down(2)
  6021.     drop = 2
  6022.     for i = 1, R.height - 1 do
  6023.         for j = 1, 4 do
  6024.             -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  6025.             T:go("C1R1", false, 0, true)
  6026.         end
  6027.         if T:down(1) then
  6028.              drop = drop + 1
  6029.         else
  6030.             isBedrock = true
  6031.             break
  6032.         end
  6033.         if T:isWaterOrLava("up") ~= "" then
  6034.             T:go("C0x0", false, 0, false) -- delete water/ lava block
  6035.         end
  6036.     end
  6037.     if not isBedrock then -- not sitting on bedrock, so break foot level exit block
  6038.         T:go("U1R2x1")
  6039.     end
  6040.     T:placeWater("down")
  6041.     if isBedrock then
  6042.         T:go("U1x1 U1x1")
  6043.     else
  6044.         T:go("U1x1")
  6045.     end
  6046.     T:up(drop - 2)
  6047.    
  6048.     return {"Safe drop completed "..drop .. " blocks"}
  6049. end
  6050.  
  6051. local function createSlopingWater(R) -- 34, 89
  6052.     --[[
  6053.     creates a sloping water area above existing lake/river/ocean
  6054.     R.width is usually 7 with an existing wall on 8th row
  6055.     R.length  is user choice, limited to bucket/slab quantities
  6056.     Places slabs into existing surface, places row of sources
  6057.     Removes slabs
  6058.     ]]
  6059.     local lib = {}
  6060.    
  6061.     function lib.fillBuckets()
  6062.         local emptyBuckets = utils.getEmptyBucketCount()
  6063.         for i = 1, emptyBuckets do
  6064.             if utils.fillBucket("down") then
  6065.                 print("Bucket filled down")
  6066.                 sleep(0.3)
  6067.             else
  6068.                 print("Unable to fill bucket ".. i .." / "..emptyBuckets)
  6069.             end
  6070.         end
  6071.         return utils.getWaterBucketCount()
  6072.     end
  6073.    
  6074.     local outbound = true
  6075.     local inWater, onWater = utils.getWaterStatus()
  6076.     inWater, onWater = utils.startWaterFunction(onWater, inWater, 2 ,false) -- move above water, max descent 2
  6077.     local waterBuckets = lib.fillBuckets()
  6078.     for w = 1, R.width do
  6079.         for l = 1, R.length do
  6080.             T:place("slab", -1, "down", false)
  6081.             if l < R.length then
  6082.                 T:forward(1)
  6083.             end
  6084.         end
  6085.         if w < R.width then
  6086.             if outbound then
  6087.                 T:go("R1F1R1")
  6088.             else
  6089.                 T:go("L1F1L1")
  6090.             end
  6091.             outbound = not outbound
  6092.         end
  6093.     end
  6094.     if outbound then
  6095.         T:go("L1F"..R.width - 1 .."L1")
  6096.     else
  6097.         T:go("R1F"..R.width - 1 .."R1")
  6098.     end
  6099.     T:placeWater("up")  -- place in corner
  6100.     local move = true
  6101.     while move do
  6102.         move = turtle.forward()
  6103.         move = turtle.forward() -- false if at end of run
  6104.         T:placeWater("up")  -- alternate positions + end of run
  6105.     end
  6106.     T:go("R2D1")
  6107.     T:sortInventory() -- get all buckets into 1 slot
  6108.     for w = 1, R.width do
  6109.         for l = 1, R.length do
  6110.             if l < R.length then
  6111.                 T:forward(1)
  6112.             end
  6113.         end
  6114.         if w < R.width then
  6115.             if outbound then
  6116.                 T:go("R1F1R1")
  6117.             else
  6118.                 T:go("L1F1L1")
  6119.             end
  6120.             outbound = not outbound
  6121.         end
  6122.     end
  6123.     if outbound then
  6124.         T:go("L1F"..R.width - 1 .."L1")
  6125.     else
  6126.         T:go("R1F"..R.width - 1 .."R1")
  6127.     end
  6128.     T:go("U2")
  6129.    
  6130.     return {}
  6131. end
  6132.  
  6133. local function createSquidFarmBase(R) -- 34
  6134.     -- dig down to y=45. assume starting at water level (64)
  6135.     local depth = 0
  6136.     local message =
  6137. [[Place the turtle under the grid
  6138. left corner above current pit
  6139. opening.
  6140. It will descend to the base and
  6141. continue to level y=45.
  6142.  
  6143. Enter to continue...
  6144. ]]
  6145.     read()
  6146.     while turtle.down()do
  6147.         depth = depth + 1
  6148.     end
  6149.     T:down(1)
  6150.     R.height = 21 - depth
  6151.     R.width = 15
  6152.     R.length = 15
  6153.     R.silent = true
  6154.     R.data = "down"
  6155.     clearSolid(R)
  6156.     T:up(depth + 4)
  6157.     return {}
  6158. end
  6159.  
  6160. local function createSandWall(R) -- 81
  6161.     local success = true
  6162.     --move above water
  6163.     local maxMove = 2
  6164.     while turtle.detectDown() and maxMove > 0 do
  6165.         T:forward(1)
  6166.         maxMove = maxMove - 1
  6167.     end
  6168.     if R.length > 0 then
  6169.         for i = 1, R.length - 1 do
  6170.             success = utils.dropSand()
  6171.             T:forward(1, false)
  6172.         end
  6173.         success = utils.dropSand()
  6174.     else
  6175.         while not turtle.detectDown() do -- over water
  6176.             while not turtle.detectDown() do -- nested to allow forward movement
  6177.                 success = utils.dropSand() -- drops sand and checks supplies
  6178.             end
  6179.             if success then
  6180.                 T:forward(1, false)
  6181.             else -- out of sand
  6182.                 break
  6183.             end
  6184.         end
  6185.     end
  6186.     return {}
  6187. end
  6188.  
  6189. local function createSinkingPlatform(R) -- 58
  6190.     local lib = {}
  6191.    
  6192.     function lib.stage1a(R)                         -- build side wall left side
  6193.         for l = 1, R.length do                      --            | |*| |
  6194.             T:go("L1C1 R1C2", false, 0, false)      -- |*|>| | to |*|>| | place left wall
  6195.             if l == 1 then                          -- first iteration
  6196.                 T:go("U1C2 D1 F1C2", false, 0, false)-- |*|>| | to |*|*|>| up/down block to delete source at corner
  6197.             elseif l < R.length then                -- mid run
  6198.                 T:go("F1C2", false, 0, false)       -- |*|>| | to |*|*|>| move forward
  6199.             else                                    -- end of run
  6200.                 T:go("C1U1 C2D1", false, 0, false)  -- |*|>| | to |*|>|*| place end wall
  6201.             end
  6202.         end
  6203.     end
  6204.    
  6205.     function lib.stage1b(R)                         -- same as stage1a on right side
  6206.         for l = 1, R.length do
  6207.             T:go("R1C1 L1C2", false, 0, false)
  6208.             if l == 1 then
  6209.                 T:go("U1C2 D1 F1C2", false, 0, false)
  6210.             elseif l < R.length then
  6211.                 T:go("F1C2", false, 0, false)
  6212.             else
  6213.                 T:go("C1U1 C2D1", false, 0, false)
  6214.             end
  6215.         end
  6216.     end
  6217.    
  6218.     function lib.stage2(forward)
  6219.         if forward then
  6220.             T:go("C1R1 F1L1 C1R2", false, 0, false)
  6221.         else
  6222.             T:go("C1L1 F1R1 C1L2", false, 0, false)
  6223.         end
  6224.     end
  6225.        
  6226.     local forward = true
  6227.     local goingRight = true
  6228.     local blockType = T:getBlockType("down")
  6229.     if blockType:find("water") ~= nil or blockType:find("lava") ~= nil then
  6230.         T:up(1)
  6231.     end
  6232.     for h = 1, R.height do                      -- repeatedly create a platform, move down and repeat
  6233.         T:down(1)                               -- move down into existing platform
  6234.         if goingRight then                      -- first side
  6235.             if forward then                     -- complete left side
  6236.                 T:go("R2C1 L2", false, 0, false) -- | |>| | to |*|<| | to |*|>| |
  6237.                 lib.stage1a(R)                  -- build left wall
  6238.                 T:go("R1F1 L1C1 R2C2", false, 0, false)         -- turn ready for next side
  6239.             else
  6240.                 T:go("L2C1 R2", false, 0, false) -- block 1, 1
  6241.                 lib.stage1b(R)                  -- turn ready for next side
  6242.                 T:go("L1F1 R1C1 L2C2", false, 0, false)
  6243.             end
  6244.         else                                    -- on right side so different approach
  6245.             if forward then
  6246.                 T:go("L2C1 R2", false, 0, false) -- | |<| | to | |>|* | to | |<|*|
  6247.                 lib.stage1b(R)                 
  6248.                 T:go("C1L1 F1R1 C1L2 C2", false, 0, false)      -- turn ready for next side
  6249.             else                                -- complete left side
  6250.                 T:go("R2C1 L2", false, 0, false) -- block 1, 1
  6251.                 lib.stage1a(R)                  -- turn ready for next side
  6252.                 T:go("C1R1 F1L1 C1R2 C2", false, 0, false)
  6253.             end
  6254.         end
  6255.         forward = not forward                   -- continue strips across until at far edge
  6256.         for w = 1, R.width - 2 do
  6257.             for l = 1, R.length do
  6258.                 if l < R.length then
  6259.                     T:go("C2F1", false, 0, false)
  6260.                 else
  6261.                     T:go("C2", false, 0, false)
  6262.                 end
  6263.             end
  6264.             if goingRight then
  6265.                 lib.stage2(forward)
  6266.             else
  6267.                 lib.stage2(not forward)
  6268.             end
  6269.             forward = not forward
  6270.         end                                     -- far side
  6271.         if goingRight then
  6272.             if forward then
  6273.                 lib.stage1b(R)
  6274.             else
  6275.                 lib.stage1a(R)
  6276.             end
  6277.         else
  6278.             if forward then
  6279.                 lib.stage1a(R)
  6280.             else
  6281.                 lib.stage1b(R)
  6282.             end
  6283.         end
  6284.         goingRight = not goingRight
  6285.         T:turnRight(2)
  6286.         forward = not forward
  6287.     end
  6288.     return {}
  6289. end
  6290.  
  6291. local function createStaircase(R) -- 13
  6292.     -- R# L# F# B# U# D# +0 -0 = Right, Left, Forward, Back, Up, Down, up while detect and return, down while not detect
  6293.     -- dig:           x0,x1,x2 (up/fwd/down)
  6294.     -- suck:          s0,s1,s2
  6295.     -- place chest:   H0,H1,H2
  6296.     -- place sapling: S0,S1,S2
  6297.     -- place Torch:   T0,T1,T2
  6298.     -- place Hopper:  P0,P1,P2
  6299.     -- mine floor:    m# = mine # blocks above and below, checking for valuable items below, and filling space with cobble or dirt
  6300.     -- mine ceiling:  M# = mine # blocks, checking for valuable items above, and filling space with cobble or dirt
  6301.     -- mine ceiling:  N# same as M but not mining block below unless valuable
  6302.     -- 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
  6303.    
  6304.     -- 3| |B| |
  6305.     --   - - -
  6306.     -- 2|A| |C|
  6307.     --   - - -
  6308.     -- 1|^|D| |
  6309.     --   - - -
  6310.     --   1 2 3
  6311.     local lib = {}
  6312.    
  6313.     function lib.checkFluids()
  6314.         local isFluid = false
  6315.         -- check if water or lava present
  6316.         for i = 1, 4 do
  6317.             blockType = T:isWaterOrLava("forward")
  6318.             if blockType:find("lava") ~= nil or blockType:find("water") ~= nil then
  6319.                 isFluid = true
  6320.             end
  6321.         end
  6322.         return isFluid
  6323.     end
  6324.    
  6325.     function lib.createStaircaseSection(onGround, levels, level)
  6326.         -- start 1,1,1, n
  6327.         -- stage A
  6328.         local isFluid = lib.checkFluids()
  6329.         local blockType = ""
  6330.         local data = T:getStock("stairs")
  6331.         if data.total == 0 then
  6332.             T:craft('stairs', 4)
  6333.         end
  6334.         if onGround and isFluid then
  6335.             -- add right side and block entrance
  6336.             T:go("R1C1R1C1R2")
  6337.         end
  6338.         if isFluid then
  6339.             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
  6340.         else
  6341.             T:go("F1x1 R1C1 L1C2B1 ^1C2", false, 0, true)
  6342.         end
  6343.         if not onGround then
  6344.             -- stage A1
  6345.             T:go("L2C1L2", false, 0, true) -- start 1,1,1,n fix corner on level 1 end: 1,1,1,n
  6346.         end
  6347.         -- stage B
  6348.         T:go("U1L1", false, 0, true) -- end  1,1,1,w layer 2
  6349.         level = level + 1
  6350.         isFluid = lib.checkFluids()
  6351.         if isFluid then
  6352.             T:go("C1", false, 0, true) -- end  1,1,1,w layer 2
  6353.         end
  6354.         if not onGround then
  6355.             if isFluid then
  6356.                 T:go("L1C1R1", false, 0, true) -- end  1,1,1,w layer 2
  6357.             end
  6358.         end
  6359.         -- stage C1
  6360.         if isFluid then
  6361.             T:go("R1C1F1C1x1 L1C1 R2C1 L1B1", false, 0, true)
  6362.         else
  6363.             T:go("R1F1 R1C1 L1B1", false, 0, true)
  6364.         end
  6365.         --level = level + 1
  6366.         --if level == levels then
  6367.             --return false, level
  6368.         --end
  6369.         -- stage C2
  6370.         T:go("U1")
  6371.         level = level + 1
  6372.         --if level == levels then
  6373.             --return true, level
  6374.         --end
  6375.         isFluid = lib.checkFluids()
  6376.         if isFluid then
  6377.             T:go("L1C1L1 C1L2 C1F1L1 C1R2 C1L1 B1C2 D1", false, 0, true) -- end 1,1,2,n
  6378.         else
  6379.             T:go("F1R1 C1L1 B1D1", false, 0, true) -- end 1,1,2,n
  6380.         end
  6381.         level = level - 1 -- went down in branch above
  6382.         --if level == levels then
  6383.             --return false, level
  6384.         --end
  6385.         -- stage D
  6386.         isFluid = lib.checkFluids()
  6387.         if isFluid then
  6388.             T:go("C1F1C1F1C1x1L1 C1R1 C1R1", false, 0, true) -- 3,1,2,e
  6389.         else
  6390.             T:go("F2 C1R1", false, 0, true) -- 3,1,2,e
  6391.         end
  6392.        
  6393.         return false, level
  6394.     end
  6395.  
  6396.     --local height = currentLevel -- eg 64 at top or 5 at bedrock
  6397.     local data = T:getStock("stairs")
  6398.     --{rt.total, rt.mostSlot, rt.leastSlot, rt.mostCount, rt.leastCount}
  6399.     local numStairs = data.total
  6400.     local levels = math.abs(R.depth - R.height) --height of stairs
  6401.     local numStairsNeeded = levels
  6402.     numStairsNeeded = numStairsNeeded - numStairs
  6403.     if numStairsNeeded > 40 then
  6404.         print('crafting '..numStairsNeeded..' : '..numStairs.. ' in stock')
  6405.         if T:craft('stairs', 40) then   -- max 40 so repeat
  6406.             data = T:getStock("stairs")
  6407.             if data.total == 0 then
  6408.                 data = T:getStock("stairs")
  6409.             end
  6410.             numStairs = data.total
  6411.             numStairsNeeded = numStairsNeeded - numStairs
  6412.         else
  6413.             return {"Unable to craft stairs"}
  6414.         end
  6415.     end
  6416.     if numStairsNeeded > 0 then
  6417.         T:craft('stairs', numStairsNeeded)
  6418.     end
  6419.     local level = 0
  6420.     if R.down then -- go down towards bedrock
  6421.         local atBedrock = false
  6422.         for i = 1, levels do
  6423.             level = level - 1
  6424.             if not T:down() then
  6425.                 atBedrock = true
  6426.                 break
  6427.             end
  6428.         end
  6429.         if atBedrock then -- hit bedrock so get to level 5 / -59
  6430.             level = T:findBedrockTop(level)
  6431.             T:go("R1F1R1", false, 0, true)
  6432.         end
  6433.     end
  6434.     local onGround = true
  6435.     level = 0
  6436.     while level < levels do
  6437.         onGround, level = lib.createStaircaseSection(onGround, levels, level)
  6438.     end
  6439.     if not turtle.detectDown() then
  6440.         T:go("C2")
  6441.     end
  6442.    
  6443.     return{"Staircase completed"}
  6444. end
  6445.  
  6446. local function createStripMine(R)
  6447.     --[[
  6448.     R.length should be a multiple of 16
  6449.     mine a corridoor repairing floor and ceiling
  6450.     check sides, remove valuable items
  6451.     plug if lava present
  6452.     Every 16 blocks dig a side passage 1 block deep 2 blocks long
  6453.     ]]
  6454.     local lib = {}
  6455.    
  6456.     function lib.seal(R)   
  6457.         if T:isValuable("forward") then -- valuable block in front. If debris then refuse already dumped
  6458.             T:dig("forward")
  6459.         end
  6460.         local blockType = T:getBlockType("forward")
  6461.         if blockType:find("lava") ~= nil then
  6462.             --T:place("stone", 0, "forward", false) -- place does not allow for specific blocktype
  6463.             T:go("C1", false, 0, false, R.useBlockType)
  6464.             return true
  6465.         end
  6466.        
  6467.         return false
  6468.     end
  6469.    
  6470.     function lib.checkSeal(R)
  6471.         local retValue = false
  6472.         T:turnRight(1)
  6473.         if lib.seal(R) then
  6474.             retValue = true
  6475.         end
  6476.         T:turnLeft(2)
  6477.         if lib.seal(R) then
  6478.             retValue = true
  6479.         end
  6480.         T:turnRight(1)
  6481.         return retValue
  6482.     end
  6483.        
  6484.     function lib.alcove(R)
  6485.         -- right side, starting at ceiling
  6486.         T:go("R1F1 C0", false, 0, false, R.useBlockType)-- stone ceiling, facing alcove wall (upper)
  6487.         lib.seal(R)                                     -- seal alcove wall (upper)
  6488.         T:go("D1C2", false, 0, false, "cobble")         -- cobble floor, facing alcove wall (lower)
  6489.         lib.seal(R)                                     -- seal alcove wall (lower)    
  6490.         T:go("L2 F1")                                   -- down 1, turn round, return to corridoor.
  6491.         -- left side   
  6492.         T:go("F1 C2", false, 0, false, "cobble")        -- cobble floor, facing alcove wall (lower)
  6493.         lib.seal(R)                                     -- seal alcove wall (lower)
  6494.         T:go("U1 C0", false, 0, false, R.useBlockType)  -- stone ceiling, still facing alcove wall
  6495.         lib.seal(R)                                     -- seal alcove wall (upper)                    
  6496.         T:go("L2F1L1")                                  -- return to corridoor at ceiling position
  6497.         lib.placeTorch(R)                              
  6498.     end
  6499.    
  6500.     function lib.placeTorch(R)
  6501.         if R.torchInterval > 0 then                     -- torches onboard
  6502.             if T:getItemSlot("minecraft:torch") > 0 then
  6503.                 T:place("minecraft:torch", -1, "down")
  6504.             end
  6505.         end
  6506.     end
  6507.    
  6508.     local seal = false
  6509.     if T:getItemSlot("minecraft:torch") == 0 then
  6510.         R.torchInterval = 0 -- set to default 16 above
  6511.     end
  6512.     for steps = 1, R.length do
  6513.         -- go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  6514.         T:go("C2U1C0", false, 0, true, R.useBlockType)      -- check and repair floor / ceiling
  6515.         if steps % 16 == 0 or steps % 16 == 1 then
  6516.             lib.alcove(R) -- enter and exit at ceiling position
  6517.         else
  6518.             seal = lib.checkSeal(R)
  6519.         end
  6520.         T:go("F1D1", false, 0, true)
  6521.         seal = lib.checkSeal(R)
  6522.     end
  6523.     if seal then -- water or lava found while tunnelling
  6524.         T:go("U1C0", false, 0, true, R.useBlockType)
  6525.         lib.checkSeal(R)
  6526.         T:go("C1", false, 0, true, R.useBlockType)
  6527.         T:down(1)
  6528.     end
  6529.     return {}
  6530. end
  6531.  
  6532. local function createTreefarm(R) -- 22
  6533.     local lib = {}
  6534.     --go(path, useTorch, torchInterval, leaveExisting, preferredBlock)
  6535.     function lib.buildWallSection(length, placePolished, useBlockType)
  6536.         for i = 1, length do
  6537.             if placePolished and i == length - 4 then
  6538.                 T:place("polished", 0, "down")
  6539.                 T:forward(1)
  6540.             else
  6541.                 if i < length then
  6542.                     T:go("C2F1", false, 0, false, useBlockType)
  6543.                 end
  6544.             end
  6545.         end
  6546.     end
  6547.    
  6548.     function lib.placeFloor(length, useBlockType)
  6549.         for i = 1, length do
  6550.             T:go("x0C2", false, 0, false, useBlockType)
  6551.             if i < length then
  6552.                 T:forward(1)
  6553.             end
  6554.         end
  6555.     end
  6556.    
  6557.     function lib.placeWater(length)
  6558.         T:placeWater("down")
  6559.         T:go("F"..length.."R1")
  6560.     end
  6561.    
  6562.     function lib.placeCorners(length, numBlocks, useBlockType)
  6563.         for i = 1, numBlocks do
  6564.             T:go("C2F1", false, 0, false, useBlockType)
  6565.         end
  6566.         -- now at 5th space
  6567.         T:forward(length - (numBlocks * 2))
  6568.         for i = 1, numBlocks do
  6569.             T:go("C2", false, 0, false, useBlockType)
  6570.             if i < numBlocks then
  6571.                 T:forward(1)
  6572.             end
  6573.         end
  6574.     end
  6575.    
  6576.     function lib.turn(outward)
  6577.         if outward then
  6578.             T:go("R1F1R1")
  6579.         else
  6580.             T:go("L1F1L1")
  6581.         end
  6582.         return not outward
  6583.     end
  6584.    
  6585.     local blockType
  6586.     local blockModifier
  6587.     -- R.data = "existing" if on existing tree farm
  6588.     -- R.up = true if clear area
  6589.     if R.up then
  6590.         clearArea(R)
  6591.     end
  6592.  
  6593.     if R.data == "existing" then
  6594.         T:go("R1F1 D1", false, 0, false) -- move 14 blocks, right, forward, down 1
  6595.         lib.buildWallSection(R.width - 1, false, R.useBlockType)
  6596.         T:turnLeft(1)
  6597.         lib.buildWallSection(R.length, false, R.useBlockType)
  6598.         T:turnLeft(1)
  6599.         lib.buildWallSection(R.width - 1, false, R.useBlockType)
  6600.         T:go("C2U1R2")
  6601.         lib.buildWallSection(R.width - 1, true, R.useBlockType)
  6602.         T:turnRight(1)
  6603.         lib.buildWallSection(R.length, true, R.useBlockType)
  6604.         T:turnRight(1)
  6605.         lib.buildWallSection(R.width, true, R.useBlockType)
  6606.         T:go("R1") -- on lower left corner facing forward
  6607.     else
  6608.         T:down(1)
  6609.         local placePolished = false
  6610.         for i = 1, 2 do
  6611.             lib.buildWallSection(R.length, placePolished, R.useBlockType)
  6612.             T:turnRight(1)
  6613.             lib.buildWallSection(R.width, placePolished, R.useBlockType)
  6614.             T:turnRight(1)
  6615.             lib.buildWallSection(R.length, placePolished, R.useBlockType)
  6616.             T:turnRight(1)
  6617.             lib.buildWallSection(R.width, placePolished, R.useBlockType)
  6618.             T:turnRight(1)
  6619.             placePolished = true
  6620.             if i == 1 then
  6621.                 T:up(1)
  6622.             end
  6623.         end -- on lower left corner facing forward
  6624.     end
  6625.     T:go("F1R1 F1L1 D2") -- over 13 x 13 internal area
  6626.     local outward = true
  6627.     for i = 1, R.width - 2 do
  6628.         lib.placeFloor(R.length - 2, R.useBlockType)
  6629.         if i < R.width - 2 then
  6630.             outward = lib.turn(outward)
  6631.         end
  6632.     end
  6633.     T:go("U1R2") -- over 13 x 13 internal area opposite corner
  6634.     -- now add corners
  6635.     lib.placeCorners(R.length - 2, 4, R.useBlockType)
  6636.     outward = lib.turn(outward)
  6637.     lib.placeCorners(R.length - 2, 3, R.useBlockType)
  6638.     outward = lib.turn(outward)
  6639.     lib.placeCorners(R.length - 2, 2, R.useBlockType)
  6640.     outward = lib.turn(outward)
  6641.     lib.placeCorners(R.length - 2, 1, R.useBlockType)
  6642.     if outward then
  6643.         T:go("R1F"..R.width - 9 .."R1")
  6644.     else
  6645.         T:go("L1F"..R.width - 9 .."L1")
  6646.     end
  6647.     outward = not outward
  6648.     lib.placeCorners(R.length - 2, 1, R.useBlockType)
  6649.     outward = lib.turn(outward)
  6650.     lib.placeCorners(R.length - 2, 2, R.useBlockType)
  6651.     outward = lib.turn(outward)
  6652.     lib.placeCorners(R.length - 2, 3, R.useBlockType)
  6653.     outward = lib.turn(outward)
  6654.     lib.placeCorners(R.length - 2, 4, R.useBlockType) -- should be back in starting corner facing front
  6655.    
  6656.     T:go("U1R1")
  6657.     lib.placeWater(R.length - 3) -- place water down then move forward, turn right
  6658.     lib.placeWater(R.width - 3)
  6659.     lib.placeWater(R.length - 3)
  6660.     lib.placeWater(R.width - 3)
  6661.     T:go("F".. math.floor((R.length - 2) / 2).."R1F".. math.floor((R.width - 2) / 2)) -- should be in centre
  6662.     T:go("D4C2 R1C1 R1C1 R1C1 R1F1 R2") -- facing back of hole ready to place water
  6663.     T:placeWater("forward")
  6664.     T:go("R2F7U4")
  6665.    
  6666.     return {"Tree farm ready for planting"}
  6667. end
  6668.  
  6669. local function createWallOrFence(R)
  6670.     local lib = {}
  6671.    
  6672.     function lib.placeBarrel(R)
  6673.         if R.data == "barrel" then
  6674.             utils.goBack(1)
  6675.             T:go("L1F1")
  6676.             T:place("barrel", 0, "down", false)
  6677.             utils.goBack(1)
  6678.             T:go("R1")
  6679.             T:forward(1)
  6680.         end
  6681.     end
  6682.    
  6683.     function lib.placeTorch(R)
  6684.         T:up(1)
  6685.         local up = 1
  6686.         local blockType = T:getBlockType("forward")
  6687.         while blockType:find(R.useBlockType) ~= nil and blockType ~= "" do -- prevent continuous upward travel
  6688.             T:up(1)
  6689.             up = up + 1
  6690.             blockType = T:getBlockType("forward")
  6691.         end
  6692.         T:place("torch", 0, "forward", true)
  6693.         T:down(up)
  6694.     end
  6695.    
  6696.     function lib.buildWall(R, length)
  6697.         -- T:place(blockType, damageNo, direction, leaveExisting, signText)
  6698.         local blockType = ""
  6699.         local blocks = 0
  6700.         lib.placeBarrel(R)
  6701.         while blocks < length do
  6702.             if turtle.back() then
  6703.                 T:place(R.useBlockType, 0, "forward", true)
  6704.                 if R.torchInterval > 0 then
  6705.                     if blocks == 0 or blocks % R.torchInterval == 0 then
  6706.                         lib.placeTorch(R)
  6707.                     end
  6708.                 end
  6709.                 blocks = blocks + 1 -- still facing start position
  6710.                 while turtle.down() do
  6711.                     T:place(R.useBlockType, 0, "up", true)
  6712.                 end
  6713.             else -- obstruction
  6714.                 T:turnRight(2) -- facing away from start
  6715.                 blockType = T:getBlockType("forward")
  6716.                 if blockType:find("torch") ~= nil then
  6717.                     T:go("F1R2")
  6718.                     T:place(R.useBlockType, 0, "forward")
  6719.                     blocks = blocks + 1 -- facing start
  6720.                 elseif blockType:find("log") ~= nil then
  6721.                     T:harvestTree()
  6722.                     T:turnRight(2)
  6723.                     T:place(R.useBlockType, 0, "forward")
  6724.                     blocks = blocks + 1 -- facing start
  6725.                 elseif T:isVegetation(blockType) then
  6726.                     T:go("F1R2")
  6727.                     T:place(R.useBlockType, 0, "forward")
  6728.                     blocks = blocks + 1 -- facing start
  6729.                 else -- cant go forward, go up instead
  6730.                     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
  6731.                         while turtle.detectUp() do -- will only run if block above
  6732.                             utils.goBack(1)
  6733.                             blocks = blocks - 1
  6734.                         end
  6735.                         turtle.up()
  6736.                         T:place(R.useBlockType, 0, "down", true)
  6737.                         blockType = T:getBlockType("forward")
  6738.                     end
  6739.                     T:turnRight(2) -- facing start
  6740.                 end
  6741.             end
  6742.         end
  6743.     end
  6744.    
  6745.     T:turnRight(2) --facing start position
  6746.     if R.width == 0 then -- single fence
  6747.         lib.buildWall(R, R.length)
  6748.     else   
  6749.         lib.buildWall(R, R.length - 1)
  6750.         T:go("R1") -- facing start so left turn = turnRight
  6751.         lib.buildWall(R, R.width - 1)
  6752.         T:go("R1")
  6753.         lib.buildWall(R, R.length - 1)
  6754.         T:go("R1")
  6755.         lib.buildWall(R, R.width - 2)
  6756.         T:go("U1")
  6757.         T:place(R.useBlockType, 0, "down", true)
  6758.     end
  6759.    
  6760.     return {"Wall or fence completed"}
  6761. end
  6762.  
  6763. local function createWaterCanal(R) -- 53
  6764.     --[[
  6765.     designed for 4 turtles, but can be done with 2 as well
  6766.     R.data = 1 (2 turtles) or 2 (4 turtles)
  6767.     R.height = 0 (in water/ on canal floor) or 1 (at ground level)
  6768.     R.side = "R" or "L"
  6769.     R.subChoice =
  6770.         1 = left side, ground level (on towpath)
  6771.         2 = left side above canal water (new canal only)
  6772.         3 = right side above canal water (new canal only)
  6773.         4 = right side, ground level (on towpath)
  6774.         5 = left side in canal water (if present)
  6775.         6 = right side in canal water (if present)
  6776.    
  6777.     if R.height = 0 then already at correct height on canal floor
  6778.         check block below, block to left and block above, move forward tunnelling
  6779.         if entering water then move up, onto canal wall and continue pathway
  6780.         if tunnelling then flood canal
  6781.     else R.height = 1 then above water and on path across
  6782.         move forward, checking for water below
  6783.         if water finishes, move into canal, drop down and continue tunnelling
  6784.     ]]
  6785.     local lib = {}
  6786.    
  6787.     function lib.newCanalSide(oTurn)
  6788.         T:go("C1 U1x1 U1x1 D2"..oTurn.."1", false, 0, false)
  6789.     end
  6790.    
  6791.     function lib.newCanalBase(R)
  6792.         local oTurn = "R"                               -- assume R.side = "L"
  6793.         if R.side == "R" then
  6794.             oTurn = "L"
  6795.         end
  6796.         if not turtle.detectDown() then                 -- air / water below: fill floor
  6797.             T:go(oTurn.."1D1")                          -- *|>| | | to *|V| | | turn towards canal centre, go down ready to repair neighbouring canal base
  6798.             if T:getBlockType("forward"):find("turtle") ~= nil then -- turtle in similar position
  6799.                 if R.side == "L" then                   -- only left side repairs, so wait 1 second
  6800.                     sleep(1)
  6801.                     T:go("C1")                          -- repair neighbouring canal base
  6802.                 end
  6803.             else
  6804.                 T:go("C1")                              -- repair neighbouring canal base
  6805.             end
  6806.             T:go(R.side.."1")                           -- *|V| | | to *|>| | | turn to face start
  6807.             T:up(1)                                     -- *|>| | | return to canal floor
  6808.         end
  6809.         T:go("C2", false, 0, false)
  6810.     end
  6811.    
  6812.     function lib.newCanal(R)
  6813.         --  no source in front as this function called                                              -- *|<| | |  facing end wall ready for new canal canal base level
  6814.         local oTurn = "R"                                   -- assume R.side = "L"
  6815.         if R.side == "R" then
  6816.             oTurn = "L"
  6817.         end
  6818.         lib.newCanalSide(oTurn)                             -- *|<| | | wall fixed. to -- *|^| | |
  6819.         lib.newCanalSide(oTurn)                             -- *|^| | | wall fixed. to -- *|>| | |
  6820.         lib.newCanalBase(R)                                 -- *|>| | | base fixed
  6821.         T:go("F1"..R.side.."1")                             -- *|>| | | to *| |>| | to *| |^| |
  6822.         lib.newCanalSide(oTurn)                             -- *| |^| | to *| |>| |
  6823.         lib.newCanalBase(R)                                 -- *| |>| | base fixed
  6824.         T:go("F1"..R.side.."1")                             -- *| |>| | to *| | |>| to *| | |^|
  6825.         lib.newCanalSide(oTurn)                             -- *| | |^| to *| | |>|
  6826.         lib.newCanalBase(R)                                 -- *| | |>| base fixed
  6827.         T:go(R.side.."2")                                   -- *| | |>| to *| | |<|facing existing / back wall
  6828.         T:forward(1)                                        -- *| |<| |
  6829.         T:placeWater("forward")                             -- *|W|<| | placed against start wall  
  6830.         T:go("L2")                                          -- *|W|>| |
  6831.         T:placeWater("forward")                             -- *|W|>|W| placed direction of travel
  6832.         T:go("R2")                                          -- *|W|<|W| rotate
  6833.         if deletesWater then
  6834.             T:up(1)
  6835.         else
  6836.             sleep(0.2)
  6837.         end
  6838.         utils.getWater()                                    -- *|W|<|W|
  6839.         T:go(oTurn.."2F1")                                  -- *|W|<|W|  to *|W|W|>|  ready to go  
  6840.     end
  6841.    
  6842.     function lib.towpathOnly(R)
  6843.         --[[single turtle on towpath only using 4 turtles. Starts at ground level]]
  6844.         for i = 1, R.length do
  6845.             if turtle.detectDown() then                     -- eg dirt, stone
  6846.                 T:dig("down")                               -- remove block below
  6847.             end
  6848.             local placeOnly = true
  6849.             if R.torchInterval > 0 then                     -- place torches
  6850.                 if i == 1 or i % R.torchInterval == 0 then  -- ready to place torch
  6851.                     T:go("C2U1")                            -- place solid block below, up 1
  6852.                     T:place("torch", 0, "down")             -- place torch, move forward
  6853.                     T:go("F1D1")                            -- move forward, down
  6854.                     placeOnly = false      
  6855.                 end
  6856.             end
  6857.             if placeOnly then
  6858.                 T:dig("up")                                 -- clear blocks above
  6859.                 if not T:place("stone", 0, "down") then     -- place stone below
  6860.                     break
  6861.                 end
  6862.                 if i < R.length then
  6863.                     T:forward(1)                            -- move forward
  6864.                 end                        
  6865.             end
  6866.         end
  6867.     end
  6868.    
  6869.     function lib.initialiseCanal(R)
  6870.         --[[ move turtle to correct position. return moves]]
  6871.         local moves = 1
  6872.         local oTurn = "R"
  6873.         if R.side == "R" then
  6874.             oTurn = "L"
  6875.         end
  6876.         local newCanal, isWater, isSource = false, false, false
  6877.         if R.data == 1 then -- use 2 turtles only
  6878.             if R.subChoice == 1 or R.subChoice == 4 then    -- left / right side on towpath- move into canal space
  6879.                 if deletesWater then
  6880.                     T:go(oTurn.."1F1")                      -- turn to face canal centre, go forward over water
  6881.                     isWater, isSource = T:isWater("down")
  6882.                     if isSource then                        -- canal already exists
  6883.                         T:go(oTurn.."1")                    -- stay above water, face existing canal
  6884.                     else                                    -- NOT above source
  6885.                         T:go("D1"..oTurn.."1")              -- go to canal floor, face existing
  6886.                         newCanal = true                     -- flag create 6 water source blocks
  6887.                     end
  6888.                 else                                        -- NOT deletesWater
  6889.                     T:go(oTurn.."1F1D1"..oTurn.."1")        -- move into canal, face back along any existing canal
  6890.                     isWater, isSource = T:isWater("forward")
  6891.                     if isSource then
  6892.                         T:go(R.side.."2")                   -- face forward for new canal
  6893.                     else
  6894.                         newCanal = true
  6895.                     end
  6896.                 end
  6897.             elseif R.subChoice == 2 or R.subChoice == 3 then-- left / right side above canal finishing pos if deletesWater
  6898.                 if deletesWater then
  6899.                     isWater, isSource = T:isWater("down")
  6900.                     if isSource then
  6901.                         T:go(R.side.."2")                   -- face towards existing canal
  6902.                     else
  6903.                         T:go("D1"..R.side.."2")             -- go down and face existing canal                      -- no water ahead
  6904.                         newCanal = true                     -- already in newCanal starting position
  6905.                     end
  6906.                 else                                        -- NOT deletesWater
  6907.                     T:go("D1"..R.side.."2")                 -- facing existing on canal floor
  6908.                     isWater, isSource = T:isWater("forward")
  6909.                     if isSource then                        -- water ahead
  6910.                         T:go(R.side.."2")                   -- face forward for new canal
  6911.                     else                                   
  6912.                         newCanal = true
  6913.                     end
  6914.                 end
  6915.             elseif R.subChoice == 5 or R.subChoice == 6 then -- left / right  side in canal base. Assume NOT deletesWater
  6916.                 T:go(R.side.."2")                           -- check if water behind   
  6917.                 isWater, isSource = T:isWater("forward")
  6918.                 if isSource then
  6919.                     T:go(oTurn.."2")    
  6920.                 else
  6921.                     newCanal = true
  6922.                 end
  6923.             end
  6924.         else    -- use 4 turtles
  6925.             if R.subChoice == 1 or R.subChoice == 4 then    -- left / right side on towpath stays in place for 4 part canal
  6926.            
  6927.             elseif R.subChoice == 2 or R.subChoice == 3 then-- left / right side above canal finishing pos if deletesWater
  6928.            
  6929.             elseif R.subChoice == 5 or R.subChoice == 6 then -- left / right  side in canal base. Assume NOT deletesWater
  6930.            
  6931.             end
  6932.         end
  6933.         if newCanal then                                -- no water ahead, facing start wall of new canal *|<| | |
  6934.             lib.newCanal(R)                             -- start new canal, finish facing new canal 6 block water sources
  6935.             moves = 2
  6936.         end
  6937.        
  6938.         return moves                                    -- facing forward ready for new canal *|>| | |
  6939.     end
  6940.    
  6941.     function lib.side(R, maxLength)
  6942.         -- Already in position facing new canal, 2 water buckets
  6943.         local torch = R.length - maxLength                  -- start torch count at 1-2 depending on lib.initialise()
  6944.         local sourceCount = 0                               -- allow for 1 iteration of placing source blocks when changing from solid to water
  6945.         local numBlocks = 0                                 -- distance travelled
  6946.         local _, isSource = nil, false                      -- initialise variables
  6947.         local oTurn = "R"                                   -- assume R.side == "L" -> oTurn = "R"
  6948.         if R.side == "R" then                               -- R.side = "R"
  6949.             oTurn = "L"                                     -- oTurn = "L"
  6950.         end
  6951.        
  6952.         while numBlocks < maxLength do                      -- loop from here. Facing forwards to extend canal
  6953.             torch = torch + 1                               -- increase torch spacing interval
  6954.             numBlocks = numBlocks + 1                       -- inrease block count
  6955.             if deletesWater then                            -- up to and including mc 1.12.2
  6956.                 T:forward(1)                                -- move forward to extend canal  | |>|
  6957.                 _, isSource = T:isWater("down")             -- check if source water below
  6958.                 if isSource then
  6959.                     sourceCount = sourceCount + 1           -- count source blocks
  6960.                 else                                       
  6961.                     T:down(1)                               -- down to canal floor
  6962.                     sourceCount = 0                         -- reset
  6963.                     T:go("C2", false, 0, false)             -- place block below
  6964.                     T:up(1)                                 -- up to water level
  6965.                 end                                         -- still facing away from canal
  6966.                 T:go(R.side.."1F1C2", false, 0, false)      -- go above towpath, place stone down, facing out
  6967.                 if turtle.detectUp() then                   -- ? block above
  6968.                     T:go(R.side.."2U1F1D1"..R.side.."2")    -- rotate to face canal, up 1 forward over canal, back down to water level, face towpath
  6969.                 else
  6970.                     utils.goBack(1)                         -- face towpath
  6971.                 end
  6972.                 -- facing towpath
  6973.                 if R.torchInterval > 0 then                 -- Are torches required?
  6974.                     if torch == R.torchInterval  or numBlocks == 0 then     -- check if ready to place
  6975.                         torch = 0                           -- reset interval counter
  6976.                         T:go("U1F1")
  6977.                         T:place("torch", -1, "down")        -- place torch
  6978.                         utils.goBack(1)
  6979.                         T:down(1)
  6980.                     end
  6981.                 end                                         -- facing towpath, above water
  6982.                 -- facing towpath
  6983.                 if isSource and scoreCount > 0 then
  6984.                     T:go(oTurn.."1x0")                      -- face new canal direction
  6985.                 else                                        -- not source below, or first time found, ensures continous canal
  6986.                     T:go(R.side.."1x0")                     -- face back to existing canal
  6987.                     T:placeWater("down")                    -- place water
  6988.                     T:forward(1)                            -- forward 1
  6989.                     T:placeWater("down")                    -- place water
  6990.                     utils.getWater()                            -- collects water from below
  6991.                     utils.goBack(1)                         -- back 1
  6992.                     T:go(oTurn.."1x0")                      -- face new canal
  6993.                 end
  6994.             else
  6995.                 T:forward(1)                                -- move forward to extend canal
  6996.                 _, isSource = T:isWater("forward")          -- check if source water ahead
  6997.                 if isSource then                            -- ? source ahead
  6998.                     sourceCount = sourceCount + 1
  6999.                 else
  7000.                     sourceCount = 0
  7001.                     if not turtle.detectDown() then         -- air / water below, but no source in front, so fill it
  7002.                         T:go(oTurn.."1D1")                  -- ready to repair neighbouring canal base
  7003.                         if T:getBlockType("forward"):find("turtle") ~= nil then -- turtle in similar position
  7004.                             if R.side == "L" then           -- only left side repairs, so wait 1 second
  7005.                                 sleep(1)
  7006.                                 T:go("C1")                  -- repair neighbouring canal base
  7007.                             end
  7008.                             T:go(R.side.."1")               -- face forward
  7009.                         else
  7010.                             T:go("C1"..R.side.."1")         -- repair neighbouring canal base if air
  7011.                         end
  7012.                         T:up(1)
  7013.                     end
  7014.                     T:go("C2", false, 0, false)             -- place block below if not already source
  7015.                 end
  7016.                 T:go(R.side.."1C1", false, 0, false)        -- face canal wall, replace with stone
  7017.                
  7018.                 local placeTorch = false
  7019.                 if R.torchInterval > 0 then                 -- Are torches required?
  7020.                     if torch == R.torchInterval  or numBlocks == 0 then     -- check if ready to place
  7021.                         torch = 0                           -- reset interval counter
  7022.                         placeTorch = true
  7023.                     end
  7024.                 end
  7025.                 if (isSource and placeTorch) or not isSource then
  7026.                     T:go("U1x1 U1x1")                       -- up 2 and excavate blocks above tow path
  7027.                     if placeTorch then                      -- torch required
  7028.                         T:forward(1)                        -- move over towpath
  7029.                         T:place("torch", -1, "down")        -- place torch
  7030.                         utils.goBack(1)                     -- move back
  7031.                     end
  7032.                     T:down(2)                               -- return to canal base
  7033.                 end
  7034.                 if isSource and sourceCount > 1 then        -- source ahead found at least once
  7035.                     T:go(oTurn.."1")                        -- face newcanal as no water refill required
  7036.                 else                                        -- not source in front, or first time found, ensures continous canal
  7037.                     T:go(oTurn.."1C1")                      -- *| | | |>| face along new canal and block entrance
  7038.                     utils.goBack(1)                         -- *| | |>| | back 1
  7039.                     T:placeWater("forward")                 -- *| | |>|W| place water
  7040.                     T:go(oTurn.."2")                        -- *| | |<|W| face existing canal
  7041.                     _, isSource = T:isWater("forward")      -- *| |?|<|W| check if source water ahead
  7042.                     if not isSource then
  7043.                         if not T:placeWater("forward") then -- place water again *| |W|<|W|
  7044.                             while not T:getWater("forward") do -- wait for other turtle
  7045.                                 print("Out of water buckets")
  7046.                                 sleep(1)
  7047.                             end
  7048.                             sleep(0.2)
  7049.                             T:getWater("forward")
  7050.                         end
  7051.                     end
  7052.                     utils.getWater()                            -- collects water *| |W|<|W|
  7053.                     T:go(R.side.."2F1")                         -- face along new canal *| |W|>|W| to *| |W|W|>|
  7054.                 end
  7055.             end
  7056.         end
  7057.     end
  7058.        
  7059.     function lib.waterOnly(R, maxLength)
  7060.         -- Already in position facing new canal, 2 water buckets
  7061.         local torch = R.length - maxLength                  -- start torch count at 1-2 depending on lib.initialise()
  7062.         local sourceCount = 0                               -- allow for 1 iteration of placing source blocks when changing from solid to water
  7063.         local numBlocks = 0                                 -- distance travelled
  7064.         local _, isSource = nil, false                      -- initialise variables
  7065.         local oTurn = "R"                                   -- assume R.side == "L" -> oTurn = "R"
  7066.         if R.side == "R" then                               -- R.side = "R"
  7067.             oTurn = "L"                                     -- oTurn = "L"
  7068.         end
  7069.        
  7070.         while numBlocks < maxLength do                      -- loop from here. Facing forwards to extend canal
  7071.             torch = torch + 1                               -- increase torch spacing interval
  7072.             numBlocks = numBlocks + 1                       -- inrease block count
  7073.             if deletesWater then                            -- up to and including mc 1.12.2
  7074.                 T:forward(1)                                -- move forward to extend canal  | |>|
  7075.                 _, isSource = T:isWater("down")             -- check if source water below
  7076.                 if isSource then
  7077.                     sourceCount = sourceCount + 1           -- count source blocks
  7078.                 else                                       
  7079.                     T:down(1)                               -- down to canal floor
  7080.                     sourceCount = 0                         -- reset
  7081.                     T:go("C2", false, 0, false)             -- place block below
  7082.                     T:up(1)                                 -- up to water level
  7083.                 end                                         -- still facing away from canal
  7084.                 if turtle.detectUp() then                   -- ? block above
  7085.                     T:go("U1x0")                            -- break block above
  7086.                 end
  7087.                 if not isSource or scoreCount == 0 then     -- not source below, or first time found, ensures continous canal
  7088.                     T:go(R.side.."2x0")                     -- face back to existing canal
  7089.                     T:placeWater("down")                    -- place water
  7090.                     T:forward(1)                            -- forward 1
  7091.                     T:placeWater("down")                    -- place water
  7092.                     utils.getWater()                        -- collects water from below
  7093.                     utils.goBack(1)                         -- back 1
  7094.                     T:go(R.side.."2")                       -- face new canal
  7095.                 end
  7096.             else
  7097.                 T:forward(1)                                -- move forward to extend canal
  7098.                 _, isSource = T:isWater("forward")          -- check if source water ahead
  7099.                 if isSource then                            -- ? source ahead
  7100.                     sourceCount = sourceCount + 1
  7101.                 else
  7102.                     sourceCount = 0
  7103.                     if not turtle.detectDown() then         -- air / water below, but no source in front, so fill it
  7104.                         T:go(oTurn.."1D1")                  -- ready to repair neighbouring canal base
  7105.                         if T:getBlockType("forward"):find("turtle") ~= nil then -- turtle in similar position
  7106.                             if R.side == "L" then           -- only left side repairs, so wait 1 second
  7107.                                 sleep(1)
  7108.                                 T:go("C1", false, 0, true)  -- repair neighbouring canal base
  7109.                             end
  7110.                             T:go(R.side.."1")               -- face forward
  7111.                         else
  7112.                             T:go("C1"..R.side.."1",false, 0, true)  -- repair neighbouring canal base if air
  7113.                         end
  7114.                         T:up(1)
  7115.                     end
  7116.                     T:go("C2", false, 0, false)             -- place block below if not already source
  7117.                 end
  7118.                 if not isSource then
  7119.                     T:go("U1x0D1")                          -- up 1 and excavate blocks above canal. return to canal base
  7120.                 end
  7121.                 T:go(R.side.."1C1"..oTurn.."1", false, 0, true) -- face canal wall, replace with stone if empty, face forward                                      
  7122.                 if not isSource and sourceCount == 0 then   -- not source in front, or first time found, ensures continous canal                   
  7123.                     T:go("C1", false, 0, true)              -- *| | | |>| face along new canal and block entrance
  7124.                     utils.goBack(1)                         -- *| | |>| | back 1
  7125.                     T:placeWater("forward")                 -- *| | |>|W| place water
  7126.                     T:go(oTurn.."2")                        -- *| | |<|W| face existing canal
  7127.                     _, isSource = T:isWater("forward")      -- *| |?|<|W| check if source water ahead
  7128.                     if not isSource then
  7129.                         if not T:placeWater("forward") then -- place water again *| |W|<|W|
  7130.                             while not T:getWater("forward") do -- wait for other turtle
  7131.                                 print("Out of water buckets")
  7132.                                 sleep(1)
  7133.                             end
  7134.                             sleep(0.2)
  7135.                             T:placeWater("forward")
  7136.                         end
  7137.                     end
  7138.                     utils.getWater()                            -- collects 2 water *| |W|<|W|
  7139.                     T:go(R.side.."2F1")                         -- face along new canal *| |W|>|W| to *| |W|W|>|
  7140.                 end
  7141.             end
  7142.         end
  7143.     end
  7144.        
  7145.     local maxLength = 512
  7146.     if R.length ~= 0 then
  7147.         maxLength = R.length
  7148.     end
  7149.     menu.clear()
  7150.     menu.colourWrite("Building canal "..R.side.." side", colors.yellow, nil, nil, false, true)
  7151.     local moves = lib.initialiseCanal(R) -- move to correct position and/or start new canal
  7152.     if R.data == 1 then -- 2 turtles
  7153.         lib.side(R, maxLength - moves) 
  7154.     else -- 4 turtles
  7155.         if R.subChoice == 1 or R.subChoice == 4 then -- towpath
  7156.             lib.towpathOnly(R)
  7157.             --lib.waterCanalTowpath(R, maxLength - moves)
  7158.         else -- main canal only
  7159.             lib.waterOnly(R, maxLength - moves)
  7160.         end
  7161.     end
  7162.    
  7163.     return {}
  7164. end
  7165.  
  7166. local function createMobGrinder(R)
  7167.     -- go down 5 and create a cavity 9 wide, 5 long, 8 high
  7168.     -- assume facing out from spawner cube at base of exit (6 blocks above ground
  7169.     -- R.subChoice = 1 or 2 (sticky or normal pistons)
  7170.    
  7171.     local lib = {}
  7172.    
  7173.     function lib.getInventory(R)
  7174.         T:clear()
  7175.         menu.colourPrint("All blocks to be ejected. Ready? Enter", colors.red)
  7176.         read()
  7177.         T:emptyInventory("up")
  7178.         T:checkInventoryForItem({"stone"}, {20}, true, "Match existing walls?")
  7179.         if R.subChoice == 1 then -- sticky pistons
  7180.             T:checkInventoryForItem({"computercraft:computer_normal"}, {1})
  7181.             T:checkInventoryForItem({"minecraft:sticky_piston"}, {2})
  7182.         else
  7183.             T:checkInventoryForItem({"computercraft:computer_normal"}, {2})
  7184.             T:checkInventoryForItem({"minecraft:piston"}, {4})
  7185.             T:checkInventoryForItem({"computercraft:cable"}, {6})
  7186.             T:checkInventoryForItem({"computercraft:wired_modem"}, {2})
  7187.         end
  7188.         T:checkInventoryForItem({"polished"}, {23}, true, "Any polished block")
  7189.         T:checkInventoryForItem({"wall"}, {2}, true, "Any wall block ? match")
  7190.         T:checkInventoryForItem({"slab"}, {7}, true, "Any stone slab. ? polished / match")
  7191.         T:checkInventoryForItem({"minecraft:glass"}, {2})
  7192.         T:checkInventoryForItem({"minecraft:stone_pressure_plate"}, {1})
  7193.         T:checkInventoryForItem({"minecraft:dispenser"}, {1})
  7194.         T:checkInventoryForItem({"hopper"}, {1})
  7195.         T:checkInventoryForItem({"chest"}, {2})
  7196.         T:checkInventoryForItem({"minecraft:redstone"}, {9})
  7197.         T:checkInventoryForItem({"lava"}, {1})
  7198.         R.useBlockType = T:getPolishedItem("")
  7199.         if R.useBlockType == "" then
  7200.             R.useBlockType = T:getMostItem("", true)
  7201.         end
  7202.     end
  7203.    
  7204.     function lib.placeRedstone()
  7205.         T:go("D2U2")                                -- in left corner facing right
  7206.         T:place("slab", 0, "down")                  -- place slab layer 1
  7207.         T:up(2)
  7208.         T:place("slab", 0, "down")                  -- place slab layer 2
  7209.         T:up(1)
  7210.         T:place("redstone", 0, "down")
  7211.         T:go("F1D4 C2L1C1 L1U1", false, 0, false)   -- facing ground level slab
  7212.         T:place("redstone", 0, "forward")           -- redstone on ground level slab
  7213.         T:up(1)
  7214.         T:place("slab", 0, "down")                  -- slab on layer 1
  7215.         T:up(2)
  7216.         T:place("slab", 0, "down")                  -- slab on layer 3
  7217.         T:up(1)
  7218.         T:place("redstone", 0, "down")              -- redstone on layer 3 slab
  7219.         utils.goBack(1)
  7220.         T:down(3)                                   -- facing layer 1 slab
  7221.         T:place("redstone", 0, "forward")           -- redstone on layer 1 slab
  7222.         T:go("D2C2", false, 0, false)               -- under end of chest position
  7223.         T:place("redstone", 0, "forward")           -- redstone on level 0 floor
  7224.         T:go("R1C1R1", false, 0, false)             -- face right, repair back wall
  7225.         T:go("F1C2 L1C1 R1", false, 0, false)       -- under chest start
  7226.         T:go("F1C2 L1C1 R1", false, 0, false)       -- under hopper
  7227.         T:go("F1C2 L1C1 R1", false, 0, false)       -- under right side wall block
  7228.         T:go("U1L2")                                -- ready for redstone
  7229.         for i = 1, 4 do
  7230.             T:place("redstone", 0, "down")          -- redstone under chest etc
  7231.             if i < 4 then
  7232.                 T:forward(1)
  7233.             end
  7234.         end
  7235.         -- finishes facing slab at ground level, redstone below
  7236.     end
  7237.    
  7238.     function lib.placeStorage()
  7239.         -- starts facing slab at ground level, redstone below
  7240.         T:go("L1F1L2")                              -- up and out ready for chest placement
  7241.         T:place("chest", 0, "forward")              -- end chest
  7242.         T:go("R1F1 L1F1 R1U2")                      -- at above start chest position facing right
  7243.         T:place("slab", 0, "down")                  -- slab above chest
  7244.         T:turnLeft(1)
  7245.         utils.goBack(1)                            
  7246.         T:down(2)                                   -- in front of start chest position
  7247.         T:place("chest", 0, "forward")              -- start chest
  7248.         T:go("R1F2L2")                              -- at pressure plate position facing left
  7249.         T:place("wall", 0, "forward")               -- place wall
  7250.         T:up(1)
  7251.         T:place("pressure", 0, "down")              -- place pressure plate
  7252.         T:go("R1F1 L1D1")                           -- at second wall position
  7253.         T:place("hopper", 0, "forward")             -- place hopper into chest
  7254.         utils.goBack(1)
  7255.         T:place("wall", 0, "forward")               -- place second wall
  7256.         -- finishes on level 1 (ground) facing right side wall block
  7257.     end
  7258.    
  7259.     function lib.placePistons(R)
  7260.         -- starts on level 1 (ground) facing right side wall block
  7261.         T:go("U1F2 R1")                                 -- go over wall block, facing back wall layer 2
  7262.         T:place(R.useBlockType, 0, "forward", false)    -- replace back wall with polished block layer 2
  7263.         T:up(1)                                         -- layer 3
  7264.         T:place(R.useBlockType, 0, "forward", false)    -- replace back wall with polished block layer 3
  7265.         T:turnRight(1)                                  -- face right side
  7266.         if R.subChoice == 1 then                        -- use sticky pistons x 2
  7267.             T:place(R.useBlockType, 0, "forward", false)-- polished block above second wall layer 3
  7268.             T:go("R2F1")                                -- ready to place lower piston (works ok as slab already in place behind it)
  7269.         else
  7270.             T:go("F2R2")                                -- move forward 2 and face left
  7271.             T:place("piston", 0, "forward")             -- lower replacer piston placed
  7272.             T:go("U1F2D1F1")                            -- go up and over piston forward 1 ready for other piston
  7273.         end
  7274.         T:place("piston", 0, "forward")                 -- lower piston placed
  7275.         utils.goBack(1)
  7276.         T:go("U1R1")                                    -- layer 4
  7277.         T:place(R.useBlockType, 0, "forward", false)    -- polished block back wall layer 4
  7278.         T:go("L1F2R2")                                  -- head left ready for dispenser
  7279.         T:place("dispenser", 0, "forward")              -- dispenser placed
  7280.         T:dropItem("lava", "forward")                   -- drop lava bucket into dispenser
  7281.         T:go("U1F2 D1")                                 -- up and over dispenser, facing right side
  7282.         T:place("slab", 0, "down")                      -- lower piston slab placed
  7283.         if R.subChoice == 1 then
  7284.             T:place(R.useBlockType, 0, "forward", false)-- polished block above second wall layer 4
  7285.             T:turnLeft(1)                               -- facing back wall
  7286.         else
  7287.             T:go("F1L1")                                -- at second computer position, facing back wall
  7288.             utils.goBack(1)                             -- ready to place computer
  7289.             T:place("computercraft:computer_normal", 0, "forward", false)   -- place computer
  7290.             T:go("L1F1R1F1")                            -- facing back wall in mob drop, level 4
  7291.         end
  7292.         T:place(R.useBlockType, 0, "forward", false)    -- polished block back wall layer 4
  7293.         T:turnLeft(1)
  7294.         T:go("U1F3R2")                                  -- level 5 ready for upper piston
  7295.         T:place("piston", 0, "forward")                 -- upper piston placed
  7296.         T:go("U1F3D1R2")                                -- up and over piston, facing left, level 5
  7297.         T:turnRight(1)                                  -- at mob drop, facing wall, level 5
  7298.         T:place(R.useBlockType, 0, "forward", false)    -- polished block back wall layer 5
  7299.         T:turnRight(1)                                  -- facing right side
  7300.         if R.subChoice == 1 then
  7301.             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       
  7302.         else
  7303.             T:go("F1C1")                                -- move forward, place temporary block
  7304.             utils.goBack(1)
  7305.             T:place("piston", 0, "forward")             -- upper replacer piston placed            
  7306.         end
  7307.         T:turnRight(2) 
  7308.         T:place("slab", 0, "forward")                   -- upper piston slab placed
  7309.         T:turnLeft(1)                                   -- facing away from back wall
  7310.     end
  7311.    
  7312.     function lib.placeComputer(R)
  7313.         -- starts facing away from back wall, layer 5, in mob drop         
  7314.         T:go("F1R1 F2R1 D1")                            -- move to left computerposition, facing back wall, layer 4
  7315.         T:place("computercraft:computer_normal", 0, "forward", false)       -- place computer in gap, layer 4
  7316.     end
  7317.    
  7318.     function lib.placeColumnSection(direction)
  7319.         T:place(R.useBlockType, 0, "forward", false)
  7320.         T:go(direction.."1")
  7321.         T:place(R.useBlockType, 0, "forward", false)
  7322.         T:go(direction.."1")
  7323.         T:place(R.useBlockType, 0, "forward", false)    -- facing right
  7324.     end
  7325.    
  7326.     function lib.placeColumns(R)
  7327.         -- starts facing left computer, layer 4
  7328.         T:go("R1F2 L1")                                 -- facing mob drop level 4
  7329.         T:place("glass", 0, "down", false)
  7330.         T:up(1)                                         -- facing mob drop level 5
  7331.         T:place("glass", 0, "down", false)              -- on top of glass facing back wall at dungeon base level 5
  7332.         T:up(1)
  7333.         T:place(R.useBlockType, 0, "down", false)       -- level 6 dungeon exit
  7334.         T:go("F1L1")
  7335.         lib.placeColumnSection("L")                     -- facing right
  7336.         T:up(1)
  7337.         lib.placeColumnSection("R")                     -- facing left
  7338.         T:up(1)
  7339.         lib.placeColumnSection("L")                     -- facing right
  7340.         T:up(1)
  7341.         lib.placeColumnSection("R")                     -- facing left
  7342.         T:up(1)
  7343.         T:place(R.useBlockType, 0, "forward", false)
  7344.         T:turnLeft(2)
  7345.         T:place(R.useBlockType, 0, "forward", false)    -- facing right
  7346.         T:turnLeft(1)                                   -- at top of column
  7347.         T:go("x1D1 x1D1 x1U2")                          -- open exit for mobs
  7348.         utils.goBack(2)
  7349.         T:place(R.useBlockType, 0, "forward", false)
  7350.         T:down(9)
  7351.     end
  7352.    
  7353.     function lib.placeNetwork()
  7354.         T:go("R1F2L1 F3U3 F1L1F1 L1x1")                             -- go behind second computer and remove block
  7355.         T:place("computercraft:wired_modem", 0, "forward", false)   -- place modem
  7356.         utils.goBack(1)
  7357.         T:place("computercraft:cable", 0, "forward", false)         -- place network cable
  7358.         T:place("computercraft:cable", 0, "forward", false)         -- place network cable (no need to move)
  7359.         T:go("R1F1 x2L1")                                           -- move forward, face back wall
  7360.         T:place("computercraft:cable", 0, "forward", false)
  7361.         T:go("R1F1 x2L1")
  7362.         T:place("computercraft:cable", 0, "forward", false)
  7363.         T:go("R1F1 x2L1F1 x1x2")                                    -- come behind left computer and expose back
  7364.         T:place("computercraft:wired_modem", 0, "forward", false)   -- place modem
  7365.         utils.goBack(1)
  7366.         T:place("computercraft:cable", 0, "forward", false)
  7367.         T:place("computercraft:cable", 0, "forward", false)
  7368.         T:go("L1D3 F4R1 F3U4 D4")                                   -- removes temporary block
  7369.     end
  7370.    
  7371.     local tempSubChoice = R.subChoice   -- store for later use
  7372.     R.width = 4                         -- settings for createFloorCeiling()
  7373.     R.length = 9
  7374.     R.height = 0
  7375.     R.up = true
  7376.     T:turnRight(2)
  7377.     local isWater, isSource, isIce, level, isAir = T:isWater("forward")
  7378.     if not isWater then
  7379.         T:turnRight(2)
  7380.         return{"Not in correct position. Must be water behind"}
  7381.     end
  7382.     --T:go("U1x1 U1L1 F4R2")                    -- go up to starting point
  7383.     T:go("U2L1 F4R2")                   -- go up to starting point
  7384.     local data = createFloorCeiling(R)[1]   -- place ceiling, returns to starting position. if water or lava present is returned as "water or lava found"
  7385.     if data == "water or lava found" then
  7386.         R.height = 10
  7387.         R.silent = true
  7388.         T:up(1)
  7389.         createSinkingPlatform(R)
  7390.         T:go("F4L1 U5x1 U1x1 U3R1 F4C0 R1F3C0 R1F8C0 R1F3C0 R1D9")          -- re-open exit hole, return to floor level
  7391.     else -- no water or lava found so empty out area
  7392.         R.height = 10
  7393.         R.subChoice = 2
  7394.         clearSolid(R) -- 76
  7395.         T:down(R.height - 1)
  7396.         R.width = 4                         -- settings for createFloorCeiling()
  7397.         R.length = 9
  7398.         R.height = 0
  7399.         R.down = true
  7400.         R.up = false
  7401.         R.subChoice = 1                     -- replace existing floor
  7402.         createFloorCeiling(R)
  7403.     end
  7404.    
  7405.     R.subChoice = tempSubChoice
  7406.     lib.getInventory(R)
  7407.     lib.placeRedstone()
  7408.     lib.placeStorage()
  7409.     lib.placePistons(R)
  7410.     lib.placeComputer(R)        -- ends facing computer
  7411.     lib.placeColumns(R)
  7412.     if R.subChoice == 2 then
  7413.         lib.placeNetwork()
  7414.     end
  7415.    
  7416.     return {}
  7417. end
  7418.  
  7419. local function sandFillArea(R) -- 81
  7420.     --clearRectangle with sand drop
  7421.     -- could be 1 wide x xx length (trench) up and return
  7422.     -- could be 2+ x 2+
  7423.     -- even no of runs return after last run
  7424.     -- odd no of runs forward, back, forward, reverse and return
  7425.     local success
  7426.     local directReturn = true
  7427.     if R.width % 2 == 1 then
  7428.         directReturn = false
  7429.     end
  7430.     if R.width == 1 then -- trench ahead, so fill then return
  7431.         for i = 1, R.length - 1 do
  7432.             success = utils.dropSand()
  7433.             T:forward(1, false)
  7434.         end
  7435.         success = utils.dropSand()
  7436.         T:go("R2F"..(R.length - 1).."R2", false, 0, false)
  7437.     else --2 or more columns
  7438.         if directReturn then -- R.width = 2,4,6,8 etc
  7439.             for i = 1, R.width, 2 do -- i = 1,3,5,7 etc
  7440.                 -- move along R.length, dropping sand
  7441.                 for j = 1, R.length - 1 do
  7442.                     success = utils.dropSand()
  7443.                     T:forward(1, false)
  7444.                 end
  7445.                 success = utils.dropSand()
  7446.                 T:go("R1F1R1") --turn right and return on next column
  7447.                 for j = 1, R.length - 1 do
  7448.                     success = utils.dropSand()
  7449.                     T:forward(1, false)
  7450.                 end
  7451.                 success = utils.dropSand()
  7452.                 if i < R.width - 2 then -- eg R.width = 8, i compares with 6: 1, 3, 5, 7
  7453.                     T:go("L1F1L1")
  7454.                 end
  7455.             end
  7456.             T:go("R1F"..R.width - 1 .."R1") --return home
  7457.         else
  7458.             for i = 1, R.width, 2 do -- i = 1,3,5,7 etc
  7459.                 -- move along R.length, dropping sand
  7460.                 for j = 1, R.length - 1 do
  7461.                     success = utils.dropSand()
  7462.                     T:forward(1, false)
  7463.                 end
  7464.                 success = utils.dropSand()
  7465.                 T:go("R1F1R1") --turn right and return on next column
  7466.                 for j = 1, R.length - 1 do
  7467.                     success = utils.dropSand()
  7468.                     T:forward(1, false)
  7469.                 end
  7470.                 success = utils.dropSand()
  7471.                 T:go("L1F1L1")
  7472.             end
  7473.             -- one more run then return
  7474.             for j = 1, R.length - 1 do
  7475.                 success = utils.dropSand()
  7476.                 T:forward(1, false)
  7477.             end
  7478.             success = utils.dropSand()
  7479.             T:go("R2F"..R.length.."R1F"..R.width - 1 .."R1")
  7480.         end
  7481.     end
  7482.     return {}
  7483. end
  7484.  
  7485. local function deactivateDragonTower() -- 45
  7486.     -- go up centre of tower to bedrock
  7487.     local height = 0
  7488.     --numBlocksMoved, errorMsg = clsTurtle.doMoves(self, numBlocksRequested, direction)
  7489.     local numBlocks, message = T:doMoves(1, "up")
  7490.     while message == nil do
  7491.         numBlocks, message = T:doMoves(1, "up")
  7492.         height = height + 1
  7493.     end
  7494.     -- go round bedrock and destroy crystal
  7495.     T:go("F1R2U2x1U1x1")
  7496.     -- return to start
  7497.     T:down(height + 5)
  7498.     return {}
  7499. end
  7500.  
  7501. local function undermineDragonTowers() -- 44
  7502.     --[[
  7503.             -13, -40....12, -40                     NNW (4)     NNE (5)
  7504.            
  7505.         -34, -25............33, -25             NWW (2)             NEE (9)
  7506.        
  7507.     -42, -1....................42, 0        W (1)                       E (8)
  7508.    
  7509.          -34, 24............33,24               SWW (3)             SEE (10)
  7510.          
  7511.               -13,39....12, 39                      SSW (7)     SSE (6)
  7512.    
  7513.     North towers centres 25 blocks apart, 40 blocks north of axis
  7514.     Mid-North towers 67 blocks apart, 25 blocks north of axis
  7515.     W-E centres 84 blocks apart, on 0 axis
  7516.     Mid-south towers 67 blocks apart, 24 blocks south of axis
  7517.     South towers centres 25 blocks apart, 39 blocks south of axis
  7518.     ]]
  7519.    
  7520.     local lib = {}
  7521.     function lib.findNextTower(maxDistance, withMarker)
  7522.         local distance = 0
  7523.         local blockTypeF = T:getBlockType("forward")
  7524.         local blockTypeD = T:getBlockType("down")
  7525.         for i = 1, maxDistance do
  7526.             if blockTypeF ~= "minecraft:obsidian" and blockTypeD ~= "minecraft:obsidian" then -- not in a tower
  7527.                 if withMarker and blockTypeD ~= "minecraft:obsidian" then -- used to mark 0 coordinate
  7528.                     T:place("cobble", -1, "down", false) -- place cobblestone or cobbled deepslate to mark zero coordinate
  7529.                 end
  7530.             else    -- obsidian found, could still be in an earlier tower
  7531.                 if i > 10 then
  7532.                     break
  7533.                 end
  7534.             end
  7535.             T:go("F1x0")
  7536.             distance = distance + 1
  7537.             blockTypeF = T:getBlockType("forward")
  7538.             blockTypeD = T:getBlockType("down")
  7539.         end
  7540.         if distance == maxDistance then -- obsidian not found ? wrong place/ direction
  7541.             print("Obsidian not found")
  7542.             error()
  7543.         end
  7544.         -- will now be at side of a tower
  7545.         lib.findCentre() -- move into tower to find the other side
  7546.         return distance
  7547.     end
  7548.    
  7549.     function lib.findCentre()
  7550.         local width = 0
  7551.         -- while obsidian in front or below (previously entered tower) measure width and return to centre
  7552.         local blockTypeF = T:getBlockType("forward")
  7553.         local blockTypeD = T:getBlockType("down")
  7554.         while blockTypeF == "minecraft:obsidian" or blockTypeD == "minecraft:obsidian" do
  7555.             T:go("F1x0")
  7556.             width = width + 1
  7557.             blockTypeF = T:getBlockType("forward")
  7558.             blockTypeD = T:getBlockType("down")
  7559.         end
  7560.         -- will always go outside the tower 1 block. width of 5 block tower = 6
  7561.         T:go("R2F"..math.ceil(width / 2)) --return to centre of tower
  7562.         T:turnLeft(1) -- now find another edge of the tower, dig forward until out of obsidian
  7563.         for i = 1, math.ceil(width) do  -- give additional loops if missed centre
  7564.             blockTypeF = T:getBlockType("forward")
  7565.             blockTypeD = T:getBlockType("down")
  7566.             if blockTypeF == "minecraft:obsidian" or blockTypeD == "minecraft:obsidian" then
  7567.                 T:go("F1x0")
  7568.             else
  7569.                 break
  7570.             end
  7571.         end
  7572.         -- now outside different edge of the tower
  7573.         -- reverse and move width/2, dig up + 1 to mark centre, face original direction
  7574.         T:go("L2F"..math.ceil(width / 2).."R1U2x1")
  7575.         T:place("minecraft:end_stone", -1, "forward", false) -- place endstone to mark facing direction
  7576.         T:down(2)
  7577.     end
  7578.    
  7579.     function lib.findPath(maxLength)
  7580.         local blockTypeD = T:getBlockType("down")
  7581.         local distance = 0
  7582.         while blockTypeD:find("cobble") == nil and distance < maxLength do
  7583.             T:go("F1x0")                            -- return to 0 axis,
  7584.             distance = distance + 1
  7585.             blockTypeD = T:getBlockType("down")
  7586.         end
  7587.         return distance
  7588.     end
  7589.    
  7590.     -- start at 0,y,0, facing West
  7591.     T:dig("up")                                 -- in case not already done
  7592.     local maxLength = 0
  7593.     local blockTypeD
  7594.     local distance = lib.findNextTower(45, true)-- find W tower (1) and mark trail with cobble
  7595.     T:turnRight(2)                     
  7596.     for i = 1, 8 do                             -- head back East 8 blocks, turn left (facing north)
  7597.         T:go("F1x0")                            -- this path may be off-axis, so dig double height
  7598.     end
  7599.     T:turnLeft(1)
  7600.     lib.findNextTower(30)                       -- find NWW tower (2)
  7601.     T:turnRight(2)
  7602.     distance = lib.findPath(30)
  7603.     distance = distance + lib.findNextTower(30) -- find SWW tower (3)
  7604.     T:turnRight(2)
  7605.     distance = lib.findPath(30)
  7606.     T:turnRight(1)                              -- should be on cobble path
  7607.     for i = 1, 21 do                            -- move East 21 blocks, turn left facing North
  7608.         T:go("F1x0")
  7609.     end
  7610.     T:turnLeft(1)
  7611.    
  7612.     distance = lib.findNextTower(45)        -- find NNW tower (4)
  7613.     T:turnRight(1)                         
  7614.     distance = lib.findNextTower(30)        -- find NNE tower (5)
  7615.     T:turnRight(1)
  7616.     distance = lib.findNextTower(85)        -- find SSE tower (6)
  7617.     T:turnRight(1)
  7618.  
  7619.     distance = lib.findNextTower(30)        -- find SSW tower (7)
  7620.     T:turnRight(1)
  7621.     distance = lib.findPath(40)             -- head North to 0 axis
  7622.     T:go("R1F13")                           -- return to 0,0 facing East
  7623.     distance = lib.findNextTower(45, true)  -- find E tower (8)
  7624.    
  7625.     T:turnRight(2)                     
  7626.     for i = 1, 9 do
  7627.         T:go("F1x0")                        -- this path may be off-axis, so dig double height
  7628.     end
  7629.     T:turnRight(1)
  7630.    
  7631.     distance = lib.findNextTower(30)        -- find NEE tower (9)
  7632.     T:turnRight(2)
  7633.     distance = lib.findPath(30) -- return to 0 axis
  7634.     distance = lib.findNextTower(30)        -- find SEE tower (10)
  7635.     T:turnRight(2)
  7636.     distance = lib.findPath(30)             -- return to 0 axis
  7637.     T:go("L1F33")                           -- return to 0, 0
  7638.    
  7639.     return {}
  7640. end
  7641.  
  7642. local function demolishPortal(R) -- 43
  7643.     --[[
  7644.     R.length = length of portal NOT width default 4
  7645.     R.height = height of portal default 5
  7646.     R.width = thickness of portal default 1
  7647.     R.data = "bury" to embed bottom into ground
  7648.     R.subChoice 1 = facing portal, 2 = aligned
  7649.     ]]
  7650.     local data = R.data
  7651.     if R.subChoice == 1 then -- facing portal
  7652.         T:go("F"..R.width.."R1")
  7653.     else
  7654.         T:forward(1)
  7655.     end
  7656.     if R.data == "bury" then
  7657.         T:down(1)
  7658.     end
  7659.  
  7660.     R.data = "up"
  7661.     R.silent = true
  7662.     if R.width == 1 then
  7663.         clearWall(R)
  7664.     else
  7665.         clearBuilding(R, true, true)
  7666.     end
  7667.     if data == "bury" then
  7668.         T:up(1)
  7669.     end
  7670.     if R.subChoice == 1 then -- facing portal
  7671.         T:go("R1F1L1F1L1")
  7672.     end
  7673.    
  7674.     return {}
  7675. end
  7676.  
  7677. local function digTrench(R) -- 77
  7678.     local blockType
  7679.     -- go down R.height, move forward
  7680.     if R.length == 0 then
  7681.         R.length = 4096 -- will go out of loaded chunks and stop or max 4096 on a server
  7682.     end
  7683.     for i = 1, R.length do
  7684.         local count = 0
  7685.         for down = 1, R.height do
  7686.             blockType = T:isWaterOrLava("down")
  7687.             -- go down only if no water or lava below
  7688.             if blockType:find("water") == nil and blockType:find("lava") == nil then
  7689.                 T:down(1)
  7690.                 count = count + 1
  7691.             end
  7692.         end
  7693.         T:go("C2", false, 0, true)              -- if empty below fill void
  7694.         T:go("U"..count)                        -- return to surface, continue if block above
  7695.         while turtle.detect() do                -- go up while block in front
  7696.             blockType = T:getBlockType("forward")
  7697.             if T:isVegetation(blockType) then
  7698.                 T:dig("forward")
  7699.                 break
  7700.             elseif blockType:find("log") ~= nil then
  7701.                 T:harvestTree("forward", false)
  7702.             else
  7703.                 T:up(1)
  7704.             end
  7705.         end
  7706.         T:forward(1)                            -- move forward
  7707.         while not turtle.detectDown() do        -- go down until block detected
  7708.             blockType = T:isWaterOrLava("down")
  7709.             if blockType:find("water") == nil and blockType:find("lava") == nil then
  7710.                 T:down(1)
  7711.             else
  7712.                 break
  7713.             end
  7714.         end
  7715.     end
  7716.    
  7717.     return {}
  7718. end
  7719.  
  7720. local function harvestTreeFarm(R) -- 24
  7721.     local lib = {}
  7722.    
  7723.     function lib.getLogCount()
  7724.         local count = 0
  7725.         for i = 1,16 do
  7726.             local item, itemCount = T:getSlotContains(i)
  7727.             if item:find("log") ~= nil then
  7728.                 count = count + itemCount
  7729.             end
  7730.         end
  7731.        
  7732.         return count
  7733.     end
  7734.    
  7735.     function lib.initialise()
  7736.         local blockType = T:getBlockType("forward")
  7737.         local logType = ""
  7738.         local startHeight = 0
  7739.         local range = 0
  7740.         if blockType == "" then
  7741.             while turtle.forward() do
  7742.                 range = range + 1
  7743.                 if range == 3 then
  7744.                     break
  7745.                 end
  7746.             end
  7747.         end
  7748.         blockType = T:getBlockType("forward")
  7749.         if blockType:find("dirt") ~= nil then
  7750.             T:up(1)
  7751.             startHeight = 1
  7752.         else
  7753.             if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil then
  7754.                 logType = blockType
  7755.             end
  7756.         end
  7757.        
  7758.         return logType, startHeight
  7759.     end
  7760.    
  7761.     R.silent = true
  7762.     local treeType, startHeight = lib.initialise() -- possible ID tree type + move to correct position 1 above dirt
  7763.    
  7764.     T:forward(1)    -- dig first log/sapling/ air if not planted
  7765.     clearRectangle({width = 7, length = 7, up = true, down = true})
  7766.     T:go("L1F2L1F2R2")
  7767.     local height = 0
  7768.     local pastLogCount = -1
  7769.     local currentLogCount = lib.getLogCount()
  7770.     while currentLogCount ~= pastLogCount do
  7771.         T:up(3)
  7772.         height = height + 3
  7773.         pastLogCount = currentLogCount -- 0 when loop starts
  7774.         clearRectangle({width = 12, length = 12, up = true, down = true})
  7775.         currentLogCount = lib.getLogCount() -- eg 20 logs from first round
  7776.     end
  7777.     T:down(height + startHeight)
  7778.     T:go("R1F2R1F2R2")
  7779.    
  7780.     return {}
  7781. end
  7782.  
  7783. local function harvestObsidian(R) -- 41
  7784.     local lib = {}
  7785.    
  7786.     function lib.forward(move)
  7787.         T:isWaterOrLava("forward")  -- automatically use lava ahead to refuel
  7788.         T:isWaterOrLava("down")     -- automatically use lava down to refuel
  7789.         T:go("C2", false, 0, false) -- place / replace block below
  7790.         if move then
  7791.             T:forward(1)
  7792.         end
  7793.     end
  7794.    
  7795.     function lib.home(outward)
  7796.         if outward then
  7797.             T:go("L1F"..R.width - 1 .."L1F"..R.length - 1)
  7798.         else   
  7799.             T:go("R1F"..R.width - 1 .."R1")
  7800.         end
  7801.     end
  7802.    
  7803.     function lib.start()
  7804.         local lavaSlot = T:getItemSlot("lava")
  7805.         if lavaSlot > 0 then
  7806.             turtle.select(slot)
  7807.             turtle.refuel()
  7808.         end
  7809.         T:down(1)
  7810.     end
  7811.    
  7812.     local outward = true
  7813.    
  7814.     lib.start()                     -- use lava bucket if placed, move down into block below
  7815.     for w = 1, R.width do
  7816.         for l = 1, R.length do
  7817.             if l < R.length then
  7818.                 lib.forward(true)
  7819.             else
  7820.                 lib.forward(false)
  7821.             end
  7822.         end
  7823.         if w < R.width then
  7824.             if outward then
  7825.                 T:go("R1F1R1")
  7826.             else
  7827.                 T:go("L1F1L1")
  7828.             end
  7829.             outward = not outward
  7830.         end
  7831.     end
  7832.    
  7833.     lib.home(outward)
  7834.    
  7835.     return {}
  7836. end
  7837.  
  7838. local function harvestShulkers(R)
  7839.     local lib = {}
  7840.    
  7841.     function lib.attackAll()
  7842.         return turtle.attack(), turtle.attackUp(), turtle.attackDown()
  7843.     end
  7844.  
  7845.     function lib.attack()
  7846.         local forward, up, down = lib.attackAll()
  7847.         while forward or up or down do
  7848.             forward, up, down = lib.attackAll()
  7849.             sleep(0.2)
  7850.         end
  7851.     end
  7852.    
  7853.     function lib.approach(direction, limit, dig)
  7854.         -- move forward until stopped by shulker
  7855.         limit = limit or 64
  7856.         dig = dig or false
  7857.         local count = 0
  7858.         local solidDown = false
  7859.         move = turtle.forward
  7860.         if direction == "up" then
  7861.             move = turtle.up
  7862.         elseif direction == "down" then
  7863.             move = turtle.down
  7864.         end
  7865.         local forward, up, down = lib.attackAll()
  7866.         if forward or up or down then -- attacks suceeded
  7867.             return true, 0, solidDown
  7868.         else
  7869.             while move() do
  7870.                 count = count + 1
  7871.                 if turtle.detectDown() then
  7872.                     solidDown = true
  7873.                 end
  7874.                 if count >= limit then
  7875.                     return false, count, solidDown
  7876.                 end
  7877.                 forward, up, down = lib.attackAll()
  7878.                 if forward or up or down then
  7879.                     return true, count, solidDown
  7880.                 else
  7881.                     if dig then
  7882.                         T:dig("forward")
  7883.                     end
  7884.                 end
  7885.             end
  7886.             return false, count, solidDown
  7887.         end
  7888.     end
  7889.    
  7890.     function lib.home(direction, moves)
  7891.         local move = turtle.back
  7892.         if direction == "up" then
  7893.             move = turtle.down
  7894.         elseif direction == "down" then
  7895.             move = turtle.up
  7896.         end
  7897.         for i = 1, moves do
  7898.             move()
  7899.         end
  7900.     end
  7901.    
  7902.     function lib.checkPosition()
  7903.         if T:detect("forward") then         -- wall in front
  7904.             T:turnRight(1)
  7905.             if T:detect("forward") then     -- wall to right
  7906.                 T:turnLeft(1)
  7907.                 return true                 -- position corrected
  7908.             else
  7909.                 T:turnLeft(2)
  7910.                 if T:detect("forward") then -- wall in front. position correct
  7911.                     return true
  7912.                 end
  7913.             end
  7914.         end
  7915.         return false
  7916.     end
  7917.    
  7918.     function lib.getLength()
  7919.         local count = 0
  7920.         while turtle.detectDown() do
  7921.             count = count + 1
  7922.             T:forward(1)
  7923.         end
  7924.         utils.goBack(1)
  7925.         return count
  7926.     end
  7927.    
  7928.     function lib.clearWall()
  7929.         local distance = 0
  7930.         while distance < 9 do   -- smallest external walls are 8 x 8
  7931.             local success, count = lib.approach("forward", 8 - distance)
  7932.             if success then
  7933.                 lib.attack()
  7934.             end
  7935.             distance = distance + count
  7936.         end
  7937.         T:turnLeft(1)
  7938.         if T:detect("forward") then -- larger than 8 blocks
  7939.             T:turnRight(1)
  7940.             while distance < 14 do  -- larger builds are 14 x 14
  7941.                 local success, count = lib.approach("forward", 13 - distance)
  7942.                 if success then
  7943.                     lib.attack()
  7944.                 end
  7945.                 distance = distance + count
  7946.             end
  7947.             T:go("L1x2")
  7948.         end
  7949.     end
  7950.    
  7951.     function lib.roof()
  7952.         -- check position
  7953.         local doContinue = lib.checkPosition()
  7954.        
  7955.         if doContinue then
  7956.             T:go("U2F3 R1F3 R1")
  7957.             local length = lib.getLength()
  7958.             local width = 1
  7959.             local outward = lib.turnRound(true)
  7960.             local success, count, onRoof = false, 0, true  
  7961.             while onRoof do
  7962.                 local distance = 0
  7963.                 while distance < length - 1 do
  7964.                     success, count, onRoof = lib.approach("forward", length - 1 - distance)
  7965.                     if success then
  7966.                         lib.attack()
  7967.                     end
  7968.                     if count == 0 then
  7969.                         turtle.dig()
  7970.                     end
  7971.                     distance = distance + count
  7972.                 end
  7973.                 width = width + 1
  7974.                 outward = lib.turnRound(outward)
  7975.             end
  7976.             if outward then
  7977.                 T:go("F".. 3 .."L1F"..width - 3 .."D2L1")
  7978.             else
  7979.                 T:go("F".. length - 3 .."R1F"..width - 3 .."D2L1")
  7980.             end
  7981.             return {}
  7982.         else
  7983.             return {"Turtle not in front of a wall"}
  7984.         end
  7985.     end
  7986.    
  7987.     function lib.turnRound(outward)
  7988.         if outward then
  7989.             T:go("R1F1R1")
  7990.         else
  7991.             T:go("L1F1L1")
  7992.         end
  7993.         return not outward
  7994.     end
  7995.  
  7996.     function lib.upAndOver()
  7997.         local start, height, forward = 0, 0, 0
  7998.         while turtle.detect() do
  7999.             turtle.up()
  8000.             start = start + 1
  8001.         end
  8002.         while turtle.forward() do
  8003.             forward = forward + 1
  8004.         end
  8005.         turtle.turnRight()
  8006.         while not turtle.detectUp() do
  8007.             local success, count = lib.approach("up", 64, true)
  8008.             if success then
  8009.                 lib.attack()
  8010.             end
  8011.             height = height + count
  8012.         end
  8013.         T:turnRight(2)
  8014.         while not turtle.detectDown() do
  8015.             if lib.approach("down", 64, true) then
  8016.                 lib.attack()
  8017.             end
  8018.         end
  8019.         T:turnLeft(1)
  8020.         for i = 1, forward do
  8021.             turtle.forward()
  8022.         end
  8023.         for i = 1, start do
  8024.             turtle.down()
  8025.         end
  8026.         T:turnRight(2)
  8027.     end
  8028.    
  8029.     function lib.walls()
  8030.         local doContinue = lib.checkPosition()
  8031.         if doContinue then
  8032.             T:go("F2R1 F2R2 D1x2")      -- on corner outside middle of wall, facing along its length, dig light rod
  8033.             for i = 1, 4 do
  8034.                 lib.clearWall()
  8035.             end
  8036.             T:go("F2L1 U1F2 R2")
  8037.         else
  8038.             return {"Turtle not in front of a wall"}
  8039.         end
  8040.     end
  8041.        
  8042.     local direction = "forward"
  8043.     local doContinue = false
  8044.    
  8045.     if R.subChoice == 1 then        -- Shulker is above
  8046.         direction = "up"
  8047.         doContinue = true
  8048.     elseif R.subChoice == 2 then    -- Shulker is ahead
  8049.         doContinue = true
  8050.     elseif R.subChoice == 3 then    -- Shulker is below
  8051.         direction = "down"
  8052.         doContinue = true
  8053.     else
  8054.         if R.subChoice == 4 then    -- Climb tower wall
  8055.             lib.upAndOver()
  8056.         elseif R.subChoice == 5 then    -- Clear roof above
  8057.             return lib.roof()
  8058.         elseif R.subChoice == 6 then    -- Clear outside walls
  8059.             lib.walls()
  8060.         end
  8061.    
  8062.     end
  8063.     if doContinue then
  8064.         local success, moves = lib.approach(direction, 64)
  8065.         if success then
  8066.             lib.attack()
  8067.         end
  8068.         lib.home(direction, moves)
  8069.     end
  8070.    
  8071.     return {}
  8072. end
  8073.  
  8074. local function manageFarm(R)
  8075.     local lib = {}
  8076.    
  8077.     function lib.checkEquipment()
  8078.         --[[ Needs pickaxe and hoe equipped ]]
  8079.         T:clear()
  8080.         --T:checkInventoryForItem(items{}, quantities{}, required, message)
  8081.         print("Checking equipment. Please wait...")
  8082.         local equippedRight, equippedLeft, inInventory = T:setEquipment() -- any tools equipped except diamond_pickaxe and crafting_table have been removed to inventory
  8083.         --[[if equippedRight ~= "minecraft:crafting_table" then
  8084.             T:checkInventoryForItem({"minecraft:crafting_table"}, {1})
  8085.             local equippedRight, equippedLeft = T:setEquipment()
  8086.         end]]
  8087.         T:suck("down")      -- if hoe already in storage get it out
  8088.         if inInventory ~= "minecraft:diamond_hoe" then
  8089.             if T:getItemSlot("minecraft:diamond_hoe") > 0 then
  8090.                 return true
  8091.             else
  8092.                 T:checkInventoryForItem({"minecraft:diamond_hoe"}, {1}, true, "Diamond Hoe required for planting!")
  8093.             end
  8094.         end
  8095.         if T:getItemSlot("minecraft:diamond_hoe") > 0 then
  8096.             return true
  8097.         end
  8098.  
  8099.         return false
  8100.     end
  8101.    
  8102.     function lib.checkPosition()
  8103.         --[[ first function called on start]]
  8104.         local atHome = false
  8105.         local blockType = T:getBlockType("down")
  8106.         print("Checking position "..blockType.. " below")
  8107.         if blockType:find("water") ~= nil then -- over water
  8108.             if lib.isStorage("forward") then
  8109.                 atHome = true
  8110.                 T:turnRight(1)
  8111.                 if lib.isStorage("forward") then-- confirms in correct position, back to crops
  8112.                     T:turnRight(2)
  8113.                 else -- facing crafting table
  8114.                     T:turnRight(1)
  8115.                 end
  8116.             else -- not a chest: facing crops or crafting table
  8117.                 T:turnRight(1)
  8118.                 if lib.isStorage("forward") then -- confirms was facing crops
  8119.                     atHome = true
  8120.                     T:turnLeft(1)
  8121.                 end
  8122.             end
  8123.             -- should now be facing crops. may be crafting table to left
  8124.         end
  8125.         return atHome-- now facing crops
  8126.     end
  8127.    
  8128.     function lib.crossFarm()
  8129.         -- used with goHome to find starting point
  8130.         local blockType = ""
  8131.         local isReady, cropType, status = lib.isCropReady("down")
  8132.         -- will go forward until chest or cobble detected below
  8133.         -- if detected within 1 move, this is ignored
  8134.         local numMoves = 0
  8135.         local endOfPath = false
  8136.         while not endOfPath do
  8137.             blockType = T:getBlockType("down", -1)
  8138.             if blockType == "" or cropType ~= "" then --crops or nothing below
  8139.                 turtle.forward()
  8140.             elseif  blockType:find("barrel") ~= nil or blockType:find("chest") ~= nil or blockType:find("cobble") ~= nil then
  8141.                 endOfPath = true
  8142.             end
  8143.             numMoves = numMoves + 1
  8144.         end
  8145.         return blockType -- either chest or cobble
  8146.     end
  8147.    
  8148.     function lib.farmInFront()
  8149.         --[[ facing crops on first farm. move to next farm in front ]]
  8150.         T:go("U1L1F11D1R1")                         -- on next farm, facing crops
  8151.         local crop = lib.manageTree()               -- refuel, gather seeds and other crops
  8152.         local isFarmToRight, _ = lib.harvest(crop)  -- harvest field, store crops
  8153.         return isFarmToRight
  8154.     end
  8155.    
  8156.     function lib.farmToRight()
  8157.         --[[ facing crops on first farm. move to next farm on right side ]]
  8158.         T:go("U1F11 D1")                -- on next farm, facing crops
  8159.         local crop = lib.manageTree()   -- refuel, gather seeds and other crops
  8160.         lib.harvest(crop)               -- harvest field, store crops
  8161.     end
  8162.    
  8163.     function lib.getCrops()
  8164.         T:turnRight(1)
  8165.  
  8166.         if lib.isStorage("forward") then
  8167.             lib.getSeeds("forward")
  8168.         end
  8169.         T:turnRight(1)
  8170.         if lib.isStorage("forward") then
  8171.             lib.getVeg("forward")
  8172.         end
  8173.         T:turnRight(2)
  8174.     end
  8175.    
  8176.     function lib.getSaplings(direction)
  8177.         --[[ get a single sapling from the chest ]]
  8178.         if direction == nil then
  8179.             direction = "forward"
  8180.         end
  8181.         while T:suck(direction, 1) do end -- remove saplings/ seeds
  8182.  
  8183.         T:dropItem("sapling", direction, 1) -- drop all but 1 saplings
  8184.         if not T:dropItem("seeds", direction, 0) then-- drop all seeds
  8185.             T:dropItem("seeds", "up", 0)
  8186.         end
  8187.        
  8188.         return T:getItemSlot("sapling", -1)
  8189.     end
  8190.    
  8191.     function lib.getSeeds(direction)
  8192.         --[[ get 1 stack of wheat seeds or 1 stack of beetroot seeds ]]
  8193.         print("Collecting seeds from storage")
  8194.         while T:suck(direction, 1) do end -- remove saplings/ seeds
  8195.         T:dropItem("sapling", direction, 0) -- drop all saplings
  8196.         T:dropItem("minecraft:wheat_seeds", direction, 64) -- drop all but 64 seeds
  8197.         T:dropItem("minecraft:beetroot_seeds", direction, 64)
  8198.         local crop = ""
  8199.         if T:getItemSlot("minecraft:wheat_seeds", -1) > 0 then
  8200.             crop = "wheat"
  8201.             print("Field crop = "..crop)
  8202.         elseif T:getItemSlot("minecraft:beetroot_seeds", -1) > 0 then
  8203.             crop = "beetroot"
  8204.             print("Field crop = "..crop)
  8205.         end
  8206.        
  8207.         return crop
  8208.     end
  8209.    
  8210.     function lib.getVeg(direction)
  8211.         -- assume only one type of crop per field
  8212.         print("Collecting crops from storage")
  8213.         direction = direction or "forward"
  8214.         while T:suck(direction, 1) do end -- remove carrots / potatoes / wheat / beetroot
  8215.         --clsTurtle.dropItem(self, item, direction, keepAmount)
  8216.         T:dropItem("wheat", direction, 0)       -- drop all wheat
  8217.         T:dropItem("beetroot", direction, 0)    -- drop all beetroot
  8218.         T:dropItem("carrot", direction, 64)     -- drop all but 64 carrots
  8219.         T:dropItem("potato", direction, 64)     -- drop all but 64 potato
  8220.         local crop = ""
  8221.         if T:getItemSlot("potato", -1) > 0 then
  8222.             crop = "potato"
  8223.             print("Field crop = "..crop)
  8224.         elseif T:getItemSlot("carrot", -1) > 0 then
  8225.             crop = "carrot"
  8226.             print("Field crop = "..crop)
  8227.         end
  8228.        
  8229.         --T:turnRight(2) -- face crops
  8230.         return crop
  8231.     end
  8232.    
  8233.     function lib.goHome()
  8234.         -- after a re-boot go to start
  8235.         local onTree = false
  8236.         -- is tree above or in front
  8237.         -- check if log in front
  8238.         if T:getBlockType("forward"):find("log") ~= nil then -- about to harvest tree
  8239.             lib.harvestTree("forward") -- will only harvest if fuel below half of limit
  8240.             onTree = true
  8241.         elseif T:getBlockType("up"):find("log") ~= nil then -- harvesting tree
  8242.             lib.harvestTree("up")
  8243.             onTree = true
  8244.         elseif T:getItemSlot("log", -1) > 0 then -- tree just harvested
  8245.             onTree = true
  8246.             turtle.up()
  8247.             if T:getBlockType("up"):find("log") ~= nil then -- harvesting tree
  8248.                 lib.harvestTree("up")
  8249.             else
  8250.                 while turtle.down() do end
  8251.             end
  8252.         end
  8253.        
  8254.         if onTree then -- tree harvested, but direction unknown
  8255.             local blockType = ""
  8256.             local turns = 0
  8257.             local onChest = lib.isStorage("down")
  8258.             while not onChest do
  8259.                 if turtle.forward() then
  8260.                     if lib.isStorage("down") then
  8261.                         onChest = true
  8262.                     else
  8263.                         turtle.back()
  8264.                     end
  8265.                 end
  8266.                 if not onChest then
  8267.                     T:turnRight(1)
  8268.                     turns = turns + 1
  8269.                 end
  8270.                 if turns == 4 then
  8271.                     break
  8272.                 end
  8273.             end -- should be on chest. If not should be over water
  8274.             if onChest then -- onChest and onTree, go left,down
  8275.                 T:go("R1F1D1R1")
  8276.             end
  8277.             atHome = lib.checkPosition()
  8278.             if atHome then
  8279.                 return true -- exit function
  8280.             end
  8281.         else
  8282.             while turtle.down() do end -- no tree around, no logs onboard
  8283.         end
  8284.            
  8285.         return false
  8286.     end
  8287.    
  8288.     function lib.gotoTree(logSlot)
  8289.         -- assume facing crops
  8290.         T:turnRight(1)
  8291.         print("Extracting saplings from storage")
  8292.         lib.getSaplings("forward") -- gets one sapling only (if present)
  8293.         print("Moving to tree position")
  8294.         T:go("U1F1R1")
  8295.         lib.harvestTree("forward") -- fell tree or plant sapling, ends facing tree / dirt / sapling. sticks already used for fuel. excess saplings placed
  8296.        
  8297.         if logSlot == 0 then -- no logs passed as parameter
  8298.             logSlot = T:getItemSlot("log")
  8299.         end
  8300.         T:go("R1F1D1")          -- return to base, facing buried storage
  8301.         if logSlot == 0 then    -- has logs so needs to craft and refuel
  8302.             T:turnRight(1)      -- facing crops
  8303.         end
  8304.        
  8305.         return logSlot
  8306.     end
  8307.    
  8308.     function lib.harvest(crop)
  8309.         --[[
  8310.         cover the field in a set pattern.
  8311.         harvest crops if ripe
  8312.         till soil and plant new ones
  8313.         place seeds / harvest in chests
  8314.         return farm(s) to right / front
  8315.         ]]
  8316.         T:go("U1") --ready to farm field
  8317.         local isFarmToRight = false
  8318.         local isFarmToFront = false
  8319.         local width = 9
  8320.         local length = 10
  8321.         local toRight = true
  8322.         for l = 1, length do
  8323.             for w = 1, width do
  8324.                 isReady, blockType, _ = lib.isCropReady("down") -- eg true, "minecraft:carrots", "7 / 7" or false, "", ""
  8325.                 turtle.select(1)
  8326.                 if blockType == "" then                 -- air (above water, storage or dirt)
  8327.                     --turtle.digDown("left")            -- use pickaxe
  8328.                     turtle.digDown("right")             -- use hoe
  8329.                     lib.plantCrop(crop, "down")         -- plant crop
  8330.                 elseif isReady then                     -- crop below is ready
  8331.                     turtle.digDown("left")              -- use pickaxe
  8332.                     lib.plantCrop(blockType, "down")    -- plant crop
  8333.                 end
  8334.                 T:forward(1)
  8335.                 if l == 1 and w == width then -- last block of first row at front of farm
  8336.                     T:forward(1)
  8337.                     if lib.isStorage("down") then
  8338.                         isFarmToRight = true
  8339.                     end
  8340.                     turtle.back()
  8341.                 end
  8342.             end
  8343.             -- end of the row: change direction
  8344.             if l < length then -- do not turn at final row
  8345.                 lib.plantCrop(crop, "down")
  8346.                 if toRight then
  8347.                     T:go("L1F1L1")
  8348.                 else
  8349.                     T:go("R1F1R1")
  8350.                 end
  8351.             end
  8352.             toRight = not toRight
  8353.         end
  8354.         T:go("R1F1") -- goes over chest/cobble on top wall
  8355.         if lib.isStorage("down") then
  8356.             isFarmToFront = true
  8357.         end
  8358.         T:go("R2F"..length.."D1L1") -- go straight across to seed chest 10 blocks, facing crops
  8359.         lib.storeCrops() -- rotates from start to deposit seeds and crops, ends facing crops
  8360.         return isFarmToRight, isFarmToFront
  8361.     end
  8362.    
  8363.     function lib.harvestTree(direction)
  8364.         --[[
  8365.             start in front of / during tree harvest
  8366.             Check if sapling present
  8367.             Harvest tree if present, replant sapling
  8368.             Dispose of apples. Use sticks as fuel
  8369.             Return to base
  8370.         ]]
  8371.         if turtle.getFuelLevel() < turtle.getFuelLimit() / 2 then -- only harvest tree if fuel < half max
  8372.             direction = direction or "forward"
  8373.             local inFront = T:getBlockType("forward")
  8374.             print("Checking tree")
  8375.             if inFront == "" then -- no tree or sapling
  8376.                 print("No sapling: planting sapling")
  8377.                 T:place("sapling", -1, "forward", false)
  8378.             elseif inFront:find("log") ~= nil or direction == "up" then -- tree above or in front
  8379.                 -- clsTurtle.harvestTree(self, extend, craftChest, direction)
  8380.                 print("Harvesting tree")
  8381.                 T:harvestTree(false, false, direction) --do not investigate side branches in case chunk unloaded
  8382.                 T:go("R2F1R2") -- face dirt
  8383.                 -- place(self, blockType, damageNo, direction, leaveExisting, signText)
  8384.                 T:place("sapling", -1, "forward", false)
  8385.             end
  8386.             print("Dropping saplings into storage")
  8387.             T:dropItem("sapling", "down", 0) -- drop all saplings down into chest
  8388.             print("Disposing of apples")
  8389.             T:dropItem("apple", "up", 0) -- drop any apples
  8390.             local slot = T:getItemSlot("minecraft:stick")
  8391.             if slot > 0 then -- use any sticks to refuel
  8392.                 turtle.select(slot)
  8393.                 turtle.refuel()
  8394.             end
  8395.         end
  8396.     end
  8397.    
  8398.     function lib.manageTree()
  8399.         --[[ starting position facing crops ]]
  8400.         local crop = ""
  8401.         local logSlot = T:getItemSlot("stick")
  8402.         if logSlot > 0 then
  8403.             turtle.select(logSlot)
  8404.             turtle.refuel()
  8405.         end
  8406.         logSlot = T:getItemSlot("log")
  8407.         local needsFuel = false
  8408.        
  8409.         if turtle.getFuelLevel() < turtle.getFuelLimit() / 2 then
  8410.             needsFuel = true
  8411.         end
  8412.         if needsFuel then
  8413.             print("Running Tree Manager")
  8414.             logSlot = lib.gotoTree(logSlot) -- check for sapling or harvest tree, retuns to start, ends facing buried barrel/chest if has logs, logSlot returned
  8415.         end
  8416.         if logSlot > 0 then
  8417.             if not needsFuel then           -- logs already onboard, no tree harvest, so turn towards buried chest
  8418.                 T:turnLeft(1)
  8419.             end
  8420.             T:go("F1")                      -- move to buried storage chest/barrel
  8421.             lib.refuelWithLogs(logSlot)     -- use any logs for fuel
  8422.             T:go("R2F1")                    -- facing seed chest/barrel
  8423.         else
  8424.             T:turnRight(1)                  -- facing seed chest/barrel
  8425.         end
  8426.        
  8427.         crop = lib.getSeeds("forward")      -- get 1 stack of beetroot / wheat seeds
  8428.         if crop == "" then
  8429.             print("No seeds available. Checking root veg")
  8430.             T:turnRight(1)                  -- face crop chests
  8431.             crop = lib.getVeg("forward")    -- gets any carrots / potatoes
  8432.             T:turnRight(2)                  -- face crops
  8433.         else
  8434.             T:turnLeft(1)                   -- face crops
  8435.         end
  8436.         return crop
  8437.     end
  8438.    
  8439.     function lib.isCropReady(direction)
  8440.         local isReady = false
  8441.         local status = ""
  8442.         local cropType = ""
  8443.         local success = false
  8444.         local data = {}
  8445.  
  8446.         direction = direction or "forward"
  8447.  
  8448.         if direction == "down" then
  8449.             success, data = turtle.inspectDown()
  8450.         else
  8451.             success, data = turtle.inspect()
  8452.         end
  8453.         if success then
  8454.             cropType = data.name
  8455.             --print("cropType: "..cropType) read()
  8456.             if data.name == "minecraft:carrots" then
  8457.                 status = data.state.age.." / 7"
  8458.                 --print("Carrots status: "..status) read()
  8459.                 if data.state.age == 7 then
  8460.                     isReady = true
  8461.                 end
  8462.             elseif data.name == "minecraft:potatoes" then
  8463.                 status = data.state.age.." / 7"
  8464.                 if data.state.age == 7 then
  8465.                     isReady = true
  8466.                 end
  8467.             elseif data.name == "minecraft:wheat" then
  8468.                 status = data.state.age.." / 7"
  8469.                 if data.state.age == 7 then
  8470.                     isReady = true
  8471.                 end
  8472.             elseif data.name == "minecraft:beetroots" then
  8473.                 status = data.state.age.." / 3"
  8474.                 if data.state.age == 3 then
  8475.                     isReady = true
  8476.                 end
  8477.             end
  8478.         end
  8479.         return isReady, cropType, status    -- eg true, "minecraft:carrots", "7 / 7" or false, "", ""
  8480.     end
  8481.  
  8482.     function lib.isStorage(direction)
  8483.         blockType = T:getBlockType(direction)
  8484.         if blockType:find("barrel") ~= nil then
  8485.             return true, "barrel"
  8486.         elseif blockType:find("chest") ~= nil then
  8487.             return true, "chest"
  8488.         end
  8489.        
  8490.         return false, ""
  8491.     end
  8492.    
  8493.     function lib.plantCrop(crop, direction)
  8494.         local planted = false
  8495.         --turtle.digDown("left") -- harvest existing
  8496.         --turtle.digDown("right") -- till soil
  8497.         if crop:find("potato") ~= nil then
  8498.             T:dropItem("poison", "up", 0)
  8499.         end
  8500.         planted = T:place("carrot", -1, direction)
  8501.         if not planted then
  8502.             planted = T:place("potato", -1, direction)
  8503.         end
  8504.         if not planted then
  8505.             planted = T:place("beetroot_seeds", -1, direction)
  8506.         end
  8507.         if not planted then
  8508.             planted = T:place("wheat_seeds", -1, direction)
  8509.         end
  8510.     end
  8511.    
  8512.     function lib.refuelWithLogs(logSlot)
  8513.         -- assume positioned in front of buried chest / barrel, saplings already dropped, apples dumped, sticks used as fuel
  8514.         print("Logs present: collecting crafting table")
  8515.         -- earlier versions used crafting table buried in the ground
  8516.         -- newer versions have a barrel or chest embedded in the ground, containing the crafting table
  8517.         print("Sorting Inventory")
  8518.         T:sortInventory()
  8519.         while T:suck("down") do end                 -- empty out barrel/chest to find crafting table
  8520.         if T:getItemSlot("crafting") == 0 then
  8521.             T:checkInventoryForItem({"crafting"}, {1}, true, "Crafting table required for logs->planks")
  8522.         end
  8523.         if T:equip("right", "minecraft:crafting_table") then -- swap equipment on right side
  8524.             for i = 1, 16 do                        -- drop anything except logs down into barrel/chest/pit
  8525.                 if T:getSlotContains(i):find("log") == nil then
  8526.                     T:drop("down", i)
  8527.                 else
  8528.                     logSlot = i
  8529.                 end
  8530.             end
  8531.             turtle.select(logSlot)
  8532.             turtle.transferTo(1)
  8533.             turtle.craft()                          -- craft logs to planks
  8534.             logSlot = T:getItemSlot("planks")
  8535.             while logSlot > 0 do
  8536.                 turtle.select(logSlot)
  8537.                 turtle.refuel()
  8538.                 logSlot = T:getItemSlot("planks")              
  8539.             end
  8540.                             -- refuel using planks
  8541.             while T:suck("down") do end             -- recover items from storagebelow
  8542.             if not T:equip("right", "minecraft:diamond_hoe") then       -- re-equip
  8543.                 T:equip("right", "minecraft:diamond_pickaxe")          
  8544.             end
  8545.             if T:dropItem("minecraft:crafting_table", "down") then
  8546.                 turtle.refuel() -- use any sticks
  8547.             end
  8548.         else
  8549.             print("Unable to equip crafting table.\n\nCheck turtle inventory and chest or barrel below")
  8550.             error()
  8551.         end
  8552.     end
  8553.    
  8554.     function lib.returnToBack()
  8555.         --[[ move from farm at front back to starting farm ]]
  8556.         T:go("U1R1F11D1L1")
  8557.     end
  8558.    
  8559.     function lib.returnToLeft()
  8560.         --[[ move from farm on right back to starting farm ]]
  8561.         T:go("U1R2F11D1R2")
  8562.     end
  8563.        
  8564.     function lib.storeCrops()
  8565.         -- place crops and seeds into chests
  8566.         T:turnRight(1)
  8567.         if lib.isStorage("forward") then
  8568.             lib.storeSeeds("forward")
  8569.         end
  8570.         T:turnRight(1)
  8571.         if lib.isStorage("forward") then
  8572.             lib.storeVeg("forward")
  8573.         end
  8574.         T:turnRight(2) -- facing crops again
  8575.     end
  8576.    
  8577.     function lib.storeSeeds(direction)
  8578.         direction = direction or "forward"
  8579.         if lib.isStorage(direction) then -- chest exists
  8580.             if T:getItemSlot("minecraft:wheat_seeds") > 0 then
  8581.                 if not T:dropItem("minecraft:wheat_seeds", direction, 0) then
  8582.                     T:dropItem("minecraft:wheat_seeds", "up", 0)
  8583.                 end -- drop all wheat seeds
  8584.             elseif T:getItemSlot("minecraft:beetroot_seeds") > 0 then
  8585.                 if not T:dropItem("minecraft:beetroot_seeds", direction, 0) then-- drop all beetroot seeds
  8586.                     T:dropItem("minecraft:beetroot_seeds", "up", 0)
  8587.                 end
  8588.             end
  8589.         end
  8590.     end
  8591.    
  8592.     function lib.storeVeg(direction)
  8593.         direction = direction or "forward"
  8594.         T:dropItem("apple", "up", 0) -- drop all apples
  8595.         T:dropItem("poison", "up", 0) -- drop all poison potatoes
  8596.         if lib.isStorage(direction) then
  8597.             if not T:dropItem("carrot", direction, 0) then-- drop carrots
  8598.                 --return false
  8599.             end
  8600.             T:dropItem("potato", direction, 0) -- drop potato
  8601.             T:dropItem("minecraft:wheat", direction, 0) -- drop all wheat
  8602.             T:dropItem("minecraft:beetroot", direction, 0) -- drop all beetroot
  8603.         end
  8604.     end
  8605.    
  8606.     function lib.watchFarm()
  8607.         --[[
  8608.         check status of crops in front of turtle.
  8609.         call lib.harvest when ripe
  8610.         return farm(s) found in front or to the right
  8611.         ]]
  8612.         local isReady, crop, status = lib.isCropReady("forward")        -- eg true, "minecraft:carrots", "7 / 7" or false, "", ""
  8613.         -- check state of crop in front. Harvest if ripe       
  8614.         while not isReady do
  8615.             isReady, crop, status = lib.isCropReady("forward")          -- eg true, "minecraft:carrots", "7 / 7" or false, "", ""
  8616.             if not isReady then
  8617.                 if crop == "" then
  8618.                     print("No crops found in front")
  8619.                     print("Plant seeds, carrots, potatoes")
  8620.                     error()
  8621.                 else
  8622.                     print("Waiting for "..crop.." status: "..status)
  8623.                 end
  8624.                 sleep(60)
  8625.             end
  8626.         end
  8627.         print("Local crops ripe")
  8628.        
  8629.         return lib.manageTree() -- "" or collected seeds / root crops
  8630.     end
  8631.    
  8632.     --[[
  8633.         called from args on start, or from user choice
  8634.         farm already built, needs planting and/or harvesting
  8635.         needs both pickaxe and hoe
  8636.         may start in any position if chunk unloaded while running
  8637.     ]]
  8638.     --local pp = utils.getPrettyPrint()
  8639.    
  8640.     local atHome = lib.checkPosition()-- facing crops, placed above water source
  8641.     if not atHome then
  8642.         if not lib.goHome() then -- try to find home
  8643.             return
  8644.             {
  8645.                 "Unable to determine my position.\n",
  8646.                 "Place me in the lower left corner",
  8647.                 "over water, facing the crops with",
  8648.                 "barrels or chests to my right and behind"
  8649.             }
  8650.         end
  8651.     end
  8652.     -- check equipment
  8653.     T:go("L1F1") -- over barrel
  8654.     local isStorage, storageType = lib.isStorage("down")
  8655.     if not isStorage then
  8656.         local message =
  8657. [["Farm upgrade required:
  8658. Previous designs had a crafting table
  8659. next to the water source.
  8660.  
  8661. 1. Place a barrel or chest under the turtle
  8662.    instead.
  8663.    
  8664. 2. Restart"
  8665. ]]
  8666.         print(message)
  8667.         error()
  8668.     end
  8669.     -- must be storage below to get this far
  8670.     if lib.checkEquipment() then
  8671.         T:equip("right", "minecraft:diamond_hoe", 0) -- equip hoe and put crafting chest into inventory
  8672.         T:dropItem("crafting", "down")
  8673.         utils.goBack(1)
  8674.         T:turnRight(1)
  8675.     else
  8676.         return {"Unable to equip hoe."}
  8677.     end
  8678.  
  8679.    
  8680.     -- check if crops already planted
  8681.     local isReady, crop, status = lib.isCropReady("forward")
  8682.     local watch = true  -- assume watching farm already planted
  8683.     if crop == "" then  -- nothing has been planted
  8684.         watch = false-- not watching, continue with planting
  8685.         pp.itemColours = {colors.lightGray, colors.red, colors.orange, colors.brown}
  8686.         crops = {"minecraft:wheat_seeds", "minecraft:beetroot_seeds", "minecraft:carrots", "minecraft:potatoes"}
  8687.         choices = {"wheat (seeds)", "beetroot (seeds)", "carrot", "potato"}
  8688.         choice = menu.menu("Choose preferred crop", choices, pp, "Type number of your choice")
  8689.         crop = crops[choice]
  8690.         T:checkInventoryForItem({crop}, {95}, true, "Do not mix! add as many as you want")
  8691.     end
  8692.  
  8693.     while true do -- start infinite loop of watching crops, farming all modules
  8694.         if watch then -- not already in inventory
  8695.             crop = lib.watchFarm() --waits if required, returns crop type when ripe
  8696.         end
  8697.         print("Beginning "..crop.." management")
  8698.         local isFarmToRight, isFarmToFront = lib.harvest(crop)
  8699.         if isFarmToRight then
  8700.             lib.farmToRight() -- no action if no farmToRight
  8701.             lib.returnToLeft() -- return home and continue with front
  8702.             isFarmToRight = false
  8703.         end
  8704.        
  8705.         if isFarmToFront then
  8706.             isFarmToRight = lib.farmInFront()
  8707.             if isFarmToRight then
  8708.                 lib.farmToRight() -- no action if no farmToRight
  8709.                 lib.returnToLeft() -- return home
  8710.             end
  8711.             lib.returnToBack()
  8712.         end
  8713.         if not R.auto then -- not started from startup.lua
  8714.             T:go("L1F1")
  8715.             while T:suck("down") do end                     -- recover items from storagebelow
  8716.             T:equip("right", "minecraft:crafting_table", 0) -- equip crafting_table
  8717.             T:dropItem("diamond_hoe", "down")               -- drop hoe into storage
  8718.             T:dropItem("crafting", "down")                  -- in case spare one picked by mistake
  8719.             utils.goBack(1)
  8720.             T:turnRight(1)
  8721.             return {"Crop management of all modules completed"}
  8722.         end
  8723.     end
  8724.     return {}
  8725. end
  8726.  
  8727. local function manageFarmSetup(R) -- 33
  8728.     local lib = {}
  8729.    
  8730.     function lib.disableAutostart()
  8731.         if fs.exists("start.txt") then
  8732.             fs.delete("start.txt")
  8733.         end
  8734.         if fs.exists("startup.lua") then
  8735.             fs.delete("startup.lua")
  8736.         end
  8737.     end
  8738.    
  8739.     function lib.enableAutostart()
  8740.         if not fs.exists("startup.lua") then
  8741.             local h = fs.open("startup.lua", "w")
  8742.             h.writeLine('function main()')
  8743.             h.writeLine('   if fs.exists("start.txt") then')
  8744.             h.writeLine('       local handle = fs.open("start.txt", "r")')
  8745.             h.writeLine('       local cmd = handle.readLine()')
  8746.             h.writeLine('       handle.close()')
  8747.             h.writeLine('       shell.run("tk.lua "..cmd)')
  8748.             h.writeLine('   end')
  8749.             h.writeLine('end')
  8750.             h.writeLine('main()')
  8751.             h.close()
  8752.         end
  8753.         local h = fs.open("start.txt", "w")
  8754.         if R.data == "farm" then
  8755.             h.writeLine('farm')
  8756.         end
  8757.         h.close()
  8758.         print("Startup files written")
  8759.     end
  8760.    
  8761.     T:clear()
  8762.     --local pp = utils.getPrettyPrint()
  8763.     local choices = {"Plant or harvest this farm complex"}
  8764.     local isManaged = fs.exists("start.txt")
  8765.     if isManaged then
  8766.         table.insert(choices, "Disable automatic farm management")
  8767.     else
  8768.         table.insert(choices, "Enable automatic farm management")
  8769.     end
  8770.     pp.itemColours = {colors.lime, colors.lightGray}
  8771.     local userChoice, modifier = menu.menu("Choose your option", choices, pp) -- 1 to 2
  8772.     if modifier == "q" then -- quit chosen
  8773.         return {"Player has quit"}
  8774.     end
  8775.     R.subChoice = userChoice
  8776.     if R.subChoice == 1 then -- harvest now
  8777.         R.silent = false
  8778.         R.data = "farm"
  8779.         R.auto = false
  8780.         return manageFarm(R)
  8781.     else -- enable/disable auto farm
  8782.         local line = menu.clear()
  8783.         if isManaged then
  8784.             local message = ( "This turtle has been configured to"..
  8785.                               "start automatically and run the farm"..
  8786.                               "management program.\n")
  8787.             line = menu.colourText(line, message, true, true)
  8788.             if menu.getBoolean("Do you want to disable this? (y/n)", line, colors.yellow, colors.black) then
  8789.                 lib.disableAutostart()
  8790.             end
  8791.             return {"Autostart disabled. Reboot to activate"}
  8792.         else -- not managed
  8793.             local message = ( "~yellow~This turtle can be configured to be\n"..
  8794.                               "a dedicated farm manager.\n\n"..
  8795.                               "~lightGray~It will then start automatically and\n"..
  8796.                               "monitor the farm complex:\n\n"..
  8797.                               "~green~harvesting~yellow~ and ~lime~replanting ~yellow~continuously.\n")
  8798.             line = menu.colourText(line, message, true, true)
  8799.             if menu.getBoolean("Do you want to enable this? (y/n)", line + 2, colors.orange, colors.black) then
  8800.                 lib.enableAutostart()
  8801.             else
  8802.                 return {"Player cancelled operation"}
  8803.             end
  8804.             return {"Autostart enabled. Reboot to activate"}
  8805.         end
  8806.     end
  8807.    
  8808.     return {}
  8809. end
  8810.  
  8811. local function measure(R) -- 101
  8812.     -- measure height/ depth / length
  8813.     local lib = {}
  8814.    
  8815.     function lib.checkBlocks(R, blocks)
  8816.         local dimension = "height"
  8817.         local message = ""
  8818.         local measure = ""
  8819.         local doContinue = true
  8820.         if R.choice == 102 then
  8821.             dimension = "depth"
  8822.         elseif R.choice == 103 then
  8823.             dimension = "length"
  8824.         end
  8825.         blocks = blocks + 1
  8826.         if blocks > R.size then
  8827.             message = "Max "..dimension.." of "..R.size.." stopped measurement"
  8828.             measure = ""
  8829.             doContinue = false
  8830.         else
  8831.             measure = dimension.." measured: "..blocks.." blocks"
  8832.         end
  8833.         return doContinue, blocks, measure, message
  8834.     end
  8835.    
  8836.     local blocks = 1
  8837.     local method = ""
  8838.     local measure = ""
  8839.     local message = ""
  8840.     local doContinue = true
  8841.     if R.choice == 101 then             -- height
  8842.         if R.subChoice == 1 then        -- obstruction above
  8843.             method = "Method: Until obstruction above"
  8844.             while turtle.up() and doContinue do
  8845.                 doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8846.             end
  8847.         elseif R.subChoice == 2 then    -- end of blocks in front of turtle eg cliff, wall
  8848.             method = "Method: Until no block detected in front"
  8849.             while turtle.detect() and doContinue do
  8850.                 if turtle.up() then
  8851.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8852.                 else
  8853.                     message = "Obstruction above stopped measurement"
  8854.                     measure = ""
  8855.                     doContinue = false
  8856.                 end
  8857.             end
  8858.         elseif R.subChoice == 3 then    -- search for specific block min 3 characters
  8859.             method = "Method:Until search: '"..R.data.."' met"
  8860.             while turtle.detect() and doContinue do
  8861.                 if turtle.up() then
  8862.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8863.                     if doContinue then
  8864.                         local blockType = T:getBlockType("forward")
  8865.                         if blockType:find(R.data) ~= nil then
  8866.                             measure = "Height measured: "..blocks.." blocks"
  8867.                             message = "Found "..blockType
  8868.                             doContinue = false
  8869.                         end
  8870.                     end
  8871.                 else
  8872.                     message = "Obstruction above stopped measurement"
  8873.                     measure = ""
  8874.                     doContinue = false
  8875.                 end
  8876.             end
  8877.         elseif R.subChoice == 4 then    -- When block above changes eg dragon tower height
  8878.             local blockType = T:getBlockType("up")
  8879.             local compare = blockType
  8880.             method = "Method: Until "..blockType.." changes"
  8881.             while blockType == compare and doContinue do
  8882.                 T:up(1)
  8883.                 doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8884.                 if doContinue then
  8885.                     blockType = T:getBlockType("up")
  8886.                 end
  8887.             end
  8888.             measure = "Height measured: "..blocks.." blocks"
  8889.             message = "Found "..blockType
  8890.         end
  8891.        
  8892.         for i = 1, blocks do
  8893.             turtle.down()
  8894.         end
  8895.     elseif R.choice == 102 then -- depth
  8896.         T:go("F1R2D1") -- go off the edge and face cliff/pit wall
  8897.         blocks = blocks + 1
  8898.         if R.subChoice == 1 then        -- obstruction water / lava below
  8899.             local move = true
  8900.             while move do
  8901.                 local blockType = T:getBlockType("down")
  8902.                 if blockType:find("water") ~= nil or blockType:find("lava") ~= nil then
  8903.                     message1 = blockType.." found at "..blocks
  8904.                     move = false
  8905.                 else
  8906.                     move = turtle.down()
  8907.                     if move then
  8908.                         blocks = blocks + 1
  8909.                     else
  8910.                         measure = "Depth measured: "..blocks.." blocks"
  8911.                     end
  8912.                 end
  8913.             end
  8914.             method = "Method: Until obstruction below"
  8915.         elseif R.subChoice == 2 then    -- end of wall in front`
  8916.             while turtle.detect() do
  8917.                 if turtle.down() then
  8918.                     blocks = blocks + 1
  8919.                     measure = "Depth measured: "..blocks.." blocks"
  8920.                 else
  8921.                     message1 = "Obstruction below stopped measurement"
  8922.                     break
  8923.                 end
  8924.             end
  8925.             method = "Method: Until no block detected ahead"
  8926.         elseif R.subChoice == 3 then    -- specific block detected ahead
  8927.             method = "Method:Until search: '"..R.data.."' met"
  8928.             while turtle.detect() do
  8929.                 if turtle.down() then
  8930.                     blocks = blocks + 1
  8931.                     local blockType = T:getBlockType("forward")
  8932.                     if blockType:find(R.data) ~= nil then
  8933.                         measure = "Depth measured: "..blocks.." blocks"
  8934.                         message = "Found "..blockType
  8935.                         break
  8936.                     end
  8937.                 else
  8938.                     message = "Obstruction below stopped measurement"
  8939.                     break
  8940.                 end
  8941.             end
  8942.         end
  8943.         for i = 1, blocks do
  8944.             turtle.up()
  8945.         end
  8946.         T:go("F1R2")
  8947.     elseif R.choice == 103 then -- length
  8948.         if R.subChoice == 1 then        -- obstruction ahead
  8949.             method = "Method: Until obstruction ahead"
  8950.             while turtle.forward() and doContinue  do
  8951.                 doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8952.             end
  8953.         elseif R.subChoice == 2 then    -- end of ceiling above
  8954.             method = "Method: Until no block detected above"
  8955.             while turtle.detectUp() and doContinue do
  8956.                 if turtle.forward() then
  8957.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8958.                 else
  8959.                     message = "Obstruction ahead stopped measurement"
  8960.                     measure = ""
  8961.                     doContinue = false
  8962.                 end
  8963.             end
  8964.         elseif R.subChoice == 3 then    -- end of floor below
  8965.             method = "Method: Until no block detected below"
  8966.             while turtle.detectDown() and doContinue do
  8967.                 if turtle.forward() then
  8968.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8969.                 else
  8970.                     message = "Obstruction ahead stopped measurement"
  8971.                     measure = ""
  8972.                     doContinue = false
  8973.                 end
  8974.             end
  8975.         elseif R.subChoice == 4 then    -- search for specific block up min 3 characters
  8976.             method = "Method:Until search: '"..R.data.."' above met"
  8977.             while turtle.detectUp() and doContinue do
  8978.                 if turtle.forward() then
  8979.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  8980.                     if doContinue then
  8981.                         local blockType = T:getBlockType("up")
  8982.                         if blockType:find(R.data) ~= nil then
  8983.                             message = "Found "..blockType
  8984.                             measure = "Length measured: "..blocks.." blocks"
  8985.                             doContinue = false
  8986.                         end
  8987.                     end
  8988.                 else
  8989.                     message = "Obstruction ahead stopped measurement"
  8990.                     measure = ""
  8991.                     doContinue = false
  8992.                 end
  8993.             end
  8994.         elseif R.subChoice == 5 then    -- search for specific block down min 3 characters
  8995.             method = "Method:Until search: '"..R.data.."' below met"
  8996.             --while turtle.detectDown() and doContinue do
  8997.             while doContinue do
  8998.                 if turtle.forward() then
  8999.                     doContinue, blocks, measure, message = lib.checkBlocks(R, blocks)
  9000.                     if doContinue then
  9001.                         local blockType = T:getBlockType("down")
  9002.                         if blockType:find(R.data) ~= nil then
  9003.                             message = "Found "..blockType
  9004.                             measure = "Length measured: "..blocks.." blocks"
  9005.                             doContinue = false
  9006.                         end
  9007.                     end
  9008.                 else
  9009.                     message = "Obstruction ahead stopped measurement"
  9010.                     measure = ""
  9011.                     doContinue = false
  9012.                 end
  9013.             end
  9014.         end
  9015.         T:turnRight(2)  -- head home
  9016.         for i = 1, blocks do
  9017.             turtle.forward()
  9018.         end
  9019.         T:turnRight(2)
  9020.     elseif R.choice == 104 then -- depth of stretch of water
  9021.         --R.length = 0 to auto calculate
  9022.         R.width = 1
  9023.         R.silent = true
  9024.         R.useBlockType = ""
  9025.         R.data = "clearWaterPlants"
  9026.         local data = clearWaterPlants(R)
  9027.         R.height = data[1]
  9028.         local length = data[2]
  9029.         T:go ("R2F"..length - 1 .."R2U1")
  9030.         return {"Greatest depth measured: ".. R.height,"Width of water: "..R.length}
  9031.     end
  9032.     if message == "" then
  9033.         return{method, measure}
  9034.     else
  9035.         return{method, measure, message}
  9036.     end
  9037. end
  9038.  
  9039. local function mineBedrockArea(R) -- 19
  9040.     --[[
  9041.     Assume on level 5 or -59
  9042.     for 1, width do
  9043.         for 1, length do
  9044.             go down until bedrock, digging/replacing all directions
  9045.             return to 5 / -59
  9046.             move forward 1 blocks
  9047.         end
  9048.         turn right/ forward 2 turn right
  9049.     end
  9050.     ]] 
  9051.     local lib = {}
  9052.    
  9053.     function lib.clearColumn(R)
  9054.         local level = 0
  9055.         --T:go("L1x1R2x1L1")
  9056.         local success = T:down(1)
  9057.         while success do
  9058.             level = level + 1
  9059.             if R.data == "leaveExposed" then
  9060.                 T:go("R1x1R1x1R1x1R1x1", false, 0, true)
  9061.             else
  9062.                 T:go("R1C1R1C1R1C1R1C1", false, 0, true)
  9063.             end
  9064.             success = T:down(1)
  9065.         end
  9066.         if R.data == "leaveExposed" then
  9067.             T:go("U"..level)
  9068.         else
  9069.             T:go("U"..level.."C2")
  9070.         end
  9071.     end
  9072.    
  9073.     local goRight = true
  9074.     for i = 1, R.width do
  9075.         for j = 1, R.length do
  9076.             lib.clearColumn(R)
  9077.             T:forward(1)
  9078.         end
  9079.         if goRight then
  9080.             T:go("R1F1R1")
  9081.         else
  9082.             T:go("L1F1L1")
  9083.         end
  9084.         goRight = not goRight
  9085.     end
  9086.     return {}
  9087. end
  9088.  
  9089. local function oceanMonumentColumns(R)
  9090.     -- utility to find corners and build columns to surface
  9091.     local lib = {}
  9092.    
  9093.     function lib.buildColumn()
  9094.         local depth = 0
  9095.         while T:isWater("forward") do
  9096.             T:go("U1C2")
  9097.             depth = depth + 1
  9098.         end
  9099.         return depth
  9100.     end
  9101.    
  9102.     function lib.buildTower()
  9103.         T:go("F1C2 F1C2 F1C2")
  9104.         T:go("L1F1 L1C2 F1C2 F1C2 F1C2")
  9105.         T:go("R1F1 R1C2 F1C2 F1C2 F1C2")
  9106.         T:go("L1F1 L1C2 F1C2 F1C2 F1C2")
  9107.        
  9108.         T:go("R2")
  9109.         for i = 1, 4 do
  9110.             T:go("U1C2")
  9111.             for j = 1, 4 do
  9112.                 T:go("F1C2 F1C2 F1C2 R1")
  9113.             end
  9114.         end
  9115.     end
  9116.    
  9117.     R.silent = true
  9118.     local blockType = T:getBlockType("down")
  9119.     while blockType:find("water") == nil do
  9120.         T:down(1) -- if on a platform will break through
  9121.         blockType = T:getBlockType("down")
  9122.     end
  9123.     --R.useBlockType = "prismarine", R.data = "oceanMonumentColumns" from getTask
  9124.     --local tempData = R.data
  9125.     --R.data = "clearWaterPlants"
  9126.     local result = clearWaterPlants(R)[1]
  9127.     if result ~= "" then
  9128.         return {result}
  9129.     else
  9130.         --on corner of monument, facing out to ocean
  9131.         local depth = lib.buildColumn()
  9132.         -- now above surface, block below at surface level
  9133.         for i = 1, 4 do
  9134.             T:turnRight(1)
  9135.             R.length = 57
  9136.             utils.createPath(R) -- roughly at next corner
  9137.             if i < 4 then
  9138.                 T:down(depth-2) -- roughly at correct depth
  9139.                 local waterBelow = utils.clearVegetation("down")
  9140.                 while waterBelow do
  9141.                     T:down(1)
  9142.                     waterBelow = utils.clearVegetation("down")
  9143.                 end
  9144.                 blockType = T:getBlockType("down")
  9145.                 while blockType:find("prismarine") ~= nil do
  9146.                     T:forward(1)
  9147.                     blockType = T:getBlockType("down")
  9148.                 end
  9149.                 turtle.back()
  9150.                 depth = lib.buildColumn()
  9151.             end
  9152.         end
  9153.         -- completed retaining paths. Build small tower for easy access
  9154.         lib.buildTower()
  9155.     end
  9156.    
  9157.     return {}
  9158. end
  9159.  
  9160. local function placeRedstoneTorch(R) -- 91, 92
  9161.     local moves = 2
  9162.     local blockType = T:getBlockType("down")
  9163.     if R.data == "level" then
  9164.         T:turnLeft(1)
  9165.         utils.goBack(1)
  9166.         if blockType:find("rail") ~= nil then
  9167.              moves = 3
  9168.         end
  9169.         T:down(moves)
  9170.         T:go("F1R1")
  9171.         --clsTurtle.place(self, blockType, damageNo, direction, leaveExisting)
  9172.         T:place(R.useBlockType, -1, "forward", false)
  9173.         utils.goBack(1)
  9174.         T:place("minecraft:redstone_torch", -1, "forward", true)
  9175.         T:turnLeft(1)
  9176.         utils.goBack(1)
  9177.         T:up(moves)
  9178.         T:go("F1R1F1")
  9179.     elseif R.data == "up" then -- sloping rail up/down is relative to dirtection facing
  9180.         moves = 3
  9181.         T:turnLeft(1)
  9182.         utils.goBack(1)
  9183.         if blockType:find("rail") ~= nil then
  9184.              moves = 4
  9185.         end
  9186.         T:down(moves)
  9187.         T:go("F1L1")
  9188.         T:place("minecraft:redstone_torch", -1, "up", false)
  9189.        
  9190.         T:turnRight(1)
  9191.         utils.goBack(1)
  9192.         T:up(moves)
  9193.         T:go("F1R1")
  9194.     end
  9195.     return {}
  9196. end
  9197.  
  9198. local function plantTreefarm(R) -- 23
  9199.     --T:place(blockType, damageNo, direction, leaveExisting, signText)
  9200.     local lib = {}
  9201.    
  9202.     function lib.checkSaplings(saplings, firstChoice, secondChoice)
  9203.         local saplingSlot, sapling, count = T:getSaplingSlot(firstChoice)
  9204.         if count < 4  and secondChoice ~= "" then
  9205.             saplingSlot, sapling, count = T:getSaplingSlot(secondChoice)
  9206.         end
  9207.         if count == 0 then
  9208.             sapling = ""
  9209.         end
  9210.        
  9211.         return sapling, count
  9212.     end
  9213.    
  9214.     function lib.getSaplingInventory()
  9215.         local saplings = {}
  9216.         saplings.oak_sapling = 0
  9217.         saplings.spruce_sapling = 0
  9218.         saplings.birch_sapling = 0
  9219.         saplings.jungle_sapling = 0
  9220.         saplings.acacia_sapling = 0
  9221.         saplings.dark_oak_sapling = 0
  9222.  
  9223.         local firstChoice = ""
  9224.         local firstCount = 0
  9225.         local secondChoice  = ""
  9226.         local secondCount = 0
  9227.         for i = 1, 16 do
  9228.             if turtle.getItemCount(i) > 0 then
  9229.                 local data = turtle.getItemDetail(i)
  9230.                 if data.name:find("sapling") ~= nil then
  9231.                     local name = data.name:sub(11) -- removes "minecraft:"
  9232.                     saplings[name] = saplings[name] + data.count
  9233.                 end
  9234.             end
  9235.         end
  9236.        
  9237.         for sapling, count in pairs(saplings) do
  9238.             if count > firstCount then
  9239.                 firstCount = count
  9240.                 firstChoice = sapling
  9241.             else
  9242.                 if count > secondCount then
  9243.                     secondCount = count
  9244.                     secondChoice = sapling
  9245.                 end
  9246.             end
  9247.         end
  9248.         return saplings, firstChoice, secondChoice -- table, "oak_sapling", "dark_oak_sapling"
  9249.     end
  9250.    
  9251.     function lib.createIsland(sapling, count, exit)
  9252.         -- place 4 dirt with saplings on all 4 unless jungle
  9253.         -- sapling count/type already checked
  9254.         T:forward(2) -- assume starting outside planting area
  9255.         for i = 1, 4 do
  9256.             T:go("R1F1")
  9257.             T:place("dirt", -1, "down", false)
  9258.         end
  9259.         T:up(1)
  9260.         if count >= 4 then
  9261.             for i = 1, 4 do
  9262.                 T:go("R1F1")
  9263.                 T:place(sapling, -1, "down", false)
  9264.             end
  9265.         else
  9266.             if sapling:find("dark") == nil and sapling ~= "" then
  9267.                 T:place(sapling, -1, "down", false)
  9268.             end
  9269.         end
  9270.         if exit == "forward" then
  9271.             T:go("F1D1")
  9272.         elseif exit == "right" then
  9273.             T:go("R1F2D1")
  9274.         elseif exit == "left" then
  9275.             T:go("L1F1D1")
  9276.         elseif exit == "back" then
  9277.             T:go("R2F2D1")
  9278.         end
  9279.     end
  9280.    
  9281.     function lib.createSingle(sapling, exit)
  9282.         -- place single dirt with sapling on top
  9283.         -- sapling count/type already checked
  9284.         T:place("dirt", -1, "down", false)
  9285.         T:up(1)
  9286.         if not T:place(sapling, -1, "down", false) then -- try specific sapling
  9287.             T:place("sapling", -1, "down", false)       -- any available sapling
  9288.         end
  9289.         if exit == "forward" then
  9290.             T:go("F1D1")
  9291.         elseif exit == "right" then
  9292.             T:go("R1F1D1")
  9293.         elseif exit == "left" then
  9294.             T:go("L1F1D1")
  9295.         elseif exit == "back" then
  9296.             T:go("R2F1D1")
  9297.         end
  9298.     end
  9299.  
  9300.     local saplings, firstChoice, secondChoice = lib.getSaplingInventory()
  9301.  
  9302.     if firstChoice ~= "" then
  9303.         print("first sapling choice: "..firstChoice .. " ("..saplings[firstChoice]..")")
  9304.     end
  9305.     if secondChoice ~= "" then
  9306.         print("second sapling choice: "..secondChoice .. " ("..saplings[secondChoice]..")")
  9307.     end
  9308.  
  9309.     -- check type/size of farm
  9310.     if R.subChoice == 1 then -- 16 single trees
  9311.         local sapling, count = lib.checkSaplings(saplings, firstChoice, secondChoice)
  9312.         T:go("U1F4") -- outside first area
  9313.         for i = 1, 3 do -- column 1/4
  9314.             lib.createSingle(sapling, "forward")
  9315.             T:forward(1)
  9316.         end
  9317.         for i = 1, 2 do
  9318.             lib.createSingle(sapling, "right") -- place 4th dirt/saling and exit to right
  9319.             T:forward(1)
  9320.         end
  9321.         for i = 1, 2 do -- column 2/4
  9322.             lib.createSingle(sapling, "forward")
  9323.             T:forward(1)
  9324.         end
  9325.         for i = 1, 2 do
  9326.             lib.createSingle(sapling, "left") -- place 4th dirt/saling and exit to right
  9327.             T:forward(1)
  9328.         end
  9329.         for i = 1, 2 do -- column 3/4
  9330.             lib.createSingle(sapling, "forward")
  9331.             T:forward(1)
  9332.         end
  9333.         for i = 1, 2 do
  9334.             lib.createSingle(sapling, "right") -- place 4th dirt/saling and exit to right
  9335.             T:forward(1)
  9336.         end
  9337.         for i = 1, 3 do -- column 4/4
  9338.             lib.createSingle(sapling, "forward")
  9339.             T:forward(1)
  9340.         end
  9341.         T:go("R1F6L1F2R2D1")   
  9342.     elseif R.subChoice == 2 then -- 4 double trees (4 saplings)
  9343.         -- assume placed 4 blocks from start
  9344.         local sapling, count = lib.checkSaplings(mostName, secondMostName)
  9345.        
  9346.         if count >= 4 then
  9347.             T:go("U1F3") -- outside first area
  9348.             lib.createIsland(sapling, count, "forward")
  9349.             sapling, count = lib.checkSaplings(mostName, secondMostName)
  9350.             T:go("F2")
  9351.             lib.createIsland(sapling, count, "right")
  9352.             sapling, count = lib.checkSaplings(mostName, secondMostName)
  9353.             T:go("F2")
  9354.             lib.createIsland(sapling, count,  "right")
  9355.             sapling, count = lib.checkSaplings(mostName, secondMostName)
  9356.             T:go("F2")
  9357.             lib.createIsland(sapling, count, "forward")
  9358.             T:go("R1D1F6L1F3R2") -- outside first area
  9359.         else
  9360.             return {"Insufficient saplings to plant"}
  9361.         end
  9362.     end
  9363.     return {}
  9364. end
  9365.  
  9366. local function quickMine(R) -- 17
  9367.     --[[
  9368.     mine valuable blocks from specified area
  9369.     if R.up set or lava/water found, ceiling is formed
  9370.     if R.down is set, or lava/water found layer is kept 1 block high
  9371.     R.subChoice
  9372.     1 At mine area start, on the floor
  9373.     2 At mine area start, on the ceiling
  9374.     3 On floor, start 1 block ahead
  9375.     4 On ceiling, start 1 block ahead
  9376.     5 On floor diagonally to left"
  9377.     ]]
  9378.     local lib = {}
  9379.    
  9380.     function lib.refuel(direction)
  9381.         if T:getWater(direction)  then
  9382.             T:refuel(1000, false)
  9383.         end
  9384.     end
  9385.    
  9386.     function lib.mine(R)
  9387.         -- starts on ceiling
  9388.         local isValuable, blockType
  9389.         for i = 1, R.length do
  9390.             local fillUp = R.up
  9391.             local fillDown = R.down
  9392.             isValuable, blockType = T:isValuable("down")
  9393.             if isValuable then
  9394.                 T:dig("down")
  9395.             elseif blockType:find("water") ~= nil then
  9396.                 fillDown = true
  9397.             elseif blockType:find("lava") ~= nil then
  9398.                 lib.refuel("down")
  9399.                 fillDown = true
  9400.             end
  9401.             isValuable, blockType = T:isValuable("up")
  9402.             if isValuable then
  9403.                 T:dig("up")
  9404.             elseif blockType:find("water") ~= nil then
  9405.                 fillUp = true
  9406.             elseif blockType:find("lava") ~= nil then
  9407.                 lib.refuel("up")
  9408.                 fillUp = true
  9409.             end
  9410.             --if not turtle.detectUp() and fillUp then
  9411.             if fillUp then
  9412.                 T:fillVoid("up")
  9413.             end
  9414.             --if not turtle.detectDown() and fillDown then
  9415.             if fillDown then
  9416.                 T:fillVoid("down")
  9417.             end
  9418.             if i < R.length then
  9419.                 T:forward(1)
  9420.             end
  9421.         end
  9422.     end
  9423.    
  9424.     local outbound = true
  9425.    
  9426.     if R.subChoice == 1 then
  9427.         T:up(1)
  9428.     elseif R.subChoice == 3 then
  9429.         T:go("U1F1")
  9430.     elseif R.subChoice == 4 then
  9431.         T:go("F1")
  9432.     elseif R.subChoice == 5 then
  9433.         T:go("U1R1 F1L1 F1")
  9434.     end
  9435.    
  9436.     for w = 1, R.width do
  9437.         lib.mine(R)
  9438.         if w < R.width then
  9439.             if outbound then
  9440.                 T:go("R1F1R1")
  9441.             else
  9442.                 T:go("L1F1L1")
  9443.             end
  9444.             outbound = not outbound
  9445.         end
  9446.         if T:getFirstEmptySlot() == 0 then
  9447.             T:dumpRefuse("forward", 1)
  9448.         end
  9449.     end
  9450.     if outbound then
  9451.         T:go("L1F"..R.width - 1 .."L1F"..R.length - 1)
  9452.     else
  9453.         T:go("R1F"..R.width - 1 .."R1")
  9454.     end
  9455.    
  9456.     return {}
  9457. end
  9458.  
  9459. local function quickMineCorridor(R) -- 16
  9460.     --[[
  9461.     R.subChoice
  9462.     1: At corridor start, on the floor
  9463.     2: At corridor start, on the ceiling
  9464.     3: On floor, start 1 block ahead
  9465.     4: On ceiling, start 1 block ahead
  9466.     ]]
  9467.     if R.subChoice == 2 then
  9468.         T:down(1)
  9469.     elseif R.subChoice == 3 then
  9470.         T:forward(1)
  9471.     elseif R.subChoice == 4 then
  9472.         T:go("D1F1")
  9473.     end
  9474.     local width = R.width - 1
  9475.     local length = R.length - 1
  9476.     R.silent = true
  9477.     R.length = length
  9478.     createCorridor(R, true) -- put floor and ceiling for R.length, place torch at start
  9479.     T:turnRight(1)
  9480.     R.length = width
  9481.     createCorridor(R, true)
  9482.     T:turnRight(1)
  9483.     R.length = length
  9484.     createCorridor(R, true)
  9485.     T:turnRight(1)
  9486.     R.length = width
  9487.     createCorridor(R, true)
  9488.     T:turnRight(1)
  9489.    
  9490.     return {}
  9491. end
  9492.  
  9493. local function repairWall(startAt, height, width, replaceWith)
  9494.     -- go up to startAt
  9495.    
  9496.     -- if width = 1
  9497.    
  9498.         -- for h = startAt, height, 1 do
  9499.        
  9500.             -- replace block with replaceWith ("" = any)
  9501.            
  9502.             -- move up
  9503.            
  9504.         --end
  9505.        
  9506.         -- move back to beginning
  9507.        
  9508.     -- else
  9509.    
  9510.         -- remain = height % 2
  9511.        
  9512.         -- for w = 1, width - remain do
  9513.        
  9514.             -- for h = startAt, height, 1 do
  9515.            
  9516.                 -- replace block with replaceWith ("" = any)
  9517.                
  9518.                 -- move up
  9519.                
  9520.             --end
  9521.            
  9522.             -- move to the right 1 block
  9523.            
  9524.             -- for i = height, startAt, -1 do
  9525.            
  9526.                 -- replace block with replaceWith ("" = any)
  9527.                
  9528.                 -- move down
  9529.                
  9530.             --end
  9531.            
  9532.         -- end
  9533.        
  9534.     -- end
  9535.    
  9536. end
  9537.  
  9538. local function getTaskItemsList()
  9539.     -- list of items required for each task
  9540.     local text = {}
  9541.     --MINING
  9542.     text[11] = {"1 ladder for each level","levels / 4 torch (optional)","levels * 4 stone"}             -- ladder to bedrock
  9543.     text[12] = {"2 stairs for each level", "6 * levels stone", "1 chest"}                               -- stairs up/down
  9544.     text[13] = {"24 torch (optional)", "1 bucket (optional)", "64 stone", "1 chest"}                    -- mine at this level
  9545.     text[14] = {"levels * 4 stone","water_bucket"}                                                      -- safe drop to water block
  9546.     text[15] = {"levels * 4 stone", "1 soul sand", "1 water bucket"}                                    -- single column bubble lift
  9547.     text[16] = {"1 bucket (optional)", "64 stone"}                                                      -- quick corridor
  9548.     text[17] = {"1 bucket (optional)", "64 stone"}                                                      -- quick mine
  9549.     text[18] = {"1 bucket (optional)"}                                                                  -- mine to bedrock
  9550.     text[19] = {"1 UNUSED diamond sword (optional)"}                                                    -- rob mineshaft
  9551.  
  9552.     -- FORESTRY
  9553.     text[21] = {"1 chest (optional)"}                                                                   -- Fell Tree
  9554.     text[22] = {"320 stone", "4 polished stone"}                                                        -- Create treefarm
  9555.     text[23] = {"min 4 saplings", "16 dirt"}                                                            -- plant treefarm
  9556.     text[24] = {"No items required"}                                                                    -- Harvest treefarm
  9557.     text[25] = {"width * length * 2 walls or fences", "torches (optional)", "4 barrels (optional)"}     -- fence or wall a forest
  9558.     text[26] = {"1 chest", " any saplings"}                                                             -- harvest and replant walled rectangle of natural forest
  9559.                
  9560.     -- FARMING         
  9561.     text[31] = {"64 stone","128 dirt (optional)", "4 water buckets","4 chests / barrels","1 sapling"}   -- Create modular crop farm
  9562.     text[32] = {"64 stone","128 dirt (optional)", "4 water buckets","5 chests/ barrels","1 sapling"}    -- extend modular farm
  9563.     text[33] = {"No items required"}                                                                    -- Manual harvest and auto setup
  9564.     text[34] = {"Walls or Fences", "Torches (optional)"}                                                -- Build a wall or fence
  9565.     text[35] = text[34]                                                                                 -- Wall or fence enclosed area
  9566.  
  9567.     -- OBSIDIAN
  9568.     text[41] = {"stone to cover area of obsidian"}                                                      -- Harvest obsidian
  9569.     text[42] = {"2 x height + width obsidian", "4 stone"}                                               -- build Nether portal
  9570.     text[43] = {"No items required"}                                                                    -- demolish Nether portal
  9571.     text[44] = {"length * 4 stone/netherrack, bucket"}                                                  -- Netherite stripping
  9572.     text[45] = {"84 stone"}                                                                             -- undermine dragon towers
  9573.     text[46] = {"No items required"}                                                                    -- deactivate dragon tower
  9574.     text[47] = {"448 stone, 145 ladders, 1 obsidian, 1 water bucket"}                                   -- dragon water trap
  9575.     text[48] = {"height * 4 stone","height * ladders", "1 trapdoor"}                                    -- build end portal platform
  9576.                
  9577.     --CANALS BRIDGES WALKWAYS
  9578.     text[51] = {"dirt or stone * length","torch (optional)"}                                            -- single path
  9579.     text[52] = {"dirt or stone 2 * length","torch (optional)"}                                          -- covered path / tunnel
  9580.     text[53] = {"2 * length stone or dirt","2 water buckets","torches (optional)"}                      -- water canal
  9581.     text[54] = {"0.5 * length Packed or blue ice","length * slabs","stone","torches (optional)"}        -- Ice canal
  9582.     text[55] = {"width * length stone"}                                                                 -- platform
  9583.     text[56] = {"width + 1 * length + 1 stone"}                                                         -- sinking platform
  9584.     text[57] = {"height * 10 stone","height * 4 + 2 soul sand, 2 water buckets"}                        -- Boat bubble lift
  9585.    
  9586.     -- MOB FARM
  9587.     text[61] = {"512 stone","1 slab"}                                                                   -- 9x9 cube round spawner
  9588.     text[62] = {"640 stone","37 slab","8 powered rail","64 rail","2 redstone torch",
  9589.                 "1 hopper minecart","1 stone button"}                                                   -- 9x9 cube round blaze spawner
  9590.     text[63] = {"2 water buckets","If using bubble lift","2 fence","2 signs","1 slab",
  9591.                 "1 soul sand (or dirt as placeholder)"}                                                 -- flood spawner chamber   
  9592.     text[64] = {"128 stone","2 water buckets","1 soul sand"}                                            --Build bubble tower kill zone
  9593.     text[65] = {"1-2 computer","2 sticky or 4 normal pistons","6 network cable + 2 wired modems",
  9594.                 "23 polished stone + 7 slabs","2 glass","1 stone pressure plate","1 dispenser",
  9595.                 "1 hopper + 2 chest", "9 redstone", "1 lava bucket"}                                    --Computercraft mob grinder
  9596.     text[66] = {"1856 stone, diorite etc (inc polished)","1 chest","10 empty buckets",
  9597.                 "2 water buckets","192 fence","8 signs","3 ladder","2 soul sand"}                       -- build endermen observation tower
  9598.                
  9599.     -- AREA CARVING
  9600.     text[71] = {"width * length dirt"}                                                                  -- Clear field
  9601.     text[72] = {"No items required"}                                                                    -- Clear rectangle width, length
  9602.     text[73] = {"No items required"}                                                                    -- Clear wall height, length
  9603.     text[74] = {"No items required"}                                                                    -- Clear rectangle perimeter only width, length
  9604.     text[75] = {"No items required"}                                                                    -- Clear structure floor/walls/ceiling
  9605.     text[76] = {"No items required"}                                                                    -- clear solid
  9606.     text[77] = {"No items required"}                                                                    -- Dig a trench
  9607.     text[78] = {"No items required"}                                                                    -- carve mountain
  9608.     text[79] = {"width * height Any material floor / ceiling"}                                          -- floor or ceiling
  9609.     text[710] = {"Blocks to add 'floor as you go'"}                                                     -- Direct control of movement
  9610.                
  9611.     -- LAVA WATER
  9612.     text[81] = {"Enough sand or gravel to fill volume"}                                                 -- sand based utilities
  9613.     text[82] = {"length * depth stone"}                                                                 -- vertical wall from surface
  9614.     text[83] = {"Blocks to add 'floor as you go'"}                                                      -- player driven path construction
  9615.     text[84] = {"width * length + extra stone"}                                                         -- water clearing by repeated block deletion
  9616.     text[85] = text[84]                                                                                 -- sinking platform
  9617.     text[86] = {"Full inventories of sand or stone"}                                                    -- Ocean monument utilities
  9618.     text[87] = {"ladder to height","stone, dirt netherrack 4 X height"}                                 -- ladder to water/lava
  9619.     text[88] = {"No items required"}                                                                    -- clear water plants
  9620.     text[89] = {"water buckets / buckets"}                                                              -- convert flowing water to source
  9621.     text[810] = {"6 buckets","slabs to cover area"}                                                     -- create sloping water
  9622.                
  9623.     -- BUILDING and MINECART
  9624.     text[91] = {"length * height stone"}                                                                -- Build a wall
  9625.     text[92] = {"length * height * 4 stone"}                                                            -- build a walled area
  9626.     text[93] = {"length * width * height stairs", "length * slabs"}                                     -- build a gable roof
  9627.     text[94] = {"length * width * height stairs", "length * slabs"}                                     -- Build a pitched roof
  9628.     text[95] = {"1 block of choice","1 redstone torch"}                                                 -- place redstone torch under current block
  9629.     text[96] = {"1 block of choice","1 redstone torch"}                                                 -- place redstone torch on upward slope
  9630.     text[97] = {"height x block of choice","height/3 x redstone torch"}                                 -- build downward slope
  9631.     text[98] = text[97]                                                                                 -- build upward slope
  9632.     return text
  9633. end
  9634.  
  9635. local function getTaskHelp(menuLevel, menuItem, noMenu, getInteger)
  9636.     -- display help about selected task
  9637.     -- terminal size = 39 x 13
  9638. --[[This line of text = 39 characters]]
  9639.     noMenu = noMenu or false
  9640.     getInteger = getInteger or false
  9641.     info = {}
  9642.     info.main = {}
  9643.     info.sub = {}
  9644.     table.insert(info.main,
  9645.     [[                ~lightGray~MINING:~white~
  9646. Can be used in over-world or nether.~brown~
  9647. Ladders and ~lightGray~stairs up/down    
  9648. Create a pre-formatted 33 x 33 blocks  
  9649. mine at chosen level.
  9650. ~blue~Bubble lift and ~cyan~safe drop to water.~magenta~  
  9651. Faster version of ~white~33x33 mine pattern  
  9652. using ~magenta~corridor and ~pink~rectangle functions.~brown~
  9653. Mine bottom layer to bedrock (not worth
  9654. the fuel and time)
  9655. ~brown~Strip resources from abandoned mines.
  9656. ]])
  9657.     table.insert(info.main,
  9658.     [[               ~lime~FORESTRY:~brown~
  9659. Fell Tree can be used in Nether as well
  9660. for cutting any size tree / branches~lime~
  9661. Create a simple 16 single tree farm
  9662. or 4 double size (Dark oak or any type)
  9663. suitable for turtle harvesting.
  9664. ~brown~ fence or wall a rectangle keeping
  9665. to contours.
  9666. ~green~Forest can be harvested and replanted.
  9667. (Must be walled off)
  9668.  
  9669. ]])
  9670.     table.insert(info.main,
  9671.     [[                ~green~FARMING:~yellow~
  9672. Farm modules can be built to fixed size
  9673. and placed next to each other in linear
  9674. or rectangular pattern.~lime~
  9675. Whole farm is managed by a dedicated
  9676. turtle, which must be equipped with a
  9677. diamond hoe as well as pickaxe.
  9678. Fuel obtained from a tree placed in the
  9679. corner of each module.
  9680. Double chests store produce and seeds.
  9681. ]])
  9682.     table.insert(info.main,
  9683.     [[               ~red~OBSIDIAN:~lightGray~
  9684. The turtle can extract obsidian from
  9685. lava areas safely.~pink~
  9686. Nether portals can be built or removed
  9687. without needing diamond pickaxes.~orange~
  9688. End World dragon towers can be
  9689. undermined ready for deactivating.
  9690. End world towers can have the crystals
  9691. destroyed.~red~
  9692. Water trapped dragon attacked from above~brown~
  9693. Minecart end portal stations built.
  9694. ]])
  9695.     table.insert(info.main,
  9696.     [[        ~brown~PATHS, BRIDGES, CANALS:~white~
  9697. Can be used in Nether and End.~lightGray~
  9698. Build pathways over air, water or lava
  9699. Optional roofed pathway for Nether use.
  9700. Tunnel through rock and place a floor
  9701. at the same time.~blue~
  9702. Build a water canal with towpath.~cyan~
  9703. Build a super-fast ice canal.~brown~
  9704. Platform for use over air, water, lava
  9705. Sinking version is removed and replaced
  9706. 1 block lower each time
  9707. ]])
  9708.     table.insert(info.main,
  9709.     [[             ~lightGray~SPAWNER FARMS:~brown~
  9710. Tools to create mob farms round
  9711. existing spawners. ~red~
  9712. Special version for Blaze farms
  9713. uses rail collection.~cyan~
  9714. Choice of bubble lift mob dropper
  9715. or ~brown~simple deep trench.~gray~
  9716. Enderman observation tower can be
  9717. built >128 above ground: is ~red~expensive.~gray~
  9718. Re-spawns new mobs when used.~red~
  9719. Suggest build only the base.
  9720. ]])
  9721.     table.insert(info.main,
  9722.     [[    ~orange~AREA CLEARING AND REFORMING:~lime~
  9723. Tools to clear a field including trees~magenta~
  9724. Clear rectangles.~pink~
  9725. Clear single walls.~brown~
  9726. Clear hollow and~orange~solid structures.~brown~
  9727. Dig a trench.~gray~
  9728. Carve away side of a mountain.~lightBlue~
  9729. Place or replace floors and ceilings
  9730.  
  9731.  
  9732.  
  9733. ]])
  9734.     table.insert(info.main,
  9735.     [[      ~blue~WATER AND LAVA TOOLS:~white~
  9736. Used to drain ocean monuments and
  9737. shipwrecks. Can also be used to make
  9738. underwater base. ~blue~Water is cleared using
  9739. sand dropping and recycling~cyan~
  9740. Destructive draining uses solid block
  9741. placing and recycling.~green~
  9742. Water plants can be removed without
  9743. damaging structures.~lightBlue~
  9744. Tools to manipulate water areas:
  9745. (convert to source, sloping water)
  9746. ]])
  9747.     table.insert(info.main,
  9748.     [[         ~cyan~BUILDING, MINECART TOOLS:~lightGray~
  9749. Build simple walls, buildings and ~gray~roofs
  9750.  
  9751. ~orange~Used to build diagonal uphill slope~brown~
  9752. and downhill slope for placing
  9753. 45 degree rail tracks.~red~
  9754. Placing Redstone torches under powered
  9755. rails when above ground level (viaduct)
  9756.  
  9757.  
  9758.  
  9759. ]])
  9760.     table.insert(info.main,
  9761.     [[           ~yellow~MEASURING TOOLS:
  9762. Used to measure
  9763.     ~red~Height
  9764.     ~purple~Depth
  9765.     ~magenta~Length~pink~
  9766.    
  9767.     Greatest depth of water
  9768.  
  9769.  
  9770.  
  9771.  
  9772. ]])
  9773.  
  9774.     info.sub[11] =
  9775. [[~yellow~Place me on the ground at ~red~^~yellow~
  9776. The ~brown~ladder ~yellow~will start at this level
  9777. and go up or down.
  9778.  
  9779. ~lightGray~| | | | | |
  9780. ~lightGray~| | |*| | | * = Ladder support block
  9781. | | |~brown~L~lightGray~| | | ~brown~L = Ladder
  9782. ~lightGray~| | |~red~^~lightGray~| | | ~red~^ = Turtle
  9783. ~lightGray~| | | | | |
  9784. | | | | | |
  9785.  
  9786. ]]-- Ladder up/down
  9787.     info.sub[12] =
  9788. [[~lightGray~Place me on the ground at ~red~^
  9789.  
  9790. ~lightGray~| | | | | | | | * = Solid block
  9791. ~lightGray~| |*|*|*|*|*| | ~cyan~^ = Stairs to back
  9792. ~lightGray~| |*|-|~cyan~>~lightGray~|-|*| | ~cyan~> = Stairs to right
  9793. ~lightGray~| |*|~cyan~^|~lightGray~*|~cyan~V~lightGray~|*| | ~cyan~V = Stairs to front
  9794. ~lightGray~| |*|-|~cyan~<~lightGray~|-|*| | ~cyan~< = Stairs to left
  9795. ~lightGray~| |*|~red~^~lightGray~|*|*|*| | - = Corner tread
  9796. ~lightGray~| | | | | | | | ~red~^ = Turtle
  9797.  
  9798. ~lightGray~Going ~blue~down~lightGray~ -> digs down then stairs up
  9799. ]] -- Stairs up/down
  9800.         info.sub[13] =
  9801. [[~yellow~Press F3 to check Y level.
  9802.  
  9803. ~lightGray~| |~red~^~lightGray~| | | ~red~^ = Turtle behind ladder
  9804. ~lightGray~| |~gray~s~lightGray~| | | ~gray~s = 1 block space
  9805. ~lightGray~| |*| | | * = Ladder support block
  9806. ~lightGray~| |~brown~L~lightGray~| | | ~brown~L = Ladder
  9807. ~lightGray~| |~brown~s~lightGray~| | | ~brown~s~gray~ = 2 spaces (inc. ladder)
  9808. ~lightGray~| |~red~V~lightGray~| | | ~red~V = Turtle ahead of ladder~yellow~
  9809.  
  9810. ]]
  9811.     if bedrock == 0 then    --pre 1.18
  9812.         info.sub[13] = info.sub[13].."Place at Y = 5, 8, 11 ~red~(11 nether)" -- Create mine at this level
  9813.     else
  9814.         info.sub[13] = info.sub[13].."Place at Y = -59, -56, -53 (11 nether)" -- Create mine at this level
  9815.     end
  9816.     info.sub[14] =
  9817. [[~yellow~Turtle goes ~blue~DOWN ~yellow~to chosen level
  9818. enclosing all sides of the column.
  9819. Water placed at bottom. Returns here.
  9820. If next to a ladder, place as below:
  9821.  
  9822. ~lightGray~| | | | | |
  9823. ~lightGray~| | |*| | | * = Ladder support block
  9824. | |~red~^~brown~|L|~red~^~lightGray~| | ~brown~L = ladder
  9825. ~lightGray~| | | | | | ~red~^ = Turtle facing forward
  9826. ~lightGray~| | | | | |
  9827.            
  9828. ]] -- safe drop
  9829.     info.sub[15] =
  9830. [[~magenta~Direction of travel = UP!
  9831. ~yellow~Place me on the ground. I will build a
  9832. 3 x 1 ~blue~water ~yellow~source and a single column
  9833. bubble lift to the chosen height.
  9834. If near a ladder, place left or right:
  9835.  
  9836. ~lightGray~| | | | | |
  9837. ~lightGray~| | |*| | | * = Ladder support block
  9838. | |~blue~^~brown~|L|~blue~^~lightGray~| | ~brown~L = ladder
  9839. ~lightGray~| | | | | | ~blue~^ = Turtle facing forward
  9840. ~lightGray~| | | | | | ~blue~^ = Bubble column above
  9841.  
  9842. ]] -- single column bubble lift
  9843.     info.sub[16] =
  9844. [[~yellow~Place me as below:
  9845.  1. On ~blue~floor   ~yellow~(feet height)
  9846.  2. On ~lime~ceiling ~yellow~(eye height)
  9847.  
  9848. ~lightGray~B|B|B|B|B|B|B    ~yellow~W I D T H
  9849. ~lightGray~B| | | | | |B               ~orange~L
  9850. ~lightGray~B| |B|B|B| |B               ~orange~E
  9851. ~lightGray~B| |B|B|B| |B               ~orange~N
  9852. ~lightGray~B| |B|B|B| |B               ~orange~G
  9853. ~lightGray~B|~red~^~lightGray~| | | | |B  ~red~^~lightGray~ = Turtle   ~orange~T
  9854. ~lightGray~B|~cyan~P~lightGray~|B|B|B|B|B  ~cyan~P~lightGray~ = Player   ~orange~H
  9855. ]] -- quick corridor system
  9856.     info.sub[17] =
  9857. [[~yellow~~yellow~Place me as below:
  9858.  1. On ~blue~floor   ~yellow~(feet height)
  9859.  2. On ~lime~ceiling ~yellow~(eye height)
  9860. ~lightGray~B|B|B|B|B|B|B
  9861. B| | | | | |B
  9862. B| |B|B|B| |B
  9863. B| |B|B|B| |B
  9864. B| |~lime~^~lightGray~|B|B| |B
  9865. B|~red~^~lightGray~|~magenta~^~lightGray~| | | |B ~white~^~lightGray~ = turtle
  9866. B|~cyan~P~lightGray~|B|B|B|B|B ~cyan~P~lightGray~ = Player
  9867. ~yellow~Note colour of ~white~^~yellow~ matches next screen->
  9868. ]] -- quick mine
  9869.         info.sub[18] =
  9870. [[~yellow~Place me level -59 / 5 on the floor to
  9871. expose bedrock ~red~(slow and inefficient)
  9872.  
  9873. ~lightGray~| | | |B| |B|     ~yellow~W I D T H
  9874. ~lightGray~|B| | | | | |B               ~orange~L
  9875. ~lightGray~| | | |B|B| |                ~orange~E
  9876. ~lightGray~| | |B| | |B|                ~orange~N
  9877. ~lightGray~|B| | | |B| |                ~orange~G
  9878. ~lightGray~| | | | | | |B               ~orange~T
  9879. ~lightGray~|~red~^~lightGray~| | | |B| |B  ~red~^~lightGray~ = Turtle   ~orange~H
  9880. ]] -- mine all blocks to bedrock pre 1.12
  9881.         info.sub[19] =
  9882. [[~yellow~Place me on the end wall of a disused
  9883. mine in the centre block, 1 block above
  9884. the floor.
  9885. Provide a ~cyan~diamond ~yellow~sword for
  9886. harvesting string from spider webs~lightGray~
  9887.  
  9888. ~gray~-------   - = Ceiling
  9889. ~lightGray~| | | |
  9890. | |~red~T~lightGray~| |  ~red~T = Turtle (facing wall)
  9891. ~lightGray~| | | |
  9892. ~gray~-------  - = Floor
  9893. ]] -- salvage mineshaft
  9894.     info.sub[21] =
  9895. [[~yellow~Place me as below.
  9896. ~brown~Chest ~yellow~ONLY required if ~blue~0 ~yellow~fuel
  9897.  
  9898. Plan view:
  9899.  
  9900. ~green~   | | | |
  9901. ~green~   | |~lime~T~green~| |  ~lime~T = Tree
  9902. ~green~   | |~red~^~green~| |  ~red~^ = Turtle
  9903. ~green~   | | | |
  9904.  
  9905.  
  9906.  
  9907. ]] -- Fell Tree
  9908.     info.sub[22] =
  9909. [[~yellow~Place me on ground as below ~red~^
  9910. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | ~brown~|D| |D|
  9911. ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | ~green~or |*|~blue~ | | | | | |
  9912. ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | ~green~or |*|~blue~ | | ~brown~|D| |D|
  9913. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9914. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9915. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9916. ~lime~|~red~^~lime~|*|*|*|~blue~M~lime~|*| | ~green~or |~red~^~green~|*|*|*|~blue~M~green~|*|*|
  9917. ~lime~4 ~brown~double ~green~       or 16 ~brown~single
  9918. ~brown~D = Dirt, ~red~^ = Turtle, ~blue~M = Marker stone
  9919. ]] -- Create treefarm
  9920.     info.sub[23] =
  9921. [[~yellow~Place me on ground as below ~red~^
  9922. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | ~brown~|D| |D|
  9923. ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | ~green~or |*|~blue~ | | | | | |
  9924. ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | ~green~or |*|~blue~ | | ~brown~|D| |D|
  9925. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9926. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9927. ~lime~|*|~blue~ | | | | | | ~green~or |*|~blue~ | | | | | |
  9928. ~lime~|*|*|*|*|~red~^~lime~|*| | ~green~or |*|*|*|*|~red~^~green~|*|*|
  9929. ~green~4 ~brown~double ~green~       or 16 ~brown~single
  9930. ~brown~D = dirt,~red~^ = Turtle, ~yellow~Max 16 saplings
  9931. Mixed OK. ~lime~Group 4 for double trees
  9932. ]] -- Plant treefarm / Harvest treefarm
  9933.     info.sub[24] = info.sub[23]
  9934.     info.sub[25] =
  9935. [[~yellow~Place me at ~red~^
  9936.  
  9937. ~lightGray~|F|F|F|F|F|F|F| F = Fence or Wall
  9938. ~lightGray~|F|~brown~B~lime~| | | |~brown~B~lightGray~|F| ~brown~B = Barrel (corners)
  9939. ~lightGray~|F|~lime~ | | | | ~lightGray~|F|
  9940. ~lightGray~|F|~lime~ | | | |~cyan~T~lightGray~|F| ~cyan~T = Tree
  9941. ~lightGray~|F|~lime~ |~cyan~T~lime~| | | ~lightGray~|F|
  9942. ~lightGray~|F|~lime~ | | | | ~lightGray~|F|
  9943. ~lightGray~|F|~brown~B~lime~| |~cyan~T~lime~| |~brown~B~lightGray~|F|
  9944. ~lightGray~|~red~^~lightGray~|F|F|F|F|F|F| ~red~^ = Turtle
  9945. ~yellow~Fence/Wall follows land contours
  9946. ]] --
  9947.     info.sub[26] =
  9948. [[~yellow~A rectangular walled area of forest:
  9949. Place me at ~red~^
  9950.  
  9951. ~lightGray~|F|F|F|F|F|F|F| F = Fence or wall
  9952. ~lightGray~|F|~brown~B~lime~| | | |~brown~B~lightGray~|F| ~brown~B = Barrel (corners)
  9953. ~lightGray~|F|~lime~ | | | | ~lightGray~|F|
  9954. ~lightGray~|F|~lime~ | | | |~cyan~T~lightGray~|F| ~cyan~T = Tree
  9955. ~lightGray~|F|~lime~ |~cyan~T~lime~| | | ~lightGray~|F|
  9956. ~lightGray~|F|~lime~ | | | | ~lightGray~|F|
  9957. ~lightGray~|F|~red~^~lime~| |~cyan~T~lime~| |~brown~B~lightGray~|F| ~red~^ = Turtle ~brown~(on Barrel)
  9958. ~lightGray~|F|F|F|F|F|F|F|
  9959.  
  9960. ]] -- manage walled forest
  9961.     info.sub[31] =
  9962. [[~yellow~Place me on the ground as below ~red~^
  9963.  
  9964. ~lightGray~|*|~green~ | | | | | | | | ~lightGray~* = Wall
  9965. ~lightGray~|*|~green~ | | | | | | | |
  9966. ~lightGray~|*|~green~ | | | | | | | |
  9967. ~lightGray~|*|~green~ | | | | | | | |
  9968. ~lightGray~|*|~green~ | | | | | | | |
  9969. ~brown~|B|B~green~| | | | | | | | ~brown~B = Barrel or Chest
  9970. ~brown~|B|~blue~W~green~| | | | | | | | ~blue~W = Water
  9971. ~lime~|~red~^~lime~|~brown~B|B|~lightGray~*|*|*|*|*|*| ~red~^ = Turtle
  9972. ~yellow~                    Size = 13 x 13
  9973. ]] -- Create modular crop farm
  9974.     info.sub[32] =
  9975. [[~yellow~Place next to the tree as below ~red~^
  9976.  
  9977. ~lightGray~|*|~green~ | | | | | | | | ~lightGray~* = Wall
  9978. ~lightGray~|*|~green~ | | | | | | | |
  9979. ~lightGray~|*|~green~ | | | | | | | |
  9980. ~lightGray~|*|~green~ | | | | | | | |
  9981. ~lightGray~|*|~green~ | | | | | | | | ~brown~B = Barrel or Chest
  9982. ~brown~|B|B~green~| | | | | | | | ~blue~W = Water
  9983. ~brown~|B|~blue~W~green~| | | | | | | | ~orange~S = Sapling or Tree
  9984. ~orange~|S|~red~^~brown~|B|~lightGray~*|*|*|*|*|*| ~red~^ = Turtle
  9985. ~yellow~                    Size = 13 x 13
  9986. ]] -- Extend farm
  9987.     info.sub[33] =
  9988. [[~yellow~Place as below (2 choices) ~blue~> ~yellow~or ~red~<
  9989.  
  9990. ~lightGray~|*|~green~ | | | | | | | | ~lightGray~* = Wall
  9991. ~lightGray~|*|~green~ | | | | | | | |
  9992. ~lightGray~|*|~green~ | | | | | | | |
  9993. ~lightGray~|*|~green~ | | | | | | | | ~brown~B = Barrel or Chest
  9994. ~lightGray~|*|~green~ | | | | | | | | ~blue~> = turtle on Water
  9995. ~brown~|B|B~green~| | | | | | | | C = Crop (first)
  9996. ~brown~|B|~blue~>~green~|C| | | | | | | ~orange~S = Sapling or Tree
  9997. ~orange~|S|~red~<~brown~|B|~lightGray~*|*|*|*|*|*| ~red~< = Turtle on Chest
  9998. ~yellow~Options to harvest or manage to follow.
  9999. ]] -- Manual harvest and auto setup
  10000.     info.sub[34] =
  10001. [[~yellow~Build a ~brown~fence ~yellow~or ~lightGray~wall ~yellow~to chosen length.
  10002.  
  10003. Turtle goes ~orange~BACKWARDS ~yellow~when started.
  10004.  
  10005. Start: length = 6, Turtle facing right
  10006.  
  10007. ~lightGray~| |~red~>~lightGray~| | | | | | | ~red~> = Turtle
  10008.  
  10009. Finish:
  10010.  
  10011. ~lightGray~| |F|F|F|F|F|F| | F = Fence or Wall
  10012. ]] -- build fence or wall
  10013.     info.sub[35] =
  10014. [[~yellow~Build a ~brown~fence ~yellow~or ~lightGray~wall ~yellow~
  10015. rectangular area.
  10016.  
  10017. ~lightGray~| | | | | | | | ~brown~F = Fence or Wall
  10018. ~lightGray~| ~brown~|F|F|F|F|F~lightGray~| |
  10019. ~lightGray~| ~brown~|F| | | |F~lightGray~| |
  10020. ~lightGray~| ~brown~|F| | | |F~lightGray~| |
  10021. ~lightGray~| ~brown~|F| | | |F~lightGray~| |
  10022. ~lightGray~| |~red~^~brown~|F|F|F|F| | ~red~^ = Turtle
  10023. ~lightGray~| | | | | | | |
  10024.  
  10025. ]] -- build rectangular fence or wall
  10026.     info.sub[41] =
  10027. [[~yellow~Place me on any block on the left
  10028. side facing the obsidian field.
  10029.  
  10030. ~gray~|O|O|O|O|O| O = Obsidian
  10031. |O|O|O|O|O|
  10032. |O|O|O|O|O|
  10033. |O|O|O|O|O|
  10034. |~red~^~gray~|O|O|O|O| ~red~^ = Turtle
  10035. |~red~^~gray~| | | | |
  10036.  
  10037. ]] -- Harvest obsidian
  10038.     info.sub[42] =
  10039. [[~yellow~Place me on the ground as below ~red~> ~pink~^
  10040. ~yellow~Start ~red~> ~yellow~(facing right) or ~pink~^ ~yellow~ahead
  10041.  
  10042. ~lightGray~| |~red~>~lightGray~|O|O|*| | |    |*|O|O|*| face view            
  10043.    ~pink~^~lightGray~               |O|~purple~+ +~lightGray~|O|
  10044.                    |O|~purple~+ +~lightGray~|O|
  10045. ~yellow~Result (plan)      ~lightGray~|O|~purple~+ +~lightGray~|O|
  10046. ~lightGray~| |O|O|O|O| | |    |*|O|O|*|
  10047.                    ~green~--------- ground
  10048. ~yellow~width=4, ~orange~height=5 ~red~(frame size)
  10049. ]] -- build Nether portal
  10050.     info.sub[43] = info.sub[42] -- Demolish Nether portal
  10051.     info.sub[44] =
  10052. [[~yellow~Press F3+G for chunk boundaries
  10053. Netherite stripmine plan view
  10054.                
  10055. ~lightGray~|*|*|*~lime~N~lightGray~*|*|*|
  10056. ~lightGray~|*|*|*~lime~|~lightGray~*|*|*| ~lime~-| = Chunk Boundaries
  10057. ~lightGray~|*|~red~^~lightGray~|*~lime~|~lightGray~*|~red~^~lightGray~|*|  ~red~^ = Turtle
  10058. ~lime~W*-*-*~blue~+~lime~*-*-*E  ~blue~+ = Boundaries junction
  10059. ~lightGray~|*|*|*~lime~|~lightGray~*|*|*|
  10060. ~lightGray~|*|*|*~lime~|~lightGray~*|*|*|  ~yellow~North of WE
  10061. ~lightGray~|*|*|*~lime~S~lightGray~*|*|*|  ~yellow~1 block from NS
  10062. Most generate close to chunk boundaries
  10063. ]] -- Netherite stripping
  10064.     info.sub[45] =
  10065. [[~yellow~Place me on the ground ~red~<~yellow~ facing ~red~West.
  10066.  
  10067. ~lime~x
  10068.                  ~lightGray~N
  10069. ~lime~a~lightGray~   -1        | | | |  
  10070. ~lime~x~lightGray~    0       ~red~W~lightGray~| |~red~<~lightGray~| |E  ~red~< = Turtle
  10071. ~lime~i~lightGray~    1        | | | |  
  10072. ~lime~s~lightGray~                S
  10073.     ~green~z axis    ~lightGray~-1 0 1
  10074.  
  10075. Centre of the dragon arena ~lime~X = 0, ~green~Z = 0
  10076. ~yellow~                           facing ~red~West
  10077. ]] -- Find dragon tower centres
  10078.     info.sub[46] =
  10079. [[~yellow~Place turtle in ceiling facing endstone
  10080.  
  10081. Plan view    Side view
  10082. ~gray~             |*|*|*|*|*|
  10083.     |*|      |*|*|*|*|*|
  10084.   |*|*|*|    |*|*|*|*|*|
  10085. |*|*|*|*|*|  |*|*|*|*|*|  * ~lightGray~= Obsidian
  10086. ~gray~|*|*|~yellow~E~gray~|*|*|  |*|*|*|*|*|  ~yellow~E ~lightGray~= Endstone
  10087. ~gray~  |*|~red~^~gray~|*|    |*|*|~red~T~gray~|*|*|~red~ ^T ~lightGray~= Turtle
  10088. ~gray~    |*|      |*|*| |*|*|
  10089.              |*|*| |*|*|
  10090. ]] -- deactivate dragon tower
  10091.     info.sub[47] =
  10092. [[~yellow~Place turtle on the ground at 100,49,0
  10093.  
  10094. |*|*|*|*|*|*|*|*|*|   ~lightGray~= Dragon Island
  10095.  
  10096.  
  10097. ~yellow~    Facing WEST
  10098. ~gray~    |*|*|*|*|*|     * ~lightGray~= Obsidian plate
  10099. ~gray~    |*|*|*|*|*|
  10100. ~yellow~  S ~gray~|*|*|~red~T~gray~|*|*| ~yellow~N   ~red~T ~lightGray~= Turtle
  10101. ~gray~    |*|*|*|*|*|
  10102.     |*|*|*|*|*|
  10103. ~yellow~         E]] -- build dragon water trap
  10104.     info.sub[48] =
  10105. [[~yellow~Place turtle under end world portal
  10106.  
  10107. ~gray~        |B|     B ~lightGray~= Bedrock
  10108. ~gray~      |B|B|B|
  10109.         ~purple~|P|     P ~lightGray~= Portal
  10110. ~gray~      |B|B|B|
  10111.         |B|
  10112.          ~green~|      
  10113.          ~green~|      ~lime~Height measured first     
  10114.          ~green~|      
  10115. ~red~         T      T ~lightGray~= Turtle 
  10116. ~yellow~  |*|*|*|*|*|*| ~red~Inventory AFTER height
  10117. ]] -- build end portal minecart
  10118.    
  10119.     info.sub[491] =
  10120. [[~yellow~Place turtle <64 blocks from shulker
  10121. Directly below or 1 block in front
  10122. ~lightGray~|*|*|*|*|*|*|*|
  10123.      ~gray~> ~lime~S ~gray~<       > T < = kill positions
  10124.        ~gray~T
  10125.  
  10126.  
  10127.  
  10128.      ~red~> T <       Attacks ahead / above
  10129. ~lightGray~|*|*|*|*|*|*|*|
  10130.  
  10131. ~red~> T <~lightGray~ = Turtle   ~lime~S~lightGray~ = Shulker]] -- Shulker is above
  10132.  
  10133.     info.sub[492] =
  10134. [[~yellow~Place turtle <64 blocks from shulker
  10135. Same level, or 1 block above/below
  10136. Plan view:
  10137.    ~red~>~lightGray~ | | | | | |~lime~S~lightGray~|
  10138.  
  10139. ~yellow~Side view:
  10140.    ~red~T~lightGray~ | | | | | |~gray~T~lightGray~|
  10141.    ~red~T~lightGray~ | | | | |~gray~T~lightGray~|~lime~S~lightGray~|   ~gray~T = kill positions
  10142.    ~red~T~lightGray~ | | | | | |~gray~T~lightGray~|
  10143.    
  10144.  ~red~> T~lightGray~ = Turtle   ~lime~S~lightGray~ = Shulker]] -- Shulker is ahead
  10145.    
  10146.     info.sub[493] =
  10147. [[~yellow~Place turtle <64 blocks from shulker
  10148. Directly above or 1 block in front
  10149. ~lightGray~|*|*|*|*|*|*|*|
  10150.      ~red~> T <       Attacks ahead / below
  10151.  
  10152.  
  10153.  
  10154.        ~gray~T
  10155.      ~gray~> ~lime~S ~gray~<       > T < = kill positions
  10156. ~lightGray~|*|*|*|*|*|*|*|
  10157.  
  10158. ~red~> T <~lightGray~ = Turtle   ~lime~S~lightGray~ = Shulker]] -- Shulker is below
  10159.  
  10160.     info.sub[494] =
  10161. [[~yellow~Place turtle in entry pit centre wall
  10162.  
  10163. ~lightGray~|*|~orange~+~lightGray~| | |~red~+~lightGray~| | |~lime~S~lightGray~|*| ~lime~S~lightGray~ = Shulker
  10164. ~lightGray~|*|~orange~+~lightGray~| |~lime~S|~red~+~lightGray~| | |~blue~+~lightGray~|*| T = turtle places
  10165. ~lightGray~|*|~orange~+~lightGray~| | |~red~+~lightGray~| | |~blue~+~lightGray~|*|
  10166. ~lightGray~|*|~orange~+~lightGray~| | |~red~+~lightGray~| | |~blue~+~lightGray~|*|     ~yellow~Plan view
  10167. ~lightGray~|*|~orange~+|+|+|~red~+|~blue~+|+|+~lightGray~|*|    |*|*|*|*|*|
  10168. ~lightGray~|*|*|*|~orange~+|~red~+|~blue~+~lightGray~|*|*|*|    |*| |~red~T~lightGray~| |*|
  10169. ~lightGray~|*|*|*|~orange~T|~red~T|~blue~T~lightGray~|*|*|*|    |*|~orange~T~lightGray~| |~blue~T~lightGray~|*|
  10170. ~lightGray~|*|*|*| | | |*|*|*|    |*| |~red~T~lightGray~| |*|
  10171.                        |*|*|*|*|*|]] -- Climb tower wall
  10172.  
  10173.     info.sub[495] =
  10174. [[~yellow~Place turtle in corner against ceiling
  10175. Face ~red~direction ~yellow~shown. It will exit up,
  10176. clear the roof above and return
  10177.  
  10178. ~lightGray~|*|*|*|*|*|*|*|*|*|*|  ~yellow~Clears 15x15
  10179. ~lightGray~|*|~red~<~lightGray~| | | | | | |~red~^~lightGray~|*|  ~yellow~area regardless
  10180. ~lightGray~|*| | | | | | | | |*|  ~yellow~of actual size
  10181.  
  10182. ~lightGray~|*| | | | | | | | |*|
  10183. ~lightGray~|*|~red~V~lightGray~| | | | | | |~red~>~lightGray~|*|
  10184. ~lightGray~|*|*|*|*|*|*|*|*|*|*|]] -- Clear roof above
  10185.  
  10186.     info.sub[496] =
  10187. [[~yellow~Place turtle in corner against ceiling
  10188. Face ~red~direction ~yellow~shown. It will exit out,
  10189. clear 4 outside walls and return.
  10190.  
  10191. ~lightGray~|*|*|*|*|*|*|*|*|*|*|  ~yellow~Size calculated
  10192. ~lightGray~|*|~red~<~lightGray~| | | | | | |~red~^~lightGray~|*|  ~yellow~automatically.
  10193. ~lightGray~|*| | | | | | | | |*|
  10194.  
  10195. ~lightGray~|*| | | | | | | | |*|
  10196. ~lightGray~|*|~red~V~lightGray~| | | | | | |~red~>~lightGray~|*|
  10197. ~lightGray~|*|*|*|*|*|*|*|*|*|*|]] -- Clear outside wall
  10198.  
  10199.     info.sub[51] =
  10200. [[~yellow~Place me on the ground as below ~red~^
  10201.  
  10202. ~yellow~Start:~blue~  |-|-|-|    - = air/water
  10203. ~orange~        |-|-|-|    - = lava
  10204. ~blue~        |-|-|-|
  10205. ~lightGray~        |*|~red~^~lightGray~|*|    ~red~^ = Turtle
  10206.  
  10207. ~yellow~Result:~blue~ |-|~lightGray~*|~blue~-|    - = air/water
  10208. ~orange~        |-|~lightGray~*|~orange~-|    - = lava
  10209. ~blue~        |-|~lightGray~*|~blue~-|
  10210. ~lightGray~        |*|*|*|    * = Solid block
  10211. ]] -- Single path
  10212.     info.sub[52] =
  10213. [[~yellow~Place ~red~^ T~yellow~ at start of path or tunnel
  10214.  
  10215. ~yellow~Plan view    Face view
  10216.  
  10217. ~lightGray~|*|~green~*~lightGray~|*|      *|*|*|*|*   ~green~* = new block
  10218. ~lightGray~|*|~green~*~lightGray~|*|      *|*|~green~*~lightGray~|*|*
  10219. ~lightGray~|*|~green~*~lightGray~|*|      *|*| |*|*
  10220. ~lightGray~|*|~green~*~lightGray~|*|      *|*|~red~T~lightGray~|*|*   ~red~^ T = Turtle
  10221.    ~red~^~lightGray~         ~green~- - * - -   ground
  10222.  
  10223. ~green~Floor + ceiling ~yellow~placed for your safety!
  10224. ]] -- Covered walkway / tunnel
  10225.     info.sub[53] =
  10226. [[~yellow~plan view
  10227.  
  10228. ~lightGray~|*|~blue~-|-~lightGray~|*|
  10229. ~lightGray~|*|~blue~-|-~lightGray~|*|    ~yellow~Cross section view
  10230. ~lightGray~|*|~blue~-|-~lightGray~|*|     ~lime~1 ~orange~2 ~brown~3 ~green~4  ~lightGray~= on ground
  10231. ~lightGray~|~lime~^~lightGray~|~blue~^~lightGray~|~cyan~^~lightGray~|~green~^~lightGray~|    |*|~blue~5~lightGray~|~cyan~6~lightGray~|*| ~lightGray~= in water
  10232.  
  10233. ~yellow~New canal       ~lime~1 ~orange~2 ~brown~3 ~green~4 ~yellow~ground level-63
  10234. ~yellow~Extend existing ~lime~1     ~green~4 ~yellow~ground level-63
  10235. ~yellow~Extend existing   ~blue~5 ~cyan~6   ~yellow~water  level-62
  10236. ]] -- new/existing canal
  10237.     info.sub[54] =
  10238. [[~lime~New ~yellow~ice canal or ~lightBlue~convert ~yellow~existing water
  10239.  
  10240. ~lightGray~ |*| | |*|    * = Slab
  10241. ~lightGray~ |~orange~T~lightGray~|~blue~I~lightGray~| |*|    ~blue~I = Ice (packed or blue)
  10242. ~lightGray~ |*| | |*|   | | = Air (empty block)
  10243. ~lightGray~ |*|~blue~I~lightGray~| |~orange~T~lightGray~|   ~orange~T = Torch (optional)
  10244. ~lime~  1 2 3 4    New ice canal
  10245. ~lightBlue~  5 6 7 8    Convert water canal
  10246.  
  10247. ~red~All turtles placed at ground level!
  10248. ~lime~1-4 ~lightGray~for ~lime~new ~lightGray~canal ~lightBlue~5-8 ~lightGray~to ~lightBlue~convert ~lightGray~water
  10249. ]] -- ice canal
  10250.     info.sub[55] =
  10251. [[~yellow~Place ~red~^~yellow~ any level air, water or lava.~lightGray~
  10252.  
  10253. | | | | | | | |
  10254. | |*|*|*|*|*| |  * = Block
  10255. | |*|*|*|*|*| |
  10256. | |*|*|*|*|*| |
  10257. | |*|*|*|*|*| |
  10258. | |~red~^~lightGray~|*|*|*|*| |  ~red~^ = Turtle~lightGray~
  10259. | | | | | | | |
  10260.  
  10261. Blocks placed under the turtle
  10262. ]] -- Platform
  10263.     info.sub[56] =
  10264. [[~yellow~Place ~red~^~yellow~ above water.~lightGray~
  10265. Existing platform replaced below
  10266.  
  10267. | |*|*|*|*|*| |  * = Block
  10268. | |*|*|*|*|*| |
  10269. | |*|*|*|*|*| |
  10270. | |*|*|*|*|*| |
  10271. | |~red~^~lightGray~|*|*|*|*| |  ~red~^ = Turtle~lightGray~
  10272. | | | | | | | |
  10273.  
  10274. Blocks placed under the turtle
  10275. ]] -- Sinking platform
  10276.     info.sub[57] =
  10277. [[~yellow~Boat Lift (Ice or Water)
  10278. Place turtle left side. ~blue~Source~yellow~ to right
  10279.  
  10280. Start~lightGray~        |*|~blue~ | ~lightGray~|*| ~yellow~Finish
  10281. ~lightGray~             |*|~blue~ | ~lightGray~|*|
  10282.              |*|~cyan~S|S|~lightGray~*| ~cyan~S ~lightGray~= Soul sand
  10283. |*|*|*|*|    |*|~brown~S|S~lightGray~|*| ~brown~S = ~lightGray~Sand + gate
  10284. |~red~^~lightGray~|~blue~W|W~lightGray~|*|    |*~blue~|W|W|~lightGray~*| ~red~^ ~lightGray~= Turtle
  10285. |*|~blue~W|W~lightGray~|*|    |*|~blue~W|W~lightGray~|*|
  10286. |*|~blue~ | ~lightGray~|*|    |*|~blue~ | ~lightGray~|*| ~yellow~Ice canal needs
  10287. ~lightGray~|*|~blue~ | ~lightGray~|*|    |*|~blue~ | ~lightGray~|*| ~yellow~2x2 water source
  10288. ]] -- boat bubble lift
  10289.     info.sub[61] =
  10290. [[~red~NOT ~yellow~for Blaze spawners!
  10291. Plan view          Side view~lightGray~
  10292.     T       T      T = Outside dungeon
  10293.  |*|*|*|*|*|*|*|   |*|~brown~1~lightGray~|*|*|*|~yellow~2~lightGray~|*| Top
  10294. T|*| | | | | |*|T  |*| | | | | |*|
  10295.  |*| | |~magenta~5~lightGray~| | |*|   |*| | |~magenta~5~lightGray~| | |*|
  10296.  |*| |~magenta~5~lightGray~|~orange~S~lightGray~|~magenta~5~lightGray~| |*|   |*|~lime~3~lightGray~|~magenta~5|~orange~S~lightGray~|~magenta~5|~green~4~lightGray~|*| Base
  10297.  |*| | |~magenta~5~lightGray~| | |*|
  10298. T|*| | | | | |*|T  * = Dungeon Wall
  10299.  |*|*|*|*|*|*|*|   ~orange~S = Spawner
  10300. ~lightGray~    T       T      T = Turtle ~brown~1 ~yellow~2 ~lime~3 ~green~4
  10301. ~magenta~5~lightGray~ = On top or adjacent (0 chests only)
  10302. ]] -- 9x9 cube round spawner
  10303.     info.sub[62] =
  10304. [[~yellow~Place turtle as indicated:
  10305. Plan view          Side view
  10306.  
  10307. ~lightGray~|*|*|*|*|*|*|*|*|  ~lime~> T = Continue build
  10308. ~lightGray~|*| | | | | | | |  ~red~< T = New build
  10309. ~lightGray~|*| | | | | | | |
  10310. |*| | | |~purple~S~lightGray~| | | |~lime~>~red~<          T
  10311. ~lightGray~|*| | | | | | | |   |*| | | |~purple~S~lightGray~| | | |~red~T
  10312. ~lightGray~|*| | | | | | | |   |*| | | | | | | |
  10313. ~lightGray~|*| | | | | | | |   |*| | | | | | | |
  10314. ~lightGray~|*|*|*|*|*|*|*|*|   |*| | | | | | | |~lime~T
  10315.                                      ~red~T]] -- 9x9 cube round blaze spawner
  10316.     info.sub[63] =
  10317. [[~yellow~ Plan view (truncated)    Side view
  10318.  
  10319. ~lightGray~ |*| | | | | | | | | |*|  |*| | | | | |
  10320. ~red~>~lightGray~|*| | | | |~purple~S~lightGray~| | | | |*|~red~<~lightGray~ |*| | | | |~purple~S~lightGray~|
  10321.  |*| | | | | | | | | |*|  |*| | | | | |
  10322.  |*| | | | | | | | | |*|  |*| | | | | |
  10323.  |*| | | | | | | | | |*|  |*| | | | | |
  10324.  |*| | | | | | | | | |*|  |*| | | | | |
  10325.  |*|*|*|*|*|*|*|*|*|*|*| ~red~T~lightGray~|*|*|*|*|*|*|
  10326.             ~red~^
  10327. ~purple~S ~lightGray~= Spawner ~red~<> ^ T ~lightGray~= Turtle
  10328. ]] -- Flood spawner chamber
  10329.     info.sub[64] =
  10330. [[~yellow~Bubble lift: Plan view at start~lightGray~
  10331.  |*| | | | | | | | | |*|
  10332.  |*| | | | |~brown~F~lightGray~| | | | |*|
  10333.  |*|*|*|*|*|~brown~F~lightGray~|*|*|*|*|*|  ~brown~F ~lightGray~= Fence
  10334.            ~brown~|~red~^~brown~|~lightGray~= Turtle on ~brown~Soul Sand
  10335.            
  10336. ~yellow~Plan view completed~lightGray~         
  10337.  |*| | | | |~brown~F~lightGray~| | | | |*|
  10338.  |*|*|*|*|*|~brown~F~lightGray~|*|*|*|*|*|  ~brown~F ~lightGray~= Fence
  10339. ~yellow~kill zone~lightGray~|*|~blue~S~lightGray~|*|~yellow~kill zone ~lightGray~Left / Right
  10340.            ~lightGray~|*|        ~blue~S ~lightGray~= Bubble lift
  10341. ]] -- Build bubble tower kill zone
  10342.     info.sub[65] =
  10343. [[~yellow~Computercraft mob grinder
  10344.  
  10345. Plan view~lightGray~ |*~blue~| | | | | | | | | |~lightGray~*|
  10346.           |*~blue~| | | | | | | | | |~lightGray~*|
  10347.           |*|*|*|*|*~blue~| |~lightGray~*|*|*|*|*| Front
  10348. ~red~T~yellow~urtle facing out    ~red~V~lightGray~              
  10349.                          
  10350. ~yellow~Side view ~lightGray~|*|*|*|*|*|*|*|*|*|*|*|
  10351.           |*|*|*|*|*|*|*|*|*|*|*|
  10352.           |*|*|*|*|*|*|*|*|*|*|*|
  10353. ~red~E~yellow~xit hole ~lightGray~|*|*|*|*|*|~red~T~lightGray~|*|*|*|*|*|
  10354.           ~gray~|*|*|*|*|*|*|*|*|*|*|*| Base
  10355. ]] -- Computercraft mob grinder
  10356.     info.sub[66] =
  10357. [[This is a 3 stage process:
  10358. 1.New tower lower base: place me on
  10359. flat ground in open plain.
  10360.  
  10361. 2.Upper base: place me in front of
  10362. the existing chest at tower base.
  10363.  
  10364. 3.Main tower, only needed to respawn
  10365. mobs. Expensive, not recommended.
  10366. Place me in front of chest in ground.
  10367. ]] -- Build endermen observation tower
  10368.  
  10369.     info.sub[71] =
  10370. [[~yellow~Clear field
  10371.  
  10372. ~lightGray~| | | | | |  Remove ~lime~trees ~lightGray~and ~pink~flowers
  10373. ~lightGray~| | | | | |  Fill ~gray~holes
  10374. ~lightGray~| | | | | |  Remove blocks > ground
  10375. | | | | | |
  10376. | | | | | |
  10377. |~red~^~lightGray~| | | | |  ~red~^ ~lightGray~= Turtle position
  10378.  
  10379. ~yellow~Optional use ~brown~dirt ~yellow~as surface
  10380.  
  10381. ]] -- Clear field
  10382.     info.sub[72] =
  10383. [[~yellow~Clear rectangle
  10384.  
  10385. ~lightGray~| | | | | |  Remove all blocks
  10386. ~lightGray~| | | | | |  Optional dig ~lime~up
  10387. ~lightGray~| | | | | |  Optional dig ~blue~down
  10388. ~lightGray~| | | | | |
  10389. | | | | | |
  10390. |~red~^~lightGray~| | | | |  ~red~^ ~lightGray~= Turtle position
  10391.  ~red~^
  10392.  
  10393. ~yellow~Can be used to clear 3 layers at a time
  10394.  
  10395. ]] -- Clear rectangle
  10396.  
  10397.     info.sub[73] =
  10398. [[~yellow~Clear wall
  10399. Plan view         Side view
  10400.                   ~gray~T ~lightBlue~T
  10401. ~red~>~lightGray~|~orange~>~lightGray~|*|*|*|*|*|    ~cyan~T~lightGray~|~blue~T~lightGray~|*|*|*|*|*| Top
  10402. ~lightGray~                   |*|*|*|*|*|*|
  10403.                    |*|*|*|*|*|*|
  10404.                    |*|*|*|*|*|*|
  10405.                    |*|*|*|*|*|*|
  10406.                   ~lime~T~lightGray~|~green~T~lightGray~|*|*|*|*|*| Base
  10407.                  
  10408. T = Turtle top / bottom/ inside / out
  10409. ~yellow~Bottom to top or top to bottom
  10410. ]] -- Clear wall
  10411.     info.sub[74] =
  10412. [[~yellow~Clear rectangle ~red~perimeter only
  10413.  
  10414. ~yellow~Plan view
  10415. ~lightGray~| | | | | |  Remove all blocks
  10416. ~lightGray~| |*|*|*| |  Optional dig ~lime~up
  10417. ~lightGray~| |*|*|*| |  Optional dig ~blue~down
  10418. ~lightGray~| |*|*|*| |
  10419. | |*|*|*| |
  10420. |~red~^~lightGray~| | | | |  ~red~^ ~lightGray~= Turtle position
  10421. ~red~ ^
  10422. ~yellow~Can be used to clear 3 layers at a time
  10423.  
  10424. ]] -- Clear rectangle (perimeter only)
  10425.     info.sub[75] =
  10426. [[~yellow~Demolish cube structure
  10427. Plan view        Side view
  10428.                ~gray~T ~lightBlue~T
  10429. ~lightGray~|*|*|*|*|*|*|  ~cyan~T~lightGray~|~blue~T~lightGray~|*|*|*|*|*|
  10430. |*|*|*|*|*|*|   |*|*|*|*|*|*|
  10431. |*|*|*|*|*|*|   |*|*|*|*|*|*|
  10432. |*|*|*|*|*|*|   |*|*|*|*|*|*|
  10433. |*|*|*|*|*|*|   |*|*|*|*|*|*|
  10434. |~lime~^~lightGray~|*|*|*|*|*|  ~lime~T~lightGray~|~green~T~lightGray~|*|*|*|*|*|
  10435.  ~green~^
  10436. ~lightGray~^ T = Turtle (top/base in/out)
  10437. ]] -- Clear structure floor/walls/ceiling hollow and solid
  10438.     info.sub[76] = info.sub[75]
  10439.     info.sub[77] =
  10440. [[~yellow~Dig a trench (Plan view)
  10441.  
  10442. ~lightGray~      |~red~>~lightGray~| | | | | | |
  10443.  
  10444. | |    ~red~>~lightGray~ = Turtle
  10445. | |    
  10446. | |
  10447. | |
  10448. | |    
  10449. |~red~^~lightGray~|    ~red~^~lightGray~ = Turtle
  10450. ]] -- Dig a trench
  10451.     info.sub[78] =
  10452. [[~yellow~Mountain carving     ~red~T ^ = Turtle
  10453. ~yellow~Side view            Plan view
  10454.  
  10455. ~lightGray~        |*|              |*|*|      ~yellow~L
  10456. ~gray~      |*~lightGray~|*|            ~gray~|*~lightGray~|*|*|*|    ~yellow~E
  10457. ~gray~      |*~lightGray~|*|*|*|      ~gray~|*|*~lightGray~|*|*|*|*|  ~yellow~N
  10458. ~gray~      |*~lightGray~|*|*|*|      ~gray~|*|*~lightGray~|*|*|*|*|  ~yellow~G
  10459. ~gray~      |*~lightGray~|*|*|*|       ~red~^~gray~|*~lightGray~|*|*|*|    ~yellow~T
  10460. ~gray~    |*|*~lightGray~|*|*|*|*|        |*|*|      ~yellow~H
  10461.    ~red~T~gray~|*|*~lightGray~|*|*|*|*|
  10462.     ~yellow~<--> no. of rows <-->
  10463. ]] -- Carve mountain
  10464.     info.sub[79] =
  10465. [[~yellow~Place / Replace floor or ceiling
  10466.  
  10467. Plan view      Side view
  10468. ~lightGray~| | | | | |    |*|*|*|*|*|
  10469. | | | | | |     T          Ceiling
  10470. | | | | | |
  10471. | | | | | |
  10472. | | | | | |     T          Floor
  10473. |~red~^~lightGray~| | | | |    |*|*|*|*|*|
  10474.  
  10475. ~red~^ ~lightGray~T = Turtle position
  10476.  
  10477. ]] -- (Re)place floor or ceiling
  10478.     info.sub[710] =
  10479. [[~yellow~Place me anywhere!
  10480. Menu or direct command interface.
  10481.  
  10482. ~lightGray~Commands:
  10483.  
  10484. direction + ~blue~number ~yellow~eg ~white~f2 ~yellow~= forward ~blue~2
  10485.  
  10486. ~yellow~f = forward  ~orange~b = backward
  10487. ~lime~l = left     ~red~r = right
  10488. ~lightGray~u = up       ~cyan~d = down
  10489.  
  10490. ]] -- Direct control
  10491.     info.sub[81] =
  10492. [[~blue~1.Drop sand or gravel wall
  10493.   ~yellow~Place me on water/lava surface
  10494.  
  10495. ~lightBlue~2.Fill area with sand
  10496.   ~yellow~Place  on left corner of area
  10497.  
  10498. ~yellow~3.Clear ~blue~(1) sand wall
  10499.   ~yellow~Place me on the surface of sand.
  10500.  
  10501. ~yellow~4.Clear ~lightBlue~(2) sand filled area
  10502.   ~yellow~Place on left corner of sand field
  10503. ]] -- Sand based utilities
  10504.     info.sub[82] =
  10505. [[~yellow~Turtle position ~red~> T ~gray~(~red~V ~gray~to enclose)
  10506. ~yellow~Plan view                      ~gray~Start:~red~V
  10507. ~blue~|~red~>~blue~| | | | | | ~yellow~to ~lightGray~|*|*|*|*|*|~red~V~lightGray~|~gray~ enclose
  10508.                             ~gray~*  area
  10509. ~yellow~Side view
  10510.  ~red~T
  10511. ~blue~| | | | | | | ~yellow~to ~lightGray~|*|*|*|*|*|*|
  10512. ~blue~| | | | | | |    ~lightGray~|*|*|*|*|*|*|
  10513. ~blue~| | | | | | |    ~lightGray~|*|*|*|*|*|*|
  10514. ~yellow~|S|~blue~ | | |~yellow~S|S|    |S|~lightGray~*|*|*|~yellow~S|S|
  10515. ~yellow~|S|S|S|S|S|S|    |S|S|S|S|S|S|
  10516. ]] -- build wall from water or lava surface downwards  
  10517.     info.sub[83] =
  10518. [[~yellow~Build a walled rectangle
  10519.  
  10520.  
  10521. ~yellow~L ~lightGray~|*|*|*|*|*|*|
  10522. ~yellow~e ~lightGray~|*| | | | |*|
  10523. ~yellow~n ~lightGray~|*| | | | |*|
  10524. ~yellow~g ~lightGray~|*| | | | |*|
  10525. ~yellow~t ~lightGray~|*|*|*|*|*|*|
  10526. ~yellow~h  ~red~^
  10527. ~yellow~   W i d t h      ~red~^ ~lightGray~= Turtle
  10528.  
  10529.  
  10530. ]] -- Create enclosed area
  10531.     info.sub[84] =
  10532. [[~yellow~Clear volume of water
  10533.  
  10534. Plan view
  10535. ~lightGray~|*|*|*|*|*|*|*|*|  * = Stone
  10536. |*|*~blue~| | |~lightGray~*|*~blue~| |~lightGray~*|  ~blue~| ~lightGray~= Water
  10537. |*~blue~| | | | | | |~lightGray~*|
  10538. |*~blue~| | | | | | |~lightGray~*|
  10539. |*~blue~| | | | | | |~lightGray~*|
  10540. |*~blue~| | | | | |~lightGray~*|*|
  10541. |*|~red~^~lightGray~|*~blue~| | | | |~lightGray~*|  ~red~^ ~lightGray~= Turtle
  10542. |*|*|*|*|*|*|*|*|  ~yellow~Width~blue~: ~yellow~6, ~orange~length~blue~:~orange~ 6
  10543.  
  10544. ]] -- Clear volume of water
  10545.     info.sub[85] = info.sub[56] -- Sinking platform
  10546.     info.sub[861] =
  10547. [[~yellow~Turtle placement  ~red~V~lime~ < ^ > ~yellow~over monument
  10548.  
  10549. ~red~******    ******  * ~lightGray~= Avoid this area
  10550. ~red~******    ******  V do not face front
  10551. ******    ******  ~lime~< ^ > ~lightGray~Ideal facing~lightGray~
  10552. ******    ******
  10553. ~green~******~lime~++++~green~******  ~lime~+ ~lightGray~= Ideal position~green~
  10554. ******~lime~++++~green~******  ~green~* ~lightGray~= Good position
  10555. ~green~****************
  10556. ****************  Or any corner < 12
  10557. ****************  blocks from edge
  10558. ]]-- Ocean monument 85 subChoice 1: 4 corner pillars
  10559.  
  10560.     info.sub[862] =
  10561. [[~yellow~Turtle positions ~red~> ^ < V
  10562.  
  10563. ~lightGray~|*|~red~>~lightGray~|*|*|*|*|*|~red~<~lightGray~|*|  ~red~NOT ~lightGray~corner blocks!
  10564. |~red~V~lightGray~|             |~red~V~lightGray~|
  10565. |*|             |*|
  10566. |*|             |*|
  10567. |*|             |*|
  10568. |*|             |*|
  10569. |*|             |*|  ~yellow~Fill inventory~lightGray~
  10570. |~red~^~lightGray~|             |~red~^~lightGray~|  ~yellow~with stone.~lightGray~
  10571. |*|~red~>~lightGray~|*|*|*|*|*|~red~<~lightGray~|*|  ~yellow~Add when asked
  10572. ]] -- Ocean monument build retaining walls
  10573.  
  10574.     info.sub[863] =
  10575. [[~yellow~Turtle ~red~> < ~yellow~on side walls only
  10576.  
  10577. ~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. ~lightGray~|~red~>~cyan~| ************* |~red~<~lightGray~|
  10585. |*|*|*|*|*|*|*|*|*|*|
  10586. ]] -- clear plants before sand draining
  10587.     info.sub[864] = info.sub[863]
  10588.     info.sub[865] = info.sub[863]
  10589.     info.sub[866] = info.sub[56]
  10590.     info.sub[867] =
  10591. [[~yellow~Turtle positions ~red~> ^ < V
  10592. ~green~|*|*|*|*|*~brown~|*|*|*|~red~V~brown~|*|
  10593. ~green~|~red~>~green~|- - - - ~brown~- - - -|*|
  10594. ~green~|*|- - - - ~brown~- - - -|*| ~lightGray~1 Turtle removes
  10595. ~green~|*|- - - - ~brown~- - - -|*| ~lightGray~1 coloured area
  10596. ~green~|*|- - - - ~brown~- - - -|*|
  10597. ~orange~|*|- - - - ~lime~- - - -|*| ~lightGray~6 chests / area
  10598. ~orange~|*|- - - - ~lime~- - - -|*| ~lightGray~Follow turtle
  10599. ~orange~|*|- - - - ~lime~- - - -|*|
  10600. ~orange~|*|- - - - ~lime~- - - -|~red~<~lime~| ~lightGray~30,000 fuel each!
  10601. ~orange~|*|~red~^~orange~|*|*|*~lime~|*|*|*|*|*| ~lightGray~3,000 stone each!
  10602. ]] -- Ocean monument drain and remove 1 of 4 quarters
  10603.     info.sub[87] =
  10604. [[~yellow~Ladder to water / lava: Plan view
  10605.  
  10606.  ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~-    ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~-
  10607.  ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~-    ~red~- ~blue~- ~red~-~lightGray~|*|- ~blue~- ~red~-
  10608.  ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~-    ~blue~- ~red~-~lightGray~|*|~brown~L~lightGray~|*|~red~- ~blue~- ~~lightGray~
  10609. |*|*|*|~red~^~lightGray~|*|*|*|  |*|*|*|*|*|*|*|
  10610. |*|*|*|*|*|*|*|  |*|*|*|*|*|*|*|
  10611. |*|*|*|*|*|*|*|  |*|*|*|*|*|*|*|
  10612.  
  10613. ~red~^ ~lightGray~= Turtle facing water / lava
  10614. ~brown~L ~lightGray~= Ladder
  10615.  
  10616. ]] -- Ladder to water/lava 
  10617.     info.sub[88] =
  10618. [[~yellow~Place ~red~T~yellow~urtle at water edge.
  10619. Returns max ~blue~d~yellow~epth. ~yellow~Water ~green~p~yellow~lants~yellow~ removed
  10620.  
  10621.    ~red~T                       T
  10622. ~lightGray~|*|*| ~blue~| | | | | | | | | | ~lightGray~|*|
  10623. |*|*| ~blue~| | | | | | | | | ~lightGray~|*|*|
  10624. |*|*| ~blue~| | | | | | | ~lightGray~|*|*|*|*|
  10625. |*|*|*| ~blue~| | |~green~p~blue~| | ~lightGray~|*|*|*|*|*|
  10626. |*|*|*| ~blue~| | |~green~p~lightGray~|*|*|*|*|*|*|*|
  10627. |*|*|*|*~blue~|d~lightGray~|*|*|*|*|*|*|*|*|*|
  10628. |*|*|*|*|*|*|*|*|*|*|*|*|*|*|
  10629. ]] -- Clear water plants from enclosed area
  10630.     info.sub[89] =
  10631. [[Place me on the left corner of the top
  10632. of retaining wall facing water
  10633. ]] -- Convert all water to source
  10634.     info.sub[810] =
  10635. [[Place me on the left corner of the top
  10636. of retaining wall facing water.
  10637. The source blocks are placed ahead to
  10638. selected length
  10639. ]] -- Create sloping water
  10640.  
  10641. -- Building and railway
  10642.     info.sub[91] =
  10643. [[~yellow~Build a wall
  10644.  
  10645. Plan view        Side view
  10646.  
  10647. ~red~>~lightGray~| | | | | | |   |*|*|*|*|*|*|
  10648.                  |*|*|*|*|*|*|
  10649.                  |*|*|*|*|*|*|
  10650.                  |*|*|*|*|*|*|
  10651.                 ~red~T~lightGray~|~red~T~lightGray~|*|*|*|*|*|
  10652.  
  10653. ~red~> T~lightGray~ = Turtle
  10654.                  
  10655. ]] -- Build a wall
  10656.     info.sub[92] =
  10657. [[~yellow~Build a walled rectangle / house
  10658.  
  10659. Plan view         Side view
  10660.  
  10661. ~yellow~L ~lightGray~|*|*|*|*|*|*|   |*|*|*|*|*|*|
  10662. ~yellow~e ~lightGray~|*| | | | |*|   |*|*|*|*|*|*|
  10663. ~yellow~n ~lightGray~|*| | | | |*|   |*|*|*|*|*|*|
  10664. ~yellow~g ~lightGray~|*| | | | |*|   |*|*|*|*|*|*|
  10665. ~yellow~t ~lightGray~|~red~^~lightGray~|*|*|*|*|*|  ~red~T~lightGray~|~red~T~lightGray~|*|*|*|*|*|
  10666. ~yellow~h  ~red~^
  10667. ~yellow~   W i d t h      ~red~^ T ~lightGray~= Turtle
  10668.  
  10669. ]] -- Build a rectangular structure
  10670.     info.sub[93] =
  10671. [[~yellow~Build a gable roof
  10672. Gable built on right side of turtle
  10673. Plan view       End view (width)
  10674.                      ~gray~+      gable top
  10675. ~yellow~L ~lightGray~|*|*|*|*|*|      ~gray~+ + +    gable end
  10676. ~yellow~e ~lightGray~|*| | | |*|    ~red~T~gray~ + + + +  gable end
  10677. ~yellow~n ~lightGray~|*| | | |*|   |*|*|*|*|*| top of wall
  10678. ~yellow~g ~lightGray~|*| | | |*|   |*|*|*|*|*|
  10679. ~yellow~t ~lightGray~|*| | | |*|   |*|*|*|*|*|
  10680. ~yellow~h ~lightGray~|~red~^~lightGray~|*|*|*|*|   |*|*|*|*|*|
  10681. ~yellow~  W i d t h     W i d t h   ~red~^T ~lightGray~= Turtle
  10682. ]] -- Build a gable end roof
  10683.     info.sub[94] =
  10684. [[~yellow~Build a pitched roof
  10685. Width ~red~MUST ~yellow~be ~red~<= ~yellow~Length eg ~red~4~yellow~ x 6
  10686. Plan view        End view (width)
  10687.  
  10688.                   ~red~T ~lightGray~on top of building
  10689. ~yellow~L ~lightGray~|*|*|*|*|      |*|*|*|*|
  10690. ~yellow~e ~lightGray~|*| | |*|      |*|*|*|*|
  10691. ~yellow~n ~lightGray~|*| | |*|      |*|*|*|*|
  10692. ~yellow~g ~lightGray~|*| | |*|      |*|*|*|*|
  10693. ~yellow~t ~lightGray~|*| | |*|
  10694. ~yellow~h ~lightGray~|~red~^~lightGray~|*|*|*|
  10695. ~yellow~  W i d t h     ~red~^ T ~lightGray~= Turtle
  10696. ]]-- Build a pitched roof
  10697.     info.sub[95] =
  10698. [[~yellow~Place me on suspended railway stone
  10699. Redstone torch will go below me
  10700.  
  10701. ~lightGray~_____
  10702. ~lightGray~|*|*|\                           ~red~>~lightGray~|*|
  10703.     |*|~red~<                       ~lightGray~/|*|
  10704.       ~lightGray~|*|______~red~T~lightGray~_________    /~lightGray~|*|~red~!
  10705.        ~red~!~lightGray~|*|*|*|*|*|*|*|*|\ /|*|
  10706.                ~red~!        ~lightGray~|*|*|
  10707.  
  10708. ~red~T < > ~lightGray~= Turtle ~red~! ~lightGray~= Redstone Torch
  10709. On block or above rail, face up slope
  10710. ]] -- Place redstone torch under block
  10711.     info.sub[96] = info.sub[95]
  10712.     info.sub[97] =
  10713. [[~yellow~Place me on last block before up/down
  10714.  
  10715. Build down            Build up~lightGray~
  10716.  
  10717. _____~red~T~lightGray~                        ___
  10718. |*|*|*|_                     _|*|
  10719.       |*|_                 _|*|
  10720.         |*|_             _|*|
  10721.           |*|__________~red~T~lightGray~|*|
  10722.             |*|*|*|*|*|*|      
  10723. ~red~T~lightGray~ = Turtle on block, not above rail
  10724. ]] -- build down
  10725.     info.sub[98] =  info.sub[97]
  10726.  
  10727. --Measurement tools
  10728.     info.sub[101] =
  10729. [[~yellow~Place me on floor.~lightGray~
  10730.             Measured Height:
  10731. |~lightBlue~*~lightGray~|*|*|*|   ~lightBlue~7. Overhead obstruction
  10732.             ~cyan~7. ~red~NOT ~cyan~detect() ~gray~7. Change~lightGray~
  10733.   |*|*|*|
  10734.   |*|*|*|
  10735.   |~lime~S~lightGray~|*|*|   ~lime~4. Specific block found~lightGray~
  10736.   |*|*|*|
  10737.   |*|*|*|
  10738.   |*|*|*|
  10739.  ~red~T~lightGray~|*|*|~red~T~lightGray~|   ~red~T~lightGray~ = Turtle
  10740. ]] -- measure height
  10741.     info.sub[102] =
  10742. [[~yellow~Depth measurement
  10743. Place me on the floor above pit / edge
  10744.  
  10745.     ~red~T~lightGray~
  10746. 1|*|*|
  10747. 2|*|*|
  10748. 3|*|*|
  10749. 4|*|*|         Measured depth:
  10750. 5|*|~lime~S~lightGray~|         ~lime~5. Specific block found
  10751. ~lightGray~6              ~cyan~6. ~red~NOT ~cyan~turtle.detect()~lightGray~
  10752. 7|*|*|~lightBlue~*~lightGray~|*| |   ~lightBlue~6. Obstruction below
  10753. ]] -- measure depth
  10754.     info.sub[103] =
  10755. [[~yellow~Length measurement
  10756.  
  10757. ~lightGray~1 2 3 4 ~lime~5~lightGray~ 6 ~lime~7 ~cyan~8 ~lightBlue~9~lightGray~ 10
  10758.                       ~cyan~8. No block up
  10759. ~lightGray~*|*|*|*|*|*|~lime~S~lightGray~| |*|*|  ~lime~7. Search block
  10760. ~red~T~lightGray~                |*|  ~lightBlue~9. Obstruction
  10761. ~lightGray~*|*|*|*|~lime~S~lightGray~|*|*| |*|*|  ~lime~5. Search block
  10762.                       ~cyan~8. No block down
  10763.  
  10764. ~red~T ~lightGray~= Turtle
  10765.  
  10766. ]] -- measure length
  10767.     info.sub[104] = info.sub[88] -- measure deepest section of water
  10768.     info.sub[105] =
  10769. [[~yellow~Place turtle anywhere:
  10770.  
  10771.  1. make a ~blue~borehole~yellow~ to chosen level.
  10772.  
  10773.  2. Write a report called:
  10774.  
  10775.  3. ~lime~borehole~blue~X~lime~.txt ~yellow~( ~blue~X ~yellow~= computer ID )
  10776.  
  10777.  4. ~orange~Return home
  10778.  
  10779. ]] -- Borehole: Analyse blocks below
  10780.     info.sub[110] =
  10781. [[~yellow~How many turtles?:
  10782.  
  10783. ~yellow~1.~lightGray~ Alternative positions for ~lime~2 ~lightGray~turtles
  10784. ~lightGray~| |~lime~1~lightGray~|~lime~2~lightGray~| |  |~lime~1~lightGray~| | |~lime~2~lightGray~| | | | | | ground 2
  10785. ~lightGray~|*|~blue~W|W~lightGray~|*|  |*|~blue~W|W~lightGray~|*| |*|~blue~1~lightGray~|~blue~2~lightGray~|*| water  2
  10786.  
  10787. ~yellow~2.~lightGray~ Alternative positions for ~orange~4 ~lightGray~turtles
  10788. ~lightGray~|~orange~1~lightGray~|~orange~2~lightGray~|~orange~3~lightGray~|~orange~4~lightGray~|                      ground 4
  10789. ~lightGray~|*|~blue~W|W~lightGray~|*|                      water  0
  10790.  
  10791. ~yellow~Enter 1 to use ~lime~2 ~yellow~turtles or 2 to use ~orange~4]]  -- initial menu for water canal
  10792.     local line = menu.clear()
  10793.     if menuLevel == 1 then -- general help
  10794.         line = menu.colourText(line, info.main[menuItem], true, true)
  10795.         term.write("Enter to continue ")
  10796.         read()
  10797.         return ""
  10798.     else -- item specific help
  10799.         if info.sub[menuItem] ~= nil then -- help file exists
  10800.             line = menu.colourText(line, info.sub[menuItem], true, true)
  10801.             if noMenu then
  10802.                
  10803.  
  10804.                 if getInteger then
  10805.                     return line -- ready for further input
  10806.                 else
  10807.                     term.setCursorPos(1, 13)
  10808.                     menu.enterToContinue()
  10809.                 end
  10810.             else
  10811.                 term.setCursorPos(1, 13)
  10812.                 term.write("Enter=exit, Any key + Enter=more ")
  10813.                 return read()
  10814.             end
  10815.         end
  10816.     end
  10817. end
  10818.  
  10819. local function getTaskOptions()
  10820.     local options = {}
  10821.     options.main =
  10822.     {
  10823.         "Mining (includes Nether)",
  10824.         "Forestry",
  10825.         "Farming",
  10826.         "Obsidian, Nether & End",
  10827.         "Canal, bridge and walkway",
  10828.         "Spawner farm tools",
  10829.         "Area shaping and clearing",
  10830.         "Lava and Water",
  10831.         "Building and minecart",
  10832.         "Measuring tools"
  10833.     }
  10834.     table.insert(options,
  10835.     {
  10836.         "Ladder up or down",
  10837.         "Stairs up or down",
  10838.         "Create mine at this level",
  10839.         "Safe drop to water block",
  10840.         "Single column bubble lift",
  10841.         "QuickMine corridor system",
  10842.         "QuickMine rectangle",
  10843.         "Mine bedrock level",
  10844.         "Rob disused mineshaft"
  10845.     })
  10846.     table.insert(options,
  10847.     {
  10848.         "Fell Tree",
  10849.         "Create tree farm",
  10850.         "Plant tree farm",
  10851.         "Harvest tree farm",
  10852.         "Fence or wall a forest",
  10853.         "Harvest and replant forest"
  10854.     })
  10855.     table.insert(options,
  10856.     {
  10857.         "Create modular crop farm",
  10858.         "Extend modular crop farm",
  10859.         "Plant, harvest or manage crop farm",
  10860.         "Build a wall or fence",
  10861.         "Fence or wall an enclosure"
  10862.     }) 
  10863.     table.insert(options,                  
  10864.     {
  10865.         "Dig obsidian field",
  10866.         "Build Nether Portal",
  10867.         "Demolish Nether Portal",
  10868.         "Stripmine Netherite",
  10869.         "Undermine Dragon Towers",
  10870.         "Deactivate Dragon Tower",
  10871.         "Build dragon water trap",
  10872.         "Build portal ladder & platform",
  10873.         "Shulker harvester"
  10874.     })
  10875.     table.insert(options,
  10876.     {
  10877.         "Simple path on air, water or lava",
  10878.         "Covered path or tunnel",
  10879.         "Water canal (mulitple options)",
  10880.         "Ice canal (multiple options)",
  10881.         "Platform",
  10882.         "Sinking platform",
  10883.         "Boat bubble lift",
  10884.     })
  10885.     table.insert(options,
  10886.     {
  10887.         "Cube around spawner (NOT blaze)",
  10888.         "Cube around Blaze spawner",
  10889.         "Flood mob farm floor",
  10890.         "Create mob bubble lift",
  10891.         "Computercraft mob grinder",
  10892.         "Build Endermen observation tower"
  10893.     })
  10894.     table.insert(options,
  10895.     {
  10896.         "Clear field (inc trees)",
  10897.         "Clear a rectangle (+ u/d opt)",
  10898.         "Clear single wall up/down",
  10899.         "Clear rectangular wall section",
  10900.         "Clear hollow structure up/down",
  10901.         "Clear solid structure up/down",
  10902.         "Dig a trench",
  10903.         "Carve mountain side",
  10904.         "Place a floor or ceiling",
  10905.         "Direct control of movement"
  10906.     })
  10907.     table.insert(options,
  10908.     {
  10909.         "Sand based utilities",
  10910.         "Vertical wall from surface",
  10911.         "Create enclosed area",
  10912.         "Clear volume of water",
  10913.         "Sinking platform",
  10914.         "Ocean monument utilities",
  10915.         "Ladder down to water/lava",
  10916.         "Clear water plants",
  10917.         "Convert all water to source",
  10918.         "Create sloping water"
  10919.     })
  10920.     table.insert(options,
  10921.     {
  10922.         "Build a wall",
  10923.         "Build a walled area / house",
  10924.         "Build a gable end roof",
  10925.         "Build a pitched roof",
  10926.         "Place Redstone:torch level track",
  10927.         "Place Redstone:torch upward track",
  10928.         "Build downward track",
  10929.         "Build upward track"
  10930.     })
  10931.     table.insert(options,
  10932.     {
  10933.         "Measure height",
  10934.         "Measure depth",
  10935.         "Measure length",
  10936.         "Measure greatest depth",
  10937.         "Borehole: Analyse blocks below"
  10938.     })
  10939.    
  10940.     return options
  10941. end
  10942.  
  10943. local function getTaskColours()
  10944.     local options = {}
  10945.     options.main =
  10946.     {
  10947.         colors.lightGray,   -- Mining (includes Nether)
  10948.         colors.lime,        -- Forestry
  10949.         colors.green,       -- Farming
  10950.         colors.red,         -- Obsidian, Nether & End Portal
  10951.         colors.brown,       -- Canal, bridge and walkway
  10952.         colors.lightGray,   -- Mob farm tools
  10953.         colors.orange,      -- Area shaping and clearing
  10954.         colors.blue,        -- Lava and Water
  10955.         colors.cyan,        -- Railway
  10956.         colors.purple       -- Measuring tools
  10957.     }
  10958.     table.insert(options,
  10959.     {
  10960.         colors.brown,       -- Ladder up or down
  10961.         colors.lightGray,   -- Stairs up or down
  10962.         colors.lightGray,   -- Create mine at this level
  10963.         colors.blue,        -- Safe drop to water block
  10964.         colors.blue,        -- Single column bubble lift
  10965.         colors.magenta,     -- QuickMine corridor system
  10966.         colors.pink,        -- QuickMine rectangle
  10967.         colors.gray,        -- Mine bedrock level
  10968.         colors.brown        -- Rob disused mineshaft
  10969.     })
  10970.     table.insert(options,
  10971.     {
  10972.         colors.brown,       -- Fell Tree
  10973.         colors.lightGray,   -- Create tree farm
  10974.         colors.lime,        -- Plant tree farm
  10975.         colors.green,       -- Harvest tree farm
  10976.         colors.brown,       -- Fence or wall an enclosure
  10977.         colors.lime         -- Harvest and replant forest
  10978.     })
  10979.     table.insert(options,
  10980.     {
  10981.         colors.yellow,      -- Create modular crop farm
  10982.         colors.green,       -- Extend modular crop farm
  10983.         colors.lime,        -- Manage modular crop farm
  10984.         colors.brown,       -- Build wall or fence
  10985.         colors.brown        -- Build rectangle wall or fence
  10986.     }) 
  10987.     table.insert(options,                  
  10988.     {
  10989.         colors.lightGray,   -- Dig obsidian field
  10990.         colors.purple,      -- Build Nether Portal
  10991.         colors.gray,        -- Demolish Nether Portal
  10992.         colors.red,         -- Netherite stripping
  10993.         colors.orange,      -- Undermine Dragon Towers
  10994.         colors.orange,      -- Deactivate Dragon Tower
  10995.         colors.blue,        -- Build dragon water trap
  10996.         colors.lightGray,   -- Build portal minecart station
  10997.         colors.red          -- Shulker harvesting
  10998.     })
  10999.     table.insert(options,
  11000.     {
  11001.         colors.lightGray,   -- Continuous path
  11002.         colors.gray,        -- Covered walkway / tunnel
  11003.         colors.blue,        -- Water canal
  11004.         colors.lightBlue,   -- Ice canal (4 options)
  11005.         colors.brown,       -- Platform
  11006.         colors.blue,        -- Sinking platform for oceans
  11007.         colors.cyan         -- Boat bubble lift
  11008.     })
  11009.     table.insert(options,
  11010.     {
  11011.         colors.brown,       -- Cube around spawner (NOT blaze)
  11012.         colors.red,         -- Cube around Blaze spawner
  11013.         colors.cyan,        -- Flood mob farm floor
  11014.         colors.blue,        -- Create mob bubble lift
  11015.         colors.brown,       -- Dig mob drop trench
  11016.         colors.gray         -- Build Endermen observation tower
  11017.     })
  11018.     table.insert(options,
  11019.     {
  11020.         colors.lime,        -- Clear field (inc trees)
  11021.         colors.magenta,     -- Clear a rectangle (+ u/d opt)
  11022.         colors.pink,        -- Clear single wall up/down
  11023.         colors.purple,      -- Clear rectangular wall section
  11024.         colors.brown,       -- Clear hollow structure up/down
  11025.         colors.orange,      -- Clear solid structure up/down
  11026.         colors.brown,       -- Dig a trench
  11027.         colors.gray,        -- Carve mountain side
  11028.         colors.lightBlue,   -- Place a floor or ceiling
  11029.         colors.red          -- Direct control of movement
  11030.     })
  11031.     table.insert(options,
  11032.     {
  11033.         colors.yellow,      -- Sand based utilities
  11034.         colors.blue,        -- Vertical wall from surface
  11035.         colors.blue,        -- Create enclosed area
  11036.         colors.cyan,        -- Clear volume of water
  11037.         colors.lightGray,   -- Sinking platform
  11038.         colors.orange,      -- Ocean monument utilities
  11039.         colors.brown,       -- Ladder down to water/lava
  11040.         colors.green,       -- Clear water plants
  11041.         colors.lightBlue,   -- Convert all water to source
  11042.         colors.blue         -- Create sloping water
  11043.     })
  11044.     table.insert(options,
  11045.     {
  11046.         colors.yellow,      -- build a wall
  11047.         colors.orange,      -- build rectangular structure
  11048.         colors.lightGray,   -- gable end roof
  11049.         colors.gray,        -- pitched roof
  11050.         colors.red,         -- Place Redstone:torch level track
  11051.         colors.red,         -- Place Redstone:torch upward track
  11052.         colors.orange,      -- Build downward track
  11053.         colors.brown        -- Build upward track
  11054.     })
  11055.     table.insert(options,
  11056.     {
  11057.         colors.red,         -- Measure height
  11058.         colors.purple,      -- Measure depth
  11059.         colors.magenta,     -- Measure length
  11060.         colors.pink,        -- Measure greatest depth
  11061.         colors.lightBlue    -- Borehole: Analyse blocks below
  11062.     })
  11063.    
  11064.     return options
  11065. end
  11066.  
  11067. local function chooseTask(R)
  11068. --[[
  11069.     called from main()
  11070.     R = chooseTask(R)
  11071.     coloured menu: 
  11072.     local pp =
  11073.     {
  11074.         prompt = colors.green,
  11075.         itemColours = {colors.white, colors.red, ... one for each item},
  11076.         menuPrompt = colors.yellow
  11077.     }
  11078.     choice, modifier = menu.menu or menu.new("Choose your option", options, pp)
  11079.     ]]
  11080.     local lib = {}
  11081.    
  11082.     function lib.getHelp(choice, itemsRequired, pp)
  11083.         local listOfItems = itemsRequired[choice]
  11084.         local result = getTaskHelp(2, choice)
  11085.         if result ~= "" then -- any key + enter = more
  11086.             lib.showItems(listOfItems)
  11087.         end
  11088.         T:clear()
  11089.         pp.itemColours = {colors.green, colors.yellow, colors.orange, colors.red}
  11090.         local options ={"Continue with selected task", "return to menu", "Return to main menu","Quit application"}
  11091.         local option = menu.menu("Choose your option", options, pp, "Type number + Enter ")
  11092.         if option == 2 then
  11093.             choice = -2 -- return to subMenu
  11094.         elseif option == 3 then
  11095.             choice = 0 -- return to main menu
  11096.         elseif option == 4 then
  11097.             choice = -1 -- quit
  11098.         -- else return original value of choice
  11099.         end
  11100.        
  11101.         return choice -- if R.choice reset to 0, then re-starts, -1 == quit
  11102.     end
  11103.    
  11104.     function lib.showItems(listOfItems)
  11105.         T:clear()
  11106.         if next(listOfItems) ~= nil then
  11107.             menu.colourPrint("Items required:", colors.lime)
  11108.             for k,v in pairs(listOfItems) do
  11109.                 menu.colourPrint("  "..v, colors.lightGray)
  11110.             end
  11111.         else
  11112.             menu.colourPrint("No items required", colors.lime)
  11113.         end
  11114.         menu.colourWrite("Enter to continue", colors.yellow, colors.black, nil, true)
  11115.         read()
  11116.     end
  11117.    
  11118.     function lib.getItemList(subChoice, itemsRequired)
  11119.         local listOfItems = itemsRequired[subChoice]
  11120.         lib.showItems(listOfItems)
  11121.     end
  11122.    
  11123.     function lib.getChoice(choice, subChoice)
  11124.         if subChoice > 9 then -- need more than 9 sub-options
  11125.             choice = subChoice + (choice * 100) -- 10 = 10 + 1000 = 1100
  11126.         else -- eg main option 1 (mining), sub-option 1 (create mine) = 1 + 10 = 11
  11127.             choice = subChoice + (choice * 10) -- 9 = 9 + 9 * 10 = 99, 1 + 10*10 = 101
  11128.         end
  11129.         return choice
  11130.     end
  11131.    
  11132.     local modifier = ""
  11133.     local subChoice = 0
  11134.     local prompt = "Choose an option"
  11135.     local mainPrompt = "Choose option (+h = help eg 3h):"
  11136.     local subPrompt = "Choose (+h = help +i = items eg 3h):"
  11137.     local options = getTaskOptions()
  11138.     local menuColours = getTaskColours()
  11139.     local itemsRequired = getTaskItemsList()
  11140.     local menuState = 0 -- use main menu
  11141.     -- local pp = utils.getPrettyPrint(colors.cyan, colors.magenta) -- specify menu title and prompt colours
  11142.     --local pp = utils.getPrettyPrint()-- uses default colours
  11143.    
  11144.     while menuState >= 0 do -- menuState has to be -1 to exit loop
  11145.         --[[
  11146.         menu returns choice=nil if user enters just q or h
  11147.         menu returns choice=2, modifier = "h" if 2h entered
  11148.         Mining (includes Nether)        white
  11149.         Forestry                        lime
  11150.         Farming                         lime
  11151.         Obsidian, Nether & End Portal   brown
  11152.         Canal, bridge and walkway       pink   
  11153.         Mob farm tools                  gray
  11154.         Area shaping and clearing       purple 
  11155.         Lava and Water                  blue
  11156.         Railway                         magenta
  11157.         Measuring tools                 cyan       
  11158.         ]]
  11159.        
  11160.         if menuState == 0 then
  11161.             pp.itemColours = menuColours.main
  11162.             local mainChoice, modifier = menu.menu(mainPrompt, options.main, pp) -- open main menu options
  11163.             if modifier == "q" then
  11164.                 R.choice = -1
  11165.                 return R -- quit application
  11166.             elseif modifier == "h" then -- get help on main menu items
  11167.                 getTaskHelp(1, mainChoice) -- "" or any return string for more
  11168.                 R.choice = 0
  11169.                 return R -- quit task system so it re-starts as help menu chosen R.choice = 0
  11170.             else
  11171.                 menuState = 1 -- next level so use sub-menu
  11172.                 R.choice = mainChoice -- 1-10
  11173.             end
  11174.         else
  11175.             pp.prompt = colors.yellow
  11176.             pp.itemColours = menuColours[R.choice]
  11177.             subChoice, modifier = menu.menu(subPrompt, options[R.choice], pp, "Back = 'q' or number + Enter: ") -- open submenu options
  11178.             if modifier == "q" then
  11179.                 R.choice = 0    -- return to root menu. change this to -1 if quit application preferred
  11180.                 return R -- quit task system so it re-starts first menu
  11181.             elseif modifier == "i" then -- get list of items
  11182.                 local index = lib.getChoice(R.choice, subChoice)
  11183.                 lib.getItemList(index, itemsRequired) -- list of items shown
  11184.                 subChoice = nil -- allow menu to continue
  11185.             elseif modifier == "h" then -- get help on main menu items
  11186.                 local index = lib.getChoice(R.choice, subChoice)
  11187.                 index = lib.getHelp(index, itemsRequired, pp)
  11188.                 --R = lib.getHelp(R, itemsRequired, pp) -- if R.choice reset to 0 then will continue
  11189.                 if index == -2 then -- redraw sub-menu
  11190.                     subChoice = nil -- allow menu to continue
  11191.                 elseif index == -1 then -- if R.choice reset to 0 then will continue
  11192.                     R.choice = -1
  11193.                     return R
  11194.                 elseif index == 0 then
  11195.                     R.choice = 0
  11196.                     menuState = 0 -- if R.choice reset to 0 then back to main menu
  11197.                 end
  11198.             end
  11199.             if subChoice ~= nil then
  11200.                 R.choice = lib.getChoice(R.choice, subChoice)
  11201.                 return R -- exit loop
  11202.             end
  11203.         end
  11204.     end
  11205.     return R
  11206. end
  11207.  
  11208. local function getTask(R)
  11209.     -- Called from main(): R = getTask(R)
  11210.     local lib = {}
  11211.    
  11212.     function lib.isAutoHelp(choice, noAutoHelp)
  11213.         for _, v in ipairs(noAutoHelp) do
  11214.             if choice == v then
  11215.                 return true
  11216.             end
  11217.         end
  11218.         return false
  11219.     end
  11220.    
  11221.     local prompt = "Choose an option"
  11222.     local noAutoHelp = {24, 47, 49, 53, 54, 81, 85}
  11223.     if not lib.isAutoHelp(R.choice, noAutoHelp) then -- exclude Water canal, ice canal, sand utilities, monument utilities, dragon trap
  11224.         getTaskHelp(2, R.choice, true)
  11225.         menu.clear()
  11226.     end
  11227. -- 01. MINING
  11228.     if R.choice >= 11 and  R.choice <= 13 then  -- createLadder, createStaircase, createMine)
  11229.         --getTaskHelp(2, R.choice, true)
  11230.         --menu.clear()
  11231.     elseif R.choice == 14 then  -- safe drop to water
  11232.         local currentLevel = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.lightGray)
  11233.         local destLevel = menu.getInteger("Go down to level? ("..currentLevel - 2 .." to "..bedrock + 5 ..")", bedrock + 5 , currentLevel - 2, nil, colors.blue, nil, bedrock + 5)
  11234.         R.height    = math.abs(destLevel - currentLevel)
  11235.     elseif R.choice == 15 then  -- bubble lift
  11236.         local currentLevel = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5 , ceiling, nil, colors.blue, nil, bedrock + 5)
  11237.         local destLevel = menu.getInteger("Go up to level? ("..currentLevel + 2 .." to "..ceiling ..") ", currentLevel + 2, ceiling, nil, colors.lightGray)
  11238.         --[[if currentLevel <= bedrock + 5 then
  11239.             if menu.getBoolean("Confirm close to bedrock (y / n) ", nil, colors.yellow, colors.black) then
  11240.                 R.data = "bedrock"
  11241.             end
  11242.         end]]
  11243.         R.height    = math.abs(destLevel - currentLevel)
  11244.     elseif R.choice == 16 then -- create mining corridor system default: square 17 x 17
  11245.         local choices = {"At corridor start, on the floor",
  11246.                          "At corridor start, on the ceiling",
  11247.                          "On floor, move forward to start",
  11248.                          "On ceiling, move forward to start"}
  11249.         pp.itemColours = {colors.lime, colors.green, colors.magenta, colors.pink}
  11250.         local userChoice, modifier = menu.menu("Starting position?", choices, pp, "Type number + Enter ") -- 1 to 4
  11251.         if modifier == "q" then -- quit chosen
  11252.             R.data = "quit"
  11253.             return R
  11254.         end
  11255.         R.width     = menu.getInteger("Width (2-64 default 17) ", 2, 64, nil, colors.yellow, nil, 17)
  11256.         R.length    = menu.getInteger("Length (2-64 default 17) ", 2, 64, nil, colors.orange, nil, 17)
  11257.         R.torchInterval = 9 -- 8 spaces between torches
  11258.         if mcMajorVersion >= 1.18 then
  11259.             R.torchInterval = 17 -- 16 spaces between torches
  11260.         end
  11261.         R.subChoice = userChoice
  11262.     elseif R.choice == 17 then -- clear a rectangle, fill empty spaces above
  11263.         local choices = {"At mine area start, on the floor",
  11264.                          "At mine area start, on the ceiling",
  11265.                          "On floor, move forward to start",
  11266.                          "On ceiling, move forward to start",
  11267.                          "On floor diagonally to left"} -- just finished corridor
  11268.         pp.itemColours = {colors.lime, colors.green, colors.magenta, colors.pink, colors.red}
  11269.         local userChoice, modifier = menu.menu("Starting position?", choices, pp, "Type number + Enter ") -- 1 to 4
  11270.         if modifier == "q" then -- quit chosen
  11271.             R.data = "quit"
  11272.             return R
  11273.         end
  11274.         R.width     = menu.getInteger("Width (2-64 default 15) ", 2, 64, nil, colors.yellow, nil, 15)
  11275.         R.length    = menu.getInteger("Length (2-64 default 15) ", 2, 64, nil, colors.orange, nil, 15)
  11276.         R.subChoice = userChoice
  11277.     elseif R.choice == 18 then -- Mine bedrock area
  11278.         --getTaskHelp(2, R.choice, true)
  11279.         --menu.clear()
  11280.         R.width     = menu.getInteger("Width (2-64 default 17) ", 2, 64, nil, colors.yellow, nil,  17)
  11281.         R.length    = menu.getInteger("Length (2-64 default 17) ", 2, 64, nil, colors.orange, nil,  17)
  11282.         if menu.getBoolean("Leave bedrock exposed? (y/n) ", nil, colors.yellow) then
  11283.             R.data = "leaveExposed"
  11284.         end
  11285.     elseif R.choice == 19 then -- salvage mine shaft
  11286.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11287. -- 02. FORESTRY
  11288.     elseif R.choice == 22 then --Create treefarm
  11289.         R.width = 15
  11290.         R.length = 15
  11291.         pp.itemColours = {colors.lightGray, colors.green}
  11292.         choices = {"New tree farm. Start here", "On right side of existing farm" }
  11293.         local choice = menu.menu(prompt, choices, pp, "Type number + Enter ")
  11294.         if choice == 2 then
  11295.             R.data = "existing"
  11296.         end
  11297.         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)
  11298.     elseif R.choice == 23 then -- plant treefarm
  11299.         local choices   = {"16 single trees", "4 double trees any type"}
  11300.         pp.itemColours = {colors.lime, colors.green}
  11301.         R.subChoice = menu.menu(prompt, choices, pp, "Type number + Enter ")
  11302.     --elseif R.choice == 24 then -- Harvest treefarm
  11303.    
  11304.     elseif R.choice == 25 then -- Build wall or fence
  11305.         R.width     = menu.getInteger("Width of the area (1-64)", 1, 64, nil, colors.yellow)
  11306.         R.length    = menu.getInteger("Length of the area (1-64)", 1, 64, nil, colors.orange)
  11307.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11308.         if menu.getBoolean("Storage barrels in corners? (y/n)", nil, colors.brown) then
  11309.             R.data = "barrel"
  11310.         end
  11311.     elseif R.choice == 26 then -- Harvest and replant natural forest
  11312.  
  11313.        
  11314. -- 03. FARMING
  11315.     elseif R.choice == 31 then -- new crop farm
  11316.  
  11317.     elseif R.choice == 32 then -- extend crop farm
  11318.         local choices   = {"Add a farm at the back", "Add a farm to the right"}
  11319.         pp.itemColours = {colors.lime, colors.green}
  11320.         R.subChoice = menu.menu(prompt, choices, pp, "Type number + Enter ")
  11321.     elseif R.choice == 33 then -- manage crop farm
  11322.  
  11323.     elseif R.choice == 34 then -- fence or wall
  11324.         R.length    = menu.getInteger("Length of wall / fence (1-256)", 1, 256, nil, colors.orange)
  11325.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11326.     elseif R.choice == 35 then -- rectangle fence or wall
  11327.         R.width     = menu.getInteger("Width of the area (1-64)", 1, 64, nil, colors.yellow)
  11328.         R.length    = menu.getInteger("Length of the area (1-64)", 1, 64, nil, colors.orange)
  11329.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11330.    
  11331. -- 04. OBSIDIAN
  11332.     elseif R.choice == 41 then  -- Harvest obsidian
  11333.         R.width     = menu.getInteger("Width of the area (1-64) ", 1, 64, nil, colors.yellow)
  11334.         R.length    = menu.getInteger("Length of the area (1-64) ", 1, 64, nil, colors.orange)
  11335.     elseif R.choice == 42 or R.choice == 43 then -- build Nether portal / demolish Nether portal
  11336.         local choices = {"Facing portal: forward, turn right",
  11337.                          "Aligned with portal: start ahead"}
  11338.         pp.itemColours = {colors.pink, colors.red}
  11339.         local userChoice, modifier = menu.menu("Starting position?", choices, pp, "Type number + Enter ") -- 1 to 2
  11340.         R.subChoice = userChoice
  11341.         if modifier == "q" then -- quit chosen
  11342.             R.data = "quit"
  11343.             return R
  11344.         end
  11345.         R.length    = menu.getInteger("Portal width", 1, 64, nil, colors.yellow, nil, 4)
  11346.         R.height    = menu.getInteger("Portal height (inc. buried base)", 1, 64, nil, colors.lightGray, nil, 5)
  11347.         R.width     = menu.getInteger("Thickness (Usually 1) Enter = 1)", 1, 64, nil, colors.red, nil, 1)
  11348.         if menu.getBoolean("Base below surface (y/n)", nil, colors.orange) then
  11349.             R.data = "bury"
  11350.         end
  11351.     elseif R.choice == 44 then -- Netherite stripping
  11352.         R.width     = 1
  11353.         while R.length == 0 or R.length % 16 > 0 do
  11354.             R.length = menu.getInteger("Strip length (divisible by 16) ", 16, 512, 1, colors.orange)
  11355.             if R.length % 16 > 0 then
  11356.                 menu.colourText(1, "~red~Must be multiple of 16")
  11357.             end
  11358.         end
  11359.         R.torchInterval = 16
  11360.         R.data = "seal"
  11361.     elseif R.choice == 45 then -- undermine dragon towers
  11362.  
  11363.     elseif R.choice == 46 then -- deactivate dragon tower
  11364.    
  11365.     elseif R.choice == 47 then -- build dragon water trap
  11366.         local text =
  11367. [[~yellow~You ~red~MUST ~yellow~have already constructed a
  11368. bridge / tunnel into the dragon island
  11369. to allow for safe construction of the
  11370. dragon trap.
  11371.  
  11372. If not use toolkit:
  11373.   ~brown~5.~gray~2 Covered path or tunnel~yellow~ length 100
  11374.  
  11375. start centre of obsidian platform:
  11376.   100,49,0 facing west]]
  11377.         menu.colourText(1, text)
  11378.         if menu.getBoolean("Bridge already made? (y/n)", 12, colors.orange) then
  11379.             getTaskHelp(2, R.choice, true)
  11380.             menu.clear()
  11381.         else
  11382.             R.data = "quit"
  11383.             return R
  11384.         end
  11385.     elseif R.choice == 48 then -- build end portal minecart station
  11386.     elseif R.choice == 49 then -- Shulker harvesting
  11387.         local items =
  11388.         {
  11389.             "Shulker is above",
  11390.             "Shulker is ahead",
  11391.             "Shulker is below",
  11392.             "Climb tower wall",
  11393.             "Clear roof above",
  11394.             "Clear outside walls"
  11395.         }
  11396.         pp.itemColours = {colors.lightGray, colors.brown, colors.blue, colors.yellow, colors.orange, colors.lightGray}
  11397.         R.subChoice = menu.menu("Which utility? ", items, pp)
  11398.         getTaskHelp(2, R.choice * 10 + R.subChoice, true)  -- eg 490 + 1 = 491
  11399.         menu.clear()   
  11400.        
  11401. -- 05. CANAL BRIDGE
  11402.     elseif R.choice == 51 then  --single path
  11403.         if menu.getBoolean("Shorten an existing path? (y/n)", nil, colors.brown) then
  11404.             R.data = "reduce"
  11405.         end
  11406.         if R.data == "reduce" then
  11407.             R.length = menu.getInteger("Reduce by? 0 = here to end", 0, 1024, nil, colors.orange, nil, 64)
  11408.         else
  11409.             R.length = menu.getInteger("Path length? 0 = continuous ", 0, 1024, nil, colors.orange, nil, 64)
  11410.             R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, line, colors.red, nil, 0)
  11411.         end
  11412.     elseif R.choice == 52 then  -- 2 block corridor / covered walkway
  11413.         R.length    = menu.getInteger("Corridor length?", 1, 1024, nil, colors.orange, nil, 64)
  11414.         R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, nil, colors.red)
  11415.         if menu.getBoolean("Seal off water or lava? (y/n)", nil, colors.brown) then
  11416.             R.data = "seal"
  11417.         end
  11418.     elseif R.choice == 53 then  --left/right side of new/existing canal
  11419.         local line = getTaskHelp(2, 110, true, true) -- request line no of help display if needed for getInteger
  11420.         R.data = menu.getInteger("Choose method 1 or 2", 1, 2, line + 1, colors.white)  -- 2 or 4 turtles
  11421.         menu.clear()
  11422.         line = getTaskHelp(2, R.choice, true, true) -- request line no of help display if needed for getInteger
  11423.         R.subChoice = menu.getInteger("Type position of this turtle", 1, 6, line + 1, colors.white)
  11424.         local position = "on ground"
  11425.         local side = "left"
  11426.         local colour = colors.lime
  11427.         if R.subChoice == 1 then
  11428.             R.side = "L"
  11429.             R.height = 1
  11430.             position = "on ground"
  11431.             colour = colors.lime
  11432.         elseif R.subChoice == 2 then
  11433.             R.side = "L"
  11434.             R.height = 1
  11435.             position = "above canal"
  11436.             colour = colors.orange
  11437.         elseif R.subChoice == 3 then
  11438.             R.side = "R"
  11439.             side = "right"
  11440.             R.height = 1
  11441.             position = "above canal"
  11442.             colour = colors.brown
  11443.         elseif R.subChoice == 4 then
  11444.             R.side = "R"
  11445.             side = "right"
  11446.             R.height = 1
  11447.             colour = colors.green
  11448.         elseif R.subChoice == 5 then
  11449.             R.side = "L"
  11450.             R.height = 0
  11451.             position = "on canal base"
  11452.             colour = colors.blue
  11453.         elseif R.subChoice == 6 then
  11454.             R.side = "R"
  11455.             side = "right"
  11456.             R.height = 0
  11457.             position = "on canal base"
  11458.             colour = colors.cyan
  11459.         end
  11460.         line = menu.clear()
  11461.         if R.data == 1 or (R.data == 2 and (R.subChoice == 1 or R.subChoice == 4)) then
  11462.             R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, line, colors.red, nil, 0)
  11463.         end
  11464.         -- menu.colourPrint(text, fg, bg, width)
  11465.         -- menu.colourText(row, text, reset)
  11466.         menu.colourPrint("Turtle placed "..side.." "..position, colour)
  11467.         R.length    = menu.getInteger("Canal length? 0 = continuous ", 0, 512, line + 2, colors.orange, nil, 64)
  11468.     elseif R.choice == 54 then  --ice canal 4 sections: edge+torch, edge, centre+ice, centre no ice
  11469.         local line = getTaskHelp(2, R.choice, true, true) -- request line no of help display if needed for getInteger
  11470.         R.subChoice = menu.getInteger("Type turtle position", 1, 8, line, colors.white)
  11471.         R.side = "L"
  11472.         local position = "on towpath"
  11473.         local side = "left"
  11474.         local colour = colors.lime
  11475.         line = menu.clear()
  11476.         --[[
  11477.             new canal
  11478.             1 = left towpath- move to centre left
  11479.             2 = centre left ice or hollow
  11480.             3 = centre right ice or hollow
  11481.             4 = right side - move to centre right
  11482.             convert water canal
  11483.             5 = left towpath
  11484.             6 = centre left ice or air
  11485.             7 = centre right ice or air
  11486.             8 = right towpath
  11487.         ]]
  11488.         if R.subChoice == 1 or R.subChoice == 4 or R.subChoice == 5 or R.subChoice == 8 then
  11489.             -- on towpath r/l
  11490.             R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, line, colors.red, nil, 0)
  11491.             if R.subChoice == 4 or R.subChoice == 8 then
  11492.                 side = "right"
  11493.                 R.side = "R"
  11494.             end
  11495.             if R.subChoice <= 4 then -- 1 or 4 only
  11496.                 if menu.getBoolean("Place Ice as well? (y/n)", line + 1, colors.blue) then
  11497.                     R.data = "ice"
  11498.                 end
  11499.             end
  11500.         else -- on canal centre r/l
  11501.             if R.subChoice == 3 or R.subChoice == 7 then
  11502.                 side = "right"
  11503.                 R.side = "R"
  11504.             end
  11505.             if R.subChoice == 2 or R.subChoice == 3 then -- new canal
  11506.                 R.torchInterval = menu.getInteger("Torch spacing? (0-64)", 0, 64, line, colors.red, nil, 0)
  11507.                 position = "above air/ice"
  11508.             end
  11509.             if menu.getBoolean("Place Ice as well? (y/n)", line + 1, colors.blue) then
  11510.                 R.data = "ice"
  11511.                 if R.subChoice == 6 or R.subChoice == 7 then   
  11512.                     position = "alternate air/ice"
  11513.                     colour = colors.lightBlue
  11514.                 end
  11515.             else
  11516.                 if R.subChoice == 6 or R.subChoice == 7 then   
  11517.                     position = "on air spaces"
  11518.                     colour = colors.lighGray
  11519.                     if R.subChoice == 7 then
  11520.                         side = "right"
  11521.                         R.side = "R"
  11522.                     end
  11523.                 end
  11524.             end
  11525.         end
  11526.         R.length    = menu.getInteger("Canal length? 0 = continuous ", 0, 1024, line + 2, colors.orange, nil, 64)
  11527.         menu.colourPrint("Turtle on "..side.." side "..position, colour)
  11528.         sleep(2)
  11529.     elseif R.choice == 55 then  --platform
  11530.         R.width     = menu.getInteger("Platform width", 1, 256, 1, colors.yellow)
  11531.         R.length    = menu.getInteger("Platform length", 1, 256, 2, colors.orange)
  11532.         if menu.getBoolean("Remove blocks above? (y/n)",3, colours.red) then
  11533.             R.up = true
  11534.         end
  11535.        
  11536.     elseif R.choice == 56 then  --sinking platform
  11537.         R.width     = menu.getInteger("Width (excluding retaining wall)? ", 1, 1024, nil, colors.yellow)
  11538.         R.length    = menu.getInteger("Length (excluding retaining wall)? ", 1, 1024 / R.width, nil, colors.orange)
  11539.         R.height    = menu.getInteger("Levels to go down?", 1, 1024 / R.width * R.length, nil, colors.blue)
  11540.     elseif R.choice == 57 then  --boat bubble lift
  11541.         R.height    = menu.getInteger("Levels to go up?", 1, ceiling - 2, nil, colors.lightBlue)
  11542.        
  11543. -- 06. MOB SPAWNER TOOLS
  11544.     elseif R.choice == 61 then -- create cube round mob spawner
  11545.         local text =
  11546. [[~yellow~Turtle placement options:
  11547.  
  11548. ~lime~1. On top or in front of the spawner
  11549.    ~green~(cave spider OR no chests around)
  11550. ~lightGray~2. Outside the dungeon at floor or
  11551.    ceiling level ~red~1 block from corner
  11552. ~yellow~Make sure you have access to the block
  11553. facing the spawner, as any chests
  11554. found inside will be placed outside
  11555. the new dungeon wall at this height
  11556.  
  11557. ~white~Enter to continue
  11558. ]]
  11559.         menu.colourText(nil, text, true)
  11560.         read()
  11561.         menu.clear()
  11562.         R.data = "spawner"
  11563.         if menu.getBoolean("Any chests around spawner? (y/n)",1, colours.red) then
  11564.             R.data = "chest"
  11565.         end
  11566.         local choices = {"Turtle on spawner (no chests)",
  11567.                          "Outside wall: left side, floor",
  11568.                          "Outside wall: left side, ceiling",
  11569.                          "Outside wall: right side, floor",
  11570.                          "Outside wall: right side, ceiling"}
  11571.         pp.itemColours = {colors.red, colors.lime, colors.orange, colors.green, colors.yellow}
  11572.         local userChoice, modifier = menu.new("Select turtle position", choices, pp) -- 1 to 5
  11573.        
  11574.         if modifier == "q" then -- quit chosen
  11575.             R.data = "quit"
  11576.             return R
  11577.         end
  11578.         R.subChoice     = userChoice
  11579.         if R.subChoice > 1 then -- get dungeon wall dimensions
  11580.             R.width     = menu.getInteger("Dungeon external width ", 0, 11, nil, colors.yellow, nil, 11)
  11581.             R.length    = menu.getInteger("Dungeon external length ", 0, 11, nil, colors.orange, nil, 11)
  11582.         end
  11583.        
  11584.     elseif R.choice == 62 then -- Blaze spawner
  11585.         local text =
  11586. [[~yellow~Turtle placement options:
  11587.  
  11588. ~red~1a On top of the spawner
  11589.  
  11590. ~red~1b ~orange~At the same level in direct line of
  11591. spawner.~yellow~ (can be behind a safety wall)
  11592.  
  11593. ~red~1c~lightGray~ Room below spawner (via stairs)
  11594.  
  11595. ~lime~2 Finish build: In brick floor outside
  11596.   existing cube. (facing player)
  11597.  
  11598. ~white~Enter to continue]]
  11599.         menu.colourText(nil, text, true)
  11600.         read()
  11601.         pp.itemColours = {colors.red, colors.lime}
  11602.         R.subChoice = menu.new("Choose your option", {"New Blaze spawner", "Complete part build (killzone)"}, pp, "Type number + Enter") -- 1 = new, 2= continue
  11603.         R.data = "blaze"            -- default
  11604.         if R.subChoice == 1 then    -- new blaze spawner
  11605.             text =
  11606. [[~yellow~Turtle placement options:
  11607. ~red~1. On top of the spawner
  11608. ~orange~2. In direct sight (safety wall ok)
  11609. ~lightGray~3. Room below spawner (via stairs)
  11610.    |*|*|*|*|*|   Ceiling
  11611.    |*|*|~red~T~lightGray~|*|*|   Turtle under ceiling
  11612.    |*|~brown~+~lightGray~|*|~brown~+~lightGray~|*|   Top of fence
  11613.    |*|~brown~+~lightGray~|*|~brown~+~lightGray~|*|
  11614.    |*|~brown~+~lightGray~|*|~brown~+~lightGray~|*|   Bottom of fence
  11615.    |*|*|*|*|*|   Floor level]]
  11616.             --R.subChoice = menu.new("Choose your position", {"On top of spawner", "In direct sight (safety wall ok)", "Room below spawner"}, pp, "Type number + Enter")
  11617.             --getInteger(prompt, minValue, maxValue, row, fg, bg, default)
  11618.             T:clear()
  11619.             menu.colourText(nil, text, true)
  11620.             R.subChoice = menu.getInteger("Enter position number", 1, 3, 12, colors.white)
  11621.         else
  11622.             R.data = "restart"      -- complete part build
  11623.         end
  11624.     elseif R.choice == 63 then -- flood spawner cube
  11625.         local choices = {"Bubble lift", "Computercraft mob softener"}
  11626.         pp.itemColours = {colors.lime, colors.orange}
  11627.         local userChoice = menu.menu("Flood for Mob grinder type?", choices, pp, "Type number + Enter ")
  11628.         R.subChoice = userChoice -- 1 bubble, 2 computercraft
  11629.     elseif R.choice == 64 then -- create bubble lift at mob spawner
  11630.         local choices = {"Dropzone on left", "Dropzone on right"}
  11631.         pp.itemColours = {colors.lime, colors.orange}
  11632.         local userChoice = menu.menu("Which side do you want the mobs?", choices, pp, "Type number + Enter")
  11633.         R.subChoice = userChoice -- 1 left, 2 right
  11634.     elseif R.choice == 65 then -- Computercraft mob grinder
  11635.         local choices = {"Use Sticky pistons", "Use non-sticky pistons"}
  11636.         pp.itemColours = {colors.lime, colors.orange}
  11637.         local userChoice = menu.menu("Which type of pistons?", choices, pp, "Type number + Enter ")
  11638.         R.subChoice = userChoice -- 1 sticky, 2 normal
  11639.    
  11640. -- 07. AREA CARVING
  11641.     elseif R.choice == 71 then --Clear field
  11642.         R.width     = menu.getInteger("Width of the area (1-64)", 1, 64, nil, colors.yellow)
  11643.         R.length    = menu.getInteger("Length of the area (1-64)", 1, 64, nil, colors.orange)
  11644.         if menu.getBoolean("Dirt on the surface (y/n)", nil, colors.brown) then
  11645.             R.useBlockType = "dirt"
  11646.         end
  11647.     elseif R.choice == 72 then -- Clear solid rectangle R.width, R.length
  11648.         R.width     = menu.getInteger("Rectangle width (1-256)", 1, 256, nil, colors.yellow)
  11649.         R.length    = menu.getInteger("Rectangle length (1-256)", 1, 256, nil, colors.orange)
  11650.         R.up        = menu.getBoolean("Remove blocks above?", nil, colors.yellow)
  11651.         R.down      = menu.getBoolean("Remove blocks below?", nil, colors.orange)
  11652.         if menu.getBoolean("Am I outside clearing zone (y/n)?", nil, colors.yellow) then
  11653.             T:forward(1)
  11654.         end
  11655.     elseif R.choice == 73 then -- Clear wall
  11656.         R.width     = 1
  11657.         R.length    = menu.getInteger("Length of wall (1-256) ", 1, 256, nil, colors.orange)
  11658.         R.height    = menu.getInteger("Height of wall (1-50) ", 1, 50, nil, colors.lightGray)
  11659.         pp.itemColours = {colors.lime, colors.orange}
  11660.         R.subChoice = menu.menu("Which direction?", {"Bottom -> Top", "Top -> Bottom"}, pp, "Type number + Enter ") -- open direction menu options
  11661.         if R.subChoice == 1 then
  11662.             if menu.getBoolean("Am I outside clearing zone (y/n)?", nil, colors.yellow) then
  11663.                 T:forward(1)
  11664.             end
  11665.         else
  11666.             pp.itemColours = {colors.lightBlue, colors.cyan, colors.blue, colors.gray}
  11667.             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 ")
  11668.             if choice == 1 then
  11669.                 T:down(1)
  11670.             elseif choice == 2 then
  11671.                 T:forward(1)
  11672.             elseif choice == 4 then
  11673.                 T:go("D1F1")
  11674.             end
  11675.         end
  11676.     elseif R.choice == 74 then -- Clear rectangle perimeter only R.width, R.length
  11677.         R.width     = menu.getInteger("Perimeter width (1-256) ", 1, 256, nil, colors.yellow)
  11678.         R.length    = menu.getInteger("Perimeter length (1-256) ", 1, 256, nil, colors.orange)
  11679.         R.height    = 1
  11680.         if menu.getBoolean("Remove blocks above? (y/n)", 3, colours.red) then
  11681.             R.up = true
  11682.         end
  11683.         if menu.getBoolean("Remove blocks below? (y/n)", 4, colours.red) then
  11684.             R.down = true
  11685.         end
  11686.         if menu.getBoolean("Am I outside clearing zone (y/n)?", 5, colors.yellow) then
  11687.             T:forward(1)
  11688.         end
  11689.     elseif R.choice == 75 or R.choice == 76 then -- Clear hollow building floor/walls/ceiling OR clear solid object
  11690.         R.width     = menu.getInteger("Structure width (1-256)", 1, 256, nil, colors.yellow)
  11691.         R.length    = menu.getInteger("Structure length (1-256)", 1, 256, nil, colors.orange)
  11692.         R.height    = menu.getInteger("Depth/Height (1-256)", 1, 256, nil, colors.lightGray)
  11693.         if R.choice == 75 then -- hollow building so need to check if floors/ceilings to be removed
  11694.             R.data = {}
  11695.             R.data.ceiling = false
  11696.             R.data.floor = false
  11697.             if menu.getBoolean("Remove ceiling? (y/n)", nil, colors.yellow, colors.black) then
  11698.                 R.data.ceiling = true
  11699.             end
  11700.             if menu.getBoolean("Remove floor? (y/n)", nil, colors.orange, colors.black) then
  11701.                 R.data.floor = true
  11702.             end
  11703.         end
  11704.         pp.itemColours = {colors.lime, colors.orange}
  11705.         R.subChoice = menu.menu("Which direction?", {"Bottom -> Top", "Top -> Bottom"}, pp, "Type number + Enter ") -- open direction menu options
  11706.         if R.subChoice == 1 then
  11707.             if menu.getBoolean("Am I outside clearing zone (y/n)?", nil, colors.yellow) then
  11708.                 T:forward(1)
  11709.             end
  11710.         else
  11711.             pp.itemColours = {colors.lightBlue, colors.cyan, colors.blue, colors.gray}
  11712.             local choice = menu.menu("Exact position?", {"On top of clearing zone", "Outside clearing zone", "Inside clearing zone","Above AND outside"}, pp, "Type number + Enter ")
  11713.             if choice == 1 then
  11714.                 T:down(1)
  11715.             elseif choice == 2 then
  11716.                 T:forward(1)
  11717.             elseif choice == 4 then
  11718.                 T:go("D1F1")
  11719.             end
  11720.         end
  11721.     elseif R.choice == 77 then  -- Dig a trench
  11722.         R.height    = menu.getInteger("Depth of the trench (1-64) ", 1, 64, nil, colors.blue)
  11723.         R.length    = menu.getInteger("Trench length? 0 = continuous ", 0, 1024, nil, colors.orange)
  11724.     elseif R.choice == 78 then  -- Carve side of mountain
  11725.         pp.itemColours = {colors.lime, colors.orange}
  11726.         R.subChoice = menu.menu("Remove blocks on which side?", {"Left", "Right"}, pp, "Type number + Enter ") -- open direction menu options
  11727.         R.width     = menu.getInteger("Remove how many vertical rows? ", 1, 1024, nil, colors.yellow)
  11728.         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)
  11729.     elseif R.choice == 79 then  -- Place a floor or ceiling
  11730.         local items = { "Replacing current floor",
  11731.                         "New floor over existing",
  11732.                         "Replacing current ceiling",
  11733.                         "New ceiling under existing"}
  11734.         pp.itemColours = {colors.lime, colors.orange, colors.green, colors.yellow}
  11735.         R.subChoice = menu.menu("Laying what?", items, pp, "Type number + Enter ")
  11736.         R.height = menu.getInteger({"Enter 0 for on-site placement",
  11737.                                     "If in deep water or above reach",
  11738.                                     "Enter approx depth/height"}, 0, 64, nil, {colors.yellow, colors.blue, colors.cyan} )
  11739.         if R.subChoice < 3 then
  11740.             R.down = true
  11741.             R.width     = menu.getInteger("Width of floor (1-64) ", 1, 64, nil, colors.yellow)
  11742.             R.length    = menu.getInteger("Length of floor (1-64) ", 1, 64, nil, colors.orange)
  11743.         else
  11744.             R.up = true
  11745.             R.width     = menu.getInteger("Width of ceiling (1-64) ", 1, 64, nil, colors.yellow)
  11746.             R.length    = menu.getInteger("Length of ceiling (1-64) ", 1, 64, nil, colors.orange)
  11747.         end
  11748.     elseif R.choice == 710 or R.choice == 83 then -- Direct movement
  11749.         local choices = {"Simple path", "Covered 2 block high path"}
  11750.         pp.itemColours = {colors.lime, colors.orange}
  11751.         local userChoice = menu.menu("Choose your path option", choices, pp, "Type number + Enter ")
  11752.         R.subChoice = userChoice -- 1 open, 2 covered
  11753.         choices = {"Command driven", "Menu driven"}
  11754.         userChoice = menu.menu("Choose your preference", choices, pp, "Type number + Enter ")
  11755.         if userChoice == 1 then
  11756.             R.data = "cmd"
  11757.         else
  11758.             R.data = "menu"
  11759.         end
  11760.        
  11761. -- 08. WATER LAVA
  11762.     elseif R.choice == 81 then -- Sand based utilities
  11763.         local line = getTaskHelp(2, R.choice, true, true) -- request line no of help display if needed for getInteger
  11764.         R.subChoice = menu.getInteger("Type number of choice", 1, 4, line, colors.white)
  11765.         T:clear()
  11766.         if R.subChoice == 1 then -- drop sand into water or lava surface until solid ground reached
  11767.             R.width   = 1
  11768.             R.length  = menu.getInteger("Length of sand wall (0=to block) ", 0, 60, nil, colors.orange)
  11769.         elseif R.subChoice == 2 then    -- clear rectangle on top of building and fill with sand
  11770.             R.width   = menu.getInteger("Width of area (<=30) ", 1, 30, nil, colors.yellow)
  11771.             R.length  = menu.getInteger("Length of of area (<=30) ", 1, 30, nil, colors.orange)
  11772.         elseif R.subChoice == 3 then    -- clear sand wall or harvest sand
  11773.             R.width   = 1
  11774.             R.length  = menu.getInteger("Length of sand (0=auto-detect)", 0, 60, nil, colors.orange)
  11775.             choices = {"Stay at end of wall", "Return home"}
  11776.             pp.itemColours = {colors.lime, colors.orange}
  11777.             userChoice = menu.menu("Choose your preference", choices, pp, "Type number + Enter ")
  11778.             if userChoice == 2 then
  11779.                 R.data = "return"
  11780.             end
  11781.         elseif R.subChoice == 4 then    -- remove sand from cube. start at top
  11782.             R.width   = menu.getInteger("Width of sand (<=30) ", 1, 30, nil, colors.yellow)
  11783.             R.length  = menu.getInteger("Length of of sand (<=30) ", 1, 30, nil, colors.orange)
  11784.             R.height  = 0
  11785.             R.data = "down" -- always starts at the top
  11786.         end
  11787.         if menu.getBoolean("Am I outside the active zone (y/n)?", nil, colors.yellow) then
  11788.             T:forward(1)
  11789.         end
  11790.     elseif R.choice == 82 then -- build wall from water or lava surface downwards
  11791.         R.width     = 1
  11792.         if menu.getBoolean("Going 90 deg. from existing? (y/n)", nil, colors.yellow, colors.black) then
  11793.             getTaskHelp(2, 852, true)
  11794.             menu.clear()   
  11795.             R.length = 56
  11796.             R.data = "withPath" -- ensures turtle will break through path
  11797.             R.length = menu.getInteger({"Wall length minus corners","(Ocean monument default 56)","Number -> Enter or Enter only (56)"},
  11798.                                         1, 64, nil, {colors.yellow, colors.orange, colors.green}, colors.black, 56)
  11799.         else
  11800.             R.length    = menu.getInteger("Length of the wall (1-60) ", 1, 60, nil, colors.yellow)
  11801.             R.height    = menu.getInteger("Fixed depth or 0 = to floor ", 0, 60, nil, colors.yellow)
  11802.         end
  11803.     -- for 83 see 710
  11804.     elseif R.choice == 84 then -- Clear area of water bounded by blocks
  11805.         R.width     = menu.getInteger("Width of water (0=autodetect) ", 0, 64, nil, colors.yellow)
  11806.         if R.width > 0 then
  11807.             R.length = menu.getInteger("Length of water", 1, 64, nil, colors.orange)
  11808.         end
  11809.         R.height    = menu.getInteger("Depth of water (0=autodetect)", 0, 64, nil, colors.blue)
  11810.     elseif R.choice == 85 then -- Sinking platform
  11811.         R.width     = menu.getInteger("Width (excluding retaining wall)? ", 1, 1024, nil, colors.yellow)
  11812.         R.length    = menu.getInteger("Length (excluding retaining wall)? ", 1, 1024 / R.width, nil, colors.orange)
  11813.         R.height    = menu.getInteger("Levels to go down?", 1, 1024 / R.width * R.length, nil, colors.blue)
  11814.     elseif R.choice == 86 then -- ocean monument utilities
  11815.         local items =
  11816.         {
  11817.             "Build 4 corner marker columns",
  11818.             "Retaining wall beween 2 columns",
  11819.             "Clear plants pre sand draining",
  11820.             "Drop sand wall",
  11821.             "Recover sand wall",
  11822.             "Sinking platform",
  11823.             "Drain and remove structure"   
  11824.         }
  11825.         pp.itemColours = {colors.lightGray, colors.brown, colors.blue, colors.yellow, colors.orange, colors.lightGray, colors.gray}
  11826.         R.subChoice = menu.menu("Which utility? ", items, pp)
  11827.         if R.subChoice ~= nil then
  11828.             getTaskHelp(2, R.choice * 10 + R.subChoice, true)
  11829.         end
  11830.         menu.clear()   
  11831.         if R.subChoice == 1 then -- Build 4 corner marker columns          
  11832.             R.useBlockType = "prismarine"
  11833.             R.data = "oceanMonumentColumns"
  11834.         elseif R.subChoice == 2 then -- Retaining wall beween 2 columns
  11835.             R.length = 56
  11836.             R.data = "withPath" -- ensures turtle will break through path
  11837.             T:clear()
  11838.             R.length = menu.getInteger({"Wall length minus corners","(Ocean monument default 56)","Number -> Enter or Enter only (56)"},
  11839.                                          1, 64, nil, {colors.yellow, colors.orange, colors.green}, colors.black, 56)
  11840.         elseif R.subChoice == 3 then -- Clear plants pre sand draining
  11841.             R.useBlockType = "prismarine"
  11842.             R.data = "clearWaterPlants"
  11843.             R.silent = true
  11844.             R.width     = menu.getInteger("water width (0=auto detect) ", 0, 64, nil, colors.yellow)
  11845.             R.length    = menu.getInteger("water length (0=auto detect) ", 0, 64, nil, colors.orange)
  11846.         elseif R.subChoice == 4 then -- Drain using sand utilities
  11847.             R.width   = 1
  11848.             R.length  = 0
  11849.         elseif R.subChoice == 5 then -- remove sand wall using sand utilities
  11850.             R.width   = 1
  11851.             R.length  = 0
  11852.         elseif R.subChoice == 6 then -- sinking platform
  11853.             R.width = menu.getInteger("Width (excluding retaining wall)? ", 1, 1024, nil, colors.yellow)
  11854.             R.length = menu.getInteger("Length (excluding retaining wall)? ", 1, 1024 / R.width, nil, colors.orange)
  11855.             R.height = menu.getInteger("Levels to go down?", 1, 1024 / R.width * R.length, nil, colors.blue)
  11856.         elseif R.subChoice == 7 then -- Drain and remove structure
  11857.             R.width = 28
  11858.             R.length = 28
  11859.             R.height = menu.getInteger("Go down how far from current", 1, 64, nil, colors.blue)
  11860.         end
  11861.     elseif R.choice == 87 then -- Ladder to water/lava 
  11862.         R.height    = menu.getInteger("est. height above (?F3) ", 1, 256, nil, colors.blue)
  11863.     elseif R.choice == 88 then -- Clear water plants from enclosed area
  11864.         R.data      = "clearWaterPlants"
  11865.         R.width     = menu.getInteger("water width (0=auto detect) ", 0, 64, nil, colors.yellow)
  11866.         R.length    = menu.getInteger("water length (0=auto detect) ", 0, 64, nil, colors.orange)
  11867.     elseif R.choice == 89 then -- convert flowing water to source
  11868.         R.width     = menu.getInteger("water width  (0=auto detect) ", 0, 64, nil, colors.yellow)
  11869.         if R.width > 0 then
  11870.             R.length = menu.getInteger("water length (0=auto detect) ", 0, 64, nil, colors.orange)
  11871.         end
  11872.         R.height    = menu.getInteger("water depth (0=auto detect) ", 0, 64, nil, colors.blue)
  11873.     elseif R.choice == 810 then -- create sloping water
  11874.         R.width     = menu.getInteger("water slope width (usually 7/8) ", 1, 8, nil, colors.yellow)
  11875.         R.length    = menu.getInteger("water slope length ", 1, 64, nil, colors.orange)
  11876.    
  11877. -- 09. BUILDING & RAILWAY
  11878.     elseif R.choice == 91 then -- Build wall
  11879.         R.width     = 1
  11880.         R.length    = menu.getInteger("Length of wall (1-256) ", 1, 256, nil, colors.orange)
  11881.         R.height    = menu.getInteger("Height of wall (1-50) ", 1, 50, nil, colors.lightGray)
  11882.         pp.itemColours = {colors.lime, colors.magenta}
  11883.         R.subChoice = menu.menu("What is my current position?", {"End of wall: Start ahead","Within the wall: start here"}, pp, "Type number + Enter")
  11884.     elseif R.choice == 92 then -- Build rectangular structure
  11885.         R.width     = menu.getInteger("Building width (1-256)", 1, 256, nil, colors.yellow)
  11886.         R.length    = menu.getInteger("Building length (1-256) ", 1, 256, nil, colors.orange)
  11887.         R.height    = menu.getInteger("Building Height(1-50) ", 1, 50, nil, colors.lightGray)
  11888.         pp.itemColours = {colors.lime, colors.magenta}
  11889.         R.subChoice = menu.menu("What is my current position?", {"Outside building: Start ahead","Within the walls: start here"}, pp, "Type number + Enter")
  11890.     elseif R.choice == 93 or R.choice == 94 then -- Build gable roof / pitched roof
  11891.         R.width     = menu.getInteger("Building width (1-256)", 1, 256, nil, colors.yellow)
  11892.         R.length    = menu.getInteger("Building length (1-256) ", 1, 256, nil, colors.orange)
  11893.     elseif R.choice == 97 then -- build downward slope
  11894.         R.height    = menu.getInteger("How many blocks down (0=to ground)?", 0, 256, nil, colors.blue)
  11895.         R.down = true
  11896.     elseif R.choice == 98 then -- build upward slope
  11897.         R.height    = menu.getInteger("Go up by how many blocks?", 1, 256, nil, colors.lightGray)
  11898.         R.up = true
  11899.        
  11900. -- 10. MEASURING TOOLS
  11901.     elseif R.choice == 101 then -- measure height
  11902.         pp.itemColours = {colors.lightBlue, colors.cyan, colors.lime, colors.gray}
  11903.         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
  11904.         if R.subChoice == 3 then
  11905.             R.data = menu.getString({"Search for? eg 'ore', 'obsidian'",">"}, false, 3, 20, nil, {colors.lime, colors.yellow})
  11906.         end
  11907.         R.size = menu.getInteger("Max distance before abort?", 1, 1024, nil, colors.red, nil, 64)
  11908.     elseif R.choice == 102 then -- measure depth
  11909.         pp.itemColours = {colors.lime, colors.orange, colors.green}
  11910.         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
  11911.         if R.subChoice == 3 then
  11912.             R.data = menu.getString({"Search for? eg 'ore', 'obsidian'",">"}, false, 3, 20, nil, {colors.lime, colors.yellow})
  11913.         end
  11914.     elseif R.choice == 103 then -- measure length
  11915.         pp.itemColours = {colors.gray, colors.lime, colors.green, colors.blue, colors.cyan}
  11916.         R.subChoice = menu.menu("Measure using?", {"Obstruction ahead",
  11917.                                                     "No further blocks above",
  11918.                                                     "No further blocks below",
  11919.                                                     "Detect specific block above",
  11920.                                                     "Detect specific block below"}, pp, "Type number + Enter") -- open direction menu options
  11921.         if R.subChoice == 4 or R.subChoice == 5 then
  11922.             R.data = menu.getString({"Search for? eg 'ore', 'obsidian'",">"}, false, 3, 20, nil, {colors.lime, colors.yellow})
  11923.         end
  11924.         R.size = menu.getInteger("Max distance before abort?", 1, 1024, nil, colors.red, nil, 64)
  11925.     elseif R.choice == 104 then -- measure greatest depth of water body
  11926.         pp.itemColours = {colors.lime, colors.orange}
  11927.         R.subChoice = menu.menu("Measure using?", {"Player entered", "No further water below"}, pp, "Type number + Enter ") -- open direction menu options
  11928.         -- 1 = player entry, 2 = water length
  11929.         if R.subChoice == 1 then
  11930.             R.length = menu.getInteger("water length (0=auto detect) ", 0, 256)
  11931.         end
  11932.     elseif R.choice == 105 then -- drill borehole and write borhole.txt to file
  11933.         R.height = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.lightGray)
  11934.         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)
  11935.     end
  11936.    
  11937.     return R
  11938. end
  11939.  
  11940. local function getTaskInventoryTo30(R)
  11941.     local retValue = {}
  11942.     local thanks = "Thank you.\n\nPress the ESC key\n\nStand Back..\n"
  11943.     --local pp = utils.getPrettyPrint()
  11944.    
  11945.     if R.choice == 0 then --Missing pickaxe
  11946.         T:checkInventoryForItem({"minecraft:diamond_pickaxe"}, {1})
  11947.         print("Diamond Pickaxe being tested...")
  11948.         T:setEquipment()
  11949.     elseif R.choice == 1 then --Missing crafting table
  11950.         T:checkInventoryForItem({"minecraft:crafting_table"}, {1}) -- 0 if not present
  11951.         print("Crafting table being tested...")
  11952.         T:setEquipment()
  11953.     elseif R.choice == 2 then --Missing chest
  11954.         T:checkInventoryForItem({"minecraft:chest"}, {1}) -- 0 if not present
  11955.         sleep(1.5)
  11956.        
  11957.     -- MINING
  11958.    
  11959.     elseif R.choice == 11 or R.choice == 12 then            -- ladder down / up / stairs down / stairs up
  11960.         local description = "Creating ladder going down"    -- default action description
  11961.         pp.itemColours = {colors.blue, colors.lightGray}
  11962.         pp.allowModifier = false -- only allow numbers to be returned
  11963.         local inAir = false
  11964.         local inNether = menu.getBoolean("Are you in the nether? (y/n) ", nil, colors.yellow, colors.black)
  11965.        
  11966.         if inNether then
  11967.             bedrock = 0
  11968.             inAir = true
  11969.         end
  11970.         local option = menu.menu("Which direction?", {"Going down","Going up"}, pp)
  11971.         if option == 1 then
  11972.             R.down = true
  11973.             R.height = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.lightGray)
  11974.             R.depth = menu.getInteger("Go down to level? ("..R.height - 2 .." to "..bedrock + 5 ..") ", bedrock + 5 , R.height - 2, nil, colors.blue)
  11975.             if R.choice == 11 then
  11976.                 if menu.getBoolean("Build a shelter at base? (y/n) ", nil, colors.yellow, colors.black) then
  11977.                     R.data = "chamber"
  11978.                 end
  11979.             end
  11980.             if R.choice == 13 then
  11981.                 description = "Creating stairs going down"
  11982.             end
  11983.         else
  11984.             R.up = true
  11985.             --R.depth = utils.getSize(true,"Current level (F3->Y coord)? ", bedrock + 5, ceiling)
  11986.             --R.height = utils.getSize(true, "Go up to level? ("..R.depth + 2 .." to "..ceiling ..")", R.depth + 2, ceiling)
  11987.             R.depth = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.blue)
  11988.             R.height = menu.getInteger("Go up to level? ("..R.depth + 2 .." to "..ceiling ..") ", R.depth + 2, ceiling, nil, colors.lightGray)
  11989.             if R.choice == 11 then
  11990.                 description = "Creating ladder going up"
  11991.             else
  11992.                 description = "Creating stairs going up"
  11993.             end
  11994.         end
  11995.         local range = math.abs(R.height - R.depth)
  11996.        
  11997.         if not inAir then
  11998.             inAir = menu.getBoolean("Are you in air (add blocks)? (y/n) ", nil, colors.yellow, colors.black)
  11999.         end
  12000.         --[[
  12001.         range examples
  12002.         -50 to -59 = -59 -(-50) = -9   down
  12003.         -59 to -50 = -50 -(-59) = 9    up
  12004.          70 to -48 = -48 -   70 = -118 down
  12005.           5 to  64 =  64 -   5  = 59   up
  12006.         ]]
  12007.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12008.         if R.choice == 11 then -- ladders
  12009.             utils.checkFuelNeeded(range * 2)
  12010.             T:checkInventoryForItem({"minecraft:ladder"}, {range})
  12011.             T:checkInventoryForItem({"minecraft:torch"}, {math.floor(range / 3)}, false)
  12012.             if inAir then
  12013.                 range = range * 4 -- more blocks needed
  12014.             end
  12015.             T:checkInventoryForItem({"stone"}, {range})
  12016.         else -- stairs
  12017.             utils.checkFuelNeeded(range * 10) -- stairs: each layer needs 10 moves
  12018.             local numStairsNeeded = range
  12019.             local data = T:getStock("stairs")
  12020.             local numStairs = data.total
  12021.             local cobbleNeeded = math.min(range * 6, 256)
  12022.             if inAir then
  12023.                 cobbleNeeded = range * 6 -- 5 blocks / layer unless in water or lava
  12024.             end
  12025.             if numStairs < numStairsNeeded then
  12026.                 cobbleNeeded = cobbleNeeded + (math.floor((2 * (numStairsNeeded - numStairs)) / 3))
  12027.             end
  12028.             T:checkInventoryForItem({"stairs"}, {numStairsNeeded}, false)
  12029.             T:checkInventoryForItem({"stone"}, {cobbleNeeded})
  12030.             T:checkInventoryForItem({"minecraft:chest"}, {1})   -- needed for crafting
  12031.         end
  12032.         menu.colourPrint(description, colors.lightBlue)
  12033.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12034.         if R.choice == 11 then
  12035.             retValue = createLadder(R) -- "bedrock", 70, -48
  12036.         else
  12037.             retValue = createStaircase(R)
  12038.         end
  12039.     elseif R.choice == 13 then --Create Mine at this level
  12040.         utils.checkFuelNeeded(960)
  12041.         T:checkInventoryForItem({"minecraft:torch"}, {24}, false)
  12042.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12043.         T:checkInventoryForItem({"stone"}, {64})
  12044.         T:checkInventoryForItem({"minecraft:chest"}, {1})
  12045.         menu.colourPrint("CreateMine starting", colors.lightBlue)
  12046.         sleep(2)
  12047.         retValue = createMine()
  12048.     elseif R.choice == 14 then  -- safe drop to water
  12049.         utils.checkFuelNeeded(R.height * 2)
  12050.         T:checkInventoryForItem({"minecraft:water_bucket"}, {1})
  12051.         T:checkInventoryForItem({"stone"}, {R.height * 2}, false) -- estimate only partial cloaking needed
  12052.         menu.colourPrint("Creating safe drop ".. R.height.. " blocks deep", colors.lightBlue)
  12053.         menu.colourPrint("Wait for my return!", colors.yellow)
  12054.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12055.         retValue = createSafeDrop(R)
  12056.     elseif R.choice == 15 then  -- single column bubble lift
  12057.         local needSigns = true
  12058.         utils.checkFuelNeeded(R.height * 6)
  12059.         --print(text, fg, bg, width)
  12060.         menu.colourPrint("Checking if near ladder", colors.red)
  12061.         T:turnRight(1)
  12062.         local blockType = T:getBlockType("forward")
  12063.         if blockType:find("ladder") == nil then
  12064.             T:turnLeft(2)
  12065.             blockType = T:getBlockType("forward")
  12066.             if blockType:find("ladder") == nil then
  12067.                 needSigns = false
  12068.             end
  12069.             T:turnRight(1)
  12070.         else
  12071.             needSigns = false
  12072.             T:turnLeft(1)
  12073.         end
  12074.         sleep(1)
  12075.         if needSigns then
  12076.             T:checkInventoryForItem({"sign"}, {2}, true, "Ladder not found")
  12077.         else
  12078.             menu.colourPrint("Ladder found, signs not required", colors.orange)
  12079.             sleep(1)
  12080.         end
  12081.         if T:getBlockType("down"):find("bedrock") == nil then -- NOT bedrock below
  12082.             T:checkInventoryForItem({"minecraft:water_bucket"}, {3})
  12083.         else
  12084.             T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12085.         end
  12086.         T:checkInventoryForItem({"minecraft:soul_sand", "minecraft:dirt"}, {1, 1}, true, "? use dirt as soul sand placeholder")
  12087.         T:checkInventoryForItem({"stone"}, {R.height * 2}, false) -- estimate only partial cloaking needed
  12088.         local _, slots = T:getFirstEmptySlot() -- returns first empty slot, no of empty slots
  12089.         T:checkInventoryForItem({"minecraft:bucket"}, {slots}, false, "Add empty buckets for speed!")
  12090.         menu.colourPrint("Creating bubble lift ".. R.height.. " blocks high", colors.lime)
  12091.         if not needSigns then -- ladder present as signs not required
  12092.             menu.colourPrint("Wait at the top via ladder...", colors.orange)
  12093.         end
  12094.         menu.colourPrint("\nSTAND ON THE LADDER FOR SAFETY!", colors.red)
  12095.         menu.colourPrint("\nEnter to continue", colors.yellow)
  12096.         read()
  12097.         retValue = createBubbleLift(R)
  12098.     elseif R.choice == 16 then --QuickMine corridor
  12099.         utils.checkFuelNeeded((R.width * 2 + R.length * 2) * 2)
  12100.         T:checkInventoryForItem({"stone"}, {R.width * 2 + R.length * 2}, false)
  12101.         T:checkInventoryForItem({"minecraft:torch"}, {math.floor((R.width * 2 + R.length * 2) / R.torchInterval)}, false)
  12102.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12103.         menu.colourPrint("QuickMine corridor: R.subChoice "..R.width.. " x "..R.length, colors.lightBlue)
  12104.         retValue = quickMineCorridor(R)
  12105.     elseif R.choice == 17 then --QuickMine
  12106.         utils.checkFuelNeeded(R.width * R.length)
  12107.         T:checkInventoryForItem({"stone"}, {64})
  12108.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12109.         menu.colourPrint("QuickMine rectangle: R.subChoice "..R.width.. " x "..R.length, colors.lightBlue)
  12110.         retValue = quickMine(R)
  12111.     elseif R.choice == 18 then --Mine bedrock area
  12112.         utils.checkFuelNeeded(R.width * R.length)
  12113.         T:checkInventoryForItem({"stone"}, {64})
  12114.         T:checkInventoryForItem({"minecraft:bucket"}, {1}, false)
  12115.         retValue = mineBedrockArea(R) -- R.data = "leaveExposed" or ""
  12116.     elseif R.choice == 19 then  -- salvage mineshaft
  12117.         local equippedRight, equippedLeft, inInventory = T:setEquipment() -- check for crafting table, sword, pickaxe, Put sword in spare slot
  12118.         if equippedLeft ~= "minecraft:diamond_pickaxe" and equippedRight ~= "minecraft:diamond_pickaxe" then
  12119.             T:checkInventoryForItem({"minecraft:diamond_pickaxe"}, {1}, true)
  12120.             equippedRight, equippedLeft, inInventory = T:setEquipment() -- check for crafting table, sword, pickaxe, Put sword in spare slot
  12121.         end
  12122.         if inInventory ~= "minecraft:diamond_sword" then
  12123.             T:checkInventoryForItem({"minecraft:diamond_sword"}, {1}, false, "To harvest spider webs\nyou need a diamond sword.") --checkInventoryForItem(self, items, quantities, required, message, name)
  12124.         end
  12125.         if T:getItemSlot("minecraft:diamond_sword") > 0 then
  12126.             inInventory = "minecraft:diamond_sword"
  12127.         end
  12128.         T:checkInventoryForItem({"minecraft:torch"}, {R.torchInterval}, false)
  12129.         if inInventory == "minecraft:diamond_sword" then
  12130.             menu.colourPrint("Clearing Mineshaft and cobwebs", colors.orange)
  12131.         else
  12132.             menu.colourPrint("Clearing Mineshaft", colors.yellow)
  12133.         end
  12134.         retValue = clearMineshaft(R, equippedRight, equippedLeft, inInventory) -- pass whether the sword is present
  12135.        
  12136.     -- FORESTRY
  12137.     elseif R.choice == 21 then  -- Fell tree
  12138.         if T:isLog("forward") then
  12139.             if turtle.getFuelLevel() < 30 then
  12140.                 T:checkInventoryForItem({"minecraft:chest"}, {1}, false,"Fuel level critical: "..turtle.getFuelLevel())
  12141.                 turtle.select(1)
  12142.                 T:dig("forward")
  12143.                 T:craft("planks", 4)
  12144.                 T:refuel()
  12145.                 T:forward(1)
  12146.                 T:up(2)
  12147.                 T:craft("chest", 1)
  12148.             else
  12149.                 T:forward(1)
  12150.             end
  12151.             menu.colourPrint("Felling tree", colors.lime)
  12152.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12153.             T:harvestWholeTree("up")
  12154.             while turtle.down() do end
  12155.             retValue = {"Tree Harvested"}
  12156.         else
  12157.             retValue =
  12158.             {
  12159.                 "No log in front..",
  12160.                 "Move me in front of a tree!"
  12161.             }
  12162.         end
  12163.     elseif R.choice == 22 then --Create treefarm
  12164.         utils.checkFuelNeeded(900)
  12165.         --T:checkInventoryForItem({"minecraft:dirt"}, {16})
  12166.         T:checkInventoryForItem({"stone"}, {320})
  12167.         T:checkInventoryForItem({"polished"}, {4}) -- used to mark launch positions
  12168.         T:checkInventoryForItem({"minecraft:water_bucket"}, {5})
  12169.         R.useBlockType = T:getMostItem("", true)
  12170.         menu.colourPrint("Creating Tree Farm with "..R.useBlockType, colors.lime)
  12171.         sleep(2)
  12172.         retValue = createTreefarm(R)
  12173.     elseif R.choice == 23 then -- Plant treefarm
  12174.         if R.subChoice == 1 then
  12175.             utils.checkFuelNeeded(180)
  12176.             T:checkInventoryForItem({"dirt"}, {16})
  12177.             T:checkInventoryForItem({"sapling"}, {16}, false, "Max 16. NOT dark oak")
  12178.         elseif R.subChoice == 2 then
  12179.             utils.checkFuelNeeded(180)
  12180.             T:checkInventoryForItem({"dirt"}, {16})
  12181.             T:checkInventoryForItem({"sapling"}, {16}, false, "Max 16. 4 saplings / tree")
  12182.         end
  12183.         menu.colourPrint("plantTreefarm starting: size "..R.subChoice, colors.lime)
  12184.         retValue = plantTreefarm(R)
  12185.     elseif R.choice == 24 then  -- Harvest treefarm
  12186.         print(thanks)
  12187.         os.sleep(2)
  12188.         menu.colourPrint("Harvesting treefarm starting", colors.lime)
  12189.         retValue = harvestTreeFarm(R)
  12190.     elseif R.choice == 25 then  -- Build wall / fence
  12191.         utils.checkFuelNeeded(R.width * R.length * 2)
  12192.         local quantity = math.ceil((R.width + R.length) * 2.3)
  12193.         T:checkInventoryForItem({"wall", "fence"}, {quantity, quantity})
  12194.         if R.torchInterval > 0 then
  12195.             T:checkInventoryForItem({"minecraft:torch"}, {math.floor(quantity / R.torchInterval)}, false)
  12196.         end
  12197.         if R.data == "barrel" then
  12198.             T:checkInventoryForItem({"barrel"}, {4}, false)
  12199.         end
  12200.         R.useBlockType = T:getMostItem("", false) -- no excluded blocks, any block type
  12201.         menu.colourPrint("Creating "..R.width.." x "..R.length.." walled enclosure", colors.yellow)
  12202.         menu.colourPrint("Using: "..R.useBlockType, colors.orange)
  12203.         retValue = createWallOrFence(R)
  12204.     elseif R.choice == 26 then  -- clear natural forest
  12205.         T:checkInventoryForItem({"minecraft:chest"}, {1})
  12206.         T:checkInventoryForItem({"sapling"}, {64}, false)
  12207.         menu.colourPrint("Clearing and replanting trees", colors.lime)
  12208.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12209.         retValue = clearAndReplantTrees()
  12210.     end
  12211.     return retValue
  12212. end
  12213.  
  12214. local function getTaskInventoryTo70(R)
  12215.     local retValue = {}
  12216.     local thanks = "Thank you.\n\nPress the ESC key\n\nStand Back..\n"
  12217.     -- FARMING
  12218.     if R.choice == 31 then  -- Create modular farm
  12219.         utils.checkFuelNeeded(300)
  12220.         T:checkInventoryForItem({"cobble"}, {64})
  12221.         T:checkInventoryForItem({"dirt"}, {128}, false)
  12222.         T:checkInventoryForItem({"water_bucket"}, {4})
  12223.         T:checkInventoryForItem({"chest", "barrel"}, {5,5})
  12224.         T:checkInventoryForItem({"sapling"}, {1})
  12225.         R.useBlockType = T:getMostItem("dirt", true) -- exclude dirt from count
  12226.         print(thanks)
  12227.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12228.         print("Creating modular farm with "..R.useBlockType)
  12229.         retValue = createFarm(R, false)
  12230.     elseif R.choice == 32 then  -- Extend modular farm
  12231.         utils.checkFuelNeeded(300)
  12232.         T:checkInventoryForItem({"cobble"}, {64})
  12233.         T:checkInventoryForItem({"dirt"}, {128}, false)
  12234.         T:checkInventoryForItem({"water_bucket"}, {4})
  12235.         T:checkInventoryForItem({"chest", "barrel"}, {5,5})
  12236.         T:checkInventoryForItem({"sapling"}, {1})
  12237.         T:checkInventoryForItem({"crafting"}, {1}) -- will be placed inside barrel / chest next to water source
  12238.         R.useBlockType = T:getMostItem("dirt", true) -- exclude dirt from count
  12239.         menu.colourPrint("Checking position...\n", colors.green)
  12240.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12241.         retValue = createFarmExtension(R) -- subChoice = 1 for ahead, 2 for to the right
  12242.     elseif R.choice == 33 then  -- manage modular farm
  12243.         -- inventory checked in function depending on option taken
  12244.         R.data = "farm"
  12245.         retValue = manageFarmSetup(R)
  12246.     elseif R.choice == 34 then  -- build single fence
  12247.         utils.checkFuelNeeded(R.length)
  12248.         T:checkInventoryForItem({"wall", "fence"}, {R.length, R.length})
  12249.         if R.torchInterval > 0 then
  12250.             T:checkInventoryForItem({"minecraft:torch"}, {math.ceil(R.length / R.torchInterval)}, false)
  12251.         end
  12252.         R.useBlockType = T:getMostItem("minecraft:torch") -- exclude torch
  12253.         menu.colourPrint("Creating "..R.length.." wall or fence", colors.green)
  12254.         menu.colourPrint("Using: "..R.useBlockType, colors.orange)
  12255.         retValue = createWallOrFence(R) -- barrels not included in R.data, R.width = 0 so only single length
  12256.     elseif R.choice == 35 then  -- build fence
  12257.         utils.checkFuelNeeded(R.width * R.length * 2)
  12258.         local quantity = math.ceil((R.width + R.length) * 2.3)
  12259.         T:checkInventoryForItem({"wall", "fence"}, {quantity, quantity})
  12260.         if R.torchInterval > 0 then
  12261.             T:checkInventoryForItem({"minecraft:torch"}, {math.floor(quantity / R.torchInterval)}, false)
  12262.         end
  12263.         R.useBlockType = T:getMostItem("minecraft:torch") -- exclude torch
  12264.         menu.colourPrint("Creating "..R.width.." x "..R.length.." walled enclosure", colors.green)
  12265.         menu.colourPrint("Using: "..R.useBlockType, colors.orange)
  12266.         retValue = createWallOrFence(R) -- barrels not included in R.data
  12267.     -- OBSIDIAN
  12268.     elseif R.choice == 41 then --harvest obsidian
  12269.         utils.checkFuelNeeded(R.width * R.length * 3)
  12270.         T:checkInventoryForItem({"stone"}, {R.width * R.length})
  12271.         T:checkInventoryForItem({"minecraft:bucket", "minecraft:lava_bucket"}, {1, 1}, false, "Get extra fuel as well!")
  12272.         menu.colourPrint("Harvesting obsidian area: size "..R.width.. " x "..R.length, colors.orange)
  12273.         sleep(2)
  12274.         retValue = harvestObsidian(R)
  12275.     elseif R.choice == 42 then --build nether portal
  12276.         utils.checkFuelNeeded(R.length * R.height * R.width)    -- length = width when facing standard = 5 high 4 length 1 width
  12277.         T:checkInventoryForItem({"minecraft:obsidian"}, {((R.length - 2 + R.height - 2) * R.width * 2)})
  12278.         T:checkInventoryForItem({"stone"}, {R.width * 4})
  12279.         R.useBlockType = T:getMostItem("obsidian", true) -- exclude obsidian from count
  12280.         menu.colourPrint("Building Nether portal", colors.orange)
  12281.         sleep(2)
  12282.         retValue = createPortal(R)
  12283.     elseif R.choice == 43 then --demolish nether portal
  12284.         utils.checkFuelNeeded(20)
  12285.         print("Demolishing Nether portal")
  12286.         retValue = demolishPortal(R)
  12287.     elseif R.choice == 44 then -- Strip mine Netherite
  12288.         utils.checkFuelNeeded(R.length * 2)
  12289.         T:checkInventoryForItem({"stone"}, {R.length * 4})
  12290.         R.useBlockType = T:getMostItem("", true) -- exclude none, use stone only/netherrack
  12291.         T:checkInventoryForItem({"cobble"}, {math.floor(R.length / 16) * 4}, true, "For marking Chunk boundaries")
  12292.         T:checkInventoryForItem({"minecraft:bucket", "minecraft:lava_bucket"}, {1, 1})
  12293.         T:checkInventoryForItem({"minecraft:torch"}, {math.floor(R.length / 16)}, false)
  12294.         retValue = createStripMine(R)
  12295.     elseif R.choice == 45 then --undermine dragon towers
  12296.         utils.checkFuelNeeded(500)
  12297.         T:checkInventoryForItem({"minecraft:cobblestone", "minecraft:cobbled_deepslate"}, {84, 84})
  12298.         print("Undermining dragon towers")
  12299.         retValue = undermineDragonTowers()
  12300.     elseif R.choice == 46 then --deactivate dragon tower
  12301.         utils.checkFuelNeeded(50)
  12302.         print("Deactivating dragon tower")
  12303.         retValue = deactivateDragonTower()
  12304.     elseif R.choice == 47 then --build dragon water trap
  12305.         utils.checkFuelNeeded(256)
  12306.         T:checkInventoryForItem({"stone"}, {356})
  12307.         T:checkInventoryForItem({"minecraft:obsidian"}, {1})
  12308.         T:checkInventoryForItem({"minecraft:ladder"}, {145})
  12309.         T:checkInventoryForItem({"minecraft:water_bucket"}, {1})
  12310.         print("Building dragon water trap")
  12311.         retValue = createDragonTrap()
  12312.     elseif R.choice == 48 then --build portal minecart station
  12313.         utils.checkFuelNeeded(200)
  12314.         menu.colourPrint("Inventory after height measurement", colors.red)
  12315.         menu.colourPrint("Enter to start measurement.", colors.lime)
  12316.         read()
  12317.         print("Building portal platform")
  12318.         retValue = createPortalPlatform()
  12319.     elseif R.choice == 49 then -- shulker harvesting
  12320.         retValue = harvestShulkers(R)
  12321.        
  12322.     -- CANAL BRIDGE
  12323.     elseif R.choice == 51 then  -- continuous path over void/water/lava
  12324.         utils.checkFuelNeeded(R.length) -- allow for R.length
  12325.         if R.data ~= "reduce" then
  12326.             T:checkInventoryForItem({"stone"}, {R.length}, false)
  12327.             if R.torchInterval > 0 then
  12328.                 T:checkInventoryForItem({"minecraft:torch"}, {math.floor(R.length/R.torchInterval)}, false)
  12329.             end
  12330.             print("Building continuous path")
  12331.         end
  12332.         retValue = utils.createPath(R) -- returns {numBlocks}
  12333.     elseif R.choice == 52 then  -- simple 2 block corridor
  12334.         utils.checkFuelNeeded(R.length)
  12335.         T:checkInventoryForItem({"stone"}, {R.length * 2}, false)
  12336.         if R.torchInterval > 0 then
  12337.             T:checkInventoryForItem({"minecraft:torch"}, {math.ceil(R.length / R.torchInterval)}, false)
  12338.         end
  12339.         print(thanks)
  12340.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12341.         print("Building simple corridor")
  12342.         retValue = createCorridor(R)
  12343.     elseif R.choice == 53 then  -- canal management
  12344.         local torches = 0
  12345.         local length = R.length
  12346.         if length > 0 then
  12347.             utils.checkFuelNeeded(length * 4) -- allow for 1024 R.length
  12348.             if R.torchInterval > 0 then
  12349.                 torches = math.floor(length / R.torchInterval)
  12350.             end
  12351.         else
  12352.             utils.checkFuelNeeded(2048) -- allow for 1024 R.length
  12353.             length = 256
  12354.         end
  12355.         T:checkInventoryForItem({"stone"}, {length})
  12356.         R.useBlockType = T:getMostItem("", true)
  12357.         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
  12358.             T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12359.         end
  12360.         if torches > 0 then
  12361.             T:checkInventoryForItem({"minecraft:torch"}, {torches}, false)
  12362.         end
  12363.         retValue = createWaterCanal(R)
  12364.     elseif R.choice == 54 then  -- ice canal
  12365.         local default = R.length
  12366.         if R.length > 0 then
  12367.             utils.checkFuelNeeded(R.length)
  12368.         else
  12369.             default = 64
  12370.             utils.checkFuelNeeded(default * 2) -- allow for 128 min R.length
  12371.         end
  12372.         --[[
  12373.             new canal
  12374.             1 = left towpath- move to centre left
  12375.             2 = centre left ice or hollow
  12376.             3 = centre right ice or hollow
  12377.             4 = right side - move to centre right
  12378.             convert water canal
  12379.             5 = left towpath
  12380.             6 = centre left ice or air
  12381.             7 = centre right ice or air
  12382.             8 = right towpath
  12383.         ]]
  12384.         if R.subChoice <= 5 or R.subChoice == 8 then    -- towpath
  12385.             T:checkInventoryForItem({"slab"}, {default}, true, "Add slabs to length required")
  12386.         end
  12387.         if R.torchInterval > 0 then
  12388.             --checkInventoryForItem(items, quantities, required, message)
  12389.             T:checkInventoryForItem({"stone"}, {math.ceil(default / R.torchInterval)}, true, "NOT bricks!")
  12390.             R.useBlockType = T:getMostItem("", true)
  12391.             T:checkInventoryForItem({"torch"}, {math.ceil(default / R.torchInterval)}, false)
  12392.         end
  12393.         if R.data == "ice" then -- ice canal with 2 spaces above
  12394.             T:checkInventoryForItem({"minecraft:packed_ice", "minecraft:blue_ice"}, {math.ceil(R.length / 2), math.ceil(R.length / 2)}, false)
  12395.         end
  12396.         print(thanks)
  12397.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12398.         print("Building ice canal")
  12399.         retValue = createIceCanal(R)
  12400.     elseif R.choice == 55 then -- platform
  12401.         local volume = R.width * R.length
  12402.         utils.checkFuelNeeded(volume)
  12403.         T:checkInventoryForItem({"stone", "dirt"}, {volume, volume})
  12404.         R.useBlockType = T:getMostItem("", true)
  12405.         print(thanks)
  12406.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12407.         print("Building platform")
  12408.         retValue = createPlatform(R)
  12409.     elseif R.choice == 56 then -- sinking platform
  12410.         local volume = (R.width + 1) * (R.length + 1)
  12411.         utils.checkFuelNeeded(volume * (R.height + 1))
  12412.         T:checkInventoryForItem({"stone"}, {volume + ((R.length * 2) + (R.width * 2) * R.height) + 1})
  12413.         print(thanks)
  12414.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12415.         print("Building sinking platform")
  12416.         retValue = createSinkingPlatform(R)
  12417.     elseif R.choice == 57 then -- boat bubble lift
  12418.         utils.checkFuelNeeded(R.height * 20)
  12419.         T:checkInventoryForItem({"minecraft:bucket","minecraft:water_bucket"}, {2, 2})
  12420.         T:checkInventoryForItem({"stone"}, {R.height * 10})
  12421.         T:checkInventoryForItem({"gate"}, {R.height * 2})
  12422.         T:checkInventoryForItem({"minecraft:soul_sand"}, {R.height * 2 + 2})
  12423.         print(thanks)
  12424.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12425.         print("Building boat bubble lift")
  12426.         retValue = createBoatLift(R)
  12427.         --retValue = createBoatLift(R) -- R.subChoice:0=new, R.subChoice:1=extend, R.length:0=left, 1=right
  12428.        
  12429.     -- MOB SPAWNER
  12430.     elseif R.choice == 61 then  --  9x9 hollow cube cobble lined
  12431.         utils.checkFuelNeeded(600) -- allow for 600 moves
  12432.         T:checkInventoryForItem({"slab","stone"}, {1, 3}, true, "Slab can be crafted from 3 stone")
  12433.         if T:getItemSlot("stone") > 0 and T:getItemSlot("slab") == 0 then -- no slabs, but is stone
  12434.             local craftOK, message = T:craft("slab")
  12435.         end
  12436.         if R.data == "chest" then
  12437.             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)
  12438.             read()
  12439.         else
  12440.             T:checkInventoryForItem({"stone"}, {512}, false, "Full cube uses ~700 blocks\nEstimate your requirements")
  12441.         end
  12442.         print(thanks)
  12443.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12444.         retValue = createMobFarmCube(R) -- R.data = "spawner" or "chest": not blaze
  12445.     elseif R.choice == 62 then  -- Blaze spawner
  12446.         utils.checkFuelNeeded(2500) -- allow for 2500 moves
  12447.         if R.data == "blaze" then
  12448.             T:checkInventoryForItem({"slab"}, {122}, true)
  12449.             T:checkInventoryForItem({"stone"}, {576})
  12450.             print("You will be asked for more assets later")
  12451.             print("Enter to continue")
  12452.             read()
  12453.         end  -- else R.data == "restart"
  12454.         retValue = createMobFarmCube(R) --R.data = "blaze" or R.data = "restart"
  12455.     elseif R.choice == 63 then  --  flood mob spawner
  12456.         utils.checkFuelNeeded(60) -- allow for 60 moves
  12457.         T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12458.         if R.subChoice == 1 then
  12459.             T:checkInventoryForItem({"fence"}, {2})
  12460.             T:checkInventoryForItem({"sign"}, {2})
  12461.             T:checkInventoryForItem({"slab"}, {1})
  12462.             T:checkInventoryForItem({"minecraft:soul_sand", "minecraft:dirt"}, {1, 1}, true)
  12463.         end
  12464.         print(thanks)
  12465.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12466.         retValue = floodMobFarm(R)
  12467.     elseif R.choice == 64 then -- build bubble lift on top of soul sand
  12468.         utils.checkFuelNeeded(200) -- allow for 200 moves
  12469.         T:checkInventoryForItem({"slab","stone"}, {6, 3}, true, "Slabs can be crafted from 3 stone")
  12470.         if T:getItemSlot("stone") > 0 and T:getItemSlot("slab") == 0 then -- no slabs, but is stone
  12471.             local craftOK, message = T:craft("slab")
  12472.         end
  12473.         T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12474.         T:checkInventoryForItem({"stone"}, {256})
  12475.         if T:getBlockType("down") ~= "minecraft:soul_sand" then
  12476.             T:checkInventoryForItem({"minecraft:soul_sand"}, {1})
  12477.         end
  12478.         T:checkInventoryForItem({"hopper"}, {1}, false)
  12479.         if T:getItemSlot("hopper") > 0 then
  12480.             T:checkInventoryForItem({"chest"}, {2})
  12481.         end
  12482.         print(thanks)
  12483.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12484.         retValue = createMobBubbleLift(R)
  12485.     elseif R.choice == 65 then -- computercraft mob grinder
  12486.         utils.checkFuelNeeded(1000) -- allow for 1000 moves
  12487.         T:checkInventoryForItem({"stone"}, {256}) -- for ceiling, walls and floor of area
  12488.         R.useBlockType = T:getMostItem("", true) -- stone only, no exclusions
  12489.         print(thanks)
  12490.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12491.         retValue = createMobGrinder(R)
  12492.     elseif R.choice == 66 then -- build endermen tower
  12493.         -- build in 3 sections, base, tower, top
  12494.         getTaskHelp(2, 66) -- compulsory help display
  12495.         read() -- pause until user ready
  12496.         local numFuel = 700
  12497.         local choices =
  12498.         {
  12499.             "New tower lower base",
  12500.             "Add tower upper base + killzone",
  12501.             "128 block tower to existing base"
  12502.         }
  12503.         pp.itemColours = {colors.lime, colors.orange, colors.green}
  12504.         local option, modifier = menu.menu("Select build stage:", choices, pp)
  12505.         if option == 1 then --lower base
  12506.             T:checkInventoryForItem({"minecraft:chest"}, {1})
  12507.             T:place("chest", -1, "down", false)
  12508.             T:emptyInventory("up")
  12509.             utils.checkFuelNeeded(320) -- allow for 320 moves
  12510.             T:checkInventoryForItem({"stone"}, {144}) -- <3 stacks
  12511.             T:checkInventoryForItem({"minecraft:water_bucket"}, {2})
  12512.             T:checkInventoryForItem({"fence"}, {4})
  12513.             T:checkInventoryForItem({"sign"}, {4})
  12514.             T:checkInventoryForItem({"door"}, {2})
  12515.             T:checkInventoryForItem({"minecraft:soul_sand"}, {1})
  12516.         elseif option == 2 then -- upper base
  12517.             utils.checkFuelNeeded(710) -- allow for 703 moves
  12518.             T:checkInventoryForItem({"stone"}, {384}) -- 6 stacks
  12519.             T:checkInventoryForItem({"minecraft:bucket"}, {4})
  12520.             T:checkInventoryForItem({"fence"}, {15})
  12521.             T:checkInventoryForItem({"sign"}, {4})
  12522.             T:checkInventoryForItem({"ladder"}, {3})
  12523.             T:checkInventoryForItem({"minecraft:soul_sand"}, {1})
  12524.         else -- main tower
  12525.             utils.checkFuelNeeded(3000) -- allow for 3000 moves
  12526.             if T:getBlockType("down") ~= "minecraft:chest" then
  12527.                 T:checkInventoryForItem({"minecraft:chest"}, {1})
  12528.                 T:place("chest", -1, "down", false)
  12529.             end
  12530.             T:checkInventoryForItem({"stone"}, {768}) -- 12 stacks
  12531.             T:checkInventoryForItem({"minecraft:bucket"}, {10})
  12532.             T:checkInventoryForItem({"fence"}, {64})    -- 1 stacks    
  12533.         end
  12534.         print(thanks)
  12535.         os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12536.         retValue = createEnderTower(option) -- 1, 2, or 3
  12537.     end
  12538.     return retValue
  12539. end
  12540.  
  12541. local function getTaskInventory(R)
  12542.     -- run this loop 2x per second to check if player has put anything in the inventory
  12543.     -- fuel 1 coal = 60 = 4 planks. 64 planks = 16 coal = 960 units
  12544.     local retValue = {}
  12545.     local thanks = "Thank you.\n\nPress the ESC key\n\nStand Back..\n"
  12546.    
  12547.     if R.choice < 31 then
  12548.         return getTaskInventoryTo30(R) -- Mining, Forestry
  12549.     elseif R.choice < 71 then
  12550.         return getTaskInventoryTo70(R) -- Farming, Obsidian, Canal / Bridge
  12551.     elseif R.choice > 500 and R.choice < 700 then
  12552.         return getTaskInventoryTo70(R)
  12553.     else -- Area carving, Lava/Water, Railway
  12554.         -- AREA CARVING
  12555.         if R.choice == 71 then--Clear area
  12556.             utils.checkFuelNeeded(R.width * R.length * 3)
  12557.             if R.useBlockType == "dirt" then
  12558.                 T:checkInventoryForItem({"minecraft:dirt"}, {R.width * R.length})
  12559.             end
  12560.             print(thanks)
  12561.             sleep(2)
  12562.             print("Clearing area: size "..R.width.. " x "..R.length)
  12563.             retValue = clearArea(R)
  12564.         elseif R.choice == 72 then --Clear rectangle
  12565.             -- R.choice, R.width(R.subChoice), R.length(R.width), up(R.length), down(R.height) from getTask()
  12566.             utils.checkFuelNeeded(R.width * R.length)
  12567.             print("Clearing rectangle: size "..R.width.. " x "..R.length)
  12568.             retValue = clearRectangle(R)
  12569.         elseif R.choice == 73 then --Clear wall
  12570.             utils.checkFuelNeeded(R.length * R.height)
  12571.             print("Removing wall "..R.length.." long x "..R.height.." high")
  12572.             retValue = clearWall(R)
  12573.         elseif R.choice == 74 then --Clear single R.height perimeter wall
  12574.             utils.checkFuelNeeded((R.width + R.length) * 2)
  12575.             print("Recycling wall section "..R.width.." x "..R.length)
  12576.             retValue = clearPerimeter(R)
  12577.         elseif R.choice == 75 then --Clear hollow structure
  12578.             utils.checkFuelNeeded((R.width * R.length) + ((R.width + R.length) * R.height))
  12579.             print("Recycling hollow object "..R.width.." x "..R.length.." height: "..R.height)
  12580.             retValue = clearBuilding(R)
  12581.         elseif R.choice == 76 then --Clear solid structure / extend water pool
  12582.             utils.checkFuelNeeded((R.width * R.length) + ((R.width + R.length) * R.height))
  12583.             print("Recycling solid object w:"..R.width..", l:"..R.length..", h:"..R.height)
  12584.             retValue = clearSolid(R)
  12585.         elseif R.choice == 77 then  -- Dig trench
  12586.             utils.checkFuelNeeded(R.height * R.length * 2)
  12587.             print(thanks)
  12588.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12589.             if R.length == 0 then
  12590.                 print("Digging continuous trench "..R.height.." blocks deep")
  12591.             else
  12592.                 print("Digging trench "..R.length.." blocks long, "..R.height.." blocks deep")
  12593.             end
  12594.             retValue = digTrench(R)
  12595.         elseif R.choice == 78 then --Carve mountain
  12596.             utils.checkFuelNeeded(R.length * R.width * 10)
  12597.             print("Carving mountain side "..R.width.." x "..R.length)
  12598.             retValue = clearMountainSide(R)
  12599.         elseif R.choice == 79 then -- Place floor or Ceiling
  12600.             local blocks = R.width * R.length
  12601.             utils.checkFuelNeeded(blocks)
  12602.             T:checkInventoryForItem({"stone", "log", "planks"}, {blocks, blocks, blocks}, false)
  12603.             R.useBlockType = T:getMostItem()
  12604.             retValue = createFloorCeiling(R) -- R.subChoice integer 1 to 4
  12605.         elseif R.choice == 710 then -- direct commands
  12606.             utils.checkFuelNeeded(200)
  12607.             createRectanglePath(R)
  12608.            
  12609. -- LAVA WATER
  12610.         elseif R.choice == 81 then -- Sand based utilities
  12611.             if R.subChoice == 1 then    -- Drop sand or gravel wall
  12612.                 utils.checkFuelNeeded(100)
  12613.                 T:checkInventoryForItem({"sand", "gravel"}, {1024, 1024}, false)
  12614.                 if R.length == 0 then
  12615.                     print("Building sand wall. Auto length: ")
  12616.                 else
  12617.                     print("Building sand wall. length: "..R.length)
  12618.                 end
  12619.                 retValue = createSandWall(R)
  12620.             elseif R.subChoice == 2 then    -- Fill area with sand
  12621.                 utils.checkFuelNeeded(R.length * R.width)
  12622.                 T:checkInventoryForItem({"sand"}, {1024}, false)
  12623.                 print("Filling area with sand. length: "..R.length.." width: "..R.width)
  12624.                 retValue = sandFillArea(R)
  12625.             elseif R.subChoice == 3 then -- Clear sand wall
  12626.                 utils.checkFuelNeeded(200)
  12627.                 if R.length == 0 then
  12628.                     print("Digging sand. Auto length")
  12629.                 else
  12630.                     print("Digging sand. length: "..R.length)
  12631.                 end
  12632.                 retValue = clearSandWall(R)
  12633.             elseif R.subChoice == 4 then    -- Clear sand filled area
  12634.                 utils.checkFuelNeeded(R.length * R.width * 4)
  12635.                 print("Removing sand cube. length: "..R.length.." width: "..R.width)
  12636.                 retValue = clearSandCube(R)
  12637.             end
  12638.        
  12639.         elseif R.choice == 82 then --build containing wall in water or lava
  12640.             utils.checkFuelNeeded(R.length * R.length)
  12641.             local depth = R.height
  12642.             if depth == 0 then
  12643.                 depth = 20
  12644.             end
  12645.             T:checkInventoryForItem({"stone"}, {R.length * depth}, false)
  12646.             print("Building retaining wall in lava/water. length "..R.length)
  12647.             retValue = createRetainingWall(R)          
  12648.         elseif R.choice == 83 then -- create a rectangle path in water/lava
  12649.             utils.checkFuelNeeded(200)
  12650.             createRectanglePath(R)
  12651.         elseif  R.choice == 84 then -- Delete water/lava
  12652.             if R.width == 0 then
  12653.                 utils.checkFuelNeeded(2000)
  12654.                 T:checkInventoryForItem({"stone"}, {256}, false)
  12655.                 print("Deleting water using auto-detection")
  12656.             else
  12657.                 if R.height == 0 then
  12658.                     utils.checkFuelNeeded(2000)
  12659.                     T:checkInventoryForItem({"stone"}, {256}, false)
  12660.                 else
  12661.                     utils.checkFuelNeeded(R.width * R.length * R.height)
  12662.                     T:checkInventoryForItem({"stone"}, {math.max(R.length, R.width) * 2}, false)
  12663.                 end
  12664.                 print("Deleting enclosed water "..R.width.." x "..R.length.." x ".. R.height)
  12665.             end
  12666.             retValue = utils.drainWaterLava(R)
  12667.         elseif  R.choice == 85 then -- Sinking platform
  12668.             local volume = (R.width + 1) * (R.length + 1)
  12669.             utils.checkFuelNeeded(volume * (R.height + 1))
  12670.             T:checkInventoryForItem({"stone"}, {volume + ((R.length * 2) + (R.width * 2) * R.height) + 1})
  12671.             print(thanks)
  12672.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12673.             print("Building sinking platform")
  12674.             retValue = createSinkingPlatform(R)
  12675.         elseif R.choice == 86 then -- ocean monument utilities
  12676.             if R.subChoice == 1 then    -- Build 4 corner marker columns
  12677.                 --R.useBlockType = "prismarine", R.data = "oceanMonumentColumns"
  12678.                 T:checkInventoryForItem({"stone"}, {448})
  12679.                 retValue = oceanMonumentColumns(R)
  12680.             elseif R.subChoice == 2 then    -- Retaining wall beween 2 columns
  12681.                 T:checkInventoryForItem({"stone"}, {1024})
  12682.                 retValue = createRetainingWall(R)
  12683.             elseif R.subChoice == 3 then    -- Clear plants pre sand draining
  12684.                 retValue = clearWaterPlants(R)
  12685.             elseif R.subChoice == 4 then    -- Use sand draining
  12686.                 utils.checkFuelNeeded(100)
  12687.                 T:checkInventoryForItem({"sand", "gravel"}, {1024, 1024}, false)
  12688.                 if R.length == 0 then
  12689.                     print("Building sand wall. Auto length: ")
  12690.                 else
  12691.                     print("Building sand wall. length: "..R.length)
  12692.                 end
  12693.                 retValue = createSandWall(R)
  12694.             elseif R.subChoice == 5 then    -- remove sand wall
  12695.                 utils.checkFuelNeeded(200)
  12696.                 print("Digging sand from ocean monument")
  12697.                 retValue = clearSandWall(R)
  12698.             elseif R.subChoice == 6 then    -- Drain and remove structure
  12699.                 T:checkInventoryForItem({"stone"}, {1024})
  12700.                 retValue = utils.drainWaterLava(R)
  12701.             end
  12702.         elseif R.choice == 87 then --ladder to water/lava
  12703.             utils.checkFuelNeeded(R.height * 2)
  12704.             T:checkInventoryForItem({"minecraft:ladder"}, {R.height}, true, "Add more to be safe!")
  12705.             local cobble = R.height * 3 + 10
  12706.             T:checkInventoryForItem({"stone"}, {cobble})
  12707.             print(thanks)
  12708.             os.sleep(2)    -- pause for 2 secs to allow time to press esc
  12709.             print("Creating ladder to bedrock")
  12710.             retValue = createLadderToWater()
  12711.         elseif R.choice == 88 then --remove plants
  12712.             utils.checkFuelNeeded(R.length * R.width * 4)
  12713.             T:checkInventoryForItem({"sand", "stone"}, {64, 64})
  12714.             local width = R.width
  12715.             local length = R.length
  12716.             if width == 0 then
  12717.                 width = "auto"
  12718.             end
  12719.             if length == 0 then
  12720.                 length = "auto"
  12721.             end
  12722.             print("Removing water plants. length: "..length.." width: "..width)
  12723.             retValue = clearWaterPlants(R)
  12724.         elseif R.choice == 89 then -- convert flowing water to source
  12725.             --utils.checkFuelNeeded(R.length * R.width * 4) -- unknown as size not calculated
  12726.             T:checkInventoryForItem({"water_bucket", "bucket"}, {12, 12})
  12727.             T:checkInventoryForItem({"slab"}, {128})
  12728.             print("Converting water to source "..R.width.." x "..R.length.." x ".. R.height)
  12729.             retValue = convertWater(R)
  12730.         elseif R.choice == 810 then -- create sloping water
  12731.             utils.checkFuelNeeded(R.length * R.width * 3)
  12732.             local buckets = math.floor(R.length / 2) + 1
  12733.             T:checkInventoryForItem({"water_bucket", "bucket"}, {buckets, buckets})
  12734.             T:checkInventoryForItem({"slab"}, {R.length * R.width})
  12735.             print("Creating sloping water field "..R.width.." x "..R.length.." x ".. R.height)
  12736.             retValue = createSlopingWater(R)
  12737.         -- BUILDING & RAILWAY
  12738.         elseif R.choice == 91 then -- Build a wall
  12739.             local blocks = R.height * R.length
  12740.             utils.checkFuelNeeded(blocks)
  12741.             T:checkInventoryForItem({"stone", "planks", "bricks"}, {blocks, blocks, blocks})
  12742.             R.useBlockType = T:getMostItem()
  12743.             print("Building a wall using "..R.useBlockType)
  12744.             sleep(2)
  12745.             retValue = buildWall(R)
  12746.         elseif R.choice == 92 then -- Build a rectangular structure
  12747.             local blocks = (R.height * R.length * 2) + (R.height * R.width * 2)
  12748.             utils.checkFuelNeeded(blocks)
  12749.             T:checkInventoryForItem({"stone", "planks", "bricks"}, {blocks, blocks, blocks})
  12750.             R.useBlockType = T:getMostItem()
  12751.             print("Building a house using "..R.useBlockType)
  12752.             sleep(2)
  12753.             retValue = buildStructure(R)
  12754.         elseif R.choice == 93 or R.choice == 94 then -- Build a gable end roof / pitched roof
  12755.             local blocks = ((R.width + 2) * (R.length + 2))
  12756.             utils.checkFuelNeeded(blocks)
  12757.             if menu.getBoolean("Using stairs / planks for roof (y/n)", nil, colors.yellow) then
  12758.                 T:checkInventoryForItem({"planks", "stairs"}, {blocks, blocks})
  12759.             else
  12760.                 T:checkInventoryForItem({"stone"}, {blocks})
  12761.             end
  12762.            
  12763.             R.useBlockType = T:getMostItem()
  12764.             if R.choice == 93 then              -- Build a gableroof
  12765.                 if R.width % 2 == 1 then
  12766.                     T:checkInventoryForItem({"slab"}, {R.length + 2}, false, "Match slabs with roof blocks")
  12767.                 end
  12768.                 blocks = (R.width * 6)
  12769.                 T:checkInventoryForItem({"stone", "planks", "bricks"}, {blocks, blocks, blocks}, true, "Match gable with existing building")
  12770.             else
  12771.                 local isWidthOdd, isLengthOdd, width, length = false, false, 0, 0
  12772.                 R, isWidthOdd, isLengthOdd, width, length = utils.getRoofStats(R)
  12773.                 if isWidthOdd then
  12774.                     T:checkInventoryForItem({"slab"}, {length - 2}, false, "Match slabs with roof blocks")
  12775.                 end
  12776.             end
  12777.             print("Building a roof using "..R.useBlockType)
  12778.             sleep(2)
  12779.             if R.choice == 93 then              -- Build a gableroof
  12780.                 retValue = buildGableRoof(R)
  12781.             else                                -- Build a pitched roof
  12782.                 retValue = buildPitchedRoof(R)
  12783.             end
  12784.         elseif R.choice == 95 or R.choice == 96 then --place redstone torch level or downward slope
  12785.             utils.checkFuelNeeded(10)
  12786.             if R.choice == 95 then
  12787.                 R.data = "level"
  12788.             else
  12789.                 R.data = "up"
  12790.             end
  12791.             T:checkInventoryForItem({"stone"}, {1})
  12792.             R.useBlockType = T:getMostItem("", true)
  12793.             T:checkInventoryForItem({"minecraft:redstone_torch"}, {1})
  12794.             print("Placing redstone torch on ".. R.useBlockType)
  12795.             retValue = placeRedstoneTorch(R)
  12796.         elseif R.choice == 97 or R.choice == 98 then --build downward/upward slope
  12797.             local blocks = R.height * 2
  12798.             if R.height == 0 then
  12799.                 blocks = 64
  12800.             end
  12801.             utils.checkFuelNeeded(blocks)
  12802.             T:checkInventoryForItem({"stone"}, {blocks})
  12803.             print("Building slope")
  12804.             sleep(2)
  12805.             retValue = createRailway(R)
  12806.         elseif R.choice == 101 or R.choice == 102 or R.choice == 103 or R.choice == 104 then -- measure height/depth/length
  12807.             retValue = measure(R)
  12808.         elseif R.choice == 105 then--Borehole
  12809.             retValue = createBorehole(R)
  12810.         end
  12811.     end
  12812.     return retValue
  12813. end
  12814.  
  12815. local function test(R)
  12816.     local lib = {}
  12817.    
  12818.     function lib.dig(direction, bypass, slot)
  12819.         direction = direction or "forward"
  12820.         slot = slot or 1
  12821.         bypass = bypass or true
  12822.        
  12823.         print("direction: "..direction)
  12824.         print("bypass: "..tostring(bypass))
  12825.         print("slot: "..slot)
  12826.        
  12827.     end
  12828.     lib.dig("down")
  12829.     read()
  12830. end
  12831.  
  12832. local function main()
  12833.     local lib = {}
  12834.    
  12835.     function lib.checkLabel()
  12836.         if os.getComputerLabel() == nil then
  12837.             os.setComputerLabel("toolkit")
  12838.             print("Computer label set to "..os.getComputerLabel())
  12839.         end
  12840.     end
  12841.    
  12842.     function lib.checkLibs(libDir, filename)
  12843.         local fileExists = false
  12844.         if fs.exists(libDir) then
  12845.             if not fs.isDir(libDir) then
  12846.                 fs.move(libDir, libDir.."Renamed")
  12847.                 fs.makeDir(libDir)
  12848.             end
  12849.         else
  12850.             fs.makeDir(libDir)
  12851.         end
  12852.         if fs.exists(fs.combine(libDir, filename)) or fs.exists(fs.combine(libDir, filename..".lua")) then
  12853.             fileExists = true
  12854.         end
  12855.         return fileExists
  12856.     end
  12857.    
  12858.     local doContinue = true
  12859.     lib.checkLabel() -- make sure turtle label is set
  12860.     --check if lib folder exists
  12861.     if not lib.checkLibs("lib", "clsTurtle") then
  12862.         -- use pastebin get to download clsTurtle to libs folder
  12863.         print("Missing clsTurtle.lua in libs directory")
  12864.         print("Attempting to obtain from Pastebin...")
  12865.         if shell.run("pastebin","get","tvfj90gK","lib/clsTurtle.lua") then
  12866.             print("clsTurtle.lua installed from Pastebin")
  12867.         else
  12868.             print("failed to install clsTurtle.lua from Pastebin")
  12869.             doContinue = false
  12870.         end
  12871.     end
  12872.     if not lib.checkLibs("lib", "menu") then
  12873.         -- use pastebin get to download menu.lua to libs folder
  12874.         print("Missing menu.lua in libs directory")
  12875.         print("Attempting to obtain from Pastebin...")
  12876.         if shell.run("pastebin","get","BhjbYsw4","lib/menu.lua") then
  12877.             print("menu.lua installed from Pastebin")
  12878.         else
  12879.             print("failed to install menu.lua from Pastebin")
  12880.             doContinue = false
  12881.         end
  12882.     end
  12883.     if doContinue then
  12884.         local result = {}
  12885.         local R =
  12886.         {
  12887.             choice = 0,
  12888.             subChoice = 0,
  12889.             size = 0,
  12890.             width = 0,
  12891.             length = 0,
  12892.             height = 0,
  12893.             depth = 0,
  12894.             up = false,
  12895.             down = false,
  12896.             silent = false,
  12897.             data = "",
  12898.             torchInterval = 0,
  12899.             useBlockType = "",
  12900.             auto = false,
  12901.             side = ""
  12902.         }
  12903.         menu = require("lib.menu")
  12904.         T = require("lib.clsTurtle").new(false) -- true enables logfile to log.txt note dot NOT colon
  12905.         T:clear()
  12906.         doContinue = false  -- reset
  12907.         if args[1] ~= nil then
  12908.             if args[1]:sub(1,1) == "h" then
  12909. local help =
  12910. [[... = any following characters
  12911.  
  12912. tk v...     = mc/ccTweaked versions
  12913. tk log      = enable logging
  12914. tk log d... = enable logging + debug
  12915. tk find     = writes locate.txt
  12916. tk test     = runs test(R)
  12917. tk farm     = runs manageFarm(R)
  12918.  
  12919.  
  12920.  
  12921. Enter to exit]]
  12922.                 menu.colourPrint(help, colours.yellow)
  12923.                 read()
  12924.             elseif args[1] == "log" then
  12925.                 if args[2] ~= nil then
  12926.                     if args[2]:sub(1,1) == "d" then
  12927.                         dbug = true -- set dbug flag
  12928.                         menu.colourPrint("Logging and debugging enabled", colors.lime)
  12929.                     end
  12930.                 else
  12931.                     menu.colourPrint("Logging enabled", colors.lime)
  12932.                 end
  12933.                 if T:getLogExists() then
  12934.                     if menu.getBoolean("Delete existing log file? (y/n)", 3, colors.orange) then
  12935.                         T:deleteLog()
  12936.                         menu.colourPrint("Log file deleted", colors.yellow)
  12937.                     end
  12938.                 end
  12939.                 T:setUseLog(true)
  12940.                 doContinue = true
  12941.                 if dbug then
  12942.                     menu.colourPrint("Enter to continue...", colors.lightBlue)
  12943.                     read()
  12944.                 end
  12945.             elseif args[1] == "farm" then
  12946.                 R.silent = true
  12947.                 R.data = "farm"
  12948.                 R.auto = true
  12949.                 manageFarm(R)
  12950.             --elseif args[1] == "tree" then
  12951.                 --manageTreeFarm() -- use file to read status
  12952.             elseif args[1] == "find" then
  12953.                 -- missing turtle: player used 'tk find'
  12954.                 T:setUseLog(true)
  12955.                 T:setLogFileName("locate.txt")
  12956.                 T:appendLine("Booting succeeded")
  12957.                 T:appendLine("Block ahead: "..T:getBlockType("forward"))
  12958.                 T:appendLine("Block above: "..T:getBlockType("up"))
  12959.                 T:appendLine("Block below: "..T:getBlockType("down"))
  12960.             elseif args[1] == "test" then
  12961.                 test(R)
  12962.             elseif args[1]:find("v") ~= nil then
  12963.                 print("_HOST:")
  12964.                 print()
  12965.                 print(_HOST)
  12966.                 print()
  12967.                 print("Minecraft major version: "..mcMajorVersion)
  12968.                 print("Minecraft minor version: "..mcMinorVersion)
  12969.                 print("ccTweaked major version: "..ccMajorVersion)
  12970.                 print("ccTweaked minor version: "..ccMinorVersion)
  12971.                 print("tk version:              "..tkVersion)
  12972.                 print("clsTurtle version:       "..version)
  12973.                 print("\nEnter to exit")
  12974.                 read()
  12975.             end
  12976.         else
  12977.             doContinue = true
  12978.         end
  12979.         if doContinue then
  12980.             print("Minecraft major version: "..mcMajorVersion)
  12981.             print("Bedrock level: "..bedrock)
  12982.             if T:getUseLog() then
  12983.                 if T:saveToLog("Started with logging enabled", true) then
  12984.                     menu.colourPrint("\nEnter to continue...", colors.lightBlue)
  12985.                     read()
  12986.                 end
  12987.             else
  12988.                 print("Logging disabled")
  12989.             end
  12990.             sleep(1)
  12991.             while R.choice == 0 do
  12992.                 R = chooseTask(R)
  12993.             end
  12994.             if R.choice > 0 then
  12995.                 R = getTask(R)
  12996.                 if R.data ~= "quit" then
  12997.                     result = getTaskInventory(R) -- table of comments
  12998.                 end
  12999.             end
  13000.         end
  13001.         T:clear()
  13002.         table.insert(result, "Thank you for using 'survival toolkit'")
  13003.         local clr = {colors.yellow, colors.orange, colors.green, colors.lightBlue}
  13004.         local count = 1
  13005.         for _, value in ipairs(result) do
  13006.             --print(value)
  13007.             --.print(text, fg, bg, width)
  13008.             menu.colourPrint(tostring(value), clr[count])
  13009.             count = count + 1
  13010.             if count > #clr then
  13011.                 count = 1
  13012.             end
  13013.         end
  13014.     else
  13015.         print("Add missing files and restart")
  13016.     end
  13017. end
  13018.  
  13019. main()
Add Comment
Please, Sign In to add comment