-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbuilder.lua
More file actions
442 lines (387 loc) · 16.2 KB
/
builder.lua
File metadata and controls
442 lines (387 loc) · 16.2 KB
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
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
local robot = require("robot")
local term = require("term")
local os = require("os")
local component = require("component")
local sides = require("sides")
keyboard = require("keyboard")
local computer = require("computer")
--[[
--------------------------INTRO--------------------------
This program builds structures using a robot.
The robot should begin in front of the first layer of your schematic on the far right side, facing the schematic.
e.g. (where X is an element of your schematic in the csv and R is the robot)
R
XXXXXXX
XXXXXXX S
XXXXXXX E W (This compass is oriented re: the direction the robot faces at start)
XXXXXXX N
Note: you can instruct the robot to place a block on a specific surface by appending a #top/#bottom/#north/#south/#east/#west hashtag on the end of a cell in your .csv. See above for cardinal directions in the CSV file and below for example of an orientation hashtag.
(Note orientation tags may fail unless the relevant surface is available to be placed upon. I recommend you place all oriented blocks from above and check your .csv schematic to make sure the relevant surface will be available to be placed upon)
Place schematics in the same directory as this program before running. This program supports .csv files formatted like this:
1,, -- note this is the first layer (commas are not optional and need to equal (the width of your schematic)-1)
dirt,dirt,dirt -- front row
dirt,air,dirt -- air represents air blocks
dirt,dirt,dirt
2,, -- note this is the second layer
sand,sand,sand
sand,air,torch#south -- Note this torch will be placed in a southerly direction.
sand,sand,sand -- back row
Slot 1: Diamond Pickaxe (Or a lesser pick if you're cheap)
Slots 2-infinity: As the program tells you based on the schematic.
NOTE: This program assumes you have some means of generating power in the robot - i.e. solar or generator. It will stop to recharge when necessary. This program also assumes that you have installed an inventory controller.
]]
-- Read Schematic
function tableLength(table)
count = 1
while table[count] ~= nil do
count=count+1
end
return count-1
end
function removeOrientation(nameo)
nameo = string.gsub(nameo, "#bottom", "")
nameo = string.gsub(nameo, "#top", "")
nameo = string.gsub(nameo, "#east", "")
nameo = string.gsub(nameo, "#west", "")
nameo = string.gsub(nameo, "#north", "")
nameo = string.gsub(nameo, "#south", "")
return nameo
end
print("Schematic Name: (Include any filetype suffix)")
schematicFile = io.read()
schHeight = 0
schWidth = 0
schDepth = 0
schArray = {}
for line in io.lines(/schematics/schematicFile) do
schWidth = 0
if tonumber(string.gsub(line, ",", "")) ~= schHeight+1 then
schDepth=schDepth+1
schArray[schHeight][schDepth] = {}
end
for word in string.gmatch(line, '([^,]+)') do
if tonumber(word) == schHeight+1 then
schHeight = schHeight+1
schArray[schHeight] = {}
schDepth = 0
break
else
schWidth = schWidth+1
schArray[schHeight][schDepth][schWidth] = word
end
end
end
-- add top layer of pure air
schArray[schHeight+1] = {}
for row=1, tableLength(schArray[1]) do
schArray[schHeight+1][row] = {}
for wid=1, tableLength(schArray[1][1]) do
schArray[schHeight+1][row][wid] = "air"
end
end
print("...Schematic Imported.")
print(" ")
-- Analyze Components
compArray = {}
emptySlot = 1
name = 1
quantity = 2
for a=1, tableLength(schArray) do
for b=1, tableLength(schArray[1]) do
for c=1, tableLength(schArray[1][1]) do
foundIt=false
for i=1, tableLength(compArray) do
if removeOrientation(schArray[a][b][c]) == compArray[i][name] then
compArray[i][quantity] = compArray[i][quantity]+1
foundIt = true
break
end
end
if foundIt == false then
compArray[emptySlot] = {}
compArray[emptySlot][name] = removeOrientation(schArray[a][b][c])
compArray[emptySlot][quantity] = 1
emptySlot = emptySlot+1
end
end
end
end
above = 0
print("Please indicate which items need to be placed from above (y/n): e.g. torches, ladders")
for i=1, tableLength(compArray) do
above = "x"
if compArray[i][1] ~= "air" then
print(compArray[i][1].."?")
while above ~="y" and above~="n" do above = io.read() end
if above == "y" then compArray[i][3] = 1 else compArray[i][3] = 0 end
else
compArray[i][3] = 0
end
end
term.clear()
print("Material Confirmation... Note: this program does not yet support items that don't stack to 64.")
print("One Pickaxe!")
for i=1, tableLength(compArray) do
iSlots = compArray[i][2]/64
if compArray[i][3] == 1 then append = "Place from Above" else append = "Place normally" end
if compArray[i][1]~="air" then print(compArray[i][2].." "..compArray[i][1]..": -"..append..": "..iSlots.." stacks.") end
end
print("*Make sure your robot has enough inventory space for this!")
print(" ")
print("--- Press Space For Loading Instructions ---")
print("(Or Press Ctrl+Alt+c to exit)")
while not keyboard.isKeyDown(keyboard.keys.space) do os.sleep(0.1) end
term.clear()
-- set up dedicated inventory slots
freeSlot=2
for i=1, tableLength(compArray) do
if compArray[i][1]~="air" then compArray[i][4]=freeSlot freeSlot=math.ceil(compArray[i][2]/64)+freeSlot end
end
print("Robot Inventory Instructions:")
print(" --> One Pickaxe in slot 1.")
for i=1, tableLength(compArray) do
if compArray[i][1]~="air" then
print(" --> "..compArray[i][2].." units of "..compArray[i][1].." in slots "..compArray[i][4].." to "..compArray[i][4]+math.floor(compArray[i][2]/64)..".")
end
end
print(" ")
print("--- Press Enter When Ready to Begin ---")
while not keyboard.isKeyDown(keyboard.keys.enter) do os.sleep(0.1) end
term.clear()
robot.select(1)
component.inventory_controller.equip()
print("Building...")
nextMove = "right"
function place(block) -- checks to see if the slot is empty, if so selects next and ticks item slot, places appropriate block
z=1
block, pBottom = string.gsub(block, "#bottom", "")
block, pTop = string.gsub(block, "#top", "")
block, pEast = string.gsub(block, "#east", "")
block, pWest = string.gsub(block, "#west", "")
block, pNorth = string.gsub(block, "#north", "")
block, pSouth = string.gsub(block, "#south", "")
while compArray[z][1]~=block do z=z+1 end
if component.inventory_controller.getStackInInternalSlot(compArray[z][4]) == nil then compArray[z][4]=compArray[z][4]+1 end
robot.select(compArray[z][4])
if pBottom == 1 then
robot.place(0)
elseif pTop == 1 then
robot.place(1)
elseif pEast == 1 then
if nextMove == "right" then robot.place(3) end
if nextMove == "left" then robot.place(3) print("Can't place on the robot itself! falling back to the opposite side.") end
elseif pWest == 1 then
if nextMove == "right" then robot.place(3) print("Can't place on the robot itself! falling back to the opposite side.") end
if nextMove == "left" then robot.place(3) end
elseif pNorth == 1 then
if nextMove == "right" then robot.place(5) end
if nextMove == "left" then robot.place(4) end
elseif pSouth == 1 then
if nextMove == "right" then robot.place(4) end
if nextMove == "left" then robot.place(5) end
else
robot.place()
end
end
function placeDown(block) -- same but down
z=1
block, pBottom = string.gsub(block, "#bottom", "")
block, pTop = string.gsub(block, "#top", "")
block, pEast = string.gsub(block, "#east", "")
block, pWest = string.gsub(block, "#west", "")
block, pNorth = string.gsub(block, "#north", "")
block, pSouth = string.gsub(block, "#south", "")
while compArray[z][1]~=block do z=z+1 end
if component.inventory_controller.getStackInInternalSlot(compArray[z][4]) == nil then compArray[z][4]=compArray[z][4]+1 end
robot.select(compArray[z][4])
if pBottom == 1 then
robot.placeDown(0)
elseif pTop == 1 then
robot.placeDown(1)
elseif pEast == 1 then
if nextMove == "right" then robot.placeDown(3) end
if nextMove == "left" then robot.placeDown(2) end
elseif pWest == 1 then
if nextMove == "right" then robot.placeDown(2) end
if nextMove == "left" then robot.placeDown(3) end
elseif pNorth == 1 then
if nextMove == "right" then robot.placeDown(5) end
if nextMove == "left" then robot.placeDown(4) end
elseif pSouth == 1 then
if nextMove == "right" then robot.placeDown(4) end
if nextMove == "left" then robot.placeDown(5) end
else
robot.placeDown()
end
end
function move() -- checks to see if robot can move, if not, break block
if computer.energy() < 1000 then print("Charging...") while computer.energy() < computer.maxEnergy() do os.sleep(10) end end
if robot.back() == nil then
robot.turnAround()
robot.select(1)
robot.swing()
if component.inventory_controller.getStackInInternalSlot(1) ~= nil then
trashSlot = robot.inventorySize()
slotAdequate = false
while slotAdequate == false do
if component.inventory_controller.getStackInInternalSlot(trashSlot) == nil then slotAdequate = true break end
if robot.compareTo(trashSlot) == true and component.inventory_controller.getStackInInternalSlot(trashSlot).size <64 then slotAdequate = true break end
trashSlot=trashSlot-1
if trashSlot == 1 then robot.drop() break end
end
if slotAdequate == true then robot.transferTo(trashSlot) end
end
while robot.forward() == nil do
os.sleep(2)
robot.select(1)
robot.swing()
if component.inventory_controller.getStackInInternalSlot(1) ~= nil then
trashSlot = robot.inventorySize()
slotAdequate = false
while slotAdequate == false do
if component.inventory_controller.getStackInInternalSlot(trashSlot) == nil then slotAdequate = true break end
if robot.compareTo(trashSlot) == true and component.inventory_controller.getStackInInternalSlot(trashSlot).size <64 then slotAdequate = true break end
trashSlot=trashSlot-1
if trashSlot == 1 then robot.drop() break end
end
if slotAdequate == true then robot.transferTo(trashSlot) end
end
end
robot.turnAround()
end
end
function moveUp()
if computer.energy() < 1000 then print("Charging...") while computer.energy() < computer.maxEnergy() do os.sleep(10) end end
if robot.up() == nil then
robot.select(1)
robot.swingUp()
if component.inventory_controller.getStackInInternalSlot(1) ~= nil then
trashSlot = robot.inventorySize()
slotAdequate = false
while slotAdequate == false do
if component.inventory_controller.getStackInInternalSlot(trashSlot) == nil then slotAdequate = true break end
if robot.compareTo(trashSlot) == true and component.inventory_controller.getStackInInternalSlot(trashSlot).size <64 then slotAdequate = true break end
trashSlot=trashSlot-1
if trashSlot == 1 then robot.drop() break end
end
if slotAdequate == true then robot.transferTo(trashSlot) end
end
while robot.up() == nil do
os.sleep(2)
robot.select(1)
robot.swingUp()
if component.inventory_controller.getStackInInternalSlot(1) ~= nil then
trashSlot = robot.inventorySize()
slotAdequate = false
while slotAdequate == false do
if component.inventory_controller.getStackInInternalSlot(trashSlot) == nil then slotAdequate = true break end
if robot.compareTo(trashSlot) == true and component.inventory_controller.getStackInInternalSlot(trashSlot).size <64 then slotAdequate = true break end
trashSlot=trashSlot-1
if trashSlot == 1 then robot.drop() break end
end
if slotAdequate == true then robot.transferTo(trashSlot) end
end
end
end
end
function moveDown()
if computer.energy() < 1000 then print("Charging...") while computer.energy() < computer.maxEnergy() do os.sleep(10) end end
if robot.down() == nil then
robot.select(1)
robot.swingDown()
if component.inventory_controller.getStackInInternalSlot(1) ~= nil then
trashSlot = robot.inventorySize()
slotAdequate = false
while slotAdequate == false do
if component.inventory_controller.getStackInInternalSlot(trashSlot) == nil then slotAdequate = true break end
if robot.compareTo(trashSlot) == true and component.inventory_controller.getStackInInternalSlot(trashSlot).size <64 then slotAdequate = true break end
trashSlot=trashSlot-1
if trashSlot == 1 then robot.drop() break end
end
if slotAdequate == true then robot.transferTo(trashSlot) end
end
while robot.down() == nil do
os.sleep(2)
robot.select(1)
robot.swingDown()
if component.inventory_controller.getStackInInternalSlot(1) ~= nil then
trashSlot = robot.inventorySize()
slotAdequate = false
while slotAdequate == false do
if component.inventory_controller.getStackInInternalSlot(trashSlot) == nil then slotAdequate = true break end
if robot.compareTo(trashSlot) == true and component.inventory_controller.getStackInInternalSlot(trashSlot).size <64 then slotAdequate = true break end
trashSlot=trashSlot-1
if trashSlot == 1 then robot.drop() break end
end
if slotAdequate == true then robot.transferTo(trashSlot) end
end
end
end
end
function shouldBPD(block)
block = string.gsub(block, "#bottom", "")
block = string.gsub(block, "#top", "")
block = string.gsub(block, "#east", "")
block = string.gsub(block, "#west", "")
block = string.gsub(block, "#north", "")
block = string.gsub(block, "#south", "")
should = false
z=1
while compArray[z][1]~=block do z=z+1 end
if compArray[z][3] == 1 then should = true end
return should
end
-- Build Program
robot.turnAround() -- Turn Around
move() -- get in chunk
robot.turnLeft() -- face widthways
for h=1, tableLength(schArray) do
nextMove ="right"
for d=1, tableLength(schArray[1]) do
if nextMove == "right" then
for w=1, tableLength(schArray[1][1]), 1 do -- left to right
if h~=1 then if schArray[h-1][d][w] ~= "air" and schArray[h-1][d][w] ~= nil then if shouldBPD(schArray[h-1][d][w]) then placeDown(schArray[h-1][d][w]) end end end
if w~=1 then if schArray[h][d][w-1] ~= "air" and schArray[h][d][w-1] ~= nil then if shouldBPD(schArray[h][d][w-1]) == false then place(schArray[h][d][w-1]) end end end
if w~=tableLength(schArray[1][1]) then move() else
if d~= tableLength(schArray[1]) then
robot.turnRight()
move()
if schArray[h][d][w] ~= "air" and schArray[h][d][w] ~= nil then if shouldBPD(schArray[h][d][w]) == false then place(schArray[h][d][w]) end end
robot.turnRight()
else
moveUp()
if schArray[h][d][w] ~= "air" and schArray[h][d][w] ~= nil then placeDown(schArray[h][d][w]) end
for i=1, tableLength(schArray[1][1])-1 do move() end robot.turnRight() for i=1, tableLength(schArray[1])-1 do move() end robot.turnLeft()
end
end
end
end
if nextMove == "left" then
for w=tableLength(schArray[1][1]), 1, -1 do -- right to left
if h~=1 then if schArray[h-1][d][w] ~= "air" and schArray[h-1][d][w] ~= nil then if shouldBPD(schArray[h-1][d][w]) then placeDown(schArray[h-1][d][w]) end end end
if w~=tableLength(schArray[1][1]) then if schArray[h][d][w+1] ~= "air" and schArray[h][d][w+1] ~= nil then if shouldBPD(schArray[h][d][w+1]) == false then place(schArray[h][d][w+1]) end end end
if w~=1 then move() else
if d~= tableLength(schArray[1]) then
robot.turnLeft()
move()
if schArray[h][d][w] ~= "air" and schArray[h][d][w] ~= nil then if shouldBPD(schArray[h][d][w]) == false then place(schArray[h][d][w]) end end
robot.turnLeft()
else
moveUp()
if schArray[h][d][w] ~= "air" and schArray[h][d][w] ~= nil then placeDown(schArray[h][d][w]) end
robot.turnRight() for i=1, tableLength(schArray[1])-1 do move() end robot.turnRight()
end
end
end
end
if nextMove == "right" then nextMove = "left" else nextMove = "right" end
end
if h~=tableLength(schArray) then print("Layer "..tostring(h).." complete.") end
end
robot.turnLeft()
move()
for i=1, tableLength(schArray) do
moveDown()
end
print(" ")
print("Done!")