diff options
Diffstat (limited to 'gamemode/inventorysystem')
| -rw-r--r-- | gamemode/inventorysystem/cl_common.lua | 59 | ||||
| -rw-r--r-- | gamemode/inventorysystem/equipment/cl_equipment.lua | 66 | ||||
| -rw-r--r-- | gamemode/inventorysystem/equipment/sh_equipment.lua | 59 | ||||
| -rw-r--r-- | gamemode/inventorysystem/prayers/sh_prayers.lua | 14 | ||||
| -rw-r--r-- | gamemode/inventorysystem/shapedinventory/cl_shaped.lua | 169 | ||||
| -rw-r--r-- | gamemode/inventorysystem/shapedinventory/sh_shaped.lua | 147 |
6 files changed, 448 insertions, 66 deletions
diff --git a/gamemode/inventorysystem/cl_common.lua b/gamemode/inventorysystem/cl_common.lua new file mode 100644 index 0000000..07fc786 --- /dev/null +++ b/gamemode/inventorysystem/cl_common.lua @@ -0,0 +1,59 @@ + +local com = {} + +--Displays a dropdown of options under the players mouse, if the option is clicked, does the function +--Requires a table of strings to functions, or strings to tables of strings to functions. +--Be careful not to make this a recursive table. +function com.CreateMenuFor(menu, tbl) + for k,v in pairs(tbl) do + if isfunction(v) then --This is a dead-end, add the menu + menu:AddOption(k,v) + else --Otherwise it should be a table, recursively call to create + local submenu = menu:AddSubMenu(k) + CreateMenuFor(submenu,v) + end + end +end + +function com.generatereceiver() + return function(self,panels,dropped,index,cx,cy) + if dropped then + local froment,toent = panels[1].info.owner,self.info.owner + local fromid,toid = panels[1].info.id,self.info.id + local frompos,topos = panels[1].info.pos,self.info.pos + local frominv,toinv = panels[1].info.inv,self.info.inv + print("Something was dropped on:",x,y) + PrintTable(panels) + print("froment:",froment) + print("toent:",toent) + print("fromid",fromid) + print("toid",toid) + print("frompos:",frompos) + PrintTable(panels[1].info.pos) + print("topos:",topos) + PrintTable(self.info.pos) + print("frominv",frominv) + print("toinv",toinv) + local item = frominv:Get(frompos) + print("item was", item) + --Fake remove the item, in case the position we want to move it to overlaps with where it is now. + frominv:Remove(frompos) + local cf = toinv:CanFitIn(topos,item) + frominv:Put(frompos,item) + print("canfit was:",cf) + if cf == true then + --Send the request + net.Start("art_RequestInvMove") + net.WriteEntity(froment) + net.WriteEntity(toent) + net.WriteUInt(fromid,32) + net.WriteUInt(toid,32) + net.WriteTable(frompos) + net.WriteTable(topos) + net.SendToServer() + end + end + end +end + +return com diff --git a/gamemode/inventorysystem/equipment/cl_equipment.lua b/gamemode/inventorysystem/equipment/cl_equipment.lua index 5ffcccc..7abd27a 100644 --- a/gamemode/inventorysystem/equipment/cl_equipment.lua +++ b/gamemode/inventorysystem/equipment/cl_equipment.lua @@ -1,6 +1,7 @@ local col = nrequire("colortheme.lua") local svg = nrequire("cl_svg.lua") +local com = nrequire("cl_common.lua") local inv = {} local width, height = (ScrW() / 4) - 25, ScrH() @@ -98,20 +99,37 @@ local eqp = { } inv.DrawOnDPanel = function(self,panel) + print("Drawing equipment on panel") local prox = {} for k,v in pairs(eqp) do - local pn = vgui.Create("DImage",panel) + local pn = vgui.Create("DButton",panel) pn:SetSize(iconsize,iconsize) pn:SetPos(v.x,v.y) - if self.equiped[k] then - if self.equiped[k].OnPaint then - pn.Paint = self.equiped[k].OnPaint + pn.info = {} + pn.info.owner = LocalPlayer() + pn.info.id = self.id + pn.info.pos = {k} + pn.info.inv = self + pn:Droppable("item") + pn:Receiver("item",com.generatereceiver(),{"one","two","three"}) + if self.equiped[k] then --We have something equiped! + if self.equiped[k].GetOptions then + pn.DoClick = function() + local dm = DermaMenu() + com.CreateMenuFor(dm,self.equiped[k].GetOptions()) + dm:Open() + end + end + print("Found something equiped in ", k) + if self.equiped[k].OnEqpPaint then + pn.Paint = self.equiped[k].OnEqpPaint else pn.Paint = function(tp,w,h) draw.RoundedBox( 8, 0, 0, w, h, Color( 255, 0, 0 ) ) end end - else + else --We don't have something equiped! + print("Nothing was equiped in ", k) if v.img and v.img.material then local c = col.ui.border pn.Paint = function(tp,w,h) @@ -129,12 +147,42 @@ inv.DrawOnDPanel = function(self,panel) end prox[k] = pn end - prox.Put = function(position,item) - print("Put was called!") + prox.Put = function(self,position,item) + print("Put was called!",position,item) + PrintTable(position) + PrintTable(item) + assert(self[position[1]] ~= nil, "Tried to put an item into an unknown slot!") + if item.GetOptions then + self[position[1]].DoClick = function() + local dm = DermaMenu() + com.CreateMenuFor(dm,item.GetOptions()) + dm:Open() + end + end + if item.OnEqpPaint then + self[position[1]].Paint = item.OnEqpPaint + else + self[position[1]].Paint = function(tp,w,h) + draw.RoundedBox( 8, 0, 0, w, h, Color( 255, 0, 0 ) ) + end + end + self[position[1]]:Droppable("item") end - prox.Remove = function(position) - print("Remove was called!") + prox.Remove = function(self,position) + local pn = self[position[1]] + pn.DoClick = function() end + local c = col.ui.border + pn.Paint = function(self,w,h) + surface.SetDrawColor(c.r,c.g,c.b) + surface.DrawOutlinedRect(0, 0, w, h) + surface.SetDrawColor(255,255,255) + surface.SetMaterial( eqp[position[1]].img.material ) + surface.DrawTexturedRect( 0, 0, w, h ) + end + print("Remove was called!",position) + pn:Droppable("none") end + return prox end return inv diff --git a/gamemode/inventorysystem/equipment/sh_equipment.lua b/gamemode/inventorysystem/equipment/sh_equipment.lua index ca7c22d..3c30df15 100644 --- a/gamemode/inventorysystem/equipment/sh_equipment.lua +++ b/gamemode/inventorysystem/equipment/sh_equipment.lua @@ -64,7 +64,7 @@ inv.FindPlaceFor = function(self, item) end --Otherwise, just check if the slot is empty - if self.equiped[item.Equipable] == nil then + if self.equiped[item.Equipable] == nil and slots[self.equiped] ~= nil then return {item.Equipable} else return nil @@ -77,6 +77,7 @@ end inv.Put = function(self,position,item) self.equiped[position[1]] = item + if item.onEquip then item:onEquip(self.owner) end end inv.Has = function(self,string_or_compare_func) @@ -95,6 +96,8 @@ inv.Has = function(self,string_or_compare_func) end inv.Remove = function(self,position) + local item = self.equiped[position[1]] + if item.onUnEquip then item:onUnEquip(self.owner) end self.equiped[position[1]] = nil end @@ -124,57 +127,3 @@ inv.DeSerialize = function(self,data) end inventory.RegisterInventory(inv) - ---[[ -for k,v in pairs(slots) do - local inv = {} - inv.Name = "inv_" .. v - inv.FindPlaceFor = function(self, item) - if self.item == nil then return {} else return nil end - end - inv.CanFitIn = function(self,position,item) - if self.item == nil then return true else return "Inventory slot occupied by a(n)" .. self.item.Name end - end - inv.Put = function(self,pos,item) - self.item = item - end - inv.Has = function(self,prt) - if type(prt) == "string" then - if self.item ~= nil and self.item.Name == prt then return {} else return nil end - elseif type(prt) == "function" then - if prt(self.item) then return {} else return nil end - end - error(string.format("Passed a %s to %s:Has(), expected string or function",type(prt),self.Name)) - end - inv.Remove = function(self,pos) - self.item = nil - end - inv.Get = function(self,pos) - return self.item - end - inv.Serialize = function(self) - if self.item then - local data = ste.CreateStream() - local itemname = self.item.Name - local itemdata = self.item:Serialize() - data:WriteString(itemname) - data:WriteString(itemdata) - return data:ToString() - end - return "" - end - inv.DeSerialize = function(self,str) - print("data was",str) - if str == "" or str == nil then - return table.Copy(self) - else - local data = ste.CreateStream(str) - local itemname = data:ReadString() - local itemdata = data:ReadString() - self.item = itm.GetItemFromData(itemname,itemdata) - end - end - print("Attempting to register inventory with the name " .. inv.Name) - inventory.RegisterInventory(inv) -end -]] diff --git a/gamemode/inventorysystem/prayers/sh_prayers.lua b/gamemode/inventorysystem/prayers/sh_prayers.lua index 208540d..83414b7 100644 --- a/gamemode/inventorysystem/prayers/sh_prayers.lua +++ b/gamemode/inventorysystem/prayers/sh_prayers.lua @@ -1,5 +1,5 @@ -local reg = nrequire("inventory.lua") +local reg = nrequire("inventory/inventory.lua") local itm = nrequire("item.lua") local inv = {} inv.Name = "Prayers" @@ -27,7 +27,7 @@ function inv:Has(a) end function inv:Remove(pos) for i = 1,pos[1] do - self.track[i] = self.track[i+1] + self.track[i] = self.track[i + 1] end end function inv:Get(pos) @@ -38,6 +38,16 @@ function inv:Serialize() for k,v in pairs(self.track) do ret[v.Name] = v:Serialize() end + return util.TableToJSON(ret) +end + +function inv:DeSerialize(str) + local tbl = util.JSONToTable(str) + local i = 1 + for k,v in pairs(tbl) do + local this_prayer = itm.GetItemByName(k):DeSerialize(v) + self:Put({i},this_prayer) + end end diff --git a/gamemode/inventorysystem/shapedinventory/cl_shaped.lua b/gamemode/inventorysystem/shapedinventory/cl_shaped.lua new file mode 100644 index 0000000..3bd84c2 --- /dev/null +++ b/gamemode/inventorysystem/shapedinventory/cl_shaped.lua @@ -0,0 +1,169 @@ + +local com = nrequire("cl_common.lua") + +local inv = {} + +local width = ScrW() +--local height = ScrH() +local iconsize = width / 40 + +local function default_paint(self,w,h) + draw.RoundedBox( 8, 0, 0, w, h, Color( 0, 0, 0 ) ) +end + +--[[ +local function calcposition(dimx,dimy,x,y) + return (y * dimx) + x +end +]] + +local function shapebounds(shape) + local maxx = 0 + local maxy = 0 + for rn, row in pairs(shape) do + if #row > maxx then maxx = #row end + maxy = rn + end + return maxx, maxy +end + +--Run a function on all the panels in a shape +local function runonshape(self,shape,x,y,func) + for i = 1,#shape do + for j = 1, #shape[i] do + if shape[i][j] then + print("Running on ",i,j) + print("Which translates to", x + j, y + i) + func(self.gridpanels[x + i - 1][y + j - 1]) + end + end + end +end + +--Draw the item in a position +local function drawitemat(self,x,y,item) + print("Drawing item at ",x,y) + local tp = self.gridpanels[x][y] + runonshape(self,item.Shape,x,y,function(panel) + panel:SetVisible(false) + end) + tp:SetVisible(true) + local sx,sy = shapebounds(item.Shape) + tp:SetSize(iconsize * sx, iconsize * sy) + tp.DoClick = function() + if item.GetOptions then + com.CreateMenuFor(tp,item:GetOptions()) + end + end +end + +--Reset the position, using the item and it's shape +local function undrawitemat(self,x,y) + local item = self:Get({x,y}) + runonshape(self,item.Shape,x,y,function(panel) + panel:SetVisible(true) + panel:SetSize(iconsize,iconsize) + panel.Paint = default_paint + panel.DoClick = function() end + end) +end + +--[[ +local function generatereceiver(tinv,x,y) + return function(self,panels,dropped,index,cx,cy) + if dropped then + local froment,toent = panels[1].info.owner,self.info.owner + local fromid,toid = panels[1].info.id,self.info.id + local frompos,topos = panels[1].info.pos,self.info.pos + local frominv,toinv = panels[1].info.inv,self.info.inv + print("Something was dropped on:",x,y) + PrintTable(panels) + print("froment:",froment) + print("toent:",toent) + print("fromid",fromid) + print("toid",toid) + print("frompos:",frompos) + PrintTable(panels[1].info.pos) + print("topos:",topos) + PrintTable(self.info.pos) + print("frominv",frominv) + print("toinv",toinv) + local item = frominv:Get(frompos) + print("item was", item) + --Fake remove the item, in case the position we want to move it to overlaps with where it is now. + frominv:Remove(frompos) + local cf = toinv:CanFitIn(topos,item) + frominv:Put(frompos,item) + print("canfit was:",cf) + if cf == true then + --Send the request + net.Start("art_RequestInvMove") + net.WriteEntity(froment) + net.WriteEntity(toent) + net.WriteUInt(fromid,32) + net.WriteUInt(toid,32) + net.WriteTable(frompos) + net.WriteTable(topos) + net.SendToServer() + end + end + end +end +]] + +inv.DrawOnDPanel = function(self,panel) + print("Drawing shaped on panel") + local DScrollPanel = vgui.Create( "DScrollPanel",panel) + DScrollPanel:SetPos( 0, 0 ) + DScrollPanel:Dock(FILL) + + local grid = vgui.Create( "DGrid", DScrollPanel ) + grid:SetPos(0, 0) + grid:SetCols(self.dimx) + grid:SetColWide(iconsize) + grid:SetRowHeight(iconsize) + self.grid = grid + + self.gridpanels = {} + + --Create the full grid of dpanels + for x = 1, self.dimx do + for y = 1, self.dimy do + local dp = vgui.Create("DButton") + dp:SetSize(iconsize,iconsize) + dp.Paint = default_paint + dp:Droppable("item") + dp:Receiver("item",com.generatereceiver(),{"one","two","three"}) + dp.info = {} + dp.info.owner = LocalPlayer() + dp.info.id = self.id + dp.info.pos = {x,y} + dp.info.inv = self + grid:AddItem(dp) + self.gridpanels[x] = self.gridpanels[x] or {} + self.gridpanels[x][y] = dp + end + end + + --Go through the items, and set the dpanels appropriately. + for k,v in pairs(self.tracker) do + if type(v) == "table" then + local px = k % self.dimx + local py = math.floor(k / self.dimy) + drawitemat(self,px,py,v) + end + end + + local observer = {} + observer.Put = function(obs,position,item) + print("Drawing item at",position[1],position[2]) + drawitemat(self,position[1],position[2],item) + end + observer.Remove = function(obs,position) + print("Undrawing item at",position[1],position[2]) + undrawitemat(self,position[1],position[2]) + end + return observer +end + +return inv diff --git a/gamemode/inventorysystem/shapedinventory/sh_shaped.lua b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua new file mode 100644 index 0000000..de7ccd9 --- /dev/null +++ b/gamemode/inventorysystem/shapedinventory/sh_shaped.lua @@ -0,0 +1,147 @@ +--[[ + An inventory, with a shape! +]] + +local reg = nrequire("inventory/inventory.lua") +local itm = nrequire("item.lua") +local inv = {} +if CLIENT then inv = nrequire("cl_shaped.lua") end + +inv.Name = "Shaped Inventory" +inv.tracker = {} +inv.dimx = 5 +inv.dimy = 5 + +local function calcposition(dimx,dimy,x,y) + return ((x-1) * dimx) + y +end + +local function canfitin(self,x,y,shape) + print("Checking canfitin, tracker was") + PrintTable(self.tracker) + for rn,row in ipairs(shape) do + for cn,col in ipairs(row) do + local absx,absy = x + rn - 1, y + cn - 1 + local slot = calcposition(self.dimx,self.dimy,absx,absy) + print("Checking slot", slot) + if col and ((self.tracker[slot] ~= nil) or (slot > self.dimx * self.dimy)) then + return false + end + end + end + return true +end + +function inv:FindPlaceFor(item) + for x = 1, self.dimx do + for y = 1, self.dimy do + if canfitin(self,x,y,item.Shape) then + return {x,y} + end + end + end + return nil +end + +function inv:CanFitIn(tbl,item) + if canfitin(self,tbl[1],tbl[2],item.Shape) then + print("calculated, and can fit") + return true + else + print("calculated, could not fit") + return "Could not fit :(" + end +end + +function inv:Put(tbl,item) + print("Before putting ", item) + PrintTable(item) + print("tracker was") + PrintTable(self.tracker) + + --Set the item's shape to true + for rn,row in ipairs(item.Shape) do + for cn,col in ipairs(row) do + if col then + local slot = calcposition(self.dimx,self.dimy,tbl[1] + rn - 1,tbl[2] + cn - 1) + self.tracker[slot] = 1 + end + end + end + + --Now set the item in the correct slot + local slot = calcposition(self.dimx,self.dimy,tbl[1],tbl[2]) + self.tracker[slot] = item + print("After, tracker was ") + PrintTable(self.tracker) +end + +function inv:Has(ptr) + local compare_func = ptr + if type(ptr) == "string" then + compare_func = function(t) + return t.Name == ptr + end + end + for k,v in pairs(self.tracker) do + if type(v) == "table" and compare_func(v) then + local x = math.floor(k / self.dimx) + local y = k % self.dimx + return {x,y} + end + end + return nil +end + +function inv:Remove(tbl) + print("Removeing from",tbl[1],tbl[2]) + local slot = calcposition(self.dimx,self.dimy,tbl[1],tbl[2]) + print("Slot is",slot) + print("Tracking structure is:") + PrintTable(self.tracker) + local item = self.tracker[slot] + print("Removeing item",item) + PrintTable(item) + self.tracker[slot] = nil + for rn,row in ipairs(item.Shape) do + for cn,col in ipairs(row) do + if col then + slot = calcposition(self.dimx,self.dimy,tbl[1] + rn - 1,tbl[2] + cn - 1) + self.tracker[slot] = nil + end + end + end + print("After, tracker was") + PrintTable(self.tracker) +end + +function inv:Get(tbl) + local slot = calcposition(self.dimx,self.dimy,tbl[1],tbl[2]) + return self.tracker[slot] +end + +function inv:Serialize() + --Turn it into a sparse table + local ret = {} + for k,v in pairs(self.tracker) do + if type(v) == "table" then + ret[v.Name] = {k,v:Serialize()} + end + end + return util.TableToJSON(ret) +end + +function inv:DeSerialize(str) + print("Deserializeing from ", str) + --TODO:Implement + local tbl = util.JSONToTable(str) + for k,v in pairs(tbl) do + local name = k + local pos = v[1] + local data = v[2] + self.tracker[pos] = itm.GetItemFromData(name,data) + end +end + + +reg.RegisterInventory(inv) |
