mxp/
This is the set of instructions for installing the MXP snippet
==============================================================

1) Add mxp.c to your Makefile
2) Add this to the top of your main headerfile (merc.h)

   #include "mxp.h"

3) in comm.c the function read_from_buffer() contains the following
   lines somewhere in the middle. (This was taken from gw96).

        if ( d->inbuf[i] == '\b' && k > 0 )
            --k;
        else if ( isascii(d->inbuf[i]) && isprint(d->inbuf[i]) )
            d->incomm[k++] = d->inbuf[i];

   let's replace these lines with the following.

        if ( d->inbuf[i] == (signed char) IAC)
        {
          if (!memcmp(&d->inbuf[i], mxp_do, strlen(mxp_do)))
          {
            i += strlen(mxp_do) - 1;
            init_mxp(d);
          }
          else if (!memcmp(&d->inbuf[i], mxp_dont, strlen(mxp_dont)))
          {
            i += strlen(mxp_dont) - 1;
            shutdown_mxp(d);
          }
        }
        else if ( d->inbuf[i] == '\b' && k > 0 )
            --k;
        else if ( isascii(d->inbuf[i]) && isprint(d->inbuf[i]) )
            d->incomm[k++] = d->inbuf[i];

4) in comm.c somewhere in new_descriptor() (the unix version), you
   should be able to find some code that looks like this

      /* 
       * Send the greeting.
       */
      {
          extern char * help_greeting;
          if ( help_greeting[0] == '.' )
              write_to_buffer( dnew, help_greeting+1, 0 );
          else
              write_to_buffer( dnew, help_greeting  , 0 );
      }

   we should add a line either before or after this (your choice)
   which sends the IAC WILL TELOPT_MXP sequence, so the client
   knows that this mud supports MXP.

      write_to_buffer(dnew, mxp_will, 0);

5) Now open merc.h and find your PLR_ defines, and add a new one
   called PLR_MXP to the list (pick a free number, any number).
   I picked 2048, not that the number matters.

#define PLR_PROMPT                 1024
#define PLR_MXP                    2048

6) Again in merc.h goto the descriptor_data structure, it looks
   a bit like this

/*
 * Descriptor (channel) structure.
 */
struct  descriptor_data
{
    DESCRIPTOR_DATA *   next;
    DESCRIPTOR_DATA *   snoop_by;
    CHAR_DATA *         character;

   We need to add an additional entry to this structure, so just
   add this line somewhere inside the structure.

   bool                 mxp;

   This should by default be FALSE, so open comm.c and add goto
   the new_descriptor() function again. Somewhere it resets the
   values of the new descriptor, it looks a bit like this

      *dnew               = d_zero;
      dnew->descriptor    = desc;
      dnew->connected     = CON_GET_NAME;
      dnew->outsize       = 2000;
      dnew->outbuf        = alloc_mem( dnew->outsize );

   In some gw devs, all of this has been moved into a new function
   called init_descriptor(), if you have that one, just add this
   line there instead.

      dnew->mxp           = FALSE;

7) Open up merc.h again, and add the following prototypes and macros
   somewhere at the end of the file.

/* mxp.c */
void  mxp_to_char               ( CHAR_DATA *ch, char *txt, int mxp_style );
void  shutdown_mxp              ( DESCRIPTOR_DATA *d );
void  init_mxp                  ( DESCRIPTOR_DATA *d );

/* mxp macro */
#define USE_MXP(ch)             (IS_SET(ch->act, PLR_MXP) && ch->desc->mxp)

/* command to turn on mxp */
DECLARE_DO_FUN( do_mxp );

8 ) add do_mxp to interp.c as a command for players.

9 ) Recompile the entire code... and your ready to go.

How to use MXP in you mud
=========================
Ok, now your mud is ready to use MXP, I suggest you read through the MXP
notes on zuggsofts homepage (http://www.zuggsoft.com/zmud/mxp.htm)
this snippet does not come with support for all of them, but if you read
through the mxp_to_char() code, you'll find that it's easy enough to
add more tags. The tags this snippet DO support, all works well with zmud
and mushclient (latest versions).

When sending MXP tags to the user, you have to decide whether to use an
open or a secure stream. The open stream only allows safe MXP tags, like
underline, bold and italic text. The open stream is handy for text that
players can affect (like chat and player descriptions). The secure stream
allows ALL tags, so don't use this for anything a player can affect. It
is also possible to send a locked stream, though just using send_to_char()
will have this affect as well. The locked stream will not parse any TAGS,
and show them to the player just like normal text.

Using mxp_to_char is easy, which the following examples will show

mxp_to_char(ch, "<B>this text is bold</B> and <I>this text is italic</I>\n\r", MXP_ALL);
mxp_to_char(ch, "<U><B>This is underlined bold text</B></U>\n\r", MXP_ALL);

if you have ever written anything in html, you'll easily see how it works,
then <> tags starts a mode and the </> tags ends it.

You don't have to worry about players that doesn't have an MXP client, 
these players will just have the MXP tags stripped before it is send
to them. This is all done by mxp_to_char() so no worries :)

It is possible to do some really cool things with mxp, but you should read
through the mxp notes on zuggsoft.com for this. I'll end this with an
example of a pulldown menu (you right click on the link with your mouse
to get the menu. Left clicking will default to the first thing in the
menu).

mxp_to_char(ch, "<SEND href=\"say i clicked it|smile|look\" hint=\"Click to see the menu|First entry|Second entry|Third entry\">A Menu</SEND>", MXP_ALL);

That line, in all it's lenghtyness will show as "A menu" to the player, 
which is underlined. When left clicking on "A menu" it will cause the 
player to say "i clicked it", if the player right clicks, he gets a menu 
with three entries, labeled "First Entry", "Second Entry" and "Third Entry".
When he or she clicks on one of these entries, it will cause the player
to do one of three things (either say something, smile or look).

Have fun

Brian Graversen