aboutsummaryrefslogtreecommitdiff
path: root/gamemode/core/inventory/item.lua
blob: a598fc25559fdcef9411c7a616471b9d6ff12b9d (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
--[[
	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 = items or {} --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))
	if items[tbl.Name] ~= nil then
		MsgC(Color(255,255,0),"WARNING: attemtpted to register 2 items with the same name " .. tbl.Name .. "\n")
	else
		MsgC(Color(0,255,0),"Registered Item " .. tbl.Name .. "\n")
	end
	items[tbl.Name] = tbl
	--print("Registered item: " .. tbl.Name)
end

function itm.GetItemByName(name)
	assert(type(name) == "string",string.format("Attempted to get an item by name with a %s."))
	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

local function printitems()
	local tbl = {}
	for k,v in pairs(items) do
		tbl[#tbl + 1] = k
	end
	print(table.concat(tbl,"\n"))
end

--Must be called in a coroutine.
function itm.DeriveItem(tbl,name)
	print("Attempting to derive item",name)
	while items[name] == nil do
		print("it dosen't exist yet, items are")
		printitems()
		coroutine.yield()
	end
	print(name,"exists!")
	--Create a flywieght copy
	local ret = tbl
	local mt = {
		__index = function(ntbl,key)
			return items[name][key]
		end
	}
	setmetatable(ret,mt)
end

hook.Call("artery_include_items")

concommand.Add("art_printitems",printitems)

return itm