summaryrefslogtreecommitdiff
path: root/data/artery/global/sh_crafting_inv.lua
blob: 0514ba0bb93c2b066dae027f6986f3d040188f2c (plain)
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
--[[
	An inventory that accepts materials and can store 100's of them.
]]
--[[
	Public functions:
		RegisterInventory(tbl_inventory)	::nil
			Registers a new inventory prototype, see below
		CreateInventory(string_name)		::table_inventory
			Creates a new inventory be sure to set the .owner and .id fields!
		CreateInventoryFromData(string_name,string_data)::table_inventory)
			Just deserializes an inventory. You still need to set .owner and .id!
		DeriveInventory(string_name)		::table_inventory
			Creates a new inventory from an old, allows for heiarchy.
	Inventories have the following structure
		field								returns
		inv.Name							::string
			The name!
		inv:FindPlaceFor(item)				::table_position or nil
			Finds a place for the item
		inv:CanFitIn(table_position,item)	::boolean
			Check if the item can fit in the position
		inv:Put(table_position,item)		::nil
			Put an item in at the position
		inv:Has(string_or_compare_func)		::table_position or nil
			find an item in the inventory
		inv:Remove(position)				::table_item
			Remove an item from the position
		inv:Get(position)					::table_item
			Get the item at a position
		inv:Serialize()						::string
			Serialize the item to store it in a db
		inv:DeSerialize(str)				::table_inventory
			recreate the item from data in serialize
	The above fields must be defined for new inventories.
	-----------------------------------------------------
	The below are automatically made if they do not exist.
		inv:AddObserver(tbl_other)			::number_id				Whenever put or remove is called on this inventory, tbl_other's put() and remove() is also called, for easy networking to whoever needs it
		inv:RemoveObserver(number_id)		::nil					Removes an observer from the inventory
	------------------------------------------------------
	These fields should be defined when an inventory is created, before it can be used
		inv.Owner							::entity
		inv.id								::number
]]
if not nrequire then return end
local reg = nrequire("core/inventory/inventory.lua")
local itm = nrequire("core/inventory/item.lua")
local i = {}

i.Name = "Crafting Inventory"
i.materials = {}
i.accepts = {}

function i:FindPlaceFor(item)
	if not self.accepts[item.Name] then return nil end
	return {item.Name}
end

function i:CanFitIn(position,item)
	return self.accepts[item.Name]
end

function i:Put(pos,item)
	self.materials[item.Name] = (self.materials[item.Name] or 0) + 1
end

function i:Has(str_or_cmp)
	if type(str_or_cmp) == "function" then error("Tried to check has of a workbench with function") end
	if (self.materials[str_or_cmp] or 0) > 0 then
		return {str_or_cmp}
	else
		return nil
	end
end

function i:Remove(tbl)
	local ret = itm.GetItemByName(tbl[1])
	assert(self.materials[ tbl[1] ] > 0, "Tried to remove a resource when we didn't have any!")
	self.materials[ tbl[1] ] = self.materials[ tbl[1] ] - 1
	return ret
end

function i:Get(tbl)
	return itm.GetItemByName(tbl[1])
end

function i:Serialize()
	local s = {
		materials = self.materials,
		accepts = self.accepts
	}
	return util.TableToJSON(s)
end

function i:DeSerialize(data)
	local cpy = table.Copy(self)
	local d = util.JSONToTable(data)
	cpy.materials = d.materials
	cpy.accepts = d.accepts
	return cpy
end

if CLIENT then
	local svg = nrequire("cl_svg.lua")
	local com = nrequire("cl_common.lua")
	local col = nrequire("colortheme.lua")
	local c = col.ui.border
	local inputimg = svg.MaterialFromSVG("materials/svg/delapouite/gui/svg/000000/transparent/plain-arrow.svg", nil, ucol)
	
	function i.DrawOnDPanel(self,dpanel)
		local matpnls = {}
		local matscroll = vgui.Create("DScrollPanel",dpanel)
		matscroll:Dock(FILL)
		
		local inputpnl = vgui.Create("DModelPanel",dpanel)
		--inputpnl:Dock(TOP)
		inputpnl.PaintOver = function(tp,w,h)
			if inputimg.material then
				surface.SetDrawColor(c.r,c.g,c.b)
				surface.DrawOutlinedRect(0, 0, h, h)
				surface.SetDrawColor(255,255,255)
				surface.SetMaterial( inputimg.material	)
				surface.DrawTexturedRect( 0, 0, h, h )
			end
		end
		inputpnl:Receiver("item",com.generatereceiver())
		inputpnl:SetSize(50,50)
		inputpnl.info = {
			owner = self.Owner,
			id = self.id,
			pos = {"*"},
			inv = self
		}
		inputpnl:Dock(TOP)
		
		local function create_panel(k,v)
			local pnlitem = {}
			pnlitem.panel = vgui.Create("DPanel",matscroll)
			pnlitem.panel:Dock(TOP)
			pnlitem.text = vgui.Create("DLabel",pnlitem.panel)
			pnlitem.text:SetText(string.format("%10s : %5d",k,v - 1))
			pnlitem.text:Dock(FILL)
			pnlitem.text:SetDark(true)
			local ta = vgui.Create("DModelPanel",pnlitem.panel)
			ta:Dock(LEFT)
			ta:Droppable("item")
			ta.info = {
				owner = self.Owner,
				id = self.id,
				pos = {k},
				inv = self
			}
			matpnls[k] = pnlitem
		end
		
		for k,v in pairs(self.materials) do
			if v > 0 then
				create_panel(k,v)
			end
		end
		
		local function refresh_ammt(name,p)
			local pnlitem = matpnls[ name ]
			local ammt = self.materials[name]
			if ammt == 0 or ammt == nil then
				pnlitem.panel:Remove()
			else
				pnlitem.text:SetText(string.format("%10s : %5d",name,ammt)) --Called before the actual inventorie's put, so +1
			end
		end
		
		local observer = {}
		observer.Put = function(obs,position,item)
			if self.materials[ item.Name ] == nil or self.materials[ item.Name ] == 0 then --Create a panel for the item
				create_panel(item.Name,1)
			else
				refresh_ammt(item.Name,1)
			end
			--matslbls[ position[1] ]:SetText(self.materials[ position[1] ])
			--drawitemat(self,position[1],position[2],item)
		end
		observer.Remove = function(obs,position)
			if self.materials[position[1]] == 1 then --Remove at 1 since this is called before inventory's remove()
				matpnls[position[1]].panel:Remove()
			end
			refresh_ammt(position[1],-1)
			--matslbls[ position[1] ]:SetText(self.materials[ position[1] ])
			--undrawitemat(self,position[1],position[2])
		end
		return observer
	end
end

reg.RegisterInventory(i)