SHOW:
|
|
- or go back to the newest paste.
| 1 | - | version = 20250410.0800 |
| 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.21.1 |
| 20 | + | ccTweaked started around mc 1.12.2 and currently at 1.18 |
| 21 | - | mc 1.18 onwards has new blocks and bedrock at -64, so needs to be taken into account. |
| 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 | - | local barrelItems = nil -- list of items and the barrels where they are usually found |
| 33 | + | |
| 34 | - | local chestItems = nil -- list of items and the chests where they are usually found |
| 34 | + | |
| 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 network = {}
|
| 119 | + | |
| 120 | for i,value in pairs(tbl) do | |
| 121 | - | function network.addToStorageList(storageType, itemKey, storageName, writeToFile) |
| 121 | + | |
| 122 | - | -- itemKey is a table, so is passed byRef. No need to return a value |
| 122 | + | |
| 123 | - | -- eg itemKey: [ "minecraft:dark_oak_sapling" ] = {"minecraft:barrel_94", "minecraft:barrel_96"}
|
| 123 | + | |
| 124 | - | -- storageName = "minecraft:barrel_99" |
| 124 | + | |
| 125 | - | local itemTable = {}
|
| 125 | + | |
| 126 | - | if storageType == "chest" then |
| 126 | + | |
| 127 | - | itemTable = chestItems[itemKey] -- eg [ "minecraft:dark_oak_sapling" ] = {"minecraft:barrel_94", "minecraft:barrel_96"}
|
| 127 | + | |
| 128 | end | |
| 129 | - | itemTable = barrelItems[itemKey] |
| 129 | + | |
| 130 | function utils.calculateDimensions(R) | |
| 131 | - | if itemTable == nil then -- key does not match. This item not previously stored |
| 131 | + | |
| 132 | - | if storageType == "chest" then |
| 132 | + | |
| 133 | - | chestItems[itemKey] = {storageName} -- eg U.chestItems[minecraft:diorite] = {chest_105}
|
| 133 | + | |
| 134 | print("Calculated Length = "..R.length)
| |
| 135 | - | barrelItems[itemKey] = {storageName}
|
| 135 | + | |
| 136 | R.width = utils.calculateDistance(R.width) -- now facing right | |
| 137 | print("Calculated width = "..R.width)
| |
| 138 | - | for _, storage in ipairs(itemTable) do -- is "minecraft:barrel_99" already in the list? |
| 138 | + | |
| 139 | - | if storage == storageName then |
| 139 | + | |
| 140 | - | return -- exit function |
| 140 | + | |
| 141 | if R.height == 0 then -- use auto settings based on water detection | |
| 142 | R.height = 64 | |
| 143 | - | -- not found so add to table. return not required as funcion is ended |
| 143 | + | |
| 144 | - | table.insert(itemTable, storageName) -- add to table eg table[ "minecraft:dark_oak_sapling" ] = {"minecraft:barrel_94", "minecraft:barrel_96",, "minecraft:barrel_99"}
|
| 144 | + | |
| 145 | end | |
| 146 | - | if writeToFile then |
| 146 | + | |
| 147 | - | network.updateList(storageType) |
| 147 | + | |
| 148 | --[[ | |
| 149 | measure length | |
| 150 | movement stops when either solid block in front or solid below | |
| 151 | - | function network.attachModem() |
| 151 | + | |
| 152 | - | -- modem cannot be "attached". Has to be player right-click! |
| 152 | + | |
| 153 | - | -- place on top or next to a modem and ask player to right-click |
| 153 | + | |
| 154 | local nonSolidBelow = utils.clearVegetation("down")
| |
| 155 | - | menu.colourPrint("Please right-click on the modem(s) I am next to or above/below"..
|
| 155 | + | |
| 156 | - | "\nThe centre square should be lit red.\n".. |
| 156 | + | |
| 157 | - | "If embedded use narrow gap at side\n", colors.red) |
| 157 | + | |
| 158 | - | local event, side = os.pullEvent("peripheral")
|
| 158 | + | |
| 159 | - | for timer = 5, 0, -1 do |
| 159 | + | |
| 160 | - | -- text, fg, bg, width, isInput, cr |
| 160 | + | |
| 161 | - | menu.colourWrite("Thanks. continuing in ".. timer.." seconds", colors.lime, colors.black, 0, false, true)
|
| 161 | + | |
| 162 | if turtle.forward() then -- able to move forward | |
| 163 | moves = moves + 1 | |
| 164 | else | |
| 165 | break | |
| 166 | - | function network.checkInventory(inventory, itemName, itemsPerSlot, matchPart) |
| 166 | + | |
| 167 | if not utils.clearVegetation("down") then -- solid below
| |
| 168 | - | Find an item already in an inventory |
| 168 | + | |
| 169 | - | inventory = The wrapped inventory or it's name |
| 169 | + | |
| 170 | - | itemName = The name of the item to find. |
| 170 | + | |
| 171 | - | return no of items already present, and storage space for additional |
| 171 | + | |
| 172 | end | |
| 173 | - | itemsPerSlot = itemsPerSlot or 64 |
| 173 | + | |
| 174 | - | matchPart = matchPart or "" |
| 174 | + | |
| 175 | - | local contents = nil |
| 175 | + | |
| 176 | - | local numSlots = 0 |
| 176 | + | |
| 177 | - | if type(inventory) == "string" then |
| 177 | + | |
| 178 | - | contents = peripheral.call(inventory, "list") |
| 178 | + | local quantity = tonumber(quantity) |
| 179 | - | numSlots = peripheral.call(inventory, "size") |
| 179 | + | local fuelNeeded = quantity - tonumber(turtle.getFuelLevel()) -- eg 600 |
| 180 | - | --assert(contents ~= nil, "Nil contents from inventory "..tostring(inventory)) |
| 180 | + | |
| 181 | - | T:saveToLog("network.checkInventory('"..inventory.."', itemName = "..itemName..", itemsPerSlot = "..itemsPerSlot..", matchPart = "..tostring(matchPart))
|
| 181 | + | |
| 182 | if T:checkInventoryForItem({"coal"}, {math.ceil(fuelNeeded / 60)}, false) == nil then
| |
| 183 | - | contents = inventory.list() |
| 183 | + | |
| 184 | - | numSlots = inventory.size() |
| 184 | + | |
| 185 | end | |
| 186 | - | local inStock = 0 |
| 186 | + | |
| 187 | - | local partMatch = false |
| 187 | + | |
| 188 | - | local canStore = 0 |
| 188 | + | |
| 189 | - | if contents ~= nil then |
| 189 | + | |
| 190 | - | T:saveToLog("#slots in use = "..#contents)
|
| 190 | + | |
| 191 | - | canStore = (numSlots - #contents) * itemsPerSlot -- capacity of empty slots |
| 191 | + | |
| 192 | - | for slot, item in pairs(contents) do |
| 192 | + | -- blockType, blockModifier, data |
| 193 | - | if item.name == itemName then |
| 193 | + | local blockType, blockModifier = T:getBlockType(direction) |
| 194 | - | inStock = inStock + item.count |
| 194 | + | |
| 195 | - | canStore = canStore + itemsPerSlot - item.count |
| 195 | + | |
| 196 | T:dig(direction) | |
| 197 | - | if matchPart ~= "" then -- eg check for "cobblestone" or "slab" |
| 197 | + | |
| 198 | - | if item.name:find(matchPart) ~= nil then |
| 198 | + | |
| 199 | - | partMatch = true |
| 199 | + | |
| 200 | and blockType:find("ice") == nil then
| |
| 201 | -- NOT water, ice or lava | |
| 202 | isAirWaterLava = false -- solid block | |
| 203 | end | |
| 204 | end | |
| 205 | - | T:saveToLog("network.checkInventory return inStock = "..inStock..", canStore = "..canStore..", partMatch = "..tostring(partMatch))
|
| 205 | + | |
| 206 | - | return inStock, canStore, partMatch -- eg 1, 3647, false if contains only 1 matching item in otherwise empty chest |
| 206 | + | |
| 207 | end | |
| 208 | ||
| 209 | - | function network.emptyInventory(R, barrels, chests, sticksAsFuel) |
| 209 | + | |
| 210 | - | --[[network.emptyInventory(R, {"sapling", "propagule", "dirt", "crafting"}, {"all"}, true)]]
|
| 210 | + | |
| 211 | - | if not T:isEmpty() then |
| 211 | + | |
| 212 | - | if sticksAsFuel then |
| 212 | + | |
| 213 | - | utils.useSticksAsFuel() |
| 213 | + | |
| 214 | if type(R) == "table" then | |
| 215 | - | for _, item in ipairs(barrels) do |
| 215 | + | |
| 216 | - | network.sendItemToNetworkStorage(R, "barrel", item, 0) |
| 216 | + | |
| 217 | reduce = true | |
| 218 | - | for _, item in ipairs(chests) do |
| 218 | + | |
| 219 | - | network.sendItemToNetworkStorage(R, "chest", item, 0) |
| 219 | + | |
| 220 | else | |
| 221 | length = R | |
| 222 | end | |
| 223 | local numBlocks = 0 | |
| 224 | - | function network.loadStorageLists() |
| 224 | + | |
| 225 | if reduce then | |
| 226 | T:forward(1) | |
| 227 | - | function lib.createList(storageType) |
| 227 | + | |
| 228 | - | local storage, turtleName, storageNames = network.wrapModem(R, storageType) -- list of barrel/chest peripherals, name of turtle, names of barrels / chests |
| 228 | + | |
| 229 | - | local total = 0 |
| 229 | + | |
| 230 | - | local locations = {}
|
| 230 | + | |
| 231 | - | for _, store in pairs(storageNames) do -- eg "minecraft:chest_1" |
| 231 | + | |
| 232 | - | T:clear() |
| 232 | + | |
| 233 | - | T:saveToLog("Checking "..store.. " contents") -- eg "checking minecraft:chest_1 contents"
|
| 233 | + | |
| 234 | - | local contents = peripheral.call(store, "list") -- list of items / slots for this chest |
| 234 | + | |
| 235 | - | for slot, item in pairs(contents) do -- for each item check if this storage is listed |
| 235 | + | |
| 236 | - | if locations[item.name] == nil then -- this item not yet found |
| 236 | + | |
| 237 | - | locations[item.name] = {store} -- add to table eg locations["minecraft:cobblestone"] = {"minecraft:chest_1"}
|
| 237 | + | |
| 238 | - | else -- already has at least 1 location |
| 238 | + | |
| 239 | - | network.addToStorageList(storageType, locations[item.name], store, false) |
| 239 | + | |
| 240 | end | |
| 241 | local place = utils.clearVegetation("down")
| |
| 242 | - | total = total + 1 |
| 242 | + | |
| 243 | if T:fillVoid("down", {}, false) then -- false if out of blocks
| |
| 244 | - | T:saveToLog("found ".. total.." "..storageType)
|
| 244 | + | |
| 245 | - | local output = textutils.serialize(locations) -- serialise to json ready to write to file |
| 245 | + | |
| 246 | - | local fileName = storageType.."Items.lua" -- barrelList.lua or chestList.lua |
| 246 | + | |
| 247 | - | local outputHandle = fs.open(fileName, "w") -- open file |
| 247 | + | |
| 248 | - | outputHandle.writeLine("return") -- start file with return
|
| 248 | + | |
| 249 | - | outputHandle.write(output) -- add serialised table |
| 249 | + | T:place("minecraft:torch", -1, "forward", false)
|
| 250 | - | outputHandle.close() -- close file |
| 250 | + | |
| 251 | end | |
| 252 | - | return locations |
| 252 | + | |
| 253 | else | |
| 254 | break | |
| 255 | - | function lib.listNeedUpdating(storageType, list) |
| 255 | + | |
| 256 | - | -- see if named chest/barrel in list is found in fresh peripheral.find |
| 256 | + | |
| 257 | - | -- turtle may have moved to a different network |
| 257 | + | |
| 258 | - | -- list = eg [ "minecraft:stick" ] = {"minecraft:barrel_91","minecraft:barrel_114"}
|
| 258 | + | |
| 259 | - | local rawStorage = {peripheral.find(storageType)}
|
| 259 | + | |
| 260 | - | if not utils.isTableEmpty(rawStorage) then -- chests / barrels are attached see if they match |
| 260 | + | |
| 261 | - | for item, storeList in pairs(list) do -- existing storage names can be found here |
| 261 | + | |
| 262 | - | local found = false |
| 262 | + | |
| 263 | - | for key, value in ipairs(rawStorage) do -- look in the fresh list of storage names to see if there are missing entries |
| 263 | + | |
| 264 | - | local name = peripheral.getName(value) |
| 264 | + | |
| 265 | - | for _, storageName in ipairs(storeList) do -- check each storage name found |
| 265 | + | |
| 266 | - | if storageName == name then -- recorded name matches, check next one |
| 266 | + | |
| 267 | - | found = true |
| 267 | + | |
| 268 | - | break |
| 268 | + | |
| 269 | D.height = # | |
| 270 | D.ceiling = false | |
| 271 | - | if found then break end |
| 271 | + | |
| 272 | D.vDirection = "U" or "D" | |
| 273 | - | if not found then |
| 273 | + | |
| 274 | - | -- no match in existing list for this storage: list needs updating |
| 274 | + | |
| 275 | - | return true-- list does not match |
| 275 | + | |
| 276 | ]] | |
| 277 | local turn = "R1" | |
| 278 | local oTurn = "L1" | |
| 279 | - | return false -- list is ok |
| 279 | + | |
| 280 | turn = "L1" | |
| 281 | oTurn = "R1" | |
| 282 | - | local _, turtleName, storageNames = network.wrapModem(R, "chest") -- _, name of turtle, list of names of storage |
| 282 | + | |
| 283 | - | if turtleName == "Modem not found" then return turtleName end |
| 283 | + | |
| 284 | - | local redo = false |
| 284 | + | |
| 285 | - | if barrelItems == nil then -- not yet loaded |
| 285 | + | |
| 286 | - | T:saveToLog("barrelItems == nil")
|
| 286 | + | |
| 287 | - | if fs.exists("barrelItems.lua") then
|
| 287 | + | |
| 288 | - | T:saveToLog("require('barrelItems')")
|
| 288 | + | |
| 289 | - | barrelItems = require("barrelItems") -- global variable
|
| 289 | + | |
| 290 | - | redo = lib.listNeedUpdating("barrel", barrelItems)
|
| 290 | + | |
| 291 | return "C2" | |
| 292 | - | T:saveToLog("lib.createList('barrel'")
|
| 292 | + | |
| 293 | - | barrelItems = lib.createList("barrel")
|
| 293 | + | |
| 294 | if D.ceiling then | |
| 295 | return "C0" | |
| 296 | - | if chestItems == nil then -- not yet loaded |
| 296 | + | |
| 297 | - | T:saveToLog("chestItems == nil")
|
| 297 | + | |
| 298 | - | if fs.exists("chestItems.lua") then
|
| 298 | + | |
| 299 | - | T:saveToLog("require('chestItems')")
|
| 299 | + | |
| 300 | - | chestItems = require("chestItems") -- global variable
|
| 300 | + | |
| 301 | - | redo = lib.listNeedUpdating("chest", barrelItems)
|
| 301 | + | |
| 302 | end | |
| 303 | - | T:saveToLog("lib.createList('chest'")
|
| 303 | + | |
| 304 | - | chestItems = lib.createList("chest")
|
| 304 | + | |
| 305 | - | end |
| 305 | + | |
| 306 | end | |
| 307 | - | if redo then |
| 307 | + | |
| 308 | - | barrelItems = lib.createList("barrel")
|
| 308 | + | |
| 309 | - | chestItems = lib.createList("chest")
|
| 309 | + | |
| 310 | return "" -- start and finish both false | |
| 311 | end | |
| 312 | ||
| 313 | - | function network.findEmptySlot(list, size) |
| 313 | + | |
| 314 | - | --[[ adapted from https://github.com/cc-tweaked/CC-Tweaked/discussions/1552 |
| 314 | + | |
| 315 | - | Find the first empty slot in a chest. |
| 315 | + | |
| 316 | - | list = list of items in the chest/barrel/dropper |
| 316 | + | |
| 317 | - | size = The size of the inventory |
| 317 | + | |
| 318 | - | return integer? slot The slot number of the first empty slot, or nil if none are empty. |
| 318 | + | |
| 319 | T:go(place, false, 0, true)-- place floor / ceiling | |
| 320 | - | for slot = 1, size do |
| 320 | + | |
| 321 | - | if not list[slot] then |
| 321 | + | |
| 322 | - | return slot |
| 322 | + | |
| 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 | - | return nil |
| 326 | + | |
| 327 | T:go(oTurn..placeF..turn, false, 0, true) -- face wall and check if block | |
| 328 | end | |
| 329 | - | function network.findItemCountInInventory(list, itemName, exactMatch) |
| 329 | + | |
| 330 | -- move forward | |
| 331 | - | Find an item in an inventory |
| 331 | + | |
| 332 | - | list = The list of items in the inventory |
| 332 | + | |
| 333 | - | itemName = The name of the item to find. |
| 333 | + | |
| 334 | - | return integer? The slot number of the item, or nil if not found. |
| 334 | + | |
| 335 | if width < D.width then | |
| 336 | - | exactMatch = exactMatch or false |
| 336 | + | |
| 337 | - | if type(list) == "string" then |
| 337 | + | |
| 338 | - | list = peripheral.call(list, "list") |
| 338 | + | |
| 339 | else | |
| 340 | - | local retValue = nil |
| 340 | + | |
| 341 | - | local count = 0 |
| 341 | + | |
| 342 | - | for slot, item in pairs(list) do |
| 342 | + | |
| 343 | else | |
| 344 | - | if exactMatch then |
| 344 | + | |
| 345 | - | if item.name == itemName then found = true end |
| 345 | + | |
| 346 | else | |
| 347 | - | if item.name:find(itemName) ~= nil then found = true end |
| 347 | + | |
| 348 | end | |
| 349 | end | |
| 350 | - | if retValue == nil then |
| 350 | + | |
| 351 | - | retValue = {}
|
| 351 | + | |
| 352 | ||
| 353 | - | table.insert(retValue,{slot, item.count}) -- eg {1, 64}
|
| 353 | + | |
| 354 | - | count = count + item.count |
| 354 | + | |
| 355 | if height == 1 then | |
| 356 | lib.layer(D, true, false) -- first layer, so start = true, finish = false | |
| 357 | - | return count, retValue -- either nil or eg {{1, 64},{4, 22}}
|
| 357 | + | |
| 358 | lib.layer(D, false, true) -- final layer, so start = false, finish = true | |
| 359 | else | |
| 360 | - | function network.findItemInInventory(inventory, itemName, exactMatch) |
| 360 | + | |
| 361 | - | --[[ adapted from https://github.com/cc-tweaked/CC-Tweaked/discussions/1552 |
| 361 | + | |
| 362 | - | Find an item in an inventory |
| 362 | + | |
| 363 | - | inventory = name of inventory or wrapped peripheral |
| 363 | + | |
| 364 | - | itemName = The name of the item to find. |
| 364 | + | |
| 365 | - | return integer?, integer? The slot number and count of the item, or nil if not found. |
| 365 | + | |
| 366 | if D.goHome then-- ends at starting point | |
| 367 | - | exactMatch = exactMatch or false |
| 367 | + | |
| 368 | - | if type(inventory) == "string" then |
| 368 | + | |
| 369 | - | T:saveToLog("network.findItemInInventory("..inventory..", "..itemName..", exactMatch = "..tostring(exactMatch)..")", true)
|
| 369 | + | |
| 370 | - | contents = peripheral.call(inventory, "list") |
| 370 | + | |
| 371 | - | else -- should be supplied with .list() already |
| 371 | + | |
| 372 | - | T:saveToLog("network.findItemInInventory(<inventory>, "..itemName..", exactMatch = "..tostring(exactMatch)..")", true)
|
| 372 | + | |
| 373 | - | contents = inventory |
| 373 | + | |
| 374 | ||
| 375 | - | --T:saveToLog("contents = "..table.concat(contents, ", "))
|
| 375 | + | |
| 376 | - | --utils.writeTraceTable("contents = ", contents)
|
| 376 | + | |
| 377 | - | if contents ~= nil then |
| 377 | + | |
| 378 | - | for slot, item in pairs(contents) do |
| 378 | + | |
| 379 | - | --T:saveToLog("item.name = "..item.name..", item.count = "..item.count)
|
| 379 | + | |
| 380 | - | if exactMatch then |
| 380 | + | |
| 381 | - | if item.name == itemName then |
| 381 | + | |
| 382 | - | T:saveToLog("Item found in "..slot..", quantity = "..item.count)
|
| 382 | + | |
| 383 | - | return slot, item.count |
| 383 | + | |
| 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 | - | if (item.name):find(itemName) ~= nil then |
| 386 | + | |
| 387 | - | T:saveToLog("Matching Item found in "..slot..", quantity = "..item.count)
|
| 387 | + | |
| 388 | - | return slot, item.count |
| 388 | + | |
| 389 | for i = 1, 2 do | |
| 390 | T:placeWater("down")
| |
| 391 | T:go("F1R1F1R1", false, 0, false)
| |
| 392 | end | |
| 393 | - | T:saveToLog("Item not found")
|
| 393 | + | |
| 394 | - | return 0,0 |
| 394 | + | |
| 395 | sleep(0.5) | |
| 396 | T:placeWater("down")
| |
| 397 | - | function network.getItemFromNetwork(storageType, itemRequired, countRequired, toTurtleSlot, ignoreStock) |
| 397 | + | |
| 398 | T:go("R2F1R1F1R1")
| |
| 399 | -- end above lower left of pond (starting point) | |
| 400 | - | function lib.getItem(storageTable, turtleName, itemRequired, countRequired, toTurtleSlot, sent) |
| 400 | + | |
| 401 | - | local exit = false |
| 401 | + | |
| 402 | - | for k, storageName in pairs(storageTable) do -- eg {"minecraft:barrel_17", "minecraft:barrel_18"...}
|
| 402 | + | |
| 403 | - | local available, data = network.findItemCountInInventory(storageName, itemRequired, false) -- either nil or eg {{1, 64},{4, 22}}
|
| 403 | + | |
| 404 | - | T:saveToLog("network.findItemCountInInventory("..storageName..", "..itemRequired..", false")
|
| 404 | + | |
| 405 | - | if data ~= nil then |
| 405 | + | |
| 406 | - | for i = 1, #data do |
| 406 | + | |
| 407 | - | local request = countRequired |
| 407 | + | |
| 408 | - | if countRequired > 64 then |
| 408 | + | |
| 409 | - | request = 64 |
| 409 | + | |
| 410 | end | |
| 411 | - | local received = network.sendItemsToTurtle(turtleName, storageName, data[i][1], request, toTurtleSlot) -- request items, returns number sent |
| 411 | + | |
| 412 | - | if received == nil then received = 0 end |
| 412 | + | |
| 413 | - | sent = sent + received |
| 413 | + | |
| 414 | - | T:saveToLog("received = "..received..", request = "..request.." from "..storageName..", sent = "..sent)
|
| 414 | + | |
| 415 | - | if sent >= countRequired then |
| 415 | + | |
| 416 | - | exit = true |
| 416 | + | |
| 417 | - | break |
| 417 | + | |
| 418 | - | end -- job done, no need to check remaining slots |
| 418 | + | |
| 419 | - | countRequired = countRequired - sent -- this line not reached if sent >= count |
| 419 | + | |
| 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 | - | --if sent >= countRequired then break end -- no need to check other storage |
| 422 | + | |
| 423 | - | --if countRequired <= 0 then break end |
| 423 | + | |
| 424 | - | if exit then |
| 424 | + | |
| 425 | - | return sent, countRequired |
| 425 | + | |
| 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 | - | return sent, countRequired |
| 429 | + | |
| 430 | ||
| 431 | function lib.frontTurn() | |
| 432 | - | -- eg slot, count = network.getItemFromNetwork("barrel", "minecraft:crafting_table", 1)
|
| 432 | + | |
| 433 | - | -- storageType either "chest" or "barrel" |
| 433 | + | |
| 434 | - | if countRequired == nil then return 0,0 end |
| 434 | + | |
| 435 | - | --if toTurtleSlot not specified then nil = use any slot |
| 435 | + | |
| 436 | - | ignoreStock = ignoreStock or false -- return only no of items obtained from storage |
| 436 | + | |
| 437 | - | T:saveToLog("network.getItemFromNetwork(storageType = "..storageType..", itemRequired = ".. itemRequired..
|
| 437 | + | |
| 438 | - | ", countRequired = ".. countRequired..", toTurtleSlot = "..tostring(toTurtleSlot)..", ignoreStock = "..tostring(ignoreStock)) |
| 438 | + | |
| 439 | - | -- Must be next to a modem: MUST remove crafting table if modem on that side. Other tools ok |
| 439 | + | |
| 440 | - | local sent = 0 |
| 440 | + | |
| 441 | - | local turtleSlot, turtleCount = T:getItemSlot(itemRequired) -- check local stock |
| 441 | + | |
| 442 | - | if not ignoreStock then -- take account of existing items and reduce count accordingly |
| 442 | + | |
| 443 | - | countRequired = countRequired - turtleCount |
| 443 | + | |
| 444 | lib.startCorner() | |
| 445 | - | local savedItems = nil |
| 445 | + | |
| 446 | - | if storageType == "barrel" then |
| 446 | + | |
| 447 | - | savedItems = barrelItems |
| 447 | + | |
| 448 | - | elseif storageType == "chest" then |
| 448 | + | |
| 449 | - | savedItems = chestItems |
| 449 | + | |
| 450 | end | |
| 451 | - | local storage, turtleName, storageNames = network.wrapModem(R, storageType) -- list of chest/barrel peripherals, name of turtle, list of storage names |
| 451 | + | |
| 452 | - | --if turtleName == "Modem not found" then return 0, nil, nil, turtleName end |
| 452 | + | |
| 453 | - | if countRequired > 0 then -- not enough in stock, or ignore current stock |
| 453 | + | |
| 454 | - | -- check if item in storageLists |
| 454 | + | |
| 455 | - | local testStores = nil |
| 455 | + | |
| 456 | - | if savedItems[itemRequired] ~= nil then -- only works with full item names |
| 456 | + | |
| 457 | - | T:saveToLog("savedItems key in list: "..textutils.serialise(savedItems[itemRequired], {compact = true}))
|
| 457 | + | |
| 458 | - | testStores = savedItems[itemRequired] |
| 458 | + | |
| 459 | return 1 | |
| 460 | - | for key, value in pairs(savedItems) do |
| 460 | + | |
| 461 | - | if key:find(itemRequired)~= nil then |
| 461 | + | |
| 462 | - | T:saveToLog("savedItems found in list: "..textutils.serialise(value, {compact = true}))
|
| 462 | + | |
| 463 | - | testStores = value |
| 463 | + | |
| 464 | local waterPresent = false | |
| 465 | for i = 1, distance do | |
| 466 | if T:isWater("down") then
| |
| 467 | waterPresent = true | |
| 468 | - | if testStores == nil then -- no match in storage lists |
| 468 | + | |
| 469 | - | T:saveToLog("Unable to find recorded storage, using all "..storageType.."s")
|
| 469 | + | |
| 470 | - | sent, countRequired = lib.getItem(storageNames, turtleName, itemRequired, countRequired, toTurtleSlot, sent) |
| 470 | + | |
| 471 | - | else -- match found, list of storage availble -- eg {"minecraft:barrel_17", "minecraft:barrel_18"...}
|
| 471 | + | |
| 472 | - | T:saveToLog("Using recorded list alias 'testStores'")
|
| 472 | + | |
| 473 | - | sent, countRequired = lib.getItem(testStores, turtleName, itemRequired, countRequired, toTurtleSlot, sent) |
| 473 | + | |
| 474 | T:go("C1", false, 0, true)
| |
| 475 | end | |
| 476 | - | -- slotData.lastSlot, total, slotData -- integer, integer, table |
| 476 | + | |
| 477 | - | local data = {}
|
| 477 | + | |
| 478 | - | turtleSlot, turtleCount, data = T:getItemSlot(itemRequired) |
| 478 | + | |
| 479 | - | T:saveToLog("turtleSlot = "..turtleSlot..", turtleCount = "..turtleCount..", sent = "..sent) --..", data = "..textutils.serialise(data))
|
| 479 | + | |
| 480 | - | if ignoreStock then |
| 480 | + | |
| 481 | - | return turtleSlot, sent -- 0 -> count |
| 481 | + | |
| 482 | for i = 1, distance do | |
| 483 | - | return turtleSlot, turtleCount -- 0 -> count |
| 483 | + | |
| 484 | if i < distance then | |
| 485 | T:forward(1) | |
| 486 | end | |
| 487 | - | function network.getSlotContains(inventoryName, inSlot) |
| 487 | + | |
| 488 | - | local list = peripheral.call(inventoryName, "list") |
| 488 | + | |
| 489 | - | for slot, item in pairs(list) do |
| 489 | + | |
| 490 | - | if inSlot == slot then |
| 490 | + | |
| 491 | - | return item.name |
| 491 | + | |
| 492 | if R.data == "" then | |
| 493 | if turtle.detectDown() then -- on solid surface | |
| 494 | - | return "" |
| 494 | + | |
| 495 | end | |
| 496 | end | |
| 497 | - | function network.moveItem(inventoryName, itemName, toSlot) |
| 497 | + | |
| 498 | - | --[[ adapted from https://github.com/cc-tweaked/CC-Tweaked/discussions/1552 |
| 498 | + | |
| 499 | - | Move a specific item to specific slot eg 1, moving other items out of the way if needed. |
| 499 | + | |
| 500 | - | inventoryName = The name of the chest/barrel/dropper to search. |
| 500 | + | |
| 501 | - | itemName = The name of the item to find. |
| 501 | + | |
| 502 | - | toSlot optional. default is slot 1 |
| 502 | + | |
| 503 | - | return boolean success Whether or not the item was successfully moved to toSlot (or already existed there) |
| 503 | + | |
| 504 | R = utils.calculateDimensions(R) | |
| 505 | - | toSlot = toSlot or 1 |
| 505 | + | |
| 506 | - | local list = peripheral.call(inventoryName, "list") |
| 506 | + | |
| 507 | - | local size = peripheral.call(inventoryName, "size") |
| 507 | + | |
| 508 | - | local slot = network.findItemInInventory(list, itemName) |
| 508 | + | |
| 509 | T:go("R2D2", false, 0, true) -- at start, level 2, facing towards the front, move backards
| |
| 510 | - | -- If the item didn't exist, or is already in the first slot, we're done. |
| 510 | + | |
| 511 | - | if not slot then |
| 511 | + | |
| 512 | - | T:saveToLog("network.moveItem(): Item not found")
|
| 512 | + | |
| 513 | if lib.placeDam(R.length) then | |
| 514 | waterPresent = true | |
| 515 | - | if slot == toSlot then |
| 515 | + | |
| 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 | - | -- If an item is blocking the first slot (we already know it's not the one we want), we need to move it. |
| 519 | + | |
| 520 | - | if list[toSlot] then |
| 520 | + | |
| 521 | - | T:saveToLog("network.moveItem() Slot "..toSlot.." occupied, moving..")
|
| 521 | + | |
| 522 | - | local emptySlot = network.findEmptySlot(list, size) |
| 522 | + | |
| 523 | waterPresent = true | |
| 524 | - | -- If there are no empty slots, we can't move the item. |
| 524 | + | |
| 525 | - | if not emptySlot then |
| 525 | + | |
| 526 | - | T:saveToLog("network.moveItem(): No empty slots")
|
| 526 | + | |
| 527 | -- lay right wall | |
| 528 | lib.frontTurn() | |
| 529 | lib.removeDam(R.length) | |
| 530 | - | -- Move the item to the first empty slot. |
| 530 | + | |
| 531 | row = row + lib.placeRetainingWall(R.length) | |
| 532 | - | if not network.moveItemStack(inventoryName, toSlot, emptySlot) then |
| 532 | + | |
| 533 | - | T:saveToLog("network.moveItem(): Failed to move item to slot " .. emptySlot)
|
| 533 | + | |
| 534 | T:go("L1F1R1")
| |
| 535 | lib.removeDam(R.length) -- faces to front on finish | |
| 536 | depth = depth + 3 | |
| 537 | - | T:saveToLog("network.moveItem(): Moved item to slot " .. emptySlot)
|
| 537 | + | |
| 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 | - | -- Move the item to slot 1. |
| 540 | + | |
| 541 | - | if not network.moveItemStack(inventoryName, slot, toSlot) then |
| 541 | + | |
| 542 | - | T:saveToLog("network.moveItem(): Failed to move item to slot "..toSlot)
|
| 542 | + | |
| 543 | end | |
| 544 | return {}
| |
| 545 | end | |
| 546 | - | T:saveToLog("network.moveItem(): Moved item to slot "..toSlot)
|
| 546 | + | |
| 547 | - | return true |
| 547 | + | |
| 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 | - | function network.moveItemsFromTurtle(turtleName, toInventoryName, fromTurtleSlot, quantity, toSlot) |
| 550 | + | |
| 551 | sleep(2) | |
| 552 | - | Move quantity of an item from one inventory to another. Turtles MUST use attachedInventory.pullItems() |
| 552 | + | |
| 553 | - | eg network.moveItemsFromTurtle(turtleName, chestName, turtleSlot, turtleCount, nil) |
| 553 | + | |
| 554 | - | turtleName: The name of the turtle (via getLocalName()) |
| 554 | + | |
| 555 | - | toInventoryName: The name of the inventory to move items into. |
| 555 | + | |
| 556 | - | fromTurtleSlot: The slot to move from. must be pre-determined for the item required |
| 556 | + | |
| 557 | - | quantity: The amount to transfer (nil for full stack) |
| 557 | + | |
| 558 | - | toSlot: The slot to move to. (nil will use any available slot(s)) |
| 558 | + | |
| 559 | allows 2 turtles to co-operate | |
| 560 | - | return peripheral.call(toInventoryName, "pullItems", turtleName, fromTurtleSlot, quantity, toSlot) |
| 560 | + | |
| 561 | R.side = "R" or "L" | |
| 562 | ]] | |
| 563 | - | function network.moveItemStack(inventoryName, fromSlot, toSlot) |
| 563 | + | |
| 564 | - | --[[ adapted from https://github.com/cc-tweaked/CC-Tweaked/discussions/1552 |
| 564 | + | |
| 565 | - | Move an item from one slot to another in a given inventory. |
| 565 | + | |
| 566 | - | inventoryName The name of the inventory to move items in. |
| 566 | + | |
| 567 | - | fromSlot The slot to move from. |
| 567 | + | |
| 568 | - | toSlot The slot to move to. |
| 568 | + | |
| 569 | local finished = false | |
| 570 | - | return peripheral.call(inventoryName, "pushItems", inventoryName, fromSlot, nil, toSlot) |
| 570 | + | |
| 571 | rs.setAnalogueOutput("front", 0) -- switch off output
| |
| 572 | local blockType = T:getBlockType("forward")
| |
| 573 | - | function network.sendItemToNetworkStorage(R, storageType, itemToSend, amountToSend) |
| 573 | + | |
| 574 | - | -- used to remove items from turtle inventory |
| 574 | + | |
| 575 | - | -- Must be next to a modem: MUST remove crafting table if modem on that side. Other tools ok |
| 575 | + | |
| 576 | sleep(0.1) | |
| 577 | timer = timer + 0.1 | |
| 578 | - | function lib.sendItem(savedItems, peripheralNames, turtleName, turtleSlot, item, slotCount, itemsPerSlot) |
| 578 | + | |
| 579 | - | local storageToUse = "" |
| 579 | + | |
| 580 | - | local storageList = lib.getStorageFromList(savedItems, item, slotCount, itemsPerSlot) -- try from savedList |
| 580 | + | |
| 581 | - | if storageList == nil then -- no match found, but use first one found with network.wrapModem |
| 581 | + | |
| 582 | - | T:saveToLog("No storage with matching items found, using first empty chest")
|
| 582 | + | |
| 583 | - | storageToUse = lib.findEmptyStorage(peripheralNames, item, itemsPerSlot, slotCount) |
| 583 | + | |
| 584 | endTimer = 0 | |
| 585 | - | T:saveToLog("Storage with matching items found, checking capacity")
|
| 585 | + | |
| 586 | - | storageToUse = lib.checkCapacity(storageList, item, slotCount, itemsPerSlot) |
| 586 | + | |
| 587 | - | if storageToUse == "" then -- no capacity in known storage list, so start a new one |
| 587 | + | |
| 588 | - | storageToUse = lib.findEmptyStorage(peripheralNames, item, itemsPerSlot, slotCount) |
| 588 | + | |
| 589 | if confirmed then | |
| 590 | menu.colourWrite("Turtle confirmed: input = "..rsIn.." output = "..rsOut, colors.orange, nil, nil, false, true)
| |
| 591 | - | --network.moveItemsFromTurtle(turtleName, toInventoryName, fromTurtleSlot, quantity, toSlot) |
| 591 | + | |
| 592 | - | T:saveToLog("network.moveItemsFromTurtle(turtleName = "..turtleName..", storageToUse = "..tostring(storageToUse)..", slot = "..tostring(turtleSlot)..", slotCount = "..tostring(slotCount)..")")
|
| 592 | + | |
| 593 | - | network.moveItemsFromTurtle(turtleName, storageToUse, turtleSlot, slotCount) |
| 593 | + | |
| 594 | else | |
| 595 | menu.colourWrite("Waiting: input = "..rsIn.." output = "..rsOut, colors.orange, nil, nil, false, true)
| |
| 596 | - | function lib.findEmptyStorage(peripheralNames, itemName, itemsPerSlot, itemCount) |
| 596 | + | |
| 597 | - | T:saveToLog("lib.findEmptyStorage("..textutils.serialise(peripheralNames,{compact = true})..", itemName = "..itemName.. ", itemsPerSlot = "..itemsPerSlot)
|
| 597 | + | |
| 598 | - | for store = 1, #peripheralNames do |
| 598 | + | |
| 599 | - | inStock, canStore, partMatch = network.checkInventory(peripheralNames[store], itemName, itemsPerSlot, "") |
| 599 | + | |
| 600 | - | if canStore > itemCount then |
| 600 | + | |
| 601 | - | return peripheralNames[store] |
| 601 | + | |
| 602 | end | |
| 603 | if endTimer >= 10 then -- allows time for other computer to get ready | |
| 604 | - | return nil |
| 604 | + | |
| 605 | end | |
| 606 | rs.setAnalogueOutput("front", 1) -- output 1 as a signal initially
| |
| 607 | - | function lib.getStorageFromList(savedItems, item, sendAmount, itemsPerSlot) |
| 607 | + | |
| 608 | - | if savedItems[item] == nil then -- no record of this item stored |
| 608 | + | |
| 609 | - | T:saveToLog("lib.getStorageFromList() "..item.." not found")
|
| 609 | + | |
| 610 | - | local parts = T:getNames(item) -- eg minecraft:jungle_planks = "minecraft", "jungle", "planks" |
| 610 | + | |
| 611 | - | for part = #parts, 1, -1 do -- iterate "planks", "jungle", "minecraft" |
| 611 | + | |
| 612 | - | local searchTerm = parts[part] |
| 612 | + | |
| 613 | - | if searchTerm ~= "minecraft" and searchTerm ~= "mysticalagriculture" then |
| 613 | + | |
| 614 | - | for itemName, storageList in pairs(savedItems) do -- iterate items used as keys eg minecraft:jungle_log matches jungle |
| 614 | + | |
| 615 | - | if itemName:find(searchTerm) ~= nil then -- partial match eg "sapling" found in "minecraft:oak_sapling" |
| 615 | + | |
| 616 | - | T:saveToLog("lib.getStorageFromList() matched "..searchTerm.." with "..itemName)
|
| 616 | + | |
| 617 | - | return storageList -- eg {"minecraft:chest_22", "minecraft:chest_23"}
|
| 617 | + | |
| 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 | - | T:saveToLog("lib.getStorageFromList() ["..item.."] found")
|
| 623 | + | |
| 624 | - | return savedItems[item] -- list of chests with this item available |
| 624 | + | |
| 625 | T:go(R.side.."3") | |
| 626 | - | return nil |
| 626 | + | |
| 627 | return rsIn -- 15 | |
| 628 | end | |
| 629 | - | function lib.checkCapacity(storageList, item, sendAmount, itemsPerSlot) |
| 629 | + | |
| 630 | - | -- find a chest/barrel with sufficient capacity from list of storage |
| 630 | + | |
| 631 | - | for store = 1, #storageList do |
| 631 | + | |
| 632 | - | local inStock, canStore, partMatch = network.checkInventory(storageList[store], item, itemsPerSlot, "") |
| 632 | + | |
| 633 | - | if canStore > sendAmount then |
| 633 | + | |
| 634 | - | return storageList[store] |
| 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 | - | amountToSend = amountToSend or 0 -- 0 = remove all of this item |
| 640 | + | |
| 641 | - | local totalSent = 0 -- track quantity sent |
| 641 | + | |
| 642 | - | local minSend = 0 -- minimum amount to send |
| 642 | + | |
| 643 | - | if amountToSend > 0 then minSend = amountToSend end -- update minimum to send |
| 643 | + | |
| 644 | - | local _, turtleName, peripheralNames = network.wrapModem(R, storageType) -- _, name of turtle, list of names of storage |
| 644 | + | |
| 645 | if T:getBlockType("forward"):find("water") ~= nil or T:getBlockType("forward"):find("bubble") ~= nil then
| |
| 646 | - | T:saveToLog("network.sendItemToNetworkStorage(R, storageType = '"..storageType.."', itemToSend = '"..itemToSend.."', amountToSend = "..amountToSend..")")
|
| 646 | + | |
| 647 | - | T:saveToLog("network.wrapModem(R, storageType = "..storageType..", turtleName = "..turtleName..")")
|
| 647 | + | |
| 648 | - | local savedItems = nil |
| 648 | + | |
| 649 | - | if storageType == "barrel" then |
| 649 | + | |
| 650 | - | savedItems = barrelItems |
| 650 | + | |
| 651 | - | elseif storageType == "chest" then |
| 651 | + | |
| 652 | - | savedItems = chestItems |
| 652 | + | |
| 653 | end | |
| 654 | -- should now be above water, but may be further down so onWater still false | |
| 655 | - | if itemToSend == "all" then -- empty Turtle, so item names not relevant |
| 655 | + | |
| 656 | - | T:saveToLog("itemToSend = all")
|
| 656 | + | |
| 657 | descent = descent + 1 | |
| 658 | - | local item, turtleSlot, slotCount, itemsPerSlot = "", 0, 0, 64 |
| 658 | + | |
| 659 | - | for slot = 1, 16 do |
| 659 | + | |
| 660 | - | item, slotCount = T:getSlotContains(slot) |
| 660 | + | |
| 661 | - | if slotCount > 0 then |
| 661 | + | |
| 662 | - | turtleSlot = slot |
| 662 | + | |
| 663 | - | T:saveToLog("for slot = 1, 16 do: item = "..item..", slotCount = "..slotCount)
|
| 663 | + | |
| 664 | - | itemsPerSlot = utils.getSlotCapacity(slot) -- most items capacity is 64 per slot |
| 664 | + | |
| 665 | - | T:saveToLog("sending'"..item.."' from slot "..slot..", quantity = "..slotCount)
|
| 665 | + | |
| 666 | end | |
| 667 | -- now above water | |
| 668 | if goIn then | |
| 669 | - | if turtleSlot > 0 then |
| 669 | + | |
| 670 | - | lib.sendItem(savedItems, peripheralNames, turtleName, turtleSlot, item, slotCount, itemsPerSlot) |
| 670 | + | |
| 671 | end | |
| 672 | - | until turtleSlot == 0 |
| 672 | + | |
| 673 | - | return 0 -- exit function |
| 673 | + | |
| 674 | ||
| 675 | - | local storageToUse = "" |
| 675 | + | |
| 676 | - | repeat -- until item no longer present in inventory or requested amount has been sent |
| 676 | + | |
| 677 | - | local sourceSlot, total, data = T:getItemSlot(itemToSend) -- which slot and how much of itemToSend is in turtle? |
| 677 | + | |
| 678 | - | local slotCount = data.leastCount |
| 678 | + | |
| 679 | - | T:saveToLog("T:getItemSlot('"..itemToSend.."' sourceSlot = "..sourceSlot..", total = "..total..")")
|
| 679 | + | |
| 680 | - | if sourceSlot == 0 then |
| 680 | + | |
| 681 | - | T:saveToLog(itemToSend.." not found in turtle inventory") |
| 681 | + | |
| 682 | - | return 0 -- exit function |
| 682 | + | |
| 683 | ||
| 684 | - | local itemsPerSlot = utils.getSlotCapacity(sourceSlot) -- most items capacity is 64 per slot |
| 684 | + | |
| 685 | - | itemToSend = data.leastName -- full name of item with lowest itemCount |
| 685 | + | local lastSlot, leastModifier, total, slotData = T:getItemSlot("minecraft:bucket", -1)
|
| 686 | - | T:saveToLog("network.sendItemToNetworkStorage(R, '"..itemToSend.."', sourceSlot = "..sourceSlot..", slotCount = "..slotCount) --..", data = "..textutils.serialise(data)..")")
|
| 686 | + | |
| 687 | - | if sourceSlot > 0 then -- item is present in turtle inventory |
| 687 | + | |
| 688 | - | local newStore = false |
| 688 | + | |
| 689 | - | local sent = 0 |
| 689 | + | |
| 690 | - | local storageList = lib.getStorageFromList(savedItems, itemToSend, slotCount, itemsPerSlot) |
| 690 | + | |
| 691 | - | if storageList == nil then |
| 691 | + | |
| 692 | - | T:saveToLog("not found in any storage, finding empty")
|
| 692 | + | |
| 693 | - | storageToUse = lib.findEmptyStorage(peripheralNames, itemToSend, itemsPerSlot, total) |
| 693 | + | |
| 694 | - | T:saveToLog("new storage: "..storageToUse.." is available")
|
| 694 | + | |
| 695 | - | network.addToStorageList(storageType, itemToSend, storageToUse, true) |
| 695 | + | |
| 696 | - | sent = network.moveItemsFromTurtle(turtleName, storageToUse, sourceSlot, slotCount) |
| 696 | + | |
| 697 | ||
| 698 | - | storageToUse = lib.checkCapacity(storageList, itemToSend, slotCount, itemsPerSlot) |
| 698 | + | |
| 699 | - | if storageToUse == "" then -- no capacity in known storage list, so start a new one |
| 699 | + | |
| 700 | - | storageToUse = lib.findEmptyStorage(peripheralNames, itemToSend, itemsPerSlot, total) |
| 700 | + | |
| 701 | - | newStore = true |
| 701 | + | |
| 702 | end | |
| 703 | - | T:saveToLog("sent = network.moveItemsFromTurtle(turtleName = "..turtleName..", storageToUse = "..storageToUse..", sourceSlot = "..sourceSlot..", slotCount = ".. slotCount)
|
| 703 | + | |
| 704 | - | sent = network.moveItemsFromTurtle(turtleName, storageToUse, sourceSlot, slotCount) |
| 704 | + | |
| 705 | end | |
| 706 | - | totalSent = totalSent + sent |
| 706 | + | |
| 707 | - | if minSend > 0 and totalSent >= minSend then |
| 707 | + | |
| 708 | - | return totalSent |
| 708 | + | |
| 709 | ||
| 710 | - | if amountToSend > 0 then -- sending specified amount |
| 710 | + | |
| 711 | - | amountToSend = amountToSend - sent |
| 711 | + | |
| 712 | T:getWater("down") -- take water from source
| |
| 713 | - | if newStore then |
| 713 | + | |
| 714 | - | network.addToStorageList(storageType, itemToSend, storageName, true) |
| 714 | + | |
| 715 | else | |
| 716 | if not turtle.detectDown() then | |
| 717 | T:go("C2", false, 0, false)
| |
| 718 | - | until sourceSlot == 0 |
| 718 | + | |
| 719 | T:getWater("forward") -- take water from source
| |
| 720 | sleep(0.2) | |
| 721 | - | return totalSent |
| 721 | + | |
| 722 | end | |
| 723 | end | |
| 724 | - | function network.sendItemsToCrafter(crafterName, fromInventoryName, fromInventorySlot, quantity, toCrafterSlot) |
| 724 | + | |
| 725 | function utils.getWaterBucketCount() | |
| 726 | - | fromInventoryName: The name of the inventory to move items from. |
| 726 | + | -- lastSlot, leastModifier, total, slotData = T:getItemSlot(item, useDamage) |
| 727 | - | fromInventorySlot: The slot to move from. must be pre-determined for the item required |
| 727 | + | local lastSlot, leastModifier, total, slotData = T:getItemSlot("minecraft:water_bucket", -1)
|
| 728 | - | quantity: The amount to transfer (nil for full stack) |
| 728 | + | |
| 729 | - | toCrafterSlot: The slot to move to. (nil will use any available slot(s)) |
| 729 | + | |
| 730 | ||
| 731 | - | return peripheral.call(fromInventoryName, "pushItems", crafterName, fromInventorySlot, quantity, toCrafterSlot) |
| 731 | + | |
| 732 | --[[ Usage: | |
| 733 | local inWater, onWater = utils.getWaterStatus() -- returns turtle position near water | |
| 734 | - | function network.sendItemsToTurtle(turtleName, fromInventoryName, fromInventorySlot, quantity, toTurtleSlot) |
| 734 | + | |
| 735 | - | --network.sendItemsToTurtle(turtleName, storageName, storageSlot, count, toTurtleSlot) |
| 735 | + | |
| 736 | ]] | |
| 737 | - | Move quantity of an item from one inventory to another. Turtles MUST use attachedInventory.pushItems() |
| 737 | + | |
| 738 | - | eg network.sendItemsToTurtle(turtleName, chestName, chestSlot, chestCount, 16) -- move to slot 16 so must be empty |
| 738 | + | |
| 739 | - | fromInventoryName: The name of the inventory to move items from. |
| 739 | + | |
| 740 | - | fromInventorySlot: The slot to move from. must be pre-determined for the item required |
| 740 | + | |
| 741 | - | quantity: The amount to transfer (nil for full stack) |
| 741 | + | |
| 742 | - | toTurtleSlot: The slot to move to. (nil will use any available slot(s)) |
| 742 | + | |
| 743 | T:turnRight(1) | |
| 744 | - | return peripheral.call(fromInventoryName, "pushItems", turtleName, fromInventorySlot, quantity, toTurtleSlot) |
| 744 | + | |
| 745 | if T:getBlockType("down"):find("water") ~= nil or T:getBlockType("down"):find("bubble") ~= nil then
| |
| 746 | onWater = true | |
| 747 | - | function network.transferItem(fromInventoryName, toInventoryName, itemName, quantity, toSlot) |
| 747 | + | |
| 748 | return inWater, onWater | |
| 749 | - | Move a specific number of an item from one inventory to another |
| 749 | + | |
| 750 | - | fromInventoryName: The name of the chest/barrel/dropper to search. |
| 750 | + | |
| 751 | - | toInventoryName: The name of the receiving inventory (chest/barrel/dropper/smelter) |
| 751 | + | |
| 752 | - | itemName: The name of the item to find. |
| 752 | + | |
| 753 | - | toSlot: optional. nil picks any slot |
| 753 | + | |
| 754 | - | return: boolean success Whether or not the item was successfully moved to toSlot (or already existed there) |
| 754 | + | |
| 755 | if not turtle.back() then | |
| 756 | - | --T:saveToLog("network.transferItem(from: "..fromInventoryName..", to: "..toInventoryName..", itemName = "..itemName..", quantity = "..tostring(quantity)..", toSlot = "..tostring(toSlot))
|
| 756 | + | |
| 757 | - | local list = peripheral.call(fromInventoryName, "list") |
| 757 | + | |
| 758 | - | local size = peripheral.call(fromInventoryName, "size") |
| 758 | + | |
| 759 | - | --T:saveToLog("network.transferItem() size = "..size..", list = \n"..textutils.serialize(list))
|
| 759 | + | |
| 760 | - | local count, data = network.findItemCountInInventory(list, itemName) -- either nil or eg {{1, 64},{4, 22}}
|
| 760 | + | |
| 761 | - | --T:saveToLog("network.transferItem() data = "..textutils.serialize(data, {compact = true}))
|
| 761 | + | |
| 762 | - | local remaining = quantity -- eg 22 items needed |
| 762 | + | |
| 763 | ||
| 764 | - | if data == nil then -- Item not found |
| 764 | + | |
| 765 | - | return quantity -- return amount requested = nothing sent |
| 765 | + | |
| 766 | menuPromptColour = menuPromptColour or colors.white | |
| 767 | ||
| 768 | - | local fromSlot = 0 |
| 768 | + | |
| 769 | - | local count = 64 |
| 769 | + | |
| 770 | - | local available = 0 |
| 770 | + | |
| 771 | - | for _, v in pairs(data) do -- eg {1, 64},{2, 64}
|
| 771 | + | |
| 772 | - | if v[2] < count and v[2] >= quantity then |
| 772 | + | |
| 773 | - | fromSlot = v[1] |
| 773 | + | |
| 774 | - | count = v[2] |
| 774 | + | |
| 775 | end | |
| 776 | - | available = available + v[2] |
| 776 | + | |
| 777 | function utils.move(R, blocks, reverse) | |
| 778 | if reverse == nil then | |
| 779 | - | if fromSlot > 0 then -- now have slot with min required quantity |
| 779 | + | |
| 780 | - | T:saveToLog("network.transferItem() from: "..fromInventoryName..", to: "..toInventoryName..", fromSlot: "..fromSlot..", toSlot: "..tostring(toSlot)..", quantity: "..tostring(quantity))
|
| 780 | + | |
| 781 | - | network.transferItems(fromInventoryName, toInventoryName, fromSlot, toSlot, quantity) |
| 781 | + | |
| 782 | - | return 0 |
| 782 | + | if R.subChoice == 2 then -- reverse direction |
| 783 | - | else -- available must be at least 1 |
| 783 | + | |
| 784 | - | for i = 1, #data do -- itreate all slots containg at least 1 item |
| 784 | + | |
| 785 | - | fromSlot = data[i][1] -- eg slot 1 |
| 785 | + | |
| 786 | - | local send = data[i][2] -- eg 10 items |
| 786 | + | |
| 787 | - | if remaining - send < 0 then -- eg 22 - 10 = 12 |
| 787 | + | |
| 788 | - | send = remaining |
| 788 | + | |
| 789 | - | remaining = 0 |
| 789 | + | |
| 790 | T:up(blocks) | |
| 791 | - | remaining = remaining - send-- eg remaining = 22 - 10 = 12 |
| 791 | + | |
| 792 | T:down(blocks) | |
| 793 | - | network.transferItems(fromInventoryName, toInventoryName, fromSlot, toSlot, send) |
| 793 | + | |
| 794 | - | if remaining <= 0 then -- all required items transferred |
| 794 | + | |
| 795 | - | return 0 |
| 795 | + | |
| 796 | end | |
| 797 | ||
| 798 | function utils.setStorageOptions() | |
| 799 | local storage = "" | |
| 800 | - | return remaining -- return remaining items to be found from a different inventory |
| 800 | + | |
| 801 | if T:getItemSlot("barrel") > 0 then
| |
| 802 | storage = "barrel" | |
| 803 | - | function network.transferItems(fromInventoryName, toInventoryName, fromSlot, toSlot, quantity) |
| 803 | + | |
| 804 | end | |
| 805 | - | Move quantity of an item from one inventory to another |
| 805 | + | |
| 806 | - | fromInventoryName: The name of the inventory to move items from. |
| 806 | + | |
| 807 | - | toInventoryName: The name of the inventory to move items into. |
| 807 | + | |
| 808 | - | fromSlot: The slot to move from. must be pre-determined for the item required |
| 808 | + | |
| 809 | - | toSlot: The slot to move to. (nil will use any available slot(s)) |
| 809 | + | |
| 810 | - | quantity: The amount to transfer (nil for full stack) |
| 810 | + | |
| 811 | return storage, storageBackup | |
| 812 | - | T:saveToLog("network.transferItems(from: "..fromInventoryName..", to: "..toInventoryName..", fromSlot: "..fromSlot..", toSlot: "..tostring(toSlot)..", quantity: "..tostring(quantity)..")")
|
| 812 | + | |
| 813 | - | return peripheral.call(fromInventoryName, "pushItems", toInventoryName, fromSlot, quantity, toSlot) |
| 813 | + | |
| 814 | local pp = utils.getPrettyPrint() | |
| 815 | ||
| 816 | - | function network.transferItemToTurtle(availableStorage, availableStorageKeys, turtleName, crafterData) |
| 816 | + | |
| 817 | - | -- network.transferItemToTurtle(<availableStorage>, data = {{1, 64},{4, 22}}, "crafter_01", <crafterData>)
|
| 817 | + | |
| 818 | - | -- availableStorage.minecraft:chest_114 = {count = 86, data = {{1, 64},{4, 22}},
|
| 818 | + | |
| 819 | - | -- availableStorage.minecraft:chest_115 = {count = 1024, data = {{1, 64},{2, 64},{3, 64}, ... }
|
| 819 | + | |
| 820 | - | -- crafterData = {{2,64}, {4,64}, {6,64}, {8,64}} 64 items in each of 4 slots in the crafter
|
| 820 | + | |
| 821 | - | -- glitch? in crafter inventory, cannot add sequentially to existing items. |
| 821 | + | |
| 822 | - | -- send to turtle slot first, then transfer |
| 822 | + | |
| 823 | - | T:saveToLog("network.transferItemToTurtle(availableStorage = "..textutils.serialise(availableStorage, {compact = true})..
|
| 823 | + | |
| 824 | - | "\navailableStorageKeys = "..textutils.serialise(availableStorageKeys, {compact = true})..
|
| 824 | + | |
| 825 | - | "\n"..turtleName..", crafterData = "..textutils.serialise(crafterData, {compact = true}))
|
| 825 | + | |
| 826 | T:go("C1", false, 0, false, R.useBlockType)
| |
| 827 | - | local total = 0 |
| 827 | + | |
| 828 | - | local numSlots = 0 |
| 828 | + | |
| 829 | - | local sent = 0 |
| 829 | + | |
| 830 | - | for _, v in ipairs(crafterData) do -- how many items required in total? |
| 830 | + | |
| 831 | - | total = total + v[2] -- how many slots does it go in |
| 831 | + | |
| 832 | - | numSlots = numSlots + 1 |
| 832 | + | |
| 833 | if l == R.length and R.data == "house" then | |
| 834 | - | for _, availableStorageKey in ipairs(availableStorageKeys) do -- eg {minecraft:chest_114, minecraft:chest_115}
|
| 834 | + | |
| 835 | - | local storageName = availableStorageKey -- eg minecraft:chest_114 |
| 835 | + | |
| 836 | - | local object = availableStorage[storageName] -- availableStorage.minecraft:chest_114 = {count = 90, data = {{14,64},{15,26}}
|
| 836 | + | |
| 837 | - | local storageData = object.data -- eg data = {{14,64},{15,26}}
|
| 837 | + | |
| 838 | - | local storageCount = object.count -- eg count = 90 |
| 838 | + | |
| 839 | - | for _, crafterSlotData in ipairs(crafterData) do -- eg {{2,22}, {4,22}, {6,22}, {8,22}} -> iteration 1 = {2, 22} iterate crafter slots to be filled
|
| 839 | + | |
| 840 | - | local toCrafterSlot = crafterSlotData[1] -- eg slot 2 in turtle |
| 840 | + | |
| 841 | - | local amountToSend = crafterSlotData[2] -- eg place 22 items in slot 2 |
| 841 | + | |
| 842 | - | T:saveToLog("storageData = "..textutils.serialise(storageData, {compact = true}))
|
| 842 | + | |
| 843 | - | T:saveToLog("crafterSlotData = "..textutils.serialise(crafterSlotData, {compact = true}))
|
| 843 | + | |
| 844 | - | for i = 1, #storageData do -- {{14,64},{15,26}}
|
| 844 | + | |
| 845 | - | local slotData = storageData[i] -- {14,64}
|
| 845 | + | |
| 846 | - | local availableToSend = slotData[2] -- 64 |
| 846 | + | |
| 847 | - | local fromStorageSlot = slotData[1] -- 14 |
| 847 | + | |
| 848 | - | local confirmedSent = 0 |
| 848 | + | |
| 849 | end | |
| 850 | - | T:saveToLog("i = "..i..", slotData = "..textutils.serialise(slotData, {compact = true}))
|
| 850 | + | |
| 851 | - | if availableToSend >= amountToSend then |
| 851 | + | |
| 852 | - | T:saveToLog("availableToSend ("..availableToSend..") >= amountToSend: ("..amountToSend.."), current value of sent = "..sent)
|
| 852 | + | |
| 853 | - | T:saveToLog("?confirmedSent = peripheral.call("..storageName..", 'pushItems', "..turtleName..
|
| 853 | + | |
| 854 | - | ", from slot "..fromStorageSlot..", amountToSend = ".. |
| 854 | + | |
| 855 | - | amountToSend..", to turtle slot "..toCrafterSlot) |
| 855 | + | |
| 856 | - | confirmedSent = peripheral.call(storageName, "pushItems", turtleName, fromStorageSlot, amountToSend, toCrafterSlot) |
| 856 | + | |
| 857 | - | sent = sent + confirmedSent |
| 857 | + | |
| 858 | - | T:saveToLog("verified confirmedSent = "..confirmedSent..", sent = "..sent)
|
| 858 | + | |
| 859 | - | slotData[2] = slotData[2] - confirmedSent |
| 859 | + | |
| 860 | - | crafterSlotData[2] = 0 |
| 860 | + | |
| 861 | - | T:saveToLog("slotData[2] = "..slotData[2]..", crafterSlotData[2] = "..crafterSlotData[2])
|
| 861 | + | |
| 862 | T:turnRight(2) -- rotate 180 | |
| 863 | - | T:saveToLog("availableToSend ("..availableToSend..") < amountToSend: ("..amountToSend.."), current value of sent = "..sent)
|
| 863 | + | |
| 864 | - | T:saveToLog("?confirmedSent = peripheral.call("..storageName..", 'pushItems', "..turtleName..
|
| 864 | + | |
| 865 | - | ", from slot "..fromStorageSlot..", availableToSend = ".. |
| 865 | + | |
| 866 | - | availableToSend..", to turtle slot "..toCrafterSlot) |
| 866 | + | |
| 867 | - | -- taking items from multiple storage slots requires loading into turtle first |
| 867 | + | |
| 868 | - | confirmedSent = peripheral.call(storageName, "pushItems", turtleName, fromStorageSlot, availableToSend, toCrafterSlot) |
| 868 | + | |
| 869 | - | sent = sent + confirmedSent |
| 869 | + | |
| 870 | - | T:saveToLog("verified confirmedSent = "..confirmedSent..", sent = "..sent)
|
| 870 | + | |
| 871 | - | amountToSend = amountToSend - confirmedSent |
| 871 | + | |
| 872 | - | slotData[2] = slotData[2] - confirmedSent |
| 872 | + | |
| 873 | - | crafterSlotData[2] = amountToSend |
| 873 | + | |
| 874 | - | T:saveToLog("slotData[2] = "..slotData[2]..", crafterSlotData[2] = "..crafterSlotData[2])
|
| 874 | + | |
| 875 | T:go("U3F1R2")
| |
| 876 | end | |
| 877 | - | if crafterSlotData[2] == 0 then |
| 877 | + | |
| 878 | - | T:saveToLog("crafterSlotData[2]("..crafterSlotData[2]..") == 0: breaking\n")
|
| 878 | + | |
| 879 | - | break -- already sent correct amount |
| 879 | + | |
| 880 | elseif remaining == 2 then | |
| 881 | lib.doubleLayer(R) | |
| 882 | end | |
| 883 | - | if sent >= total then |
| 883 | + | |
| 884 | - | T:saveToLog("sent("..sent..") >= total ("..total.."): breaking\n")
|
| 884 | + | |
| 885 | while turtle.down() do end | |
| 886 | end | |
| 887 | ||
| 888 | return {}
| |
| 889 | - | return sent |
| 889 | + | |
| 890 | ||
| 891 | local function buildStructure(R) | |
| 892 | - | function network.pullItems(fromName, fromSlot, quantity, toName, toSlot) |
| 892 | + | |
| 893 | - | quantity = quantity or 1 |
| 893 | + | |
| 894 | - | toSlot = toSlot or nil |
| 894 | + | |
| 895 | - | if type(fromName) == "table" then -- already a wrapped peripheral |
| 895 | + | |
| 896 | - | fromName = peripheral.getName(fromName) |
| 896 | + | |
| 897 | T:down(1) | |
| 898 | - | if type(toName) == "string" then |
| 898 | + | |
| 899 | - | toName = peripheral.wrap(toName) |
| 899 | + | |
| 900 | local buildHeight = R.height | |
| 901 | - | toName.pullItems(fromName, fromSlot, quantity, toSlot) |
| 901 | + | |
| 902 | local width = R.width | |
| 903 | local length = R.length | |
| 904 | - | function network.updateList(storageType) |
| 904 | + | |
| 905 | - | local output = "" |
| 905 | + | |
| 906 | - | if storageType == "barrel" then |
| 906 | + | |
| 907 | - | output = textutils.serialize(barrelItems) -- serialise to json ready to write to file |
| 907 | + | |
| 908 | - | elseif storageType == "chest" then |
| 908 | + | |
| 909 | - | output = textutils.serialize(chestItems) -- serialise to json ready to write to file |
| 909 | + | |
| 910 | end | |
| 911 | - | local fileName = storageType.."Items.lua" -- barrelList.lua or chestList.lua |
| 911 | + | |
| 912 | - | local outputHandle = fs.open(fileName, "w") -- open file |
| 912 | + | |
| 913 | - | outputHandle.writeLine("return") -- start file with return
|
| 913 | + | |
| 914 | - | outputHandle.write(output) -- add serialised table |
| 914 | + | |
| 915 | - | outputHandle.close() -- close file |
| 915 | + | |
| 916 | buildWall(R) | |
| 917 | ||
| 918 | - | function network.wrapModem(R, storageType) |
| 918 | + | |
| 919 | - | --[[To move turtle inventory items use the target peripheral: |
| 919 | + | |
| 920 | - | local modem = peripheral.wrap("front") -- wrap modem next to turtle (beware crafting table!)
|
| 920 | + | |
| 921 | - | local turtleName = modem.getNameLocal() -- get name of the turtle |
| 921 | + | |
| 922 | - | local barrel = peripheral.find("barrel") -- find barrel name you want to receive goods
|
| 922 | + | |
| 923 | - | barrel.pushItems(turtleName, 1, 1) -- push items FROM turtle to barrel pushItems(toName, fromSlot , limit , toSlot) |
| 923 | + | |
| 924 | - | barrel.pullItems(turtleName, fromSlot , limit , toSlot) |
| 924 | + | |
| 925 | lib.goDown(R) | |
| 926 | - | local modem = peripheral.find("modem") -- find modem
|
| 926 | + | |
| 927 | - | if modem == nil then |
| 927 | + | |
| 928 | - | return nil, "Modem not found" |
| 928 | + | |
| 929 | height = height - R.height -- 1, 2 or 3 | |
| 930 | - | local turtleName = modem.getNameLocal() -- get name of the turtle |
| 930 | + | |
| 931 | - | local rawStorage = nil -- peripheral find can return duplicate values |
| 931 | + | |
| 932 | - | if storageType:find("barrel") ~= nil then
|
| 932 | + | |
| 933 | - | rawStorage = {peripheral.find("minecraft:barrel")}
|
| 933 | + | |
| 934 | - | elseif storageType:find("chest") ~= nil then
|
| 934 | + | |
| 935 | - | rawStorage = {peripheral.find("minecraft:chest")}
|
| 935 | + | |
| 936 | R.length = length | |
| 937 | - | local storage = {}
|
| 937 | + | |
| 938 | - | local names = {}
|
| 938 | + | |
| 939 | - | for k, value in ipairs(rawStorage) do |
| 939 | + | |
| 940 | - | local name = peripheral.getName(value) |
| 940 | + | |
| 941 | - | if not utils.tableContains(names, name, true) then -- use exact match as checking peripherals |
| 941 | + | |
| 942 | - | table.insert(storage, value) |
| 942 | + | |
| 943 | - | table.insert(names, name) |
| 943 | + | |
| 944 | return {}
| |
| 945 | end | |
| 946 | - | return storage, turtleName, names |
| 946 | + | |
| 947 | local function buildGableRoof(R) | |
| 948 | --[[ | |
| 949 | - | function utils.assessFarm(R) |
| 949 | + | |
| 950 | - | -- sets R.networkFarm and R.mysticalAgriculture |
| 950 | + | |
| 951 | - | menu.colourPrint("Assessing farm properties...", colors.yellow)
|
| 951 | + | |
| 952 | - | --local storage = true |
| 952 | + | |
| 953 | - | for turns = 1, 4 do |
| 953 | + | |
| 954 | | down | |
| 955 | - | local itemAhead = T:getBlockType("forward")
|
| 955 | + | |
| 956 | - | if itemAhead:find("modem") ~= nil then
|
| 956 | + | |
| 957 | - | if not R.networkFarm then -- prevents repeated text display |
| 957 | + | |
| 958 | - | R.networkFarm = true |
| 958 | + | |
| 959 | - | menu.colourPrint("Network storage in use.", colors.magenta)
|
| 959 | + | |
| 960 | for i = 1, R.length + 2 do | |
| 961 | if R.useBlockType:find("stairs") ~= nil then
| |
| 962 | - | if itemAhead:find("mysticalagriculture") ~= nil then
|
| 962 | + | T:place("stairs", 0, "up")
|
| 963 | - | R.mysticalAgriculture = true |
| 963 | + | |
| 964 | - | menu.colourPrint("Mystical Agriculture deployed.", colors.lime)
|
| 964 | + | |
| 965 | end | |
| 966 | if i < R.length + 2 then | |
| 967 | - | sleep(1.5) |
| 967 | + | |
| 968 | T:go("L1F1R1")
| |
| 969 | else | |
| 970 | T:go("R1F1L1")
| |
| 971 | end | |
| 972 | - | function utils.assessTreeFarm(R) |
| 972 | + | |
| 973 | end | |
| 974 | end | |
| 975 | - | function lib.getSaplingType(R, blockType) |
| 975 | + | |
| 976 | - | if blockType == "minecraft:mangrove_log" then |
| 976 | + | |
| 977 | - | R.logType = "mangrove" |
| 977 | + | |
| 978 | - | R.useBlockType ="mangrove_propagule" |
| 978 | + | |
| 979 | for w = 1, width do | |
| 980 | - | local parts = T:getNames(blockType) |
| 980 | + | |
| 981 | - | if parts[2] == "dark" then |
| 981 | + | |
| 982 | - | R.logType = "dark_oak" |
| 982 | + | |
| 983 | - | parts[2] = "dark_oak" |
| 983 | + | |
| 984 | else | |
| 985 | - | R.logType = parts[2] -- eg "oak" |
| 985 | + | |
| 986 | end | |
| 987 | end | |
| 988 | - | R.useBlockType = parts[2].."_sapling" -- eg "oak_sapling" |
| 988 | + | |
| 989 | if h < R.height then | |
| 990 | if outward then | |
| 991 | - | turtle.turnLeft() |
| 991 | + | |
| 992 | else | |
| 993 | - | return R |
| 993 | + | |
| 994 | end | |
| 995 | end | |
| 996 | width = width - 2 | |
| 997 | - | if blockType:find("modem") ~= nil then
|
| 997 | + | |
| 998 | - | R.networkFarm = true |
| 998 | + | |
| 999 | return outward | |
| 1000 | - | if blockType:find("polished") == nil then
|
| 1000 | + | |
| 1001 | - | R.message = "Not on modem or polished. Check position" |
| 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 | - | if R.networkFarm then |
| 1005 | + | |
| 1006 | ||
| 1007 | utils.goBack(1) | |
| 1008 | - | T:saveToLog("T:forward(1): blockType = "..blockType)
|
| 1008 | + | |
| 1009 | - | if blockType:find("log") ~= nil then
|
| 1009 | + | |
| 1010 | - | R = lib.getSaplingType(R, blockType) |
| 1010 | + | |
| 1011 | - | elseif blockType:find("barrel") ~= nil then
|
| 1011 | + | |
| 1012 | - | T:go("R2F2")
|
| 1012 | + | |
| 1013 | T:down(1) | |
| 1014 | - | if blockType:find("log") ~= nil then
|
| 1014 | + | |
| 1015 | - | R = lib.getSaplingType(R, blockType) |
| 1015 | + | |
| 1016 | end | |
| 1017 | - | else -- if in correct position water is 2 blocks below |
| 1017 | + | |
| 1018 | T:go("F"..R.height + 2 .."R2U"..R.height)
| |
| 1019 | else | |
| 1020 | - | if blockType:find("water") == nil then
|
| 1020 | + | |
| 1021 | - | R.message = "No modem below. Check position" |
| 1021 | + | |
| 1022 | for h = 1, R.height + 1 do -- place tiles on right side of roof | |
| 1023 | lib.placeRoof(R, outward) | |
| 1024 | - | turtle.up() |
| 1024 | + | |
| 1025 | - | utils.goBack(1) |
| 1025 | + | |
| 1026 | - | T:go("R1F1")
|
| 1026 | + | |
| 1027 | outward = not outward | |
| 1028 | - | if blockType:find("log") ~= nil then
|
| 1028 | + | |
| 1029 | - | R = lib.getSaplingType(R, blockType) |
| 1029 | + | |
| 1030 | -- gable ends | |
| 1031 | - | R.message = "Unable to determine location. Check position" |
| 1031 | + | |
| 1032 | - | return R |
| 1032 | + | |
| 1033 | else | |
| 1034 | T:go("F1L1U1")
| |
| 1035 | end | |
| 1036 | - | R.message = "Unable to determine location. Check position" |
| 1036 | + | |
| 1037 | - | return R |
| 1037 | + | |
| 1038 | if outward then | |
| 1039 | T:go("R1F"..R.height - 1 .."R1")
| |
| 1040 | else | |
| 1041 | T:go("L1F"..R.height - 1 .."L1")
| |
| 1042 | - | return R -- sets R.networkFarm and R.useBlockType to sapling type |
| 1042 | + | |
| 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 | - | function utils.checkFarmPosition(R) |
| 1092 | + | |
| 1093 | - | local discovered = "" |
| 1093 | + | |
| 1094 | - | local success, storage, detected = false, "", 0 |
| 1094 | + | |
| 1095 | T:go("R1")
| |
| 1096 | - | T:saveToLog("Checking position "..blockType.. " down")
|
| 1096 | + | |
| 1097 | - | if blockType:find("water") ~= nil then -- over water, ? facing E (crops)
|
| 1097 | + | |
| 1098 | - | -- network: E = __modem_, N = _modem__, W = modem___, S = ___modem |
| 1098 | + | |
| 1099 | - | -- storage: E = _chestchest_, N = chestchest__, W = chest__chest, S = __chestchest |
| 1099 | + | |
| 1100 | - | -- storage: E = _barrelbarrel_, N = barrelbarrel__, W = barrel__barrel, S = __barrelbarrel |
| 1100 | + | |
| 1101 | - | T:saveToLog("? over water = true")
|
| 1101 | + | |
| 1102 | -- add slabs at top | |
| 1103 | - | success, storage = utils.isStorage("forward") -- true/false, chest, barrel, modem / ""
|
| 1103 | + | |
| 1104 | - | local itemAhead = T:getBlockType("forward")
|
| 1104 | + | |
| 1105 | T:forward(length - 3) | |
| 1106 | - | discovered = discovered .. storage |
| 1106 | + | |
| 1107 | - | if storage == "modem" then |
| 1107 | + | T:place("slab", 0, "forward")
|
| 1108 | - | R.networkFarm = true |
| 1108 | + | |
| 1109 | end | |
| 1110 | T:place("slab", 0, "forward")
| |
| 1111 | - | discovered = discovered .. "_" |
| 1111 | + | |
| 1112 | T:place("slab", 0, "forward")
| |
| 1113 | - | if itemAhead:find("mysticalagriculture") ~= nil then
|
| 1113 | + | |
| 1114 | - | R.mysticalAgriculture = true |
| 1114 | + | |
| 1115 | utils.goBack(1) | |
| 1116 | end | |
| 1117 | --[[ | |
| 1118 | - | T:saveToLog("Storage blocks found:"..discovered)
|
| 1118 | + | |
| 1119 | - | if R.networkFarm then |
| 1119 | + | |
| 1120 | - | if discovered == "modemmodem__" then |
| 1120 | + | |
| 1121 | - | T:turnLeft(1) |
| 1121 | + | |
| 1122 | - | elseif discovered == "modem__modem" then |
| 1122 | + | |
| 1123 | - | T:turnLeft(2) |
| 1123 | + | |
| 1124 | - | elseif discovered == "__modemmodem" then |
| 1124 | + | |
| 1125 | - | T:turnRight(1) |
| 1125 | + | |
| 1126 | if width is odd, ignore top layer as is only 1 block wide | |
| 1127 | - | R.ready = true |
| 1127 | + | |
| 1128 | local isWidthOdd, isLengthOdd, width, length = false, false, 0, 0 | |
| 1129 | - | if discovered == "barrelbarrel__" or |
| 1129 | + | |
| 1130 | - | discovered == "barrelchest__" or |
| 1130 | + | |
| 1131 | - | discovered == "chestchest__" then |
| 1131 | + | |
| 1132 | - | T:turnLeft(1) |
| 1132 | + | |
| 1133 | - | elseif discovered == "barrel__barrel" or discovered == "chest__chest" then |
| 1133 | + | |
| 1134 | - | T:turnLeft(2) |
| 1134 | + | |
| 1135 | - | elseif discovered == "__barrelbarrel" or discovered == "__chestchest" then |
| 1135 | + | |
| 1136 | - | T:turnRight(1) |
| 1136 | + | |
| 1137 | width = width + 2 | |
| 1138 | - | R.ready = true |
| 1138 | + | |
| 1139 | utils.goBack(1) | |
| 1140 | - | end -- else not over water |
| 1140 | + | |
| 1141 | utils.goBack(1) | |
| 1142 | - | T:saveToLog("utils.checkFarmPosition(R) return R = "..textutils.serialise(R, {compact = true}))
|
| 1142 | + | |
| 1143 | - | return R -- now facing crops, R.ready = true/false, R.networkFarm = true/false |
| 1143 | + | |
| 1144 | while turtle.down() do end | |
| 1145 | ||
| 1146 | return {}
| |
| 1147 | - | local fuelNeeded = quantity - turtle.getFuelLevel() -- eg 600 |
| 1147 | + | |
| 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 | - | -- blockType, data |
| 1160 | + | |
| 1161 | - | local blockType = T:getBlockType(direction) |
| 1161 | + | |
| 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 | - | function utils.convertEssence(R) |
| 1177 | + | |
| 1178 | - | -- R.subChoice = 1 to 5 |
| 1178 | + | |
| 1179 | - | -- R.size = quantity |
| 1179 | + | |
| 1180 | - | -- 1 = inferium to prudentium |
| 1180 | + | |
| 1181 | - | -- 2 = prudentium to tertium |
| 1181 | + | |
| 1182 | - | -- 3 = Tertium to Imperium |
| 1182 | + | |
| 1183 | - | -- 4 = Imperium to Supremium |
| 1183 | + | T:place(sapling, -1, "down") |
| 1184 | - | -- 5 = Supremium to Insanium |
| 1184 | + | |
| 1185 | end | |
| 1186 | T:forward(1) -- above pre-planted sapling | |
| 1187 | - | function lib.getCrystal() |
| 1187 | + | |
| 1188 | - | local turtleSlot, turtleCount = 0, 0 |
| 1188 | + | if not T:place(sapling, -1, "down") then |
| 1189 | - | if utils.isStorage("up") then
|
| 1189 | + | T:place("sapling", -1, "down")
|
| 1190 | - | turtle.select(2) |
| 1190 | + | |
| 1191 | - | turtle.suckUp() |
| 1191 | + | |
| 1192 | else | |
| 1193 | - | turtleSlot = T:getItemSlot("crystal")
|
| 1193 | + | if not T:place(sapling, -1, "down") then |
| 1194 | - | if turtleSlot == 0 then |
| 1194 | + | T:place("sapling", -1, "down")
|
| 1195 | - | turtleSlot, turtleCount = network.getItemFromNetwork("chest", "infusion_crystal", 1)
|
| 1195 | + | |
| 1196 | end | |
| 1197 | - | if turtleSlot > 0 then |
| 1197 | + | |
| 1198 | - | turtle.select(turtleSlot) |
| 1198 | + | |
| 1199 | - | turtle.transferTo(2) |
| 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 | - | function lib.loadCrafter(crafterName) |
| 1206 | + | |
| 1207 | - | -- up to 64 essences stored in turtle slots 2, 4, 6, 8 |
| 1207 | + | |
| 1208 | - | local slots = {2, 4, 6, 8}
|
| 1208 | + | |
| 1209 | - | for _, slot in ipairs(slots) do -- drop each slot contents into crafter ? slot 1 |
| 1209 | + | |
| 1210 | if direction == "r" then | |
| 1211 | - | turtle.drop() |
| 1211 | + | |
| 1212 | - | peripheral.call(crafterName, "pushItems", crafterName, 1, nil, slot) -- move to correct place |
| 1212 | + | |
| 1213 | else | |
| 1214 | T:turnLeft(1) | |
| 1215 | direction = "r" | |
| 1216 | - | function lib.loadTurtle(availableStorage, availableStorageKeys, turtleName, essence, loaded) |
| 1216 | + | |
| 1217 | - | -- collect essence as above and place in minecraft:crafter slots 2, 4, 6, 8 |
| 1217 | + | |
| 1218 | - | local crafterData = {{2, loaded}, {4, loaded}, {6, loaded}, {8, loaded}} -- eg 64 items in each of 4 slots in the crafter
|
| 1218 | + | |
| 1219 | - | network.transferItemToTurtle(availableStorage, availableStorageKeys, turtleName, crafterData) |
| 1219 | + | |
| 1220 | function lib.emptyInventory(blockTypeD) | |
| 1221 | --[[ Empty all except 32 of each sapling and 1 chest ]] | |
| 1222 | - | function lib.runCrafter(crafterName, count) |
| 1222 | + | |
| 1223 | - | -- can only craft once, then crystal + output is returned to turtle |
| 1223 | + | |
| 1224 | - | -- repeat process count times |
| 1224 | + | |
| 1225 | - | -- drop crystal into crafter, move to slot 5 |
| 1225 | + | |
| 1226 | -- empty logs, apples, sticks and all but 1 stack of each sapling type | |
| 1227 | - | local slot = T:getItemSlot("crystal")
|
| 1227 | + | |
| 1228 | - | if slot > 0 then |
| 1228 | + | |
| 1229 | else | |
| 1230 | - | turtle.drop() |
| 1230 | + | |
| 1231 | - | network.moveItem(crafterName, "crystal", 5) |
| 1231 | + | |
| 1232 | - | for i = 1, 3 do |
| 1232 | + | |
| 1233 | - | rs.setAnalogOutput("front",15)
|
| 1233 | + | |
| 1234 | - | sleep(0.1) |
| 1234 | + | |
| 1235 | - | rs.setAnalogOutput("front", 0)
|
| 1235 | + | |
| 1236 | if blockTypeD == nil then | |
| 1237 | blockTypeD = T:getBlockType("down")
| |
| 1238 | end | |
| 1239 | - | while turtle.suck() do end |
| 1239 | + | |
| 1240 | T:down(1) | |
| 1241 | lib.suck() | |
| 1242 | - | function lib.storeCrystal() |
| 1242 | + | |
| 1243 | - | if utils.isStorage("up") then
|
| 1243 | + | |
| 1244 | - | T:dropItem("crystal", "up")
|
| 1244 | + | |
| 1245 | end | |
| 1246 | - | network.sendItemToNetworkStorage(R, "chest", "crystal", 0) -- empty turtle to storage chests |
| 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 | - | function lib.storeOutput() |
| 1250 | + | |
| 1251 | - | if utils.isStorage("up") then
|
| 1251 | + | |
| 1252 | - | T:dropItem("crystal", "up")
|
| 1252 | + | |
| 1253 | T:dig("up") -- remove leaves / low branches above to allow space for player
| |
| 1254 | - | network.sendItemToNetworkStorage(R, "chest", "all", 0) -- empty turtle to storage chests |
| 1254 | + | |
| 1255 | blockTypeD = lib.moveDown() | |
| 1256 | if not lib.emptyInventory(blockTypeD) then -- check if above a corner chest / barrel | |
| 1257 | - | function lib.getStorageData(essence) |
| 1257 | + | |
| 1258 | - | local _, turtleName, storageNames = network.wrapModem(R, "chests") -- _, turtleName, list of chest names |
| 1258 | + | |
| 1259 | - | if turtleName == "Modem not found" then return 0, nil, nil, turtleName end |
| 1259 | + | |
| 1260 | - | local availableStorage = {}
|
| 1260 | + | |
| 1261 | - | local availableStorageKeys = {}
|
| 1261 | + | |
| 1262 | - | local total = 0 |
| 1262 | + | |
| 1263 | - | for _, storageName in pairs(storageNames) do |
| 1263 | + | |
| 1264 | - | local storageCount, storageData = network.findItemCountInInventory(storageName, essence) -- eg 86, {{1, 64},{4, 22}}
|
| 1264 | + | |
| 1265 | - | if storageCount > 0 then -- eg 86: storage has some items |
| 1265 | + | |
| 1266 | - | T:saveToLog("storageCount = "..storageCount)
|
| 1266 | + | |
| 1267 | - | availableStorage[storageName] = {}
|
| 1267 | + | |
| 1268 | - | availableStorage[storageName].count = storageCount |
| 1268 | + | |
| 1269 | - | availableStorage[storageName].data = storageData |
| 1269 | + | |
| 1270 | - | table.insert(availableStorageKeys, storageName) |
| 1270 | + | |
| 1271 | - | total = total + storageCount |
| 1271 | + | |
| 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 | - | return total, availableStorage, availableStorageKeys, turtleName |
| 1275 | + | |
| 1276 | blockTypeF = T:getBlockType("forward")
| |
| 1277 | - | availableStorage.minecraft:chest_114 = {count = 86, data = {{1, 64},{4, 22}},
|
| 1277 | + | |
| 1278 | - | availableStorage.minecraft:chest_115 = {count = 1024, data = {{1, 64},{2, 64},{3, 64}, ... }
|
| 1278 | + | |
| 1279 | return T:getBlockType("forward")
| |
| 1280 | elseif blockTypeF:find("leaves") ~= nil then
| |
| 1281 | T:dig("forward")
| |
| 1282 | - | local essences = {"mysticalagriculture:inferium_essence",
|
| 1282 | + | |
| 1283 | - | "mysticalagriculture:prudentium_essence", |
| 1283 | + | |
| 1284 | - | "mysticalagriculture:tertium_essence", |
| 1284 | + | |
| 1285 | - | "mysticalagriculture:imperium_essence", |
| 1285 | + | |
| 1286 | - | "mysticalagriculture:supremium_essence", |
| 1286 | + | |
| 1287 | - | "mysticalagriculture:insanium_essence"} |
| 1287 | + | |
| 1288 | function lib.harvestTree(blockTypeF) | |
| 1289 | - | local message = network.loadStorageLists() |
| 1289 | + | |
| 1290 | - | if message ~= nil then return {message} end
|
| 1290 | + | |
| 1291 | - | local essence = essences[R.subChoice] |
| 1291 | + | |
| 1292 | - | local missing = "" |
| 1292 | + | |
| 1293 | - | local crafter = peripheral.find("minecraft:crafter")
|
| 1293 | + | |
| 1294 | - | local crafterName = "" |
| 1294 | + | |
| 1295 | - | local completed = 0 |
| 1295 | + | |
| 1296 | - | if R.size > 0 then |
| 1296 | + | |
| 1297 | - | R.size = math.floor(R.size / 4) * 4 |
| 1297 | + | |
| 1298 | - | if R.size == 0 then R.size = 4 end |
| 1298 | + | |
| 1299 | local success = true | |
| 1300 | - | if crafter == nil then |
| 1300 | + | |
| 1301 | - | return {"No crafter found"}
|
| 1301 | + | |
| 1302 | if not success then -- did not move forwards, block in the way: either log, dirt/grass, border block or vegetation | |
| 1303 | - | crafterName = peripheral.getName(crafter) |
| 1303 | + | |
| 1304 | - | T:saveToLog("utils.convertEssence started using "..essence..", quantity = "..R.size )
|
| 1304 | + | |
| 1305 | - | while turtle.suck() do end -- empty crafter |
| 1305 | + | |
| 1306 | - | lib.storeOutput() -- empty turtle to storage chests, (except crystal if storage above) |
| 1306 | + | |
| 1307 | - | if not lib.getCrystal() then |
| 1307 | + | |
| 1308 | - | return {"Failed: missing infusion crystal"}
|
| 1308 | + | |
| 1309 | blockTypeF = lib.moveUp(blockTypeF) -- move up until leaves/log/air | |
| 1310 | - | lib.storeCrystal() |
| 1310 | + | |
| 1311 | - | local totalInStorage, availableStorage, availableStorageKeys, turtleName = lib.getStorageData(essence) |
| 1311 | + | |
| 1312 | - | if totalInStorage < 4 then |
| 1312 | + | |
| 1313 | - | return {"Only "..totalInStorage.." ".. essence:sub(20).." available"}
|
| 1313 | + | |
| 1314 | end | |
| 1315 | - | -- can only transfer full amount direct to crafter |
| 1315 | + | |
| 1316 | - | -- if a chest has 32 items in 1 slot and 32 in another Slot |
| 1316 | + | |
| 1317 | - | -- these have to be sent into the turtle first, dropped into crafter slot 1 and moved to correct position |
| 1317 | + | |
| 1318 | - | totalInStorage = math.floor(totalInStorage / 4) * 4 |
| 1318 | + | |
| 1319 | - | if R.size == 0 then -- process all |
| 1319 | + | |
| 1320 | - | T:saveToLog("initial call lib.loadTurtle("..turtleName..", "..totalInStorage.." essence")
|
| 1320 | + | |
| 1321 | - | local processed = 0 |
| 1321 | + | |
| 1322 | - | local loaded = 0 |
| 1322 | + | |
| 1323 | function lib.isBorder(blockType) | |
| 1324 | - | while totalInStorage > 0 do -- use ALL stored essence |
| 1324 | + | |
| 1325 | - | if totalInStorage - 256 > 0 then |
| 1325 | + | |
| 1326 | - | loaded = 64 |
| 1326 | + | |
| 1327 | end | |
| 1328 | - | loaded = totalInStorage / 4 |
| 1328 | + | |
| 1329 | return false, "" | |
| 1330 | - | lib.loadTurtle(availableStorage, availableStorageKeys, turtleName, essence, loaded) |
| 1330 | + | |
| 1331 | - | lib.loadCrafter(crafterName) |
| 1331 | + | |
| 1332 | - | lib.getCrystal() |
| 1332 | + | |
| 1333 | - | processed = processed + loaded |
| 1333 | + | |
| 1334 | - | totalInStorage = totalInStorage - loaded * 4 |
| 1334 | + | |
| 1335 | - | lib.runCrafter(crafterName, loaded) |
| 1335 | + | |
| 1336 | - | lib.storeOutput() |
| 1336 | + | |
| 1337 | end | |
| 1338 | - | elseif R.size <= 64 then |
| 1338 | + | |
| 1339 | - | local loaded = math.min(R.size, totalInStorage) -- process requested or available if less |
| 1339 | + | |
| 1340 | - | if loaded > 0 then |
| 1340 | + | |
| 1341 | - | lib.loadTurtle(availableStorage, availableStorageKeys, turtleName, essence, loaded) |
| 1341 | + | |
| 1342 | - | lib.loadCrafter(crafterName) |
| 1342 | + | |
| 1343 | - | lib.getCrystal() |
| 1343 | + | |
| 1344 | - | lib.runCrafter(crafterName, loaded) |
| 1344 | + | |
| 1345 | - | lib.storeOutput() |
| 1345 | + | |
| 1346 | end | |
| 1347 | - | else -- amount > 64 |
| 1347 | + | |
| 1348 | - | local processed = 0 |
| 1348 | + | |
| 1349 | - | local loaded = 0 |
| 1349 | + | |
| 1350 | - | while totalInStorage > 0 and processed < R.size do -- stop if run out of essence, or reached target |
| 1350 | + | |
| 1351 | - | if totalInStorage - 256 > 0 and R.size - processed >= 64 then |
| 1351 | + | |
| 1352 | - | loaded = 64 |
| 1352 | + | |
| 1353 | - | elseif totalInStorage - 256 > 0 and R.size - processed > 0 then |
| 1353 | + | |
| 1354 | - | loaded = R.size - processed |
| 1354 | + | |
| 1355 | else | |
| 1356 | - | lib.loadTurtle(availableStorage, availableStorageKeys, turtleName, essence, loaded) |
| 1356 | + | |
| 1357 | - | lib.loadCrafter(crafterName) |
| 1357 | + | |
| 1358 | - | lib.getCrystal() |
| 1358 | + | |
| 1359 | - | processed = processed + loaded |
| 1359 | + | |
| 1360 | - | totalInStorage = totalInStorage - loaded * 4 |
| 1360 | + | |
| 1361 | - | lib.runCrafter(crafterName, loaded) |
| 1361 | + | |
| 1362 | - | lib.storeOutput() |
| 1362 | + | |
| 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 | - | lib.storeOutput() |
| 1365 | + | |
| 1366 | if blockType:find("log") ~= nil then -- originally felling a tree so complete it
| |
| 1367 | - | return {"success"}
|
| 1367 | + | |
| 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 | - | function utils.craftItem(R) |
| 1371 | + | |
| 1372 | - | local message = network.loadStorageLists() -- initialises or creates lists of where an item can be found: GLOBAL LISTS! |
| 1372 | + | |
| 1373 | - | if message ~= nil then return {message} end
|
| 1373 | + | |
| 1374 | - | T:saveToLog("call network.emptyInventory(R, {'sapling', 'propagule', 'dirt', 'crafting'}, {'all'}, true)")
|
| 1374 | + | |
| 1375 | - | network.emptyInventory(R, {"sapling", "propagule", "dirt", "crafting"}, {"all"}, true) -- 2 lists, one for barrels, one for chests
|
| 1375 | + | |
| 1376 | - | T:saveToLog("\ncall network.getItemFromNetwork('barrel', 'minecraft:dirt', 169)")
|
| 1376 | + | |
| 1377 | - | --network.getItemFromNetwork(storageType, itemRequired, countRequired, toTurtleSlot, ignoreStock) |
| 1377 | + | |
| 1378 | - | local turtleSlot, turtleCount = network.getItemFromNetwork("barrel", "minecraft:dirt", 169, nil, false)
|
| 1378 | + | |
| 1379 | - | T:saveToLog("Get from barrel completed: turtleSlot = "..turtleSlot..", turtleCount = "..turtleCount..", ignoreStock = "..tostring(ignoreStock))
|
| 1379 | + | |
| 1380 | - | if turtleCount < 169 then |
| 1380 | + | |
| 1381 | - | T:saveToLog("\ncall network.getItemFromNetwork('chest', 'minecraft:dirt', ".. 169 - turtleCount..", ignoreStock = "..tostring(ignoreStock)..")")
|
| 1381 | + | |
| 1382 | - | turtleSlot, turtleCount = network.getItemFromNetwork("chest", "minecraft:dirt", 169 - turtleCount, nil, true)
|
| 1382 | + | |
| 1383 | - | if turtleCount < 169 then -- ask player for saplings |
| 1383 | + | |
| 1384 | - | T:checkInventoryForItem({"dirt"}, {169 - turtleCount})
|
| 1384 | + | |
| 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 | - | T:place("minecraft:torch", "forward", false)
|
| 1430 | + | |
| 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 | - | function utils.createStorage() |
| 1446 | + | |
| 1447 | - | -- start in centre, above 1st level |
| 1447 | + | |
| 1448 | - | T:place("modem", "down")
|
| 1448 | + | |
| 1449 | end | |
| 1450 | if y < R.length then | |
| 1451 | - | T:place("chest", "down") -- places with handle at back of turtle
|
| 1451 | + | |
| 1452 | end | |
| 1453 | - | T:place("chest", "down") -- 2nd of pair
|
| 1453 | + | |
| 1454 | - | for i = 1, 3 do |
| 1454 | + | |
| 1455 | if x < loopWidth or (x == loopWidth and evenWidth) then -- go down if on R.width 2,4,6,8 etc | |
| 1456 | - | T:place("chest", "down")
|
| 1456 | + | |
| 1457 | - | T:go("R1F1L1")
|
| 1457 | + | |
| 1458 | - | T:place("chest", "down")
|
| 1458 | + | |
| 1459 | if not turtle.detectDown() then | |
| 1460 | T:place("minecraft:dirt", -1, "down", true)
| |
| 1461 | - | T:go("F1L1F1") -- end at starting position
|
| 1461 | + | |
| 1462 | - | network.attachModem() |
| 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 | - | if not T:place("sand", "down", false) then
|
| 1749 | + | |
| 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 | - | local lastSlot, leastModifier, total, slotData = T:getItemSlot("minecraft:bucket")
|
| 1885 | + | |
| 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 | - | function utils.getSlotCapacity(slot) |
| 1910 | + | |
| 1911 | - | return turtle.getItemSpace(slot) + turtle.getItemCount(slot) |
| 1911 | + | |
| 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 | - | -- lastSlot, leastModifier, total, slotData = T:getItemSlot(item) |
| 1930 | + | |
| 1931 | - | local lastSlot, leastModifier, total, slotData = T:getItemSlot("minecraft:water_bucket")
|
| 1931 | + | |
| 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 | - | function utils.isStorage(direction) |
| 1981 | + | |
| 1982 | - | local blockType = T:getBlockType(direction) |
| 1982 | + | |
| 1983 | - | if blockType:find("barrel") ~= nil then
|
| 1983 | + | |
| 1984 | - | return true, "barrel" |
| 1984 | + | |
| 1985 | - | elseif blockType:find("chest") ~= nil then
|
| 1985 | + | |
| 1986 | - | return true, "chest" |
| 1986 | + | |
| 1987 | - | elseif blockType:find("modem") ~= nil then
|
| 1987 | + | |
| 1988 | - | return true, "modem" |
| 1988 | + | |
| 1989 | end | |
| 1990 | -- go up 1 to prevent loop | |
| 1991 | - | return false, blockType |
| 1991 | + | |
| 1992 | D.depth = D.depth - 1 | |
| 1993 | end | |
| 1994 | - | function utils.isTableEmpty(aTable) |
| 1994 | + | |
| 1995 | - | if next(aTable) == nil then |
| 1995 | + | |
| 1996 | end | |
| 1997 | end | |
| 1998 | - | return false |
| 1998 | + | |
| 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 | - | if blocks == 0 then return 0 end |
| 2002 | + | |
| 2003 | end | |
| 2004 | ||
| 2005 | function lib.checkArches(D) | |
| 2006 | -- gone under a block so could be monument arch (6) | |
| 2007 | - | --if R.subChoice == 2 then -- reverse direction |
| 2007 | + | |
| 2008 | - | if R.direction == "down" or R.subChoice == 2 then -- reverse direction |
| 2008 | + | |
| 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 | - | --if R.subChoice == 1 then |
| 2015 | + | |
| 2016 | - | if R.direction == "up" or R.subChoice == 1 then |
| 2016 | + | |
| 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 | - | function utils.printR(R) |
| 2025 | + | |
| 2026 | T:go(path) -- clears arch top 4 and returns | |
| 2027 | - | choice = 0, |
| 2027 | + | |
| 2028 | - | subChoice = 0, |
| 2028 | + | |
| 2029 | - | size = 0, |
| 2029 | + | |
| 2030 | - | width = 0, |
| 2030 | + | |
| 2031 | - | length = 0, |
| 2031 | + | |
| 2032 | - | height = 0, |
| 2032 | + | |
| 2033 | - | depth = 0, |
| 2033 | + | |
| 2034 | - | up = false, |
| 2034 | + | |
| 2035 | - | down = false, |
| 2035 | + | |
| 2036 | - | silent = false, |
| 2036 | + | |
| 2037 | - | data = {},
|
| 2037 | + | |
| 2038 | - | torchInterval = 0, |
| 2038 | + | |
| 2039 | - | useBlockType = "", |
| 2039 | + | |
| 2040 | - | auto = false, |
| 2040 | + | |
| 2041 | - | side = "", |
| 2041 | + | |
| 2042 | - | direction = "", |
| 2042 | + | |
| 2043 | - | ready = false, |
| 2043 | + | |
| 2044 | - | networkFarm = false, |
| 2044 | + | |
| 2045 | - | mysticalAgriculture = false, |
| 2045 | + | |
| 2046 | - | logType = "", |
| 2046 | + | |
| 2047 | - | treeSize = "", |
| 2047 | + | |
| 2048 | - | message = "" |
| 2048 | + | |
| 2049 | end | |
| 2050 | end | |
| 2051 | - | print("choice= ".. tostring(R.choice)..", subChoice= ".. tostring(R.subChoice))
|
| 2051 | + | |
| 2052 | - | print("size= ".. tostring(R.size)..", width= ".. tostring(R.width))
|
| 2052 | + | |
| 2053 | - | print("length= ".. tostring(R.length)..", height= ".. tostring(R.height)..", depth= ".. tostring(R.depth))
|
| 2053 | + | |
| 2054 | - | print("silent= "..tostring(R.silent)..", up= ".. tostring(R.up)..", down= "..tostring(R.down))
|
| 2054 | + | |
| 2055 | - | print("torchInterval= ".. tostring(R.torchInterval))
|
| 2055 | + | |
| 2056 | - | print("useBlockType= "..tostring(R.useBlockType))
|
| 2056 | + | |
| 2057 | - | print("auto= ".. tostring(R.auto)..", side= "..tostring(R.side)..", direction= "..tostring(R.direction))
|
| 2057 | + | |
| 2058 | - | print("ready= ".. tostring(R.ready)..", networkFarm= "..tostring(R.networkFarm)..", mysticalAgriculture= "..tostring(R.mysticalAgriculture))
|
| 2058 | + | |
| 2059 | - | print("logType= ".. tostring(R.logType)..", treeSize= "..tostring(R.treeSize)..", message= "..tostring(R.message))
|
| 2059 | + | |
| 2060 | - | if type(R.data) == "table" then |
| 2060 | + | |
| 2061 | - | io.write("data= ")
|
| 2061 | + | |
| 2062 | - | for k,v in pairs(R.data) do |
| 2062 | + | |
| 2063 | - | print(k ..": "..tostring(v)) |
| 2063 | + | |
| 2064 | repeat | |
| 2065 | if utils.clearVegetation("forward") then
| |
| 2066 | - | print("data= ".. tostring(R.data))
|
| 2066 | + | |
| 2067 | D = lib.clearDown(D) -- go down if in water/air, D.blockType is updated with floor type | |
| 2068 | - | io.write("Enter to continue")
|
| 2068 | + | |
| 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 | - | function utils.tableContains(tableName, value, exactMatch) |
| 2100 | + | |
| 2101 | - | exactMatch = exactMatch or false |
| 2101 | + | |
| 2102 | - | for k, v in ipairs(tableName) do |
| 2102 | + | |
| 2103 | - | if exactMatch then |
| 2103 | + | |
| 2104 | - | if v == value then |
| 2104 | + | |
| 2105 | direction = "L" | |
| 2106 | end | |
| 2107 | T:go(direction.. 1) | |
| 2108 | - | if v:find(value) ~= nil then |
| 2108 | + | |
| 2109 | T:forward(1) | |
| 2110 | --D.depth = D.depth + lib.clearDown(depth) | |
| 2111 | D = lib.clearDown(D) | |
| 2112 | else | |
| 2113 | - | return false |
| 2113 | + | |
| 2114 | T:up(1) | |
| 2115 | D.depth = D.depth - 1 | |
| 2116 | - | function utils.useSticksAsFuel() |
| 2116 | + | |
| 2117 | - | local slot = T:getItemSlot("minecraft:stick")
|
| 2117 | + | |
| 2118 | - | if slot > 0 then -- use any sticks to refuel |
| 2118 | + | |
| 2119 | - | turtle.select(slot) |
| 2119 | + | |
| 2120 | - | turtle.refuel() |
| 2120 | + | |
| 2121 | ||
| 2122 | - | slot = T:getItemSlot("minecraft:mangrove_roots")
|
| 2122 | + | |
| 2123 | - | if slot > 0 then -- use any roots to refuel |
| 2123 | + | |
| 2124 | - | turtle.select(slot) |
| 2124 | + | |
| 2125 | - | turtle.refuel() |
| 2125 | + | |
| 2126 | D.depth = 0 | |
| 2127 | D.maxDepth = 0 | |
| 2128 | D.blockType = "" | |
| 2129 | - | function utils.waitForInput(message) |
| 2129 | + | |
| 2130 | - | -- debugging. Pause script and asks user to continue |
| 2130 | + | |
| 2131 | - | -- global dbug flag has to be set first |
| 2131 | + | |
| 2132 | - | if dbug then |
| 2132 | + | |
| 2133 | - | if message ~= nil then |
| 2133 | + | |
| 2134 | - | print(message) |
| 2134 | + | |
| 2135 | - | T:saveToLog(message, false) |
| 2135 | + | |
| 2136 | D.onWater = false | |
| 2137 | - | menu.colourPrint("Enter to continue...", colors.lightBlue)
|
| 2137 | + | |
| 2138 | - | --io.write("Press Enter to continue...")
|
| 2138 | + | |
| 2139 | - | return read() |
| 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 | - | function utils.writeTraceTable(description, tbl) |
| 2143 | + | |
| 2144 | - | local text = "" |
| 2144 | + | |
| 2145 | - | for key, value in pairs(tbl) do |
| 2145 | + | |
| 2146 | - | if type(value) == "table" then |
| 2146 | + | |
| 2147 | - | for k,v in pairs(value) do |
| 2147 | + | |
| 2148 | - | text = text.."k = "..k..", v = "..v.."; " |
| 2148 | + | |
| 2149 | end | |
| 2150 | end | |
| 2151 | - | text = "key = "..key..", value = "..value |
| 2151 | + | |
| 2152 | D = lib.clearDown(D) -- go down to floor, set depth, maxDepth, blockType | |
| 2153 | if R.data == "clearWaterPlants" then -- NOT monument corner discovery | |
| 2154 | - | T:saveToLog(description.."\n".. text) |
| 2154 | + | |
| 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 | - | T:place("stairs", "up")
|
| 2305 | + | |
| 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 | - | T:place("slab", "forward")
|
| 2399 | + | |
| 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 | - | T:place("stairs", "up")
|
| 2424 | + | |
| 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:place("slab", "forward")
|
| 2450 | + | |
| 2451 | T:forward(above) | |
| 2452 | end | |
| 2453 | - | T:place("slab", "forward")
|
| 2453 | + | |
| 2454 | -- now back at starting point | |
| 2455 | - | T:place("slab", "forward")
|
| 2455 | + | |
| 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 | - | T:place(sapling, "down") |
| 2526 | + | |
| 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 not T:place(sapling, "down") then |
| 2531 | + | |
| 2532 | - | T:place("sapling", "down")
|
| 2532 | + | |
| 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 | - | if not T:place(sapling, "down") then |
| 2536 | + | |
| 2537 | - | T:place("sapling", "down")
|
| 2537 | + | |
| 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 | - | T:place("minecraft:dirt", "down", true)
|
| 2782 | + | |
| 2783 | ]] | |
| 2784 | local lib = {}
| |
| 2785 | ||
| 2786 | function lib.checkStartPosition() | |
| 2787 | --[[ | |
| 2788 | - | T:place("minecraft:dirt", "down", true)
|
| 2788 | + | |
| 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 | - | T:place("minecraft:dirt", "down", true)
|
| 2803 | + | |
| 2804 | if blockType:find("water") == nil then -- on at least level 0
| |
| 2805 | - | blockType = T:getBlockType("down")
|
| 2805 | + | |
| 2806 | sleep(2) | |
| 2807 | T:forward(1) | |
| 2808 | blockType = T:getBlockType("down")
| |
| 2809 | - | T:place("minecraft:dirt", "down", true)
|
| 2809 | + | |
| 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 | - | --T:go("x0x2F1x0x2")
|
| 2842 | + | |
| 2843 | - | turtle.digDown() -- dig below |
| 2843 | + | |
| 2844 | - | while turtle.digUp() do end -- dig up including gravity blocks |
| 2844 | + | |
| 2845 | - | while not turtle.forward() do -- if no block in front, moves forward |
| 2845 | + | |
| 2846 | - | turtle.dig() -- block in front, so dig it |
| 2846 | + | |
| 2847 | isWater, isSource, isIce = T:isWater(direction) | |
| 2848 | - | turtle.digDown() -- now moved forward so dig down again |
| 2848 | + | |
| 2849 | - | while turtle.digUp() do end -- dig up again including gravity blocks |
| 2849 | + | |
| 2850 | end | |
| 2851 | end | |
| 2852 | end | |
| 2853 | if direction == "" then | |
| 2854 | print("Unable to locate water source")
| |
| 2855 | - | --T:go("x0F1x0")
|
| 2855 | + | |
| 2856 | - | while turtle.digUp() do end |
| 2856 | + | |
| 2857 | - | while not turtle.forward() do -- if no block in front, moves forward |
| 2857 | + | |
| 2858 | - | turtle.dig() -- block in front, so dig it |
| 2858 | + | |
| 2859 | sleep(0.3) | |
| 2860 | - | while turtle.digUp() do end |
| 2860 | + | |
| 2861 | print("Unable to fill bucket ".. i .." / "..emptyBuckets)
| |
| 2862 | end | |
| 2863 | end | |
| 2864 | end | |
| 2865 | end | |
| 2866 | - | --T:go("x2F1x2")
|
| 2866 | + | |
| 2867 | - | turtle.digDown() |
| 2867 | + | |
| 2868 | - | while not turtle.forward() do -- if no block in front, moves forward |
| 2868 | + | |
| 2869 | - | turtle.dig() -- block in front, so dig it |
| 2869 | + | |
| 2870 | for i = 1, length do | |
| 2871 | - | turtle.digDown() |
| 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 | - | elseif R.down then -- single block wide trench dig R.down = 2 blocks deep |
| 2889 | + | |
| 2890 | if moves < length then | |
| 2891 | - | else -- single block wide = 1 block deep |
| 2891 | + | |
| 2892 | moves = moves + 1 | |
| 2893 | end | |
| 2894 | - | T:turnRight(2) -- turn at the top of the run |
| 2894 | + | |
| 2895 | - | T:forward(R.length - 1) -- return to start |
| 2895 | + | |
| 2896 | - | T:turnRight(2) -- turn round to original position |
| 2896 | + | |
| 2897 | - | else -- R.width 2 or more blocks |
| 2897 | + | |
| 2898 | - | local iterations = 0 -- R.width = 2, 4, 6, 8 etc |
| 2898 | + | T:place("slab", -1, "down", false)
|
| 2899 | - | if R.width % 2 == 1 then -- R.width = 3, 5, 7, 9 eg R.width 7 |
| 2899 | + | |
| 2900 | - | iterations = (R.width - 1) / 2 -- iterations 1, 2, 3, 4 for widths 3, 5, 7, 9 |
| 2900 | + | |
| 2901 | if T:placeWater("up") then -- end of length
| |
| 2902 | print("Placed final source up")
| |
| 2903 | end | |
| 2904 | - | for i = 1, iterations do -- eg 3 blocks wide, iterations = 1 |
| 2904 | + | |
| 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 | - | menu item: Clear hollow structure |
| 3004 | + | |
| 3005 | T:placeWater("down") -- place water down
| |
| 3006 | - | if outside active area will have already moved in |
| 3006 | + | |
| 3007 | - | R.direction = "up" or "down" as direction of travel |
| 3007 | + | T:place("gate", -1, "forward", false) -- place fence gate
|
| 3008 | - | R.up = true / false to dig up as well |
| 3008 | + | |
| 3009 | - | R.down = true / false to dig down as well |
| 3009 | + | |
| 3010 | - | R.data.ceiling = true / false to remove ceiling |
| 3010 | + | |
| 3011 | - | R.data.floor = true / false to remove floor |
| 3011 | + | T:place("gate", -1, "forward", false) -- place fence gate
|
| 3012 | - | examples use a 5 x 5 x 7 cube |
| 3012 | + | |
| 3013 | T:go("R1F1 L1x1 R1C1")
| |
| 3014 | - | --utils.printR(R) -- debug values in R |
| 3014 | + | |
| 3015 | - | local height = 1 -- current level of turtle |
| 3015 | + | |
| 3016 | - | local cleared = false |
| 3016 | + | |
| 3017 | backToWater = 1 | |
| 3018 | - | R.up = false |
| 3018 | + | |
| 3019 | - | R.down = false |
| 3019 | + | |
| 3020 | - | -- check if floor/ceiling is to be cleared |
| 3020 | + | |
| 3021 | - | if R.direction == "up" then -- from bottom to top |
| 3021 | + | |
| 3022 | - | if R.data.floor then |
| 3022 | + | |
| 3023 | - | clearRectangle(R) |
| 3023 | + | |
| 3024 | - | cleared = true |
| 3024 | + | |
| 3025 | T:go("D1 L1C1 U1C1") -- build left towpath, facing towpath, above water level
| |
| 3026 | - | else -- from top to bottom |
| 3026 | + | |
| 3027 | - | if R.data.ceiling then |
| 3027 | + | |
| 3028 | - | clearRectangle(R) |
| 3028 | + | |
| 3029 | - | cleared = true |
| 3029 | + | |
| 3030 | utils.goBack(1) | |
| 3031 | T:go("L1F1")
| |
| 3032 | T:placeWater("down")
| |
| 3033 | - | if R.height == 1 and not cleared then -- only 1 layer, perimeter only eg R.height = 7 |
| 3033 | + | |
| 3034 | return {}
| |
| 3035 | - | elseif R.height == 2 and not cleared then -- only 2 layers, perimeter only |
| 3035 | + | |
| 3036 | - | if R.direction == "up" then -- from bottom to top |
| 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 | - | elseif R.height >= 3 then -- 3 or more levels, floor/ceiling already assessed eg R.height = 7 |
| 3042 | + | |
| 3043 | --R.height = current level | |
| 3044 | ||
| 3045 | - | height = height + utils.move(R, 1) -- move up/down 1 block for first layer eg height: 1 + 1 = 2 |
| 3045 | + | |
| 3046 | - | -- height h + 3 R.height loop |
| 3046 | + | |
| 3047 | - | -- 2 5 5 end |
| 3047 | + | |
| 3048 | - | -- 2 5 7 + |
| 3048 | + | |
| 3049 | - | -- 5 8 7 end |
| 3049 | + | |
| 3050 | - | repeat |
| 3050 | + | |
| 3051 | - | clearPerimeter(R) -- runs at least once, removes 3 layers: 1,2,3 |
| 3051 | + | |
| 3052 | - | local move = 3 |
| 3052 | + | |
| 3053 | - | --if height + 3 < R.height then -- range with min 3(0), 4(1), 5(2), 6(3), 7(4), 8(5), 9(6) etc |
| 3053 | + | |
| 3054 | - | --height = height + utils.move(R, move) -- move up/down 3 blocks eg height 5, 8, 11, 14 |
| 3054 | + | |
| 3055 | - | --else |
| 3055 | + | |
| 3056 | - | --move = R.height - height - 1 |
| 3056 | + | |
| 3057 | - | --height = height + utils.move(R, move) -- move up/down 1-2 blocks eg height = 2 + 3 = 5 |
| 3057 | + | |
| 3058 | end | |
| 3059 | end | |
| 3060 | - | if height + 3 >= R.height then -- range with min 3(0), 4(1), 5(2), 6(3), 7(4), 8(5), 9(6) etc |
| 3060 | + | |
| 3061 | - | move = R.height - height |
| 3061 | + | |
| 3062 | end | |
| 3063 | - | height = height + utils.move(R, move) -- move up/down 1-2 blocks eg height = 2 + 3 = 5 |
| 3063 | + | |
| 3064 | - | until height > R.height - 3 -- min 3 levels eg height = 2, R.height - 3 --> 7 - 3 = 4, 4 - 3 = 1 |
| 3064 | + | |
| 3065 | return diary | |
| 3066 | - | R.down = false |
| 3066 | + | |
| 3067 | - | if height == R.height then -- already on top/bottom layer eg height = 5, R.height = 5 |
| 3067 | + | |
| 3068 | - | if R.direction == "up" then -- reverse digging direction. Up = move to top and dig down |
| 3068 | + | |
| 3069 | - | R.down = true |
| 3069 | + | |
| 3070 | - | else -- reverse digging direction. Up = move to floor and dig up |
| 3070 | + | |
| 3071 | - | R.up = true |
| 3071 | + | |
| 3072 | return item | |
| 3073 | - | clearPerimeter(R) |
| 3073 | + | |
| 3074 | ||
| 3075 | - | if R.direction == "up" then -- reverse digging direction. Up = move to top and dig down |
| 3075 | + | |
| 3076 | - | R.down = true |
| 3076 | + | |
| 3077 | - | else -- reverse digging direction. Up = move to floor and dig up |
| 3077 | + | |
| 3078 | - | R.up = true |
| 3078 | + | |
| 3079 | for l = 1, levelsPerCol do -- add 32 empty strings | |
| 3080 | table.insert(lines, "") | |
| 3081 | - | clearPerimeter(R) |
| 3081 | + | |
| 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 | - | R.up = false |
| 3085 | + | |
| 3086 | - | R.down = false |
| 3086 | + | |
| 3087 | - | if R.direction == "up" then |
| 3087 | + | |
| 3088 | - | if R.data.ceiling then -- from bottom to top |
| 3088 | + | |
| 3089 | - | clearRectangle(R) |
| 3089 | + | |
| 3090 | lev = "-0"..math.abs(level).." " -- "-09 " to "-01 " | |
| 3091 | - | elseif R.direction == "down" then |
| 3091 | + | |
| 3092 | - | if R.data.floor then -- from top to bottom |
| 3092 | + | |
| 3093 | - | clearRectangle(R) |
| 3093 | + | |
| 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 | - | T:place("minecraft:torch", "down", false) ---(self, blockType, damageNo, direction, leaveExisting, signText)
|
| 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 | - | utils.waitForInput() |
| 3654 | + | |
| 3655 | end | |
| 3656 | end | |
| 3657 | ||
| 3658 | function lib.stackBuckets() | |
| 3659 | local data = {}
| |
| 3660 | local bucketSlot = 0 | |
| 3661 | local emptySlots = 0 | |
| 3662 | - | utils.waitForInput() |
| 3662 | + | |
| 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 | - | utils.waitForInput() |
| 3731 | + | |
| 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 | - | utils.waitForInput() |
| 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 | - | --[[ direction = R.direction "up" or "down" ]] |
| 3888 | + | |
| 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 | - | if R.direction == "up" then |
| 3902 | + | |
| 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 | - | T:place("slab", "down", false)
|
| 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 | - | T:place("slab", "down", false)
|
| 4215 | + | |
| 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 | - | T:place("slab", "down", true)
|
| 4228 | + | |
| 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 | - | --T:place(blockType, direction, leaveExisting, signText) |
| 4307 | + | |
| 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 | - | T:place("soul", "down", false) -- place soulsand down
|
| 4316 | + | |
| 4317 | - | T:place("soul", "forward", false) -- place soulsand forward
|
| 4317 | + | |
| 4318 | waterPresent = true | |
| 4319 | - | T:place("soul", "down", false) -- place soulsand down
|
| 4319 | + | |
| 4320 | - | T:place("soul", "forward", false) -- place soulsand forward
|
| 4320 | + | |
| 4321 | T:place(useBlock, -1, direction, false) -- leaveExisting = false | |
| 4322 | if y < R.length then | |
| 4323 | T:go("F1", false, 0, false)
| |
| 4324 | - | T:place("gate", "forward", false) -- place fence gate
|
| 4324 | + | |
| 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:place("gate", "forward", false) -- place fence gate
|
| 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 | - | T:go("L1C1B1")
|
| 4471 | + | |
| 4472 | - | T:place("sign", "forward")
|
| 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 | - | if T:getBlockType("forward"):find("sign") ~= nil then
|
| 4485 | + | |
| 4486 | - | T:up(1) |
| 4486 | + | |
| 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 | - | T:place("stone", "up")
|
| 4512 | + | |
| 4513 | end | |
| 4514 | ||
| 4515 | function lib.initialise(R) | |
| 4516 | if R.subChoice == 1 or R.subChoice == 4 then | |
| 4517 | - | function lib.fillBuckets(withSort) |
| 4517 | + | |
| 4518 | - | local emptyBuckets = T:getItemCount("minecraft:bucket")
|
| 4518 | + | |
| 4519 | T:go(oTurn.."1F1D1"..R.side.."2") -- move right/left forward, down onto ice canal top, face canal wall | |
| 4520 | - | if T:getWater("down") then
|
| 4520 | + | |
| 4521 | - | sleep(0.5) |
| 4521 | + | |
| 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 | - | return T:getItemCount("minecraft:water_bucket")
|
| 4525 | + | |
| 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 | - | T:place(dirt, "forward", false) -- placed at end of potential water source, next to ladder |
| 4601 | + | |
| 4602 | local numBlocks, errorMsg = 0, "" | |
| 4603 | - | T:place(dirt, "down", false) -- placed in ground, next to ladder |
| 4603 | + | |
| 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 | - | --lib.fillBuckets(R.height, true) -- fill as many buckets as required or until inventory full, sort inventory as well |
| 4614 | + | |
| 4615 | - | lib.fillBuckets(true) -- fill as many buckets as required or until inventory full, sort inventory as well |
| 4615 | + | |
| 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 | - | T:go("L1C1 R1C1 R1C1 L1", false, 0, true) -- prepare layer 1
|
| 4633 | + | |
| 4634 | -- go down to water/lava with alternaate solid/open layers | |
| 4635 | - | T:go("U1F1 R1F1 L1C1 R1C1 R1C1 L1", false, 0, true) -- prepare layer 2
|
| 4635 | + | |
| 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("soul_sand", "down", false)
|
| 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 | - | T:place("stone", "forward", false)
|
| 4772 | + | |
| 4773 | end | |
| 4774 | ||
| 4775 | - | T:place("stone", "forward", false)
|
| 4775 | + | |
| 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 | - | T:place("minecraft:torch", "down")
|
| 4801 | + | |
| 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 | - | T:place("minecraft:ladder", "down")
|
| 4901 | + | |
| 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 | - | T:place("minecraft:obsidian", "down")
|
| 4909 | + | |
| 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 | - | T:place("fence", "down", false)
|
| 5010 | + | |
| 5011 | end | |
| 5012 | - | T:place(preferredBlock, "down", false) |
| 5012 | + | |
| 5013 | found, position = lib.isSpawner() -- true/false, top/bottom/nil | |
| 5014 | - | T:place(preferredBlock, "down", false) |
| 5014 | + | |
| 5015 | T:go("R2F"..moves + 2 .."R2")
| |
| 5016 | - | T:place(preferredBlock, "down", false) |
| 5016 | + | |
| 5017 | end | |
| 5018 | end | |
| 5019 | end | |
| 5020 | - | T:place(preferredBlock, "down", false) |
| 5020 | + | |
| 5021 | return found, position | |
| 5022 | - | T:place(preferredBlock, "down", false) |
| 5022 | + | |
| 5023 | ||
| 5024 | ||
| 5025 | if not continue then -- new mob cube either dungeon or blaze | |
| 5026 | - | T:place("sign", "forward", false, message)
|
| 5026 | + | |
| 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 | - | T:place(preferredBlock, "down", false) |
| 5083 | + | |
| 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 | - | if not T:place("fence", "down", false) then-- first side
|
| 5107 | + | |
| 5108 | - | T:place(preferredBlock, "down", false) |
| 5108 | + | |
| 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 | - | T:place("minecraft:soul_sand", "down", false) -- over block 1 of water source
|
| 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 | - | T:place("door", "forward", false)
|
| 5156 | + | |
| 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:place(preferredBlock, "down", false) |
| 5163 | + | |
| 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:place("door", "forward", false)
|
| 5170 | + | |
| 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 | - | T:place("fence", "down", false) -- fence centre of bottom side layer 22
|
| 5208 | + | |
| 5209 | end | |
| 5210 | ||
| 5211 | - | T:place("ladder", "forward", false)
|
| 5211 | + | |
| 5212 | --[[Part 2 / 3 Mob Spawner Farm turtle on floor, pointing towards water source wall, single hole]] | |
| 5213 | - | T:place("ladder", "forward", false)
|
| 5213 | + | |
| 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 | - | T:place("minecraft:soul_sand", "down", false)
|
| 5222 | + | |
| 5223 | T:turnLeft(2) -- turn round | |
| 5224 | while turtle.forward() do | |
| 5225 | width = width + 1 | |
| 5226 | end -- go forward 7 | |
| 5227 | - | T:place("ladder", "down", false)
|
| 5227 | + | |
| 5228 | T:placeWater("down") -- place water
| |
| 5229 | - | T:place("sign", "forward", false, "UP\n^\n|\n|")
|
| 5229 | + | |
| 5230 | T:go("L2F".. math.floor(width / 2) .."L1") -- turn round, go forward 3 (centre of wall), turn left
| |
| 5231 | end | |
| 5232 | - | T:place("sign", "forward", false, "UP\n^\n|\n|")
|
| 5232 | + | |
| 5233 | function lib.digFloor() | |
| 5234 | T:go("x2F1 x2") -- first block, move forward
| |
| 5235 | - | T:place("sign", "forward", false, "UP\n^\n|\n|")
|
| 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:place("sign", "forward", false, "UP\n^\n|\n|")
|
| 5240 | + | |
| 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:place("fence", "up", false)
|
| 5272 | + | |
| 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 | - | local function createFarmNetworkStorage(R, withStorage, removeLegacy) |
| 5304 | + | if not T:place("minecraft:soul_sand", -1, "down", false) then
|
| 5305 | - | removeLegacy = removeLegacy or false |
| 5305 | + | |
| 5306 | - | -- new or converted farm will have: |
| 5306 | + | |
| 5307 | - | -- 2 modems, 1 barrel per plot |
| 5307 | + | |
| 5308 | - | -- primary plot and storage needs 1 modem, 1 barrel, 8 chests |
| 5308 | + | |
| 5309 | blockType = T:getBlockType("forward")
| |
| 5310 | local turns = 0 | |
| 5311 | - | function lib.createBasement(R, up, down, width, length) |
| 5311 | + | |
| 5312 | - | -- start facing lower left |
| 5312 | + | |
| 5313 | - | R.up = up |
| 5313 | + | |
| 5314 | - | R.down = down |
| 5314 | + | |
| 5315 | - | R.width = width |
| 5315 | + | |
| 5316 | - | R.length = length |
| 5316 | + | |
| 5317 | - | clearRectangle(R) -- dig 10 x 10 x 2 area, return to starting position |
| 5317 | + | |
| 5318 | - | -- add network cable, modems and chests |
| 5318 | + | |
| 5319 | return {""}
| |
| 5320 | end | |
| 5321 | - | function lib.placeNetwork(count, pattern) |
| 5321 | + | |
| 5322 | function lib.createWaterSource(oTurn) | |
| 5323 | - | T:place("computercraft:cable", "up", true)
|
| 5323 | + | |
| 5324 | - | if i < count then |
| 5324 | + | |
| 5325 | - | T:go(pattern) |
| 5325 | + | |
| 5326 | T:go("C2 L1C1 R2C1 L1")
| |
| 5327 | if i < 3 then | |
| 5328 | T:go("F1x0")
| |
| 5329 | end | |
| 5330 | - | -- called when starting at lower left side of plot, facing crops |
| 5330 | + | |
| 5331 | - | if removeLegacy then |
| 5331 | + | |
| 5332 | T:placeWater("forward")
| |
| 5333 | - | while turtle.suckDown() do end |
| 5333 | + | |
| 5334 | - | --T:dig("down", false) -- do not bypass chests
|
| 5334 | + | |
| 5335 | - | turtle.digDown() |
| 5335 | + | |
| 5336 | - | T:place("dirt", "down")
|
| 5336 | + | |
| 5337 | - | T:go("R2F1")
|
| 5337 | + | |
| 5338 | - | while turtle.suck() do end |
| 5338 | + | |
| 5339 | - | T:go("F1L1 F1U1 R2") -- remove barrel/wall or double chest. face tree
|
| 5339 | + | |
| 5340 | - | T:place("stone", "down")
|
| 5340 | + | |
| 5341 | sleep(0.1) | |
| 5342 | - | T:place("modem", "down")
|
| 5342 | + | |
| 5343 | - | -- could be tree/sapling in front |
| 5343 | + | |
| 5344 | ||
| 5345 | - | if T:getBlockType("down") == "minecraft:dirt" then
|
| 5345 | + | |
| 5346 | - | T:place("barrel", "down")
|
| 5346 | + | |
| 5347 | - | T:go("U1x0")
|
| 5347 | + | |
| 5348 | - | T:place("dirt", "up")
|
| 5348 | + | |
| 5349 | - | T:go("B1U2")
|
| 5349 | + | |
| 5350 | - | if T:getBlockType("forward"):find("log") ~= nil then
|
| 5350 | + | T:place("chest", 0, "down")
|
| 5351 | - | T:place("sapling", "forward")
|
| 5351 | + | |
| 5352 | T:dig("down")
| |
| 5353 | - | T:go("D3F1 R1F1")
|
| 5353 | + | T:place("chest", 0, "down")
|
| 5354 | T:go(turn.."1") | |
| 5355 | - | T:place("barrel", "down")
|
| 5355 | + | |
| 5356 | T:go("D1x1")
| |
| 5357 | T:place("hopper", 0, "forward")
| |
| 5358 | - | while turtle.suckDown() do end |
| 5358 | + | |
| 5359 | - | T:place("modem", "down")
|
| 5359 | + | |
| 5360 | - | network.attachModem() |
| 5360 | + | |
| 5361 | - | T:go("F1x2 R2C2 F1L1 F1D1")
|
| 5361 | + | |
| 5362 | function lib.up() | |
| 5363 | - | T:go("L1D3") -- move below crop field, face N
|
| 5363 | + | |
| 5364 | - | lib.createBasement(R, true, true, 10, 10) -- ends facing N below water source |
| 5364 | + | |
| 5365 | - | T:go("U1 F9R1 F1R2 C1R2 F8R1 F1R2 C1R2 F8R1 F1R2 C1R2 F8") -- facing W below water source
|
| 5365 | + | |
| 5366 | - | T:go("F1 R2C1 R1 F1L1 x0x2") -- move to corner, face along front edge
|
| 5366 | + | |
| 5367 | - | for c = 1, 4 do |
| 5367 | + | |
| 5368 | - | if c == 1 then |
| 5368 | + | |
| 5369 | - | lib.placeNetwork(12, "F1x0x2") |
| 5369 | + | |
| 5370 | end | |
| 5371 | - | lib.placeNetwork(11, "F1x0x2") |
| 5371 | + | |
| 5372 | function lib.createChamber() | |
| 5373 | - | if c < 4 then |
| 5373 | + | |
| 5374 | - | T:go("L1F1 x0x2 L1C1R1")
|
| 5374 | + | |
| 5375 | D.length = 7 | |
| 5376 | D.height = 4 | |
| 5377 | - | -- now in bottom left facing S |
| 5377 | + | |
| 5378 | - | T:go("L2F1R1") -- under modem/netwok cable facing in
|
| 5378 | + | |
| 5379 | - | for i = 1, 3 do |
| 5379 | + | |
| 5380 | - | T:go("L1C1 R1C1 R1C1 L1D1")
|
| 5380 | + | |
| 5381 | - | T:place("computercraft:cable", "up", true)
|
| 5381 | + | |
| 5382 | ||
| 5383 | - | T:go("C1L1 C1L1 C1L1 C1L1 D1L1")-- ready for clearing rectangle up/down
|
| 5383 | + | |
| 5384 | - | T:place("computercraft:cable", "up", true)
|
| 5384 | + | |
| 5385 | ||
| 5386 | - | T:place("computercraft:cable", "up", true)
|
| 5386 | + | |
| 5387 | - | lib.createBasement(R, true, true, 11, 11) |
| 5387 | + | |
| 5388 | T:go("F1C0C2 R1C1 R1C1 R1C1 R1C1")
| |
| 5389 | - | lib.placeNetwork(11, "F1") |
| 5389 | + | |
| 5390 | - | T:go("R2F4 R1")
|
| 5390 | + | |
| 5391 | - | lib.placeNetwork(11, "F1") |
| 5391 | + | |
| 5392 | - | T:go("L1F5 L1F9 R1D1 C1") -- ready to make ladder column
|
| 5392 | + | |
| 5393 | end | |
| 5394 | - | if i < 5 then |
| 5394 | + | |
| 5395 | - | T:go("U1C1")
|
| 5395 | + | |
| 5396 | local turn = "R" | |
| 5397 | local oTurn = "L" | |
| 5398 | if R.subChoice == 1 then | |
| 5399 | - | T:place("ladder", "down")
|
| 5399 | + | |
| 5400 | oTurn = "R" | |
| 5401 | - | if withStorage then |
| 5401 | + | |
| 5402 | - | T:go("R1F4 R1F3 D1x2")
|
| 5402 | + | |
| 5403 | - | T:place("computercraft:cable", "down", true) --ready to build chest storage area
|
| 5403 | + | |
| 5404 | if data[1] ~= "" then | |
| 5405 | - | utils.createStorage() |
| 5405 | + | |
| 5406 | - | T:go("U1R1 F5R1 F5U1 C2U1 R2") -- end on plot starting position, facing crops
|
| 5406 | + | |
| 5407 | lib.createWaterSource(oTurn) -- everything in place, build a water source, facing spawner | |
| 5408 | - | T:go("U1F2 L1F1 U1C2 U1L1") -- end on plot starting position, facing crops
|
| 5408 | + | |
| 5409 | T:go(turn.."1C1"..turn.."1C1"..turn.."1x1"..turn.."1U1", false, 0, true) | |
| 5410 | end | |
| 5411 | - | return "Farm converted to network storage" |
| 5411 | + | |
| 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 | - | -- extend "right" or "forward". only adds a single new farm. |
| 5416 | + | |
| 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 | - | T:place("dirt", "forward", false)
|
| 5431 | + | |
| 5432 | T:go("C1")
| |
| 5433 | - | --if not T:place("minecraft:crafting_table", "forward", false) then
|
| 5433 | + | |
| 5434 | - | if T:place(storage, "forward", false) then |
| 5434 | + | |
| 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:place("dirt", "forward", false) -- dirt if no storage available
|
| 5439 | + | |
| 5440 | utils.goBack(7) -- over down shaft | |
| 5441 | T:down(1) -- start shaft, facing bubble column | |
| 5442 | - | T:place(R.useBlockType, "forward", false) |
| 5442 | + | |
| 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:placeWater("down") -- ends facing same direction as started, over water source
|
| 5447 | + | |
| 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 | - | T:place("dirt", "down", false)
|
| 5454 | + | |
| 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:place("dirt", "down", false)
|
| 5462 | + | |
| 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 | - | if not T:place(storage, "down", false) then-- place barrel/chest below |
| 5469 | + | |
| 5470 | - | T:place(storageBackup, "down", false) -- place chest below |
| 5470 | + | |
| 5471 | end | |
| 5472 | T:go("U3R2")
| |
| 5473 | for i = 1, 7 do | |
| 5474 | T:go("F1x2")
| |
| 5475 | - | -- current position if extend == nil is on ground/farm level facing N |
| 5475 | + | |
| 5476 | - | -- if extend = "right", "front" above water source facing crops |
| 5476 | + | |
| 5477 | - | local numPlots = 0 |
| 5477 | + | |
| 5478 | lib.placeCollector(turn, oTurn) -- if hopper / chests present | |
| 5479 | ||
| 5480 | return {}
| |
| 5481 | end | |
| 5482 | ||
| 5483 | - | T:forward(11) |
| 5483 | + | |
| 5484 | - | numPlots = numPlots + 1 |
| 5484 | + | |
| 5485 | - | until not utils.isStorage("down") -- on top of chest, barrel or modem
|
| 5485 | + | |
| 5486 | - | T:go("R1F1R2") -- move to front right corner of last plot on right side
|
| 5486 | + | |
| 5487 | - | --T:go("R1U1 F1L1 F10L1") -- move to front right corner
|
| 5487 | + | |
| 5488 | T:go("x2C2", false, 0, false, R.useBlockType)
| |
| 5489 | if R.up then | |
| 5490 | T:dig("up")
| |
| 5491 | end | |
| 5492 | - | T:forward(11) |
| 5492 | + | |
| 5493 | - | numPlots = numPlots + 1 |
| 5493 | + | |
| 5494 | - | until not utils.isStorage("down") -- on top of chest, barrel or modem
|
| 5494 | + | |
| 5495 | - | T:go("L1F1 R1x2") -- could dig tree or sapling + block below
|
| 5495 | + | |
| 5496 | - | --T:go("L2U1 F1R1 F10")
|
| 5496 | + | |
| 5497 | - | elseif extend == "convertWithStorage" then |
| 5497 | + | |
| 5498 | - | -- convert normal (storage) primary plot farm to networked storage |
| 5498 | + | |
| 5499 | - | --T:turnLeft(1) -- over water source, facing N |
| 5499 | + | |
| 5500 | - | local response = createFarmNetworkStorage(R, true, true) |
| 5500 | + | |
| 5501 | - | return {response}
|
| 5501 | + | |
| 5502 | - | elseif extend == "convert" or extend == "convertWithStorage" then |
| 5502 | + | |
| 5503 | - | -- convert normal (storage) extended farm to networked storage |
| 5503 | + | |
| 5504 | - | --T:turnLeft(1) -- over water source, facing N |
| 5504 | + | |
| 5505 | - | createFarmNetworkStorage(R, false, true) |
| 5505 | + | |
| 5506 | - | return {"Farm converted to network storage"}
|
| 5506 | + | |
| 5507 | - | else -- new farm. |
| 5507 | + | |
| 5508 | - | T:up(1) -- assume on the ground, go up 1 |
| 5508 | + | |
| 5509 | end | |
| 5510 | end | |
| 5511 | - | -- design change: sapling placed 2 blocks above corner for ease of walking round |
| 5511 | + | |
| 5512 | - | if R.networkFarm then -- barrel on corner of plot, modems on each side N/E |
| 5512 | + | |
| 5513 | - | T:place("barrel", "down", false)
|
| 5513 | + | |
| 5514 | end | |
| 5515 | - | T:place(R.useBlockType, "down", false) |
| 5515 | + | |
| 5516 | local function createPortal(R) -- 42 | |
| 5517 | - | -- stage 2 place sapling |
| 5517 | + | |
| 5518 | R.length = length of portal NOT width default 4 | |
| 5519 | - | T:place("dirt", "down")
|
| 5519 | + | |
| 5520 | - | T:up(1) |
| 5520 | + | |
| 5521 | - | T:place("sapling", "down") -- plant sapling
|
| 5521 | + | |
| 5522 | - | T:go("F1D4")
|
| 5522 | + | |
| 5523 | - | if R.networkFarm then |
| 5523 | + | |
| 5524 | - | T:place("modem", "down", false)
|
| 5524 | + | |
| 5525 | - | network.attachModem() |
| 5525 | + | |
| 5526 | function lib.buildBase() | |
| 5527 | - | T:place(R.useBlockType, "down", false) |
| 5527 | + | |
| 5528 | T:go("C2", false, 0, false, R.useBlockType)
| |
| 5529 | - | -- stage 2 place double barrel/chest |
| 5529 | + | |
| 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:go("R1F1L1")
|
| 5532 | + | |
| 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:go("F1 x0x2C 2", false, 0, false, R.useBlockType)
|
| 5540 | + | |
| 5541 | end | |
| 5542 | T:place("minecraft:obsidian", 0, "down", false)
| |
| 5543 | end | |
| 5544 | ||
| 5545 | - | lib.placeDirt(9, false) -- place dirt back to start |
| 5545 | + | |
| 5546 | - | if R.networkFarm then -- water source next to modem |
| 5546 | + | |
| 5547 | - | lib.addWaterSource(R, {"c","c","d","d"}, storage)
|
| 5547 | + | |
| 5548 | - | -- T:go(path, useTorch, torchInterval, leaveExisting, preferredBlock |
| 5548 | + | |
| 5549 | - | T:go("U1F1L1")
|
| 5549 | + | |
| 5550 | - | T:place("modem", "down", false)
|
| 5550 | + | |
| 5551 | - | T:go("F1C2 L1F1 D1", false, 0, false, R.useBlockType)
|
| 5551 | + | |
| 5552 | for width = 1, R.width do | |
| 5553 | - | lib.addWaterSource(R, {"c","c","t","d"}, storage) -- put barrel / chest in floor
|
| 5553 | + | |
| 5554 | - | T:go("U1F1R2")
|
| 5554 | + | |
| 5555 | - | if T:getBlockType("down"):find(storage) == nil and T:getBlockType("down"):find(storageBackup) == nil then
|
| 5555 | + | |
| 5556 | - | lib.placeStorage(storage, storageBackup) |
| 5556 | + | |
| 5557 | lib.buildLayer() | |
| 5558 | - | T:go("R1F1L1")
|
| 5558 | + | |
| 5559 | - | if T:getBlockType("down"):find(storage) == nil and T:getBlockType("down"):find(storageBackup) == nil then
|
| 5559 | + | |
| 5560 | - | lib.placeStorage(storage, storageBackup) |
| 5560 | + | |
| 5561 | lib.buildBase() | |
| 5562 | - | T:go("F1D1")
|
| 5562 | + | |
| 5563 | T:go("R2F"..R.length - 1)
| |
| 5564 | end | |
| 5565 | if width < R.width then | |
| 5566 | T:go("R1F1D"..R.height.."R1")
| |
| 5567 | - | T:go("F1U1x0C2"..turn.."1F1"..turn.."1x0 x2C2 F1D1", false, 0, false, R.useBlockType)
|
| 5567 | + | |
| 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 | - | lib.addWaterSource(R, {"d","c","c","d"}, storage) -- bottom right
|
| 5576 | + | |
| 5577 | end | |
| 5578 | - | lib.addWaterSource(R, {"c","c","d","d"}, storage) -- top right, facing away from plot
|
| 5578 | + | |
| 5579 | - | T:go("F1U1 R1C2 x0F1 x0x2 C2R1", false, 0, false, R.useBlockType)
|
| 5579 | + | |
| 5580 | - | for i = 1, 11 do -- build right wall from top of plot to bottom |
| 5580 | + | |
| 5581 | local lib ={}
| |
| 5582 | ||
| 5583 | - | T:go("R1F10") -- ends on top of front storage/ modem facing tree
|
| 5583 | + | |
| 5584 | - | if R.networkFarm then -- network storage |
| 5584 | + | |
| 5585 | - | network.attachModem() |
| 5585 | + | |
| 5586 | - | T:go("R1F1D1R1") -- over water source, facing E (crops)
|
| 5586 | + | |
| 5587 | - | if extend == "" then -- primary plot |
| 5587 | + | |
| 5588 | - | createFarmNetworkStorage(R, true) |
| 5588 | + | |
| 5589 | break | |
| 5590 | - | createFarmNetworkStorage(R, false) |
| 5590 | + | |
| 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 | - | utils.goBack(numPlots * 11) |
| 5595 | + | |
| 5596 | else -- nothing in front, probably under centre, or facing wrong direction so check | |
| 5597 | for i = 1, 4 do | |
| 5598 | - | T:go("R1U1F".. numPlots * 11 .."D1L1")
|
| 5598 | + | |
| 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 | - | --T:setUseLog(true, "farmCreateLog.txt", true) |
| 5607 | + | |
| 5608 | - | --dbug = true -- set dbug flag |
| 5608 | + | |
| 5609 | - | --utils.waitForInput("Logging and debugging enabled") --utils.waitForInput(message)
|
| 5609 | + | |
| 5610 | while turtle.down() do | |
| 5611 | height = height + 1 | |
| 5612 | end | |
| 5613 | return found, height | |
| 5614 | end | |
| 5615 | ||
| 5616 | - | R = utils.checkFarmPosition(R) |
| 5616 | + | |
| 5617 | for i = 1, length do | |
| 5618 | - | if not R.ready then |
| 5618 | + | |
| 5619 | - | return {"Unable to determine starting position"}
|
| 5619 | + | |
| 5620 | else | |
| 5621 | T:go("C2", false, 0, true)
| |
| 5622 | - | createFarm(R, extend) |
| 5622 | + | |
| 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 | - | R.data == "random" for random floor placement |
| 5632 | + | |
| 5633 | end | |
| 5634 | T:place("minecraft:ladder", 0, "forward", true)
| |
| 5635 | T:up(1) | |
| 5636 | end | |
| 5637 | - | function lib.goToRemote(R) |
| 5637 | + | |
| 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 | - | return "Measured depth/height of "..depth.." > setting: "..R.height |
| 5654 | + | |
| 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 | - | function lib.checkPosition(R) |
| 5660 | + | |
| 5661 | - | -- check if block above/below |
| 5661 | + | |
| 5662 | - | local blockBelow = turtle.detectDown() |
| 5662 | + | |
| 5663 | - | local blockAbove = turtle.detectUp() |
| 5663 | + | |
| 5664 | - | if R.subChoice == 2 then -- New floor over existing |
| 5664 | + | --[[Build steps up or down ready for railtrack]] |
| 5665 | - | -- if no block below, assume in correct position and continue |
| 5665 | + | |
| 5666 | - | -- else move up 1 and continue |
| 5666 | + | |
| 5667 | - | if blockBelow then T:up(1) end |
| 5667 | + | |
| 5668 | - | elseif R.subChoice == 4 then -- New ceiling under existing |
| 5668 | + | |
| 5669 | - | -- if no block above, assume in correct position and continue |
| 5669 | + | |
| 5670 | - | -- else move down 1 and continue |
| 5670 | + | |
| 5671 | - | if blockAbove then T:down(1) end |
| 5671 | + | |
| 5672 | T:go("C2", false, 0, true)
| |
| 5673 | end | |
| 5674 | end | |
| 5675 | - | function lib.placeRow(R, direction, waterPresent) |
| 5675 | + | |
| 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 | - | R = lib.getRandomBlock(R) -- changes block randomly ONLY if R.data == "random" |
| 5683 | + | |
| 5684 | - | R = lib.changeCheckered(R) -- changes to next block type ONLY if R.data == "checked" |
| 5684 | + | |
| 5685 | - | -- ONLY if R.data == "striped" has already been changed for whole row |
| 5685 | + | |
| 5686 | - | T:place(R.inventory.useBlock, direction, false) -- leaveExisting = false |
| 5686 | + | |
| 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 | - | return waterPresent, R |
| 5691 | + | |
| 5692 | local lib = {}
| |
| 5693 | ||
| 5694 | - | function lib.getRandomBlock(R) |
| 5694 | + | |
| 5695 | - | if R.data == "random" then |
| 5695 | + | |
| 5696 | - | local index = math.random(1, #R.inventory.names) -- random index between 1 and no of block types |
| 5696 | + | |
| 5697 | - | local success = false |
| 5697 | + | |
| 5698 | - | for i = index, R.inventory.blockTypeCount do -- iterate from index upwards |
| 5698 | + | |
| 5699 | - | if R.inventory.quantities[i] > 0 then -- at least 1 block left |
| 5699 | + | |
| 5700 | - | R.inventory.useBlock = R.inventory.names[i] |
| 5700 | + | |
| 5701 | - | R.inventory.quantities[i] = R.inventory.quantities[i] - 1 |
| 5701 | + | |
| 5702 | - | R.inventory.blockCount = R.inventory.blockCount - 1 |
| 5702 | + | |
| 5703 | - | success = true |
| 5703 | + | |
| 5704 | end | |
| 5705 | ||
| 5706 | function lib.back(R) | |
| 5707 | for i = 1, R.length do | |
| 5708 | - | if not success then -- no blocks left in the range of index -> no of block types |
| 5708 | + | |
| 5709 | - | for i = index, 1, -1 do -- go backwards from index to 1 |
| 5709 | + | |
| 5710 | - | if R.inventory.quantities[i] > 0 then -- at least 1 block left |
| 5710 | + | |
| 5711 | - | R.inventory.useBlock = R.inventory.names[i] |
| 5711 | + | |
| 5712 | - | R.inventory.quantities[i] = R.inventory.quantities[i] - 1 |
| 5712 | + | |
| 5713 | - | R.inventory.blockCount = R.inventory.blockCount - 1 |
| 5713 | + | |
| 5714 | - | success = true |
| 5714 | + | |
| 5715 | ||
| 5716 | function lib.right(R) | |
| 5717 | T:turnRight(R.length) | |
| 5718 | end | |
| 5719 | - | end |
| 5719 | + | |
| 5720 | function lib.up(R) | |
| 5721 | - | return R |
| 5721 | + | |
| 5722 | T:go("U2R2 x1R2 D1C2", false, 0, true)
| |
| 5723 | else | |
| 5724 | - | function lib.changeStripe(R) |
| 5724 | + | |
| 5725 | - | if R.data == "striped" then |
| 5725 | + | |
| 5726 | - | R.size = R.size + 1 |
| 5726 | + | |
| 5727 | - | if R.size > R.inventory.blockTypeCount then |
| 5727 | + | |
| 5728 | - | R.size = 1 |
| 5728 | + | |
| 5729 | T:go("D1C2", false, 0, true)
| |
| 5730 | - | R.inventory.useBlock = R.inventory.names[R.size] |
| 5730 | + | |
| 5731 | ||
| 5732 | - | return R |
| 5732 | + | |
| 5733 | -- mimics direct commands using f.lua, r.lua etc with space between commands and number | |
| 5734 | local width = 0 | |
| 5735 | - | function lib.changeCheckered(R) |
| 5735 | + | |
| 5736 | - | --swap between 2 block types |
| 5736 | + | |
| 5737 | - | if R.data == "checked" then |
| 5737 | + | |
| 5738 | - | if R.inventory.useBlock == R.inventory.names[1] then |
| 5738 | + | |
| 5739 | - | R.inventory.useBlock = R.inventory.names[2] |
| 5739 | + | |
| 5740 | "Back 1 block", | |
| 5741 | - | R.inventory.useBlock = R.inventory.names[1] |
| 5741 | + | |
| 5742 | "Turn Right", | |
| 5743 | "Turn Left", | |
| 5744 | - | return R |
| 5744 | + | |
| 5745 | "Down 1 block", | |
| 5746 | "Quit" | |
| 5747 | } | |
| 5748 | local choice, modifier | |
| 5749 | - | if R.data == "random" then |
| 5749 | + | |
| 5750 | - | math.randomseed(R.inventory.blockCount) |
| 5750 | + | |
| 5751 | - | print("Using random blocks")
|
| 5751 | + | |
| 5752 | - | elseif R.data == "striped" then |
| 5752 | + | |
| 5753 | - | print("Using striped pattern")
|
| 5753 | + | |
| 5754 | - | elseif R.data == "checked" then |
| 5754 | + | |
| 5755 | - | print("Using checkered pattern")
|
| 5755 | + | |
| 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 | - | local message = lib.goToRemote(R) |
| 5763 | + | |
| 5764 | - | if message ~= "" then -- error encountered |
| 5764 | + | |
| 5765 | - | return {message}
|
| 5765 | + | |
| 5766 | R.length = 1 | |
| 5767 | lib.right(R) | |
| 5768 | elseif choice == 6 then | |
| 5769 | - | lib.checkPosition(R) |
| 5769 | + | |
| 5770 | - | -- based on clearRectangle code |
| 5770 | + | |
| 5771 | - | if R.width == 1 then -- single block ahead only |
| 5771 | + | |
| 5772 | - | waterPresent, R = lib.placeRow(R, direction, waterPresent) |
| 5772 | + | |
| 5773 | - | T:turnRight(2) -- turn at the top of the run |
| 5773 | + | |
| 5774 | - | T:forward(R.length - 1) -- return to start |
| 5774 | + | |
| 5775 | - | T:turnRight(2) -- turn round to original position |
| 5775 | + | |
| 5776 | end | |
| 5777 | - | local iterations = 0 -- R.width = 2, 4, 6, 8 etc |
| 5777 | + | |
| 5778 | - | if R.width % 2 == 1 then -- R.width = 3, 5, 7, 9 eg R.width 7 |
| 5778 | + | |
| 5779 | - | iterations = (R.width - 1) / 2 -- iterations 1, 2, 3, 4 for widths 3, 5, 7, 9 |
| 5779 | + | |
| 5780 | ||
| 5781 | direction + ~blue~number ~yellow~eg ~white~f2 ~yellow~= forward ~blue~2 | |
| 5782 | ~lightGray~direction without number = ~blue~1 | |
| 5783 | - | R = lib.changeStripe(R) |
| 5783 | + | |
| 5784 | - | R = lib.changeCheckered(R) |
| 5784 | + | |
| 5785 | - | for i = 1, iterations do -- eg 3 blocks wide, iterations = 1 |
| 5785 | + | |
| 5786 | - | waterPresent, R = lib.placeRow(R, direction, waterPresent) |
| 5786 | + | |
| 5787 | ||
| 5788 | - | R = lib.changeStripe(R) |
| 5788 | + | |
| 5789 | - | --R = lib.changeCheckered(R) |
| 5789 | + | |
| 5790 | - | waterPresent, R = lib.placeRow(R, direction, waterPresent) |
| 5790 | + | |
| 5791 | local cmd = "" | |
| 5792 | while cmd ~= "q" do | |
| 5793 | local line = menu.clear() | |
| 5794 | - | R = lib.changeStripe(R) |
| 5794 | + | |
| 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 | - | R = lib.changeStripe(R) |
| 5799 | + | |
| 5800 | - | waterPresent, R = lib.placeRow(R, direction, waterPresent) |
| 5800 | + | |
| 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 | - | T:place("torch", "forward") -- place torch, move forward
|
| 5843 | + | |
| 5844 | end | |
| 5845 | ||
| 5846 | function lib.patchMissingBlock() | |
| 5847 | if turtle.back() then | |
| 5848 | T:go("C1")
| |
| 5849 | else | |
| 5850 | - | if not T:place("slab", "down") then -- break if out of slabs
|
| 5850 | + | |
| 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 | - | -- T:place(blockType, direction, leaveExisting, signText) |
| 5886 | + | |
| 5887 | - | if not T:place("stone", "forward", false) then
|
| 5887 | + | |
| 5888 | local place = utils.clearVegetation("down")
| |
| 5889 | -- build back column | |
| 5890 | while place do -- loop will be entered at least once | |
| 5891 | - | if T:getItemSlot("minecraft:torch") > 0 then
|
| 5891 | + | |
| 5892 | - | T:place("torch", "forward", false)
|
| 5892 | + | |
| 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 | - | if not T:place("slab", "forward", false) then
|
| 5899 | + | |
| 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 not T:place("stone", "forward", false) then
|
| 5912 | + | |
| 5913 | T:go("C1")
| |
| 5914 | else | |
| 5915 | T:go("B1C1")
| |
| 5916 | - | if T:getItemSlot("minecraft:torch") > 0 then
|
| 5916 | + | |
| 5917 | - | T:place("torch", "forward", false)
|
| 5917 | + | |
| 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 | - | T:place("ice", "down", true)
|
| 5926 | + | |
| 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 | - | if not T:place("ice", "down", true) then -- out of ice
|
| 5941 | + | |
| 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 not T:place("ladder", "forward", false) then
|
| 6027 | + | |
| 6028 | drop = drop + 1 | |
| 6029 | else | |
| 6030 | isBedrock = true | |
| 6031 | break | |
| 6032 | - | T:place("common", direction, false) -- any common block
|
| 6032 | + | |
| 6033 | if T:isWaterOrLava("up") ~= "" then
| |
| 6034 | - | T:place("minecraft:torch", direction, false)
|
| 6034 | + | |
| 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 | - | T:place("ladder", "up")
|
| 6109 | + | |
| 6110 | if l < R.length then | |
| 6111 | T:forward(1) | |
| 6112 | end | |
| 6113 | end | |
| 6114 | - | T:place("ladder", "forward")
|
| 6114 | + | |
| 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 | - | T:place("minecraft:chest", "up", false)
|
| 6133 | + | |
| 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 | - | while T:getItemSlot("minecraft:torch") > 0 do
|
| 6148 | + | |
| 6149 | - | turtle.select(T:getItemSlot("minecraft:torch"))
|
| 6149 | + | |
| 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 | - | T:place("slab", "up", false)
|
| 6234 | + | |
| 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 | - | T:place("slab", "up", false)
|
| 6256 | + | |
| 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 | - | T:place("slab", "up", false)
|
| 6276 | + | |
| 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 | - | -- T:place(blockType, direction, leaveExisting, signText) |
| 6316 | + | |
| 6317 | blockType = T:isWaterOrLava("forward")
| |
| 6318 | if blockType:find("lava") ~= nil or blockType:find("water") ~= nil then
| |
| 6319 | - | T:place(blockType, "down", false) |
| 6319 | + | |
| 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 | - | T:place("chest", "forward", false)
|
| 6383 | + | |
| 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:place("slab", "down", true) -- place slab on top T:place(blockType, direction, leaveExisting)
|
| 6526 | + | |
| 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 | - | T:place(brick, "up") |
| 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 | - | T:place("lava", "down")
|
| 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 | - | T:place("sign", true, "")
|
| 6641 | + | lib.placeCorners(R.length - 2, 1, R.useBlockType) |
| 6642 | if outward then | |
| 6643 | - | T:place(brick, "up") |
| 6643 | + | T:go("R1F"..R.width - 9 .."R1")
|
| 6644 | else | |
| 6645 | T:go("L1F"..R.width - 9 .."L1")
| |
| 6646 | end | |
| 6647 | - | T:place(brick, "forward") |
| 6647 | + | |
| 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 | - | if not T:place("chest", "down") then
|
| 6653 | + | outward = lib.turn(outward) |
| 6654 | - | T:place("barrel", "down")
|
| 6654 | + | lib.placeCorners(R.length - 2, 4, R.useBlockType) -- should be back in starting corner facing front |
| 6655 | ||
| 6656 | T:go("U1R1")
| |
| 6657 | - | T:place("hopper", "down")
|
| 6657 | + | lib.placeWater(R.length - 3) -- place water down then move forward, turn right |
| 6658 | lib.placeWater(R.width - 3) | |
| 6659 | - | T:place("slab", "forward")
|
| 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("fence", "down", false)
|
| 6723 | + | T:place(R.useBlockType, 0, "forward") |
| 6724 | blocks = blocks + 1 -- facing start | |
| 6725 | - | T:place("fence", "down", false)
|
| 6725 | + | |
| 6726 | T:go("F1R2")
| |
| 6727 | T:place(R.useBlockType, 0, "forward") | |
| 6728 | - | T:place("sign", "down", false)
|
| 6728 | + | |
| 6729 | else -- cant go forward, go up instead | |
| 6730 | - | T:place("slab", "up", false)
|
| 6730 | + | |
| 6731 | while turtle.detectUp() do -- will only run if block above | |
| 6732 | - | T:place("sign", "forward", false)
|
| 6732 | + | |
| 6733 | blocks = blocks - 1 | |
| 6734 | - | if not T:place("minecraft:soul_sand", "down", false) then
|
| 6734 | + | |
| 6735 | - | T:place("minecraft:dirt", "down", false)
|
| 6735 | + | |
| 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 | - | if not T:place("minecraft:soul_sand", "down", false) then
|
| 6758 | + | |
| 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:place("chest", "down")
|
| 6804 | + | |
| 6805 | end | |
| 6806 | T:go(R.side.."1") -- *|V| | | to *|>| | | turn to face start | |
| 6807 | - | T:place("chest", "down")
|
| 6807 | + | |
| 6808 | end | |
| 6809 | T:go("C2", false, 0, false)
| |
| 6810 | end | |
| 6811 | - | T:place("hopper", "forward")
|
| 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 | - | T:place("slab", "down")
|
| 6904 | + | |
| 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 | - | T:place("minecraft:obsidian", "down", false)
|
| 6985 | + | |
| 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:place("minecraft:obsidian", "down", false)
|
| 6992 | + | |
| 6993 | end | |
| 6994 | else | |
| 6995 | T:forward(1) -- move forward to extend canal | |
| 6996 | - | T:place("minecraft:obsidian", "down", false)
|
| 6996 | + | |
| 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:place("minecraft:ladder", "forward", true)
|
| 7088 | + | |
| 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 | - | T:place("trapdoor", "up", false)
|
| 7109 | + | |
| 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 | - | Build steps up or down ready for railtrack |
| 7119 | + | |
| 7120 | - | R.depth = headroom, default 2 |
| 7120 | + | |
| 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 | - | --T:go("U1x0 D1x1 F1x0x1 D1x1 C2", false, 0, false)
|
| 7134 | + | |
| 7135 | - | T:go("U"..R.depth - 1 .."x0 D"..R.depth - 1 .."x1 F1x0x1 D1x1 C2", false, 0, false)
|
| 7135 | + | |
| 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 | - | --T:go("C1U2 x0D1F1", false, 0, false) --put stone in front, up 2 excavate 1, down 1, forward 1
|
| 7140 | + | |
| 7141 | - | T:go("C1U"..R.depth.." x0D"..R.depth.."F1", false, 0, false) --put stone in front, up 2 (or headroom) excavate 1, down 1, forward 1
|
| 7141 | + | |
| 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 | - | T:place("slab", "down", false)
|
| 7539 | + | |
| 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 | - | --T:place("stone", "forward", false) -- place does not allow for specific blocktype
|
| 7921 | + | |
| 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 | - | T:place("minecraft:torch", "down")
|
| 7962 | + | |
| 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 | - | function lib.buildWallSection(section, useBlockType) |
| 7994 | + | |
| 7995 | - | -- build a layer 1 block high below turtle |
| 7995 | + | |
| 7996 | - | for i = 1, #section do |
| 7996 | + | |
| 7997 | - | local block = section:sub(i, i) |
| 7997 | + | |
| 7998 | - | if block == "l" then |
| 7998 | + | |
| 7999 | - | T:place("log", "down")
|
| 7999 | + | |
| 8000 | - | elseif block == "m" then |
| 8000 | + | |
| 8001 | - | T:place("modem", "down")
|
| 8001 | + | |
| 8002 | - | elseif block == "b" then |
| 8002 | + | |
| 8003 | - | T:place("barrel", "down")
|
| 8003 | + | |
| 8004 | - | elseif block == "c" then |
| 8004 | + | |
| 8005 | - | T:place("cable", "down")
|
| 8005 | + | |
| 8006 | while not turtle.detectUp() do | |
| 8007 | - | T:place(useBlockType, "down") |
| 8007 | + | |
| 8008 | if success then | |
| 8009 | - | if i < #section then |
| 8009 | + | |
| 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 | - | while turtle.digUp() do end |
| 8017 | + | |
| 8018 | - | turtle.digDown() |
| 8018 | + | |
| 8019 | - | T:place(useBlockType, "down") |
| 8019 | + | |
| 8020 | - | --T:go("x0C2", false, 0, false, useBlockType)
|
| 8020 | + | |
| 8021 | turtle.forward() | |
| 8022 | - | while not turtle.forward() do |
| 8022 | + | |
| 8023 | - | turtle.dig() |
| 8023 | + | |
| 8024 | turtle.down() | |
| 8025 | - | --T:forward(1) |
| 8025 | + | |
| 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 | - | function lib.findLegacyStart() |
| 8058 | + | |
| 8059 | lib.walls() | |
| 8060 | - | local block = T:getBlockType("down")
|
| 8060 | + | |
| 8061 | - | if block:find("polished") ~= nil then
|
| 8061 | + | |
| 8062 | - | return "" -- in correct position, facing centre of front wall |
| 8062 | + | |
| 8063 | if doContinue then | |
| 8064 | - | -- assume on left corner |
| 8064 | + | |
| 8065 | - | T:forward (1) |
| 8065 | + | |
| 8066 | - | local couint = 0 |
| 8066 | + | |
| 8067 | - | while (T:getBlockType("down")):find("polished") == nil do
|
| 8067 | + | |
| 8068 | lib.home(direction, moves) | |
| 8069 | end | |
| 8070 | - | if count > 10 then |
| 8070 | + | |
| 8071 | - | return "Unable to locate polished block" |
| 8071 | + | |
| 8072 | end | |
| 8073 | ||
| 8074 | local function manageFarm(R) | |
| 8075 | local lib = {}
| |
| 8076 | ||
| 8077 | - | function lib.floodFarm(R) |
| 8077 | + | function lib.checkEquipment() |
| 8078 | --[[ Needs pickaxe and hoe equipped ]] | |
| 8079 | - | T:sortInventory(false) |
| 8079 | + | |
| 8080 | - | for i = 1, R.width - 2 do |
| 8080 | + | --T:checkInventoryForItem(items{}, quantities{}, required, message)
|
| 8081 | - | lib.placeFloor(R.length - 2, R.useBlockType) |
| 8081 | + | |
| 8082 | - | if i < R.width - 2 then |
| 8082 | + | local equippedRight, equippedLeft, inInventory = T:setEquipment() -- any tools equipped except diamond_pickaxe and crafting_table have been removed to inventory |
| 8083 | - | outward = lib.turn(outward) |
| 8083 | + | --[[if equippedRight ~= "minecraft:crafting_table" then |
| 8084 | T:checkInventoryForItem({"minecraft:crafting_table"}, {1})
| |
| 8085 | local equippedRight, equippedLeft = T:setEquipment() | |
| 8086 | - | T:go("U1R2") -- over 13 x 13 internal area opposite corner
|
| 8086 | + | |
| 8087 | - | -- now add corners |
| 8087 | + | T:suck("down") -- if hoe already in storage get it out
|
| 8088 | - | lib.placeCorners(R.length - 2, 4, R.useBlockType) |
| 8088 | + | if inInventory ~= "minecraft:diamond_hoe" then |
| 8089 | - | outward = lib.turn(outward) |
| 8089 | + | if T:getItemSlot("minecraft:diamond_hoe") > 0 then
|
| 8090 | - | lib.placeCorners(R.length - 2, 3, R.useBlockType) |
| 8090 | + | |
| 8091 | - | outward = lib.turn(outward) |
| 8091 | + | |
| 8092 | - | lib.placeCorners(R.length - 2, 2, R.useBlockType) |
| 8092 | + | T:checkInventoryForItem({"minecraft:diamond_hoe"}, {1}, true, "Diamond Hoe required for planting!")
|
| 8093 | - | outward = lib.turn(outward) |
| 8093 | + | |
| 8094 | - | lib.placeCorners(R.length - 2, 1, R.useBlockType) |
| 8094 | + | |
| 8095 | if T:getItemSlot("minecraft:diamond_hoe") > 0 then
| |
| 8096 | - | T:go("R1F"..R.width - 9 .."R1")
|
| 8096 | + | |
| 8097 | end | |
| 8098 | - | T:go("L1F"..R.width - 9 .."L1")
|
| 8098 | + | |
| 8099 | return false | |
| 8100 | end | |
| 8101 | - | lib.placeCorners(R.length - 2, 1, R.useBlockType) |
| 8101 | + | |
| 8102 | - | outward = lib.turn(outward) |
| 8102 | + | |
| 8103 | - | lib.placeCorners(R.length - 2, 2, R.useBlockType) |
| 8103 | + | --[[ first function called on start]] |
| 8104 | - | outward = lib.turn(outward) |
| 8104 | + | local atHome = false |
| 8105 | - | lib.placeCorners(R.length - 2, 3, R.useBlockType) |
| 8105 | + | |
| 8106 | - | outward = lib.turn(outward) |
| 8106 | + | print("Checking position "..blockType.. " below")
|
| 8107 | - | lib.placeCorners(R.length - 2, 4, R.useBlockType) -- should be back in starting corner facing front |
| 8107 | + | if blockType:find("water") ~= nil then -- over water
|
| 8108 | if lib.isStorage("forward") then
| |
| 8109 | - | T:go("U1R1")
|
| 8109 | + | atHome = true |
| 8110 | - | lib.placeWater(R.length - 3) -- place water down then move forward, turn right |
| 8110 | + | |
| 8111 | - | lib.placeWater(R.width - 3) |
| 8111 | + | if lib.isStorage("forward") then-- confirms in correct position, back to crops
|
| 8112 | - | lib.placeWater(R.length - 3) |
| 8112 | + | |
| 8113 | - | lib.placeWater(R.width - 3) |
| 8113 | + | else -- facing crafting table |
| 8114 | - | T:go("F".. math.floor((R.length - 2) / 2).."R1F".. math.floor((R.width - 2) / 2)) -- should be in centre
|
| 8114 | + | |
| 8115 | end | |
| 8116 | - | --T:go("D6x2 F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 R1F7 R1U1")
|
| 8116 | + | else -- not a chest: facing crops or crafting table |
| 8117 | - | T:go("D6F7 R1F7 R1U1") -- end facing back at left corner, 1 block above floor/1 below ceiling
|
| 8117 | + | |
| 8118 | if lib.isStorage("forward") then -- confirms was facing crops
| |
| 8119 | atHome = true | |
| 8120 | - | function lib.clearBasement() |
| 8120 | + | T:turnLeft(1) |
| 8121 | - | T:sortInventory(false) |
| 8121 | + | |
| 8122 | - | T:dropItem("seeds", "forward")
|
| 8122 | + | |
| 8123 | - | T:dropItem("flint", "forward")
|
| 8123 | + | -- should now be facing crops. may be crafting table to left |
| 8124 | - | clearRectangle({width = 15, length = 15, up = true, down = true})
|
| 8124 | + | |
| 8125 | - | -- area has been cleared. starts facing back, 1 block above ground, 1 block below ceiling |
| 8125 | + | return atHome-- now facing crops |
| 8126 | end | |
| 8127 | - | for i = 1, 14 do -- place cable into gutter beneath front of farm |
| 8127 | + | |
| 8128 | - | T:place("cable", "up")
|
| 8128 | + | function lib.crossFarm() |
| 8129 | - | if i < 14 then |
| 8129 | + | |
| 8130 | local blockType = "" | |
| 8131 | local isReady, cropType, status = lib.isCropReady("down")
| |
| 8132 | -- will go forward until chest or cobble detected below | |
| 8133 | - | -- ends right side facing right, just below ceiling |
| 8133 | + | |
| 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 | - | -- R.data = "new", "left", "right" or "back" to extend tree farm |
| 8139 | + | |
| 8140 | elseif blockType:find("barrel") ~= nil or blockType:find("chest") ~= nil or blockType:find("cobble") ~= nil then
| |
| 8141 | - | -- R.networkFarm to create storage area |
| 8141 | + | |
| 8142 | end | |
| 8143 | numMoves = numMoves + 1 | |
| 8144 | end | |
| 8145 | - | -- R.data = "new", "left", "right", "back", "convertStorage", "convert" |
| 8145 | + | return blockType -- either chest or cobble |
| 8146 | - | if R.data == "new" then -- new treeFarm, Start at current position |
| 8146 | + | |
| 8147 | - | -- build 4 wall sections in 2 passes |
| 8147 | + | |
| 8148 | function lib.farmInFront() | |
| 8149 | - | lib.buildWallSection("---------------", R.useBlockType) -- left wall (15 blocks)
|
| 8149 | + | |
| 8150 | - | T:go("R1F1")
|
| 8150 | + | T:go("U1L1F11D1R1") -- on next farm, facing crops
|
| 8151 | local crop = lib.manageTree() -- refuel, gather seeds and other crops | |
| 8152 | - | lib.buildWallSection("--------------", R.useBlockType) -- back/ right wall (14 blocks)
|
| 8152 | + | local isFarmToRight, _ = lib.harvest(crop) -- harvest field, store crops |
| 8153 | return isFarmToRight | |
| 8154 | end | |
| 8155 | - | lib.buildWallSection("------c------", R.useBlockType) -- front wall (14 blocks) c = network cable
|
| 8155 | + | |
| 8156 | function lib.farmToRight() | |
| 8157 | - | lib.buildWallSection("---------------", R.useBlockType) -- left wall top (15 blocks)
|
| 8157 | + | |
| 8158 | - | T:go("R1F1")
|
| 8158 | + | T:go("U1F11 D1") -- on next farm, facing crops
|
| 8159 | local crop = lib.manageTree() -- refuel, gather seeds and other crops | |
| 8160 | - | lib.buildWallSection("--------------", R.useBlockType) --back/right wall (14 blocks)
|
| 8160 | + | lib.harvest(crop) -- harvest field, store crops |
| 8161 | end | |
| 8162 | ||
| 8163 | - | --lib.buildWallSection("-----lmb-----", R.useBlockType) --front wall (14 blocks) log/modem/barrel
|
| 8163 | + | function lib.getCrops() |
| 8164 | - | lib.buildWallSection("-----lmb", R.useBlockType)
|
| 8164 | + | |
| 8165 | ||
| 8166 | - | network.attachModem() |
| 8166 | + | if lib.isStorage("forward") then
|
| 8167 | lib.getSeeds("forward")
| |
| 8168 | - | lib.buildWallSection("-----", R.useBlockType)
|
| 8168 | + | |
| 8169 | - | T:go("R1F1 D2") -- over 13 x 13 internal area
|
| 8169 | + | |
| 8170 | - | elseif R.data == "left" or R.data == "right" or R.data == "back" then |
| 8170 | + | if lib.isStorage("forward") then
|
| 8171 | - | -- build 3 wall sections in 2 passes |
| 8171 | + | lib.getVeg("forward")
|
| 8172 | - | if R.data == "left" then -- should be on left corner of existing |
| 8172 | + | |
| 8173 | - | T:go("L1F1 D1") -- move left 1 blocks, down 1: <-
|
| 8173 | + | |
| 8174 | - | lib.buildWallSection("------c-------", R.useBlockType) -- front wall (14 blocks) c = network cable <-
|
| 8174 | + | |
| 8175 | ||
| 8176 | - | lib.buildWallSection("--------------", R.useBlockType) -- left wall (14 blocks) ^
|
| 8176 | + | function lib.getSaplings(direction) |
| 8177 | --[[ get a single sapling from the chest ]] | |
| 8178 | - | lib.buildWallSection("-------------", R.useBlockType) -- back wall (13 blocks) ->
|
| 8178 | + | |
| 8179 | - | T:go("U1R2") -- turn round ready to add next layer <-
|
| 8179 | + | |
| 8180 | - | lib.buildWallSection("--------------", R.useBlockType) -- back wall top (14 blocks) <-
|
| 8180 | + | |
| 8181 | while T:suck(direction, 1) do end -- remove saplings/ seeds | |
| 8182 | - | lib.buildWallSection("--------------", R.useBlockType) -- left wall top (14 blocks) v
|
| 8182 | + | |
| 8183 | T:dropItem("sapling", direction, 1) -- drop all but 1 saplings
| |
| 8184 | - | lib.buildWallSection("-----bm", R.useBlockType) -- front wall (7 blocks) barrel/modem ->
|
| 8184 | + | if not T:dropItem("seeds", direction, 0) then-- drop all seeds
|
| 8185 | - | network.attachModem() |
| 8185 | + | T:dropItem("seeds", "up", 0)
|
| 8186 | end | |
| 8187 | - | lib.buildWallSection("l-----", R.useBlockType) -- front wall (5 blocks) log ->
|
| 8187 | + | |
| 8188 | - | T:go("R2F12 R1F1 D2") -- over 13 x 13 internal area lower left side
|
| 8188 | + | return T:getItemSlot("sapling", -1)
|
| 8189 | - | elseif R.data == "right" then -- should be on right corner of existing |
| 8189 | + | |
| 8190 | - | T:go("R1F1 D1") -- move right, forward, down 1
|
| 8190 | + | |
| 8191 | - | lib.buildWallSection("------c-------", R.useBlockType) -- front wall (14 blocks) c = network cable
|
| 8191 | + | function lib.getSeeds(direction) |
| 8192 | --[[ get 1 stack of wheat seeds or 1 stack of beetroot seeds ]] | |
| 8193 | - | lib.buildWallSection("--------------", R.useBlockType) -- right wall (14 blocks)
|
| 8193 | + | print("Collecting seeds from storage")
|
| 8194 | while T:suck(direction, 1) do end -- remove saplings/ seeds | |
| 8195 | - | lib.buildWallSection("-------------", R.useBlockType) -- back wall (13 blocks)
|
| 8195 | + | T:dropItem("sapling", direction, 0) -- drop all saplings
|
| 8196 | - | T:go("U1R2") -- turn round ready to add next layer
|
| 8196 | + | T:dropItem("minecraft:wheat_seeds", direction, 64) -- drop all but 64 seeds
|
| 8197 | - | lib.buildWallSection("--------------", R.useBlockType) -- back wall top (14 blocks)
|
| 8197 | + | T:dropItem("minecraft:beetroot_seeds", direction, 64)
|
| 8198 | local crop = "" | |
| 8199 | - | lib.buildWallSection("--------------", R.useBlockType) -- left wall top (14 blocks)
|
| 8199 | + | if T:getItemSlot("minecraft:wheat_seeds", -1) > 0 then
|
| 8200 | crop = "wheat" | |
| 8201 | - | lib.buildWallSection("-----lmb", R.useBlockType)
|
| 8201 | + | print("Field crop = "..crop)
|
| 8202 | elseif T:getItemSlot("minecraft:beetroot_seeds", -1) > 0 then
| |
| 8203 | - | network.attachModem() |
| 8203 | + | crop = "beetroot" |
| 8204 | - | T:forward(2) |
| 8204 | + | print("Field crop = "..crop)
|
| 8205 | - | lib.buildWallSection("-----", R.useBlockType)
|
| 8205 | + | |
| 8206 | - | T:go("R1F1 D2") -- over 13 x 13 internal area
|
| 8206 | + | |
| 8207 | - | elseif R.data == "back" then -- should be on left front corner of existing |
| 8207 | + | return crop |
| 8208 | - | T:go("R2F1 D4R2 F1") -- move forward 14 blocks, down 1
|
| 8208 | + | |
| 8209 | - | for i = 1, 15 do |
| 8209 | + | |
| 8210 | - | T:place("cable", "up")
|
| 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 | - | if T:getBlockType("up") == R.useBlockType then -- already a farm on left side
|
| 8214 | + | while T:suck(direction, 1) do end -- remove carrots / potatoes / wheat / beetroot |
| 8215 | - | T:go("U2C2 U1C2 F13R1 F1D1", false, 0, false, R.useBlockType)
|
| 8215 | + | --clsTurtle.dropItem(self, item, direction, keepAmount) |
| 8216 | - | lib.buildWallSection("--------------", R.useBlockType) -- back wall (14 blocks)
|
| 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 | - | lib.buildWallSection("--------------", R.useBlockType) -- left wall (14 blocks)
|
| 8220 | + | local crop = "" |
| 8221 | if T:getItemSlot("potato", -1) > 0 then
| |
| 8222 | - | lib.buildWallSection("--------------", R.useBlockType) -- back wall (14 blocks)
|
| 8222 | + | crop = "potato" |
| 8223 | print("Field crop = "..crop)
| |
| 8224 | elseif T:getItemSlot("carrot", -1) > 0 then
| |
| 8225 | crop = "carrot" | |
| 8226 | - | lib.buildWallSection("-------------", R.useBlockType) --right wall (13 blocks) no special blocks
|
| 8226 | + | print("Field crop = "..crop)
|
| 8227 | - | T:go("U1R2") -- turn round ready to add next layer
|
| 8227 | + | |
| 8228 | - | for i = 1, 2 do |
| 8228 | + | |
| 8229 | - | lib.buildWallSection("--------------", R.useBlockType) --right wall top (14 blocks) no special blocks
|
| 8229 | + | --T:turnRight(2) -- face crops |
| 8230 | - | T:go("L1F1")
|
| 8230 | + | return crop |
| 8231 | end | |
| 8232 | - | lib.buildWallSection("-------------", R.useBlockType) -- left wall top (13 blocks) no special blocks
|
| 8232 | + | |
| 8233 | - | T:go("F1L1 F7x2")
|
| 8233 | + | function lib.goHome() |
| 8234 | - | T:go("D1x2")
|
| 8234 | + | |
| 8235 | - | T:place("cable", "down")
|
| 8235 | + | |
| 8236 | -- is tree above or in front | |
| 8237 | - | T:place("modem", "down")
|
| 8237 | + | |
| 8238 | - | T:go("F1R2x2")
|
| 8238 | + | |
| 8239 | - | T:place("log", "down")
|
| 8239 | + | lib.harvestTree("forward") -- will only harvest if fuel below half of limit
|
| 8240 | - | T:go("F2x2")
|
| 8240 | + | |
| 8241 | - | T:place("barrel", "down")
|
| 8241 | + | |
| 8242 | lib.harvestTree("up")
| |
| 8243 | - | network.attachModem() |
| 8243 | + | |
| 8244 | - | T:go("F6R1 F1D2")
|
| 8244 | + | elseif T:getItemSlot("log", -1) > 0 then -- tree just harvested
|
| 8245 | onTree = true | |
| 8246 | - | else -- convertStorage or convert |
| 8246 | + | |
| 8247 | - | -- legacy farm had polished block on positions 4 / (10) from left corner |
| 8247 | + | |
| 8248 | - | local message = lib.findLegacyStart() |
| 8248 | + | lib.harvestTree("up")
|
| 8249 | - | if message ~= "" then |
| 8249 | + | |
| 8250 | - | return {message}
|
| 8250 | + | while turtle.down() do end |
| 8251 | - | end |
| 8251 | + | |
| 8252 | - | -- now on top of polished block, 4 from left corner, facing Centre |
| 8252 | + | |
| 8253 | - | T:forward(2) |
| 8253 | + | |
| 8254 | - | T:place("barrel", "down")
|
| 8254 | + | if onTree then -- tree harvested, but direction unknown |
| 8255 | - | T:go("F1D1")
|
| 8255 | + | |
| 8256 | - | T:place("cable", "down")
|
| 8256 | + | local turns = 0 |
| 8257 | - | T:up(1) |
| 8257 | + | local onChest = lib.isStorage("down")
|
| 8258 | - | T:place("modem", "down")
|
| 8258 | + | while not onChest do |
| 8259 | - | network.attachModem() |
| 8259 | + | |
| 8260 | - | T:forward(1) |
| 8260 | + | if lib.isStorage("down") then
|
| 8261 | - | T:place("log", "down")
|
| 8261 | + | onChest = true |
| 8262 | - | T:go("R1F1 R1F1 D5R1 F1L1 F7R1")-- left corner, facing back ready to clear basement
|
| 8262 | + | |
| 8263 | turtle.back() | |
| 8264 | - | if (R.data):find("convert") == nil then
|
| 8264 | + | |
| 8265 | - | lib.floodFarm(R) |
| 8265 | + | |
| 8266 | if not onChest then | |
| 8267 | - | lib.clearBasement() -- area has been cleared. ends right side facing right, just below ceiling |
| 8267 | + | |
| 8268 | turns = turns + 1 | |
| 8269 | - | if R.data == "back" then |
| 8269 | + | |
| 8270 | - | T:go("R2F6 R1D1")
|
| 8270 | + | if turns == 4 then |
| 8271 | break | |
| 8272 | - | T:go("R2F6 L1F1 U4D5 R2F1") -- make exit for player. end mid floor/ceiling height, facing back, in centre
|
| 8272 | + | |
| 8273 | end -- should be on chest. If not should be over water | |
| 8274 | - | if R.data == "new" or R.data == "convertStorage" then -- put storage in this farm |
| 8274 | + | if onChest then -- onChest and onTree, go left,down |
| 8275 | T:go("R1F1D1R1")
| |
| 8276 | - | T:place("cable", "up")
|
| 8276 | + | |
| 8277 | atHome = lib.checkPosition() | |
| 8278 | if atHome then | |
| 8279 | - | T:place("cable", "up")
|
| 8279 | + | return true -- exit function |
| 8280 | end | |
| 8281 | - | utils.createStorage() -- creates on ground, 1 below current |
| 8281 | + | |
| 8282 | while turtle.down() do end -- no tree around, no logs onboard | |
| 8283 | - | T:place("cable", "forward")
|
| 8283 | + | |
| 8284 | ||
| 8285 | return false | |
| 8286 | - | T:place("cable", "up")
|
| 8286 | + | |
| 8287 | ||
| 8288 | function lib.gotoTree(logSlot) | |
| 8289 | -- assume facing crops | |
| 8290 | - | for i = 1, 6 do |
| 8290 | + | |
| 8291 | - | T:place("cable", "up")
|
| 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 | - | T:place("modem", "up")
|
| 8295 | + | lib.harvestTree("forward") -- fell tree or plant sapling, ends facing tree / dirt / sapling. sticks already used for fuel. excess saplings placed
|
| 8296 | - | T:go("F1R2U2")
|
| 8296 | + | |
| 8297 | - | T:place("barrel", "down")
|
| 8297 | + | if logSlot == 0 then -- no logs passed as parameter |
| 8298 | - | T:drop("down", "dirt", 64)-- override 'slot' with item string
|
| 8298 | + | logSlot = T:getItemSlot("log")
|
| 8299 | - | T:up(1) |
| 8299 | + | |
| 8300 | - | T:place("hopper", "down")
|
| 8300 | + | T:go("R1F1D1") -- return to base, facing buried storage
|
| 8301 | if logSlot == 0 then -- has logs so needs to craft and refuel | |
| 8302 | - | network.attachModem() |
| 8302 | + | T:turnRight(1) -- facing crops |
| 8303 | - | T:go("U1C2 U2F6 R2")
|
| 8303 | + | |
| 8304 | - | --network.attachModem() |
| 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:place("barrel", "down", false)
|
| 8316 | + | |
| 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 | - | T:place("torch", "forward", true)
|
| 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 | - | -- T:place(blockType, direction, leaveExisting, signText) |
| 8337 | + | if lib.isStorage("down") then
|
| 8338 | isFarmToRight = true | |
| 8339 | end | |
| 8340 | turtle.back() | |
| 8341 | end | |
| 8342 | end | |
| 8343 | - | T:place(R.useBlockType, "forward", true) |
| 8343 | + | |
| 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 | - | T:place(R.useBlockType, "up", true) |
| 8351 | + | |
| 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:place(R.useBlockType, "forward") |
| 8358 | + | |
| 8359 | lib.storeCrops() -- rotates from start to deposit seeds and crops, ends facing crops | |
| 8360 | return isFarmToRight, isFarmToFront | |
| 8361 | end | |
| 8362 | ||
| 8363 | - | T:place(R.useBlockType, "forward") |
| 8363 | + | function lib.harvestTree(direction) |
| 8364 | --[[ | |
| 8365 | start in front of / during tree harvest | |
| 8366 | Check if sapling present | |
| 8367 | - | T:place(R.useBlockType, "forward") |
| 8367 | + | |
| 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 | - | T:place(R.useBlockType, "down", true) |
| 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 | - | T:place(R.useBlockType, "down", true) |
| 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 | - | T:place("torch", "down") -- place torch, move forward
|
| 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 | - | if not T:place("stone", "down") then -- place stone below
|
| 8499 | + | |
| 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 | - | T:place("torch", "down") -- place torch
|
| 8617 | + | |
| 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 | - | T:place("torch", "down") -- place torch
|
| 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 | - | T:place("slab", "down") -- place slab layer 1
|
| 8846 | + | |
| 8847 | elseif R.subChoice == 2 then -- end of blocks in front of turtle eg cliff, wall | |
| 8848 | - | T:place("slab", "down") -- place slab layer 2
|
| 8848 | + | |
| 8849 | while turtle.detect() and doContinue do | |
| 8850 | - | T:place("redstone", "down")
|
| 8850 | + | |
| 8851 | doContinue, blocks, measure, message = lib.checkBlocks(R, blocks) | |
| 8852 | - | T:place("redstone", "forward") -- redstone on ground level slab
|
| 8852 | + | |
| 8853 | message = "Obstruction above stopped measurement" | |
| 8854 | - | T:place("slab", "down") -- slab on layer 1
|
| 8854 | + | |
| 8855 | doContinue = false | |
| 8856 | - | T:place("slab", "down") -- slab on layer 3
|
| 8856 | + | |
| 8857 | end | |
| 8858 | - | T:place("redstone", "down") -- redstone on layer 3 slab
|
| 8858 | + | |
| 8859 | method = "Method:Until search: '"..R.data.."' met" | |
| 8860 | while turtle.detect() and doContinue do | |
| 8861 | - | T:place("redstone", "forward") -- redstone on layer 1 slab
|
| 8861 | + | |
| 8862 | doContinue, blocks, measure, message = lib.checkBlocks(R, blocks) | |
| 8863 | - | T:place("redstone", "forward") -- redstone on level 0 floor
|
| 8863 | + | |
| 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 | - | T:place("redstone", "down") -- redstone under chest etc
|
| 8870 | + | |
| 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 | - | T:place("chest", "forward") -- end chest
|
| 8881 | + | |
| 8882 | T:up(1) | |
| 8883 | - | T:place("slab", "down") -- slab above chest
|
| 8883 | + | |
| 8884 | if doContinue then | |
| 8885 | blockType = T:getBlockType("up")
| |
| 8886 | end | |
| 8887 | - | T:place("chest", "forward") -- start chest
|
| 8887 | + | |
| 8888 | measure = "Height measured: "..blocks.." blocks" | |
| 8889 | - | T:place("wall", "forward") -- place wall
|
| 8889 | + | |
| 8890 | end | |
| 8891 | - | T:place("pressure", "down") -- place pressure plate
|
| 8891 | + | |
| 8892 | for i = 1, blocks do | |
| 8893 | - | T:place("hopper", "forward") -- place hopper into chest
|
| 8893 | + | |
| 8894 | end | |
| 8895 | - | T:place("wall", "forward") -- place second wall
|
| 8895 | + | |
| 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 | - | T:place(R.useBlockType, "forward", false) -- replace back wall with polished block layer 2 |
| 8902 | + | |
| 8903 | message1 = blockType.." found at "..blocks | |
| 8904 | - | T:place(R.useBlockType, "forward", false) -- replace back wall with polished block layer 3 |
| 8904 | + | |
| 8905 | else | |
| 8906 | move = turtle.down() | |
| 8907 | - | T:place(R.useBlockType, "forward", false)-- polished block above second wall layer 3 |
| 8907 | + | |
| 8908 | blocks = blocks + 1 | |
| 8909 | else | |
| 8910 | measure = "Depth measured: "..blocks.." blocks" | |
| 8911 | - | T:place("piston", "forward") -- lower replacer piston placed
|
| 8911 | + | |
| 8912 | end | |
| 8913 | end | |
| 8914 | - | T:place("piston", "forward") -- lower piston placed
|
| 8914 | + | |
| 8915 | elseif R.subChoice == 2 then -- end of wall in front` | |
| 8916 | while turtle.detect() do | |
| 8917 | - | T:place(R.useBlockType, "forward", false) -- polished block back wall layer 4 |
| 8917 | + | |
| 8918 | blocks = blocks + 1 | |
| 8919 | - | T:place("dispenser", "forward") -- dispenser placed
|
| 8919 | + | |
| 8920 | else | |
| 8921 | message1 = "Obstruction below stopped measurement" | |
| 8922 | - | T:place("slab", "down") -- lower piston slab placed
|
| 8922 | + | |
| 8923 | end | |
| 8924 | - | T:place(R.useBlockType, "forward", false)-- polished block above second wall layer 4 |
| 8924 | + | |
| 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 | - | T:place("computercraft:computer_normal", "forward", false) -- place computer
|
| 8929 | + | |
| 8930 | blocks = blocks + 1 | |
| 8931 | local blockType = T:getBlockType("forward")
| |
| 8932 | - | T:place(R.useBlockType, "forward", false) -- polished block back wall layer 4 |
| 8932 | + | |
| 8933 | measure = "Depth measured: "..blocks.." blocks" | |
| 8934 | message = "Found "..blockType | |
| 8935 | - | T:place("piston", "forward") -- upper piston placed
|
| 8935 | + | |
| 8936 | end | |
| 8937 | else | |
| 8938 | - | T:place(R.useBlockType, "forward", false) -- polished block back wall layer 5 |
| 8938 | + | |
| 8939 | break | |
| 8940 | end | |
| 8941 | - | T:place(R.useBlockType, "forward", false)-- right side polished block layer 5, facing right side, in mob drop -- layer 5 facing left side, in mob drop |
| 8941 | + | |
| 8942 | end | |
| 8943 | for i = 1, blocks do | |
| 8944 | turtle.up() | |
| 8945 | - | T:place("piston", "forward") -- upper replacer piston placed
|
| 8945 | + | |
| 8946 | T:go("F1R2")
| |
| 8947 | elseif R.choice == 103 then -- length | |
| 8948 | - | T:place("slab", "forward") -- upper piston slab placed
|
| 8948 | + | |
| 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 | - | T:place("computercraft:computer_normal", "forward", false) -- place computer in gap, layer 4
|
| 8955 | + | |
| 8956 | if turtle.forward() then | |
| 8957 | doContinue, blocks, measure, message = lib.checkBlocks(R, blocks) | |
| 8958 | else | |
| 8959 | - | T:place(R.useBlockType, "forward", false) |
| 8959 | + | |
| 8960 | measure = "" | |
| 8961 | - | T:place(R.useBlockType, "forward", false) |
| 8961 | + | |
| 8962 | end | |
| 8963 | - | T:place(R.useBlockType, "forward", false) -- facing right |
| 8963 | + | |
| 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 | - | T:place("glass", "down", false)
|
| 8969 | + | |
| 8970 | message = "Obstruction ahead stopped measurement" | |
| 8971 | - | T:place("glass", "down", false) -- on top of glass facing back wall at dungeon base level 5
|
| 8971 | + | |
| 8972 | doContinue = false | |
| 8973 | - | T:place(R.useBlockType, "down", false) -- level 6 dungeon exit |
| 8973 | + | |
| 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 | - | T:place(R.useBlockType, "forward", false) |
| 8983 | + | |
| 8984 | measure = "Length measured: "..blocks.." blocks" | |
| 8985 | - | T:place(R.useBlockType, "forward", false) -- facing right |
| 8985 | + | |
| 8986 | end | |
| 8987 | end | |
| 8988 | else | |
| 8989 | - | T:place(R.useBlockType, "forward", false) |
| 8989 | + | |
| 8990 | measure = "" | |
| 8991 | doContinue = false | |
| 8992 | end | |
| 8993 | end | |
| 8994 | elseif R.subChoice == 5 then -- search for specific block down min 3 characters | |
| 8995 | - | T:place("computercraft:wired_modem", "forward", false) -- place modem
|
| 8995 | + | |
| 8996 | --while turtle.detectDown() and doContinue do | |
| 8997 | - | T:place("computercraft:cable", "forward", false) -- place network cable
|
| 8997 | + | |
| 8998 | - | T:place("computercraft:cable", "forward", false) -- place network cable (no need to move)
|
| 8998 | + | |
| 8999 | doContinue, blocks, measure, message = lib.checkBlocks(R, blocks) | |
| 9000 | - | T:place("computercraft:cable", "forward", false)
|
| 9000 | + | |
| 9001 | local blockType = T:getBlockType("down")
| |
| 9002 | - | T:place("computercraft:cable", "forward", false)
|
| 9002 | + | |
| 9003 | message = "Found "..blockType | |
| 9004 | - | T:place("computercraft:wired_modem", "forward", false) -- place modem
|
| 9004 | + | |
| 9005 | doContinue = false | |
| 9006 | - | T:place("computercraft:cable", "forward", false)
|
| 9006 | + | |
| 9007 | - | T:place("computercraft:cable", "forward", false)
|
| 9007 | + | |
| 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 | - | local function createTrialCover(R) |
| 9059 | + | |
| 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 | - | function lib.findSpawner() |
| 9078 | + | |
| 9079 | if goRight then | |
| 9080 | T:go("R1F1R1")
| |
| 9081 | - | -- assume turtle placed facing trial spawner |
| 9081 | + | |
| 9082 | T:go("L1F1L1")
| |
| 9083 | end | |
| 9084 | goRight = not goRight | |
| 9085 | end | |
| 9086 | return {}
| |
| 9087 | end | |
| 9088 | - | if moves > 32 then |
| 9088 | + | |
| 9089 | local function oceanMonumentColumns(R) | |
| 9090 | -- utility to find corners and build columns to surface | |
| 9091 | local lib = {}
| |
| 9092 | ||
| 9093 | - | if not found then -- could be behind a wall |
| 9093 | + | |
| 9094 | - | print("Assuming spawner behind a wall")
|
| 9094 | + | |
| 9095 | while T:isWater("forward") do
| |
| 9096 | T:go("U1C2")
| |
| 9097 | - | while turtle.forward() and not quit do |
| 9097 | + | |
| 9098 | end | |
| 9099 | - | if moves > 32 then |
| 9099 | + | |
| 9100 | - | quit = true |
| 9100 | + | |
| 9101 | ||
| 9102 | function lib.buildTower() | |
| 9103 | - | found, position = lib.isSpawner() -- true/false, top/bottom/nil |
| 9103 | + | |
| 9104 | - | if not found then |
| 9104 | + | |
| 9105 | - | T:go("R2F"..moves + 2 .."R2")
|
| 9105 | + | |
| 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 found, position = lib.findSpawner() -- move forwards until meet Spawner, go through wall if present |
| 9139 | + | |
| 9140 | - | if not found then --outside dungeon |
| 9140 | + | |
| 9141 | - | return {"Trial spawner not found"}
|
| 9141 | + | |
| 9142 | - | end |
| 9142 | + | |
| 9143 | - | if position == "top" then |
| 9143 | + | |
| 9144 | - | T:go("B2D1")
|
| 9144 | + | |
| 9145 | - | elseif position == "forward" then |
| 9145 | + | |
| 9146 | - | T:go("B1")
|
| 9146 | + | |
| 9147 | blockType = T:getBlockType("down")
| |
| 9148 | - | T:go("B2U1")
|
| 9148 | + | |
| 9149 | turtle.back() | |
| 9150 | - | T:go("R1F2R2") --on lower right corner
|
| 9150 | + | |
| 9151 | - | -- starts with wall across spawner |
| 9151 | + | |
| 9152 | - | buildStructure(R) |
| 9152 | + | |
| 9153 | - | T:go("U3F1 R1F1 L1U1 F1")
|
| 9153 | + | |
| 9154 | lib.buildTower() | |
| 9155 | - | R.width = 3 |
| 9155 | + | |
| 9156 | - | R.length = 3 |
| 9156 | + | |
| 9157 | return {}
| |
| 9158 | - | createFloorCeiling(R) |
| 9158 | + | |
| 9159 | - | T:go("F1R1 B1D1 B1D2 F1")
|
| 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:place("cobble", "down", false) -- place cobblestone or cobbled deepslate to mark zero coordinate
|
| 9273 | + | |
| 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 | - | T:place("minecraft:end_stone", "forward", false) -- place endstone to mark facing direction
|
| 9320 | + | |
| 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 | - | -- assumes legacy tree farm with turtle on polished block 4 blocks from corner |
| 9481 | + | |
| 9482 | - | local message = "" |
| 9482 | + | |
| 9483 | - | R.treeSize = "single" |
| 9483 | + | |
| 9484 | createCorridor(R, true) | |
| 9485 | - | --local logType = "" |
| 9485 | + | |
| 9486 | - | --local startHeight = 0 |
| 9486 | + | |
| 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 | - | if blockType:find("dirt") ~= nil then -- dirt found
|
| 9497 | + | |
| 9498 | - | T:go("R1F1L1")
|
| 9498 | + | |
| 9499 | ||
| 9500 | - | if blockType:find("dirt") ~= nil then
|
| 9500 | + | |
| 9501 | - | R.treeSize = "double" |
| 9501 | + | |
| 9502 | -- move up | |
| 9503 | - | T:go("L1F1 R1")
|
| 9503 | + | |
| 9504 | - | else -- dirt NOT found where expected |
| 9504 | + | |
| 9505 | - | message = "Unable to determine position" |
| 9505 | + | |
| 9506 | -- move back to beginning | |
| 9507 | ||
| 9508 | - | blockType = T:getBlockType("forward") -- 1 block above dirt
|
| 9508 | + | |
| 9509 | - | if blockType:find("log") ~= nil or blockType:find("sapling") ~= nil or blockType:find("propagule") ~= nil then
|
| 9509 | + | |
| 9510 | - | local parts = T:getNames(blockType) |
| 9510 | + | |
| 9511 | - | if parts[2] == "dark" then |
| 9511 | + | |
| 9512 | - | R.logType = "dark_oak" |
| 9512 | + | |
| 9513 | ||
| 9514 | - | R.logType = parts[2] -- eg "oak" |
| 9514 | + | |
| 9515 | ||
| 9516 | - | if R.logType == "mangrove" then |
| 9516 | + | |
| 9517 | - | R.useBlockType = "mangrove_propagule" |
| 9517 | + | |
| 9518 | -- move up | |
| 9519 | - | R.useBlockType = parts[2].."_sapling" -- eg "oak_sapling" |
| 9519 | + | |
| 9520 | --end | |
| 9521 | ||
| 9522 | - | T:down(1) -- facing dirt |
| 9522 | + | |
| 9523 | ||
| 9524 | - | return R, message |
| 9524 | + | |
| 9525 | ||
| 9526 | -- replace block with replaceWith ("" = any)
| |
| 9527 | - | function lib.waitForGrowth(R) |
| 9527 | + | |
| 9528 | - | local pattern = R.treeSize --"single","double" |
| 9528 | + | |
| 9529 | - | local elapsed = 0 |
| 9529 | + | |
| 9530 | - | local facing = "left" |
| 9530 | + | |
| 9531 | - | local ready = {}
|
| 9531 | + | |
| 9532 | - | ready.left = false |
| 9532 | + | |
| 9533 | - | ready.top = false |
| 9533 | + | |
| 9534 | - | ready.right = false |
| 9534 | + | |
| 9535 | - | ready.bottom = false |
| 9535 | + | |
| 9536 | - | if R.logType == "mangrove" then |
| 9536 | + | |
| 9537 | - | pattern = "mangrove" |
| 9537 | + | |
| 9538 | - | local facings = {"left", "top", "right", "bottom"}
|
| 9538 | + | |
| 9539 | - | T:up(1) -- go up from dirt to sapling level |
| 9539 | + | |
| 9540 | - | while not ready.left or not ready.right or not ready.top or not ready.bottom do |
| 9540 | + | |
| 9541 | --MINING | |
| 9542 | text[11] = {"1 ladder for each level","levels / 4 torch (optional)","levels * 4 stone"} -- ladder to bedrock
| |
| 9543 | - | if blockType:find("propagule") == nil then -- either grown or deleted by roots
|
| 9543 | + | |
| 9544 | - | ready[facings[i]] = true |
| 9544 | + | |
| 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 | - | if ready.left and ready.right and ready.top and ready.bottom then |
| 9548 | + | |
| 9549 | text[18] = {"1 bucket (optional)"} -- mine to bedrock
| |
| 9550 | text[19] = {"1 UNUSED diamond sword (optional)"} -- rob mineshaft
| |
| 9551 | - | sleep(15) |
| 9551 | + | |
| 9552 | - | elapsed = elapsed + 15 |
| 9552 | + | |
| 9553 | - | if elapsed / 60 > 15 then -- max 15 mins real time before farm is harvested |
| 9553 | + | |
| 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 | - | print("Waiting for mangrove growth "..elapsed / 60 .." minutes")
|
| 9557 | + | |
| 9558 | - | print("Left = "..tostring(ready.left)..
|
| 9558 | + | |
| 9559 | - | ", top = "..tostring(ready.top).. |
| 9559 | + | |
| 9560 | - | ", right = "..tostring(ready.right).. |
| 9560 | + | |
| 9561 | - | ", bottom = "..tostring(ready.bottom)) |
| 9561 | + | |
| 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 | - | --T:go("L1D1")
|
| 9564 | + | |
| 9565 | - | T:turnLeft(1) -- face front |
| 9565 | + | |
| 9566 | ||
| 9567 | - | while not ready.left or not ready.right do |
| 9567 | + | |
| 9568 | - | T:up(1) -- go up from dirt to sapling level |
| 9568 | + | |
| 9569 | - | local blockType = T:getBlockType("forward")
|
| 9569 | + | |
| 9570 | - | if blockType:find("log") ~= nil then
|
| 9570 | + | |
| 9571 | - | ready[facing] = true |
| 9571 | + | |
| 9572 | text[45] = {"84 stone"} -- undermine dragon towers
| |
| 9573 | - | if pattern == "single" then |
| 9573 | + | |
| 9574 | - | --alternate between 2 trees, starts facing left |
| 9574 | + | |
| 9575 | text[48] = {"height * 4 stone","height * ladders", "1 trapdoor"} -- build end portal platform
| |
| 9576 | - | if facing == "left" then |
| 9576 | + | |
| 9577 | - | facing = "right" |
| 9577 | + | |
| 9578 | - | elseif facing == "right" then |
| 9578 | + | |
| 9579 | - | facing = "left" |
| 9579 | + | |
| 9580 | text[53] = {"2 * length stone or dirt","2 water buckets","torches (optional)"} -- water canal
| |
| 9581 | - | blockType = T:getBlockType("forward")
|
| 9581 | + | |
| 9582 | - | if blockType:find("log") ~= nil then
|
| 9582 | + | |
| 9583 | - | ready[facing] = true |
| 9583 | + | |
| 9584 | text[57] = {"height * 10 stone","height * 4 + 2 soul sand, 2 water buckets"} -- Boat bubble lift
| |
| 9585 | - | T:down(1) -- drop below sapling to dirt level |
| 9585 | + | |
| 9586 | - | elseif pattern == "double" then |
| 9586 | + | |
| 9587 | - | if ready.left and facing == "left" then-- tree on left now grown. check right |
| 9587 | + | |
| 9588 | - | T:go("R2F2")
|
| 9588 | + | |
| 9589 | - | facing = "right" |
| 9589 | + | |
| 9590 | text[63] = {"2 water buckets","If using bubble lift","2 fence","2 signs","1 slab",
| |
| 9591 | - | blockType = T:getBlockType("forward")
|
| 9591 | + | |
| 9592 | - | if blockType:find("log") ~= nil then
|
| 9592 | + | |
| 9593 | - | ready[facing] = true |
| 9593 | + | |
| 9594 | "23 polished stone + 7 slabs","2 glass","1 stone pressure plate","1 dispenser", | |
| 9595 | - | T:down(1) -- drop below sapling to dirt level |
| 9595 | + | |
| 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 | - | print("Farm type: "..pattern)
|
| 9598 | + | |
| 9599 | - | print("Waiting for tree growth "..elapsed / 60 .." minutes")
|
| 9599 | + | |
| 9600 | - | print("Left grown = "..tostring(ready.left)..", right grown = "..tostring(ready.right))
|
| 9600 | + | |
| 9601 | - | if not ready.left or not ready.right then |
| 9601 | + | |
| 9602 | - | sleep(15) |
| 9602 | + | |
| 9603 | - | elapsed = elapsed + 15 |
| 9603 | + | |
| 9604 | - | if pattern == "single" and elapsed / 60 > 10 then -- max 10 mins real time before farm is harvested |
| 9604 | + | |
| 9605 | text[76] = {"No items required"} -- clear solid
| |
| 9606 | - | elseif pattern == "double" and elapsed / 60 > 15 then -- max 15 mins real time before farm is harvested |
| 9606 | + | |
| 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 | - | -- growth complete |
| 9612 | + | |
| 9613 | - | if pattern == "single" then |
| 9613 | + | |
| 9614 | - | if facing == "right" then |
| 9614 | + | |
| 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 | - | --T:go("F1R1 F3R1") -- facing first dirt
|
| 9619 | + | |
| 9620 | - | T:go("F1R1 F1R1") -- facing first dirt
|
| 9620 | + | |
| 9621 | - | elseif pattern == "double" then -- assume on right side |
| 9621 | + | |
| 9622 | - | if facing == "right" then |
| 9622 | + | |
| 9623 | - | T:go("R1F1 R1F4 R1")
|
| 9623 | + | |
| 9624 | text[91] = {"length * height stone"} -- Build a wall
| |
| 9625 | - | T:go("L1F1 R1F2 R1")
|
| 9625 | + | |
| 9626 | text[93] = {"length * width * height stairs", "length * slabs"} -- build a gable roof
| |
| 9627 | - | elseif pattern == "mangrove" then |
| 9627 | + | |
| 9628 | - | T:go("D2F6 U1F1 R1F6 R1F1 U1")
|
| 9628 | + | |
| 9629 | text[96] = {"1 block of choice","1 redstone torch"} -- place redstone torch on upward slope
| |
| 9630 | - | -- ends facing dirt at base of first tree |
| 9630 | + | |
| 9631 | - | -- no return needed, function exit so trees are grown |
| 9631 | + | |
| 9632 | return text | |
| 9633 | end | |
| 9634 | - | function lib.watchFarm(R) |
| 9634 | + | |
| 9635 | - | -- rotate to check if dirt on both sides |
| 9635 | + | |
| 9636 | - | -- R.subChoice == 1: 16 single trees, 2 = 4 doubles |
| 9636 | + | |
| 9637 | - | if R.logType ~= "mangrove" then |
| 9637 | + | |
| 9638 | - | R.treeSize = "single" |
| 9638 | + | |
| 9639 | - | T:turnRight(2) -- if no dirt then on 4 x doubles |
| 9639 | + | |
| 9640 | - | if T:getBlockType("forward") == "" then
|
| 9640 | + | |
| 9641 | - | R.treeSize = "double" |
| 9641 | + | |
| 9642 | info.main = {}
| |
| 9643 | - | T:saveToLog("lib.watchFarm: R.treeSize set to '"..R.treeSize.."'")
|
| 9643 | + | |
| 9644 | - | T:turnLeft(2) -- face lower left double dirt |
| 9644 | + | |
| 9645 | [[ ~lightGray~MINING:~white~ | |
| 9646 | - | lib.waitForGrowth(R) |
| 9646 | + | |
| 9647 | Ladders and ~lightGray~stairs up/down | |
| 9648 | - | return R |
| 9648 | + | |
| 9649 | mine at chosen level. | |
| 9650 | ~blue~Bubble lift and ~cyan~safe drop to water.~magenta~ | |
| 9651 | - | function lib.harvestSingle(direction, moves) |
| 9651 | + | |
| 9652 | - | -- if direction == "up": starting inside tree on dirt at dirt level |
| 9652 | + | |
| 9653 | - | T:saveToLog("lib.harvestSingle('"..direction.."', moves = "..moves)
|
| 9653 | + | |
| 9654 | the fuel and time) | |
| 9655 | - | while turtle.detectUp() do |
| 9655 | + | |
| 9656 | ]]) | |
| 9657 | table.insert(info.main, | |
| 9658 | [[ ~lime~FORESTRY:~brown~ | |
| 9659 | - | else -- direction = "down", but could be mid-tree |
| 9659 | + | |
| 9660 | - | local movesUp = 0 |
| 9660 | + | |
| 9661 | - | while turtle.detectUp() do |
| 9661 | + | |
| 9662 | or 4 double size (Dark oak or any type) | |
| 9663 | - | movesUp = movesUp + 1 |
| 9663 | + | |
| 9664 | ~brown~ fence or wall a rectangle keeping | |
| 9665 | - | T:down(movesUp) |
| 9665 | + | |
| 9666 | - | T:down(moves) |
| 9666 | + | |
| 9667 | (Must be walled off) | |
| 9668 | ||
| 9669 | ]]) | |
| 9670 | table.insert(info.main, | |
| 9671 | - | function lib.harvestSingleRow() |
| 9671 | + | |
| 9672 | - | -- start next to tree/dirt |
| 9672 | + | |
| 9673 | and placed next to each other in linear | |
| 9674 | - | local moves = lib.harvestSingle("up", 0)
|
| 9674 | + | |
| 9675 | - | T:go("F2")
|
| 9675 | + | |
| 9676 | - | lib.harvestSingle("down", moves)
|
| 9676 | + | |
| 9677 | - | T:go("F2")
|
| 9677 | + | |
| 9678 | - | moves = lib.harvestSingle("up", 0)
|
| 9678 | + | |
| 9679 | - | T:go("F2")
|
| 9679 | + | |
| 9680 | - | lib.harvestSingle("down", moves)
|
| 9680 | + | |
| 9681 | ]]) | |
| 9682 | table.insert(info.main, | |
| 9683 | - | function lib.harvestDouble() |
| 9683 | + | |
| 9684 | - | T:forward(1) -- dig dirt, move into left (S) corner |
| 9684 | + | |
| 9685 | lava areas safely.~pink~ | |
| 9686 | - | while turtle.detectUp() do |
| 9686 | + | |
| 9687 | - | turtle.dig() |
| 9687 | + | |
| 9688 | - | turtle.digUp() |
| 9688 | + | |
| 9689 | undermined ready for deactivating. | |
| 9690 | End world towers can have the crystals | |
| 9691 | destroyed.~red~ | |
| 9692 | - | turtle.dig() |
| 9692 | + | |
| 9693 | - | T:go("R1F1L1") -- move to right corner
|
| 9693 | + | |
| 9694 | ]]) | |
| 9695 | - | turtle.dig() |
| 9695 | + | |
| 9696 | - | turtle.digDown() |
| 9696 | + | |
| 9697 | Can be used in Nether and End.~lightGray~ | |
| 9698 | Build pathways over air, water or lava | |
| 9699 | - | turtle.dig() |
| 9699 | + | |
| 9700 | - | T:go("F1L1F1R1") -- move to left corner (N)
|
| 9700 | + | |
| 9701 | at the same time.~blue~ | |
| 9702 | Build a water canal with towpath.~cyan~ | |
| 9703 | - | --T:setUseLog(true, "treeFarmLog.txt", true) -- T:setUseLog(use, filename, delete) |
| 9703 | + | |
| 9704 | - | --dbug = true -- set dbug flag |
| 9704 | + | |
| 9705 | Sinking version is removed and replaced | |
| 9706 | 1 block lower each time | |
| 9707 | - | -- if on modem, R.networkFarm has already been set |
| 9707 | + | |
| 9708 | - | T:saveToLog("harvestTreeFarm(R) R.networkFarm = "..tostring(R.networkFarm))
|
| 9708 | + | |
| 9709 | [[ ~lightGray~SPAWNER FARMS:~brown~ | |
| 9710 | - | if R.networkFarm then |
| 9710 | + | |
| 9711 | - | local message = network.loadStorageLists() -- initialises or creates lists of where an item can be found: GLOBAL LISTS! |
| 9711 | + | |
| 9712 | - | if message ~= nil then return {message} end
|
| 9712 | + | |
| 9713 | - | network.emptyInventory(R, {"sapling", "propagule", "dirt"}, {"all"}, true)
|
| 9713 | + | |
| 9714 | Choice of bubble lift mob dropper | |
| 9715 | or ~brown~simple deep trench.~gray~ | |
| 9716 | - | if turtle.getFuelLevel() < turtle.getFuelLimit() / 2 then |
| 9716 | + | |
| 9717 | - | local turtleSlot, turtleCount = network.getItemFromNetwork("chest", "log", 16)
|
| 9717 | + | |
| 9718 | - | if turtleSlot > 0 then |
| 9718 | + | |
| 9719 | - | if turtle.craft() then |
| 9719 | + | |
| 9720 | ]]) | |
| 9721 | - | T:saveToLog("harvestTreeFarm(R) R.networkFarm = "..tostring(R.networkFarm))
|
| 9721 | + | |
| 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 | - | if R.networkFarm then -- monitor trees for growth |
| 9726 | + | |
| 9727 | - | if R.logType == "mangrove" then |
| 9727 | + | |
| 9728 | Carve away side of a mountain.~lightBlue~ | |
| 9729 | - | T:place("dirt", "up")
|
| 9729 | + | |
| 9730 | - | T:go("F6x2U1L1") -- move under dirt covering, clear roots from hopper, move level with dirt, face left
|
| 9730 | + | |
| 9731 | ||
| 9732 | - | T:go("F4R1") -- either in between 2 trees or in gap between double trees at dirt level
|
| 9732 | + | |
| 9733 | - | if turtle.detect() then -- single trees, move between 1st and 2nd rows |
| 9733 | + | |
| 9734 | - | T:go("R1F1 R1F2 R1F1 L1")
|
| 9734 | + | |
| 9735 | - | else -- using double trees |
| 9735 | + | |
| 9736 | - | T:go("R2F1")
|
| 9736 | + | |
| 9737 | - | if not turtle.detect() then |
| 9737 | + | |
| 9738 | - | return {"Unable to determine position"}
|
| 9738 | + | |
| 9739 | sand dropping and recycling~cyan~ | |
| 9740 | Destructive draining uses solid block | |
| 9741 | placing and recycling.~green~ | |
| 9742 | - | R = lib.watchFarm(R) -- wait for trees to grow, then start harvest |
| 9742 | + | |
| 9743 | damaging structures.~lightBlue~ | |
| 9744 | - | --logType, startHeight, R = lib.initialise(R) -- possible ID tree type + move to correct position 1 above dirt |
| 9744 | + | |
| 9745 | - | R, message = lib.initialise(R) -- possible ID tree type + move to correct position next to first dirt |
| 9745 | + | |
| 9746 | - | if message ~= "" then |
| 9746 | + | |
| 9747 | - | return{message}
|
| 9747 | + | |
| 9748 | [[ ~cyan~BUILDING, MINECART TOOLS:~lightGray~ | |
| 9749 | Build simple walls, buildings and ~gray~roofs | |
| 9750 | - | T:saveToLog("R.networkFarm = "..tostring(R.networkFarm)..", logType = "..R.logType..", treeSize = "..R.treeSize)
|
| 9750 | + | |
| 9751 | - | -- different clearing for different trees: |
| 9751 | + | |
| 9752 | - | -- double spruce and jungle: staight up/down or small |
| 9752 | + | |
| 9753 | - | if R.logType == "mangrove" then |
| 9753 | + | |
| 9754 | - | clearRectangle({width = 13, length = 13, up = true, down = true })
|
| 9754 | + | |
| 9755 | - | T:go("U2F2 R1F2L1")
|
| 9755 | + | |
| 9756 | - | clearSolid({width = 9, length = 9, height = 18, direction ="up"})
|
| 9756 | + | |
| 9757 | - | T:go("D3R1 F4R1 F3R2")
|
| 9757 | + | |
| 9758 | - | network.emptyInventory(R, {"sapling", "propagule", "dirt", "crafting"}, {"all"}, true)
|
| 9758 | + | |
| 9759 | - | elseif R.logType == "birch" or R.logType == "spruce" or R.logType == "jungle" then -- use column harvest |
| 9759 | + | |
| 9760 | - | if R.treeSize == "single" then |
| 9760 | + | |
| 9761 | - | lib.harvestSingleRow() |
| 9761 | + | |
| 9762 | - | T:go("F1R1F2R1")
|
| 9762 | + | |
| 9763 | - | lib.harvestSingleRow() |
| 9763 | + | |
| 9764 | - | T:go("F1L1F2L1")
|
| 9764 | + | |
| 9765 | - | lib.harvestSingleRow() |
| 9765 | + | |
| 9766 | - | T:go("F1R1F2R1")
|
| 9766 | + | |
| 9767 | - | lib.harvestSingleRow() |
| 9767 | + | |
| 9768 | - | if R.networkFarm then |
| 9768 | + | |
| 9769 | - | T:go("F1R1 F3L1 F3R2")
|
| 9769 | + | |
| 9770 | - | network.emptyInventory(R, {"sapling", "propagule", "dirt", "crafting"}, {"all"}, true)
|
| 9770 | + | |
| 9771 | ||
| 9772 | - | T:go("F1R1 F6L1 F3R2")
|
| 9772 | + | |
| 9773 | ||
| 9774 | info.sub[11] = | |
| 9775 | - | lib.harvestDouble() |
| 9775 | + | |
| 9776 | - | T:go("F3")
|
| 9776 | + | |
| 9777 | - | lib.harvestDouble() |
| 9777 | + | |
| 9778 | - | T:go("R1F4")
|
| 9778 | + | |
| 9779 | - | lib.harvestDouble() |
| 9779 | + | |
| 9780 | - | T:go("R1F4")
|
| 9780 | + | |
| 9781 | - | lib.harvestDouble() |
| 9781 | + | |
| 9782 | - | if R.networkFarm then |
| 9782 | + | |
| 9783 | - | T:go("F1R1 F3L1 F3R2")
|
| 9783 | + | |
| 9784 | - | network.emptyInventory(R, {"sapling", "propagule", "dirt", "crafting"}, {"all"}, true)
|
| 9784 | + | |
| 9785 | ||
| 9786 | - | T:go("F1R1 F6L1 F3R2")
|
| 9786 | + | |
| 9787 | info.sub[12] = | |
| 9788 | [[~lightGray~Place me on the ground at ~red~^ | |
| 9789 | - | else -- use cube harvest, including mangrove |
| 9789 | + | |
| 9790 | - | local size = 10 |
| 9790 | + | |
| 9791 | - | local start = "L1F1 L1F1 R2" |
| 9791 | + | |
| 9792 | - | local finish = "R1F1 R1F3 R2" |
| 9792 | + | |
| 9793 | - | if R.logType == "acacia" then |
| 9793 | + | |
| 9794 | - | size = 12 |
| 9794 | + | |
| 9795 | - | start = "L1F2 L1F2 R2" |
| 9795 | + | |
| 9796 | - | finish = "R1F2 R1F2 R2" |
| 9796 | + | |
| 9797 | - | elseif R.logType == "cherry" then |
| 9797 | + | |
| 9798 | - | size = 14 |
| 9798 | + | |
| 9799 | - | start = "L1F3 L1F3 R2" |
| 9799 | + | |
| 9800 | - | finish = "R1F3 R1F1 R2" |
| 9800 | + | |
| 9801 | [[~yellow~Press F3 to check Y level. | |
| 9802 | - | T:go("U1F1") -- into first log at base of tree
|
| 9802 | + | |
| 9803 | - | clearRectangle({width = 7, length = 7, up = true, down = true})
|
| 9803 | + | |
| 9804 | - | --T:go("L1F2 L1F2 R2") -- rect size 12
|
| 9804 | + | |
| 9805 | - | --T:go("L1F1 L1F1 R2") -- rect size 10
|
| 9805 | + | |
| 9806 | - | T:go(start) |
| 9806 | + | |
| 9807 | - | local height = 0 |
| 9807 | + | |
| 9808 | - | local pastLogCount = -1 |
| 9808 | + | |
| 9809 | - | local currentLogCount = lib.getLogCount() |
| 9809 | + | |
| 9810 | - | --while currentLogCount ~= pastLogCount do |
| 9810 | + | |
| 9811 | - | while currentLogCount - pastLogCount > 5 do -- ony continue if at least 5 logs harvested last round |
| 9811 | + | |
| 9812 | - | T:up(3) |
| 9812 | + | |
| 9813 | else | |
| 9814 | - | pastLogCount = currentLogCount -- 0 when loop starts |
| 9814 | + | |
| 9815 | - | --clearRectangle({width = 12, length = 12, up = true, down = true})
|
| 9815 | + | |
| 9816 | - | clearRectangle({width = size, length = size, up = true, down = true})
|
| 9816 | + | |
| 9817 | - | currentLogCount = lib.getLogCount() -- eg 20 logs from first round |
| 9817 | + | |
| 9818 | - | end |
| 9818 | + | |
| 9819 | - | T:down(height + 1) |
| 9819 | + | |
| 9820 | - | --T:go("R1F2 R1F2 R2") -- on polished stone rect size 12
|
| 9820 | + | |
| 9821 | - | --T:go("R1F1 R1F3 R2") -- on polished stone rect size 10
|
| 9821 | + | |
| 9822 | - | T:go(finish) |
| 9822 | + | |
| 9823 | - | if R.networkFarm then |
| 9823 | + | |
| 9824 | - | T:go("R1F3 L1") -- on modem
|
| 9824 | + | |
| 9825 | - | network.emptyInventory(R, {"sapling", "propagule", "dirt", "crafting"}, {"all"}, true)
|
| 9825 | + | |
| 9826 | ~lightGray~| | | | | | | |
| 9827 | ||
| 9828 | ]] -- safe drop | |
| 9829 | - | return {} -- if player initiated, stops here. If R.auto then returns to plantTreeFarm()
|
| 9829 | + | |
| 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 | - | local function upgradeFarmland(R) |
| 10123 | + | |
| 10124 | - | local essences = {":inferium", ":prudentium", ":tertium", ":imperium", ":supremium", ":awakened" , ":insanium"}
|
| 10124 | + | |
| 10125 | ||
| 10126 | ||
| 10127 | ||
| 10128 | - | function lib.isHigherTeir(essence, farmLand) |
| 10128 | + | |
| 10129 | - | -- eg "ma:prudentium_essence", "mc:farmland" |
| 10129 | + | |
| 10130 | - | local teir = 0 |
| 10130 | + | |
| 10131 | - | for index = 1, #essences do |
| 10131 | + | |
| 10132 | - | if farmLand:find(essences[index]) ~= nil then |
| 10132 | + | |
| 10133 | - | teir = index -- 0 if vanilla, else eg 2 for prudentium |
| 10133 | + | |
| 10134 | [[~yellow~Place turtle <64 blocks from shulker | |
| 10135 | Same level, or 1 block above/below | |
| 10136 | Plan view: | |
| 10137 | - | for index = 1, #essences do |
| 10137 | + | |
| 10138 | - | if essence:find(essences[index]) ~= nil then |
| 10138 | + | |
| 10139 | - | if index > teir then |
| 10139 | + | |
| 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 | - | function lib.upgrade(essence, slot) |
| 10147 | + | |
| 10148 | - | -- essence is the slot no of any essence |
| 10148 | + | |
| 10149 | - | turtle.select(slot) |
| 10149 | + | |
| 10150 | - | local blockType = T:getBlockType("up")
|
| 10150 | + | |
| 10151 | - | if blockType:find("farmland") ~= nil then -- farmland found (vanilla or modded)
|
| 10151 | + | |
| 10152 | - | if lib.isHigherTeir(essence, blockType) then -- eg "ma:inferium", mc:farmland" |
| 10152 | + | |
| 10153 | - | turtle.placeUp() |
| 10153 | + | |
| 10154 | ~gray~T | |
| 10155 | ~gray~> ~lime~S ~gray~< > T < = kill positions | |
| 10156 | ~lightGray~|*|*|*|*|*|*|*| | |
| 10157 | - | -- check if any essence still onboard |
| 10157 | + | |
| 10158 | - | T:checkInventoryForItem({"essence"}, {95}, false)
|
| 10158 | + | |
| 10159 | - | -- return slotData.lastSlot, total, slotData -- integer, integer, table |
| 10159 | + | |
| 10160 | - | local name = "" |
| 10160 | + | |
| 10161 | - | local slot, amount, data = T:getItemSlot("essence")
|
| 10161 | + | |
| 10162 | - | name = data.mostName or "" |
| 10162 | + | |
| 10163 | - | local empty = T:getFirstEmptySlot() |
| 10163 | + | |
| 10164 | ~lightGray~|*|~orange~+~lightGray~| |~lime~S|~red~+~lightGray~| | |~blue~+~lightGray~|*| T = turtle places | |
| 10165 | - | if slot > 0 then |
| 10165 | + | |
| 10166 | - | T:go("D2")
|
| 10166 | + | |
| 10167 | ~lightGray~|*|~orange~+|+|+|~red~+|~blue~+|+|+~lightGray~|*| |*|*|*|*|*| | |
| 10168 | - | for w = 1, 10 do |
| 10168 | + | |
| 10169 | - | for i = 1, 9 do |
| 10169 | + | |
| 10170 | - | if turtle.getItemCount(slot) == 0 then |
| 10170 | + | |
| 10171 | - | slot, amount, data = T:getItemSlot("essence")
|
| 10171 | + | |
| 10172 | - | name = data.mostName or "" |
| 10172 | + | |
| 10173 | - | if slot == 0 then |
| 10173 | + | |
| 10174 | - | slot = empty |
| 10174 | + | |
| 10175 | Face ~red~direction ~yellow~shown. It will exit up, | |
| 10176 | clear the roof above and return | |
| 10177 | - | lib.upgrade(name, slot) |
| 10177 | + | |
| 10178 | - | if w == 1 and i == 1 then |
| 10178 | + | |
| 10179 | - | T:go("F1R2 C1R2")
|
| 10179 | + | |
| 10180 | - | elseif w == 10 and i == 1 then |
| 10180 | + | |
| 10181 | - | |
| 10181 | + | |
| 10182 | ~lightGray~|*| | | | | | | | |*| | |
| 10183 | ~lightGray~|*|~red~V~lightGray~| | | | | | |~red~>~lightGray~|*| | |
| 10184 | ~lightGray~|*|*|*|*|*|*|*|*|*|*|]] -- Clear roof above | |
| 10185 | ||
| 10186 | info.sub[496] = | |
| 10187 | - | lib.upgrade(name, slot) |
| 10187 | + | |
| 10188 | - | if w == 1 then |
| 10188 | + | |
| 10189 | - | T:go("L1F1 L2C1 R1")
|
| 10189 | + | |
| 10190 | - | elseif w == 9 then |
| 10190 | + | |
| 10191 | - | T:go("L1F1 L1F1 L2C1 L2")
|
| 10191 | + | |
| 10192 | ~lightGray~|*|~red~<~lightGray~| | | | | | |~red~^~lightGray~|*| ~yellow~automatically. | |
| 10193 | ~lightGray~|*| | | | | | | | |*| | |
| 10194 | ||
| 10195 | ~lightGray~|*| | | | | | | | |*| | |
| 10196 | - | if w < 10 then |
| 10196 | + | |
| 10197 | - | lib.upgrade(name, slot) |
| 10197 | + | |
| 10198 | ||
| 10199 | info.sub[51] = | |
| 10200 | - | T:go("L1F1 L2C1 R2F8 L1U1 C2U2") -- 1 above normal position
|
| 10200 | + | |
| 10201 | ||
| 10202 | ~yellow~Start:~blue~ |-|-|-| - = air/water | |
| 10203 | ~orange~ |-|-|-| - = lava | |
| 10204 | ~blue~ |-|-|-| | |
| 10205 | - | -- sometimes original essence pops out of the ground when upgraded, so rescue it |
| 10205 | + | |
| 10206 | - | for w = 1, 10 do |
| 10206 | + | |
| 10207 | - | for i = 1, 9 do |
| 10207 | + | |
| 10208 | - | turtle.suckDown() |
| 10208 | + | |
| 10209 | - | turtle.suck() |
| 10209 | + | |
| 10210 | ~lightGray~ |*|*|*| * = Solid block | |
| 10211 | ]] -- Single path | |
| 10212 | info.sub[52] = | |
| 10213 | - | turtle.suckDown() |
| 10213 | + | |
| 10214 | - | turtle.suck() |
| 10214 | + | |
| 10215 | ~yellow~Plan view Face view | |
| 10216 | ||
| 10217 | - | if w < 10 then |
| 10217 | + | |
| 10218 | - | turtle.suckDown() |
| 10218 | + | |
| 10219 | - | turtle.suck() |
| 10219 | + | |
| 10220 | ~lightGray~|*|~green~*~lightGray~|*| *|*|~red~T~lightGray~|*|* ~red~^ T = Turtle | |
| 10221 | ~red~^~lightGray~ ~green~- - * - - ground | |
| 10222 | - | T:go("L1F9 L1D1") -- normal position
|
| 10222 | + | |
| 10223 | ~green~Floor + ceiling ~yellow~placed for your safety! | |
| 10224 | ]] -- Covered walkway / tunnel | |
| 10225 | info.sub[53] = | |
| 10226 | [[~yellow~plan view | |
| 10227 | ||
| 10228 | - | return ({"Farmland Upgraded"})
|
| 10228 | + | |
| 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 | - | function lib.askPlayerForCrops() |
| 10234 | + | |
| 10235 | - | local seed = "" |
| 10235 | + | |
| 10236 | - | pp.itemColours = {colors.lightGray, colors.red, colors.orange, colors.brown, colors.magenta, colors.yellow}
|
| 10236 | + | |
| 10237 | - | crops = {"minecraft:wheat_seeds", "minecraft:beetroot_seeds", "minecraft:carrots", "minecraft:potatoes", "mysticalagriculture", "none"}
|
| 10237 | + | |
| 10238 | - | choices = {"wheat (seeds)", "beetroot (seeds)", "carrot", "potato", "Mystical Agriculture", "Till soil only"}
|
| 10238 | + | |
| 10239 | ||
| 10240 | ~lightGray~ |*| | |*| * = Slab | |
| 10241 | - | if crop == "none" then |
| 10241 | + | |
| 10242 | - | return "", "" |
| 10242 | + | |
| 10243 | - | elseif crop == "mysticalagriculture" then |
| 10243 | + | |
| 10244 | - | T:checkInventoryForItem({"seeds"}, {95}, true, "Add one type of M. Agriculture seeds")
|
| 10244 | + | |
| 10245 | ~lightBlue~ 5 6 7 8 Convert water canal | |
| 10246 | - | T:checkInventoryForItem({crop}, {95}, true, "Do not mix! add as many as you want")
|
| 10246 | + | |
| 10247 | ~red~All turtles placed at ground level! | |
| 10248 | - | crop = T:getMostItem("", false) -- not searching for any specific item, not checking stone only
|
| 10248 | + | |
| 10249 | - | -- crop could be wheat/beetroot seeds, carrots, potatoes or mystical agriculture seeds |
| 10249 | + | |
| 10250 | - | seed, crop = lib.getCropSeed(crop) -- seed type or "", crop type |
| 10250 | + | |
| 10251 | - | return seed, crop |
| 10251 | + | |
| 10252 | ||
| 10253 | | | | | | | | | | |
| 10254 | - | function lib.assessPlot(R) |
| 10254 | + | |
| 10255 | - | local crop = T:getBlockType("forward") -- convert ma:inferium_crop to ma:inferium_seeds
|
| 10255 | + | |
| 10256 | - | local seed = lib.getCropSeed(crop) |
| 10256 | + | |
| 10257 | - | turtle.down() -- into water source |
| 10257 | + | |
| 10258 | - | local soil = T:getBlockType("forward")
|
| 10258 | + | |
| 10259 | - | turtle.up() -- at crop level |
| 10259 | + | |
| 10260 | - | return crop, seed, soil |
| 10260 | + | |
| 10261 | Blocks placed under the turtle | |
| 10262 | ]] -- Platform | |
| 10263 | - | function lib.checkEquipment(R, itemRequired) |
| 10263 | + | |
| 10264 | - | -- Check if item is equipped and return it to slot |
| 10264 | + | |
| 10265 | Existing platform replaced below | |
| 10266 | ||
| 10267 | - | local equipped, slot = T:getEquipped("right", false) -- see what is equipped and replace it
|
| 10267 | + | |
| 10268 | - | if equipped == itemRequired then |
| 10268 | + | |
| 10269 | - | equipped, slot = T:getEquipped("right", true) -- remove item and return slot
|
| 10269 | + | |
| 10270 | - | return slot |
| 10270 | + | |
| 10271 | | |~red~^~lightGray~|*|*|*|*| | ~red~^ = Turtle~lightGray~ | |
| 10272 | | | | | | | | | | |
| 10273 | - | return 0 -- not found |
| 10273 | + | |
| 10274 | Blocks placed under the turtle | |
| 10275 | ]] -- Sinking platform | |
| 10276 | - | function lib.crossFarm(R) |
| 10276 | + | |
| 10277 | [[~yellow~Boat Lift (Ice or Water) | |
| 10278 | Place turtle left side. ~blue~Source~yellow~ to right | |
| 10279 | - | local isReady, cropType, seed, status |
| 10279 | + | |
| 10280 | - | isReady, cropType, seed, status, R = lib.isCropReady(R,"down") |
| 10280 | + | |
| 10281 | - | -- will go forward until chest, barrel, modem or cobble detected below |
| 10281 | + | |
| 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 | - | elseif blockType:find("barrel") ~= nil or
|
| 10289 | + | |
| 10290 | - | blockType:find("chest") ~= nil or
|
| 10290 | + | |
| 10291 | - | blockType:find("modem") ~= nil or
|
| 10291 | + | |
| 10292 | - | blockType:find("cobble") ~= nil then
|
| 10292 | + | |
| 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 | - | return R, blockType -- either barrel, chest, modem or cobble |
| 10297 | + | |
| 10298 | T|*| | | | | |*|T * = Dungeon Wall | |
| 10299 | |*|*|*|*|*|*|*| ~orange~S = Spawner | |
| 10300 | - | function lib.farmAll(R, isFarmToRight, isFarmToFront) |
| 10300 | + | |
| 10301 | - | local plotCountR = 0 -- plot a1 harvested |
| 10301 | + | |
| 10302 | - | local plotCountF = 0 -- plot a1 harvested |
| 10302 | + | |
| 10303 | info.sub[62] = | |
| 10304 | - | while isFarmToRight do -- do all plots on this axis |
| 10304 | + | |
| 10305 | - | R, isFarmToRight = lib.farmToRight(R) -- plot harvested and back to plot origin |
| 10305 | + | |
| 10306 | - | plotCountR = plotCountR + 1 |
| 10306 | + | |
| 10307 | ~lightGray~|*|*|*|*|*|*|*|*| ~lime~> T = Continue build | |
| 10308 | - | lib.goToLeft(R, plotCountR) |
| 10308 | + | |
| 10309 | ~lightGray~|*| | | | | | | | | |
| 10310 | |*| | | |~purple~S~lightGray~| | | |~lime~>~red~< T | |
| 10311 | - | while isFarmToFront do -- do all plots on this axis |
| 10311 | + | |
| 10312 | - | plotCountR = 0 -- reset |
| 10312 | + | |
| 10313 | - | R, isFarmToRight, isFarmToFront = lib.farmInFront(R) |
| 10313 | + | |
| 10314 | - | if isFarmToRight then |
| 10314 | + | |
| 10315 | - | while isFarmToRight do -- do all plots on this axis |
| 10315 | + | |
| 10316 | - | R, isFarmToRight = lib.farmToRight(R) -- plot harvested and back to plot origin |
| 10316 | + | |
| 10317 | - | plotCountR = plotCountR + 1 |
| 10317 | + | |
| 10318 | ||
| 10319 | - | lib.goToLeft(R, plotCountR) -- return home and continue with front |
| 10319 | + | |
| 10320 | ~red~>~lightGray~|*| | | | |~purple~S~lightGray~| | | | |*|~red~<~lightGray~ |*| | | | |~purple~S~lightGray~| | |
| 10321 | - | plotCountF = plotCountF + 1 |
| 10321 | + | |
| 10322 | |*| | | | | | | | | |*| |*| | | | | | | |
| 10323 | - | lib.goToFront(R, plotCountF) |
| 10323 | + | |
| 10324 | |*| | | | | | | | | |*| |*| | | | | | | |
| 10325 | |*|*|*|*|*|*|*|*|*|*|*| ~red~T~lightGray~|*|*|*|*|*|*| | |
| 10326 | ~red~^ | |
| 10327 | - | function lib.farmInFront(R) |
| 10327 | + | |
| 10328 | ]] -- Flood spawner chamber | |
| 10329 | - | T:go("U1L1 F11D1 R1") -- on next farm, facing crops
|
| 10329 | + | |
| 10330 | - | local seed, crop = lib.manageTree(R) -- refuel, gather seeds or other crops |
| 10330 | + | |
| 10331 | |*| | | | | | | | | |*| | |
| 10332 | - | R, isFarmToRight = lib.harvest(R, seed, crop) -- harvest field, store crops |
| 10332 | + | |
| 10333 | - | return R, isFarmToRight |
| 10333 | + | |
| 10334 | ~brown~|~red~^~brown~|~lightGray~= Turtle on ~brown~Soul Sand | |
| 10335 | ||
| 10336 | - | function lib.farmToRight(R) |
| 10336 | + | |
| 10337 | |*| | | | |~brown~F~lightGray~| | | | |*| | |
| 10338 | - | T:go("U1F11 D1") -- on next farm, facing crops
|
| 10338 | + | |
| 10339 | - | local seed, crop = lib.manageTree(R) -- refuel, gather seeds and other crops |
| 10339 | + | |
| 10340 | - | R, isFarmToRight = lib.harvest(R, seed, crop) -- harvest field, store crops |
| 10340 | + | |
| 10341 | - | -- now at starting position of current plot |
| 10341 | + | |
| 10342 | - | return R, isFarmToRight |
| 10342 | + | |
| 10343 | [[~yellow~Computercraft mob grinder | |
| 10344 | ||
| 10345 | - | function lib.getCropSeed(crop) |
| 10345 | + | |
| 10346 | - | -- change growing crops into equivalent seed names |
| 10346 | + | |
| 10347 | - | -- crop could be seeds, so return equivalent crop |
| 10347 | + | |
| 10348 | - | local start = crop:find("_crop")
|
| 10348 | + | |
| 10349 | - | if start ~= nil then -- only modded seeds have "crop" |
| 10349 | + | |
| 10350 | - | return crop:sub(1, start).."seeds", crop |
| 10350 | + | |
| 10351 | |*|*|*|*|*|*|*|*|*|*|*| | |
| 10352 | - | if crop:find("seeds") ~= nil then -- asked to return crop from seed type
|
| 10352 | + | |
| 10353 | - | if crop:find("wheat") ~= nil then
|
| 10353 | + | |
| 10354 | - | return "minecraft:wheat_seeds", "minecraft:wheat" |
| 10354 | + | |
| 10355 | ]] -- Computercraft mob grinder | |
| 10356 | - | if crop:find("beetroot") ~= nil then
|
| 10356 | + | |
| 10357 | - | return "minecraft:beetroot_seeds", "minecraft:beetroot" |
| 10357 | + | |
| 10358 | 1.New tower lower base: place me on | |
| 10359 | flat ground in open plain. | |
| 10360 | - | if crop:find("wheat") ~= nil then
|
| 10360 | + | |
| 10361 | - | return "minecraft:wheat_seeds", "minecraft:wheat" |
| 10361 | + | |
| 10362 | the existing chest at tower base. | |
| 10363 | - | if crop:find("beetroot") ~= nil then
|
| 10363 | + | |
| 10364 | - | return "minecraft:beetroot_seeds", "minecraft:beetroot" |
| 10364 | + | |
| 10365 | mobs. Expensive, not recommended. | |
| 10366 | - | if crop:find("carrot") ~= nil then
|
| 10366 | + | |
| 10367 | - | return "", "minecraft:carrot" |
| 10367 | + | |
| 10368 | ||
| 10369 | info.sub[71] = | |
| 10370 | - | return "", "minecraft:potato" |
| 10370 | + | |
| 10371 | ||
| 10372 | - | -- planted crops are plural, harvested singular: carrots / carrot, pototoes/ potato |
| 10372 | + | |
| 10373 | - | return "", crop -- no seed for carrot / potato |
| 10373 | + | |
| 10374 | ~lightGray~| | | | | | Remove blocks > ground | |
| 10375 | | | | | | | | |
| 10376 | - | function lib.getHoe() |
| 10376 | + | |
| 10377 | |~red~^~lightGray~| | | | | ~red~^ ~lightGray~= Turtle position | |
| 10378 | - | if R.networkFarm then -- get hoe from storage |
| 10378 | + | |
| 10379 | - | hoeSlot = network.getItemFromNetwork("barrel", "minecraft:diamond_hoe", 1)
|
| 10379 | + | |
| 10380 | - | if hoeSlot == 0 then |
| 10380 | + | |
| 10381 | - | if T:checkInventoryForItem({"minecraft:diamond_hoe"}, {1}, true, "Diamond Hoe required for planting!") ~= nil then
|
| 10381 | + | |
| 10382 | - | hoeSlot = T:getItemSlot("minecraft:diamond_hoe")
|
| 10382 | + | |
| 10383 | [[~yellow~Clear rectangle | |
| 10384 | ||
| 10385 | - | else -- put crafting table into barrel in floor |
| 10385 | + | |
| 10386 | - | T:go("L1F1") -- over barrel
|
| 10386 | + | |
| 10387 | - | local isStorage, storageType = utils.isStorage("down")
|
| 10387 | + | |
| 10388 | - | if not isStorage then |
| 10388 | + | |
| 10389 | - | message = |
| 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 | - | instead. |
| 10395 | + | |
| 10396 | ||
| 10397 | info.sub[73] = | |
| 10398 | [[~yellow~Clear wall | |
| 10399 | - | return 0, message |
| 10399 | + | |
| 10400 | ~gray~T ~lightBlue~T | |
| 10401 | - | -- must be storage below to get this far |
| 10401 | + | |
| 10402 | - | T:suck("down") -- if hoe already in storage get it out
|
| 10402 | + | |
| 10403 | - | hoeSlot = T:getItemSlot("minecraft:diamond_hoe")
|
| 10403 | + | |
| 10404 | - | if hoeSlot == 0 then |
| 10404 | + | |
| 10405 | - | if T:checkInventoryForItem({"minecraft:diamond_hoe"}, {1}, true, "Diamond Hoe required for planting!") ~= nil then
|
| 10405 | + | |
| 10406 | - | hoeSlot = T:getItemSlot("minecraft:diamond_hoe")
|
| 10406 | + | |
| 10407 | ||
| 10408 | T = Turtle top / bottom/ inside / out | |
| 10409 | ~yellow~Bottom to top or top to bottom | |
| 10410 | - | return hoeSlot, "" |
| 10410 | + | |
| 10411 | info.sub[74] = | |
| 10412 | [[~yellow~Clear rectangle ~red~perimeter only | |
| 10413 | - | function lib.getSaplings(R, direction) |
| 10413 | + | |
| 10414 | ~yellow~Plan view | |
| 10415 | ~lightGray~| | | | | | Remove all blocks | |
| 10416 | ~lightGray~| |*|*|*| | Optional dig ~lime~up | |
| 10417 | ~lightGray~| |*|*|*| | Optional dig ~blue~down | |
| 10418 | - | if R.networkFarm then |
| 10418 | + | |
| 10419 | - | network.getItemFromNetwork("barrel", "sapling", 1)
|
| 10419 | + | |
| 10420 | - | --lib.getItemFromNetworkBarrels(R, "sapling", 1) |
| 10420 | + | |
| 10421 | ~red~ ^ | |
| 10422 | - | while T:suck(direction, 1) do end -- remove saplings/ seeds |
| 10422 | + | |
| 10423 | - | T:dropItem("sapling", direction, 1) -- drop all but 1 saplings
|
| 10423 | + | |
| 10424 | - | if not T:dropItem("seeds", direction, 0) then-- drop all seeds
|
| 10424 | + | |
| 10425 | - | T:dropItem("seeds", "up", 0)
|
| 10425 | + | |
| 10426 | [[~yellow~Demolish cube structure | |
| 10427 | Plan view Side view | |
| 10428 | ~gray~T ~lightBlue~T | |
| 10429 | - | return T:getItemSlot("sapling")
|
| 10429 | + | |
| 10430 | |*|*|*|*|*|*| |*|*|*|*|*|*| | |
| 10431 | |*|*|*|*|*|*| |*|*|*|*|*|*| | |
| 10432 | - | function lib.getSeeds(R, direction, seed) |
| 10432 | + | |
| 10433 | - | --[[ |
| 10433 | + | |
| 10434 | - | seed = name of growing crops seed or "" |
| 10434 | + | |
| 10435 | - | turtle facing crops on networked, else facing storage |
| 10435 | + | |
| 10436 | - | allow for other seeds from mods eg MysticalAgriculture |
| 10436 | + | |
| 10437 | - | get 1 stack of seeds of whatever type is being farmed |
| 10437 | + | |
| 10438 | info.sub[76] = info.sub[75] | |
| 10439 | - | if seed == "" then |
| 10439 | + | |
| 10440 | - | return "", 0 |
| 10440 | + | |
| 10441 | ||
| 10442 | - | local inventorySlot, seedCount = 0, 0 |
| 10442 | + | |
| 10443 | - | T:saveToLog("Collecting seeds from storage")
|
| 10443 | + | |
| 10444 | - | if R.networkFarm then |
| 10444 | + | |
| 10445 | - | inventorySlot, seedCount = network.getItemFromNetwork("chest", seed, 64)
|
| 10445 | + | |
| 10446 | | | | |
| 10447 | - | while T:suck(direction, 1) do end -- remove saplings/ seeds |
| 10447 | + | |
| 10448 | - | T:dropItem("sapling", direction, 0) -- drop all saplings
|
| 10448 | + | |
| 10449 | - | T:dropItem("seeds", direction, 64) -- drop all but 64 of any seed type
|
| 10449 | + | |
| 10450 | - | seedCount = T:getItemCount(seed) |
| 10450 | + | |
| 10451 | info.sub[78] = | |
| 10452 | - | if seedCount > 0 then |
| 10452 | + | |
| 10453 | - | T:saveToLog("planting " ..seed)
|
| 10453 | + | |
| 10454 | ||
| 10455 | - | return seed, seedCount -- could be: "", 0 or "minecraft:wheat_seeds", 64 |
| 10455 | + | |
| 10456 | ~gray~ |*~lightGray~|*| ~gray~|*~lightGray~|*|*|*| ~yellow~E | |
| 10457 | ~gray~ |*~lightGray~|*|*|*| ~gray~|*|*~lightGray~|*|*|*|*| ~yellow~N | |
| 10458 | - | function lib.getVeg(R, direction, crop) |
| 10458 | + | |
| 10459 | ~gray~ |*~lightGray~|*|*|*| ~red~^~gray~|*~lightGray~|*|*|*| ~yellow~T | |
| 10460 | - | -- local item, itemName, shortName, slot = "", "","", 0 |
| 10460 | + | |
| 10461 | - | local inventorySlot, cropCount = 0, 0 |
| 10461 | + | |
| 10462 | ~yellow~<--> no. of rows <--> | |
| 10463 | - | if R.networkFarm then |
| 10463 | + | |
| 10464 | - | inventorySlot, cropCount = network.getItemFromNetwork("chest", crop, 64)
|
| 10464 | + | |
| 10465 | [[~yellow~Place / Replace floor or ceiling | |
| 10466 | - | if not R.mysticalAgriculture then |
| 10466 | + | |
| 10467 | - | print("Collecting root crops from storage")
|
| 10467 | + | |
| 10468 | - | direction = direction or "forward" |
| 10468 | + | |
| 10469 | - | while T:suck(direction, 1) do end -- remove carrots / potatoes / wheat / beetroot / essence |
| 10469 | + | |
| 10470 | - | --item, itemName, shortName, slot = T:getFirstItem() |
| 10470 | + | |
| 10471 | - | local found = false |
| 10471 | + | |
| 10472 | - | if T:getItemSlot("potato") > 0 then
|
| 10472 | + | |
| 10473 | - | T:dropItem("potato", direction, 64) -- drop all but 65 potato
|
| 10473 | + | |
| 10474 | - | found = true |
| 10474 | + | |
| 10475 | - | crop = "minecraft:potato" |
| 10475 | + | |
| 10476 | ||
| 10477 | - | if T:getItemSlot("carrot") > 0 then
|
| 10477 | + | |
| 10478 | - | T:dropItem("carrot", direction, 64) -- drop all but 64 carrots
|
| 10478 | + | |
| 10479 | - | found = true |
| 10479 | + | |
| 10480 | - | crop = "minecraft:carrot" |
| 10480 | + | |
| 10481 | ||
| 10482 | - | if not found then |
| 10482 | + | |
| 10483 | - | T:dropAll(direction) -- drop everything back |
| 10483 | + | |
| 10484 | direction + ~blue~number ~yellow~eg ~white~f2 ~yellow~= forward ~blue~2 | |
| 10485 | ||
| 10486 | - | cropCount = T:getItemCount(crop) |
| 10486 | + | |
| 10487 | ~lime~l = left ~red~r = right | |
| 10488 | ~lightGray~u = up ~cyan~d = down | |
| 10489 | - | if cropCount > 0 then |
| 10489 | + | |
| 10490 | - | print("planting " ..crop)
|
| 10490 | + | |
| 10491 | info.sub[81] = | |
| 10492 | - | return crop, cropCount -- could be: "", 0 or "minecraft:potato", 64 |
| 10492 | + | |
| 10493 | ~yellow~Place me on water/lava surface | |
| 10494 | ||
| 10495 | - | function lib.goHome(R) |
| 10495 | + | |
| 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 | - | lib.harvestTree(R, "forward") -- will only harvest if fuel below half of limit |
| 10501 | + | |
| 10502 | - | onTree = true -- end on dirt |
| 10502 | + | |
| 10503 | ]] -- Sand based utilities | |
| 10504 | - | lib.harvestTree(R, "up") -- end on dirt |
| 10504 | + | |
| 10505 | [[~yellow~Turtle position ~red~> T ~gray~(~red~V ~gray~to enclose) | |
| 10506 | - | elseif T:getItemSlot("log") > 0 then-- tree just harvested
|
| 10506 | + | |
| 10507 | ~blue~|~red~>~blue~| | | | | | ~yellow~to ~lightGray~|*|*|*|*|*|~red~V~lightGray~|~gray~ enclose | |
| 10508 | ~gray~* area | |
| 10509 | ~yellow~Side view | |
| 10510 | - | lib.harvestTree(R, "up") -- end on dirt |
| 10510 | + | |
| 10511 | ~blue~| | | | | | | ~yellow~to ~lightGray~|*|*|*|*|*|*| | |
| 10512 | - | while turtle.down() do end -- end on dirt |
| 10512 | + | |
| 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 | - | if onTree then |
| 10516 | + | |
| 10517 | - | local success, storage = false, "" |
| 10517 | + | |
| 10518 | - | -- tree harvested, sitting on dirt, but direction unknown |
| 10518 | + | |
| 10519 | - | T:down(1) -- dig dirt, go down |
| 10519 | + | |
| 10520 | - | -- if storage type farm chest/barrel will give position |
| 10520 | + | |
| 10521 | - | for turns = 1, 4 do |
| 10521 | + | |
| 10522 | ~yellow~e ~lightGray~|*| | | | |*| | |
| 10523 | - | success, storage = utils.isStorage("forward")
|
| 10523 | + | |
| 10524 | ~yellow~g ~lightGray~|*| | | | |*| | |
| 10525 | - | T:go("L2U1")
|
| 10525 | + | |
| 10526 | - | T:place("dirt", "down")
|
| 10526 | + | |
| 10527 | - | T:go("B1R1 F1D1R1")
|
| 10527 | + | |
| 10528 | - | R.ready = true |
| 10528 | + | |
| 10529 | ||
| 10530 | ]] -- Create enclosed area | |
| 10531 | info.sub[84] = | |
| 10532 | - | -- if networked will be in air 2 blocks above barrel or stone |
| 10532 | + | |
| 10533 | ||
| 10534 | - | T:place("dirt", "up")
|
| 10534 | + | |
| 10535 | - | T:down(1) --should be on corner |
| 10535 | + | |
| 10536 | - | for turns = 1, 4 do |
| 10536 | + | |
| 10537 | |*~blue~| | | | | | |~lightGray~*| | |
| 10538 | - | success, storage = utils.isStorage("down")
|
| 10538 | + | |
| 10539 | - | if storage == "modem" then |
| 10539 | + | |
| 10540 | - | T:go("R1F1D1")
|
| 10540 | + | |
| 10541 | - | R.ready = true |
| 10541 | + | |
| 10542 | |*|*|*|*|*|*|*|*| ~yellow~Width~blue~: ~yellow~6, ~orange~length~blue~:~orange~ 6 | |
| 10543 | ||
| 10544 | - | T:go("B1R1")
|
| 10544 | + | |
| 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 | - | return R -- R.ready == false |
| 10550 | + | |
| 10551 | ****** ****** ~lime~< ^ > ~lightGray~Ideal facing~lightGray~ | |
| 10552 | ****** ****** | |
| 10553 | - | function lib.goToLeft(R, plotCountR) |
| 10553 | + | |
| 10554 | - | T:go("U1R2 F"..plotCountR * 11 .."D1R2") -- return home and continue with front
|
| 10554 | + | |
| 10555 | - | if R.config ~= nil then |
| 10555 | + | |
| 10556 | - | local coord = R.config.currentPlot |
| 10556 | + | |
| 10557 | - | for i = 1, plotCountR do |
| 10557 | + | |
| 10558 | - | coord = lib.configUpdateCoords(R, coord, "left") |
| 10558 | + | |
| 10559 | ||
| 10560 | - | R.config.currentPlot = coord |
| 10560 | + | |
| 10561 | [[~yellow~Turtle positions ~red~> ^ < V | |
| 10562 | ||
| 10563 | ~lightGray~|*|~red~>~lightGray~|*|*|*|*|*|~red~<~lightGray~|*| ~red~NOT ~lightGray~corner blocks! | |
| 10564 | - | function lib.goToFront(R, plotCountF) |
| 10564 | + | |
| 10565 | - | T:go("U1R1F"..plotCountF * 11 .."D1L1")
|
| 10565 | + | |
| 10566 | - | if R.config ~= nil then |
| 10566 | + | |
| 10567 | - | local coord = R.config.currentPlot |
| 10567 | + | |
| 10568 | - | for i = 1, plotCountF do |
| 10568 | + | |
| 10569 | - | coord = lib.configUpdateCoords(R, coord, "back") |
| 10569 | + | |
| 10570 | |~red~^~lightGray~| |~red~^~lightGray~| ~yellow~with stone.~lightGray~ | |
| 10571 | - | R.config.currentPlot = coord |
| 10571 | + | |
| 10572 | ]] -- Ocean monument build retaining walls | |
| 10573 | ||
| 10574 | info.sub[863] = | |
| 10575 | - | function lib.gotoTree(R) |
| 10575 | + | |
| 10576 | ||
| 10577 | - | if not R.networkFarm then |
| 10577 | + | |
| 10578 | - | T:turnRight(1) -- face storage |
| 10578 | + | |
| 10579 | ~lightGray~|~red~>~cyan~| ***** ***** |~red~<~lightGray~| | |
| 10580 | - | T:saveToLog("Extracting saplings from storage")
|
| 10580 | + | |
| 10581 | - | lib.getSaplings(R, "forward") -- gets one sapling only (if present) |
| 10581 | + | |
| 10582 | - | T:saveToLog("Moving to tree position")
|
| 10582 | + | |
| 10583 | - | if R.networkFarm then |
| 10583 | + | |
| 10584 | - | T:turnRight(1) -- face wall next to corner barrel |
| 10584 | + | |
| 10585 | |*|*|*|*|*|*|*|*|*|*| | |
| 10586 | - | T:go("U1F1R1") -- move on top of wall/storage. face tree direction
|
| 10586 | + | |
| 10587 | info.sub[864] = info.sub[863] | |
| 10588 | - | -- check if tree or dirt ahead |
| 10588 | + | |
| 10589 | - | if turtle.forward() then -- No tree or sapling ahead. assume tree is missing or 2 blocks above |
| 10589 | + | |
| 10590 | - | if T:getBlockType("down") == "minecraft:dirt" then
|
| 10590 | + | |
| 10591 | - | turtle.back() -- older design, return |
| 10591 | + | |
| 10592 | ~green~|*|*|*|*|*~brown~|*|*|*|~red~V~brown~|*| | |
| 10593 | ~green~|~red~>~green~|- - - - ~brown~- - - -|*| | |
| 10594 | - | if turtle.detectUp() then -- dirt above = new tree layout |
| 10594 | + | |
| 10595 | - | if T:getBlockType("up") == "minecraft:dirt" then
|
| 10595 | + | |
| 10596 | - | T:go("B1U2") -- check tree in elevated position
|
| 10596 | + | |
| 10597 | ~orange~|*|- - - - ~lime~- - - -|*| ~lightGray~6 chests / area | |
| 10598 | - | turtle.back() -- not dirt above ? removed or lost |
| 10598 | + | |
| 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 | - | lib.harvestTree(R, "forward") -- fell tree or plant sapling, ends facing tree / dirt / sapling. sticks already used for fuel. excess saplings placed |
| 10603 | + | |
| 10604 | - | T:go("R1F1D1R1") -- return to base, facing crops
|
| 10604 | + | |
| 10605 | - | if R.networkFarm then |
| 10605 | + | |
| 10606 | - | network.sendItemToNetworkStorage(R, "barrel", "sapling", 64) --move saplings to any attached barrel |
| 10606 | + | |
| 10607 | ~red~- ~blue~- ~red~- ~blue~- ~red~- ~blue~- ~red~- ~red~- ~blue~- ~red~-~lightGray~|*|- ~blue~- ~red~- | |
| 10608 | - | T:turnRight(1) -- facing plot storage |
| 10608 | + | |
| 10609 | - | T:saveToLog("Dropping saplings into storage")
|
| 10609 | + | |
| 10610 | - | T:dropItem("sapling", "forward", 0) -- drop all saplings forward into chest/barrel
|
| 10610 | + | |
| 10611 | |*|*|*|*|*|*|*| |*|*|*|*|*|*|*| | |
| 10612 | ||
| 10613 | - | -- ends in field facing crops |
| 10613 | + | |
| 10614 | ~brown~L ~lightGray~= Ladder | |
| 10615 | ||
| 10616 | - | function lib.harvest(R, seed, crop) |
| 10616 | + | |
| 10617 | info.sub[88] = | |
| 10618 | [[~yellow~Place ~red~T~yellow~urtle at water edge. | |
| 10619 | - | harvest crop if ripe |
| 10619 | + | |
| 10620 | ||
| 10621 | ~red~T T | |
| 10622 | ~lightGray~|*|*| ~blue~| | | | | | | | | | ~lightGray~|*| | |
| 10623 | - | crop is full name. if mixed seeds only one type returned |
| 10623 | + | |
| 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 | - | lib.replant(R, seed, crop) -- check and replant crop below |
| 10633 | + | |
| 10634 | info.sub[810] = | |
| 10635 | [[Place me on the left corner of the top | |
| 10636 | of retaining wall facing water. | |
| 10637 | - | if utils.isStorage("down") then -- chest, barrel or modem
|
| 10637 | + | |
| 10638 | selected length | |
| 10639 | ]] -- Create sloping water | |
| 10640 | ||
| 10641 | -- Building and railway | |
| 10642 | info.sub[91] = | |
| 10643 | [[~yellow~Build a wall | |
| 10644 | ||
| 10645 | - | lib.replant(R, seed, crop) -- check and replant crop below |
| 10645 | + | |
| 10646 | ||
| 10647 | ~red~>~lightGray~| | | | | | | |*|*|*|*|*|*| | |
| 10648 | |*|*|*|*|*|*| | |
| 10649 | |*|*|*|*|*|*| | |
| 10650 | |*|*|*|*|*|*| | |
| 10651 | - | lib.replant(R, seed, crop) |
| 10651 | + | |
| 10652 | ||
| 10653 | ~red~> T~lightGray~ = Turtle | |
| 10654 | ||
| 10655 | ]] -- Build a wall | |
| 10656 | - | if utils.isStorage("down") then
|
| 10656 | + | |
| 10657 | [[~yellow~Build a walled rectangle / house | |
| 10658 | ||
| 10659 | Plan view Side view | |
| 10660 | - | lib.storeCrops(R) -- rotates from start to deposit seeds and crops, ends facing crops |
| 10660 | + | |
| 10661 | - | return R, isFarmToRight, isFarmToFront |
| 10661 | + | |
| 10662 | ~yellow~e ~lightGray~|*| | | | |*| |*|*|*|*|*|*| | |
| 10663 | ~yellow~n ~lightGray~|*| | | | |*| |*|*|*|*|*|*| | |
| 10664 | - | function lib.harvestTree(R, direction) |
| 10664 | + | |
| 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 | - | Return to top of storage |
| 10670 | + | |
| 10671 | [[~yellow~Build a gable roof | |
| 10672 | Gable built on right side of turtle | |
| 10673 | Plan view End view (width) | |
| 10674 | - | local inFront = T:getBlockType("forward")
|
| 10674 | + | |
| 10675 | - | print("Checking tree")
|
| 10675 | + | |
| 10676 | - | if inFront == "" then -- no tree or sapling |
| 10676 | + | |
| 10677 | - | print("No sapling: planting sapling")
|
| 10677 | + | |
| 10678 | - | T:place("sapling", "forward")
|
| 10678 | + | |
| 10679 | - | elseif inFront:find("log") ~= nil or direction == "up" then -- tree above or in front
|
| 10679 | + | |
| 10680 | - | -- clsTurtle.harvestTree(self, extend, craftChest, direction) |
| 10680 | + | |
| 10681 | - | print("Harvesting tree")
|
| 10681 | + | |
| 10682 | - | T:harvestTree(false, false, direction) --do not investigate side branches in case chunk unloaded |
| 10682 | + | |
| 10683 | - | T:back(1) -- face dirt |
| 10683 | + | |
| 10684 | - | -- place(self, blockType, direction, leaveExisting, signText) |
| 10684 | + | |
| 10685 | - | T:place("sapling", "forward")
|
| 10685 | + | |
| 10686 | Plan view End view (width) | |
| 10687 | - | print("Disposing of apples")
|
| 10687 | + | |
| 10688 | - | T:dropItem("apple", "up", 0) -- drop any apples
|
| 10688 | + | |
| 10689 | - | utils.useSticksAsFuel() |
| 10689 | + | |
| 10690 | ~yellow~e ~lightGray~|*| | |*| |*|*|*|*| | |
| 10691 | - | while turtle.down() do end -- ends facing tree, on top of plot storage |
| 10691 | + | |
| 10692 | ~yellow~g ~lightGray~|*| | |*| |*|*|*|*| | |
| 10693 | ~yellow~t ~lightGray~|*| | |*| | |
| 10694 | - | function lib.manageTree(R) |
| 10694 | + | |
| 10695 | ~yellow~ W i d t h ~red~^ T ~lightGray~= Turtle | |
| 10696 | - | local isReady, crop, seed, status, R = lib.isCropReady(R, "forward") |
| 10696 | + | |
| 10697 | - | if crop == "" and not R.auto then -- only ask player if not running via startup |
| 10697 | + | |
| 10698 | - | seed, crop = lib.askPlayerForCrops() -- "" or specific seed type, |
| 10698 | + | |
| 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 | - | T:saveToLog("Running Tree Manager")
|
| 10713 | + | |
| 10714 | - | lib.gotoTree(R) -- check for sapling or harvest tree, retuns to facing crops |
| 10714 | + | |
| 10715 | Build down Build up~lightGray~ | |
| 10716 | ||
| 10717 | _____~red~T~lightGray~ ___ | |
| 10718 | - | if logSlot > 0 then --logs onboard, need to equip crafting table |
| 10718 | + | |
| 10719 | - | if R.networkFarm then |
| 10719 | + | |
| 10720 | - | lib.refuelWithLogs(R, logSlot) -- use any logs for fuel |
| 10720 | + | |
| 10721 | |*|__________~red~T~lightGray~|*| | |
| 10722 | - | T:go("L1F1") -- move to buried storage chest/barrel
|
| 10722 | + | |
| 10723 | - | lib.refuelWithLogs(R, logSlot) -- use any logs for fuel |
| 10723 | + | |
| 10724 | - | T:go("R2F1") -- facing seed chest/barrel
|
| 10724 | + | |
| 10725 | info.sub[98] = info.sub[97] | |
| 10726 | ||
| 10727 | - | if not R.networkFarm then |
| 10727 | + | |
| 10728 | info.sub[101] = | |
| 10729 | [[~yellow~Place me on floor.~lightGray~ | |
| 10730 | Measured Height: | |
| 10731 | - | -- get seeds or veg based on what is growing |
| 10731 | + | |
| 10732 | - | if seed ~= "" then |
| 10732 | + | |
| 10733 | - | local seedType, seedCount = lib.getSeeds(R, "forward", seed) -- table: get 95 of beetroot / wheat / mysticalagriculture seeds |
| 10733 | + | |
| 10734 | - | if seedCount == 0 then |
| 10734 | + | |
| 10735 | - | T:saveToLog("No seeds available.")
|
| 10735 | + | |
| 10736 | |*|*|*| | |
| 10737 | - | else -- seed = "" |
| 10737 | + | |
| 10738 | - | local veg, vegCount = "", 0 |
| 10738 | + | |
| 10739 | - | if R.networkFarm then |
| 10739 | + | |
| 10740 | - | veg, vegCount = lib.getVeg(R, "forward", crop) -- gets any carrots / potatoes |
| 10740 | + | |
| 10741 | info.sub[102] = | |
| 10742 | - | T:turnRight(1) -- face crop chests |
| 10742 | + | |
| 10743 | - | veg, vegCount = lib.getVeg(R, "forward", crop) -- gets any carrots / potatoes |
| 10743 | + | |
| 10744 | - | T:turnRight(2) -- face crops |
| 10744 | + | |
| 10745 | ~red~T~lightGray~ | |
| 10746 | - | if veg ~= "" then |
| 10746 | + | |
| 10747 | - | crop = veg |
| 10747 | + | |
| 10748 | 3|*|*| | |
| 10749 | 4|*|*| Measured depth: | |
| 10750 | 5|*|~lime~S~lightGray~| ~lime~5. Specific block found | |
| 10751 | - | return seed, crop -- name of seed / "", crop / "" |
| 10751 | + | |
| 10752 | 7|*|*|~lightBlue~*~lightGray~|*| | ~lightBlue~6. Obstruction below | |
| 10753 | ]] -- measure depth | |
| 10754 | - | function lib.isCropReady(R, direction) |
| 10754 | + | |
| 10755 | [[~yellow~Length measurement | |
| 10756 | ||
| 10757 | ~lightGray~1 2 3 4 ~lime~5~lightGray~ 6 ~lime~7 ~cyan~8 ~lightBlue~9~lightGray~ 10 | |
| 10758 | - | local crop, seed = "", "" |
| 10758 | + | |
| 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 | - | --T:saveToLog("lib.isCropReady(R,".. direction..")")
|
| 10768 | + | |
| 10769 | - | if success then -- inspect() success |
| 10769 | + | |
| 10770 | - | crop = data.name -- name of growing plant |
| 10770 | + | |
| 10771 | - | if crop:find("flower") ~= nil then
|
| 10771 | + | |
| 10772 | - | T:saveToLog("Flower "..crop.." found")
|
| 10772 | + | |
| 10773 | - | return true, crop, "open" -- eg torchflower |
| 10773 | + | |
| 10774 | ||
| 10775 | - | if data.name:find("beetroot") ~= nil then
|
| 10775 | + | |
| 10776 | - | status = data.state.age.." / 3" |
| 10776 | + | |
| 10777 | - | if data.state.age == 3 then |
| 10777 | + | |
| 10778 | - | isReady = true |
| 10778 | + | |
| 10779 | ]] -- Borehole: Analyse blocks below | |
| 10780 | - | else -- all other crops inc Mystical Agriculture |
| 10780 | + | |
| 10781 | - | status = data.state.age.." / 7" |
| 10781 | + | |
| 10782 | - | if data.state.age == 7 then |
| 10782 | + | |
| 10783 | - | isReady = true |
| 10783 | + | |
| 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 | - | seed, crop = lib.getCropSeed(crop) |
| 10787 | + | |
| 10788 | ~lightGray~|~orange~1~lightGray~|~orange~2~lightGray~|~orange~3~lightGray~|~orange~4~lightGray~| ground 4 | |
| 10789 | - | --T:saveToLog("return isReady = "..tostring(isReady)..", crop = "..crop..", seed = "..seed..", status = "..status)
|
| 10789 | + | |
| 10790 | - | -- crop: "", "minecraft:carrots", "minecraft:beetroot", "minecraft:potatoes", "minecraft:wheat", "mysticalagriculture:*_crop" |
| 10790 | + | |
| 10791 | - | return isReady, crop, seed, status, R -- eg true, "minecraft:carrots", "7 / 7" or false, "mysticalagriculture:inferium_crop", "1 / 7" |
| 10791 | + | |
| 10792 | local line = menu.clear() | |
| 10793 | if menuLevel == 1 then -- general help | |
| 10794 | - | function lib.locateFarm(R) |
| 10794 | + | |
| 10795 | - | T:saveToLog("? over water = false")
|
| 10795 | + | |
| 10796 | read() | |
| 10797 | return "" | |
| 10798 | - | detected = i |
| 10798 | + | |
| 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 | - | T:saveToLog("Neighbouring blocks detected at: "..detected)
|
| 10802 | + | |
| 10803 | - | -- check if on corner |
| 10803 | + | |
| 10804 | - | if detected > 0 then |
| 10804 | + | |
| 10805 | - | --assume tree / sapling on corner on older farm type |
| 10805 | + | |
| 10806 | - | T:saveToLog("Assuming next to tree / sapling. Moving..")
|
| 10806 | + | |
| 10807 | - | T:go("R"..detected .."F1D1R1")
|
| 10807 | + | |
| 10808 | - | else -- no surrounding blocks |
| 10808 | + | |
| 10809 | end | |
| 10810 | else | |
| 10811 | - | success, storage = utils.isStorage("down")
|
| 10811 | + | |
| 10812 | - | T:saveToLog("i = "..i..",success = "..tostring(success)..". storage = "..storage)
|
| 10812 | + | |
| 10813 | return read() | |
| 10814 | - | discovered = discovered .. storage |
| 10814 | + | |
| 10815 | - | if storage == "modem" then |
| 10815 | + | |
| 10816 | - | R.networkFarm = true |
| 10816 | + | |
| 10817 | end | |
| 10818 | ||
| 10819 | - | if storage == "" then |
| 10819 | + | |
| 10820 | - | discovered = discovered .. "_" |
| 10820 | + | |
| 10821 | options.main = | |
| 10822 | - | discovered = discovered .. "wall" |
| 10822 | + | |
| 10823 | "Mining (includes Nether)", | |
| 10824 | "Forestry", | |
| 10825 | "Farming", | |
| 10826 | "Obsidian, Nether & End", | |
| 10827 | "Canal, bridge and walkway", | |
| 10828 | - | T:saveToLog("Neighbouring blocks found:"..discovered)
|
| 10828 | + | |
| 10829 | "Area shaping and clearing", | |
| 10830 | - | -- check discovered for patterns eg {_wall_barrel}
|
| 10830 | + | |
| 10831 | - | -- |W|*|B| * = turtle on wall |
| 10831 | + | |
| 10832 | - | -- | | |M| |
| 10832 | + | "Measuring tools" |
| 10833 | - | if R.networkFarm then |
| 10833 | + | |
| 10834 | - | -- E = wall_barrel_, N = _barrel_wall, W = wall_barrel_, S = _wall_barrel |
| 10834 | + | |
| 10835 | - | if discovered == "_wall_barrel" then |
| 10835 | + | |
| 10836 | - | T:go("F1D1R1")
|
| 10836 | + | |
| 10837 | - | elseif discovered == "barrel_wall_" then |
| 10837 | + | |
| 10838 | "Create mine at this level", | |
| 10839 | - | elseif discovered == "_barrel_wall" then |
| 10839 | + | |
| 10840 | - | T:go("R2F1D1R1")
|
| 10840 | + | |
| 10841 | - | elseif discovered == "wall_barrel_" then |
| 10841 | + | |
| 10842 | - | T:go("L1F1D1R1")
|
| 10842 | + | |
| 10843 | "Mine bedrock level", | |
| 10844 | - | else -- normal storage farm |
| 10844 | + | |
| 10845 | - | if discovered == "_chest_chest" then |
| 10845 | + | |
| 10846 | - | T:go("F1D1R1")
|
| 10846 | + | |
| 10847 | - | elseif discovered == "chest__chest" then |
| 10847 | + | |
| 10848 | "Fell Tree", | |
| 10849 | - | elseif discovered == "_chest_chest" then |
| 10849 | + | "Create tree farm", |
| 10850 | - | T:go("R2F1D1R1")
|
| 10850 | + | |
| 10851 | - | elseif discovered == "chest_chest_" then |
| 10851 | + | |
| 10852 | - | T:go("L1F1D1R1")
|
| 10852 | + | |
| 10853 | "Harvest and replant forest" | |
| 10854 | }) | |
| 10855 | table.insert(options, | |
| 10856 | {
| |
| 10857 | "Create modular crop farm", | |
| 10858 | - | success, storage = utils.isStorage("forward") -- true/false, chest, barrel, modem / ""
|
| 10858 | + | |
| 10859 | - | if success and storage == "modem" then |
| 10859 | + | "Plant, harvest or manage crop farm", |
| 10860 | - | R.networkFarm = true |
| 10860 | + | |
| 10861 | "Fence or wall an enclosure" | |
| 10862 | }) | |
| 10863 | table.insert(options, | |
| 10864 | - | R.ready = true |
| 10864 | + | |
| 10865 | "Dig obsidian field", | |
| 10866 | "Build Nether Portal", | |
| 10867 | "Demolish Nether Portal", | |
| 10868 | - | function lib.plantCrop(R, seed, crop, direction) |
| 10868 | + | |
| 10869 | "Undermine Dragon Towers", | |
| 10870 | "Deactivate Dragon Tower", | |
| 10871 | "Build dragon water trap", | |
| 10872 | "Build portal ladder & platform", | |
| 10873 | "Shulker harvester" | |
| 10874 | - | --T:saveToLog("lib.plantCrop(R, seed = "..seed..", crop = "..crop)
|
| 10874 | + | |
| 10875 | table.insert(options, | |
| 10876 | - | -- place(blockType, direction, leaveExisting, signText, doNotAttack) |
| 10876 | + | |
| 10877 | - | if seed == "" then -- must be a crop |
| 10877 | + | |
| 10878 | - | success = T:place(crop, direction, true, "", true) |
| 10878 | + | |
| 10879 | - | --success = T:place(crop, direction, false, "", true) |
| 10879 | + | |
| 10880 | - | --T:saveToLog("Seed = "..seed..". Placing "..crop..": success = "..tostring(success))
|
| 10880 | + | |
| 10881 | "Platform", | |
| 10882 | - | success = T:place(seed, direction, true, "", true) -- eg "mysticalagriculture:air_seeds" |
| 10882 | + | |
| 10883 | - | --success = T:place(seed, direction, false, "", true) -- eg "mysticalagriculture:air_seeds" |
| 10883 | + | |
| 10884 | - | --T:saveToLog("Placing "..seed..": success = "..tostring(success))
|
| 10884 | + | |
| 10885 | table.insert(options, | |
| 10886 | - | if not success then |
| 10886 | + | |
| 10887 | - | success = T:place("seed", direction, true, "", true) -- failsafe
|
| 10887 | + | |
| 10888 | - | --success = T:place("seed", direction, false, "", true) -- failsafe
|
| 10888 | + | |
| 10889 | - | --T:saveToLog("Placing generic 'seeds' : success = "..tostring(success))
|
| 10889 | + | |
| 10890 | "Create mob bubble lift", | |
| 10891 | - | return success |
| 10891 | + | |
| 10892 | "Build Endermen observation tower" | |
| 10893 | }) | |
| 10894 | - | function lib.replant(R, seed, crop) |
| 10894 | + | |
| 10895 | - | -- check crop below. If ripe, dig and replant seed |
| 10895 | + | |
| 10896 | - | local isReady, cropType, seedType, status |
| 10896 | + | |
| 10897 | - | isReady, cropType, seedType, status, R = lib.isCropReady(R, "down") -- eg true, "minecraft:carrots", "7 / 7" or false, "", "" |
| 10897 | + | |
| 10898 | - | if cropType == "" then -- no crop below (above water, storage or dirt) |
| 10898 | + | |
| 10899 | - | turtle.digDown("right") -- use hoe
|
| 10899 | + | |
| 10900 | - | lib.plantCrop(R, seed, crop, "down")-- plant crop |
| 10900 | + | |
| 10901 | - | elseif isReady then -- crop below is ready |
| 10901 | + | |
| 10902 | - | turtle.digDown("left") -- use pickaxe
|
| 10902 | + | |
| 10903 | - | lib.plantCrop(R, seedType, cropType, "down") -- plant crop |
| 10903 | + | |
| 10904 | "Place a floor or ceiling", | |
| 10905 | "Direct control of movement" | |
| 10906 | - | return R |
| 10906 | + | |
| 10907 | table.insert(options, | |
| 10908 | {
| |
| 10909 | - | function lib.refuelWithLogs(R, logSlot) |
| 10909 | + | |
| 10910 | - | -- saplings already dropped, apples dumped, sticks used as fuel |
| 10910 | + | |
| 10911 | - | -- assume positioned in front of crops if networked, or over buried storage |
| 10911 | + | |
| 10912 | "Clear volume of water", | |
| 10913 | "Sinking platform", | |
| 10914 | - | -- networked version uses remote storage, turtle faces crops and has modem at back |
| 10914 | + | |
| 10915 | - | local slot, count = 0, 0 |
| 10915 | + | |
| 10916 | - | T:saveToLog("Sorting Inventory") -- make sure all items collected together
|
| 10916 | + | |
| 10917 | - | T:sortInventory(true) |
| 10917 | + | |
| 10918 | - | T:saveToLog("Logs present: collecting crafting table")
|
| 10918 | + | |
| 10919 | - | if R.networkFarm then |
| 10919 | + | |
| 10920 | - | slot, count = network.getItemFromNetwork("barrel", "minecraft:crafting_table", 1)
|
| 10920 | + | |
| 10921 | - | --slot = lib.getItemFromNetworkBarrels(R, "minecraft:crafting_table", 1) |
| 10921 | + | |
| 10922 | "Build a wall", | |
| 10923 | - | while T:suck("down") do end -- empty out barrel/chest to find crafting table
|
| 10923 | + | |
| 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 | - | if R.networkFarm then |
| 10929 | + | |
| 10930 | - | network.sendItemToNetworkStorage(R, "barrel", "minecraft:diamond_hoe", 1) |
| 10930 | + | |
| 10931 | table.insert(options, | |
| 10932 | {
| |
| 10933 | "Measure height", | |
| 10934 | - | T:drop("down", i) -- into water if networked, buried chest otherwise
|
| 10934 | + | |
| 10935 | "Measure length", | |
| 10936 | "Measure greatest depth", | |
| 10937 | "Borehole: Analyse blocks below" | |
| 10938 | }) | |
| 10939 | ||
| 10940 | return options | |
| 10941 | end | |
| 10942 | ||
| 10943 | - | while logSlot > 0 and turtle.getFuelLevel() < turtle.getFuelLimit() do |
| 10943 | + | |
| 10944 | local options = {}
| |
| 10945 | - | turtle.refuel() -- refuel using planks |
| 10945 | + | |
| 10946 | {
| |
| 10947 | colors.lightGray, -- Mining (includes Nether) | |
| 10948 | - | while T:suck("down") do end -- recover items from water / storage below
|
| 10948 | + | |
| 10949 | - | --T:unequip("right")
|
| 10949 | + | |
| 10950 | - | if R.networkFarm then |
| 10950 | + | |
| 10951 | - | slot = network.getItemFromNetwork("barrel", "minecraft:diamond_hoe", 1)
|
| 10951 | + | |
| 10952 | colors.lightGray, -- Mob farm tools | |
| 10953 | - | if not T:equip("right", "minecraft:diamond_hoe") then -- re-equip hoe/remove crafting table
|
| 10953 | + | |
| 10954 | colors.blue, -- Lava and Water | |
| 10955 | colors.cyan, -- Railway | |
| 10956 | - | if R.networkFarm then |
| 10956 | + | colors.purple -- Measuring tools |
| 10957 | - | network.sendItemToNetworkStorage(R, "barrel", "minecraft:crafting_table", 1) |
| 10957 | + | |
| 10958 | table.insert(options, | |
| 10959 | - | T:dropItem("minecraft:crafting_table", "down")
|
| 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 | - | function lib.storeCrops(R) |
| 10967 | + | |
| 10968 | - | -- place crops and seeds into chests. starts facing crops |
| 10968 | + | |
| 10969 | }) | |
| 10970 | table.insert(options, | |
| 10971 | - | if R.networkFarm then |
| 10971 | + | |
| 10972 | - | network.emptyInventory(R, {"sapling", "diamond_hoe", "crafting"}, {"all"}, true)
|
| 10972 | + | |
| 10973 | colors.lightGray, -- Create tree farm | |
| 10974 | - | T:turnRight(1) -- face seed storage |
| 10974 | + | |
| 10975 | - | lib.storeSeeds(R, "forward") |
| 10975 | + | |
| 10976 | colors.brown, -- Fence or wall an enclosure | |
| 10977 | - | if utils.isStorage(direction) then |
| 10977 | + | |
| 10978 | - | T:dropAll(direction) -- drops everything including essences |
| 10978 | + | |
| 10979 | table.insert(options, | |
| 10980 | - | T:turnRight(2) -- facing crops again |
| 10980 | + | |
| 10981 | colors.yellow, -- Create modular crop farm | |
| 10982 | colors.green, -- Extend modular crop farm | |
| 10983 | colors.lime, -- Manage modular crop farm | |
| 10984 | - | function lib.storeSeeds(R, direction) |
| 10984 | + | |
| 10985 | colors.brown -- Build rectangle wall or fence | |
| 10986 | - | if utils.isStorage(direction) then -- chest exists |
| 10986 | + | |
| 10987 | - | if not R.networkFarm then |
| 10987 | + | |
| 10988 | - | if T:getItemSlot("minecraft:wheat_seeds") > 0 then
|
| 10988 | + | |
| 10989 | - | if not T:dropItem("minecraft:wheat_seeds", direction, 0) then
|
| 10989 | + | |
| 10990 | - | T:dropItem("minecraft:wheat_seeds", "up", 0)
|
| 10990 | + | |
| 10991 | - | end -- drop all wheat seeds |
| 10991 | + | |
| 10992 | - | elseif T:getItemSlot("minecraft:beetroot_seeds") > 0 then
|
| 10992 | + | |
| 10993 | - | if not T:dropItem("minecraft:beetroot_seeds", direction, 0) then-- drop all beetroot seeds
|
| 10993 | + | |
| 10994 | - | T:dropItem("minecraft:beetroot_seeds", "up", 0)
|
| 10994 | + | |
| 10995 | colors.blue, -- Build dragon water trap | |
| 10996 | - | elseif T:getItemSlot("seeds") > 0 then
|
| 10996 | + | |
| 10997 | - | if not T:dropItem("seeds", direction, 0) then -- drop all other seeds as chest is full
|
| 10997 | + | |
| 10998 | - | T:dropItem("seeds", "up", 0)
|
| 10998 | + | |
| 10999 | - | -- or could print a message and wait for player to empty storage |
| 10999 | + | |
| 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 | - | function lib.watchFarm(R) |
| 11006 | + | |
| 11007 | colors.cyan -- Boat bubble lift | |
| 11008 | }) | |
| 11009 | table.insert(options, | |
| 11010 | {
| |
| 11011 | colors.brown, -- Cube around spawner (NOT blaze) | |
| 11012 | - | local isReady, crop, seed, status -- bool, string, string, integer |
| 11012 | + | |
| 11013 | - | isReady, crop, seed, status, R = lib.isCropReady(R, "forward") -- eg true, "minecraft:carrots", "7 / 7" or false, "", "" |
| 11013 | + | |
| 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 | - | if crop:find("mysticalagriculture") ~= nil then
|
| 11023 | + | |
| 11024 | - | R.mysticalAgriculture = true |
| 11024 | + | |
| 11025 | colors.orange, -- Clear solid structure up/down | |
| 11026 | colors.brown, -- Dig a trench | |
| 11027 | colors.gray, -- Carve mountain side | |
| 11028 | - | isReady, crop, seed, status, R = lib.isCropReady(R, "forward") -- eg true, "minecraft:carrots", "7 / 7" or false, "", "" |
| 11028 | + | |
| 11029 | colors.red -- Direct control of movement | |
| 11030 | - | until isReady |
| 11030 | + | |
| 11031 | - | T:saveToLog("Local crops ripe", true)
|
| 11031 | + | |
| 11032 | - | seed, crop = lib.manageTree(R) -- "", "" or name of seed, crop |
| 11032 | + | |
| 11033 | - | return seed, crop |
| 11033 | + | |
| 11034 | colors.blue, -- Vertical wall from surface | |
| 11035 | colors.blue, -- Create enclosed area | |
| 11036 | colors.cyan, -- Clear volume of water | |
| 11037 | - | ENTRY POINT********************************************** |
| 11037 | + | |
| 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 | - | --T:setUseLog(true, "farmLog.txt", true) -- T:setUseLog(use, filename, delete) |
| 11045 | + | |
| 11046 | - | --dbug = true -- set dbug flag |
| 11046 | + | |
| 11047 | - | --if not R.auto then -- not running from startup.lua |
| 11047 | + | |
| 11048 | - | --utils.waitForInput("Logging and debugging enabled") --utils.waitForInput(message)
|
| 11048 | + | |
| 11049 | - | --end |
| 11049 | + | |
| 11050 | colors.red, -- Place Redstone:torch level track | |
| 11051 | - | R = utils.checkFarmPosition(R) -- should be facing crops, placed above water source. R.ready, R.networkFarm is true/false |
| 11051 | + | |
| 11052 | - | if R.networkFarm then |
| 11052 | + | |
| 11053 | - | local message = network.loadStorageLists() -- initialises or creates lists of where an item can be found: GLOBAL LISTS! |
| 11053 | + | |
| 11054 | - | if message ~= nil then return {message} end
|
| 11054 | + | |
| 11055 | table.insert(options, | |
| 11056 | - | if not R.ready then -- not in correct starting place |
| 11056 | + | |
| 11057 | - | R = lib.goHome(R) |
| 11057 | + | |
| 11058 | - | if not R.ready then -- try to find home |
| 11058 | + | |
| 11059 | colors.magenta, -- Measure length | |
| 11060 | colors.pink, -- Measure greatest depth | |
| 11061 | colors.lightBlue -- Borehole: Analyse blocks below | |
| 11062 | }) | |
| 11063 | ||
| 11064 | - | "barrel or chest to my right and behind", |
| 11064 | + | |
| 11065 | - | "(or modem behind if networked farm)" |
| 11065 | + | |
| 11066 | ||
| 11067 | local function chooseTask(R) | |
| 11068 | --[[ | |
| 11069 | - | if not T:isEmpty() then -- items in turtle inventory |
| 11069 | + | |
| 11070 | - | local logSlot = T:getItemSlot("log")
|
| 11070 | + | |
| 11071 | coloured menu: | |
| 11072 | - | if R.networkFarm then |
| 11072 | + | |
| 11073 | - | lib.refuelWithLogs(R, logSlot) -- use any logs for fuel |
| 11073 | + | |
| 11074 | prompt = colors.green, | |
| 11075 | - | T:go("L1F1") -- move to buried storage chest/barrel
|
| 11075 | + | |
| 11076 | - | lib.refuelWithLogs(R, logSlot) -- use any logs for fuel |
| 11076 | + | |
| 11077 | - | T:go("R2F1") -- facing seed chest/barrel
|
| 11077 | + | |
| 11078 | choice, modifier = menu.menu or menu.new("Choose your option", options, pp)
| |
| 11079 | ]] | |
| 11080 | - | if not T:isEmpty() then -- still items in turtle inventory |
| 11080 | + | |
| 11081 | - | lib.storeCrops(R) |
| 11081 | + | |
| 11082 | function lib.getHelp(choice, itemsRequired, pp) | |
| 11083 | local listOfItems = itemsRequired[choice] | |
| 11084 | - | -- in correct position. Check equipment first, harvest tree, re-equip then harvest crops |
| 11084 | + | |
| 11085 | - | local hoeSlot = lib.checkEquipment(R, "minecraft:diamond_hoe") -- returns slot or 0 |
| 11085 | + | |
| 11086 | lib.showItems(listOfItems) | |
| 11087 | - | if hoeSlot == 0 then -- hoe not in inventory |
| 11087 | + | |
| 11088 | - | local message |
| 11088 | + | |
| 11089 | - | hoeSlot, message = lib.getHoe() |
| 11089 | + | |
| 11090 | - | if message ~= "" then |
| 11090 | + | |
| 11091 | - | return {message}
|
| 11091 | + | |
| 11092 | if option == 2 then | |
| 11093 | choice = -2 -- return to subMenu | |
| 11094 | - | -- hoe present or user cancelled request for hoe. Turtle is ready to exchange items |
| 11094 | + | |
| 11095 | - | if hoeSlot > 0 then |
| 11095 | + | |
| 11096 | - | T:equip("right", "minecraft:diamond_hoe", 0) -- equip hoe and put crafting chest into barrel
|
| 11096 | + | |
| 11097 | - | if R.networkFarm then -- drop crafting table into storage |
| 11097 | + | |
| 11098 | - | network.sendItemToNetworkStorage(R, "barrel", "minecraft:crafting_table", 1) |
| 11098 | + | |
| 11099 | - | else -- put crafting table into barrel in floor |
| 11099 | + | |
| 11100 | - | T:dropItem("crafting", "down")
|
| 11100 | + | |
| 11101 | - | T:go("B1R1")
|
| 11101 | + | |
| 11102 | end | |
| 11103 | - | else -- hoe not present: return to start and exit |
| 11103 | + | |
| 11104 | - | if not R.networkFarm then |
| 11104 | + | |
| 11105 | - | T:go("B1R1")
|
| 11105 | + | |
| 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 | - | local isFarmToRight, isFarmToFront = false, false |
| 11111 | + | |
| 11112 | - | local isReady, crop, seed, status |
| 11112 | + | |
| 11113 | - | isReady, crop, seed, status, R = lib.isCropReady(R, "forward") |
| 11113 | + | |
| 11114 | menu.colourWrite("Enter to continue", colors.yellow, colors.black, nil, true)
| |
| 11115 | - | local init = false |
| 11115 | + | |
| 11116 | end | |
| 11117 | - | seed, crop = lib.askPlayerForCrops() |
| 11117 | + | |
| 11118 | - | if crop ~= "" or seed ~= "" then -- something has been chosen |
| 11118 | + | |
| 11119 | - | T:saveToLog("Initial planting of "..crop, true)
|
| 11119 | + | |
| 11120 | - | R, isFarmToRight, isFarmToFront = lib.harvest(R, seed, crop) -- harvest plot a1 plots to right / front recorded |
| 11120 | + | |
| 11121 | - | init = true |
| 11121 | + | |
| 11122 | ||
| 11123 | - | watch = false -- not watching, continue with planting |
| 11123 | + | |
| 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 | - | if watch and not init then -- init true when farm first planted |
| 11127 | + | |
| 11128 | - | seed, crop = lib.watchFarm(R) -- waits if required, returns seed / crop |
| 11128 | + | |
| 11129 | - | init = false |
| 11129 | + | |
| 11130 | end | |
| 11131 | - | T:saveToLog("Beginning "..crop.. " management", true)
|
| 11131 | + | |
| 11132 | - | R, isFarmToRight, isFarmToFront = lib.harvest(R, seed, crop) -- harvest plot a1 plots to right / front recorded |
| 11132 | + | |
| 11133 | - | lib.farmAll(R, isFarmToRight, isFarmToFront) |
| 11133 | + | |
| 11134 | local prompt = "Choose an option" | |
| 11135 | - | if R.networkFarm then |
| 11135 | + | |
| 11136 | - | T:unequip("right") -- unequip hoe
|
| 11136 | + | |
| 11137 | - | network.getItemFromNetwork("barrel", "minecraft:crafting_table", 1)
|
| 11137 | + | |
| 11138 | - | network.sendItemToNetworkStorage(R, "barrel", "minecraft:diamond_hoe", 1) |
| 11138 | + | |
| 11139 | - | T:equip("right", "minecraft:crafting_table", 0) -- equip crafting_table
|
| 11139 | + | |
| 11140 | local menuState = 0 -- use main menu | |
| 11141 | - | T:go("L1F1")
|
| 11141 | + | |
| 11142 | - | while T:suck("down") do end -- recover items from storagebelow
|
| 11142 | + | |
| 11143 | - | T:equip("right", "minecraft:crafting_table", 0) -- equip crafting_table
|
| 11143 | + | |
| 11144 | - | T:dropItem("minecraft:diamond_hoe", "down") -- drop hoe into storage
|
| 11144 | + | |
| 11145 | - | T:dropItem("crafting", "down") -- in case spare one picked by mistake
|
| 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 | - | --local pp = utils.getPrettyPrint() |
| 11190 | + | |
| 11191 | - | local choices = {"Plant or harvest this farm complex"} -- 1.
|
| 11191 | + | |
| 11192 | R.choice = -1 | |
| 11193 | return R | |
| 11194 | elseif index == 0 then | |
| 11195 | - | table.insert(choices, "Disable automatic farm management") -- 2. |
| 11195 | + | |
| 11196 | menuState = 0 -- if R.choice reset to 0 then back to main menu | |
| 11197 | - | table.insert(choices, "Enable automatic farm management") -- 2. |
| 11197 | + | |
| 11198 | end | |
| 11199 | if subChoice ~= nil then | |
| 11200 | - | if not R.networkFarm then |
| 11200 | + | |
| 11201 | - | table.insert(choices, "Convert to Network Storage") -- 3. |
| 11201 | + | |
| 11202 | - | table.insert(pp.itemColours, colors.magenta) |
| 11202 | + | |
| 11203 | end | |
| 11204 | - | if R.mysticalAgriculture then |
| 11204 | + | |
| 11205 | - | --table.insert(choices, "Convert to Mystical Agriculture") |
| 11205 | + | |
| 11206 | - | table.insert(choices, "Upgrade Mystical Agriculture soil") --3/4 |
| 11206 | + | |
| 11207 | - | table.insert(pp.itemColours, colors.green) |
| 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 | - | elseif R.subChoice == 2 then -- enable/disable auto farm |
| 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 | - | --elseif R.subChoice == 3 and #choices == 4 then -- convert normal farm to network storage |
| 11245 | + | |
| 11246 | - | elseif R.subChoice == 3 then -- convert normal farm to network storage |
| 11246 | + | |
| 11247 | - | local isMain = false |
| 11247 | + | |
| 11248 | "On ceiling, move forward to start"} | |
| 11249 | - | local message = ("~yellow~You have chosen to convert this farm "..
|
| 11249 | + | |
| 11250 | - | "to ~magenta~network storage ~yellow~with modems.".. |
| 11250 | + | |
| 11251 | - | "All ~brown~chests and barrels ~red~will be removed.\n") |
| 11251 | + | |
| 11252 | - | line = menu.colourText(line, message, true, true) |
| 11252 | + | |
| 11253 | - | if menu.getBoolean("Is this the main or only plot? (y/n)", line + 3, colors.orange, colors.black) then
|
| 11253 | + | |
| 11254 | - | isMain = true |
| 11254 | + | |
| 11255 | R.width = menu.getInteger("Width (2-64 default 17) ", 2, 64, nil, colors.yellow, nil, 17)
| |
| 11256 | - | T:checkInventoryForItem({"stone"}, {16})
|
| 11256 | + | |
| 11257 | - | T:checkInventoryForItem({"dirt"}, {2})
|
| 11257 | + | |
| 11258 | if mcMajorVersion >= 1.18 then | |
| 11259 | - | T:checkInventoryForItem({"barrel"}, {1})
|
| 11259 | + | |
| 11260 | - | T:checkInventoryForItem({"ladder"}, {5})
|
| 11260 | + | |
| 11261 | - | if isMain then |
| 11261 | + | |
| 11262 | - | T:checkInventoryForItem({"chest"}, {8})
|
| 11262 | + | |
| 11263 | - | T:checkInventoryForItem({"wired_modem_full"}, {3})
|
| 11263 | + | |
| 11264 | - | T:checkInventoryForItem({"computercraft:cable"}, {70})
|
| 11264 | + | |
| 11265 | - | return createFarm(R, "convertWithStorage") |
| 11265 | + | |
| 11266 | "On ceiling, move forward to start", | |
| 11267 | - | T:checkInventoryForItem({"wired_modem_full"}, {2})
|
| 11267 | + | |
| 11268 | - | T:checkInventoryForItem({"computercraft:cable"}, {57})
|
| 11268 | + | |
| 11269 | - | return createFarm(R, "convert") |
| 11269 | + | |
| 11270 | if modifier == "q" then -- quit chosen | |
| 11271 | - | --elseif R.subChoice == 3 and #choices == 3 then -- upgrade farmland with essence (network opt not present) |
| 11271 | + | |
| 11272 | - | --elseif R.subChoice == 3 and #choices == 3 then -- upgrade farmland with essence (network opt not present) |
| 11272 | + | |
| 11273 | - | --return upgradeFarmland(R) |
| 11273 | + | |
| 11274 | - | elseif R.subChoice == 4 then -- upgrade farmland with essence |
| 11274 | + | |
| 11275 | - | return upgradeFarmland(R) |
| 11275 | + | |
| 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 | - | T:place(R.useBlockType, "forward", false) |
| 11642 | + | |
| 11643 | R.length = menu.getInteger("Length of the area (1-64)", 1, 64, nil, colors.orange)
| |
| 11644 | - | T:place("minecraft:redstone_torch", "forward", true)
|
| 11644 | + | |
| 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 | - | T:place("minecraft:redstone_torch", "up", false)
|
| 11658 | + | |
| 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 | - | -- already known R.networkFarm, R.subChoice (1 = singe, 2 = double, 3 = mangrove) |
| 11669 | + | |
| 11670 | - | --T:place(blockType, damageNo, leaveExisting, signText) |
| 11670 | + | |
| 11671 | T:forward(1) | |
| 11672 | elseif choice == 4 then | |
| 11673 | - | function lib.checkSaplings(firstChoice, secondChoice) |
| 11673 | + | |
| 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 | - | function lib.emptyInventory(R) |
| 11685 | + | |
| 11686 | - | if not T:isEmpty() then |
| 11686 | + | |
| 11687 | - | utils.useSticksAsFuel() |
| 11687 | + | |
| 11688 | - | network.sendItemToNetworkStorage(R, "barrel", "sapling", 64) |
| 11688 | + | |
| 11689 | - | network.sendItemToNetworkStorage(R, "barrel", "propagule", 64) |
| 11689 | + | |
| 11690 | - | network.sendItemToNetworkStorage(R, "barrel", "apple", 64) |
| 11690 | + | |
| 11691 | - | network.sendItemToNetworkStorage(R, "barrel", "dirt", 64) |
| 11691 | + | |
| 11692 | - | network.sendItemToNetworkStorage(R, "chest", "all", 0) |
| 11692 | + | |
| 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 | - | function lib.getSaplingInventory(R) |
| 11696 | + | |
| 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 | - | saplings.cherry_sapling = 0 |
| 11704 | + | |
| 11705 | - | saplings.mangrove_propagule = 0 |
| 11705 | + | |
| 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 | - | if T:getItemSlot("sapling") > 0 then
|
| 11711 | + | |
| 11712 | - | for i = 1, 16 do |
| 11712 | + | |
| 11713 | - | if turtle.getItemCount(i) > 0 then |
| 11713 | + | |
| 11714 | - | local data = turtle.getItemDetail(i) |
| 11714 | + | |
| 11715 | - | if data.name:find("sapling") ~= nil then
|
| 11715 | + | |
| 11716 | - | local name = data.name:sub(11) -- removes "minecraft:" |
| 11716 | + | |
| 11717 | - | saplings[name] = saplings[name] + data.count |
| 11717 | + | |
| 11718 | T:go("D1F1")
| |
| 11719 | end | |
| 11720 | end | |
| 11721 | - | elseif T:getItemSlot("propagule") > 0 then
|
| 11721 | + | |
| 11722 | - | saplings.mangrove_propagule = turtle.getItemCount(T:getItemSlot("propagule"))
|
| 11722 | + | |
| 11723 | - | else -- no saplings onBoard: ? automated networked farm |
| 11723 | + | |
| 11724 | - | if R.networkFarm then |
| 11724 | + | |
| 11725 | - | -- networked farms use 1 type of sapling indicated by log embedded to right of modem |
| 11725 | + | |
| 11726 | - | -- discovered from utils.assessTreeFarm() on manual Startup |
| 11726 | + | |
| 11727 | - | if R.auto then -- called here as NOT manual startup |
| 11727 | + | |
| 11728 | - | R = utils.assessTreeFarm(R) |
| 11728 | + | |
| 11729 | - | if R.message ~= "" then |
| 11729 | + | |
| 11730 | - | return {R.message} -- location of turtle error
|
| 11730 | + | |
| 11731 | "New floor over existing", | |
| 11732 | "Replacing current ceiling", | |
| 11733 | - | local turtleSlot, turtleCount = network.getItemFromNetwork("barrel", R.useBlockType, 16)
|
| 11733 | + | |
| 11734 | - | if turtleCount == 0 then -- ask player for saplings |
| 11734 | + | |
| 11735 | - | T:checkInventoryForItem({R.useBlockType}, {16}, true, "Saplings required for tree farm")
|
| 11735 | + | |
| 11736 | R.height = menu.getInteger({"Enter 0 for on-site placement",
| |
| 11737 | - | saplings[R.useBlockType] = saplings[R.useBlockType] + turtleCount |
| 11737 | + | |
| 11738 | - | turtleSlot, turtleCount = network.getItemFromNetwork("barrel", "minecraft:dirt", 16)
|
| 11738 | + | |
| 11739 | - | if turtleCount == 0 then |
| 11739 | + | |
| 11740 | - | turtleSlot, turtleCount = network.getItemFromNetwork("chest", "minecraft:dirt", 16)
|
| 11740 | + | |
| 11741 | R.width = menu.getInteger("Width of floor (1-64) ", 1, 64, nil, colors.yellow)
| |
| 11742 | - | if turtleCount == 0 then -- ask player |
| 11742 | + | |
| 11743 | - | T:checkInventoryForItem({"minecraft:dirt"}, {16}, true, "Dirt required for tree farm")
|
| 11743 | + | |
| 11744 | R.up = true | |
| 11745 | - | return saplings, R.useBlockType, R.useBlockType |
| 11745 | + | |
| 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 | - | T:place("dirt", "down", false, "", true)
|
| 11768 | + | |
| 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 | - | T:place(sapling, "down", false, "", true) |
| 11774 | + | |
| 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 | - | T:place(sapling, "down", false, "", true) |
| 11778 | + | |
| 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 | - | T:place("dirt", "down", false, "", true)
|
| 11795 | + | |
| 11796 | R.data = "withPath" -- ensures turtle will break through path | |
| 11797 | - | if not T:place(sapling, "down", false, "", true) then -- try specific sapling |
| 11797 | + | |
| 11798 | - | T:place("sapling", "down", false, "", true) -- any available sapling
|
| 11798 | + | |
| 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 | - | function lib.getMangroveSupplies() |
| 11811 | + | |
| 11812 | - | local turtleSlot, turtleCount = network.getItemFromNetwork("barrel", "minecraft:dirt", 169)
|
| 11812 | + | |
| 11813 | - | if turtleCount < 169 then |
| 11813 | + | |
| 11814 | - | turtleSlot, turtleCount = network.getItemFromNetwork("chest", "minecraft:dirt", 169 - turtleCount)
|
| 11814 | + | |
| 11815 | - | if turtleCount < 169 then -- ask player for saplings |
| 11815 | + | |
| 11816 | - | T:checkInventoryForItem({"dirt"}, {169 - turtleCount})
|
| 11816 | + | |
| 11817 | "Build 4 corner marker columns", | |
| 11818 | "Retaining wall beween 2 columns", | |
| 11819 | - | turtleSlot, turtleCount = network.getItemFromNetwork("barrel", "minecraft:mangrove_propagule", 25)
|
| 11819 | + | |
| 11820 | - | if turtleCount == 0 then -- ask player for saplings |
| 11820 | + | |
| 11821 | - | T:checkInventoryForItem({"mangrove_propagule"}, {25}, true, "Mangrove propagules required")
|
| 11821 | + | |
| 11822 | "Sinking platform", | |
| 11823 | "Drain and remove structure" | |
| 11824 | } | |
| 11825 | - | function lib.plantMangrove() |
| 11825 | + | |
| 11826 | - | T:go("L1F6 R1F1 U1")
|
| 11826 | + | |
| 11827 | - | createFloorCeiling({width = 13, length = 13, up = false, down = true,
|
| 11827 | + | |
| 11828 | - | height = 0, subChoice = 0, useBlockType = "minecraft:dirt", |
| 11828 | + | |
| 11829 | - | inventory = T:getInventory()}) |
| 11829 | + | |
| 11830 | menu.clear() | |
| 11831 | - | --T:go("U1F5 R1F5 L1") -- lower left of planting area, facing Back
|
| 11831 | + | |
| 11832 | - | T:go("U1F4 R1F4 L1") -- lower left of planting area, facing Back
|
| 11832 | + | |
| 11833 | - | for x = 1, 5 do |
| 11833 | + | |
| 11834 | - | for i = 1, 5 do |
| 11834 | + | |
| 11835 | - | T:place("propagule", "down") -- left 1
|
| 11835 | + | |
| 11836 | - | if i < 5 then |
| 11836 | + | |
| 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 | - | if x % 2 == 1 then |
| 11840 | + | |
| 11841 | - | if x < 5 then |
| 11841 | + | |
| 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 | - | T:go("L1F2 L1F2 D2U2 F7R2 D2")
|
| 11848 | + | |
| 11849 | elseif R.subChoice == 5 then -- remove sand wall using sand utilities | |
| 11850 | - | T:place("propagule", "down") -- left 1
|
| 11850 | + | |
| 11851 | R.length = 0 | |
| 11852 | - | T:place("propagule", "down") -- left 2
|
| 11852 | + | |
| 11853 | R.width = menu.getInteger("Width (excluding retaining wall)? ", 1, 1024, nil, colors.yellow)
| |
| 11854 | - | T:place("propagule", "down") -- left 3/top 1
|
| 11854 | + | |
| 11855 | R.height = menu.getInteger("Levels to go down?", 1, 1024 / R.width * R.length, nil, colors.blue)
| |
| 11856 | - | T:go("R1F1")
|
| 11856 | + | |
| 11857 | - | T:place("propagule", "down") -- top 2
|
| 11857 | + | |
| 11858 | R.length = 28 | |
| 11859 | - | T:place("propagule", "down") -- top 3/right 1
|
| 11859 | + | |
| 11860 | - | T:go("R1F1")
|
| 11860 | + | |
| 11861 | elseif R.choice == 87 then -- Ladder to water/lava | |
| 11862 | - | T:place("propagule", "down") -- right 2
|
| 11862 | + | |
| 11863 | elseif R.choice == 88 then -- Clear water plants from enclosed area | |
| 11864 | - | T:place("propagule", "down") -- right 3/bottom 1
|
| 11864 | + | |
| 11865 | - | T:go("R1F1")
|
| 11865 | + | |
| 11866 | - | T:place("propagule", "down") -- bottom 2]]
|
| 11866 | + | |
| 11867 | elseif R.choice == 89 then -- convert flowing water to source | |
| 11868 | - | --T:go("R1F1R2 D2U2 F7R2 D2")
|
| 11868 | + | |
| 11869 | if R.width > 0 then | |
| 11870 | R.length = menu.getInteger("water length (0=auto detect) ", 0, 64, nil, colors.orange)
| |
| 11871 | - | function lib.plantSingle(R) |
| 11871 | + | |
| 11872 | - | local sapling, count = lib.checkSaplings(firstChoice, secondChoice) |
| 11872 | + | |
| 11873 | - | if count >= 1 then |
| 11873 | + | |
| 11874 | - | if R.networkFarm then |
| 11874 | + | |
| 11875 | - | T:go("U1L1 F3R1 F4") -- outside first area
|
| 11875 | + | |
| 11876 | ||
| 11877 | - | T:go("U1F4") -- outside first area
|
| 11877 | + | |
| 11878 | elseif R.choice == 91 then -- Build wall | |
| 11879 | - | for i = 1, 3 do -- column 1/4 |
| 11879 | + | |
| 11880 | - | lib.createSingle(sapling, "forward") |
| 11880 | + | |
| 11881 | R.height = menu.getInteger("Height of wall (1-50) ", 1, 50, nil, colors.lightGray)
| |
| 11882 | pp.itemColours = {colors.lime, colors.magenta}
| |
| 11883 | - | for i = 1, 2 do |
| 11883 | + | |
| 11884 | - | lib.createSingle(sapling, "right") -- place 4th dirt/saling and exit to right |
| 11884 | + | |
| 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 | - | for i = 1, 2 do -- column 2/4 |
| 11887 | + | |
| 11888 | - | lib.createSingle(sapling, "forward") |
| 11888 | + | |
| 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 | - | for i = 1, 2 do |
| 11891 | + | |
| 11892 | - | lib.createSingle(sapling, "left") -- place 4th dirt/saling and exit to right |
| 11892 | + | |
| 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 | - | for i = 1, 2 do -- column 3/4 |
| 11895 | + | |
| 11896 | - | lib.createSingle(sapling, "forward") |
| 11896 | + | |
| 11897 | R.height = menu.getInteger("Go up by how many blocks?", 1, 256, nil, colors.lightGray)
| |
| 11898 | R.up = true | |
| 11899 | - | for i = 1, 2 do |
| 11899 | + | |
| 11900 | - | lib.createSingle(sapling, "right") -- place 4th dirt/saling and exit to right |
| 11900 | + | |
| 11901 | elseif R.choice == 101 then -- measure height | |
| 11902 | pp.itemColours = {colors.lightBlue, colors.cyan, colors.lime, colors.gray}
| |
| 11903 | - | for i = 1, 3 do -- column 4/4 |
| 11903 | + | |
| 11904 | - | lib.createSingle(sapling, "forward") |
| 11904 | + | |
| 11905 | R.data = menu.getString({"Search for? eg 'ore', 'obsidian'",">"}, false, 3, 20, nil, {colors.lime, colors.yellow})
| |
| 11906 | end | |
| 11907 | - | if R.networkFarm then |
| 11907 | + | |
| 11908 | - | T:go("R1F3 R1F2L1") -- in-between 2 trees
|
| 11908 | + | |
| 11909 | - | if R.auto then |
| 11909 | + | |
| 11910 | - | harvestTreeFarm(R) |
| 11910 | + | |
| 11911 | if R.subChoice == 3 then | |
| 11912 | - | T:go("L1F4R2D1")
|
| 11912 | + | |
| 11913 | end | |
| 11914 | elseif R.choice == 103 then -- measure length | |
| 11915 | - | T:go("R1F6 L1F2 R2D1")
|
| 11915 | + | |
| 11916 | R.subChoice = menu.menu("Measure using?", {"Obstruction ahead",
| |
| 11917 | "No further blocks above", | |
| 11918 | - | return "No saplings to plant" |
| 11918 | + | |
| 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 | - | function lib.plantDouble(R) |
| 11924 | + | |
| 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.networkFarm then |
| 11929 | + | |
| 11930 | - | T:go("U1L1 F3R1 F3") -- outside first area
|
| 11930 | + | |
| 11931 | end | |
| 11932 | - | T:go("U1F3") -- outside first area
|
| 11932 | + | |
| 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 | - | sapling, count = lib.checkSaplings(firstChoice, secondChoice) |
| 11935 | + | |
| 11936 | ||
| 11937 | return R | |
| 11938 | - | sapling, count = lib.checkSaplings(firstChoice, secondChoice) |
| 11938 | + | |
| 11939 | ||
| 11940 | local function getTaskInventoryTo30(R) | |
| 11941 | - | sapling, count = lib.checkSaplings(firstChoice, secondChoice) |
| 11941 | + | |
| 11942 | local thanks = "Thank you.\n\nPress the ESC key\n\nStand Back..\n" | |
| 11943 | --local pp = utils.getPrettyPrint() | |
| 11944 | ||
| 11945 | - | if R.networkFarm then |
| 11945 | + | |
| 11946 | - | T:go("R1F4 R1F1 L1") -- on left side of double tree
|
| 11946 | + | |
| 11947 | - | if R.auto then |
| 11947 | + | |
| 11948 | - | harvestTreeFarm(R) |
| 11948 | + | |
| 11949 | elseif R.choice == 1 then --Missing crafting table | |
| 11950 | - | T:go("L1F4 L1F1 L1D1") -- back to start
|
| 11950 | + | |
| 11951 | print("Crafting table being tested...")
| |
| 11952 | T:setEquipment() | |
| 11953 | - | T:go("R1D1 F6L1 F3R2") -- outside first area
|
| 11953 | + | |
| 11954 | T:checkInventoryForItem({"minecraft:chest"}, {1}) -- 0 if not present
| |
| 11955 | sleep(1.5) | |
| 11956 | - | return "Insufficient saplings to plant" |
| 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 | - | if R.networkFarm then |
| 11961 | + | |
| 11962 | - | local message = network.loadStorageLists() -- initialises or creates lists of where an item can be found: GLOBAL LISTS! |
| 11962 | + | |
| 11963 | - | if message ~= nil then return {message} end
|
| 11963 | + | |
| 11964 | - | lib.emptyInventory(R) |
| 11964 | + | |
| 11965 | ||
| 11966 | - | if R.subChoice == 3 then -- mangrove, R.networkFarm only |
| 11966 | + | |
| 11967 | - | lib.getMangroveSupplies() |
| 11967 | + | |
| 11968 | - | lib.plantMangrove() |
| 11968 | + | |
| 11969 | end | |
| 11970 | - | local saplings, firstChoice, secondChoice = lib.getSaplingInventory(R) |
| 11970 | + | |
| 11971 | - | if firstChoice ~= "" then |
| 11971 | + | |
| 11972 | - | print("first sapling: "..firstChoice .. " ("..saplings[firstChoice]..")")
|
| 11972 | + | |
| 11973 | R.height = menu.getInteger("Current level (F3->Y coord)? ", bedrock + 5, ceiling, nil, colors.lightGray)
| |
| 11974 | - | if secondChoice ~= "" then |
| 11974 | + | |
| 11975 | - | print("second sapling: "..secondChoice .. " ("..saplings[secondChoice]..")")
|
| 11975 | + | |
| 11976 | if menu.getBoolean("Build a shelter at base? (y/n) ", nil, colors.yellow, colors.black) then
| |
| 11977 | R.data = "chamber" | |
| 11978 | - | -- check type/size of farm |
| 11978 | + | |
| 11979 | end | |
| 11980 | - | if R.subChoice == 1 then -- 16 single trees |
| 11980 | + | |
| 11981 | - | message = lib.plantSingle(R) -- always "" |
| 11981 | + | |
| 11982 | - | elseif R.subChoice == 2 then -- 4 double trees (4 saplings) |
| 11982 | + | |
| 11983 | - | message = lib.plantDouble(R) -- "" or error about numbers |
| 11983 | + | |
| 11984 | R.up = true | |
| 11985 | --R.depth = utils.getSize(true,"Current level (F3->Y coord)? ", bedrock + 5, ceiling) | |
| 11986 | - | if R.networkFarm then |
| 11986 | + | |
| 11987 | - | lib.emptyInventory(R) |
| 11987 | + | |
| 11988 | R.height = menu.getInteger("Go up to level? ("..R.depth + 2 .." to "..ceiling ..") ", R.depth + 2, ceiling, nil, colors.lightGray)
| |
| 11989 | - | return {message}
|
| 11989 | + | |
| 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 | - | text[15] = {"1 soul sand", "3 water bucket", "levels * 4 stone", "1-9 buckets (optional)",
|
| 12172 | + | |
| 12173 | - | "2 signs if no ladder present"} -- single column bubble lift |
| 12173 | + | |
| 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 | - | "2 water buckets","192 fence","8 signs","3 ladder","2 soul sand"} -- build endermen observation tower |
| 12224 | + | |
| 12225 | - | text[67] = {"24 blocks of any type"} -- Cover Trial spawners to prevent mobs escaping
|
| 12225 | + | |
| 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 | - | [[ ~yellow~NETWORK TOOLS: |
| 12402 | + | |
| 12403 | - | Still on ToDo List! |
| 12403 | + | |
| 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 | - | [[~yellow~New, extend left/back=~red~^ ~orange~Extend Right=^ |
| 12550 | + | |
| 12551 | - | ~lightGray~|*|~blue~ | | | | | | ~brown~|D| |D| ~blue~| | ~lightGray~|*| |
| 12551 | + | |
| 12552 | - | ~lightGray~|*|~blue~ | | ~brown~|D|D|~blue~ | | | | | | | ~lightGray~|*| |
| 12552 | + | |
| 12553 | - | ~lightGray~|*|~blue~ | | ~brown~|D|D|~blue~ | ~brown~|D| |D| ~blue~| | ~lightGray~|*| |
| 12553 | + | |
| 12554 | - | ~lightGray~|*|~blue~ | | | | | | | | | | | | ~lightGray~|*| |
| 12554 | + | |
| 12555 | - | ~lightGray~|*|~blue~ | | | | | | | | | | | | ~lightGray~|*| |
| 12555 | + | |
| 12556 | - | ~lightGray~|*|~blue~ | | | | | | | | | | | | ~lightGray~|*| |
| 12556 | + | |
| 12557 | - | ~lightGray~|~red~^~lightGray~|*|*|*|*|*|*~magenta~|M|~lightGray~*|*|*|*|*|*|~orange~^| |
| 12557 | + | |
| 12558 | - | ~lime~4 ~brown~double trees~green~ or 16 ~brown~single trees |
| 12558 | + | |
| 12559 | - | ~brown~D = Dirt, ~magenta~M = Modem |
| 12559 | + | |
| 12560 | - | ~red~^~yellow~ = Turtle ~red~(new/left/back) ~orange~^ on right |
| 12560 | + | |
| 12561 | sleep(2) | |
| 12562 | print("Clearing area: size "..R.width.. " x "..R.length)
| |
| 12563 | - | [[~yellow~Place me on ground as below ~lightGray~^ ~magenta~^ |
| 12563 | + | |
| 12564 | - | ~lime~|*|~blue~ | | | | | | | ~green~or |*|~blue~ | | ~brown~|D| |D| | |
| 12564 | + | |
| 12565 | - | ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | | ~green~or |*|~blue~ | | | | | | | |
| 12565 | + | |
| 12566 | - | ~lime~|*|~blue~ | | ~brown~|D|D|~blue~ | | ~green~or |*|~blue~ | | ~brown~|D| |D| | |
| 12566 | + | |
| 12567 | - | ~lime~|*|~blue~ | | | | | | | ~green~or |*|~blue~ | | | | | | | |
| 12567 | + | |
| 12568 | - | ~lime~|*|~blue~ | | | | | | | ~green~or |*|~blue~ | | | | | | | |
| 12568 | + | |
| 12569 | - | ~lime~|*|*|*|*|~lightGray~^~lime~|*| ~magenta~|^| ~green~or |*|*|*|*|~lightGray~^~green~|*|*~magenta~|^| |
| 12569 | + | |
| 12570 | - | ~lime~ 4 ~brown~double trees~green~ or 16 ~brown~single trees |
| 12570 | + | |
| 12571 | - | ~brown~D = dirt |
| 12571 | + | |
| 12572 | - | ~lightGray~^ = Turtle on marker (Legacy storage) |
| 12572 | + | |
| 12573 | - | ~magenta~^ = Turtle on Modem (Network storage) |
| 12573 | + | |
| 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 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | ~lightGray~* = Wall |
| 12606 | + | |
| 12607 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | |
| 12607 | + | |
| 12608 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | |
| 12608 | + | |
| 12609 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | |
| 12609 | + | |
| 12610 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | ~magenta~M = Modem |
| 12610 | + | |
| 12611 | - | ~brown~|B|B~green~| | |~lightGray~or |*| ~green~| | ~brown~B = Barrel or Chest |
| 12611 | + | |
| 12612 | - | ~brown~|B|~blue~W~green~| | |~lightGray~or ~magenta~|M|~blue~W~green~| | ~blue~W = Water |
| 12612 | + | |
| 12613 | - | ~lime~|~red~^~lime~|~brown~B|B|~lightGray~*|or ~brown~|~red~^~brown~|~magenta~M|~lightGray~*| ~red~^ = Turtle |
| 12613 | + | |
| 12614 | - | ~brown~Legacy ~lightGray~or ~magenta~Network ~yellow~Size = 12 x 12 |
| 12614 | + | |
| 12615 | print("Building sand wall. Auto length: ")
| |
| 12616 | else | |
| 12617 | - | [[~yellow~Place on any ~brown~T ~blue~T ~magenta~T~yellow~ facing < > ^ v |
| 12617 | + | |
| 12618 | end | |
| 12619 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | ~lightGray~* = Wall |
| 12619 | + | |
| 12620 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | |
| 12620 | + | |
| 12621 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | |
| 12621 | + | |
| 12622 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | ~magenta~M = Modem |
| 12622 | + | |
| 12623 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | ~brown~B = Barrel or Chest |
| 12623 | + | |
| 12624 | - | ~brown~|B|B~green~| | |~lightGray~or |*| ~green~| | ~blue~W = Water |
| 12624 | + | |
| 12625 | - | ~brown~|B~blue~|T| ~green~| |~lightGray~or ~magenta~|M|~blue~T~green~| | ~orange~S = Sapling or Tree |
| 12625 | + | |
| 12626 | - | ~orange~|S|~brown~T|B|~lightGray~*|or ~brown~|B~magenta~|T|~lightGray~*| ~brown~T ~lightGray~= Turtle (~blue~T ~magenta~T~lightGray~) |
| 12626 | + | |
| 12627 | - | ~brown~Legacy ~lightGray~or ~magenta~Network ~yellow~Size = 12 x 12 |
| 12627 | + | |
| 12628 | print("Digging sand. Auto length")
| |
| 12629 | else | |
| 12630 | - | [[~yellow~Place as below ~blue~T~yellow~ facing < > ^ v |
| 12630 | + | |
| 12631 | end | |
| 12632 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | ~lightGray~* = Wall |
| 12632 | + | |
| 12633 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | |
| 12633 | + | |
| 12634 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | |
| 12634 | + | |
| 12635 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | ~magenta~M = Modem |
| 12635 | + | |
| 12636 | - | ~lightGray~|*|~green~ | | | ~lightGray~|*| ~green~| | ~brown~B = Barrel or Chest |
| 12636 | + | |
| 12637 | - | ~brown~|B|B~green~| | |~lightGray~or |*| ~green~| | C = Crop (first) |
| 12637 | + | |
| 12638 | - | ~brown~|B|~blue~T~green~|C| |~lightGray~or ~magenta~|M|~blue~T~green~|C| ~orange~S = Sapling or Tree |
| 12638 | + | |
| 12639 | - | ~orange~|S|~brown~B|B|~lightGray~*|or ~magenta~|M|~brown~B|~lightGray~*| ~blue~T = Turtle on Water |
| 12639 | + | |
| 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 | - | info.sub[67] = |
| 13010 | + | |
| 13011 | - | [[Turtle moves toward spawner |
| 13011 | + | |
| 13012 | - | Place at spawner level. |
| 13012 | + | |
| 13013 | end | |
| 13014 | - | Can be behind a wall for protection |
| 13014 | + | |
| 13015 | - | of player. |
| 13015 | + | |
| 13016 | end | |
| 13017 | - | Embeds in wall with attack working |
| 13017 | + | |
| 13018 | ||
| 13019 | - | Needs 24 blocks |
| 13019 | + |