diff options
Diffstat (limited to 'gamemode/inventorysystem/shapedinventory')
| -rw-r--r-- | gamemode/inventorysystem/shapedinventory/cl_shaped.lua | 169 | ||||
| -rw-r--r-- | gamemode/inventorysystem/shapedinventory/sh_shaped.lua | 147 |
2 files changed, 316 insertions, 0 deletions
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) |
