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