ackfuss-4.3.2/area/boards/
ackfuss-4.3.2/npcs/a/
ackfuss-4.3.2/npcs/b/
ackfuss-4.3.2/npcs/c/
ackfuss-4.3.2/npcs/d/
ackfuss-4.3.2/npcs/e/
ackfuss-4.3.2/npcs/f/
ackfuss-4.3.2/npcs/h/
ackfuss-4.3.2/npcs/i/
ackfuss-4.3.2/npcs/k/
ackfuss-4.3.2/npcs/l/
ackfuss-4.3.2/npcs/n/
ackfuss-4.3.2/npcs/o/
ackfuss-4.3.2/npcs/p/
ackfuss-4.3.2/npcs/r/
ackfuss-4.3.2/npcs/s/
ackfuss-4.3.2/npcs/w/
ackfuss-4.3.2/player/c/
ackfuss-4.3.2/reports/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  Ack 2.2 improvements copyright (C) 1994 by Stephen Dooley              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *       _/          _/_/_/     _/    _/     _/    ACK! MUD is modified    *
 *      _/_/        _/          _/  _/       _/    Merc2.0/2.1/2.2 code    *
 *     _/  _/      _/           _/_/         _/    (c)Stephen Zepp 1998    *
 *    _/_/_/_/      _/          _/  _/             Version #: 4.3          *
 *   _/      _/      _/_/_/     _/    _/     _/                            *
 *                                                                         *
 *                        http://ackmud.nuc.net/                           *
 *                        zenithar@ackmud.nuc.net                          *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

/* This code inspired by a snippet from :                                  */

/************************************************************************/
/* mlkesl@stthomas.edu	=====>	Ascii Automapper utility                */
/* Let me know if you use this. Give a newbie some _credit_,            */
/* at least I'm not asking how to add classes...                        */
/* Also, if you fix something could ya send me mail about, thanks       */
/* PLEASE mail me if you use this or like it, that way I will keep it up*/
/************************************************************************/

#include <ctype.h>   /* for isalpha */
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
#include "mapper.h"

extern char *compass_name[];

int door_marks[4][2] = { {-1, 0}, {0, 1}, {1, 0}, {0, -1} };
int offsets[4][2] = { {-2, 0}, {0, 2}, {2, 0}, {0, -2} };

#define SECT_HERE	SECT_MAX
#define SECT_UNSEEN	( SECT_MAX + 1 )
#define SECT_BLOCKED	( SECT_UNSEEN + 1 )
#define SECT_TOP	( SECT_BLOCKED + 1 )


const struct map_info_type door_info[] = {
   {DOOR_LOCKED, "@@R", "#@@N", "@@f", "Locked door"},
   {DOOR_OPEN, "@@W", "#@@N", "@@f", "Open door"},
   {DOOR_CLOSED, "@@R", "#@@N", "@@f", "Closed Door"},
   {DOOR_NS, "@@W", "|@@N", "@@f", "N/S Exit"},
   {DOOR_EW, "@@W", "-@@N", "@@f", "E/W Exit"},
   {DOOR_NULL, "@@N", " ", "@@f", "Invalid"}
};

const struct map_info_type map_info[] = {
   {SECT_BLOCKED, "@@m", "~@@N", "", "blocked"},
   {SECT_UNSEEN, "@@N@@d", " @@N", "", "unknown"},
   {SECT_HERE, "@@N@@W", "*@@N", "", "you!"},
   {SECT_CITY, "@@g@@i", " @@N", "", "city"},
   {SECT_FIELD, "@@r@@i", " @@N", "", "field"},
   {SECT_FOREST, "@@3", " @@N", "@@W", "forest"},
   {SECT_HILLS, "@@4", " @@N", "@@W", "hills"},
   {SECT_MOUNTAIN, "@@2", " @@N", "", "mountain"},
   {SECT_WATER_SWIM, "@@l@@i", " @@N", "", "shallow water"},
   {SECT_WATER_NOSWIM, "@@1", " @@N", "", "deep running water"},
   {SECT_RECALL_OK, "@@5", " @@N", "", "inside"},
   {SECT_AIR, "@@a@@i", " @@N", "", "air"},
   {SECT_DESERT, "@@y@@i", " @@N", "", "desert"},
   {SECT_INSIDE, "@@d@@i", " @@N", "", "inside"},
   {SECT_TOP, "@@y", "~@@N", "", "bad sector type"}
};

char *get_sector_display( int sector )
{
   sh_int looper;
   for( looper = 0;; looper++ )
      if( ( map_info[looper].sector_type == sector ) || ( map_info[looper].sector_type == SECT_TOP ) )
         break;
   return ( map_info[looper].display_code );
}
char *get_sector_color( int sector )
{
   sh_int looper;
   for( looper = 0;; looper++ )
      if( ( map_info[looper].sector_type == sector ) || ( map_info[looper].sector_type == SECT_TOP ) )
         break;
   return ( map_info[looper].display_color );
}
char *get_invert_color( int sector )
{
   sh_int looper;
   for( looper = 0;; looper++ )
      if( ( map_info[looper].sector_type == sector ) || ( map_info[looper].sector_type == SECT_TOP ) )
         break;
   return ( map_info[looper].invert_color );
}
char *get_door_display( int door )
{
   sh_int looper;
   for( looper = 0;; looper++ )
      if( ( door_info[looper].sector_type == door ) || ( door_info[looper].sector_type == DOOR_NULL ) )
         break;
   return ( door_info[looper].display_code );
}
char *get_door_color( int door )
{
   sh_int looper;
   for( looper = 0;; looper++ )
      if( ( door_info[looper].sector_type == door ) || ( door_info[looper].sector_type == DOOR_NULL ) )
         break;
   return ( door_info[looper].display_color );
}
char *get_sector_name( int sector )
{
   sh_int looper;
   for( looper = 0;; looper++ )
      if( ( map_info[looper].sector_type == sector ) || ( map_info[looper].sector_type == SECT_TOP ) )
         break;
   return ( map_info[looper].desc );
}


/*
 * This code written by Altrag for Ack!Mud 
 */

#define iseol(c)	((c)=='\n' || (c)=='\r')

/* Like one_argument but saves case, and if len isnt NULL, fills it in
 * with the length.  Also accounts for color.  Does NOT account for
 * quoted text. */
char *break_arg( char *str, char *first_arg, int bufsize, int max, int *buflen, int *len )
{
   int slen = 0;
   char *arg;

   while( isspace( *str ) )
      ++str;
   if( *str == '\\' && str[1] == 'b' && str[2] == 'r' )
   {
      strcpy( first_arg, "\n\r" );
      if( buflen )
         *buflen = 0;
      if( len )
         *len = 0;
      str += 3;
      while( isspace( *str ) )
         ++str;
      return str;
   }
   arg = first_arg;
   while( *str && arg - first_arg < bufsize && slen < max )
   {
      if( isspace( *str ) )
      {
         ++str;
         break;
      }
      else if( *str == '@' && str[1] == '@' && str[2] != '\0' )
      {
         if( arg - first_arg >= max - 3 )
            break;
         *arg++ = *str++;
         *arg++ = *str++;
         *arg++ = *str++;
      }
      else if( *str == '\\' && str[1] == 'b' && str[2] == 'r' )
         break;
      else
      {
         *arg++ = *str++;
         ++slen;
      }
   }
   *arg = '\0';
   if( len )
      *len = slen;
   if( buflen )
      *buflen = arg - first_arg;
   while( isspace( *str ) )
      ++str;
   return str;
}

char *string_justify( char *str, int len, int width, int numwords, int *rlen )
{
   static char buf[MSL];
   char arg[MAX_INPUT_LENGTH];
   int minspaces = numwords - 1;
   int spaces_needed;
   float space_ratio, space_between;
   int i, j = 0, alen;
   char *bp = buf;

   spaces_needed = minspaces + ( width - ( len + 1 ) );
   if( spaces_needed <= minspaces || minspaces <= 0 )
   {
      sprintf( buf, "%s\n\r", str );
      return buf;
   }
   space_ratio = ( float )spaces_needed / ( float )minspaces;
   space_between = space_ratio;
   for( i = 0; i < minspaces; ++i )
   {
      str = break_arg( str, arg, sizeof( arg ), width, &alen, NULL );
      strcpy( bp, arg );
      bp += alen;
      for( ; j < ( int )( space_between + 0.5 ); ++j )
         *bp++ = ' ';
      space_between += space_ratio;
   }
   str = break_arg( str, arg, sizeof( arg ), width, &alen, NULL );
   strcpy( bp, arg );
   bp += alen;
/*  bp += sprintf(bp, "\n\r%d:%d:%d", len, width, numwords);
  bp += sprintf(bp, "\n\r%d:%d:%f", minspaces, spaces_needed, space_ratio);*/
   *bp++ = '\n';
   *bp++ = '\r';
   *bp = '\0';
   if( rlen )
      *rlen = bp - buf;
   return buf;
}

char last_color( char *str )
{
   char *end;

   for( end = str + strlen( str ) - 2; end > str; --end )
      if( *end == '@' && end[-1] == '@' )
         return end[1];
   return '\0';
}

char *string_format( char *str, int *numlines, int width, int height, bool unjust )
{
   static char ret[MSL];
   char buf[MSL];
   char arg[MAX_INPUT_LENGTH];
   int alen;
   int blen = 0;
   char *pbuf = buf, *pret = ret;
   int len;
   int currline = 0;
   int last;
   char *sp;
   char c;
   int numwords = 0;
   int jlen;

   --height;
   --width;
   *pret = '\0';
   for( sp = break_arg( str, arg, sizeof( arg ), width, &len, &alen ); *arg;
        sp = break_arg( sp, arg, sizeof( arg ), width, &len, &alen ) )
   {
      blen += alen;
      if( blen + 1 >= width || iseol( *arg ) )
      {
         *pbuf++ = '\n';
         *pbuf++ = '\r';
         *pbuf = '\0';
         c = last_color( buf );
         if( unjust || iseol( *arg ) )
         {
            strcpy( pret, buf );
            pret += pbuf - buf;
         }
         else
         {
            strcpy( pret, string_justify( buf, blen - alen, width, numwords, &jlen ) );
            pret += jlen;
         }
         pbuf = buf;
         if( ++currline > height )
            break;
         if( c )
         {
            *pbuf++ = '@';
            *pbuf++ = '@';
            *pbuf++ = c;
         }
         blen = alen;
         if( iseol( *arg ) )
            *arg = '\0';
         numwords = 0;
      }
      else if( pbuf > buf )
      {
         if( pbuf - buf > 2 && pbuf[-2] == '@' && pbuf[-3] == '@' )
         {
            if( pbuf - buf == 3 )
               last = 0;
            else
               last = -4;
         }
         else
            last = -1;
         if( last )
         {
            if( unjust && pbuf[last] == '.' )
               *pbuf++ = ' ', ++blen;
//        if (!iseol(pbuf[last]))
            *pbuf++ = ' ', ++blen;
         }
      }
      strcpy( pbuf, arg );
      pbuf += len;
      ++numwords;
   }
   if( pbuf > buf )
   {
      if( pbuf - buf > 2 && pbuf[-2] == '@' && pbuf[-3] == '@' )
      {
         if( pbuf - buf == 3 )
            last = 0;
         else
            last = -4;
      }
      else
         last = -1;
      if( last && pbuf[last] != '\n' && pbuf[last] != '\r' )
      {
         *pbuf++ = '\n';
         *pbuf++ = '\r';
         ++currline;
      }
   }
   *pbuf = '\0';
   strcpy( pret, buf );
   if( numlines )
      *numlines = currline;
   return ret;
}

char *map_format( char *str, int start, char map[MAP_Y][MSL], int *numlines, int term_width, int height, bool unjust )
{
   static char ret[MSL];
   char buf[MSL];
   char arg[MAX_INPUT_LENGTH];
   int width = ( start < MAP_Y ? term_width - 15 : term_width - 1 );
   int alen;
   int blen = 0;
   char *pbuf = buf, *pret = ret;
   int len;
   int currline = start;
   int last;
   char *sp;
   char c;
   int numwords = 0;
   int jlen;

   --height;
   *pret = '\0';
   for( sp = break_arg( str, arg, sizeof( arg ), width, &len, &alen ); *arg;
        sp = break_arg( sp, arg, sizeof( arg ), width, &len, &alen ) )
   {
      blen += alen;
      if( blen + 1 >= width || iseol( *arg ) )
      {
         *pbuf++ = '\n';
         *pbuf++ = '\r';
         *pbuf = '\0';
         c = last_color( buf );
         if( currline < MAP_Y )
            pret += sprintf( pret, "%s   ", map[currline] );
         else if( currline == MAP_Y )
            strcpy( pret, "              " ), pret += 14;
         if( unjust || iseol( *arg ) )
         {
            strcpy( pret, buf );
            pret += pbuf - buf;
         }
         else
         {
            strcpy( pret, string_justify( buf, blen - alen, width, numwords, &jlen ) );
            pret += jlen;
         }
         if( currline == MAP_Y )
            width = term_width - 1;
         pbuf = buf;
         if( ++currline > height )
            break;
         if( c )
         {
            *pbuf++ = '@';
            *pbuf++ = '@';
            *pbuf++ = c;
         }
         blen = alen;
         if( iseol( *arg ) )
            *arg = '\0';
         numwords = 0;
      }
      else if( pbuf > buf )
      {
         if( pbuf - buf > 2 && pbuf[-2] == '@' && pbuf[-3] == '@' )
         {
            if( pbuf - buf == 3 )
               last = 0;
            else
               last = -4;
         }
         else
            last = -1;
         if( last )
         {
            if( unjust && pbuf[last] == '.' )
               *pbuf++ = ' ', ++blen;
//        if (!iseol(pbuf[last]))
            *pbuf++ = ' ', ++blen;
         }
      }
      strcpy( pbuf, arg );
      pbuf += len;
      ++numwords;
   }
/*  sprintf(bug_buf, "%d:%d", width, blen);
  monitor_chan(bug_buf, MONITOR_DEBUG);*/
   if( pbuf > buf )
   {
      if( pbuf - buf > 2 && pbuf[-2] == '@' && pbuf[-3] == '@' )
      {
         if( pbuf - buf == 3 )
            last = 0;
         else
            last = -4;
      }
      else
         last = -1;
      if( last && pbuf[last] != '\n' && pbuf[last] != '\r' )
      {
         *pbuf++ = '\n';
         *pbuf++ = '\r';
         if( currline < MAP_Y )
            pret += sprintf( pret, "%s   ", map[currline] );
         else if( currline == MAP_Y || ( currline == MAP_Y + 1 && blen <= term_width - 15 ) )
            strcpy( pret, "              " ), pret += 14;
         ++currline;
      }
   }
   *pbuf = '\0';
   strcpy( pret, buf );
   if( numlines )
      *numlines = currline;
   return ret;
}

char *exit_string( CHAR_DATA * ch, ROOM_INDEX_DATA * r )
{
   int e;
   static char buf[128];

   strcpy( buf, "[" );
   for( e = 0; e < 6; e++ )
      if( r->exit[e] && r->exit[e]->to_room && !str_cmp( "", r->exit[e]->keyword ) )
      {
         if( IS_SET( r->exit[e]->exit_info, EX_CLOSED ) )
         {
            if( IS_SET( r->exit[e]->exit_info, EX_NODETECT ) )
            {
               continue;
            }
            else if( ( IS_NPC( ch ) ? 50 : ch->pcdata->learned[gsn_find_doors] ) > number_percent(  ) )
            {
               sprintf( buf + strlen( buf ), " (%s)", compass_name[e] );
            }
         }
         else
         {
            sprintf( buf + strlen( buf ), " %s", compass_name[e] );
         }
      }
   strcat( buf, " ]" );
   return buf;
}

void disp_map( char *border, char *map, CHAR_DATA * ch )
{
#ifdef ACK_43
   int cols = ( IS_NPC( ch ) ? 80 : ch->pcdata->term_columns );
   int rows = ( IS_NPC( ch ) || !IS_SET( ch->config, CONFIG_FULL_ANSI ) ? 9999 : 10 );
#else
   int cols = 80;
   int rows = 9999;
#endif
   char bufs[MAP_Y][MSL];
   char disp[MSL];
   int y, ty = MAP_Y - 1;
   char *x, *ox;

   strcpy( bufs[0], border );
   strcpy( bufs[ty], border );
   x = map;
   for( y = 1; y < ty && *x; ++y )
   {
      while( *x == '\n' || *x == '\r' )
         ++x;
      ox = x;
      while( *x != '\n' && *x != '\r' && *x != '\0' )
         ++x;
      sprintf( bufs[y], "%.*s", ( x - ox ), ox );
   }
#ifdef ACK_43
   if( !IS_NPC( ch ) && IS_SET( ch->config, CONFIG_FULL_ANSI ) )
   {
      sprintf( disp, "%s%s%i;%ir%s%i;%iH%s%s",
               CRS_SAVE_ALL,
               CRS_CMD,
               ch->pcdata->term_rows - 11, ch->pcdata->term_rows - 1, CRS_CMD, ch->pcdata->term_rows - 11, 0, CRS_CMD, "J" );
      send_to_char( disp, ch );
   }
#endif
   strcpy( disp, map_format( ch->in_room->name, 0, bufs, &y, cols, rows, TRUE ) );
   strcat( disp, map_format( exit_string( ch, ch->in_room ), y, bufs, &y, cols, rows, TRUE ) );
   strcat( disp, map_format( ch->in_room->description, y, bufs, &y, cols, rows, !IS_SET( ch->config, CONFIG_JUSTIFY ) ) );
   if( y < MAP_Y )
   {
      x = disp + strlen( disp );
      while( y < MAP_Y )
         x += sprintf( x, "%s\n\r", bufs[y] ), ++y;
   }
   send_to_char( disp, ch );
#ifdef ACK_43
   if( !IS_NPC( ch ) && IS_SET( ch->config, CONFIG_FULL_ANSI ) )
   {
      sprintf( disp, "%s%i;%ir%s%i;%iH", CRS_CMD, 0, ch->pcdata->term_rows - 12, CRS_CMD, ch->pcdata->term_rows - 13, 0 );
      send_to_char( disp, ch );
   }
#endif
   return;
}




void MapArea( ROOM_INDEX_DATA * room, CHAR_DATA * ch, int x, int y, int min, int max, int line_of_sight )
{
   ROOM_INDEX_DATA *prospect_room;
   EXIT_DATA *pexit;
   CHAR_DATA *victim;
   int door, looper;
   sh_int door_type = 0;
   if( map[x][y] <= 0 )
      return;  /* it's a door, not a room in the map */

   /*
    * marks the room as visited 
    */
   map[x][y] = room->sector_type;

/* displays seen mobs nearby as numbers */

   for( looper = 0, victim = room->first_person; victim; victim = victim->next_in_room )
      if( ( can_see( ch, victim ) ) && ( !is_same_group( ch, victim ) ) )
         looper++;
   if( looper > 0 )
      sprintf( contents[x][y].string, "%i@@N", UMIN( looper, 9 ) );
   else
      contents[x][y].string[0] = '\0';

   for( door = 0; door < MAX_MAP_DIR; door++ )
   {  /* cycles through for each exit */
      if( ( ( pexit = room->exit[door] ) != NULL ) && ( pexit->to_room != NULL ) )

      {  /* if exit there */
         if( ( x < min ) || ( y < min ) || ( x > max ) || ( y > max ) )
            return;

         prospect_room = pexit->to_room;
         if( ( prospect_room->exit[rev_dir[door]] ) && ( prospect_room->exit[rev_dir[door]]->to_room != room ) )
         {  /* if not two way */
            map[x][y] = SECT_BLOCKED;  /* one way into area OR maze */
            return;
         }  /* end two way */

/* selects door symbol */

         door_type = 0;
         if( !IS_SET( pexit->exit_info, EX_ISDOOR ) )
         {
            if( ( door == 0 ) || ( door == 2 ) )
               door_type = DOOR_NS;
            else
               door_type = DOOR_EW;
         }
         else if( IS_SET( pexit->exit_info, EX_LOCKED ) )
         {
            door_type = DOOR_LOCKED;
         }
         else if( IS_SET( pexit->exit_info, EX_CLOSED ) )
         {
            door_type = DOOR_CLOSED;
         }
         else
            door_type = DOOR_OPEN;
         if( ( !IS_NPC( ch ) )
             && ( !str_cmp( pexit->keyword, "" ) )
             && ( ( door_type <= DOOR_OPEN )
                  || ( !IS_SET( pexit->exit_info, EX_ISDOOR ) )
                  || ( ( IS_SET( pexit->exit_info, EX_CLOSED ) )
                       && ( !IS_SET( pexit->exit_info, EX_NODETECT ) )
                       && ( ch->pcdata->learned[gsn_find_doors] > number_percent(  ) )
                       && ( !str_cmp( pexit->keyword, "" ) ) ) ) )
         {
            map[x + door_marks[door][0]][y + door_marks[door][1]] = door_type;
            if( ( door_type < DOOR_CLOSED )
                && ( ( line_of_sight == LOS_INITIAL )
                     || ( door == line_of_sight ) ) && ( map[x + offsets[door][0]][y + offsets[door][1]] == SECT_UNSEEN ) )
            {
               MapArea( pexit->to_room, ch,
                        x + offsets[door][0], y + offsets[door][1], min, max,
                        ( line_of_sight == LOS_INITIAL ) ? door : line_of_sight );
            }
         }
      }
/* end if exit there */
   }
   return;
}

void ShowRoom( CHAR_DATA * ch, int min, int max, int size, int center )
{
   void disp_map( char *border, char *map, CHAR_DATA * ch );
   int x, y, looper;
   char outbuf[MSL];
   char catbuf[MSL];
   char borderbuf[MSL];
   char colorbuf[MSL];
   char displaybuf[MSL];
   outbuf[0] = '\0';
   sprintf( outbuf, "%s", "\n\r" );
   sprintf( borderbuf, "%s", "@@y+@@W" );
   for( looper = 0; looper <= size + 1; looper++ )
   {
      sprintf( catbuf, "%s", "-" );
      safe_strcat( MSL, borderbuf, catbuf );
   }
   safe_strcat( MSL, borderbuf, "@@y+@@N" );
   for( x = min; x <= max; ++x )
   {  /* every row */

      safe_strcat( MSL, outbuf, "@@W| " );
      for( y = min; y <= max; ++y )
      {  /* every column */
         if( ( y == min ) || ( map[x][y - 1] != map[x][y] ) )
         {
            sprintf( colorbuf, "%s%s",
                     ( ( map[x][y] <= 0 ) ?
                       get_door_color( map[x][y] ) :
                       get_sector_color( map[x][y] ) ),
                     ( ( contents[x][y].string[0] == '\0' ) ? "" : get_invert_color( map[x][y] ) ) );
            sprintf( displaybuf, "%s",
                     ( ( map[x][y] <= 0 ) ?
                       get_door_display( map[x][y] ) :
                       ( ( contents[x][y].string[0] == '\0' ) ?
                         get_sector_display( map[x][y] ) : contents[x][y].string ) ) );
            sprintf( catbuf, "%s%s", colorbuf, displaybuf );
            safe_strcat( MSL, outbuf, catbuf );

         }
         else
         {
            sprintf( catbuf, "%s", ( map[x][y] <= 0 ) ? get_door_display( map[x][y] ) : get_sector_display( map[x][y] ) );
            safe_strcat( MSL, outbuf, catbuf );
         }

      }
      safe_strcat( MSL, outbuf, " @@W|@@N\n\r" );
   }

   disp_map( borderbuf, outbuf, ch );

/* NOTE: with your imp, probably put the three together into one string? */

   return;
}




/* mlk :: shows a map, specified by size */


void ShowMap( CHAR_DATA * ch, int min, int max, int size, int center )
{
   int x, y, looper;
   char outbuf[MSL];
   char catbuf[MSL];
   char borderbuf[MSL];
   char colorbuf[MSL];
   char displaybuf[MSL];
   outbuf[0] = '\0';
   sprintf( outbuf, "%s", "\n\r" );
   sprintf( borderbuf, "%s", "@@y+@@W" );
   for( looper = 0; looper <= size + 1; looper++ )
   {
      sprintf( catbuf, "%s", "-" );
      safe_strcat( MSL, borderbuf, catbuf );
   }
   safe_strcat( MSL, borderbuf, "@@y+@@N" );
   for( x = min; x <= max; ++x )
   {  /* every row */

      safe_strcat( MSL, outbuf, "@@W| " );
      for( y = min; y <= max; ++y )
      {  /* every column */
         if( ( y == min ) || ( map[x][y - 1] != map[x][y] ) )
         {
            sprintf( colorbuf, "%s%s",
                     ( ( map[x][y] <= 0 ) ?
                       get_door_color( map[x][y] ) :
                       get_sector_color( map[x][y] ) ),
                     ( ( contents[x][y].string[0] == '\0' ) ? "" : get_invert_color( map[x][y] ) ) );
            sprintf( displaybuf, "%s",
                     ( ( map[x][y] <= 0 ) ?
                       get_door_display( map[x][y] ) :
                       ( ( contents[x][y].string[0] == '\0' ) ?
                         get_sector_display( map[x][y] ) : contents[x][y].string ) ) );
            sprintf( catbuf, "%s%s", colorbuf, displaybuf );
            safe_strcat( MSL, outbuf, catbuf );

         }
         else
         {
            sprintf( catbuf, "%s", ( map[x][y] <= 0 ) ? get_door_display( map[x][y] ) : get_sector_display( map[x][y] ) );
            safe_strcat( MSL, outbuf, catbuf );
         }

      }
      safe_strcat( MSL, outbuf, " @@W|@@N\n\r" );
   }
   send_to_char( "\n\r", ch );
   /*
    * this is the top line of the map itself, currently not part of the mapstring 
    */
   send_to_char( borderbuf, ch );
   /*
    * this is the contents of the map 
    */
   send_to_char( outbuf, ch );
   /*
    * this is the bottom line of the map 
    */
   send_to_char( borderbuf, ch );
   send_to_char( "\n\r", ch );
   send_to_char( "Also try map legend.\n\r", ch );

   return;
}










void do_mapper( CHAR_DATA * ch, char *argument )
{
   int size, center, x, y, min, max, looper;
   char arg1[MSL];
   char catbuf[MSL];
   char outbuf[MSL];
   one_argument( argument, arg1 );
   if( is_name( arg1, "legend key help" ) )
   {
      sprintf( outbuf, "@@WMap Legend:@@N\n\r" );
      for( looper = 0; looper < SECT_TOP - 1; looper++ )
      {
         sprintf( catbuf, "%s%s : @@N%s\n\r",
                  map_info[looper].display_color, map_info[looper].display_code, map_info[looper].desc );
         safe_strcat( MSL, outbuf, catbuf );
      }
      for( looper = 0; looper < 5; looper++ )
      {
         sprintf( catbuf, "%s%s : @@N%s\n\r",
                  door_info[looper].display_color, door_info[looper].display_code, door_info[looper].desc );
         safe_strcat( MSL, outbuf, catbuf );
      }
      send_to_char( outbuf, ch );
      return;
   }
   size = ( is_number( arg1 ) ) ? atoi( arg1 ) : 11;

   if( size != 7 )
   {
      size = IS_IMMORTAL( ch ) ? size :
         get_curr_int( ch ) / 2 + ( ( !IS_NPC( ch ) ) ? ch->pcdata->learned[gsn_scout] / 25 : 0 );
      if( size % 2 == 0 )
         size += 1;
      size = URANGE( 9, size, MAX_MAP );
   }
   size = URANGE( 3, size, MAX_MAP );

   center = MAX_MAP / 2;

   min = MAX_MAP / 2 - size / 2;
   max = MAX_MAP / 2 + size / 2;

   for( x = 0; x < MAX_MAP; ++x )
      for( y = 0; y < MAX_MAP; ++y )
      {
         map[x][y] = SECT_UNSEEN;
         contents[x][y].string[0] = '\0';
      }

/* starts the mapping with the center room */
   MapArea( ch->in_room, ch, center, center, min - 1, max, LOS_INITIAL );

/* marks the center, where ch is */
   sprintf( contents[center][center].string, "%s", "@@f*@@N" );
   if( size == 7 )
      ShowRoom( ch, min, max, size, center );
   else
      ShowMap( ch, min, max, size, center );
   return;

}