map = map or {}
map.room_info = map.room_info or {}
map.prev_info = map.prev_info or {}
map.aliases = map.aliases or {}
local defaults = {
-- using Geyser to handle the mapper in this, since this is a totally new script
mapper = {x = "-21%", y = 0, width = "20%", height = "30%"}
}
local terrain_types = {
-- used to make rooms of different terrain types have different colors
-- add a new entry for each terrain type, and set the color with RGB values
-- each id value must be unique, terrain types not listed here will use mapper default color
["Inside"] = {id = 1, r = 255, g = 0, b = 0},
}
-- list of possible movement directions and appropriate coordinate changes
local move_vectors = {
north = {0,1,0}, south = {0,-1,0}, east = {1,0,0}, west = {-1,0,0},
northwest = {-1,1,0}, northeast = {1,1,0}, southwest = {-1,-1,0}, southeast = {1,-1,0},
up = {0,0,1}, down = {0,0,-1}
}
-- used to convert short dirs for full dirs
local exits = {
n = "north", s = "south", w = "west", e = "east",
nw = "northwest", ne = "northeast", sw = "southwest", se = "southeast",
u = "up", d = "down"
}
local function make_room()
local info = map.room_info
local coords = {0,0,0}
addRoom(info.vnum)
local areas = getAreaTable()
local areaID = areas[info.area]
if not areaID then
areaID = addAreaName(info.area)
else
coords = {getRoomCoordinates(map.prev_info.vnum)}
local shift = {0,0,0}
for k,v in pairs(map.prev_info.exits) do
if v == info.vnum and move_vectors[k] then
shift = move_vectors[k]
break
end
end
for n = 1,3 do
coords[n] = coords[1] + shift[n]
end
-- map stretching
local overlap = getRoomsByPosition(areaID,coords[1],coords[2],coords[3])
if not table.is_empty(overlap) then
local rooms = getAreaRooms(areaID)
local rcoords
for _,id in ipairs(rooms) do
rcoords = getRoomCoordinates(id)
for n = 1,3 do
if shift[n] ~= 0 and (rcoords[n] - coords[n]) * shift[n] >= 0 then
rcoords[n] = rcoords[n] + shift[n]
end
end
setRoomCoords(id,rcoords[1],rcoords[2],rcoords[3])
end
end
end
setRoomArea(info.vnum, areaID)
setRoomCoordinates(info.vnum, coords[1], coords[2], coords[3])
if terrain_types[info.terrain] then
setRoomEnv(info.vnum, terrain_types[info.terrain].id)
end
for dir, id in pairs(info.exits) do
-- need to see how special exits are represented to handle those properly here
if getRoomName(id) then
setExit(info.vnum, id, dir)
else
setExitStub(info.vnum, dir, true)
end
end
end
local function shift_room(dir)
local ID = map.room_info.vnum
local x,y,z = getRoomCoords(ID)
local x1,y1,z1 = move_vector[dir]
x = x + x1
y = y + y1
z = z + z1
setRoomCoordinates(ID,x,y,z)
updateMap()
end
local function handle_move()
if not getRoomName(map.room_info.vnum) then
make_room()
end
centerview(map.room_info.vnum)
end
local function config()
-- don't actually know how MSDP works... but this seems to be in line with the examples I have seen
sendMSDP("REPORT", "ROOM")
-- setting terrain colors
for k,v in pairs(terrain_types) do
setCustomEnvColor(v.id, v.r, v.g, v.b, 255)
end
-- making mapper window
local info = defaults.mapper
Geyser.Mapper:new({name = "myMap", x = info.x, y = info.y, width = info.width, height = info.height})
-- clearing existing aliases if they exist
for k,v in pairs(map.aliases) do
killAlias(k)
end
-- making an alias to let the user shift a room around via command line
table.insert(map.aliases,tempAlias([[^shift (\w+)$]],[[raiseEvent("shiftRoom",matches[2])]]))
end
function map.eventHandler(event,...)
-- don't actually know how MSDP works... but this seems to be in line with the examples I have seen
if event == "msdp.ROOM" then
map.prev_info = map.room_info
map.room_info = table.update({},msdp.Room)
handle_move()
elseif event == "shiftRoom" then
local dir = exits[arg[1]] or arg[1]
if not table.contains(exits, dir) then
echo("Error: Invalid direction '" .. dir .. "'.")
else
shift_room(dir)
end
elseif event == "sysConnectionEvent" then
config()
end
end
registerAnonymousEventHandler("msdp.ROOM","map.eventHandler")
registerAnonymousEventHandler("shiftRoom","map.eventHandler")
registerAnonymousEventHandler("sysConnectionEvent", "map.eventHandler")
Edit2: Decided to toss in map stretching, and also fixed another bug I think I found.