View difference between Paste ID: APTbHvQR and biP6fFEi
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")