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