aboutsummaryrefslogtreecommitdiff
path: root/gamemode/inventorysystem
diff options
context:
space:
mode:
Diffstat (limited to 'gamemode/inventorysystem')
-rw-r--r--gamemode/inventorysystem/cl_common.lua59
-rw-r--r--gamemode/inventorysystem/equipment/cl_equipment.lua66
-rw-r--r--gamemode/inventorysystem/equipment/sh_equipment.lua59
-rw-r--r--gamemode/inventorysystem/prayers/sh_prayers.lua14
-rw-r--r--gamemode/inventorysystem/shapedinventory/cl_shaped.lua169
-rw-r--r--gamemode/inventorysystem/shapedinventory/sh_shaped.lua147
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)