--[[ 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 (absx > self.dimx) or (absy > 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)