Generic Mapping Script

All and any discussion and development of the Mudlet Mapper.
illusaen
Posts: 3
Joined: Thu Sep 05, 2013 3:52 pm

Re: Generic Mapping Script

Post by illusaen »

Hi Jor'Mox,

I've been trying to get your MSDP script (on page18) working with my MUD (Legends of Kallisti, legendsofkallisti.com/4000); however, it seems to be running into some issues where the coordinates aren't being set correctly for some rooms while others are. I'm having issues with figuring out why. I've attached the code so you can take a look at where I setup the MSDP functions and added a setRoomName call. Any help would be appreciated!

Code: Select all

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 exitmap = {[1] = "north",   [2] = "northeast",   [3] = "northwest",   [4] = "east",
  [5] = "west",   [6] = "south",   [7] = "southeast",   [8] = "southwest",
  [9] = "up",   [10] = "down",   [11] = "in",   [12] = "out",}

local function make_room()
    local info = map.room_info
    local coords = {0,0,0}
    addRoom(info.vnum)
		setRoomName(info.vnum, info.name)
    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
						echo("\nv: " .. v .. " info.vnum: " .. info.vnum .. "\n")
            if v == info.vnum and move_vectors[k] then
                shift = move_vectors[k]
                break
            end
        end
				echo("final shift:\n")
				display(shift)
        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)
								echo("RCOORDS:\n")
								display(rcoords)
                for n = 1,3 do
								    echo("shift["..n.."]: " .. shift[n] .. " coords[n]: " .. coords[n] .. "\n")
                    if shift[n] ~= 0 and (rcoords[n] - coords[n]) * shift[n] >= 0 then
                        rcoords[n] = rcoords[n] + shift[n]
                    end
                end
								echo("\nCOORDS:\n")
								display(rcoords)
                setRoomCoords(id,rcoords[1],rcoords[2],rcoords[3])
            end
        end
    end
    setRoomArea(info.vnum, areaID)
    --setRoomName(info.vnum, info.name)
    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 = getRoomCoordinates(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()
    local info = map.room_info
    if not getRoomName(info.vnum) then
        make_room()
    else
        local stubs = getExitStubs1(info.vnum)
				if stubs then
          for _, n in ipairs(stubs) do
              local dir = exitmap[n]
              local id = info.exits[dir]
              -- need to see how special exits are represented to handle those properly here
              if getRoomName(id) then
                  setExit(info.vnum, id, dir)
              end
          end
				end
    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
    -- 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])]]))
		table.insert(map.aliases,tempAlias([[^make_room$]],[[make_room()]]))
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_VNUM" then
        local roomExits = {}
        for k, v in pairs(msdp.ROOM_EXITS) do
            if tonumber(v) then
            roomExits[k] = tonumber(v)
            end
        end
				--tempTimer(1, function()
        map.prev_info = map.room_info
				echo("\nPREVINFO:\n")
				display(map.prev_info)
        map.room_info = table.update({}, {vnum = tonumber(msdp.ROOM_VNUM), area = msdp.AREA_NAME, name = msdp.ROOM_NAME, exits = roomExits})
				echo("\nROOMINFO:\n")
				display(map.room_info)
        handle_move()
				--end)
    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_VNUM","map.eventHandler")
registerAnonymousEventHandler("shiftRoom","map.eventHandler")
registerAnonymousEventHandler("sysConnectionEvent", "map.eventHandler")

Jor'Mox
Posts: 1142
Joined: Wed Apr 03, 2013 2:19 am

Re: Generic Mapping Script

Post by Jor'Mox »

So, I went to your game, took your script, and modified it until I got it working, at least to the extent that I can wandering around in the starting city of Midgaard. Here is the code I'm using:
Code: [show] | [select all] lua
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 = "-31%", y = 0, width = "30%", height = "50%"}
}

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 exitmap = {[1] = "north",   [2] = "northeast",   [3] = "northwest",   [4] = "east",
  [5] = "west",   [6] = "south",   [7] = "southeast",   [8] = "southwest",
  [9] = "up",   [10] = "down",   [11] = "in",   [12] = "out",}

local function make_room()
    local info = map.room_info
    local coords = {0,0,0}
    addRoom(info.vnum)
	setRoomName(info.vnum, info.name)
    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(info.exits) do
            if v == map.prev_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
                setRoomCoordinates(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 = getRoomCoordinates(ID)
    local x1,y1,z1 = unpack(move_vectors[dir])
    x = x + x1
    y = y + y1
    z = z + z1
    setRoomCoordinates(ID,x,y,z)
    updateMap()
end

local function handle_move()
    local info = map.room_info
    if not getRoomName(info.vnum) then
        make_room()
    else
        local stubs = getExitStubs1(info.vnum)
		if stubs then
          for _, n in ipairs(stubs) do
              local dir = exitmap[n]
              local id = info.exits[dir]
              -- need to see how special exits are represented to handle those properly here
              if id and getRoomName(id) then
                  setExit(info.vnum, id, dir)
              end
          end
		end
    end
    centerview(map.room_info.vnum)
end

local function config()
		sendMSDP("REPORT", "ROOM_VNUM")
		sendMSDP("REPORT", "ROOM_NAME")
		sendMSDP("REPORT", "AREA_NAME")
		sendMSDP("REPORT", "ROOM_EXITS")
		
    -- 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(v)
    end
    map.aliases = {}
    -- 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])]]))
	table.insert(map.aliases,tempAlias([[^make_room$]],[[make_room()]]))
end

function map.eventHandler(event,...)
    if event == "msdp.ROOM_VNUM" then
        map.prev_info = map.room_info
        map.room_info = {vnum = tonumber(msdp.ROOM_VNUM), area = msdp.AREA_NAME, name = msdp.ROOM_NAME, exits = msdp.ROOM_EXITS}
        for k,v in pairs(map.room_info.exits) do
            map.room_info.exits[k] = tonumber(v)
        end
        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_VNUM","map.eventHandler")
registerAnonymousEventHandler("shiftRoom","map.eventHandler")
registerAnonymousEventHandler("sysConnectionEvent", "map.eventHandler")

storesund97
Posts: 1
Joined: Sat Jun 01, 2019 12:17 am

Re: Generic Mapping Script

Post by storesund97 »

HALP, I am trying to get a mapping script to work on Flexible Survival(adult game) but it messes up and I have no idea what I am doing. Please help me.

Zoticus
Posts: 3
Joined: Thu May 09, 2013 3:12 am

Re: Generic Mapping Script

Post by Zoticus »

Hello -

I have been recently playing Asteria (asteriamud.com port 1111) and have been making use of the generic mapper script to map the cities!

However, the script does not allow for the use of special exit delays, and I would greatly welcome some help in either modifying the current wait timer function to allow for situational activation, or another function that'd let me pause the mapper for whatever reason.

The mapper also does not seem to recognize use of 'script:' in the special exits GUI interface, sending anything there as a command. I would also greatly appreciate this functionality.

*Edit*

As a workaround, I have modified the following part of the 'continue_walk()' function to include a pause check:

Code: Select all

-- send command if we don't need to wait
    if not new_room and not speedwalk_paused then --added pause here
        send(table.remove(map.walkDirs,1))
        -- check to see if we are done
        if #map.walkDirs == 0 then
            walking = false
        end
I then use a trigger for the start of my delayed travel to set the paused variable to true, and another trigger upon arrival to unpause the mapper. This does work, and it'll let me use special exits, provided all of them have clearly defined 'start' and 'end' triggers, but I definitely welcome a more experienced coder to offer a more flexible fix.

Daagar
Posts: 89
Joined: Fri Feb 19, 2010 2:42 am

Re: Generic Mapping Script

Post by Daagar »

Way late to the party, but @Zoticus - check out the ASUI interface available for Asteria. It contains a modified mapping script (not this one) specific to Asteria that might solve all your issues.


More generally, I'm wondering if there would be value in a thread (wiki page?) that contains just a collection of trigger setups per mud? There is a lot of great info in this thread, but 38 pages is getting a tad long and there have been many updates to the script since page 1 that invalidates some of the earlier info. After messing around with using the script after being away for years, it seems that it does most everything one would need short of all-out crazy customization and having a one-stop shop for mud-specific trigger patterns for those looking for a plug-and-play solution might really help.

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Generic Mapping Script

Post by Vadi »

Yes! Glad you asked. The page exists on https://wiki.mudlet.org/w/Generic_Mapper_Additions - add your lines in there!

Daagar
Posts: 89
Joined: Fri Feb 19, 2010 2:42 am

Re: Generic Mapping Script

Post by Daagar »

Thank you Vadi! That page is slightly non-discoverable - or was there some more direct route to it that I was overlooking?

User avatar
Vadi
Posts: 5035
Joined: Sat Mar 14, 2009 3:13 pm

Re: Generic Mapping Script

Post by Vadi »

Not really - let me know how it could be better!

pakhibirdy
Posts: 3
Joined: Tue Mar 24, 2020 3:37 pm

Re: Generic Mapping Script

Post by pakhibirdy »

Hi, I am playing Accursed Lands (AL) and the generic mapper doesn't work for it.
Address:mud.accursed-lands.comPort:8000
Can you please modify the code to make it work?

Sample room:

The crossroad of a cobblestone road and a paved alley

Obvious exits: south, west, north, and east
It is well lit here.
------------------------------------------------------------------
This is the crossroad of Way of the Worm and Lame Man's Alley. Lame Man's
Alley continues to the north and south, and the Way of the Worm leads to the
east and west. A couple of seating areas have been set up in the northeastern
and southwestern corners of this area.
This area is large.
------------------------------------------------------------------
A heap of trash is collected close by to the northeast.
A heavy wooden bench is right next to you.
A heavy wooden bench is nearby to the northeast.
==================================================================
| > [hints] You can use the "rate" command if you notice someone doing a good job
of roleplaying or helping out over the OOC channels.
Last edited by pakhibirdy on Tue Mar 24, 2020 5:55 pm, edited 1 time in total.

pakhibirdy
Posts: 3
Joined: Tue Mar 24, 2020 3:37 pm

Re: Generic Mapping Script

Post by pakhibirdy »

I made it work. Another question:
What if there is multi-line exits? i.e.

Obvious exits:
Up : darkness
South: You see the southern end of the temple.
East : A quiet alcove
West : The World Adventurer's Social Point

What should I modify in this case?

Post Reply