forked from martin2250/ComputerCraftLuaPrograms
-
Notifications
You must be signed in to change notification settings - Fork 0
/
OreQuarry.lua
335 lines (266 loc) · 5.84 KB
/
OreQuarry.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
-- OreQuarry by martin2250 (https://www.github.com/martin2250/)
-- This program will dig out a square from layer 5 to the specified maximum height
-- It will skip two layers a time, but it will still dig out any block not listed in badBlocks,
-- so it will remove 100% of the ores in the column while being very time and fuel efficient
-- for technical reasons, the size has to be a multiple of two
-- [][][][][][][][][][]
-- [][][][][][][][][][]
-- [][][][][][][][][][]
-- [][][][][][][][][][]
-- [][][][][][][][][][]
-- [][][][][][][][][][]
-- [][][][][][][][][][]
-- [][][][][][][][][][]
-- [][][][][][][][][][]
-- /\[][][][][][][][][]
-- C
-- [] : area that is mined out (in this case 10 by 10)
-- /\ : initial position and direction of the turtle
-- C : a chest (stack multiple chests on top of eachother for more space)
-- for very space efficient mining, use a pattern similar to this:
-- /\
-- < CC >
-- \/
if not turtle then
error("Only runs on turtles")
end
local x, y, z = 0, 0, nil
local direction = 0
local maxHeight, size, startHeight = nil, nil, nil
local badBlocks = {
["minecraft:cobblestone"]=true,
["minecraft:stone"]=true,
["minecraft:dirt"]=true,
["minecraft:gravel"]=true,
["minecraft:sand"]=true,
["minecraft:bedrock"]=true,
["minecraft:flint"]=true,
["minecraft:rotten_flesh"]=true,
["minecraft:sandstone"]=true,
["minecraft:diorite"]=true,
["minecraft:andesite"]=true,
["chisel:limestone"]=true,
["chisel:diorite"]=true,
["chisel:marble"]=true
}
local currentLayer
local chatBox = peripheral.find("chatbox")
function say(message)
print(message)
if chatBox then
pcall(chatBox.say, message) --prevent too many messages error
end
end
-- 0 y+
-- 3 ^ 1 x- x+
-- 2 y-
function turnTo(newDirection)
while newDirection < 0 do
newDirection = newDirection + 4
end
newDirection = newDirection % 4
if (newDirection - direction) % 4 > 1 then
while direction ~= newDirection do
turtle.turnLeft()
direction = (direction + 3) % 4
end
else
while direction ~= newDirection do
turtle.turnRight()
direction = (direction + 1) % 4
end
end
end
function fastSelect(i)
if turtle.getSelectedSlot() ~= i then
turtle.select(i)
end
end
function move(moveFunc, digFunc, attackFunc)
local failCount = 0
digFunc()
while not moveFunc() do
digFunc()
attackFunc()
sleep(0.25)
failCount = failCount + 1
if failCount == 100 then
say("Unable to move")
end
end
end
function up()
move(turtle.up, turtle.digUp, turtle.attackUp)
z = z + 1
end
function down()
move(turtle.down, turtle.digDown, turtle.attackDown)
z = z - 1
end
function forward()
move(turtle.forward, turtle.dig, turtle.attack)
if direction == 0 then
y = y + 1
elseif direction == 1 then
x = x + 1
elseif direction == 2 then
y = y - 1
else
x = x - 1
end
end
function check()
local success, data = turtle.inspectUp()
if success and not badBlocks[data.name] then
fastSelect(1)
turtle.digUp()
end
success, data = turtle.inspectDown()
if success and not badBlocks[data.name] then
fastSelect(1)
turtle.digDown()
end
end
function gotoZ(newZ)
while z < newZ do
up()
end
while z > newZ do
down()
end
end
function dropAndSortItems()
say("claning up inventory")
for i=1, 16 do
local data = turtle.getItemDetail(i)
if data and badBlocks[data.name] then
fastSelect(i)
turtle.dropDown()
else
for ii=1, i do
local other = turtle.getItemDetail(ii)
if not other or (other.name == data.name and turtle.getItemSpace(ii) > 0) then
fastSelect(i)
turtle.transferTo(ii)
if turtle.getItemCount(i) == 0 then
break
end
end
end
end
end
end
function emptyInventory(force)
if not force then
if turtle.getItemCount(16) == 0 then
return
end
end
dropAndSortItems()
if not force then
if turtle.getItemCount(15) == 0 then
fastSelect(1)
return
end
end
say("returning to the surface to drop off items")
local oldX, oldY, oldZ, oldDir = x, y, z, direction
turnTo(3)
while x > 0 do
forward()
end
turnTo(2)
while y > 0 do
forward()
end
gotoZ(startHeight)
for i=1, 16 do
if turtle.getItemCount(i) > 0 then
fastSelect(i)
while not turtle.drop() do
up()
end
end
end
fastSelect(1)
gotoZ(oldZ)
turnTo(0)
while y < oldY do
forward()
end
turnTo(1)
while x < oldX do
forward()
end
turnTo(oldDir)
end
startHeight, size, maxHeight, currentLayer = ...
startHeight = tonumber(startHeight)
size = tonumber(size)
maxHeight = tonumber(maxHeight)
currentLayer = tonumber(currentLayer)
if not (startHeight and size) then
print("usage: OreQuarry [Y coordinate] [Size] <Max mining height: Y-2 > <Start Height: 5>")
print("turtle will mine a square of [size] blocks")
print("place a vertical column of chests behind the turtle")
return
end
startHeight = math.floor(startHeight)
z = startHeight
size = math.floor(size)
if not currentLayer then
currentLayer = 5
end
if not maxHeight then
maxHeight = startHeight - 2
end
maxHeight = math.floor(maxHeight)
currentLayer = math.floor(currentLayer)
if size % 2 ~= 0 then
print("Size must be multiple of 2")
return
end
if size < 0 or startHeight < 6 or startHeight > 255 or maxHeight < 8 or maxHeight > startHeight - 2 then
print("Bad Arguments")
return
end
while currentLayer < maxHeight do
say("Mining Layer " .. currentLayer)
gotoZ(currentLayer)
while true do
turnTo((x % 2) * 2)
if x % 2 == 0 then
while y < size - 1 do
check()
forward()
emptyInventory()
end
else
while y > 0 do
check()
forward()
emptyInventory()
end
end
check()
if x < size - 1 then
turnTo(1)
forward()
else
turnTo(3)
while x > 0 do
forward()
end
turnTo(2)
while y > 0 do
forward()
end
break
end
end
currentLayer = currentLayer + 3
end
dropAndSortItems()
gotoZ(startHeight)
emptyInventory(true)
say("Done")