Inksaver

autoDoor

Feb 21st, 2021 (edited)
752
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Lua 16.26 KB | None | 0 0
  1. version = 20210222.1510
  2. --[[
  3.     **********bDoor2x3**********
  4.     https://pastebin.com/5r8YHT6S
  5.     Last edited: see version YYYYMMDD.HHMM
  6.     if online:
  7.         lib folder will be created and files obtained automatically!
  8.     else
  9.         Make sure you create a folder 'lib'
  10.         and place menu.lua https://pastebin.com/BhjbYsw4
  11.         and clsTurtle.lua https://pastebin.com/tvfj90gK
  12.         into it
  13.     end
  14.     This is a port of bDoor2x3 by Kaikaku
  15.     pastebin: BvavMNTW
  16.     youtube:  https://www.youtube.com/watch?v=De1Dy6d2VgU
  17.    
  18.     Uses the turtle class by Inksaver, designed to allow complex movements,
  19.     flexible inventory filling, menus and idiot-proof user input:
  20.     https://pastebin.com/tvfj90gK (approx 3500 lines)
  21.    
  22.     This is automatically downloaded when this program is run.
  23. ]]
  24.  
  25. local cPrgName = "bDoor2x3"
  26. local cVersion  = "v2.01"
  27. local menu, T
  28. local tArgs = {...}
  29.  
  30. local function showInfo()
  31.     local iPage = 1
  32.     local pages = {}
  33.     pages[1] =
  34.     {
  35.         "| Builds a 2x3 piston door.           |",  
  36.         "| Footprint from above:               |",
  37.         "|                                     |",
  38.         "|   bbbppbbb   b=back wall  p=p.plate |",
  39.         "|   XXXDDXXX   X=other block  D=door  |",
  40.         "|   fffppfff   f=front wall           |",
  41.         "|      T       T=mining turtle        |",
  42.         "|                                     |"
  43.     }
  44.     pages[2] =
  45.     {
  46.         "| Inventory set-up:                   |",
  47.         "|   6 sticky pistons any slot         |",
  48.         "|   2 redstone torches any slot       |",
  49.         "|   13 redstone dust any slot         |",
  50.         "|   4 pressure plates any type/slot   |",
  51.         "|   26 building blocks any type/slot  |",
  52.         "|                                     |",
  53.         "| Turtle needs min 110 fuel to run.   |"
  54.     }
  55.     pages[3] =
  56.     {
  57.         "| Inventory options for block choice: |",
  58.         "| To use different/same door blocks:  |",
  59.         "| -add 6 new/existing blocks at prompt|",
  60.         "| To build front wall:                |",
  61.         "| -add 18 blocks at prompt Enter=skip |",
  62.         "| To build back wall:                 |",
  63.         "| -add 18 blocks at prompt Enter=skip |",
  64.         "|                                     |"
  65.     }
  66.     pages[4] =
  67.     {
  68.         "| Features/summary:                   |",
  69.         "| - replaces blocks for redstone dust |",
  70.         "| - can build in mid-air              |",
  71.         "| - can build into the mountain       |",
  72.         "| - inventory sufficient for 1 build  |",
  73.         "| - optional walls front/back         |",
  74.         "| - choose any solid door blocks      |",
  75.         "| - fuel in any slot (min 110)        |"
  76.     }
  77.     local iPageMax = #pages
  78.     pages.top = {}
  79.     pages.top[1] = "+-------------------------------------+"
  80.     pages.top[2] = ""
  81.     pages.top[3] = "+-------------------------------------+"
  82.     pages.base = {"+-------------------------------------+"}
  83.     for page = 1, iPageMax do
  84.         pages.top[2] = "+ "..cPrgName..", "..cVersion..", by Kaikaku ("..page.."/"..iPageMax..")   +"
  85.         for _, line in pairs(pages.top) do
  86.             print(line)
  87.         end
  88.         for _, line in pairs(pages[page]) do
  89.             print(line)
  90.         end
  91.         for _, line in pairs(pages.base) do
  92.             print(line)
  93.         end
  94.         write("Press Enter when ready")
  95.         read()
  96.     end
  97. end
  98.  
  99. local function backWall(name)
  100.     local blockTypes = T:getUserBlockType(name)
  101.     if next(blockTypes) ~= nil then -- table is not empty
  102.         T:go("U1F3C2C0 B1C1C2C0 B1C1C2C0 B1C1 R2x0 F1x0F3 C2C0 B1C1C2C0 B1C1C2C0 B1C1 R2D1", false, 0, false, blockTypes)
  103.     else -- User did not select back wall
  104.         T:back(1)
  105.     end
  106. end
  107.  
  108. local function frontWall(name)
  109.     local blockTypes = T:getUserBlockType(name)
  110.     if next(blockTypes) ~= nil then
  111.         T:go("L2F3C2C0 B1C1C2C0 B1C1C2C0 B1C1 R2F4C2C0 B1C1C2C0 B1C1C2C0 B1C1 B1 ", false, 0, false, blockTypes)
  112.     end
  113. end
  114.  
  115. local function checkFuelNeeded(quantity)
  116.     local fuelNeeded = quantity - turtle.getFuelLevel() -- eg 600
  117.     if fuelNeeded > 0 then
  118.         -- library call: T:checkInventoryForItem(items, quantity, required, message, name)
  119.         -- ({items}, {quantity}, bool<required=true>, string<message="", string<name>="")
  120.         T:checkInventoryForItem({"minecraft:lava_bucket", "minecraft:coal", "minecraft:planks"},
  121.                                 {1, math.ceil(fuelNeeded / 60), math.ceil(fuelNeeded / 15)},
  122.                                 true, "refuel", "fuel") --the message "refuel" will automatically use the item for refuelling
  123.     end
  124. end
  125.  
  126. local function checkLabel()
  127.     if os.getComputerLabel() == nil then
  128.         os.setComputerLabel("T".. os.getComputerID())
  129.         print("Computer label set to "..os.getComputerLabel())
  130.     end
  131. end
  132.  
  133. local function checkLibs(libDir)
  134.     local doContinue = true
  135.    
  136.     local lib = {}
  137.     function lib.createLibDir(libDir)
  138.         if fs.exists(libDir) then
  139.             if not fs.isDir(libDir) then
  140.                 fs.move(libDir, libDir.."Renamed")
  141.                 fs.makeDir(libDir)
  142.             end
  143.         else
  144.             fs.makeDir(libDir)
  145.         end
  146.     end
  147.    
  148.     function lib.getVersion(line)
  149.         -- eg version = 20201223.1104
  150.         line = string.gsub(line, " ", "") -- remove spaces
  151.         local start = string.find(line, "=")
  152.         local version = 0
  153.         if start ~= nil then -- found
  154.             local dateString = string.sub(line, start + 1)
  155.             version = tonumber(dateString)
  156.         end
  157.         return version
  158.     end
  159.    
  160.     function lib.isValid(dir, fileName, minVersion)
  161.         -- open file to read version
  162.         local isvalid = false
  163.         local currentVer = 0
  164.         if lib.fileExists(dir, fileName) then
  165.             current = fs.open(fs.combine(dir, fileName), "r")
  166.             currentVer = lib.getVersion(current.readLine())
  167.             current.close()
  168.             if currentVer ~= nil then
  169.                 if currentVer >= minVersion then
  170.                     isvalid = true
  171.                 end
  172.             end
  173.         end
  174.        
  175.         return isvalid, currentVer --file does not exist
  176.     end
  177.    
  178.     function lib.fileExists(dir, fileName)
  179.         if fs.exists(fs.combine(dir, fileName)) or fs.exists(fs.combine(dir, fileName..".lua")) then
  180.             return true
  181.         else
  182.             return false
  183.         end
  184.     end
  185.    
  186.     function lib.update(dir, fileName, pastebin, version)
  187.         -- use pastebin get to download files to libs folder
  188.         print(dir.."/"..fileName.." needs updating")
  189.         print("Attempting to obtain from Pastebin...")
  190.         --print("dir: "..dir..", fileName: "..fileName.."\nPastebin: "..pastebin..", version: "..tostring(version))
  191.         if version > 0 then
  192.             fs.move(fs.combine(dir, fileName), fs.combine(dir, fileName..version))
  193.         end
  194.         if shell.run("pastebin", "get", pastebin, fs.combine(dir, fileName)) then
  195.             print(fileName.." installed from Pastebin")
  196.             return true
  197.         else
  198.             print("failed to install "..fileName.." from Pastebin")
  199.             return false
  200.         end
  201.     end
  202.    
  203.     -- {directory, filename, pastebin code, minimum version}
  204.     local files =
  205.     {
  206.         {dir = 'lib', filename = 'clsTurtle.lua', pastebin = 'tvfj90gK', minVersion = 20210221.1440},
  207.         {dir = 'lib', filename = 'menu.lua', pastebin = 'BhjbYsw4', minVersion = 20201206.1005}
  208.     }
  209.    
  210.     for i = 1, #files do
  211.         lib.createLibDir(files[i].dir)
  212.         if not lib.fileExists(files[i].dir, files[i].filename) then
  213.             if lib.update(files[i].dir, files[i].filename, files[i].pastebin, 0) then
  214.                 doContinue = true
  215.             end
  216.         end
  217.         if doContinue then
  218.             print("Checking: "..files[i].filename)
  219.             local isvalid, version =  lib.isValid(files[i].dir, files[i].filename, files[i].minVersion)
  220.             if not isvalid then --out of date existing file
  221.                 if not lib.update(files[i].dir, files[i].filename, files[i].pastebin, version) then --unable to update
  222.                     doContinue = false
  223.                 end
  224.             end
  225.         end
  226.     end
  227.        
  228.     return doContinue
  229. end
  230.  
  231. local function digHole(name)
  232.     local success = true
  233.     --go(self, path, useTorch, torchInterval, leaveExisting, preferredBlock)
  234.     local blockTypes = T:getUserBlockType(name) -- eg {minecraft:cobblestone}
  235.     if next(blockTypes) ~= nil then
  236.         T:go("F1D2x2C2", false, 0, false, blockType) -- C command places preferred blockType 0=up,1=forward,2=down
  237.         T:go("F1x0x2C2 F1x0x2C2", false, 0, false, blockTypes) -- forward 1, dig up and down, place down, x2
  238.         T:go("R1 F1x0x2C2", false, 0, false, blockTypes) --turn right 1, forward 1, dig up and down, place down
  239.         T:go("R1 F1x0x2C2 F1x0x2C2", false, 0, false, blockTypes) --turn right 1, forward 1, dig up + down, place down
  240.         T:go("B1L1 F1x0x2C2", false, 0, false, blockTypes) --back 1, turnLeft, forward 1, dig up/down, place down
  241.         T:go("U1 F1x0x2C2 x1C1", false, 0, false, blockTypes) --up 1,forward 1, dig up and down, place down, dig, place
  242.         T:go("R2F3D1 F1x0x2C2", false, 0, false, blockTypes) --right 2, forward 3, down 1, forward 1, dig up and down, place down
  243.         T:go("U1 F1x0x2C2 x1C1", false, 0, false, blockTypes) --up 1, forward 1, dig up and down, place down, dig, place
  244.     else
  245.         print("Unable to locate blocks matching "..name)
  246.         success = false
  247.     end
  248.     return success
  249. end
  250.  
  251. local function placeFloor(name)
  252.     local success = true
  253.     local blockTypes = T:getUserBlockType(name) --table of "frame" blocks eg blockTypes["minecraft:cobblestone"] = 26
  254.     if next(blockTypes) ~= nil then
  255.         T:go("L1F3C2 F1C2 R1F1C2 R1F1C2 L1F1C2 L1F1C2", false, 0, false, blockTypes)
  256.     else
  257.         print("Unable to locate blocks matching "..name)
  258.         success = false
  259.     end
  260.     return success
  261. end
  262.  
  263. local function placeDoor(plate, door)
  264.     local success = true
  265.     local blockTypes = T:getUserBlockType(plate) --table of "plate" blocks eg blockTypes["minecraft:stone_pressure_plate"] = 2
  266.     if next(blockTypes) ~= nil then --place pressure plates
  267.         T:go("C1 U1C2 x0x1", false, 0, false, blockTypes)
  268.         blockTypes = T:getUserBlockType(door)
  269.         if next(blockTypes) ~= nil then --door blocks
  270.             T:go("R1B1C2C0 R1B1C1C2C0 L1B1C1", false, 0, false, blockTypes)
  271.             blockTypes = T:getUserBlockType(plate)
  272.             T:go("R1F1C2 B1C2", false, 0, false, blockTypes)
  273.         else
  274.             print("Unable to locate blocks matching "..door)
  275.             success = false
  276.         end
  277.     else
  278.         print("Unable to locate blocks matching "..plate)
  279.         success = false
  280.     end
  281.     return success
  282. end
  283.  
  284. local function placePistons(frame, piston)
  285.     local success = true
  286.     local blockTypes = T:getUserBlockType(frame)
  287.     if next(blockTypes) ~= nil then --place frame
  288.         T:go("U1x1C1 U1x1C1 U1x1C1 B1", false, 0, false, blockTypes) -- up(1), place, up(1), place, up(1), place, back(1)
  289.         blockTypes = T:getUserBlockType(piston)
  290.         if next(blockTypes) ~= nil then --place pistons
  291.             T:go("C1D1C1D1C1", false, 0, false, blockTypes) --place, down(1), place, down(1), place
  292.             T:go("R2F4", false, 0, false, blockType) --turnRight(2), forward(4)
  293.             blockTypes = T:getUserBlockType(frame)
  294.             if next(blockTypes) ~= nil then --place frame blocks
  295.                 T:go("x1C1 U1x1C1 U1x1C1 B1", false, 0, false, blockTypes) --place, down(1), place,down(1), place, back(1)
  296.                 blockTypes = T:getUserBlockType(piston)
  297.                 if next(blockTypes) ~= nil then --place pistons
  298.                     T:go("x1C1 D1x1C1 D1x1C1", false, 0, false, blockTypes) --place, down(1), place,down(1), place
  299.                 else
  300.                     success = false
  301.                 end
  302.             else
  303.                 success = false
  304.             end
  305.         else
  306.             success = false
  307.         end
  308.     else
  309.         success = false
  310.     end
  311.    
  312.     return success
  313. end
  314.  
  315. local function placeRedstone(name)
  316.     local success = true
  317.     local blockTypes = T:getUserBlockType(name)
  318.     if next(blockTypes) ~= nil then --place redstone
  319.         T:go("D1x1C1C2 B1D1L1C1 R2C1 L1B1C1 L1C1 R2C1 R1C1 U1C2 F1C1", false, 0, false, blockTypes)
  320.         T:go("U1L1F1R1 F2R1F1x1B1", false, 0, false, blockTypes)
  321.         T:place("minecraft:redstone_torch", -1, "forward", false)
  322.         T:up(2)
  323.         T:go("x1C1 R1F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 F1x2 L1x1C1 D2F1x1 B1", false, 0, false, blockTypes)
  324.         T:place("minecraft:redstone_torch", -1, "forward", false)
  325.     else
  326.         print("Unable to locate blocks matching "..name)
  327.         success = false
  328.     end
  329.    
  330.     return success
  331. end
  332.  
  333. local function goHome()
  334.     T:go("L1B1D1", false, 0, false)
  335. end
  336.  
  337. local function isTurtle(cPrgName)
  338.     local try = {}
  339.     function try.getFuelLevel()
  340.         return turtle.getFuelLevel()
  341.     end
  342.    
  343.     local ok, fuelLevel = pcall(try.getFuelLevel)
  344.     if type(fuelLevel) == 'string' then -- error message
  345.         term.clear()
  346.         term.setCursorPos(1,1)
  347.         print("+-------------------------------------+")
  348.         print("  ",cPrgName,", by Kaikaku")
  349.         print("+-------------------------------------+")
  350.         print("| This is a turtle program.           |")
  351.         print("| Please, execute it with a turtle!   |")
  352.         print("+-------------------------------------+")
  353.     end
  354.    
  355.     return ok -- true if turtle
  356. end
  357.  
  358. local function main()
  359.     local doContinue = true
  360.     if isTurtle(cPrgName) then
  361.         checkLabel() -- make sure turtle label is set
  362.         -- check if lib/menu and lib/clsTurtle exists
  363.         if not checkLibs("lib") then
  364.             doContinue = false
  365.         end
  366.         if doContinue then
  367.             --load menu library
  368.             menu = require("lib.menu")
  369.             -- instantiate turtle class
  370.             T = require("lib.clsTurtle"):new(1) -- 1 sent for debug purposes
  371.             T:clear() -- clear terminal
  372.             if next(tArgs) ~= nil then --tArgs has been passed
  373.                 for i = 1, #tArgs do
  374.                     if tArgs[i]:find("help") ~= nil then -- "help", "-help", "--help" etc
  375.                         local input = T:getInput() -- assign getInput() method from clsTurtle object to local variable
  376.                         if input.getBoolean("Do you want to view info pages?") then
  377.                             showInfo()
  378.                         end
  379.                     end
  380.                     if tArgs[i]:find("bug") ~= nil then -- "dbug", "debug", "--debug" etc
  381.                         print("Debugging mode enabled.")
  382.                         print("Check file: "..cPrgName..".log.txt")
  383.                         sleep(2)
  384.                         -- debug to log file
  385.                         T:setLogFileName(cPrgName..".log.txt") -- name of text file in current dir
  386.                         T:deleteLog() -- if you want to start with new file every time the program runs
  387.                         T:setUseLog(true) -- set to false to prevent logfile being used
  388.                         -- method usage from this program: T:saveToLog(string<text>, bool<toScreen>)
  389.                         -- example: T:saveToLog("Log file created", true)
  390.                         -- This will automatically enable logging from within clsTurtle as well
  391.                     end
  392.                 end
  393.             end
  394.             checkFuelNeeded(110) -- check minimum 110
  395.             -- method usage: T:checkInventoryForItem({items}, {quantity}, bool<required=true>, string<message="">, string<label>)
  396.             T:checkInventoryForItem({"minecraft:sticky_piston"}, {6}, true, "", "stickyPiston")
  397.             T:checkInventoryForItem({"minecraft:redstone_torch"}, {2}, true, "", "redstone_Torch")
  398.             T:checkInventoryForItem({"minecraft:redstone"}, {13}, true, "", "redstone")
  399.             T:checkInventoryForItem({"pressure_plate"}, {4}, true, "", "plate")
  400.             T:checkInventoryForItem({"user"}, {26}, true, "Choose door frame blocks", "frame")
  401.             T:checkInventoryForItem({"user"}, {6}, true, "Choose blocks to construct door", "door")
  402.             T:checkInventoryForItem({"user"}, {18}, false, "Optional blocks for front wall", "front")
  403.             T:checkInventoryForItem({"user"}, {18}, false, "Optional blocks for back wall", "back")
  404.             T:clear()
  405.             print("Starting in 2 secs...")
  406.             sleep(2)
  407.             --[[
  408.                 A table of all the above items is created inside the turtle class and can be used to
  409.                 refer to specific items, eg to use door blocks, search for "door" to get the block name.
  410.                 local userBlocks = T:getUserBlocks() -- returns entire table
  411.                 table userBlocks: true=user chose block, false=no choice given, if no name given, item name used
  412.                 userBlocks[#] = {"string<name>, string<item>, int<#required>, bool<userChoice>}
  413.                
  414.                 userBlocks[1] = {"stickyPiston", "minecraft:sticky_piston", 6, false}
  415.                 userBlocks[2] = {"redstone_torch", "minecraft:redstone_torch", 2, false}
  416.                 userBlocks[3] = {"redstone", "minecraft:redstone", 13, false}
  417.                 userBlocks[4] = {"plate", "minecraft:stone_pressure_plate", 2, false}
  418.                 userBlocks[5] = {"plate", "minecraft:oak_pressure_plate", 2, false}
  419.                 userBlocks[6] = {"frame", "minecraft:end_stone", 26, true}
  420.                 userBlocks[7] = {"door",  "minecraft:spruce_log", 6, true}
  421.                 userBlocks[8] = {"front", "minecraft:cobblestone", 18, true}
  422.                 userBlocks[9] = {"back",  "minecraft:cobblestone", 18, true}
  423.                
  424.                 use blockTypes = T:getBlockType("plate"):
  425.                 table of all pressure_plates (user added 2x stone and 2x oak)
  426.                 blockTypes["minecraft:stone_pressure_plate"] = 2
  427.                 blockTypes["minecraft:oak_pressure_plate] = 2
  428.             ]]
  429.             if doContinue then
  430.                 if not digHole("frame") then doContinue = false end
  431.             end
  432.             if doContinue then
  433.                 if not placePistons("frame", "stickyPiston") then doContinue = false end
  434.             end
  435.             if doContinue then
  436.                 if not placeRedstone("redstone") then doContinue = false end
  437.             end
  438.             if doContinue then
  439.                 if not placeFloor("frame") then doContinue = false end
  440.             end
  441.             if doContinue then
  442.                 backWall("back")
  443.             end
  444.             if doContinue then
  445.                 if not placeDoor("plate", "door") then doContinue = false end
  446.             end
  447.             if doContinue then
  448.                 frontWall("front")
  449.             end
  450.             if doContinue then
  451.                 goHome()
  452.             end
  453.             T:clear()
  454.             print("Thank you for using "..cPrgName)
  455.         else
  456.             print("Add missing files and restart")
  457.         end
  458.     end
  459. end
  460.  
  461. main()
Add Comment
Please, Sign In to add comment