aboutsummaryrefslogtreecommitdiff
path: root/gamemode/core/inventory/item.lua
blob: 1e6a0cff98046fb38a76301f0bb7b1fe0cb06acf (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
---The main module to use when createing new items.
-- Registers items that will work with the inventory system
--@module item.lua
--[[
	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 log = nrequire("log.lua")
local itm = {}
local required_fields = {
	"Name","Serialize","DeSerialize"
}

local items = items or {} --Master table of all item prototypes

---Registers an item.
-- Registers an item that can be gotten later. It usually dosn't make sense for only parts of the level to have an item (the player probably can travel between all the parts of your world with the item in their inventory), therefore you should make sure items are loaded globally.
--@see itemtbl
--@tparam table tbl The table to register for the item prototype
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
		log.warn(string.format("Attempted to register 2 items with the same name: %q, overwriteing previous",tbl.Name))
	else
		log.info(string.format("Registered item %s",tbl.Name))
	end
	items[tbl.Name] = tbl
	--print("Registered item: " .. tbl.Name)
end

---Gets an instance of an item.
-- Gets an instanced copy of an item registered with RegisterItem()
--@tparam string name The name of the item
--@treturn itemtbl item The item
function itm.GetItemByName(name)
	assert(type(name) == "string",string.format("Attempted to get an item by name with a %s.",type(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

---Gets an item, with data.
-- Just gets the item, then calls DeSerialize(), returning whatever deserialize returned
--@tparam string name The name of the item
--@tparam string data The data to instantiate the item with
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

---To be depriciated.
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