From d2868db28210b8c4debab2b70dca2833d582fdfd Mon Sep 17 00:00:00 2001 From: Alexander Pickering Date: Fri, 23 Mar 2018 15:20:30 -0400 Subject: Refactored the inventory system Inventory system now uses flyweight pattern with metatables. --- gamemode/config/sv_newplayer.lua | 29 ++++++--- gamemode/core/inventory/inventory.lua | 20 +++++-- gamemode/core/inventory/item.lua | 22 ++++--- .../inventorysystem/equipment/sh_equipment.lua | 10 ++-- .../inventorysystem/equipment/sv_equipment.lua | 16 +++++ gamemode/inventorysystem/prayers/cl_prayers.lua | 20 ++++--- gamemode/inventorysystem/prayers/sh_prayers.lua | 9 +-- gamemode/inventorysystem/quests/cl_quests.lua | 62 +++++++++++++++++++ gamemode/inventorysystem/quests/sh_quests.lua | 69 ++++++++++++++++++++++ .../inventorysystem/shapedinventory/cl_shaped.lua | 3 + .../inventorysystem/shapedinventory/sh_shaped.lua | 7 ++- gamemode/inventorysystem/skills/sh_skills.lua | 10 ++-- 12 files changed, 229 insertions(+), 48 deletions(-) create mode 100644 gamemode/inventorysystem/quests/cl_quests.lua create mode 100644 gamemode/inventorysystem/quests/sh_quests.lua (limited to 'gamemode') diff --git a/gamemode/config/sv_newplayer.lua b/gamemode/config/sv_newplayer.lua index 1385bf5..229c11e 100644 --- a/gamemode/config/sv_newplayer.lua +++ b/gamemode/config/sv_newplayer.lua @@ -1,20 +1,31 @@ local np = {} local inv = nrequire("inventory/inventory.lua") +nrequire("inventorysystem/equipment/sh_equipment.lua") +nrequire("inventorysystem/shapedinventory/sh_shaped.lua") +nrequire("inventorysystem/prayers/sh_prayers.lua") +nrequire("inventorysystem/skills/sh_skills.lua") +nrequire("inventorysystem/quests/sh_quests.lua") +local log = nrequire("log.lua") --local itm = nrequire("inventory/item.lua") +local data = { + inventories = { + {"Equipment", inv.CreateInventory("Equipment"):Serialize()}, + {"Shaped Inventory",inv.CreateInventory("Shaped Inventory"):Serialize()}, + {"Prayers",inv.CreateInventory("Prayers"):Serialize()}, + {"Skills",inv.CreateInventory("Skills"):Serialize()}, + {"Quests",inv.CreateInventory("Quests"):Serialize()}, + }, +} + np.newdata = function() - return { - inventories = { - {"Equipment", inv.CreateInventory("Equipment"):Serialize()}, - {"Shaped Inventory",inv.CreateInventory("Shaped Inventory"):Serialize()}, - {"Prayers",inv.CreateInventory("Prayers"):Serialize()}, - {"Skills",inv.CreateInventory("Skills"):Serialize()}, - }, - quests = {}, - } + log.debug("newdata asked for") + log.debug(table.ToString(data,"data",true)) + return data end np.newmeta = function() + log.debug("newmeta asked for") return { lastserver = "67.163.245.187:27015", lastlocation = "-1209 1544 -1770" diff --git a/gamemode/core/inventory/inventory.lua b/gamemode/core/inventory/inventory.lua index d97f5be..ff9cc8c 100644 --- a/gamemode/core/inventory/inventory.lua +++ b/gamemode/core/inventory/inventory.lua @@ -149,10 +149,16 @@ end -- Consider carefully if you want to use this method, or the CreateInventoryFromData method. --@see invtbl --@tparam string name The name of the inventory type when it was registered -function inv.CreateInventory(name) +function inv.CreateInventory(name,initstr) --print("Createing inventory", name) + initstr = initstr or "" assert(inventories[name] ~= nil, string.format("Tried to create a copy of inventory that does not exist:%s\nValid inventories are:\n\t%s",name,table.concat(table.GetKeys(inventories),"\n\t"))) - local ret = TableCopy(inventories[name]) + local ret_m = { + __index = inventories[name] + } + local ret = {} + setmetatable(ret,ret_m) + ret:DeSerialize(initstr) ret.observers = {} return ret end @@ -177,10 +183,12 @@ end concommand.Add("artery_printinventories", function(ply,cmd,args) PrintTable(inventories) end) -concommand.Add("artery_printmyinventories",function(ply,cmd,args) - print("Inventories of:",ply:Nick()) - PrintTable(ply.data.inventories) -end) +if SERVER then + concommand.Add("artery_printmyinventories",function(ply,cmd,args) + print("Inventories of:",ply:Nick()) + PrintTable(ply.data.inventories) + end) +end ---To Be Depriciated. function inv.DeriveInventory(name) diff --git a/gamemode/core/inventory/item.lua b/gamemode/core/inventory/item.lua index 79f9ad5..16b30dd 100644 --- a/gamemode/core/inventory/item.lua +++ b/gamemode/core/inventory/item.lua @@ -41,7 +41,7 @@ function itm.RegisterItem(tbl) 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)) + --log.info(string.format("Registered item %s",tbl.Name)) end items[tbl.Name] = tbl --print("Registered item: " .. tbl.Name) @@ -54,11 +54,13 @@ end 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]) + local item_m = { + __index = items[name] + } + local item = {} + setmetatable(item,item_m) + if item.init then + item:init() end return item end @@ -70,7 +72,13 @@ end --@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) + local ret_m = { + __index = items[name] + } + local ret = {} + setmetatable(ret,ret_m) + ret:DeSerialize(data) + return ret end local function printitems() diff --git a/gamemode/inventorysystem/equipment/sh_equipment.lua b/gamemode/inventorysystem/equipment/sh_equipment.lua index 5bea682..b27dd08 100644 --- a/gamemode/inventorysystem/equipment/sh_equipment.lua +++ b/gamemode/inventorysystem/equipment/sh_equipment.lua @@ -117,16 +117,14 @@ inv.Serialize = function(self) end inv.DeSerialize = function(self,data) - if data == nil or data == '' then - return table.Copy(self) - end + self.equiped = {} local tbl = util.JSONToTable(data) - local cpy = table.Copy(self) + tbl = tbl or {} for k,v in pairs(tbl) do local te = itm.GetItemByName(v[1]):DeSerialize(v[2]) - cpy:Put({k},te) + self:Put({k},te) end - return cpy + return self end inventory.RegisterInventory(inv) diff --git a/gamemode/inventorysystem/equipment/sv_equipment.lua b/gamemode/inventorysystem/equipment/sv_equipment.lua index 2189122..6c28674 100644 --- a/gamemode/inventorysystem/equipment/sv_equipment.lua +++ b/gamemode/inventorysystem/equipment/sv_equipment.lua @@ -1,5 +1,21 @@ --[[ Needed so the includer dosn't freak out ]] +for k,v in pairs({ + "materials/svg/delapouite/originals/svg/000000/transparent/ring.svg", + "materials/svg/lorc/originals/svg/000000/transparent/cracked-helm.svg", + "materials/svg/skoll/originals/svg/000000/transparent/pauldrons.svg", + "materials/svg/willdabeast/deviations/svg/000000/transparent/chain-mail.svg", + "materials/svg/lorc/originals/svg/000000/transparent/knapsack.svg", + "materials/svg/skoll/originals/svg/000000/transparent/bracers.svg", + "materials/svg/lucasms/equipment/svg/000000/transparent/belt.svg", + "materials/svg/delapouite/originals/svg/000000/transparent/gloves.svg", + "materials/svg/sbed/originals/svg/000000/transparent/shield.svg", + "materials/svg/delapouite/originals/svg/000000/transparent/thor-hammer.svg", + "materials/svg/irongamer/originals/svg/000000/transparent/armored-pants.svg", + "materials/svg/lorc/originals/svg/000000/transparent/boots.svg", +}) do + resource.AddSingleFile(v) +end return {} diff --git a/gamemode/inventorysystem/prayers/cl_prayers.lua b/gamemode/inventorysystem/prayers/cl_prayers.lua index afea1cc..e28db63 100644 --- a/gamemode/inventorysystem/prayers/cl_prayers.lua +++ b/gamemode/inventorysystem/prayers/cl_prayers.lua @@ -8,7 +8,7 @@ function pray:DrawOnDPanel(panel) --Active grid local agrid = vgui.Create("DGrid",panel) agrid:SetCols(4) - local w = ((ScrW()/4) - 10) / 4 + local w = ((ScrW() / 4) - 10) / 4 agrid:SetHeight(w) agrid:SetColWide(w) agrid:SetRowHeight(w) @@ -17,14 +17,19 @@ function pray:DrawOnDPanel(panel) rec:SetText("F"..i) rec:SetSize(w,w) rec.DoClick = function(s) - local ap = self.activeprayers[i] + local ap = pray.activeprayers[i] explain:SetText(ap ~= nil and ap.Description or "Select a prayer") end rec:Receiver("prayer",function(s,tbl,dropped,mi,x,y) if not dropped then return end - self.activeprayers[i] = tbl.item - if tbl.item.DoOnPanel then - tbl.item.DoOnPanel(s) + pray.activeprayers[i] = tbl[1].item + if tbl[1].item == nil then + print("Failed to get item, tbl was") + PrintTable(tbl) + error("Failed to get item") + end + if tbl[1].item.DoOnPanel then + tbl[1].item:DoOnPanel(rec) end end,{}) agrid:AddItem(rec) @@ -64,6 +69,7 @@ function pray:DrawOnDPanel(panel) local observer = {} observer.Put = function(obs,pos,item) print("Prayer observer got request to put") + debug.Trace() drawprayer(item) end observer.Remove = function(obs,pos,item) @@ -79,12 +85,12 @@ local prayerhooks = { ["gm_showspare1"] = 3, ["gm_showspare2"] = 4 } -hook.Add("PlayerBindPress", function( ply, bind, pressed ) +hook.Add("PlayerBindPress", "pray_hook", function( ply, bind, pressed ) local phn = prayerhooks[bind] if phn == nil then return end local pap = pray.activeprayers[phn] if pap == nil then return end - pap:pray() + pap:Pray() end) return pray diff --git a/gamemode/inventorysystem/prayers/sh_prayers.lua b/gamemode/inventorysystem/prayers/sh_prayers.lua index e1e7347..9d8ff3b 100644 --- a/gamemode/inventorysystem/prayers/sh_prayers.lua +++ b/gamemode/inventorysystem/prayers/sh_prayers.lua @@ -14,7 +14,7 @@ end inv.Name = "Prayers" inv.track = {} function inv:FindPlaceFor(item) - if item.isprayer then + if item.Pray ~= nil then return {#self.track} end return nil @@ -54,14 +54,15 @@ function inv:Serialize() end function inv:DeSerialize(str) - local cpy = table.Copy(self) + self.track = {} local tbl = util.JSONToTable(str) + tbl = tbl or {} local i = 1 for k,v in pairs(tbl) do local this_prayer = itm.GetItemByName(k):DeSerialize(v) - cpy:Put({i},this_prayer) + self:Put({i},this_prayer) end - return cpy + return self end diff --git a/gamemode/inventorysystem/quests/cl_quests.lua b/gamemode/inventorysystem/quests/cl_quests.lua new file mode 100644 index 0000000..2052e19 --- /dev/null +++ b/gamemode/inventorysystem/quests/cl_quests.lua @@ -0,0 +1,62 @@ + +local inv = {} +--the gui elements +local elements = {} + +local questlist = nil +local questlog = nil +local function add_quest(panel,quest) + +end + +inv.DrawOnDPanel = function(self,panel) + local spanel = vgui.Create("DPanel", panel) + spanel:Dock(FILL) + local halfs = vgui.Create("DVerticalDivider",spanel) + questlist = vgui.Create("DListLayout", spanel) + questlog = vgui.Create("DLabel",spanel) + halfs:SetBottom(questlist) + halfs:SetTop(questlog) + questlist:Dock(FILL) + questlog:Dock(FILL) + for k,v in pairs(self.track) do + local questbutton = vgui.Create("DButton",questlist) + questbutton:SetText(v.QuestName) + questbutton.DoClick = function() + questlog:SetText(v:GetText()) + end + for i,j in pairs(v) do + local ipanel = vgui.Create("DListLayout",layout) + local label = vgui.Create("DLabel",ipanel) + label:Dock(TOP) + label:SetDark(true) + local bar = vgui.Create("DProgress",ipanel) + bar:Dock(TOP) + elements[j] = { + ["label"] = label, + ["bar" ] = bar, + } + set_xp_of(j,self.skills[j] or 0) + ipanel:Add(label) + ipanel:Add(bar) + ipanel:InvalidateLayout() + ipanel:SizeToChildren(true,true) + layout:Add(ipanel) + end + layout:Dock(FILL) + sheet:AddSheet(k, spanel, "icon16/cross.png") + end + + local prox = {} + prox.Put = function(s,position,item) + --Observer might be called before our put() + end + + prox.Remove = function(s,position) + -- + end + + return prox +end + +return inv diff --git a/gamemode/inventorysystem/quests/sh_quests.lua b/gamemode/inventorysystem/quests/sh_quests.lua new file mode 100644 index 0000000..3515d61 --- /dev/null +++ b/gamemode/inventorysystem/quests/sh_quests.lua @@ -0,0 +1,69 @@ +--[[ + Quests must have an Arcs field + +]] +local reg = nrequire("inventory/inventory.lua") +local itm = nrequire("item.lua") +local inv = {} +if CLIENT then + inv = nrequire("cl_quests.lua") +end + +inv.Name = "Quests" +inv.track = {} +function inv:FindPlaceFor(item) + if item.Arcs ~= nil then + return {#self.track} + end + return nil +end +function inv:CanFitIn(pos,item) + return pos[1] == #self.track +end +function inv:Put(pos,item) + print("Added a quest:") + PrintTable(item) + self.track[pos[1]] = item +end +function inv:Has(a) + if type(a) == "string" then + for k,v in pairs(self.track) do + if v == a then return {k} end + end + elseif type(a) == "function" then + for k,v in pairs(self.track) do + if a(v) then return {k} end + end + end + return nil +end +function inv:Remove(pos) + for i = 1,pos[1] do + self.track[i] = self.track[i + 1] + end +end +function inv:Get(pos) + return self.track[pos[1]] +end +function inv:Serialize() + local ret = {} + for k,v in pairs(self.track) do + ret[v.Name] = v:Serialize() + end + return util.TableToJSON(ret) +end + +function inv:DeSerialize(str) + self.track = {} + local tbl = util.JSONToTable(str) + tbl = tbl or {} + local i = 1 + for k,v in pairs(tbl) do + local this_prayer = itm.GetItemByName(k):DeSerialize(v) + self:Put({i},this_prayer) + end + return self +end + + +reg.RegisterInventory(inv) diff --git a/gamemode/inventorysystem/shapedinventory/cl_shaped.lua b/gamemode/inventorysystem/shapedinventory/cl_shaped.lua index 7c60156..d9a4a08 100644 --- a/gamemode/inventorysystem/shapedinventory/cl_shaped.lua +++ b/gamemode/inventorysystem/shapedinventory/cl_shaped.lua @@ -46,6 +46,9 @@ end --Draw the item in a position local function drawitemat(self,x,y,item) + assert(self ~= nil, "I am nil!") + assert(self.gridpanels ~= nil, "My gridpanels were nil!") + assert(self.gridpanels[x] ~= nil, "Could not find that row!") local tp = self.gridpanels[x][y] if tp == nil then error("Unable to continue, could not find item at (" .. x .. "," .. y .. ")") diff --git a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua index 5de6272..42edaa6 100644 --- a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua +++ b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua @@ -119,17 +119,18 @@ function inv:Serialize() end function inv:DeSerialize(str) - local ret = table.Copy(self) + self.tracker = {} local tbl = util.JSONToTable(str) + tbl = tbl or {} for k,v in pairs(tbl) do local name = k local pos = v[1] local data = v[2] local item = itm.GetItemFromData(name,data) - ret:Put(pos,item) + self:Put(pos,item) --ret.tracker[pos] = itm.GetItemFromData(name,data) end - return ret + return self end diff --git a/gamemode/inventorysystem/skills/sh_skills.lua b/gamemode/inventorysystem/skills/sh_skills.lua index a1c878f..3c212bf 100644 --- a/gamemode/inventorysystem/skills/sh_skills.lua +++ b/gamemode/inventorysystem/skills/sh_skills.lua @@ -140,16 +140,14 @@ inv.Serialize = function(self) end inv.DeSerialize = function(self,data) - if data == nil or data == '' then - return table.Copy(inv) - end calculate_skills() - local cpy = table.Copy(self) + self.skills = {} local gen = util.JSONToTable(data) + gen = gen or {} for k,v in pairs(gen) do - cpy.skills[k] = v + self.skills[k] = v end - return cpy + return self end inventory.RegisterInventory(inv) -- cgit v1.2.3-70-g09d2