aboutsummaryrefslogtreecommitdiff
path: root/gamemode/core/inventory/cl_invtracker.lua
blob: 2591e9604fffdd637d1654d30648095d49ddf873 (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
---Keeps track of inventories on the client side.
--@client cl_invtracker.lua
--@alias q

local inv = nrequire("inventory/inventory.lua")
local itm = nrequire("item.lua")
local log = nrequire("log.lua")
-- nrequire("cl_loadglobals.lua")
--local state = nrequire("cl_state.lua")

local q = {}

local known_inventories = {}
local inventory_frames = {}
local invsheet

---An array of all the known inventories.
--@export
q.known_inventories = known_inventories

local drawfloatinginventory = function(id, inventory)
	--print("Drawing a floating inventory!")
	local frame = vgui.Create("DFrame")
	frame:SetPos( ScrW() - (ScrW() / 4), 0 )
	frame:SetSize( ScrW() / 4, ScrH() / 4 )
	frame:SetTitle( inventory.Name )
	frame:SetDraggable( true )
	local panel = vgui.Create("DPanel",frame)
	panel:Dock(FILL)
	if inventory.DrawOnDPanel then
		local prox = inventory:DrawOnDPanel(panel)
		frame.id = known_inventories[id]:AddObserver(prox)
	else
		error("Inventory needs a DrawOnDPanel method!")
	end
	frame:MakePopup()
	frame.OnClose = function(self)
		--print("Closeing chest id", id)
		--print("entity is", known_inventories[id].Owner)
		known_inventories[id]:RemoveObserver(self.id)
		net.Start("closechestinv")
		net.WriteEntity(known_inventories[id].Owner)
		net.SendToServer()
		known_inventories[id] = nil
		self:Remove()
	end
end

local drawsheeton = function(id,inventory,higharchy)
	--print("Drawing an inventory on a sheet!")
	if invsheet == nil then return end
	local tpanel = vgui.Create( "DPanel", invsheet )
	--tpanel.Paint = function( self, w, h )
	--	draw.RoundedBox( 4, 0, 0, w, h, Color( 0, 128, 255 ) )
	--end
	if inventory.DrawOnDPanel then
		print("Has drawondpanel")
		local prox = inventory:DrawOnDPanel(tpanel)
		print("Prox returned was",prox)
		PrintTable(prox)
		known_inventories[id]:AddObserver(prox)
		print("Oservers is now")
		PrintTable(known_inventories[id].observers)
	end
	invsheet:AddSheet( inventory.Name, tpanel, "icon16/tab.png" )
end

net.Receive("art_ObserveInventory",function()
	local id = net.ReadUInt(32)
	local inv_type = net.ReadString()
	local datalen = net.ReadUInt(32)
	local inital_data = net.ReadData(datalen)
	local ownent = net.ReadEntity()
	--An array of hiarchy
	local partof = net.ReadTable()
	assert(known_inventories[id] == nil, "Trying to observe the same inventory twice!",id)
	local tinv = inv.CreateInventoryFromData(inv_type,inital_data,ownent)
	tinv.id = id
	local cursor = known_inventories
	for k,v in pairs(partof) do
		cursor[v] = cursor[v] or {}
		cursor = cursor[v]
	end
	cursor[id] = tinv
	if id > 10 then
		drawfloatinginventory(id,tinv)
		hook.Call("OnSpawnMenuOpen")
	else
		drawsheeton(id,tinv)
	end
end)

net.Receive("art_UpdateInventory",function()
	local id = net.ReadUInt(32)
	local isput = net.ReadBool()
	local position = net.ReadTable()
	if isput then
		local item_name = net.ReadString()
		local item_data = net.ReadData(net.ReadUInt(32))
		local item = itm.GetItemFromData(item_name,item_data)
		known_inventories[id]:Put(position,item)
		item.inv = known_inventories[id]
		--print("Inventorie's observers:")
		--PrintTable(known_inventories[id].observers)
		--print("Inventory is now")
		--PrintTable(known_inventories[id])
	else
		known_inventories[id]:Remove(position)
	end
end)

net.Receive("art_CloseInventory",function()
	local id = net.ReadUInt(32)
	known_inventories[id] = nil
	if inventory_frames[id] then
		inventory_frames[id]:Close()
		inventory_frames[id] = nil
	end
end)

concommand.Add("PrintKnownInventories",function(ply,cmd,args)
	print("Printing known inventories")
	PrintTable(known_inventories)
end)

---Drops an item.
-- Client side only, will error if you try to use it server side
--@tparam entity ent_or_tbl the entity that wants to drop the item
--@tparam number invid The inventory number the entity wants to drop from
--@tparam table frompos The position in the inventory the item was in.
function q.DropItem(ent_or_tbl,invid,frompos)
	--[[
	if type(ent_or_tbl) == "table" then
		drop_self(ent_or_tbl)
	else
		drop_provided(ent_or_tbl,invid,frompos)
	end
	]]
	assert(CLIENT,"requested to drop an item when we are not the client!")
	log.debug("Drop item was requested, ent_or_tbl is" .. tostring(ent_or_tbl))
	net.Start("art_RequestInvDrop")
	net.WriteEntity(ent_or_tbl)
	net.WriteUInt(invid,32)
	net.WriteTable(frompos)
	net.SendToServer()
end

return q