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
|
local chest
for _,name in ipairs(peripheral.getNames()) do
if name:match("chest") then chest = peripheral.wrap(name) break end
end
assert(chest,"couldn't find chest")
-- might not work if there are multiple modems but why would you do that
local localname = peripheral.find("modem").getNameLocal()
local function take_stock()
-- if you do this in parallel, you avoid having to wait 1 tick for each
-- slot of the chest. which is probably good.
local out = {}
local fns = {}
for i=1,chest.size() do
fns[i] = function() out[i] = chest.getItemDetail(i) end
end
parallel.waitForAll(unpack(fns))
return out
end
local function item_desc_matches(idesc,itemdetail)
-- idesc is an entry from ITEMS
-- itemdetail is something returned from getItemDetail on the chest
-- if you were wondering
return idesc.itname == itemdetail.name
end
local function amt_of(stockinfo,idesc)
local total = 0
for ix,itm in pairs(stockinfo) do
if item_desc_matches(idesc,itm) then
total = total + itm.count
end
end
return total
end
local function give(stockinfo,idesc,amt)
amt = amt or 1
-- assumes that we have at least amt in stock already
-- actually no, might as well double check this anyway
assert(amt_of(stockinfo,idesc) >= amt)
assert(amt>0)
-- make sure current turtle inv slot is empty
assert(turtle.getItemCount() == 0)
for slotidx,idtl in pairs(stockinfo) do
if item_desc_matches(idesc,idtl) then
local a = math.min(amt,idtl.count)
chest.pushItems(localname, slotidx, a, 1)
turtle.drop(a)
amt = amt - a
if amt <= 0 then break end
end
end
end
return {take_stock=take_stock,amt_of=amt_of,give=give}
|