SHOW:
|
|
- or go back to the newest paste.
1 | - | function PlaceTorch() |
1 | + | -- Position tracking |
2 | - | for a = 1, 16 do |
2 | + | local currentX = 0 |
3 | - | turtle.select(a) |
3 | + | local currentY = 0 |
4 | - | c = turtle.getItemCount(a) |
4 | + | local currentZ = 0 |
5 | - | if c == 0 then |
5 | + | local facing = 0 -- 0=forward(away from chest), 1=right, 2=back(toward chest), 3=left |
6 | local startRow = true -- Track if we're starting from the front or back of the row | |
7 | local miningLength = 0 -- Store length as a module-level variable | |
8 | - | s = turtle.getItemDetail(a) |
8 | + | local forward = true -- Moved to module-level to preserve state between layers |
9 | local resumePos = {x=0, y=0, z=0, facing=0} | |
10 | - | if s.name == "minecraft:torch" then |
10 | + | |
11 | - | turtle.placeDown() |
11 | + | -- Add this at the top with other variables |
12 | - | return |
12 | + | local ESSENTIAL_ITEMS = { |
13 | ["minecraft:torch"] = 64, | |
14 | ["minecraft:cobblestone"] = 128, | |
15 | ["minecraft:dirt"] = 128, | |
16 | ["minecraft:cobbled_deepslate"] = 128 | |
17 | } | |
18 | - | local tArgs = {...} |
18 | + | |
19 | - | if #tArgs ~= 3 then |
19 | + | local function setMiningLength(len) |
20 | - | print("Requires length, width & height!") |
20 | + | miningLength = len |
21 | end | |
22 | ||
23 | - | |
23 | + | -- Utility functions |
24 | - | local x = tonumber(tArgs[1]) - 1 |
24 | + | local function findItem(itemName) |
25 | - | local y = tonumber(tArgs[2]) |
25 | + | for slot = 1, 16 do |
26 | - | local z = tonumber(tArgs[3]) |
26 | + | local item = turtle.getItemDetail(slot) |
27 | - | local x2 = 0 |
27 | + | if item and item.name == itemName then |
28 | - | local y2 = 0 |
28 | + | turtle.select(slot) |
29 | - | local startingtorch = false |
29 | + | return true |
30 | - | local distance = 0 |
30 | + | |
31 | - | local countdown = false |
31 | + | |
32 | - | |
32 | + | return false |
33 | - | if x == nil or y == nil or z == nil then |
33 | + | |
34 | ||
35 | local function hasInventorySpace() | |
36 | for slot = 1, 16 do | |
37 | - | |
37 | + | if turtle.getItemCount(slot) == 0 then |
38 | - | if x < 0 or y < 0 or z < 0 then |
38 | + | return true |
39 | - | print("Invalid (negative) dimensions!") |
39 | + | |
40 | end | |
41 | return false | |
42 | - | |
42 | + | |
43 | - | local fuel = turtle.getFuelLevel() |
43 | + | |
44 | - | local roomSize = x * y * z |
44 | + | local function handleLiquid(direction) |
45 | - | while fuel < roomSize do |
45 | + | if findItem("minecraft:cobblestone") or findItem("minecraft:dirt") or findItem("minecraft:cobbled_deepslate") then |
46 | - | if not turtle.refuel(1) then |
46 | + | if direction == "up" then |
47 | - | print("Not enough fuel!") |
47 | + | turtle.placeUp() |
48 | elseif direction == "down" then | |
49 | turtle.placeDown() | |
50 | else | |
51 | turtle.place() | |
52 | - | local xTimes = x + 1 |
52 | + | |
53 | - | local yTimes = y |
53 | + | sleep(0.5) |
54 | - | local xTorches = 0 |
54 | + | return true |
55 | - | local yTorches = 0 |
55 | + | |
56 | - | local t = true |
56 | + | return false |
57 | - | local tt = true |
57 | + | |
58 | ||
59 | - | while t == true do |
59 | + | local function turnToFacing(targetFacing) |
60 | - | if xTimes >= 4 then |
60 | + | while facing ~= targetFacing do |
61 | - | xTimes = xTimes - 4 |
61 | + | |
62 | - | xTorches = xTorches + 1 |
62 | + | facing = (facing + 1) % 4 |
63 | - | elseif xTimes < 4 and xTimes > 0 then |
63 | + | |
64 | - | xTorches = xTorches + 1 |
64 | + | |
65 | - | t = false |
65 | + | |
66 | - | elseif xTimes == 1 then |
66 | + | -- Optimized turning function that takes shortest path |
67 | - | xTorches = xTorches + 1 |
67 | + | local function turnToFacingOptimal(targetFacing) |
68 | - | t = false |
68 | + | local currentFacing = facing |
69 | local rightTurns = (targetFacing - currentFacing) % 4 | |
70 | - | t = false |
70 | + | local leftTurns = (currentFacing - targetFacing) % 4 |
71 | - | if xTimes == 0 then |
71 | + | |
72 | - | xTimes = 4 |
72 | + | if rightTurns <= leftTurns then |
73 | -- Turn right is shorter or equal | |
74 | for i = 1, rightTurns do | |
75 | turtle.turnRight() | |
76 | facing = (facing + 1) % 4 | |
77 | - | while tt == true do |
77 | + | |
78 | - | if yTimes >= 4 then |
78 | + | |
79 | - | yTimes = yTimes - 4 |
79 | + | -- Turn left is shorter |
80 | - | yTorches = yTorches + 1 |
80 | + | for i = 1, leftTurns do |
81 | - | elseif yTimes < 4 and yTimes > 0 then |
81 | + | turtle.turnLeft() |
82 | - | yTorches = yTorches + 1 |
82 | + | facing = (facing - 1) % 4 |
83 | - | tt = false |
83 | + | |
84 | - | elseif yTimes == 1 then |
84 | + | |
85 | - | yTorches = yTorches + 1 |
85 | + | |
86 | - | tt = false |
86 | + | |
87 | local function tryMove(moveFunc, digFunc, direction) | |
88 | - | tt = false |
88 | + | -- First check if there's a liquid |
89 | - | if yTimes == 0 then |
89 | + | local detectFunc |
90 | - | yTimes = 4 |
90 | + | if direction == "up" then |
91 | detectFunc = turtle.detectUp | |
92 | elseif direction == "down" then | |
93 | detectFunc = turtle.detectDown | |
94 | else | |
95 | - | local RequiredTorches = xTorches * yTorches |
95 | + | detectFunc = turtle.detect |
96 | - | local Torches = 0 |
96 | + | |
97 | ||
98 | - | for a = 1, 16 do |
98 | + | -- Maximum attempts to handle falling blocks |
99 | - | turtle.select(a) |
99 | + | local maxAttempts = 10 |
100 | - | c = turtle.getItemCount(a) |
100 | + | local attempts = 0 |
101 | - | if c == 0 then |
101 | + | |
102 | while attempts < maxAttempts do | |
103 | attempts = attempts + 1 | |
104 | - | s = turtle.getItemDetail(a) |
104 | + | |
105 | - | if s.name == "minecraft:torch" then |
105 | + | if detectFunc() then |
106 | - | Torches = Torches + c |
106 | + | -- Handle liquid first |
107 | if handleLiquid(direction) then | |
108 | digFunc() | |
109 | if moveFunc() then | |
110 | break | |
111 | - | if RequiredTorches > Torches and z > 1 then |
111 | + | end |
112 | - | print("Not enough Torches! You require a total of " .. RequiredTorches .. " Torches!") |
112 | + | else |
113 | digFunc() | |
114 | if moveFunc() then | |
115 | - | print("Good to go!") |
115 | + | break |
116 | end | |
117 | end | |
118 | - | local direction = true |
118 | + | else |
119 | - | for i = 1, z do |
119 | + | if moveFunc() then |
120 | - | for j = 1, y do |
120 | + | break |
121 | - | for k = 1, x do |
121 | + | else |
122 | - | if i == 2 and j == yTimes and k == xTimes then |
122 | + | -- If movement failed but no block detected, try handling liquid |
123 | - | PlaceTorch() |
123 | + | if handleLiquid(direction) then |
124 | - | startingtorch = true |
124 | + | if moveFunc() then |
125 | break | |
126 | - | if turtle.forward() == false then |
126 | + | end |
127 | - | repeat |
127 | + | end |
128 | - | turtle.dig() |
128 | + | |
129 | - | sleep(0.25) |
129 | + | |
130 | - | until turtle.forward() == true |
130 | + | |
131 | -- If we're still here after an attempt, brief pause before next try | |
132 | - | if i == 2 and startingtorch == true then |
132 | + | -- This helps with falling blocks settling |
133 | - | if countdown == false then |
133 | + | sleep(0.2) |
134 | - | x2 = x2 + 1 |
134 | + | |
135 | - | if x2 == 4 then |
135 | + | -- If we've tried several times and still can't move, it might be an infinite fall |
136 | - | PlaceTorch() |
136 | + | if attempts == maxAttempts then |
137 | - | x2 = 0 |
137 | + | print("Warning: Possible falling blocks causing obstruction") |
138 | return false | |
139 | - | elseif countdown == true then |
139 | + | |
140 | - | distance = distance + 1 |
140 | + | |
141 | - | if xTimes == 1 then |
141 | + | |
142 | - | if distance == (x + 1) * 3 + 1 then |
142 | + | -- Update position after successful move |
143 | - | distance = 0 |
143 | + | if attempts < maxAttempts then -- Only update if we actually moved |
144 | - | PlaceTorch() |
144 | + | if moveFunc == turtle.forward then |
145 | - | countdown = false |
145 | + | if facing == 0 then currentY = currentY - 1 |
146 | elseif facing == 1 then currentX = currentX + 1 | |
147 | - | elseif xTimes == 2 then |
147 | + | elseif facing == 2 then currentY = currentY + 1 |
148 | - | if distance == (x + 1) * 3 + 2 then |
148 | + | else currentX = currentX - 1 end |
149 | - | distance = 0 |
149 | + | elseif moveFunc == turtle.up then |
150 | - | PlaceTorch() |
150 | + | currentZ = currentZ + 1 |
151 | - | countdown = false |
151 | + | elseif moveFunc == turtle.down then |
152 | currentZ = currentZ - 1 | |
153 | - | elseif xTimes == 3 then |
153 | + | |
154 | - | if distance == (x + 1) * 3 + 3 then |
154 | + | return true |
155 | - | distance = 0 |
155 | + | |
156 | - | PlaceTorch() |
156 | + | |
157 | - | countdown = false |
157 | + | return false |
158 | end | |
159 | - | elseif xTimes == 4 then |
159 | + | |
160 | - | if distance == (x + 1) * 3 + 4 then |
160 | + | -- Optimized turning function that takes shortest path |
161 | - | distance = 0 |
161 | + | local function turnToFacingOptimal(targetFacing) |
162 | - | PlaceTorch() |
162 | + | local currentFacing = facing |
163 | - | countdown = false |
163 | + | local rightTurns = (targetFacing - currentFacing) % 4 |
164 | local leftTurns = (currentFacing - targetFacing) % 4 | |
165 | ||
166 | if rightTurns <= leftTurns then | |
167 | -- Turn right is shorter or equal | |
168 | for i = 1, rightTurns do | |
169 | - | if j < y then |
169 | + | turtle.turnRight() |
170 | - | if direction then |
170 | + | facing = (facing + 1) % 4 |
171 | - | if i == 2 and countdown == false and startingtorch == true then |
171 | + | |
172 | - | countdown = true |
172 | + | |
173 | -- Turn left is shorter | |
174 | for i = 1, leftTurns do | |
175 | - | if turtle.forward() == false then |
175 | + | turtle.turnLeft() |
176 | - | repeat |
176 | + | facing = (facing - 1) % 4 |
177 | - | turtle.dig() |
177 | + | |
178 | - | sleep(0.25) |
178 | + | |
179 | - | until turtle.forward() == true |
179 | + | |
180 | ||
181 | - | if i == 2 and startingtorch == true and countdown == true then |
181 | + | local function returnToChest() |
182 | - | distance = distance + 1 |
182 | + | local returnFacing = facing |
183 | local pathFound = false | |
184 | ||
185 | - | direction = false |
185 | + | -- Try multiple vertical levels to find an open path |
186 | local function tryPathAtLevel(targetZ) | |
187 | - | turtle.turnLeft() |
187 | + | -- Move to target Z level first |
188 | - | if turtle.forward() == false then |
188 | + | while currentZ > targetZ do |
189 | - | repeat |
189 | + | if not turtle.down() then return false end |
190 | - | turtle.dig() |
190 | + | currentZ = currentZ - 1 |
191 | - | sleep(0.25) |
191 | + | |
192 | - | until turtle.forward() == true |
192 | + | while currentZ < targetZ do |
193 | if not turtle.up() then return false end | |
194 | - | if i == 2 and startingtorch == true and countdown == true then |
194 | + | currentZ = currentZ + 1 |
195 | - | distance = distance + 1 |
195 | + | |
196 | - | if xTimes == 1 then |
196 | + | |
197 | - | if distance == (x + 1) * 3 + 1 then |
197 | + | -- Face toward chest (facing 2) |
198 | - | distance = 0 |
198 | + | turnToFacingOptimal(2) |
199 | - | PlaceTorch() |
199 | + | |
200 | - | countdown = false |
200 | + | -- Try Y movement without digging |
201 | local initialY = currentY | |
202 | - | elseif xTimes == 2 then |
202 | + | while currentY < 0 do |
203 | - | if distance == (x + 1) * 3 + 2 then |
203 | + | if not turtle.forward() then |
204 | - | distance = 0 |
204 | + | -- If blocked, restore position and return false |
205 | - | PlaceTorch() |
205 | + | while currentY < initialY do |
206 | - | countdown = false |
206 | + | turtle.back() |
207 | currentY = currentY + 1 | |
208 | - | elseif xTimes == 3 then |
208 | + | end |
209 | - | if distance == (x + 1) * 3 + 3 then |
209 | + | return false |
210 | - | distance = 0 |
210 | + | |
211 | - | PlaceTorch() |
211 | + | currentY = currentY + 1 |
212 | - | countdown = false |
212 | + | |
213 | ||
214 | - | elseif xTimes == 4 then |
214 | + | -- Try X movement without digging |
215 | - | if distance == (x + 1) * 3 + 4 then |
215 | + | if currentX ~= 0 then |
216 | - | distance = 0 |
216 | + | if currentX > 0 then |
217 | - | PlaceTorch() |
217 | + | turnToFacingOptimal(3) -- face left |
218 | - | countdown = false |
218 | + | else |
219 | turnToFacingOptimal(1) -- face right | |
220 | end | |
221 | ||
222 | - | turtle.turnLeft() |
222 | + | local initialX = currentX |
223 | - | direction = true |
223 | + | while currentX ~= 0 do |
224 | if not turtle.forward() then | |
225 | -- If blocked, restore position and return false | |
226 | while currentX ~= initialX do | |
227 | - | if i < z then |
227 | + | turtle.back() |
228 | - | turtle.digUp() |
228 | + | currentX = currentX + (currentX > 0 and 1 or -1) |
229 | - | turtle.up() |
229 | + | end |
230 | return false | |
231 | - | turtle.turnRight() |
231 | + | end |
232 | currentX = currentX + (currentX > 0 and -1 or 1) | |
233 | end | |
234 | - | |
234 | + | |
235 | - | if y % 2 == 0 then |
235 | + | |
236 | - | turtle.turnRight() |
236 | + | return true |
237 | - | for i = 1, y do |
237 | + | |
238 | - | turtle.forward() |
238 | + | |
239 | -- Try paths at different levels, starting with levels we expect to be clear | |
240 | - | turtle.turnRight() |
240 | + | local levelsToTry = { |
241 | 0, -- Ground level (where chest is) | |
242 | - | turtle.turnLeft() |
242 | + | -1, -- One below ground |
243 | - | for i = 1, y do |
243 | + | 1, -- One above ground |
244 | - | turtle.forward() |
244 | + | currentZ, -- Current level |
245 | } | |
246 | - | turtle.turnLeft() |
246 | + | |
247 | - | for i = 1, x do |
247 | + | -- Add intermediate levels if we're far from 0 |
248 | - | turtle.forward() |
248 | + | if math.abs(currentZ) > 1 then |
249 | table.insert(levelsToTry, math.floor(currentZ/2)) | |
250 | - | turtle.turnRight() |
250 | + | |
251 | - | turtle.turnRight() |
251 | + | |
252 | -- Try each level until we find a clear path | |
253 | - | for i = 1, z do |
253 | + | for _, targetZ in ipairs(levelsToTry) do |
254 | - | turtle.down() |
254 | + | if tryPathAtLevel(targetZ) then |
255 | pathFound = true | |
256 | break | |
257 | end | |
258 | end | |
259 | ||
260 | -- If no clear path found, fall back to original digging behavior | |
261 | if not pathFound then | |
262 | -- Original digging behavior | |
263 | while currentZ > 0 do | |
264 | if not tryMove(turtle.down, turtle.digDown, "down") then | |
265 | print("Can't move down to Z=0") | |
266 | return false | |
267 | end | |
268 | end | |
269 | while currentZ < 0 do | |
270 | if not tryMove(turtle.up, turtle.digUp, "up") then | |
271 | print("Can't move up to Z=0") | |
272 | return false | |
273 | end | |
274 | end | |
275 | ||
276 | turnToFacingOptimal(2) | |
277 | while currentY < 0 do | |
278 | if not tryMove(turtle.forward, turtle.dig, "forward") then | |
279 | print("Obstruction while returning on Y axis") | |
280 | return false | |
281 | end | |
282 | end | |
283 | ||
284 | if currentX ~= 0 then | |
285 | if currentX > 0 then | |
286 | turnToFacingOptimal(3) | |
287 | else | |
288 | turnToFacingOptimal(1) | |
289 | end | |
290 | ||
291 | while currentX ~= 0 do | |
292 | if not tryMove(turtle.forward, turtle.dig, "forward") then | |
293 | print("Obstruction while returning on X axis") | |
294 | return false | |
295 | end | |
296 | end | |
297 | end | |
298 | end | |
299 | ||
300 | -- Final position verification and facing correction | |
301 | if currentX ~= 0 or currentY ~= 0 or currentZ ~= 0 then | |
302 | print("Failed to reach chest position!") | |
303 | return false | |
304 | end | |
305 | ||
306 | -- Ensure we're facing the chest (facing 2) at the end | |
307 | turnToFacingOptimal(2) | |
308 | ||
309 | return true | |
310 | end | |
311 | ||
312 | local function hasEssentialItems() | |
313 | local hasTorches = false | |
314 | local hasBlocks = false | |
315 | ||
316 | for slot = 1, 16 do | |
317 | local item = turtle.getItemDetail(slot) | |
318 | if item then | |
319 | if item.name == "minecraft:torch" then | |
320 | hasTorches = true | |
321 | elseif item.name == "minecraft:cobblestone" | |
322 | or item.name == "minecraft:dirt" | |
323 | or item.name == "minecraft:cobbled_deepslate" then | |
324 | hasBlocks = true | |
325 | end | |
326 | end | |
327 | end | |
328 | ||
329 | return hasTorches and hasBlocks | |
330 | end | |
331 | ||
332 | -- Modified hasOperationalInventory | |
333 | local function hasOperationalInventory() | |
334 | -- Check if we have at least 1 free slot AND essential items | |
335 | local hasSpace = false | |
336 | local preservedItems = {} | |
337 | ||
338 | -- First check for space | |
339 | for slot = 1, 16 do | |
340 | if turtle.getItemCount(slot) == 0 then | |
341 | hasSpace = true | |
342 | break | |
343 | end | |
344 | end | |
345 | ||
346 | -- Then check essential items | |
347 | for itemName in pairs(ESSENTIAL_ITEMS) do | |
348 | local found = false | |
349 | for slot = 1, 16 do | |
350 | local item = turtle.getItemDetail(slot) | |
351 | if item and item.name == itemName then | |
352 | found = true | |
353 | break | |
354 | end | |
355 | end | |
356 | if not found then | |
357 | return false | |
358 | end | |
359 | end | |
360 | ||
361 | return hasSpace | |
362 | end | |
363 | ||
364 | ||
365 | local function dumpInventory() | |
366 | -- Store current position | |
367 | resumePos.x = currentX | |
368 | resumePos.y = currentY | |
369 | resumePos.z = currentZ | |
370 | resumePos.facing = facing | |
371 | ||
372 | -- Return to chest | |
373 | print("Inventory full! Returning to chest...") | |
374 | if not returnToChest() then return false end | |
375 | ||
376 | -- Track preserved quantities | |
377 | local preserved = { | |
378 | ["minecraft:torch"] = 0, | |
379 | ["minecraft:cobblestone"] = 0, | |
380 | ["minecraft:dirt"] = 0, | |
381 | ["minecraft:cobbled_deepslate"] = 0 | |
382 | } | |
383 | ||
384 | -- First pass: Calculate total preserved items | |
385 | for slot = 1, 16 do | |
386 | local item = turtle.getItemDetail(slot) | |
387 | if item and ESSENTIAL_ITEMS[item.name] then | |
388 | preserved[item.name] = preserved[item.name] + item.count | |
389 | end | |
390 | end | |
391 | ||
392 | -- Second pass: Drop excess items | |
393 | for slot = 1, 16 do | |
394 | turtle.select(slot) | |
395 | local item = turtle.getItemDetail(slot) | |
396 | ||
397 | if item then | |
398 | local itemName = item.name | |
399 | if ESSENTIAL_ITEMS[itemName] then | |
400 | local maxKeep = ESSENTIAL_ITEMS[itemName] | |
401 | local alreadyPreserved = preserved[itemName] | |
402 | ||
403 | if alreadyPreserved > maxKeep then | |
404 | -- Drop excess from this slot | |
405 | local toDrop = math.min(alreadyPreserved - maxKeep, item.count) | |
406 | turtle.drop(toDrop) | |
407 | preserved[itemName] = preserved[itemName] - toDrop | |
408 | end | |
409 | else | |
410 | -- Drop all non-essential items | |
411 | turtle.drop() | |
412 | end | |
413 | end | |
414 | end | |
415 | ||
416 | -- Return to mining position with optimized movement | |
417 | -- Move vertically first | |
418 | while currentZ ~= resumePos.z do | |
419 | if currentZ < resumePos.z then | |
420 | tryMove(turtle.up, turtle.digUp, "up") | |
421 | else | |
422 | tryMove(turtle.down, turtle.digDown, "down") | |
423 | end | |
424 | end | |
425 | ||
426 | -- Optimize Y movement | |
427 | if currentY ~= resumePos.y then | |
428 | if currentY > resumePos.y then | |
429 | turnToFacingOptimal(0) -- Face mining direction | |
430 | else | |
431 | turnToFacingOptimal(2) -- Face chest direction | |
432 | end | |
433 | while currentY ~= resumePos.y do | |
434 | tryMove(turtle.forward, turtle.dig, "forward") | |
435 | end | |
436 | end | |
437 | ||
438 | -- Optimize X movement | |
439 | if currentX ~= resumePos.x then | |
440 | if currentX < resumePos.x then | |
441 | turnToFacingOptimal(1) -- Face right | |
442 | else | |
443 | turnToFacingOptimal(3) -- Face left | |
444 | end | |
445 | while currentX ~= resumePos.x do | |
446 | tryMove(turtle.forward, turtle.dig, "forward") | |
447 | end | |
448 | end | |
449 | ||
450 | -- Return to original facing | |
451 | turnToFacingOptimal(resumePos.facing) | |
452 | return true | |
453 | end | |
454 | ||
455 | local function dumpAllInventory() | |
456 | -- Return to chest if not already there | |
457 | if currentX ~= 0 or currentY ~= 0 or currentZ ~= 0 then | |
458 | if not returnToChest() then | |
459 | print("Failed to return to chest!") | |
460 | return false | |
461 | end | |
462 | end | |
463 | ||
464 | -- Ensure facing chest | |
465 | turnToFacingOptimal(2) | |
466 | ||
467 | -- Small delay to ensure stable chest interaction | |
468 | sleep(0.5) | |
469 | ||
470 | -- Dump everything from inventory | |
471 | for slot = 1, 16 do | |
472 | turtle.select(slot) | |
473 | -- Drop entire stack, regardless of item type | |
474 | turtle.drop() | |
475 | end | |
476 | ||
477 | return true | |
478 | end | |
479 | ||
480 | local function calculateTorches(length, width) | |
481 | return math.ceil(length/4) * math.ceil(width/4) | |
482 | end | |
483 | ||
484 | -- Main Program | |
485 | local args = {...} | |
486 | if #args < 3 then | |
487 | print("Usage: digRoom <length> <width> <height> [horizontal] [vertical]") | |
488 | print("horizontal: left/right (default: right)") | |
489 | print("vertical: up/down (default: up)") | |
490 | return | |
491 | end | |
492 | ||
493 | local length = tonumber(args[1]) | |
494 | local width = tonumber(args[2]) | |
495 | local height = tonumber(args[3]) | |
496 | local horizontalDir = args[4] or "right" | |
497 | local verticalDir = args[5] or "up" | |
498 | ||
499 | setMiningLength(length) | |
500 | ||
501 | if not (length and width and height) or length < 1 or width < 1 or height < 1 then | |
502 | print("Invalid dimensions!") | |
503 | return | |
504 | end | |
505 | ||
506 | if horizontalDir ~= "left" and horizontalDir ~= "right" then | |
507 | print("Invalid horizontal direction! Use 'left' or 'right'") | |
508 | return | |
509 | end | |
510 | ||
511 | if verticalDir ~= "up" and verticalDir ~= "down" then | |
512 | print("Invalid vertical direction! Use 'up' or 'down'") | |
513 | return | |
514 | end | |
515 | ||
516 | -- Calculate required resources | |
517 | local totalBlocks = length * width * height | |
518 | local fuelNeeded = totalBlocks + height + math.ceil(width/2) * 2 | |
519 | local requiredTorches = height > 1 and calculateTorches(length, width) or 0 | |
520 | ||
521 | -- Check fuel | |
522 | if turtle.getFuelLevel() < fuelNeeded then | |
523 | print(string.format("Need %d fuel, have %d", fuelNeeded, turtle.getFuelLevel())) | |
524 | return | |
525 | end | |
526 | ||
527 | -- Check torches if needed | |
528 | if requiredTorches > 0 then | |
529 | local torchCount = 0 | |
530 | for slot = 1, 16 do | |
531 | local item = turtle.getItemDetail(slot) | |
532 | if item and item.name == "minecraft:torch" then | |
533 | torchCount = torchCount + turtle.getItemCount(slot) | |
534 | end | |
535 | end | |
536 | if torchCount < requiredTorches then | |
537 | print(string.format("Need %d torches, have %d", requiredTorches, torchCount)) | |
538 | return | |
539 | end | |
540 | end | |
541 | ||
542 | -- Check for blocking material | |
543 | local hasBlockingMaterial = false | |
544 | for slot = 1, 16 do | |
545 | local item = turtle.getItemDetail(slot) | |
546 | if item and (item.name == "minecraft:cobblestone" or item.name == "minecraft:dirt" or item.name == "minecraft:cobbled_deepslate") then | |
547 | hasBlockingMaterial = true | |
548 | break | |
549 | end | |
550 | end | |
551 | ||
552 | if not hasBlockingMaterial then | |
553 | print("Warning: No blocks available for liquid handling") | |
554 | print("Recommend having cobblestone, dirt, or cobbled deepslate") | |
555 | print("Continue anyway? (y/n)") | |
556 | local response = read():lower() | |
557 | if response ~= "y" then | |
558 | return | |
559 | end | |
560 | end | |
561 | ||
562 | local function turnToDir(targetDir) | |
563 | if horizontalDir == "left" then | |
564 | if targetDir == "right" then | |
565 | turtle.turnLeft() | |
566 | facing = (facing - 1) % 4 | |
567 | else | |
568 | turtle.turnRight() | |
569 | facing = (facing + 1) % 4 | |
570 | end | |
571 | else | |
572 | if targetDir == "right" then | |
573 | turtle.turnRight() | |
574 | facing = (facing + 1) % 4 | |
575 | else | |
576 | turtle.turnLeft() | |
577 | facing = (facing - 1) % 4 | |
578 | end | |
579 | end | |
580 | end | |
581 | ||
582 | local function moveVertical() | |
583 | if verticalDir == "up" then | |
584 | return turtle.up, turtle.digUp, "up" | |
585 | else | |
586 | return turtle.down, turtle.digDown, "down" | |
587 | end | |
588 | end | |
589 | ||
590 | -- Modified inventory check in mining loop | |
591 | local function mineLayer() | |
592 | for row = 1, width do | |
593 | for col = 1, length - 1 do | |
594 | -- New inventory check logic | |
595 | local hasSpace = false | |
596 | for slot = 1, 16 do | |
597 | if turtle.getItemCount(slot) == 0 then | |
598 | hasSpace = true | |
599 | break | |
600 | end | |
601 | end | |
602 | ||
603 | if not hasSpace then | |
604 | if not dumpInventory() then | |
605 | print("Aborting mining operation") | |
606 | return false | |
607 | end | |
608 | end | |
609 | ||
610 | -- Only place torches in larger rooms or narrow corridors with enough length | |
611 | if (row == 2 and col % 4 == 0) and | |
612 | ((width > 2) or (width <= 2 and col >= math.ceil(length / 2))) then | |
613 | if findItem("minecraft:torch") then | |
614 | turtle.placeDown() | |
615 | end | |
616 | end | |
617 | ||
618 | if not tryMove(turtle.forward, turtle.dig, "forward") then | |
619 | print("Obstruction detected") | |
620 | return false | |
621 | end | |
622 | end | |
623 | ||
624 | if row < width then | |
625 | if forward then | |
626 | turnToDir("right") | |
627 | if not tryMove(turtle.forward, turtle.dig, "forward") then return false end | |
628 | turnToDir("right") | |
629 | startRow = false | |
630 | else | |
631 | turnToDir("left") | |
632 | if not tryMove(turtle.forward, turtle.dig, "forward") then return false end | |
633 | turnToDir("left") | |
634 | startRow = true | |
635 | end | |
636 | forward = not forward -- Toggle direction for next row | |
637 | end | |
638 | end | |
639 | ||
640 | return true | |
641 | end | |
642 | ||
643 | -- Modified end of main program | |
644 | for layer = 1, height do | |
645 | if width % 2 == 0 then | |
646 | forward = (layer % 2 == 1) | |
647 | else | |
648 | forward = true | |
649 | end | |
650 | ||
651 | if not mineLayer() then break end | |
652 | ||
653 | if layer < height then | |
654 | -- Move up/down | |
655 | local moveFunc, digFunc, direction = moveVertical() | |
656 | if not tryMove(moveFunc, digFunc, direction) then | |
657 | print("Warning: Unable to move " .. verticalDir .. " (possible liquid)") | |
658 | print("Try again? (y/n)") | |
659 | local response = read():lower() | |
660 | if response ~= "y" then | |
661 | break | |
662 | end | |
663 | end | |
664 | ||
665 | -- Turn around for next layer | |
666 | turtle.turnRight() | |
667 | turtle.turnRight() | |
668 | facing = (facing + 2) % 4 | |
669 | end | |
670 | end | |
671 | ||
672 | -- Final return and dump all inventory | |
673 | print("Mining complete! Returning to chest...") | |
674 | if dumpAllInventory() then | |
675 | print("All items deposited in chest.") | |
676 | turnToFacingOptimal(0) | |
677 | else | |
678 | print("Failed to deposit all items!") | |
679 | end |