Updates to bring all maps and their viewers up to date with latest changes

This commit is contained in:
Matt Blunt 2016-02-10 09:47:15 +00:00
parent 75c4f8ee1c
commit 86a66af83b
7 changed files with 291 additions and 206 deletions

View File

@ -153,7 +153,7 @@ local mapMethods = {
set = function(self, tVector, value) set = function(self, tVector, value)
if not isValidValue(value) then if not isValidValue(value) then
--should we throw an error or use a default value? --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 end
local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector) local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector)
local grid = getGrid(self, gX, gY, gZ) local grid = getGrid(self, gX, gY, gZ)
@ -175,7 +175,7 @@ local mapMethods = {
else else
if not isValidValue(value) then if not isValidValue(value) then
--should we throw an error or use a default value? --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 end
if not grid[pX] then if not grid[pX] then
grid[pX] = {} grid[pX] = {}
@ -197,11 +197,11 @@ function new(mapDir)
if not fs.exists(mapDir) then if not fs.exists(mapDir) then
fs.makeDir(mapDir) fs.makeDir(mapDir)
elseif not fs.isDir(mapDir) then elseif not fs.isDir(mapDir) then
error("compactMap new: not a valid directory", 2) error("new: not a valid directory")
end end
tMap.mapDir = mapDir tMap.mapDir = mapDir
else else
error("compactMap new: directory must be string", 2) error("new: directory must be string")
end end
tMap.map = {} tMap.map = {}
setmetatable(tMap, mapMetatable) setmetatable(tMap, mapMetatable)

104
maps/map
View File

@ -1,5 +1,3 @@
local maps = {}
local function toGridCode(tVector) 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 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 end
@ -23,7 +21,17 @@ local function getGrid(tMap, x, y, z)
end end
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) load = function(self, tVector, y, z)
local gX, gY, gZ local gX, gY, gZ
@ -32,19 +40,15 @@ local methods = {
else else
gX, gY, gZ = toGridCode(tVector) gX, gY, gZ = toGridCode(tVector)
end end
if self.name then local gridPath = fs.combine(self.mapDir, gX..","..gY..","..gZ)
if fs.exists(".maps/"..self.name.."/"..gX..","..gY..","..gZ) then if fs.exists(gridPath) then
local handle = fs.open(".maps/"..self.name.."/"..gX..","..gY..","..gZ, "r") local handle = fs.open(gridPath, "r")
if handle then if handle then
local grid = handle.readAll() local grid = handle.readAll()
handle.close() handle.close()
for i = 15, 0, -1 do grid = textutils.unserialise(grid)
grid = string.gsub(grid, tostring(i).."=", "%["..tostring(i).."%]=") if type(grid) == "table" then
end return setGrid(self, gX, gY, gZ, grid)
grid = textutils.unserialize(grid)
if type(grid) == "table" then
return setGrid(self, gX, gY, gZ, grid)
end
end end
end end
end end
@ -52,8 +56,8 @@ local methods = {
end, end,
loadAll = function(self) loadAll = function(self)
if self.name and fs.exists(".maps/"..self.name) and fs.isDir(".maps/"..self.name) then if fs.exists(self.mapDir) and fs.isDir(self.mapDir) then
for _, gridFile in ipairs(fs.list(".maps/"..self.name)) do for _, gridFile in ipairs(fs.list(self.mapDir)) do
local _, _, gX, gY, gZ = string.find(gridFile, "(.+)%,(.+)%,(.+)") local _, _, gX, gY, gZ = string.find(gridFile, "(.+)%,(.+)%,(.+)")
if gX and gY and gX then if gX and gY and gX then
self:load(tonumber(gX), tonumber(gY), tonumber(gZ)) self:load(tonumber(gX), tonumber(gY), tonumber(gZ))
@ -62,23 +66,32 @@ local methods = {
end end
end, end,
save = function(self) save = function(self, tVector, y, z)
if self.name then local gX, gY, gZ
local saveDir = ".maps/"..self.name if y and z then
for x, YZmap in pairs(self.map) do gX, gY, gZ = tVector, y, z
for y, Zmap in pairs(YZmap) do else
for z, grid in pairs(Zmap) do gX, gY, gZ = toGridCode(tVector)
if next(grid) then end
local handle = fs.open(fs.combine(saveDir, x..","..y..","..z), "w") if self.map[gX] and self.map[gX][gY] and self.map[gX][gY][gZ] then
local data = textutils.serialize(grid) local grid = self.map[gX][gY][gZ]
data = string.gsub(data, " ", "") if next(grid) then
for i = 0, 15 do local handle = fs.open(fs.combine(self.mapDir, gX..","..gY..","..gZ), "w")
data, num = string.gsub(data, "%["..tostring(i).."%]=", tostring(i).."=") if handle then
end handle.write(textutils.serialise(grid))
handle.write(data) handle.close()
handle.close() end
end else
end 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 end
end end
@ -123,20 +136,21 @@ local methods = {
end, end,
} }
local mapMetatable = {__index = mapMethods}
function new(name) function new(mapDir)
local tMap = {} local tMap = {}
if name and type(name) == "string" then if type(mapDir) == "string" then
if maps[name] then if not fs.exists(mapDir) then
return maps[name] fs.makeDir(mapDir)
elseif not fs.isDir(mapDir) then
error("new: not a valid directory")
end end
tMap.name = name tMap.mapDir = mapDir
if not fs.exists(".maps/"..name) then else
fs.makeDir(".maps/"..name) error("new: directory must be string")
end
maps[name] = tMap
end end
tMap.map = {} tMap.map = {}
setmetatable(tMap, {__index = methods}) setmetatable(tMap, mapMetatable)
return tMap return tMap
end end

176
maps/map_viewer Normal file
View File

@ -0,0 +1,176 @@
local tArgs = {...}
local function printUsage()
print("Usage:")
print(fs.getName(shell.getRunningProgram()).." <mapAPI_path> <map_path> <x_pos> <y_pos> <z_pos>")
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()

View File

@ -55,6 +55,16 @@ end
local mapMethods = { 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) load = function(self, tVector, y, z)
local gX, gY, gZ local gX, gY, gZ
if y and z then if y and z then
@ -123,33 +133,46 @@ local mapMethods = {
end end
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 gX, YZmap in pairs(self.map) do
for gY, Zmap in pairs(YZmap) do for gY, Zmap in pairs(YZmap) do
for gZ, grid in pairs(Zmap) do for gZ, grid in pairs(Zmap) do
if next(grid) then self:save(gX, gY, gZ)
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
end end
end end
@ -166,7 +189,7 @@ local mapMethods = {
set = function(self, tVector, value) set = function(self, tVector, value)
if not isValidValue(value) then if not isValidValue(value) then
--should we throw an error or use a default value? --should we throw an error or use a default value?
error("set: value is not valid", 2) error("set: value is not valid")
end end
local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector) local gX, gY, gZ, pX, pY, pZ = toGridCode(tVector)
local grid = getGrid(self, gX, gY, gZ) local grid = getGrid(self, gX, gY, gZ)
@ -188,7 +211,7 @@ local mapMethods = {
else else
if not isValidValue(value) then if not isValidValue(value) then
--should we throw an error or use a default value? --should we throw an error or use a default value?
error("getOrSet: value is not valid", 2) error("getOrSet: value is not valid")
end end
if not grid[pX] then if not grid[pX] then
grid[pX] = {} grid[pX] = {}
@ -210,11 +233,11 @@ function new(mapDir)
if not fs.exists(mapDir) then if not fs.exists(mapDir) then
fs.makeDir(mapDir) fs.makeDir(mapDir)
elseif not fs.isDir(mapDir) then elseif not fs.isDir(mapDir) then
error("new: not a valid directory", 2) error("new: not a valid directory")
end end
tMap.mapDir = mapDir tMap.mapDir = mapDir
else else
error("new: directory must be string", 2) error("new: directory must be string")
end end
tMap.map = {} tMap.map = {}
setmetatable(tMap, mapMetatable) setmetatable(tMap, mapMetatable)

View File

@ -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()

View File

@ -204,7 +204,7 @@ local function scan(currPos)
else else
detectAll(currPos) detectAll(currPos)
end end
mainMap:save() mainMap:saveAll()
end end
local function move(currPos, adjPos) local function move(currPos, adjPos)