1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
--[[
An inventory, with a shape!
Items are stored in a 1-d array, array is 1-indexed
]]
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.width = 5
inv.height = 5
local function calcposition(width,height,row,col)
return ((row-1) * width) + col
end
local function canfitin(self,arow,acol,shape)
for rn,row in ipairs(shape) do
for cn,col in ipairs(row) do
local absrow,abscol = arow + rn - 1, acol + cn - 1
local slot = calcposition(self.width,self.height,absrow,abscol)
if col and ((self.tracker[slot] ~= nil) or (absrow > self.width) or (abscol > self.height)) then
return false
end
end
end
return true
end
function inv:FindPlaceFor(item)
if item.Shape == nil then return nil end
for row = 1, self.height do
for col = 1, self.width do
if canfitin(self,row,col,item.Shape) then
return {row,col}
end
end
end
return nil
end
function inv:CanFitIn(tbl,item)
if item.Shape == nil then return false end
if canfitin(self,tbl[1],tbl[2],item.Shape) then
return true
else
return "Could not fit :("
end
end
function inv:Put(tbl,item)
--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.width,self.height,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.width,self.height,tbl[1],tbl[2])
self.tracker[slot] = item
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 row = math.ceil(k / self.width)
local col = ((k - 1) % self.width) + 1
return {row,col}
end
end
return nil
end
function inv:Remove(tbl)
local slot = calcposition(self.width,self.height,tbl[1],tbl[2])
local item = self.tracker[slot]
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.width,self.height,tbl[1] + rn - 1,tbl[2] + cn - 1)
self.tracker[slot] = nil
end
end
end
return item
end
function inv:Get(tbl)
local slot = calcposition(self.width,self.height,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
local row = math.ceil(k / self.width)
local col = k % self.width
ret[v.Name] = {{row,col},v:Serialize()}
end
end
return util.TableToJSON(ret)
end
function inv:DeSerialize(str)
local ret = table.Copy(self)
local tbl = util.JSONToTable(str)
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)
--ret.tracker[pos] = itm.GetItemFromData(name,data)
end
return ret
end
reg.RegisterInventory(inv)
|