View difference between Paste ID: rNYKGP0n and 8JaJH3g2
SHOW: | | - or go back to the newest paste.
1
--cc:Tweaked: Turtle Inventory Management
2
--pastebin get 8JaJH3g2 inventory.lua
3
--inv=require("inventory")
4
--chest=inv.wrap("left")
5
--chest.count()
6
--require("inventory").wrap("left").find("minecraft:redstone")
7
8
local inventory = {}
9
10
function stacksEqual(a,b)
11
	if a==nil or b==nil then return false end
12
13
	if type(a) == "string" then a = {name=a} end
14
	if type(b) == "string" then b = {name=b} end
15
	
16
	if a.damage == nil then a["damage"] = 0 end
17
	if b.damage == nil then b["damage"] = 0 end
18
   
19
	return a.damage == b.damage and a.name == b.name
20
end
21
22
local function extend(_count, _size, _detail, _list)
23-
	local base = {}
23+
	base = {}
24
25
	function base.list()
26
		return _list()
27
	end
28
	
29
	function base.size()
30
		return _size()
31
	end
32
	
33
	function base.item(slot)
34
		return _list()[slot]
35
	end
36
	
37
	function base.itemDetail(slot)
38
		return _detail(slot)
39
	end
40
	
41
	function base.counts()
42
		counts = {}
43
		for slot,item in pairs(_list()) do
44-
			if item ~= nil then
44+
			local count = counts[item.name]
45-
				local count = counts[item.name]
45+
			if count == nil then
46-
				if count == nil then
46+
				counts[item.name] = item.count
47-
					counts[item.name] = item.count
47+
			else
48-
				else
48+
				counts[item.name] = item.count + count
49-
					counts[item.name] = item.count + count
49+
50
		end
51
		return counts
52
	end
53
	
54
	--item == nil: # of slots which contain items
55
	--item == number: count of items in slot
56
	--item == string: total count of items
57
	--item == {item}: total count of items
58
	function base.find(item)
59
		for slot,cursor in pairs(_list()) do
60
			if stacksEqual(item, cursor) then return true, slot, cursor.count end
61
		end
62
		return false
63
	end
64
65
	function base.isFull()
66
		return base.count() == _size()
67
	end
68
	
69
	function base.count(item)
70
		local count = 0
71
72
		if item == nil then
73
			return #_list()
74
		elseif 
75-
			for slot,cursor in pairs(_list()) do
75+
76-
				count = count + 1
76+
77
			for _,cursor in pairs(_list()) do
78
				if stacksEqual(cursor, item) then
79
					count = count + cursor.count
80
				end
81
			end
82
			return count
83
		end
84
	end
85
	
86
	return base
87
end
88
89
function inventory.wrap(side)
90
91
	local __wrapper = peripheral.wrap(side)
92
	if __wrapper == nil then return nil end
93
94
	local chest = extend(
95
		function(slot) local items = __wrapper.list() if items[slot] == nil then return 0 else return items[slot].count end end,
96
		function() return __wrapper.size() end,
97
		function(slot) return __wrapper.getItemDetail(slot) end,
98
		function() return __wrapper.list() end
99
	)
100
	
101
	chest.name = side
102
	
103
	--Moves an item from this inventory to another.
104
	--[item | slot] = item can be item name or slot
105
	function chest.push(to, item, count, toSlot)
106
		if type(to) ~= "string" then to = to.name end
107
		local total = 0
108
		
109
		if type(item) == "number" then 
110-
	--returns: 
110+
111-
	--  Boolean - Entire stack moved and slot is now empty
111+
			moved = __wrapper.pushItems(to,item,count,toSlot)
112-
	--  Number  - Number of items in stack moved
112+
			
113
			if(count == nil) then
114
				return true
115
			else
116
				total = total + moved
117
				return count == total,total
118-
			if(count == nil) then count = chest.count(item) end
118+
119-
			local moved = __wrapper.pushItems(to,item,count,toSlot)
119+
120-
			return count == moved,total
120+
121
		local counted =  base.count(item)
122
		if count == nil then count = counted end
123-
		local counted =  chest.count(item)
123+
124
		repeat 
125
			local found, slot, stack = base.find(item)
126
			if(not found) then return false, total end
127
			if stack > count - total then stack = count - total end
128-
			local found, slot, stack = chest.find(item)
128+
129
		until count == total
130
		return true, total
131
	end
132
	
133
	function chest.pull(from,item,count,toSlot)
134
		if type(from) == "string" then from = inventory.wrap(from) end
135
		return from.push(chest,item,count,toSlot)
136
	end
137
	
138
	--Turtle can't interact directly with chests in this way in CC:Tweaked. Modem required.
139
	--https://github.com/cc-tweaked/CC-Tweaked/discussions/601
140
	function chest.put(item, count, toSlot)
141
		error("Not Supported") 
142
	end
143
144
	function chest.get(item, count)
145
		error("Not implemented")
146
	end
147
	
148
	return chest
149
end
150
151
if turtle == nil then return inventory end
152
153
local function tlist()
154
	list={}
155
	for s=1,16 do
156
		local count = turtle.getItemCount(s)
157
		if count > 0 then 
158
			list[s] = turtle.getItemDetail(s, false)
159
		end
160
	end
161
	return list
162
end
163
164
local t_inventory = extend(
165
	turtle.getItemCount,
166
	function () return 16 end,
167-
turtle.items = extend(
167+
168
	tlist
169
)
170
171
function t_inventory.compact()
172
	local source = t_inventory.size()
173
	local dest = 1
174-
function turtle.items.compact()
174+
	local count = t_inventory.count()
175-
	local source = turtle.items.size()
175+
176
	for s=t_inventory.size(),2,-1 do
177-
	local count = turtle.items.count()
177+
178
		if turtle.getItemCount(s) > 0 then 
179-
	for s=turtle.items.size(),2,-1 do
179+
180
				if turtle.getItemSpace(d) > 0 then 
181
					local dest = turtle.getItemDetail(d)
182
					if dest == nil or stacksEqual(source,dest) then
183
						turtle.select(s)
184
						if turtle.transferTo(d) then
185
							if turtle.getItemCount() == 0 then break end
186
						end
187
					end
188
				end
189
			end
190
		end
191
	end
192
	
193
	return t_inventory.count() ~= count
194
end
195
196-
	return turtle.items.count() ~= count
196+
function t_inventory.selected()
197
	return turtle.getItemDetail()
198
end
199-
function turtle.items.selected()
199+
200
function t_inventory.depositAll(side)
201
	local dropCount = 0
202
	
203-
function turtle.items.select(item)
203+
	local chest = inventory.getInventory(side)
204-
	local found,slot,count = turtle.items.find(item)
204+
205-
	if found then turtle.select(slot) end
205+
206-
	return found,slot,count
206+
	for n=1,INV_COUNT do
207
		if inventory.getItemCount(n) > 0 then
208
			turtle.select(n)
209-
function turtle.items.depositAll(side)
209+
210
				return false
211
			end
212-
	local chest = inventory.wrap(side)
212+
213
	end
214
	
215-
	for n=1,turtle.items.size() do
215+
216-
		if turtle.items.count(n) > 0 then
216+
217
218
turtle.inventory = t_inventory