SHOW:
|
|
- or go back to the newest paste.
1 | --slots = textutils.unserialize( fs.open("slots","r").readAll() ) | |
2 | --nObjective = 1 | |
3 | --instructions = textutils.unserialize( fs.open("instructions","r").readAll() ) | |
4 | ||
5 | ||
6 | ||
7 | --instructions[n] = {x,y,z,id,data} | |
8 | ||
9 | function getLength(checklist) | |
10 | local c = 0 | |
11 | for i,v in pairs(checklist) do | |
12 | for k,l in pairs(v) do | |
13 | if l then | |
14 | c = c + 1 | |
15 | end | |
16 | end | |
17 | end | |
18 | return c | |
19 | end | |
20 | ||
21 | function getSlotsUsed(checklist) | |
22 | local c = 0 | |
23 | local count = 0 | |
24 | for id,table in pairs(checklist) do | |
25 | for data,count in pairs(table) do | |
26 | c = c + math.ceil(count/64) | |
27 | end | |
28 | end | |
29 | return c | |
30 | end | |
31 | ||
32 | function sort() | |
33 | items = {} | |
34 | for i = 1,16 do | |
35 | local item = turtle.getItemDetail(i) | |
36 | if item then | |
37 | local pSlot = nil | |
38 | if items[item.name] then | |
39 | pSlot = items[item.name][item.damage] | |
40 | end | |
41 | if pSlot then | |
42 | turtle.select(i) | |
43 | turtle.transferTo(pSlot) | |
44 | if turtle.getItemCount(pSlot) == 64 then | |
45 | if turtle.getItemCount(i) > 0 then | |
46 | items[item.name][item.damage] = i | |
47 | else | |
48 | items[item.name][item.damage] = nil | |
49 | end | |
50 | end | |
51 | elseif turtle.getItemCount(i) < 64 then | |
52 | if not items[item.name] then | |
53 | items[item.name] = {} | |
54 | end | |
55 | items[item.name][item.damage] = i | |
56 | end | |
57 | end | |
58 | end | |
59 | end | |
60 | ||
61 | local function add2checklist(checklist,name,damage,slots_available) | |
62 | --checklist[id][data] = count version | |
63 | --INPUT: item, checklist | |
64 | --OUTPUT: added to checklist if there's space | |
65 | slots_available = slots_available or 15 | |
66 | local numCheckList = getSlotsUsed(checklist) | |
67 | ||
68 | if name == nil then | |
69 | return checklist | |
70 | end | |
71 | ||
72 | if checklist[name] and checklist[name][damage] then | |
73 | checklist[name][damage] = checklist[name][damage] + 1 | |
74 | if getSlotsUsed(checklist) > slots_available then | |
75 | checklist[name][damage] = checklist[name][damage] - 1 | |
76 | return checklist,true | |
77 | else | |
78 | return checklist | |
79 | end | |
80 | end | |
81 | ||
82 | if numCheckList < slots_available then | |
83 | if checklist[name] then | |
84 | checklist[name][damage] = 1 | |
85 | else | |
86 | checklist[name] = {} | |
87 | checklist[name][damage] = 1 | |
88 | end | |
89 | else | |
90 | --error("checklist full") | |
91 | return checklist,true | |
92 | end | |
93 | return checklist | |
94 | end | |
95 | ||
96 | function checklistMaker(nObjective,instructions,slots) | |
97 | --INPUT: nObjective,instructions,slots | |
98 | --OUTPUT: next 15 invo spaces worth of blocks required in checklist[id][data] = count | |
99 | local checklist = {} | |
100 | ||
101 | for i = nObjective,#instructions do | |
102 | local name,damage = unpack(slots[ instructions[i][4] ][ instructions[i][5] ]) | |
103 | checklist,bFull = add2checklist(checklist,name,damage,15) | |
104 | if bFull then | |
105 | return checklist | |
106 | end | |
107 | end | |
108 | ||
109 | return checklist | |
110 | end | |
111 | ||
112 | local function insert_rubbish(rubbishList,id,data,count) | |
113 | if not id then | |
114 | return | |
115 | end | |
116 | if not rubbishList[id] then | |
117 | rubbishList[id]= {} | |
118 | end | |
119 | if not rubbishList[id][data] then | |
120 | rubbishList[id][data] = 0 | |
121 | end | |
122 | rubbishList[id][data] = rubbishList[id][data] + count | |
123 | return rubbishList | |
124 | end | |
125 | ||
126 | local function flatten_checklist(checklist,rubbishList) | |
127 | --get rid of negative count in checklist | |
128 | for id,table in pairs(checklist) do | |
129 | for data,count in pairs(table) do | |
130 | if count < 0 then | |
131 | rubbishList = insert_rubbish(rubbishList,id,data,math.abs(count)) | |
132 | checklist[id][data] = 0 | |
133 | end | |
134 | end | |
135 | end | |
136 | return checklist,rubbishList | |
137 | end | |
138 | ||
139 | function subtractInventory(checklist) | |
140 | local rubbishList = {} | |
141 | for i = 1,16 do | |
142 | local deets = turtle.getItemDetail(i) | |
143 | ||
144 | if deets then | |
145 | if checklist[deets.name] and checklist[deets.name][deets.damage] then | |
146 | checklist[deets.name][deets.damage] = checklist[deets.name][deets.damage] - deets.count | |
147 | elseif (not deets.name:lower():find("wrench")) and (not deets.name:lower():find("hammer")) then | |
148 | --not a wrench, not on the list | |
149 | insert_rubbish(rubbishList,deets.name,deets.damage,deets.count) | |
150 | end | |
151 | end | |
152 | end | |
153 | checklist,rubbishList = flatten_checklist(checklist,rubbishList) | |
154 | return checklist,rubbishList | |
155 | end | |
156 | ||
157 | function find_in_turtle(id,data) | |
158 | for i = 1,16 do | |
159 | local deets = turtle.getItemDetail(i) | |
160 | if deets and (deets.name == id and deets.damage == data) then | |
161 | return i,deets.count | |
162 | end | |
163 | end | |
164 | return nil | |
165 | end | |
166 | ||
167 | function throw_away(rubbishList,intoSlot) | |
168 | for id,table in pairs(rubbishList) do | |
169 | for data,count in pairs(table) do | |
170 | if count > 0 then | |
171 | local slot, amount = find_in_turtle(id,data) | |
172 | if amount >= count then | |
173 | --peripheral.call("bottom","pushItem","down",slot,count,intoSlot) | |
174 | rubbishList[id][data] = 0 | |
175 | else | |
176 | local mem = turtle.getSelectedSlot() | |
177 | while amount < count do | |
178 | local i,amount_transferred = find_in_turtle(id,data) | |
179 | if i then | |
180 | turtle.select(i) | |
181 | turtle.transferTo(mem) | |
182 | local remainder = turtle.getItemCount() | |
183 | amount = amount + (amount_transferred-remainder) | |
184 | end | |
185 | ||
186 | end | |
187 | turtle.select(mem) | |
188 | end | |
189 | --pushItem(direction,slot,maxAmount?,intoSlot?) | |
190 | peripheral.call("bottom","pushItem","down",slot,amount,intoSlot) | |
191 | end | |
192 | end | |
193 | end | |
194 | end | |
195 | ||
196 | ||
197 | ||
198 | function save(table,filename) | |
199 | local h = fs.open(filename,"w") | |
200 | if fs.exists("textutilsFIX") then | |
201 | os.loadAPI("textutilsFIX") | |
202 | h.write(textutilsFIX.serialize(table)) | |
203 | else | |
204 | h.write(textutils.serialize(table)) | |
205 | end | |
206 | h.close() | |
207 | end | |
208 | --throwAway file | |
209 | ||
210 | function db(entity,name) | |
211 | local h = fs.open("console","a") | |
212 | name = name or "" | |
213 | os.loadAPI("textutilsFIX") | |
214 | if type(entity) == "table" then | |
215 | h.writeLine(name..": "..textutilsFIX.serialize(table)) | |
216 | else | |
217 | h.writeLine(name..": "..tostring(entity)) | |
218 | end | |
219 | h.close() | |
220 | end | |
221 | ||
222 | function find_in_turtle(id,data) | |
223 | for i = 1,16 do | |
224 | local deets = turtle.getItemDetail(i) | |
225 | if deets and (deets.name == id and deets.damage == data) then | |
226 | return i,deets.count | |
227 | end | |
228 | end | |
229 | return nil | |
230 | end | |
231 | ||
232 | - | function findEmptySlots(chest) |
232 | + | function findEmptySlots(chest,inv) |
233 | - | local randomTable = {} |
233 | + | |
234 | - | for i,v in pairs(chest) do |
234 | + | |
235 | - | table.insert(randomTable,i) |
235 | + | |
236 | emptySlots = emptySlots + 1 | |
237 | - | return #randomTable |
237 | + | |
238 | end | |
239 | return emptySlots | |
240 | - | function findEmptySlotsOLD(chest,inv) |
240 | + | |
241 | ||
242 | function throwAway2(rubbishList,chest,inv) | |
243 | local emptySlots = findEmptySlots(chest,inv) | |
244 | assert(emptySlots) | |
245 | --print("emptySlots = ",emptySlots) | |
246 | for i = 1,16 do | |
247 | local count = nil | |
248 | local deets = turtle.getItemDetail(i) | |
249 | if rubbishList and deets and rubbishList[deets.name] then | |
250 | count = rubbishList[deets.name][deets.damage] | |
251 | end | |
252 | if count and count > 0 and emptySlots > 0 then | |
253 | turtle.select(i) | |
254 | local amount = turtle.getItemCount(i) | |
255 | if amount > count then | |
256 | turtle.dropDown(count) | |
257 | count = 0 | |
258 | elseif count <= 64 then | |
259 | turtle.dropDown(count) | |
260 | count = 0 | |
261 | else | |
262 | turtle.dropDown() | |
263 | count = count - 64 | |
264 | end | |
265 | emptySlots = emptySlots - 1 | |
266 | rubbishList[deets.name][deets.damage] = count | |
267 | end | |
268 | end | |
269 | return rubbishList | |
270 | end | |
271 | ||
272 | function take(chest_slot,amount,me,chest) | |
273 | sort() | |
274 | if me then | |
275 | peripheral.call("bottom","exportItem",chest[chest_slot].fingerprint,"up",amount) | |
276 | else | |
277 | peripheral.call("bottom","pushItem","up",chest_slot,amount) | |
278 | end | |
279 | end | |
280 | ||
281 | function take2(chest_slot,amount) | |
282 | assert(chest_slot) | |
283 | amount = amount or 64 | |
284 | peripheral.call("bottom","swapStacks",chest_slot,1) | |
285 | turtle.suckDown(amount) | |
286 | end | |
287 | ||
288 | function pullBlocks(checklist,chest) | |
289 | local me = false | |
290 | if peripheral.call("bottom","getInventoryName") == "TileInterface" then | |
291 | me = true | |
292 | end | |
293 | assert(checklist) | |
294 | assert(chest) | |
295 | for chest_slot,func in pairs(chest) do | |
296 | - | function pullBlocks(checklist,chest,invType) |
296 | + | |
297 | if me then | |
298 | - | if invType == "TileInterface" then |
298 | + | |
299 | damage = func.fingerprint.dmg | |
300 | qty = func.size | |
301 | else | |
302 | name = func.basic().id | |
303 | db(name,chest_slot) | |
304 | damage = func.basic().dmg | |
305 | db(damage,"dmg") | |
306 | qty = func.basic().qty | |
307 | db(qty,"qty") | |
308 | end | |
309 | local checklist_count = nil | |
310 | if checklist and checklist[name] then | |
311 | checklist_count = checklist[name][damage] | |
312 | end | |
313 | if checklist_count and checklist_count > 0 then | |
314 | --take | |
315 | ||
316 | if checklist_count <= qty then | |
317 | --take checklist_count amount | |
318 | take(chest_slot,checklist_count,me,chest) | |
319 | checklist_count = 0 | |
320 | db(name," name") | |
321 | db(checklist_count," checklist_count") | |
322 | db(qty," qty") | |
323 | elseif checklist_count>=64 then | |
324 | --take 64 | |
325 | take(chest_slot,64,me,chest) | |
326 | checklist_count = checklist_count - 64 | |
327 | db(name," name") | |
328 | db(checklist_count," checklist_count") | |
329 | db(qty," qty") | |
330 | elseif checklist_count > qty then | |
331 | --take qty | |
332 | take(chest_slot,qty,me,chest) | |
333 | checklist_count = checklist_count - qty | |
334 | db(name," name") | |
335 | db(checklist_count," checklist_count") | |
336 | db(qty," qty") | |
337 | else | |
338 | db(name," NOT COUNTED") | |
339 | db(damage) | |
340 | db(qty) | |
341 | end | |
342 | ||
343 | ||
344 | checklist[name][damage] = checklist_count | |
345 | end | |
346 | end | |
347 | return checklist | |
348 | end | |
349 | ||
350 | function check_chests(checklist,rubbishList) | |
351 | --if openperipherals | |
352 | if reference.multiturtle and reference.returnx and reference.returny and reference.returnz then | |
353 | goto(reference.finalx+1,reference.returny,reference.returnz) | |
354 | goto(reference.returnx,reference.returny,reference.returnz) | |
355 | else | |
356 | goto(heightPos,reference.starty,reference.startz-1) | |
357 | goto(reference.startx,reference.starty,reference.startz-1) | |
358 | end | |
359 | local i = 1 | |
360 | - | --if reference.multiturtle and reference.returnx and reference.returny and reference.returnz then |
360 | + | |
361 | local numChests = 0 | |
362 | while true do | |
363 | - | --else |
363 | + | if reference.multiturtle then |
364 | - | --goto(heightPos,reference.starty,reference.startz-1) |
364 | + | |
365 | - | --goto(reference.startx,reference.starty,reference.startz-1) |
365 | + | |
366 | - | --end |
366 | + | goto(reference.startx,reference.starty,reference.startz-i) |
367 | end | |
368 | local inv = peripheral.call("bottom","getInventorySize") | |
369 | local invType = peripheral.call("bottom","getInventoryName") | |
370 | ||
371 | - | --if reference.multiturtle then |
371 | + | if inv and inv > 0 then |
372 | local chest | |
373 | - | --else |
373 | + | |
374 | - | --goto(reference.startx,reference.starty,reference.startz-i) |
374 | + | |
375 | - | --end |
375 | + | |
376 | - | --local inv = peripheral.call("bottom","getInventorySize") |
376 | + | |
377 | - | --local invType = peripheral.call("bottom","getInventoryName") |
377 | + | |
378 | - | local invType = false |
378 | + | |
379 | - | local lookSee,lookData = turtle.inspectDown() |
379 | + | |
380 | - | if lookSee then |
380 | + | rubbishList = throwAway2(rubbishList,chest,inv) |
381 | - | if lookData.name:find("chest") then |
381 | + | |
382 | - | invType = true |
382 | + | checklist = pullBlocks(checklist,chest) |
383 | - | elseif lookData.name:find("tile.BlockInterface") then |
383 | + | |
384 | - | invType = "TileInterface" |
384 | + | |
385 | if not reference.numChests then | |
386 | if invType == "TileInterface" then | |
387 | reference.numChests = numChests | |
388 | updateVar(reference.filename,"reference.numChests",numChest) --needs testing | |
389 | - | if invType then |
389 | + | break |
390 | end | |
391 | end | |
392 | --if (everything checked off) then | |
393 | --go back to building | |
394 | --end | |
395 | if reference.numChests == numChests then | |
396 | --print("ok stop here") | |
397 | break | |
398 | - | rubbishList = throwAway2(rubbishList,chest) |
398 | + | |
399 | else | |
400 | - | checklist = pullBlocks(checklist,chest,invType) |
400 | + | |
401 | if noInvo == 2 and numChests == 0 then | |
402 | error("needs refill chest within 2 blocks behind start location under the turtle") | |
403 | end | |
404 | if noInvo == 3 then | |
405 | reference.numChests = numChests | |
406 | - | if invType == "TileInterface" and not reference.numChests then |
406 | + | |
407 | break | |
408 | end | |
409 | end | |
410 | ||
411 | i = i + 1 | |
412 | end | |
413 | --print("stop") | |
414 | save(rubbishList,"rubbishList") | |
415 | save(checklist,"checklist") | |
416 | end | |
417 | ||
418 | ||
419 | --checklist = checklistMaker(1,instructions,slots) | |
420 | --checklist, rubbishList = subtractInventory(checklist) | |
421 | ||
422 | --save(checklist,"checklist") | |
423 | --save(rubbishList,"rubbishList") |