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