diff options
Diffstat (limited to 'data/artery/global/sh_crafting_inv.lua')
| -rw-r--r-- | data/artery/global/sh_crafting_inv.lua | 193 |
1 files changed, 193 insertions, 0 deletions
diff --git a/data/artery/global/sh_crafting_inv.lua b/data/artery/global/sh_crafting_inv.lua new file mode 100644 index 0000000..d720551 --- /dev/null +++ b/data/artery/global/sh_crafting_inv.lua @@ -0,0 +1,193 @@ +--[[ + An inventory that accepts materials and can store 100's of them. +]] +--[[ + Public functions: + RegisterInventory(tbl_inventory) ::nil + Registers a new inventory prototype, see below + CreateInventory(string_name) ::table_inventory + Creates a new inventory be sure to set the .owner and .id fields! + CreateInventoryFromData(string_name,string_data)::table_inventory) + Just deserializes an inventory. You still need to set .owner and .id! + DeriveInventory(string_name) ::table_inventory + Creates a new inventory from an old, allows for heiarchy. + Inventories have the following structure + field returns + inv.Name ::string + The name! + inv:FindPlaceFor(item) ::table_position or nil + Finds a place for the item + inv:CanFitIn(table_position,item) ::boolean + Check if the item can fit in the position + inv:Put(table_position,item) ::nil + Put an item in at the position + inv:Has(string_or_compare_func) ::table_position or nil + find an item in the inventory + inv:Remove(position) ::table_item + Remove an item from the position + inv:Get(position) ::table_item + Get the item at a position + inv:Serialize() ::string + Serialize the item to store it in a db + inv:DeSerialize(str) ::table_inventory + recreate the item from data in serialize + The above fields must be defined for new inventories. + ----------------------------------------------------- + The below are automatically made if they do not exist. + inv:AddObserver(tbl_other) ::number_id Whenever put or remove is called on this inventory, tbl_other's put() and remove() is also called, for easy networking to whoever needs it + inv:RemoveObserver(number_id) ::nil Removes an observer from the inventory + ------------------------------------------------------ + These fields should be defined when an inventory is created, before it can be used + inv.Owner ::entity + inv.id ::number +]] +if not nrequire then return end +local reg = nrequire("core/inventory/inventory.lua") +local itm = nrequire("core/inventory/item.lua") +local i = {} + +i.Name = "Crafting Inventory" +i.materials = {} +i.accepts = {} + +function i:FindPlaceFor(item) + if not self.accepts[item.Name] then return nil end + return {item.Name} +end + +function i:CanFitIn(position,item) + return self.accepts[item.Name] +end + +function i:Put(pos,item) + self.materials[item.Name] = (self.materials[item.Name] or 0) + 1 +end + +function i:Has(str_or_cmp) + if type(str_or_cmp) == "function" then error("Tried to check has of a workbench with function") end + if (self.materials[str_or_cmp] or 0) > 0 then + return {str_or_cmp} + else + return nil + end +end + +function i:Remove(tbl) + local ret = itm.GetItemByName(tbl[1]) + assert(self.materials[ tbl[1] ] > 0, "Tried to remove a resource when we didn't have any!") + self.materials[ tbl[1] ] = self.materials[ tbl[1] ] - 1 + return ret +end + +function i:Get(tbl) + return itm.GetItemByName(tbl[1]) +end + +function i:Serialize() + local s = { + materials = self.materials, + accepts = self.accepts + } + return util.TableToJSON(s) +end + +function i:DeSerialize(data) + local cpy = table.Copy(self) + local d = util.JSONToTable(data) + cpy.materials = d.materials + cpy.accepts = d.accepts + return cpy +end + +if CLIENT then + local svg = nrequire("cl_svg.lua") + local com = nrequire("cl_common.lua") + local col = nrequire("colortheme.lua") + local c = col.ui.border + local inputimg = svg.MaterialFromSVG("materials/svg/delapouite/gui/svg/000000/transparent/plain-arrow.svg", nil, ucol) + + function i.DrawOnDPanel(self,dpanel) + local matpnls = {} + local matscroll = vgui.Create("DScrollPanel",dpanel) + matscroll:Dock(FILL) + + local inputpnl = vgui.Create("DModelPanel",dpanel) + --inputpnl:Dock(TOP) + inputpnl.PaintOver = function(tp,w,h) + if inputimg.material then + surface.SetDrawColor(c.r,c.g,c.b) + surface.DrawOutlinedRect(0, 0, h, h) + surface.SetDrawColor(255,255,255) + surface.SetMaterial( inputimg.material ) + surface.DrawTexturedRect( 0, 0, h, h ) + end + end + inputpnl:Receiver("item",com.generatereceiver()) + inputpnl:SetSize(50,50) + inputpnl.info = { + owner = self.Owner, + id = self.id, + pos = {"*"}, + inv = self + } + inputpnl:Dock(TOP) + + local function create_panel(k,v) + local pnlitem = {} + pnlitem.panel = vgui.Create("DPanel",matscroll) + pnlitem.panel:Dock(TOP) + pnlitem.text = vgui.Create("DLabel",pnlitem.panel) + pnlitem.text:SetText(string.format("%10s : %5d",k,v - 1)) + pnlitem.text:Dock(FILL) + pnlitem.text:SetDark(true) + local ta = vgui.Create("DModelPanel",pnlitem.panel) + ta:Dock(LEFT) + ta:Droppable("item") + ta.info = { + owner = self.Owner, + id = self.id, + pos = {k}, + inv = self + } + matpnls[k] = pnlitem + end + + for k,v in pairs(self.materials) do + if v > 0 then + create_panel(k,v) + end + end + + local function refresh_ammt(name,p) + local pnlitem = matpnls[ name ] + local ammt = self.materials[name] + if ammt == 0 or ammt == nil then + pnlitem.panel:Remove() + else + pnlitem.text:SetText(string.format("%10s : %5d",name,ammt)) --Called before the actual inventorie's put, so +1 + end + end + + local observer = {} + observer.Put = function(obs,position,item) + if self.materials[ item.Name ] == nil or self.materials[ item.Name ] == 0 then --Create a panel for the item + create_panel(item.Name,1) + else + refresh_ammt(item.Name,1) + end + --matslbls[ position[1] ]:SetText(self.materials[ position[1] ]) + --drawitemat(self,position[1],position[2],item) + end + observer.Remove = function(obs,position) + if self.materials[position[1]] == 1 then --Remove at 1 since this is called before inventory's remove() + matpnls[position[1]].panel:Remove() + end + refresh_ammt(position[1],-1) + --matslbls[ position[1] ]:SetText(self.materials[ position[1] ]) + --undrawitemat(self,position[1],position[2]) + end + return observer + end +end + +reg.RegisterInventory(i) |
