# tinyMap

Sep 5th, 2015
240
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
2.     SET_COORD = bit.blshift(1, 5),
3.     SET_X_COORD = bit.blshift(1, 4),
4.     COORD = 15,
5.     COORD_DATA = bit.blshift(1, 4),
6. }
7.
8. local function base256_to_base64(input)
9.     local output = {}
10.     for i = 1, #input, 3 do
11.         table.insert(output, bit.brshift(input[i] or 0, 2))
12.         table.insert(output, bit.blshift(bit.band(input[i] or 0, 3), 4) + bit.brshift(input[i+1] or 0, 4))
13.         table.insert(output, bit.blshift(bit.band(input[i+1] or 0, 15), 2) + bit.brshift(input[i+2] or 0, 6))
14.         table.insert(output, bit.band(input[i+2] or 0, 63))
15.     end
16.     return output
17. end
18.
19. local function base64_to_base256(input)
20.     local output = {}
21.     for i = 1, #input, 4 do
22.          table.insert(output, bit.blshift(input[i] or 0, 2) + bit.brshift(input[i+1] or 0, 4))
23.          table.insert(output, bit.blshift(bit.band(input[i+1] or 0, 15), 4) + bit.brshift(input[i+2] or 0, 2))
24.          table.insert(output, bit.blshift(bit.band(input[i+2] or 0, 3), 6) + (input[i+3] or 0))
25.     end
26.     return output
27. end
28.
29. local function isValidValue(value)
30.     return value == nil or value == 0 or value == 1
31. end
32.
33. local function toGridCode(tVector)
34.     return math.floor(tVector.x/16), math.floor(tVector.y/16), math.floor(tVector.z/16), tVector.x % 16, tVector.y % 16, tVector.z % 16
35. end
36.
37. local function setGrid(tMap, x, y, z, grid)
38.     if not tMap.map[x] then
39.         tMap.map[x] = {}
40.     end
41.     if not tMap.map[x][y] then
42.         tMap.map[x][y] = {}
43.     end
44.     tMap.map[x][y][z] = grid
45.     return tMap.map[x][y][z]
46. end
47.
48. local function getGrid(tMap, x, y, z)
49.     if not tMap.map[x] or not tMap.map[x][y] or not tMap.map[x][y][z] then
51.     else
52.         return tMap.map[x][y][z]
53.     end
54. end
55.
56. local mapMethods = {
57.
58.     load = function(self, tVector, y, z)
59.         local gX, gY, gZ
60.         if y and z then
61.             gX, gY, gZ = tVector, y, z
62.         else
63.             gX, gY, gZ = toGridCode(tVector)
64.         end
65.         local gridPath = fs.combine(self.mapDir, gX..","..gY..","..gZ)
66.         if fs.exists(gridPath) then
67.             local handle = fs.open(gridPath, "rb")
68.             if handle then
69.                 local grid = {}
70.
71.                 local rawData = {}
73.                 while rawDataByte do
74.                     table.insert(rawData, rawDataByte)
76.                 end
77.                 handle.close()
78.
79.                 --local data = rawData
80.                 local data = base256_to_base64(rawData)
81.
83.                 local currX, currY, currZ
84.                 local dataByte
85.                 for _, dataByte in ipairs(data) do
87.                         --we are changing our currX or currY coord
89.                             --we are changing our currX coord
91.                         else
92.                             --we are changing our currY coord
94.                         end
95.                     else
96.                         --we are setting the value for a proper coord
98.                         if currX and currY and currZ then
99.                             if not grid[currX] then
100.                                 grid[currX] = {}
101.                             end
102.                             if not grid[currX][currY] then
103.                                 grid[currX][currY] = {}
104.                             end
105.                             grid[currX][currY][currZ] = bit.brshift(bit.band(dataByte, BIT_MASKS.COORD_DATA), 4)
106.                         end
107.                     end
108.                 end
109.                 return setGrid(self, gX, gY, gZ, grid)
110.             end
111.         end
112.         return setGrid(self, gX, gY, gZ, {})
113.     end,
114.
116.         if fs.exists(self.mapDir) and fs.isDir(self.mapDir) then
117.             for _, gridFile in ipairs(fs.list(self.mapDir)) do
118.                 local _, _, gX, gY, gZ = string.find(gridFile, "(.+)%,(.+)%,(.+)")
119.                 if gX and gY and gX then
121.                 end
122.             end
123.         end
124.     end,
125.
126.     save = function(self)
127.         for gX, YZmap in pairs(self.map) do
128.             for gY, Zmap in pairs(YZmap) do
129.                 for gZ, grid in pairs(Zmap) do
130.                     if next(grid) then
131.                         local rawData = {}
132.                         for x, gridYZ in pairs(grid) do
134.                             for y, gridZ in pairs(gridYZ) do
136.                                 for z, coordValue in pairs(gridZ) do
137.                                     table.insert(rawData, bit.blshift(coordValue, 4) + z)
138.                                 end
139.                             end
140.                         end
141.                         --local data = rawData
142.                         local data = base64_to_base256(rawData)
143.                         local handle = fs.open(fs.combine(self.mapDir, gX..","..gY..","..gZ), "wb")
144.                         if handle then
145.                             for _, dataByte in ipairs(data) do
146.                                 handle.write(dataByte)
147.                             end
148.                             handle.close()
149.                         end
150.                     else
151.                         fs.delete(fs.combine(self.mapDir, gX..","..gY..","..gZ))
152.                     end
153.                 end
154.             end
155.         end
156.     end,
157.
158.     get = function(self, tVector)
159.         local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector)
160.         local grid = getGrid(self, gX, gY, gZ)
161.         if grid[pX] and grid[pX][pY] then
162.             return grid[pX][pY][pZ]
163.         end
164.     end,
165.
166.     set = function(self, tVector, value)
167.         if not isValidValue(value) then
168.             --should we throw an error or use a default value?
169.             error("set: value is not valid", 2)
170.         end
171.         local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector)
172.         local grid = getGrid(self, gX, gY, gZ)
173.         if not grid[pX] then
174.             grid[pX] = {}
175.         end
176.         if not grid[pX][pY] then
177.             grid[pX][pY] = {}
178.         end
179.         grid[pX][pY][pZ] = value
180.         return grid[pX][pY][pZ]
181.     end,
182.
183.     getOrSet = function(self, tVector, value)
184.         local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector)
185.         local grid = getGrid(self, gX, gY, gZ)
186.         if grid[pX] and grid[pX][pY] and grid[pX][pY][pZ] then
187.             return grid[pX][pY][pZ], false
188.         else
189.             if not isValidValue(value) then
190.                 --should we throw an error or use a default value?
191.                 error("getOrSet: value is not valid", 2)
192.             end
193.             if not grid[pX] then
194.                 grid[pX] = {}
195.             end
196.             if not grid[pX][pY] then
197.                 grid[pX][pY] = {}
198.             end
199.             grid[pX][pY][pZ] = value
200.             return grid[pX][pY][pZ], true
201.         end
202.     end,
203.
204. }
205. local mapMetatable = {__index = mapMethods}
206.
207. function new(mapDir)
208.     local tMap = {}
209.     if type(mapDir) == "string" then
210.         if not fs.exists(mapDir) then
211.             fs.makeDir(mapDir)
212.         elseif not fs.isDir(mapDir) then
213.             error("new: not a valid directory", 2)
214.         end
215.         tMap.mapDir = mapDir
216.     else
217.         error("new: directory must be string", 2)
218.     end
219.     tMap.map = {}
220.     setmetatable(tMap, mapMetatable)
221.     return tMap
222. end
RAW Paste Data