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

104
maps/map
View File

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

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 = {
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)

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
detectAll(currPos)
end
mainMap:save()
mainMap:saveAll()
end
local function move(currPos, adjPos)