Register forum user name Search FAQ

Gammon Forum

Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the password reset link.
 Entire forum ➜ MUSHclient ➜ Plugins ➜ MUSHclient generic graphical mapper module

MUSHclient generic graphical mapper module

It is now over 60 days since the last post. This thread is closed.     Refresh page


Pages: 1  2  3  4  5  6  7 8  9  10  11  12  13  14  15  16  17  

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #90 on Fri 23 Apr 2010 04:55 AM (UTC)
Message
To be clear above I have:
l := some constant that represents the smallest unit distance between 2 rooms
d := half the length of a side of a square representing a room. i.e. each room is 2d x 2d

Now, its likely that you actually start in a corner or something, in which case you calculate the center location and add that as a constant to the above formula.
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #91 on Sun 25 Apr 2010 03:15 PM (UTC)
Message
Alright folks, I've learned a little Lua and now have a plugin which will extract the following room information and remove all the variable components so that every time you visit the room it displays the same information.

room.name --string
room.desc --string
room.exit_desc --string
room.exit --array of strings

I also capture the direction when I'm attempting to move a valid direction.

So the question now is... How do I integrate this with the mapper and database?
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #92 on Sun 25 Apr 2010 10:31 PM (UTC)
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.

Template:saveplugin=Simple_Mapper To save and install the Simple_Mapper plugin do this:
  1. Copy between the lines below (to the Clipboard)
  2. Open a text editor (such as Notepad) and paste the plugin into it
  3. Save to disk on your PC, preferably in your plugins directory, as Simple_Mapper.xml
  4. Go to the MUSHclient File menu -> Plugins
  5. Click "Add"
  6. Choose the file Simple_Mapper.xml (which you just saved in step 3) as a plugin
  7. 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

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #93 on Mon 26 Apr 2010 01:56 AM (UTC)
Message
Awesome, thanks a bunch for the example Nick! I'm adapting it to my needs as we speak, I think I'm finally done for the short term, have some testing to do later.

I'm getting the strangest little error that is more of nuisance then anything. I included the following, so the mapper doesn't automatically start up when I log in.
function OnPluginConnect()
	EnablePlugin (GetPluginID (), false)
end -- OnPluginConnect
However, its the strangest thing the mapper starts off and just kicks itself back on. I only noticed because I have it attached to the icon_bar plugin and after all the other boxes grey out it lights back up.

Anyhow, when I actually start out doing some mapping I'm sure I'll have some more in-depth questions. But, it looks great, I'll let you know how the adaptation goes once I test drive it!
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #94 on Mon 26 Apr 2010 02:22 AM (UTC)
Message
LupusFatalis said:


	EnablePlugin (GetPluginID (), false)



Just put that line at the end of OnPluginInstall. That should work.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #95 on Mon 26 Apr 2010 02:44 AM (UTC)
Message
Worked, thanks. How odd.
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #96 on Wed 28 Apr 2010 01:08 PM (UTC)
Message
Alright, finally got to do a test run! And it works beautifully. I've got a few things to work out on my end, most of which I've got a plan of attack. However, I'm not quite sure how to deal with the following...

When I graph two rooms that are supposedly occupying the same spot is there an easy way to have the mapper offset them? I.E the database distinguishes between the rooms, but visually there is no indication.
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #97 on Wed 28 Apr 2010 09:12 PM (UTC)
Message
It shouldn't be drawing two rooms on top of each other. There is quite a bit of code to stop that happening. It isn't easy to offset them either, because, for example, it may have already drawn a north-south set of rooms before it realizes the whole lot have to move west a bit to accommodate another room somewhere else.

I think one of the more recent commits changed the way that worked.

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by Larkin   (278 posts)  Bio
Date Reply #98 on Wed 28 Apr 2010 09:44 PM (UTC)
Message
What about the databases that have valid X,Y coordinates already, though? It should be much easier to draw those in the "right" places.
Top

Posted by Nick Gammon   Australia  (23,120 posts)  Bio   Forum Administrator
Date Reply #99 on Wed 28 Apr 2010 10:03 PM (UTC)

Amended on Wed 28 Apr 2010 10:04 PM (UTC) by Nick Gammon

Message
It wouldn't be too bad, I think someone is working on it. However it basically is a rewrite of the inner loop because you no longer need to deduce room positions. Although it may become problematic if lines happen to cross (or a line happens to go straight through another room, could be messy).

- Nick Gammon

www.gammon.com.au, www.mushclient.com
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #100 on Thu 29 Apr 2010 05:03 PM (UTC)
Message
Ah, well, it does. Is there anything I could have coded to somehow screw up that system of checks and balances? Also, if you like I can get a picture. You can tell they are distinct because of an outline that is drawn when you actually go to one of the rooms in the stack.
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #101 on Fri 30 Apr 2010 02:13 AM (UTC)
Message
Another thing, that is more a curiosity then anything... Often times the mapper draws that a room has exits but does not draw the unexplored rooms. Any ideas?
Top

Posted by Larkin   (278 posts)  Bio
Date Reply #102 on Fri 30 Apr 2010 02:17 AM (UTC)
Message
Why would it draw rooms you haven't yet explored? Personally, I like a map that shows where I need to go yet, so I make sure I've fully discovered everything in an area.
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #103 on Fri 30 Apr 2010 02:32 AM (UTC)
Message
Actually, in my case, offsetting it an entire level would probably do just as well. Basically the problem here is I'm in a 3d area where I don't necessarily know if I'm going up or down anyway--(nor do I really care entirely)--i.e. my north might bring me +1 north +1 up... but to me the path is all that matters, graphics are just a way to move around easily.
Top

Posted by LupusFatalis   (154 posts)  Bio
Date Reply #104 on Fri 30 Apr 2010 06:12 PM (UTC)
Message
Well, for me its drawing 1 room with a dashed line to represent a possible room to explore. I'm not sure if I like it or not. But I'm asking if its supposed to be drawing all of those possibles, or if this is possibly indicative of a deeper error.
Top

The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).

To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.


761,653 views.

This is page 7, subject is 17 pages long:  [Previous page]  1  2  3  4  5  6  7 8  9  10  11  12  13  14  15  16  17  [Next page]

It is now over 60 days since the last post. This thread is closed.     Refresh page

Go to topic:           Search the forum


[Go to top] top

Information and images on this site are licensed under the Creative Commons Attribution 3.0 Australia License unless stated otherwise.