Posted by
| Nick Gammon
Australia (23,072 posts) Bio
Forum Administrator |
Message
| Right. I have done a simple plugin (below) which illustrates integrating the mapper into a MUD which does NOT use telnet negotiation.
Basically we need to do a few things:
- Work out a unique ID (uid) for every room. In the plugin below I assume that if you concatenate the room name, room description, and room exits, this will be unique. This is then hashed to give an "id" like 1A3C0D23623EE643AB5D61B2C.
- Initialize the mapper (done in OnPluginInstall).
- Load previously-saved room and mapper config (also done in OnPluginInstall)
- Save new room information (done in OnPluginSaveState)
Note that this simple example just serializes the room data in the plugin state file. A better method would be to use the SQLite3 database, but I left that out to make the example simpler.
- Detect when we have changed rooms and call mapper.draw to update the map.
- The draw routine needs to know room information for each room, so we provide a callback function "get_room" which returns information for the requested room (if available) from the table of rooms.
- Detect where exits lead. We do this by noticing when we move (in OnPluginSent) and remembering the direction. We also remember where we were when we moved. Then upon arriving at a new room we can calculate that if we (say) were in room 12345, and we went west, and we are now in room 12346 then the west exit in room 12345 must lead to 12346. This information is used to update the rooms table.
Note that we are not sure the inverse applies so we need to go back to the original room for the reverse exit to be entered.
That's basically it. You should be able to use this on any MUD where you can detect room names, descriptions and exits. The trigger I used to detect room names is pretty simple (it just matches on the line colour). You can probably improve on that somewhat.
|
To save and install the Simple_Mapper plugin do this:
- Copy between the lines below (to the Clipboard)
- Open a text editor (such as Notepad) and paste the plugin into it
- Save to disk on your PC, preferably in your plugins directory, as Simple_Mapper.xml
- Go to the MUSHclient File menu -> Plugins
- Click "Add"
- Choose the file Simple_Mapper.xml (which you just saved in step 3) as a plugin
- Click "Close"
|
<?xml version="1.0" encoding="iso-8859-1"?>
<!DOCTYPE muclient>
<!-- Saved on Monday, April 26, 2010, 7:21 AM -->
<!-- MuClient version 4.51 -->
<!-- Plugin "Simple_Mapper" generated by Plugin Wizard -->
<muclient>
<plugin
name="Simple_Mapper"
author="Nick Gammon"
id="dd07d6dbe73fe0bd02ddb63d"
language="Lua"
purpose="Shows the mapper module in use"
save_state="y"
date_written="2010-04-26 07:21:01"
requires="4.51"
version="1.0"
>
</plugin>
<!-- Triggers -->
<triggers>
<trigger
back_colour="8"
bold="y"
enabled="y"
match="*"
match_back_colour="y"
match_bold="y"
match_inverse="y"
match_italic="y"
match_text_colour="y"
name="Name_Line"
script="Name_Line"
sequence="100"
text_colour="11"
>
</trigger>
<trigger
back_colour="8"
bold="y"
enabled="y"
match="*"
match_back_colour="y"
match_bold="y"
match_inverse="y"
match_italic="y"
match_text_colour="y"
name="Name_Or_Exits"
script="Name_Or_Exits"
sequence="100"
text_colour="15"
>
</trigger>
</triggers>
<!-- Script -->
<script>
<![CDATA[
require "mapper"
require "serialize"
require "copytable"
rooms = {}
valid_direction = {
n = "n",
s = "s",
e = "e",
w = "w",
u = "u",
d = "d",
ne = "ne",
sw = "sw",
nw = "nw",
se = "se",
north = "n",
south = "s",
east = "e",
west = "w",
up = "u",
down = "d",
northeast = "ne",
northwest = "nw",
southeast = "se",
southwest = "sw",
['in'] = "in",
out = "out",
} -- end of valid_direction
-- -----------------------------------------------------------------
-- Here on "Exits:" line ----- we have changed rooms
-- -----------------------------------------------------------------
function process_exits (exits_str)
-- genereate a "room ID" by hashing the room name, description and exits
uid = utils.tohex (utils.md5 (roomname .. roomdesc .. exits_str))
uid = uid:sub (1, 25)
-- break up exits into individual directions
exits = {}
for exit in string.gmatch (exits_str, "%w+") do
local ex = valid_direction [exit]
if ex then
exits [ex] = "0" -- don't know where it goes yet
end -- if
end -- for
-- add to table if not known
if not rooms [uid] then
rooms [uid] = { name = roomname, desc = roomdesc, exits = exits }
end -- if
-- save so we know current room later on
current_room = uid
-- call mapper to draw this rom
mapper.draw (uid)
-- try to work out where previous room's exit led
if expected_exit == "0" and from_room then
fix_up_exit ()
end -- exit was wrong
end -- process_exits
-- -----------------------------------------------------------------
-- Here on white coloured line - this is a room name or room exits
-- -----------------------------------------------------------------
function Name_Or_Exits (name, line, wildcards)
exits = string.match (line, "^Exits: (.*)")
if exits then
process_exits (exits)
end -- if
roomname = line
roomdesc = nil
end -- Name_Or_Exits
-- -----------------------------------------------------------------
-- Here on yellow line - part of room description
-- -----------------------------------------------------------------
function Name_Line (name, line, wildcards)
roomdesc = (roomdesc or "" ) .. line .. "\n"
end -- Name_Or_Exits
-- -----------------------------------------------------------------
-- mapper 'get_room' callback - it wants to know about room uid
-- -----------------------------------------------------------------
function get_room (uid)
if not rooms [uid] then
return nil
end -- if
local room = copytable.deep (rooms [uid])
local texits = {}
for dir in pairs (room.exits) do
table.insert (texits, dir)
end -- for
table.sort (texits)
room.hovermessage = string.format (
"%s\tExits: %s\nRoom: %s",
room.name,
table.concat (texits, ", "),
uid
)
if uid == current_room then
room.bordercolour = config.OUR_ROOM_COLOUR.colour
room.borderpenwidth = 2
end -- not in this area
return room
end -- get_room
-- -----------------------------------------------------------------
-- We have changed rooms - work out where the previous room led to
-- -----------------------------------------------------------------
function fix_up_exit ()
-- where we were before
local room = rooms [from_room]
-- leads to here
room.exits [last_direction_moved] = current_room
-- clear for next time
last_direction_moved = nil
from_room = nil
end -- fix_up_exit
-- -----------------------------------------------------------------
-- try to detect when we send a movement command
-- -----------------------------------------------------------------
function OnPluginSent (sText)
if valid_direction [sText] then
last_direction_moved = valid_direction [sText]
-- print ("Just moved", last_direction_moved)
if current_room and rooms [current_room] then
expected_exit = rooms [current_room].exits [last_direction_moved]
if expected_exit then
from_room = current_room
end -- if
-- print ("expected exit for this direction is to room", expected_exit)
end -- if
end -- if
end -- function
-- -----------------------------------------------------------------
-- Plugin Install
-- -----------------------------------------------------------------
function OnPluginInstall ()
config = {} -- in case not found
-- get saved configuration
assert (loadstring (GetVariable ("config") or "")) ()
-- and rooms
assert (loadstring (GetVariable ("rooms") or "")) ()
-- initialize mapper
mapper.init { config = config, get_room = get_room }
mapper.mapprint (string.format ("MUSHclient mapper installed, version %0.1f", mapper.VERSION))
end -- OnPluginInstall
-- -----------------------------------------------------------------
-- Plugin Save State
-- -----------------------------------------------------------------
function OnPluginSaveState ()
mapper.save_state ()
SetVariable ("config", "config = " .. serialize.save_simple (config))
SetVariable ("rooms", "rooms = " .. serialize.save_simple (rooms))
end -- OnPluginSaveState
]]>
</script>
</muclient>
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|