aboutsummaryrefslogtreecommitdiff
path: root/gamemode/core/inventory/item.lua
blob: 103da7f4a8928f8bd71cfb5abbd3d6579d56c263 (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
--[[
	An itemsystem
	public functions:
		RegisterItem(table_item)				::nil
			Registers a new item
		GetItemByName(string_name)				::table_item
			Returns the master copy of an item by name
		DeriveItem(table_item,string_name)		::nil
			Sets the table to a copy of an item. Copying happens in order, so if two items we derive from have a "DoThing" method, and "DoThing" is not defined in the item, the second derived item's "DoThing" method gets called on .DoThing()
	Item:
		item.Name						::string
			Items must have unique names
		item:Serialize()				::string
			Turn any instace specific data of this item into a string, should be able to recreate an exact copy of this item in DeSerialize with this data
		item:DeSerialize(string_data)	::nil
			Recreate an item. If this item has any instance specific data, it should return a table.Copy(self) with the appropriate fields set.
		The above must be defined for every item
	Items may also have methods from one or more interfaces registered with RegisterInterface
]]

local itm = {}
local required_fields = {
	"Name","Serialize","DeSerialize"
}

local items = {} --Master table of all item prototypes
function itm.RegisterItem(tbl)
	for k,v in pairs(required_fields) do
		assert(tbl[v] ~= nil, string.format("Attempted to register item without field %q",v))
	end
	assert(items[tbl.Name] == nil, string.format("Attempted to register 2 items with the same name %q",tbl.Name))
	items[tbl.Name] = tbl
	print("Registered item: " .. tbl.Name)
end

function itm.GetItemByName(name)
	assert(items[name] ~= nil,string.format("Attempted to get item with invalid name %q Valid item names are:\n\t%s",name,table.concat(table.GetKeys(items),"\n\t")))
	local item
	if items[name].init then
		item = items[name]:init()
	else
		item = table.Copy(items[name])
	end
	return item
end

function itm.GetItemFromData(name,data)
	assert(items[name] ~= nil,string.format("Attempted to get item with invalid name %q",name))
	return items[name]:DeSerialize(data)
end

--Must be called in a coroutine.
function itm.DeriveItem(tbl,name)
	while items[name] == nil do
		coroutine.yield()
	end
	--Create a flywieght copy
	local ret = tbl
	local mt = {
		__index = function(ntbl,key)
			return items[name][key]
		end
	}
	setmetatable(ret,mt)
end

concommand.Add("art_printitems",function()
	for k,v in pairs(items) do
		print(k)
	end
end)

return itm