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
|
--[[
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(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
|