Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- version = 20210222.1510
- --[[
- **********bDoor2x3**********
- https://pastebin.com/5r8YHT6S
- Last edited: see version YYYYMMDD.HHMM
- if online:
- lib folder will be created and files obtained automatically!
- else
- Make sure you create a folder 'lib'
- and place menu.lua https://pastebin.com/BhjbYsw4
- and clsTurtle.lua https://pastebin.com/tvfj90gK
- into it
- end
- This is a port of bDoor2x3 by Kaikaku
- pastebin: BvavMNTW
- youtube: https://www.youtube.com/watch?v=De1Dy6d2VgU
- Uses the turtle class by Inksaver, designed to allow complex movements,
- flexible inventory filling, menus and idiot-proof user input:
- https://pastebin.com/tvfj90gK (approx 3500 lines)
- This is automatically downloaded when this program is run.
- ]]
- local cPrgName = "bDoor2x3"
- local cVersion = "v2.01"
- local menu, T
- local tArgs = {...}
- local function showInfo()
- local iPage = 1
- local pages = {}
- pages[1] =
- {
- "| Builds a 2x3 piston door. |",
- "| Footprint from above: |",
- "| |",
- "| bbbppbbb b=back wall p=p.plate |",
- "| XXXDDXXX X=other block D=door |",
- "| fffppfff f=front wall |",
- "| T T=mining turtle |",
- "| |"
- }
- pages[2] =
- {
- "| Inventory set-up: |",
- "| 6 sticky pistons any slot |",
- "| 2 redstone torches any slot |",
- "| 13 redstone dust any slot |",
- "| 4 pressure plates any type/slot |",
- "| 26 building blocks any type/slot |",
- "| |",
- "| Turtle needs min 110 fuel to run. |"
- }
- pages[3] =
- {
- "| Inventory options for block choice: |",
- "| To use different/same door blocks: |",
- "| -add 6 new/existing blocks at prompt|",
- "| To build front wall: |",
- "| -add 18 blocks at prompt Enter=skip |",
- "| To build back wall: |",
- "| -add 18 blocks at prompt Enter=skip |",
- "| |"
- }
- pages[4] =
- {
- "| Features/summary: |",
- "| - replaces blocks for redstone dust |",
- "| - can build in mid-air |",
- "| - can build into the mountain |",
- "| - inventory sufficient for 1 build |",
- "| - optional walls front/back |",
- "| - choose any solid door blocks |",
- "| - fuel in any slot (min 110) |"
- }
- local iPageMax = #pages
- pages.top = {}
- pages.top[1] = "+-------------------------------------+"
- pages.top[2] = ""
- pages.top[3] = "+-------------------------------------+"
- pages.base = {"+-------------------------------------+"}
- for page = 1, iPageMax do
- pages.top[2] = "+ "..cPrgName..", "..cVersion..", by Kaikaku ("..page.."/"..iPageMax..") +"
- for _, line in pairs(pages.top) do
- print(line)
- end
- for _, line in pairs(pages[page]) do
- print(line)
- end
- for _, line in pairs(pages.base) do
- print(line)
- end
- write("Press Enter when ready")
- read()
- end
- end
- local function backWall(name)
- local blockTypes = T:getUserBlockType(name)
- if next(blockTypes) ~= nil then -- table is not empty
- T:go("U1F3C2C0 B1C1C2C0 B1C1C2C0 B1C1 R2x0 F1x0F3 C2C0 B1C1C2C0 B1C1C2C0 B1C1 R2D1", false, 0, false, blockTypes)
- else -- User did not select back wall
- T:back(1)
- end
- end
- local function frontWall(name)
- local blockTypes = T:getUserBlockType(name)
- if next(blockTypes) ~= nil then
- T:go("L2F3C2C0 B1C1C2C0 B1C1C2C0 B1C1 R2F4C2C0 B1C1C2C0 B1C1C2C0 B1C1 B1 ", false, 0, false, blockTypes)
- end
- end
- local function checkFuelNeeded(quantity)
- local fuelNeeded = quantity - turtle.getFuelLevel() -- eg 600
- if fuelNeeded > 0 then
- -- library call: T:checkInventoryForItem(items, quantity, required, message, name)
- -- ({items}, {quantity}, bool<required=true>, string<message="", string<name>="")
- T:checkInventoryForItem({"minecraft:lava_bucket", "minecraft:coal", "minecraft:planks"},
- {1, math.ceil(fuelNeeded / 60), math.ceil(fuelNeeded / 15)},
- true, "refuel", "fuel") --the message "refuel" will automatically use the item for refuelling
- end
- end
- local function checkLabel()
- if os.getComputerLabel() == nil then
- os.setComputerLabel("T".. os.getComputerID())
- print("Computer label set to "..os.getComputerLabel())
- end
- end
- local function checkLibs(libDir)
- local doContinue = true
- local lib = {}
- function lib.createLibDir(libDir)
- if fs.exists(libDir) then
- if not fs.isDir(libDir) then
- fs.move(libDir, libDir.."Renamed")
- fs.makeDir(libDir)
- end
- else
- fs.makeDir(libDir)
- end
- end
- function lib.getVersion(line)
- -- eg version = 20201223.1104
- line = string.gsub(line, " ", "") -- remove spaces
- local start = string.find(line, "=")
- local version = 0
- if start ~= nil then -- found
- local dateString = string.sub(line, start + 1)
- version = tonumber(dateString)
- end
- return version
- end
- function lib.isValid(dir, fileName, minVersion)
- -- open file to read version
- local isvalid = false
- local currentVer = 0
- if lib.fileExists(dir, fileName) then
- current = fs.open(fs.combine(dir, fileName), "r")
- currentVer = lib.getVersion(current.readLine())
- current.close()
- if currentVer ~= nil then
- if currentVer >= minVersion then
- isvalid = true
- end
- end
- end
- return isvalid, currentVer --file does not exist
- end
- function lib.fileExists(dir, fileName)
- if fs.exists(fs.combine(dir, fileName)) or fs.exists(fs.combine(dir, fileName..".lua")) then
- return true
- else
- return false
- end
- end
- function lib.update(dir, fileName, pastebin, version)
- -- use pastebin get to download files to libs folder
- print(dir.."/"..fileName.." needs updating")
- print("Attempting to obtain from Pastebin...")
- --print("dir: "..dir..", fileName: "..fileName.."\nPastebin: "..pastebin..", version: "..tostring(version))
- if version > 0 then
- fs.move(fs.combine(dir, fileName), fs.combine(dir, fileName..version))
- end
- if shell.run("pastebin", "get", pastebin, fs.combine(dir, fileName)) then
- print(fileName.." installed from Pastebin")
- return true
- else
- print("failed to install "..fileName.." from Pastebin")
- return false
- end
- end
- -- {directory, filename, pastebin code, minimum version}
- local files =
- {
- {dir = 'lib', filename = 'clsTurtle.lua', pastebin = 'tvfj90gK', minVersion = 20210221.1440},
- {dir = 'lib', filename = 'menu.lua', pastebin = 'BhjbYsw4', minVersion = 20201206.1005}
- }
- for i = 1, #files do
- lib.createLibDir(files[i].dir)
- if not lib.fileExists(files[i].dir, files[i].filename) then
- if lib.update(files[i].dir, files[i].filename, files[i].pastebin, 0) then
- doContinue = true
- end
- end
- if doContinue then
- print("Checking: "..files[i].filename)
- local isvalid, version = lib.isValid(files[i].dir, files[i].filename, files[i].minVersion)
- if not isvalid then --out of date existing file
- if not lib.update(files[i].dir, files[i].filename, files[i].pastebin, version) then --unable to update
- doContinue = false
- end
- end
- end
- end
- return doContinue
- end
- local function digHole(name)
- local success = true
- --go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
- local blockTypes = T:getUserBlockType(name) -- eg {minecraft:cobblestone}
- if next(blockTypes) ~= nil then
- T:go("F1D2x2C2", false, 0, false, blockType) -- C command places preferred blockType 0=up,1=forward,2=down
- T:go("F1x0x2C2 F1x0x2C2", false, 0, false, blockTypes) -- forward 1, dig up and down, place down, x2
- T:go("R1 F1x0x2C2", false, 0, false, blockTypes) --turn right 1, forward 1, dig up and down, place down
- T:go("R1 F1x0x2C2 F1x0x2C2", false, 0, false, blockTypes) --turn right 1, forward 1, dig up + down, place down
- T:go("B1L1 F1x0x2C2", false, 0, false, blockTypes) --back 1, turnLeft, forward 1, dig up/down, place down
- T:go("U1 F1x0x2C2 x1C1", false, 0, false, blockTypes) --up 1,forward 1, dig up and down, place down, dig, place
- T:go("R2F3D1 F1x0x2C2", false, 0, false, blockTypes) --right 2, forward 3, down 1, forward 1, dig up and down, place down
- T:go("U1 F1x0x2C2 x1C1", false, 0, false, blockTypes) --up 1, forward 1, dig up and down, place down, dig, place
- else
- print("Unable to locate blocks matching "..name)
- success = false
- end
- return success
- end
- local function placeFloor(name)
- local success = true
- local blockTypes = T:getUserBlockType(name) --table of "frame" blocks eg blockTypes["minecraft:cobblestone"] = 26
- if next(blockTypes) ~= nil then
- T:go("L1F3C2 F1C2 R1F1C2 R1F1C2 L1F1C2 L1F1C2", false, 0, false, blockTypes)
- else
- print("Unable to locate blocks matching "..name)
- success = false
- end
- return success
- end
- local function placeDoor(plate, door)
- local success = true
- local blockTypes = T:getUserBlockType(plate) --table of "plate" blocks eg blockTypes["minecraft:stone_pressure_plate"] = 2
- if next(blockTypes) ~= nil then --place pressure plates
- T:go("C1 U1C2 x0x1", false, 0, false, blockTypes)
- blockTypes = T:getUserBlockType(door)
- if next(blockTypes) ~= nil then --door blocks
- T:go("R1B1C2C0 R1B1C1C2C0 L1B1C1", false, 0, false, blockTypes)
- blockTypes = T:getUserBlockType(plate)
- T:go("R1F1C2 B1C2", false, 0, false, blockTypes)
- else
- print("Unable to locate blocks matching "..door)
- success = false
- end
- else
- print("Unable to locate blocks matching "..plate)
- success = false
- end
- return success
- end
- local function placePistons(frame, piston)
- local success = true
- local blockTypes = T:getUserBlockType(frame)
- if next(blockTypes) ~= nil then --place frame
- T:go("U1x1C1 U1x1C1 U1x1C1 B1", false, 0, false, blockTypes) -- up(1), place, up(1), place, up(1), place, back(1)
- blockTypes = T:getUserBlockType(piston)
- if next(blockTypes) ~= nil then --place pistons
- T:go("C1D1C1D1C1", false, 0, false, blockTypes) --place, down(1), place, down(1), place
- T:go("R2F4", false, 0, false, blockType) --turnRight(2), forward(4)
- blockTypes = T:getUserBlockType(frame)
- if next(blockTypes) ~= nil then --place frame blocks
- T:go("x1C1 U1x1C1 U1x1C1 B1", false, 0, false, blockTypes) --place, down(1), place,down(1), place, back(1)
- blockTypes = T:getUserBlockType(piston)
- if next(blockTypes) ~= nil then --place pistons
- T:go("x1C1 D1x1C1 D1x1C1", false, 0, false, blockTypes) --place, down(1), place,down(1), place
- else
- success = false
- end
- else
- success = false
- end
- else
- success = false
- end
- else
- success = false
- end
- return success
- end
- local function placeRedstone(name)
- local success = true
- local blockTypes = T:getUserBlockType(name)
- if next(blockTypes) ~= nil then --place redstone
- T:go("D1x1C1C2 B1D1L1C1 R2C1 L1B1C1 L1C1 R2C1 R1C1 U1C2 F1C1", false, 0, false, blockTypes)
- T:go("U1L1F1R1 F2R1F1x1B1", false, 0, false, blockTypes)
- T:place("minecraft:redstone_torch", -1, "forward", false)
- T:up(2)
- T:go("x1C1 R1F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 L1x1C1 D2F1x1 B1", false, 0, false, blockTypes)
- T:place("minecraft:redstone_torch", -1, "forward", false)
- else
- print("Unable to locate blocks matching "..name)
- success = false
- end
- return success
- end
- local function goHome()
- T:go("L1B1D1", false, 0, false)
- end
- local function isTurtle(cPrgName)
- local try = {}
- function try.getFuelLevel()
- return turtle.getFuelLevel()
- end
- local ok, fuelLevel = pcall(try.getFuelLevel)
- if type(fuelLevel) == 'string' then -- error message
- term.clear()
- term.setCursorPos(1,1)
- print("+-------------------------------------+")
- print(" ",cPrgName,", by Kaikaku")
- print("+-------------------------------------+")
- print("| This is a turtle program. |")
- print("| Please, execute it with a turtle! |")
- print("+-------------------------------------+")
- end
- return ok -- true if turtle
- end
- local function main()
- local doContinue = true
- if isTurtle(cPrgName) then
- checkLabel() -- make sure turtle label is set
- -- check if lib/menu and lib/clsTurtle exists
- if not checkLibs("lib") then
- doContinue = false
- end
- if doContinue then
- --load menu library
- menu = require("lib.menu")
- -- instantiate turtle class
- T = require("lib.clsTurtle"):new(1) -- 1 sent for debug purposes
- T:clear() -- clear terminal
- if next(tArgs) ~= nil then --tArgs has been passed
- for i = 1, #tArgs do
- if tArgs[i]:find("help") ~= nil then -- "help", "-help", "--help" etc
- local input = T:getInput() -- assign getInput() method from clsTurtle object to local variable
- if input.getBoolean("Do you want to view info pages?") then
- showInfo()
- end
- end
- if tArgs[i]:find("bug") ~= nil then -- "dbug", "debug", "--debug" etc
- print("Debugging mode enabled.")
- print("Check file: "..cPrgName..".log.txt")
- sleep(2)
- -- debug to log file
- T:setLogFileName(cPrgName..".log.txt") -- name of text file in current dir
- T:deleteLog() -- if you want to start with new file every time the program runs
- T:setUseLog(true) -- set to false to prevent logfile being used
- -- method usage from this program: T:saveToLog(string<text>, bool<toScreen>)
- -- example: T:saveToLog("Log file created", true)
- -- This will automatically enable logging from within clsTurtle as well
- end
- end
- end
- checkFuelNeeded(110) -- check minimum 110
- -- method usage: T:checkInventoryForItem({items}, {quantity}, bool<required=true>, string<message="">, string<label>)
- T:checkInventoryForItem({"minecraft:sticky_piston"}, {6}, true, "", "stickyPiston")
- T:checkInventoryForItem({"minecraft:redstone_torch"}, {2}, true, "", "redstone_Torch")
- T:checkInventoryForItem({"minecraft:redstone"}, {13}, true, "", "redstone")
- T:checkInventoryForItem({"pressure_plate"}, {4}, true, "", "plate")
- T:checkInventoryForItem({"user"}, {26}, true, "Choose door frame blocks", "frame")
- T:checkInventoryForItem({"user"}, {6}, true, "Choose blocks to construct door", "door")
- T:checkInventoryForItem({"user"}, {18}, false, "Optional blocks for front wall", "front")
- T:checkInventoryForItem({"user"}, {18}, false, "Optional blocks for back wall", "back")
- T:clear()
- print("Starting in 2 secs...")
- sleep(2)
- --[[
- A table of all the above items is created inside the turtle class and can be used to
- refer to specific items, eg to use door blocks, search for "door" to get the block name.
- local userBlocks = T:getUserBlocks() -- returns entire table
- table userBlocks: true=user chose block, false=no choice given, if no name given, item name used
- userBlocks[#] = {"string<name>, string<item>, int<#required>, bool<userChoice>}
- userBlocks[1] = {"stickyPiston", "minecraft:sticky_piston", 6, false}
- userBlocks[2] = {"redstone_torch", "minecraft:redstone_torch", 2, false}
- userBlocks[3] = {"redstone", "minecraft:redstone", 13, false}
- userBlocks[4] = {"plate", "minecraft:stone_pressure_plate", 2, false}
- userBlocks[5] = {"plate", "minecraft:oak_pressure_plate", 2, false}
- userBlocks[6] = {"frame", "minecraft:end_stone", 26, true}
- userBlocks[7] = {"door", "minecraft:spruce_log", 6, true}
- userBlocks[8] = {"front", "minecraft:cobblestone", 18, true}
- userBlocks[9] = {"back", "minecraft:cobblestone", 18, true}
- use blockTypes = T:getBlockType("plate"):
- table of all pressure_plates (user added 2x stone and 2x oak)
- blockTypes["minecraft:stone_pressure_plate"] = 2
- blockTypes["minecraft:oak_pressure_plate] = 2
- ]]
- if doContinue then
- if not digHole("frame") then doContinue = false end
- end
- if doContinue then
- if not placePistons("frame", "stickyPiston") then doContinue = false end
- end
- if doContinue then
- if not placeRedstone("redstone") then doContinue = false end
- end
- if doContinue then
- if not placeFloor("frame") then doContinue = false end
- end
- if doContinue then
- backWall("back")
- end
- if doContinue then
- if not placeDoor("plate", "door") then doContinue = false end
- end
- if doContinue then
- frontWall("front")
- end
- if doContinue then
- goHome()
- end
- T:clear()
- print("Thank you for using "..cPrgName)
- else
- print("Add missing files and restart")
- end
- end
- end
- main()
Add Comment
Please, Sign In to add comment