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
|
---The main module to use when createing new items.
-- Registers items that will work with the inventory system
--@shared item.lua
--@alias itm
--[[
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
]]
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.
--@tparam itemtbl 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 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
--@treturn itemtbl The item that was deserialized
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")
---Prints a list of all items the client/server knows about
--@concommand artery_printitems
--@usage artery_printitems
concommand.Add("artery_printitems",printitems)
return itm
|