From 86a66af83b7bada8e11137990cad62cc3556f8ae Mon Sep 17 00:00:00 2001 From: Matt Blunt Date: Wed, 10 Feb 2016 09:47:15 +0000 Subject: [PATCH] Updates to bring all maps and their viewers up to date with latest changes --- maps/compactMap | 8 +- maps/map | 104 +++++++++------- maps/map_viewer | 176 +++++++++++++++++++++++++++ maps/{remoteMap_client => remoteMap} | 0 maps/tinyMap | 79 +++++++----- maps/viewMap | 128 ------------------- starNav | 2 +- 7 files changed, 291 insertions(+), 206 deletions(-) create mode 100644 maps/map_viewer rename maps/{remoteMap_client => remoteMap} (100%) delete mode 100644 maps/viewMap diff --git a/maps/compactMap b/maps/compactMap index 7d0ddf4..182f5b2 100644 --- a/maps/compactMap +++ b/maps/compactMap @@ -153,7 +153,7 @@ local mapMethods = { set = function(self, tVector, value) if not isValidValue(value) then --should we throw an error or use a default value? - error("compactMap set: value is not valid", 2) + error("set: value is not valid") end local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector) local grid = getGrid(self, gX, gY, gZ) @@ -175,7 +175,7 @@ local mapMethods = { else if not isValidValue(value) then --should we throw an error or use a default value? - error("compactMap getOrSet: value is not valid", 2) + error("getOrSet: value is not valid") end if not grid[pX] then grid[pX] = {} @@ -197,11 +197,11 @@ function new(mapDir) if not fs.exists(mapDir) then fs.makeDir(mapDir) elseif not fs.isDir(mapDir) then - error("compactMap new: not a valid directory", 2) + error("new: not a valid directory") end tMap.mapDir = mapDir else - error("compactMap new: directory must be string", 2) + error("new: directory must be string") end tMap.map = {} setmetatable(tMap, mapMetatable) diff --git a/maps/map b/maps/map index 9866739..08650d3 100644 --- a/maps/map +++ b/maps/map @@ -1,5 +1,3 @@ -local maps = {} - local function toGridCode(tVector) 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 end @@ -23,7 +21,17 @@ local function getGrid(tMap, x, y, z) end end -local methods = { +local mapMethods = { + + getGrid = function(self, tVector, y, z) + local gX, gY, gZ + if y and z then + gX, gY, gZ = tVector, y, z + else + gX, gY, gZ = toGridCode(tVector) + end + return getGrid(self, gX, gY, gZ) + end, load = function(self, tVector, y, z) local gX, gY, gZ @@ -32,19 +40,15 @@ local methods = { else gX, gY, gZ = toGridCode(tVector) end - if self.name then - if fs.exists(".maps/"..self.name.."/"..gX..","..gY..","..gZ) then - local handle = fs.open(".maps/"..self.name.."/"..gX..","..gY..","..gZ, "r") - if handle then - local grid = handle.readAll() - handle.close() - for i = 15, 0, -1 do - grid = string.gsub(grid, tostring(i).."=", "%["..tostring(i).."%]=") - end - grid = textutils.unserialize(grid) - if type(grid) == "table" then - return setGrid(self, gX, gY, gZ, grid) - end + local gridPath = fs.combine(self.mapDir, gX..","..gY..","..gZ) + if fs.exists(gridPath) then + local handle = fs.open(gridPath, "r") + if handle then + local grid = handle.readAll() + handle.close() + grid = textutils.unserialise(grid) + if type(grid) == "table" then + return setGrid(self, gX, gY, gZ, grid) end end end @@ -52,8 +56,8 @@ local methods = { end, loadAll = function(self) - if self.name and fs.exists(".maps/"..self.name) and fs.isDir(".maps/"..self.name) then - for _, gridFile in ipairs(fs.list(".maps/"..self.name)) do + if fs.exists(self.mapDir) and fs.isDir(self.mapDir) then + for _, gridFile in ipairs(fs.list(self.mapDir)) do local _, _, gX, gY, gZ = string.find(gridFile, "(.+)%,(.+)%,(.+)") if gX and gY and gX then self:load(tonumber(gX), tonumber(gY), tonumber(gZ)) @@ -62,23 +66,32 @@ local methods = { end end, - save = function(self) - if self.name then - local saveDir = ".maps/"..self.name - for x, YZmap in pairs(self.map) do - for y, Zmap in pairs(YZmap) do - for z, grid in pairs(Zmap) do - if next(grid) then - local handle = fs.open(fs.combine(saveDir, x..","..y..","..z), "w") - local data = textutils.serialize(grid) - data = string.gsub(data, " ", "") - for i = 0, 15 do - data, num = string.gsub(data, "%["..tostring(i).."%]=", tostring(i).."=") - end - handle.write(data) - handle.close() - end - end + save = function(self, tVector, y, z) + local gX, gY, gZ + if y and z then + gX, gY, gZ = tVector, y, z + else + gX, gY, gZ = toGridCode(tVector) + end + if self.map[gX] and self.map[gX][gY] and self.map[gX][gY][gZ] then + local grid = self.map[gX][gY][gZ] + if next(grid) then + local handle = fs.open(fs.combine(self.mapDir, gX..","..gY..","..gZ), "w") + if handle then + handle.write(textutils.serialise(grid)) + handle.close() + end + else + fs.delete(fs.combine(self.mapDir, gX..","..gY..","..gZ)) + end + end + end, + + saveAll = function(self) + for gX, YZmap in pairs(self.map) do + for gY, Zmap in pairs(YZmap) do + for gZ, grid in pairs(Zmap) do + self:save(gX, gY, gZ) end end end @@ -123,20 +136,21 @@ local methods = { end, } +local mapMetatable = {__index = mapMethods} -function new(name) +function new(mapDir) local tMap = {} - if name and type(name) == "string" then - if maps[name] then - return maps[name] + if type(mapDir) == "string" then + if not fs.exists(mapDir) then + fs.makeDir(mapDir) + elseif not fs.isDir(mapDir) then + error("new: not a valid directory") end - tMap.name = name - if not fs.exists(".maps/"..name) then - fs.makeDir(".maps/"..name) - end - maps[name] = tMap + tMap.mapDir = mapDir + else + error("new: directory must be string") end tMap.map = {} - setmetatable(tMap, {__index = methods}) + setmetatable(tMap, mapMetatable) return tMap end \ No newline at end of file diff --git a/maps/map_viewer b/maps/map_viewer new file mode 100644 index 0000000..e4995c0 --- /dev/null +++ b/maps/map_viewer @@ -0,0 +1,176 @@ +local tArgs = {...} + +local function printUsage() + print("Usage:") + print(fs.getName(shell.getRunningProgram()).." ") + print("<(string)mapAPI_path> The path of the mapAPI the map uses.") + print("<(string)map_path> The directory path of the map you want to view.") + print("[optional] <(number)x_pos> <(number)y_pos> <(number)z_pos> The GPS coordinates you want to view the map at.") +end + +--===== LOAD MAP API =====-- +local mapAPIPath = tArgs[1] +if type(mapAPIPath) ~= "string" or not fs.exists(mapAPIPath) or fs.isDir(mapAPIPath) then + printError("invalid mapAPI_path: "..tostring(mapAPIPath)) + printUsage() + return +end +local mapAPI = fs.getName(mapAPIPath) +if not _G[mapAPI] then + if not os.loadAPI(mapAPIPath) then + printError("could not load mapAPI: "..tostring(mapAPIPath)) + printUsage() + return + end +end +mapAPI = _G[mapAPI] + +--===== LOAD MAP =====-- +if type(tArgs[2]) ~= "string" then + printError("string expected for map name") + printUsage() + return +end +local map = mapAPI.new(tArgs[2]) + +--===== FIND START COORDINATES =====-- +local currX, currY, currZ +if #tArgs == 5 then + for i = 3, 5 do + local num = tArgs[i] + if not tonumber(num) or num % 1 ~= 0 then + printError("argument "..tostring(i).." is not a number") + printUsage() + return + end + end + currX = tArgs[3] + currY = tArgs[4] + currZ = tArgs[5] +else + currX, currY, currZ = gps.locate(1) + if tonumber(currX) then + currX = math.floor(tonumber(currX)) + end + if tonumber(currY) then + currY = math.floor(tonumber(currY)) + end + if tonumber(currZ) then + currZ = math.floor(tonumber(currZ)) + end +end +if not (currX and currY and currZ) then + printError("could not identify start coords") + printUsage() + return +end + +term.setCursorBlink(false) +term.setTextColour(colours.white) +term.setBackgroundColour(colours.black) +term.clear() + +local width, height = term.getSize() +local currW, currH = 1, 1 + +local mainWindow = window.create(term.current(), 1, 1, width, math.max(0, height - 1), false) +mainWindow.setTextColour(colours.red) + +local toolbarWindow = window.create(term.current(), 1, height, width, 1, false) +toolbarWindow.setBackgroundColour(colours.grey) +toolbarWindow.setTextColour(colours.white) +toolbarWindow.clear() + +local function redrawMainWindow() + mainWindow.setVisible(false) + + mainWindow.setBackgroundColour(colours.black) + mainWindow.clear() + mainWindow.setBackgroundColour(colours.white) + + local w, h = mainWindow.getSize() + for x = 1, w do + for z = 1, h do + local value = map:get(vector.new(currX + x - 1, currY, currZ + z - 1)) + if value ~= nil then + mainWindow.setCursorPos(x, z) + mainWindow.write(string.sub(tostring(value), 1, 1)) + end + end + end + + local cursorValue = map:get(vector.new(currX + currW - 1, currY, currZ + currH - 1)) + mainWindow.setBackgroundColour(colours.green) + mainWindow.setCursorPos(currW, currH) + if cursorValue ~= nil then + mainWindow.write(string.sub(tostring(cursorValue), 1, 1)) + else + mainWindow.write(" ") + end + + mainWindow.setVisible(true) +end + +local function redrawToolbarWindow() + toolbarWindow.setVisible(false) + + toolbarWindow.setCursorPos(1, 1) + toolbarWindow.clearLine() + toolbarWindow.write(tostring(currX + currW - 1)..","..tostring(currY)..","..tostring(currZ + currH - 1)) + toolbarWindow.write(" -- ") + toolbarWindow.write(tostring(math.floor( (currX + currW - 1)/16 ))) + toolbarWindow.write(",") + toolbarWindow.write(tostring(math.floor( (currY)/16 ))) + toolbarWindow.write(",") + toolbarWindow.write(tostring(math.floor( (currZ + currH - 1)/16 ))) + + toolbarWindow.setVisible(true) +end + +local cont = true +local redraw = true +while cont do + if redraw then + redrawToolbarWindow() + redrawMainWindow() + redraw = false + end + local event = {os.pullEvent()} + if event[1] == "key" then + local key = event[2] + if key == keys.up then + currZ = currZ - 1 + currH = math.min(height - 1, currH + 1) + elseif key == keys.down then + currZ = currZ + 1 + currH = math.max(1, currH - 1) + elseif key == keys.left then + currX = currX - 1 + currW = math.min(width, currW + 1) + elseif key == keys.right then + currX = currX + 1 + currW = math.max(1, currW - 1) + elseif key == keys.numPadAdd then + currY = currY + 1 + elseif key == keys.numPadSubtract then + currY = currY - 1 + elseif key == keys.backspace then + cont = false + end + redraw = true + elseif event[1] == "mouse_click" then + if event[4] < height then + currW, currH = event[3], event[4] + redraw = true + end + elseif event[1] == "term_resize" then + width, height = term.getSize() + mainWindow.reposition(1, 1, width, math.max(0, height - 1)) + toolbarWindow.reposition(1, height, width, height) + redraw = true + end +end + +term.setBackgroundColour(colours.black) +term.setCursorPos(1, 1) +term.clear() \ No newline at end of file diff --git a/maps/remoteMap_client b/maps/remoteMap similarity index 100% rename from maps/remoteMap_client rename to maps/remoteMap diff --git a/maps/tinyMap b/maps/tinyMap index 167d243..4bd5f80 100644 --- a/maps/tinyMap +++ b/maps/tinyMap @@ -55,6 +55,16 @@ end local mapMethods = { + getGrid = function(self, tVector, y, z) + local gX, gY, gZ + if y and z then + gX, gY, gZ = tVector, y, z + else + gX, gY, gZ = toGridCode(tVector) + end + return getGrid(self, gX, gY, gZ) + end, + load = function(self, tVector, y, z) local gX, gY, gZ if y and z then @@ -123,33 +133,46 @@ local mapMethods = { end end, - save = function(self) + save = function(self, tVector, y, z) + local gX, gY, gZ + if y and z then + gX, gY, gZ = tVector, y, z + else + gX, gY, gZ = toGridCode(tVector) + end + if self.map[gX] and self.map[gX][gY] and self.map[gX][gY][gZ] then + local grid = self.map[gX][gY][gZ] + if next(grid) then + local rawData = {} + for x, gridYZ in pairs(grid) do + table.insert(rawData, BIT_MASKS.SET_COORD + BIT_MASKS.SET_X_COORD + x) + for y, gridZ in pairs(gridYZ) do + table.insert(rawData, BIT_MASKS.SET_COORD + y) + for z, coordValue in pairs(gridZ) do + table.insert(rawData, bit.blshift(coordValue, 4) + z) + end + end + end + --local data = rawData + local data = base64_to_base256(rawData) + local handle = fs.open(fs.combine(self.mapDir, gX..","..gY..","..gZ), "wb") + if handle then + for _, dataByte in ipairs(data) do + handle.write(dataByte) + end + handle.close() + end + else + fs.delete(fs.combine(self.mapDir, gX..","..gY..","..gZ)) + end + end + end, + + saveAll = function(self) for gX, YZmap in pairs(self.map) do for gY, Zmap in pairs(YZmap) do for gZ, grid in pairs(Zmap) do - if next(grid) then - local rawData = {} - for x, gridYZ in pairs(grid) do - table.insert(rawData, BIT_MASKS.SET_COORD + BIT_MASKS.SET_X_COORD + x) - for y, gridZ in pairs(gridYZ) do - table.insert(rawData, BIT_MASKS.SET_COORD + y) - for z, coordValue in pairs(gridZ) do - table.insert(rawData, bit.blshift(coordValue, 4) + z) - end - end - end - --local data = rawData - local data = base64_to_base256(rawData) - local handle = fs.open(fs.combine(self.mapDir, gX..","..gY..","..gZ), "wb") - if handle then - for _, dataByte in ipairs(data) do - handle.write(dataByte) - end - handle.close() - end - else - fs.delete(fs.combine(self.mapDir, gX..","..gY..","..gZ)) - end + self:save(gX, gY, gZ) end end end @@ -166,7 +189,7 @@ local mapMethods = { set = function(self, tVector, value) if not isValidValue(value) then --should we throw an error or use a default value? - error("set: value is not valid", 2) + error("set: value is not valid") end local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector) local grid = getGrid(self, gX, gY, gZ) @@ -188,7 +211,7 @@ local mapMethods = { else if not isValidValue(value) then --should we throw an error or use a default value? - error("getOrSet: value is not valid", 2) + error("getOrSet: value is not valid") end if not grid[pX] then grid[pX] = {} @@ -210,11 +233,11 @@ function new(mapDir) if not fs.exists(mapDir) then fs.makeDir(mapDir) elseif not fs.isDir(mapDir) then - error("new: not a valid directory", 2) + error("new: not a valid directory") end tMap.mapDir = mapDir else - error("new: directory must be string", 2) + error("new: directory must be string") end tMap.map = {} setmetatable(tMap, mapMetatable) diff --git a/maps/viewMap b/maps/viewMap deleted file mode 100644 index 44886c9..0000000 --- a/maps/viewMap +++ /dev/null @@ -1,128 +0,0 @@ -local tArgs = {...} - -local function printUsage() - print("Usages:") - print("viewMap <(string) mapAPIPath> <(string) mapName>") - print("viewMap <(string) mapAPIPath> <(string) mapName> <(int) x-coord> <(int) y-coord> <(int) z-coord>") - print("mapName must be the complete file path") -end - -local mapAPIPath = tArgs[1] -if not mapAPIPath or type(mapAPIPath) ~= "string" or not fs.exists(mapAPIPath) or fs.isDir(mapAPIPath) then - error("invalid mapAPIPath: "..tostring(mapAPIPath)) -end -local mapAPI = fs.getName(mapAPIPath) -if not _G[mapAPI] then - if not os.loadAPI(mapAPIPath) then - error("could not load mapAPI: "..tostring(mapAPIPath)) - end -end -mapAPI = _G[mapAPI] - -local map -local mapName = tArgs[2] -if mapName and type(mapName) == "string" and fs.exists(mapName) and fs.isDir(mapName) then - map = mapAPI.new(mapName) - if not map then - error("could not load map at "..mapName) - end -else - printUsage() -end - -local startX, startY, startZ -if #tArgs == 5 then - for i = 3, 5 do - local num = tArgs[i] - if not tonumber(num) or num % 1 ~= 0 then - printUsage() - return - end - end - startX = tArgs[3] - startY = tArgs[4] - startZ = tArgs[5] -end - -if not startX then - map:loadAll() - --find any point on map that isn't empty -end - -term.setCursorBlink(false) -term.setBackgroundColour(colours.black) - -local cont = true -local width, height = term.getSize() -local currW, currH = 1, 1 -term.setCursorBlink(true) -term.setTextColour(colours.red) -local redraw = true -while cont do - if redraw then - term.setBackgroundColour(colours.black) - term.clear() - term.setCursorPos(1, height) - term.clearLine() - term.write(tostring(startX + currW - 1)..","..tostring(startY)..","..tostring(startZ + currH - 1)) - term.write(" -- ") - term.write(tostring(math.floor( (startX + currW - 1)/16 ))) - term.write(",") - term.write(tostring(math.floor( (startY)/16 ))) - term.write(",") - term.write(tostring(math.floor( (startZ + currH - 1)/16 ))) - for x = 1, width do - for z = 1, height - 1 do - local value = map:get(vector.new(startX + x - 1, startY, startZ + z - 1)) - if value then - term.setBackgroundColour(colours.white) - term.setCursorPos(x, z) - term.write(string.sub(value, 1, 1)) - end - end - end - term.setCursorPos(currW, currH) - redraw = false - end - local event = {os.pullEvent()} - if event[1] == "key" then - local key = event[2] - if key == keys.up then - startZ = startZ - 1 - elseif key == keys.down then - startZ = startZ + 1 - elseif key == keys.left then - startX = startX - 1 - elseif key == keys.right then - startX = startX + 1 - elseif key == keys.numPadAdd then - startY = startY + 1 - elseif key == keys.numPadSubtract then - startY = startY - 1 - elseif key == keys.backspace then - cont = false - end - redraw = true - elseif event[1] == "mouse_click" then - if event[4] < height then - currW, currH = event[3], event[4] - term.setCursorPos(1, height) - term.clearLine() - term.write(tostring(startX + currW - 1)..","..tostring(startY)..","..tostring(startZ + currH - 1)) - term.write(" -- ") - term.write(tostring(math.floor( (startX + currW - 1)/16 ))) - term.write(",") - term.write(tostring(math.floor( (startY)/16 ))) - term.write(",") - term.write(tostring(math.floor( (startZ + currH - 1)/16 ))) - term.setCursorPos(currW, currH) - end - elseif event[1] == "term_resize" then - width, height = term.getSize() - redraw = true - end -end - -term.setBackgroundColour(colours.black) -term.setCursorPos(1, 1) -term.clear() \ No newline at end of file diff --git a/starNav b/starNav index 2c182af..12aa4ec 100644 --- a/starNav +++ b/starNav @@ -204,7 +204,7 @@ local function scan(currPos) else detectAll(currPos) end - mainMap:save() + mainMap:saveAll() end local function move(currPos, adjPos)