dome_tunnels_size2.lua

388 lines · 9.7 KB

Open raw

Dome Tunnels (Size2) by Silvamord Fixed cross-section: 7 blocks wide - Columns 1-2: height 3 - Columns 3-5: height 4 - Columns 6-7: height 3 Place the turtle at the bottom-left corner of the tunnel cross-section, facing forward along the tunnel direction. The script carves one slice per forward step using a serpentine pattern for efficiency. Prompts: - Length (number of slices forward) - Optional torches (spacing, side, slot) ]]-- local version = "1.0" -- Fixed profile for width 7: 3,3,4,4,4,3,3 local WIDTH = 7 local FIXED_HEIGHTS = {3,3,4,4,4,3,3} -- UI helpers (minimal) local function ask_number_default(prompt, default_value, min_val, max_val) while true do term.clear() term.setCursorPos(1,1) write("Dome Tunnels Size2 v"..version.."\n\n") write(string.format("%s [default: %s] ", prompt, tostring(default_value))) local s = read()

Copy & run

wget https://perlytiara.github.io/turtles.tips/raw/programs/perlytiara/dome_tunnels/dome_tunnels_size2.lua
1--[[
2 Dome Tunnels (Size2) by Silvamord
3 Fixed cross-section: 7 blocks wide
4 - Columns 1-2: height 3
5 - Columns 3-5: height 4
6 - Columns 6-7: height 3
7
8 Place the turtle at the bottom-left corner of the tunnel cross-section,
9 facing forward along the tunnel direction. The script carves one slice per
10 forward step using a serpentine pattern for efficiency.
11
12 Prompts:
13 - Length (number of slices forward)
14 - Optional torches (spacing, side, slot)
15]]--
16
17local version = "1.0"
18
19-- Fixed profile for width 7: 3,3,4,4,4,3,3
20local WIDTH = 7
21local FIXED_HEIGHTS = {3,3,4,4,4,3,3}
22
23-- UI helpers (minimal)
24local function ask_number_default(prompt, default_value, min_val, max_val)
25 while true do
26 term.clear()
27 term.setCursorPos(1,1)
28 write("Dome Tunnels Size2 v"..version.."\n\n")
29 write(string.format("%s [default: %s] ", prompt, tostring(default_value)))
30 local s = read()
31 if s == nil or s == "" then
32 return default_value
33 end
34 local n = tonumber(s)
35 if n and (not min_val or n >= min_val) and (not max_val or n <= max_val) then
36 return n
37 end
38 write("\nInvalid input. Press Enter to try again.")
39 read()
40 end
41end
42
43local function ask_yes_no(prompt, default_yes)
44 while true do
45 term.clear()
46 term.setCursorPos(1,1)
47 write("Dome Tunnels Size2 v"..version.."\n\n")
48 local def = default_yes and "Y" or "N"
49 write(string.format("%s (y/n) [default: %s] ", prompt, def))
50 local s = read()
51 s = s and string.lower(s) or ""
52 if s == "" then return default_yes end
53 if s == "y" or s == "yes" then return true end
54 if s == "n" or s == "no" then return false end
55 write("\nInvalid input. Press Enter to try again.")
56 read()
57 end
58end
59
60local function ask_choice(prompt, default_value, choices)
61 while true do
62 term.clear()
63 term.setCursorPos(1,1)
64 write("Dome Tunnels Size2 v"..version.."\n\n")
65 write(string.format("%s %s [default: %s] ", prompt, table.concat(choices, "/"), tostring(default_value)))
66 local s = read()
67 if s == nil or s == "" then return default_value end
68 s = string.lower(s)
69 for _, c in ipairs(choices) do
70 if s == c then return s end
71 end
72 write("\nInvalid input. Press Enter to try again.")
73 read()
74 end
75end
76
77-- Movement helpers
78local function ensure_fuel(threshold)
79 if turtle.getFuelLevel() == "unlimited" then return end
80 if turtle.getFuelLevel() >= threshold then return end
81 for i = 1, 16 do
82 turtle.select(i)
83 if turtle.refuel(0) then
84 while turtle.getFuelLevel() < threshold and turtle.refuel(1) do end
85 if turtle.getFuelLevel() >= threshold then
86 return
87 end
88 end
89 end
90 term.clear()
91 term.setCursorPos(1,1)
92 print("Out of fuel. Put fuel in inventory and press Enter.")
93 read()
94 return ensure_fuel(threshold)
95end
96
97local function dig_forward()
98 while turtle.detect() do
99 if not turtle.dig() then
100 turtle.attack()
101 sleep(0.2)
102 end
103 end
104end
105
106local function dig_upwards()
107 while turtle.detectUp() do
108 if not turtle.digUp() then
109 turtle.attackUp()
110 sleep(0.2)
111 end
112 end
113end
114
115local function dig_downwards()
116 while turtle.detectDown() do
117 if not turtle.digDown() then
118 turtle.attackDown()
119 sleep(0.2)
120 end
121 end
122end
123
124local function safe_forward()
125 ensure_fuel(100)
126 while not turtle.forward() do
127 dig_forward()
128 sleep(0.05)
129 end
130end
131
132local function safe_up()
133 ensure_fuel(100)
134 while not turtle.up() do
135 dig_upwards()
136 sleep(0.05)
137 end
138end
139
140local function safe_down()
141 ensure_fuel(100)
142 while not turtle.down() do
143 dig_downwards()
144 sleep(0.05)
145 end
146end
147
148local function turn_left()
149 turtle.turnLeft()
150end
151
152local function turn_right()
153 turtle.turnRight()
154end
155
156local function step_right()
157 turn_right()
158 dig_forward()
159 safe_forward()
160 turn_left()
161end
162
163local function step_left()
164 turn_left()
165 dig_forward()
166 safe_forward()
167 turn_right()
168end
169
170-- Carve the slice in front of the turtle for a single forward step
171-- starting at bottom edge; if start_at_left is true, begin at leftmost,
172-- otherwise begin at rightmost. Uses serpentine per-row to reduce moves.
173-- Returns boolean: are we at left edge after finishing the slice? and current level.
174local function carve_slice_fixed(start_at_left, current_level)
175 local heights = FIXED_HEIGHTS
176 local need_upper = true -- fixed pattern includes height 4 columns
177
178 local function move_to_level(target)
179 while current_level < target do safe_up(); current_level = current_level + 1 end
180 while current_level > target do safe_down(); current_level = current_level - 1 end
181 end
182
183 -- Enter slice once at start, then operate mostly at level 2
184 dig_forward(); safe_forward()
185 if (heights[start_at_left and 1 or WIDTH] or 0) >= 2 then
186 move_to_level(2)
187 else
188 current_level = 1
189 end
190
191 local end_at_left
192 if start_at_left then
193 for x = 1, WIDTH do
194 local h = heights[x] or 0
195 if current_level < 2 and h >= 2 then move_to_level(2) end
196 if current_level > 2 and h < 3 then move_to_level(2) end
197 if h >= 1 then turtle.digDown() end
198 if h >= 3 then dig_upwards() end
199 if x < WIDTH then step_right() end
200 end
201 end_at_left = false
202 else
203 for x = WIDTH, 1, -1 do
204 local h = heights[x] or 0
205 if current_level < 2 and h >= 2 then move_to_level(2) end
206 if current_level > 2 and h < 3 then move_to_level(2) end
207 if h >= 1 then turtle.digDown() end
208 if h >= 3 then dig_upwards() end
209 if x > 1 then step_left() end
210 end
211 end_at_left = true
212 end
213
214 -- Upper pass only for the 4-high columns
215 if need_upper then
216 move_to_level(3)
217 if end_at_left then
218 for x = 1, WIDTH do
219 if (heights[x] or 0) >= 4 then dig_upwards() end
220 if x < WIDTH then step_right() end
221 end
222 end_at_left = false
223 else
224 for x = WIDTH, 1, -1 do
225 if (heights[x] or 0) >= 4 then dig_upwards() end
226 if x > 1 then step_left() end
227 end
228 end_at_left = true
229 end
230 move_to_level(2)
231 end
232
233 return end_at_left, current_level
234end
235
236-- Estimate moves per slice for fueling
237local function estimate_moves_per_slice_fixed()
238 local lateral = (WIDTH - 1)
239 local vertical = 1 -- adjust to level 2
240 local need_upper = true
241 if need_upper then
242 vertical = vertical + 2 -- up to level 3 and back to 2
243 lateral = lateral + (WIDTH - 1)
244 end
245 local advance = 1 -- entering slice
246 return vertical + lateral + advance
247end
248
249local function ensure_fuel_or_prompt(threshold)
250 ensure_fuel(threshold)
251 if turtle.getFuelLevel() == "unlimited" then return end
252 if turtle.getFuelLevel() >= threshold then return end
253 term.clear()
254 term.setCursorPos(1,1)
255 print("Fuel still low. Put fuel in inventory and press Enter.")
256 read()
257 ensure_fuel(threshold)
258end
259
260-- Inventory helpers (minimal)
261local function count_empty_slots()
262 local empty = 0
263 for i = 1, 16 do
264 if turtle.getItemCount(i) == 0 then empty = empty + 1 end
265 end
266 return empty
267end
268
269local function ensure_inventory_capacity()
270 if count_empty_slots() > 0 then return end
271 term.clear()
272 term.setCursorPos(1,1)
273 print("Inventory full. Empty some slots and press Enter to continue.")
274 read()
275end
276
277local function turn_to_side(side)
278 if side == "left" then turn_left() else turn_right() end
279end
280
281local function place_torch_if_needed(step_idx, cfg, at_left_edge)
282 if not cfg.use_torches then return end
283 if cfg.torch_spacing <= 0 then return end
284 if step_idx % cfg.torch_spacing ~= 0 then return end
285 if turtle.getItemCount(cfg.torch_slot) == 0 then return end
286
287 local function place_on_side(side)
288 local h_edge = (side == "left") and FIXED_HEIGHTS[1] or FIXED_HEIGHTS[WIDTH]
289 local climbed = 0
290 if h_edge >= 2 then
291 safe_up()
292 climbed = climbed + 1
293 end
294 turn_to_side(side)
295 turtle.select(cfg.torch_slot)
296 local ok = turtle.place()
297 if not ok then
298 turn_to_side(side == "left" and "right" or "left")
299 for i = 1, climbed do safe_down() end
300 turtle.select(cfg.torch_slot)
301 ok = turtle.placeDown()
302 return
303 end
304 turn_to_side(side == "left" and "right" or "left")
305 for i = 1, climbed do safe_down() end
306 end
307
308 if cfg.torch_side == "both" then
309 if at_left_edge then
310 place_on_side("left")
311 place_on_side("right")
312 else
313 place_on_side("right")
314 place_on_side("left")
315 end
316 else
317 place_on_side(cfg.torch_side)
318 end
319end
320
321-- Main
322local function main()
323 term.clear()
324 term.setCursorPos(1,1)
325 print("Dome Tunnels Size2 v"..version)
326 print("Fixed profile: [3,3,4,4,4,3,3] (width 7)")
327 print("Place turtle at bottom-left corner, facing forward.")
328
329 local length = ask_number_default("Length (>=1):", 32, 1, 100000)
330 local use_torches = ask_yes_no("Place torches?", true)
331 local torch_spacing, torch_side, torch_slot
332 if use_torches then
333 torch_spacing = ask_number_default("Torch spacing (blocks):", 9, 1, 64)
334 torch_side = ask_choice("Torch side:", "both", {"left", "right", "both"})
335 torch_slot = ask_number_default("Torch slot (1-16):", 1, 1, 16)
336 else
337 torch_spacing = 0; torch_side = "right"; torch_slot = 1
338 end
339
340 local cfg = {
341 use_torches = use_torches,
342 torch_spacing = torch_spacing,
343 torch_side = torch_side,
344 torch_slot = torch_slot
345 }
346
347 term.clear()
348 term.setCursorPos(1,1)
349 print("Dome Tunnels Size2 v"..version)
350 print("Width:\t\t"..WIDTH)
351 print("Heights:\t\t[3,3,4,4,4,3,3]")
352 print("Length:\t\t"..length)
353 print("Torches:\t\t"..(cfg.use_torches and ("Yes (every "..cfg.torch_spacing.." blocks)") or "No"))
354 if cfg.use_torches then
355 print("Torch side:\t"..cfg.torch_side)
356 print("Torch slot:\t"..cfg.torch_slot)
357 end
358 print("")
359 print("Press Enter to start...")
360 read()
361
362 local per_slice_moves = estimate_moves_per_slice_fixed()
363 local depth = 0
364 local at_left_edge = true -- start at bottom-left by convention
365 local current_level = 1
366
367 for step = 1, length do
368 ensure_inventory_capacity()
369 local reserve_needed = per_slice_moves + depth + 10
370 if turtle.getFuelLevel() ~= "unlimited" and turtle.getFuelLevel() < reserve_needed then
371 ensure_fuel_or_prompt(reserve_needed)
372 end
373
374 at_left_edge, current_level = carve_slice_fixed(at_left_edge, current_level)
375 place_torch_if_needed(step, cfg, at_left_edge)
376 ensure_inventory_capacity()
377 depth = depth + 1
378 end
379
380 term.clear()
381 term.setCursorPos(1,1)
382 print("Done. 7-wide dome tunnel completed.")
383end
384
385main()
386
387
388