Jor'Mox - Thank you so very much for the help. Here is the script I currently have, it works (mostly) only the map stretching has some bugs.
SlySven - I am a huge believer in providing as much data to the player as I can, if it will improve their playing experience. Therefore I give VNUMS to everyone via MSDP. This mapper will be part of the client GUI package I am developing for Luminari MUD.
map = map or {}
map.room_info = map.room_info or {}
map.prev_info = map.prev_info or {}
map.aliases = map.aliases or {}
map.enabled = true;
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 = 130, g = 130, b = 130},
["City"] = {id = 2, r = 200, g = 200, b = 200},
["Field"] = {id = 3, r = 0, g = 170, b = 0},
["Forest"] = {id = 4, r = 0, g = 122, b = 0},
["Hills"] = {id = 5, r = 122, g = 69, b = 0},
["Low Mountains"] = {id = 6, r = 116, g = 116, b = 116},
["Water (Swim)"] = {id = 7, r = 0, g = 0, b = 255},
["Water (No Swim)"] = {id = 8, r = 0, g = 0, b = 130},
["In Flight"] = {id = 9, r = 200, g = 200, b = 255},
["Underwater"] = {id = 10, r = 43, g = 43, b = 124},
["Zone Entrance"] = {id = 211, r = 255, g = 0, b = 0},
["Road North-South"] = {id = 12, r = 119, g = 101, b = 86},
["Road East-West"] = {id = 13, r = 119, g = 101, b = 86},
["Road Intersection"] = {id = 14, r = 119, g = 101, b = 86},
["Desert"] = {id = 15, r = 234, g = 219, b = 124},
["Ocean"] = {id = 16, r = 0, g = 90, b = 90},
["Marshland"] = {id = 17, r = 81, g = 47, b = 109},
["High Mountains"] = {id = 18, r = 255, g = 255, b = 255},
["Outer Planes"] = {id = 19, r = 168, g = 42, b = 138},
["Underdark - Wild"] = {id = 20, r = 131, g = 110, b = 145},
["Underdark - City"] = {id = 21, r = 183, g = 178, b = 186},
["Underdark - Inside"] = {id = 22, r = 132, g = 132, b = 132},
["Underdark - Water (Swim)"] = {id = 23, r = 70, g = 139, b = 175},
["Underdark - Water (No Swim)"] = {id = 24, r = 34, g = 68, b = 86},
["Underdark - In Flight"] = {id = 25, r = 158, g = 178, b = 188},
["Lava"] = {id = 26, r = 255, g = 119, b = 0},
["Dirt Road North-South"] = {id = 27, r = 142, g = 85, b = 0},
["Dirt Road East-West"] = {id = 28, r = 142, g = 85, b = 0},
["Dirt Road Intersection"] = {id = 29, r = 142, g = 85, b = 0},
["Cave"] = {id = 30, r = 80, g = 80, b = 80},
["Jungle"] = {id = 31, r = 21, g = 132, b = 101},
["Tundra"] = {id = 32, r = 224, g = 224, b = 224},
["Taiga"] = {id = 33, r = 103, g = 137, b = 104},
["Beach"] = {id = 34, r = 239, g = 235, 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 exitmap = {
north = 1, northeast = 2, northwest = 3, east = 4,
west = 5, south = 6, southeast = 7, southwest = 8,
up = 9, down = 10, ["in"] = 11, out = 12,
[1] = "north", [2] = "northeast", [3] = "northwest", [4] = "east",
[5] = "west", [6] = "south", [7] = "southeast", [8] = "southwest",
[9] = "up", [10] = "down", [11] = "in", [12] = "out",
}
for k, v in pairs(exitmap) do
end
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[n] + 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 + 16)
end
for dir, id in pairs(info.EXITS) do
-- need to see how special exits are represented to handle those properly here
if not setExit(info.VNUM, id, exitmap[dir]) then
setExitStub(info.VNUM, exitmap[dir], true)
end
end
end
local function shift_room(dir)
local ID = map.room_info.VNUM
local x,y,z = getRoomCoordinates(ID)
local x1,y1,z1 = move_vectors[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()
else
if terrain_types[map.room_info.TERRAIN] then
setRoomEnv(map.room_info.VNUM, terrain_types[map.room_info.TERRAIN].id + 16)
end
local stubs = getExitStubs1(map.room_info.VNUM)
if stubs then
for _, n in ipairs(stubs) do
local dir = exitmap[n]
local id = map.room_info.EXITS[dir]
-- need to see how special exits are represented to handle those properly here
if getRoomName(id) then
setExit(map.room_info.VNUM, id, exitmap[dir])
end
end
end
end
centerview(map.room_info.VNUM)
end
local function config()
-- setting terrain colors
for k,v in pairs(terrain_types) do
setCustomEnvColor(v.id + 16, 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,...)
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
function map.onProtocolEnabled(_, protocol)
if protocol == "MSDP" then
print("MSDP enabled!")
sendMSDP("REPORT", "ROOM")
config()
end
end
registerAnonymousEventHandler("msdp.ROOM","map.eventHandler")
registerAnonymousEventHandler("shiftRoom","map.eventHandler")
registerAnonymousEventHandler("sysConnectionEvent", "map.eventHandler")
registerAnonymousEventHandler("sysProtocolEnabled", "map.onProtocolEnabled")