diff -ruNbB LOP - Copy/src/Makefile LOP/src/Makefile --- LOP - Copy/src/Makefile 2012-01-15 14:39:44.673400000 -0500 +++ LOP/src/Makefile 2012-01-27 18:51:24.430000000 -0500 @@ -46,7 +46,7 @@ handler.c hashstr.c helps.c highscore.c hint.c host.c hostlist.c hotboot.c \ interp.c \ lockers.c \ - magic.c makeobjs.c mapout.c mccp.c misc.c mpxset.c mssp.c mud_comm.c mud_prog.c mwresets.c \ + magic.c makeobjs.c mapout.c mapper.c mccp.c misc.c mpxset.c mssp.c mud_comm.c mud_prog.c mwresets.c \ news.c \ player.c polymorph.c \ quest.c \ diff -ruNbB LOP - Copy/src/act_info.c LOP/src/act_info.c --- LOP - COPY/src/act_info.c 2012-01-15 21:29:16.705000000 -0500 +++ LOP/src/act_info.c 2012-01-27 18:52:31.276000000 -0500 @@ -26,6 +26,8 @@ bool EXA_prog_trigger = true; +void draw_room_map( CHAR_DATA * ch, const char *desc ); + int get_ip_logins( void ); char *format_obj_to_char( OBJ_DATA *obj, CHAR_DATA *ch, bool fShort ) @@ -1785,7 +1787,7 @@ } showdescription[desccount] = '\0'; - send_to_char( showdescription, ch ); + draw_room_map( ch, showdescription ); } /* Used to send the room description to the character */ diff -ruNbB LOP - COPY/src/h/mapper.h LOP/src/h/mapper.h --- LOP - COPY/src/h/mapper.h 1969-12-31 19:00:00.000000000 -0500 +++ LOP/src/h/mapper.h 2012-01-27 18:50:37.832800000 -0500 @@ -0,0 +1,39 @@ +/**************************************************************************** + * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * + * -----------------------------------------------------------| (0...0) * + * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * + * -----------------------------------------------------------| {o o} * + * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * + * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* + * Tricops and Fireblade | * + * ------------------------------------------------------------------------ * + * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * + * Chastain, Michael Quan, and Mitchell Tse. * + * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * + * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * + * ------------------------------------------------------------------------ * + * Room Mapper Module * + ****************************************************************************/ + +/* Defines for ASCII Automapper */ +#define MAPX 10 +#define MAPY 8 + +/* You can change MAXDEPTH to 1 if the diagonal directions are confusing */ +#define MAXDEPTH 2 + +#define BOUNDARY(x, y) ( ( (x) < 0) || ((y) < 0 ) || ( (x) > MAPX ) || ( (y) > MAPY ) ) + +/* Structure for the map itself */ +typedef struct map_type MAP_TYPE; +struct map_type +{ +// EXT_BV info; + char tegn; /* Character to print at this map coord */ + int vnum; /* Room this coord represents */ + int depth; /* Recursive depth this coord was found at */ + int sector; /* Sector type of the map space */ + bool can_see; +}; + +void draw_room_map( CHAR_DATA * ch, const char *desc ); diff -ruNbB LOP - COPY/src/mapper.c LOP/src/mapper.c --- LOP - COPY/src/mapper.c 1969-12-31 19:00:00.000000000 -0500 +++ LOP/src/mapper.c 2012-01-27 19:35:31.344400000 -0500 @@ -0,0 +1,729 @@ +/**************************************************************************** + * [S]imulated [M]edieval [A]dventure multi[U]ser [G]ame | \\._.// * + * -----------------------------------------------------------| (0...0) * + * SMAUG 1.4 (C) 1994, 1995, 1996, 1998 by Derek Snider | ).:.( * + * -----------------------------------------------------------| {o o} * + * SMAUG code team: Thoric, Altrag, Blodkai, Narn, Haus, | / ' ' \ * + * Scryn, Rennard, Swordbearer, Gorog, Grishnakh, Nivek, |~'~.VxvxV.~'~* + * Tricops and Fireblade | * + * ------------------------------------------------------------------------ * + * Merc 2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael * + * Chastain, Michael Quan, and Mitchell Tse. * + * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * + * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * + * ------------------------------------------------------------------------ * + * Room Mapper Module * + ****************************************************************************/ + +/************************************************************************** +* 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. * +* * +* 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. * +* * +* Dystopia Mud improvements copyright (C) 2000, 2001 by Brian Graversen * +* * +* 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. * +*************************************************************************** +* Converted for AFKMud 1.64 by Zarius (jeff@mindcloud.com) * +* Downloaded from http://www.mindcloud.com * +* If you like the snippet let me know * +***************************************************************************/ +/************************************************************************** + * Version History * + ************************************************************************** + * (v1.0) - Converted Automapper to AFKMud 1.64 and added additional * + * directions and removed room desc code into a sep func * + **************************************************************************/ + +/* + TO DO + ----- + + 1. Add a way of displaying up and down directions effectively + */ +#include +#include +#include "h/mud.h" +#include "h/mapper.h" + +int colorcode( const char *src, char *dst, DESCRIPTOR_DATA *d, int dstlen, int *vislen ); + +bool check_blind( CHAR_DATA * ch ); + +/* The map itself */ +MAP_TYPE dmap[MAPX + 1][MAPY + 1]; + +/* Take care of some repetitive code for later */ +void get_exit_dir( int dir, int *x, int *y, int xorig, int yorig ) +{ + /* + * Get the next coord based on direction + */ + switch ( dir ) + { + case DIR_NORTH: /* North */ + *x = xorig; + *y = yorig - 1; + break; + + case DIR_EAST: /* East */ + *x = xorig + 1; + *y = yorig; + break; + + case DIR_SOUTH: /* South */ + *x = xorig; + *y = yorig + 1; + break; + + case DIR_WEST: /* West */ + *x = xorig - 1; + *y = yorig; + break; + + case DIR_UP: /* UP */ + break; + + case DIR_DOWN: /* DOWN */ + break; + + case DIR_NORTHEAST: /* NE */ + *x = xorig + 1; + *y = yorig - 1; + break; + + case DIR_NORTHWEST: /* NW */ + *x = xorig - 1; + *y = yorig - 1; + break; + + case DIR_SOUTHEAST: /* SE */ + *x = xorig + 1; + *y = yorig + 1; + break; + + case DIR_SOUTHWEST: /* SW */ + *x = xorig - 1; + *y = yorig + 1; + break; + + default: + *x = -1; + *y = -1; + break; + } +} + +char *get_exits( CHAR_DATA * ch ) +{ + static char buf[MSL]; + EXIT_DATA *pexit; + bool found = false; + + buf[0] = '\0'; + + if( !check_blind( ch ) ) + return buf; + + set_char_color( AT_EXITS, ch ); + + mudstrlcpy( buf, "[Exits:", MSL ); + + for( pexit = ch->in_room->first_exit; pexit; pexit = pexit->next ) + { + if( is_immortal( ch ) ) + /* + * Immortals see all exits, even secret ones + */ + { + if( pexit->to_room ) + { + found = true; + mudstrlcat( buf, " ", MSL ); + + mudstrlcat( buf, capitalize( dir_name[pexit->vdir] ), MSL ); + + /* + * New code added to display closed, or otherwise invisible exits to immortals + * Installed by Samson 1-25-98 + */ + if( xIS_SET( pexit->exit_info, EX_CLOSED ) ) + mudstrlcat( buf, "->(Closed)", MSL ); + if( xIS_SET( pexit->exit_info, EX_DIG ) ) + mudstrlcat( buf, "->(Dig)", MSL ); + if( xIS_SET( pexit->exit_info, EX_WINDOW ) ) + mudstrlcat( buf, "->(Window)", MSL ); + if( xIS_SET( pexit->exit_info, EX_HIDDEN ) ) + mudstrlcat( buf, "->(Hidden)", MSL ); + if( xIS_SET( pexit->to_room->room_flags, ROOM_DEATH ) ) + mudstrlcat( buf, "->(Deathtrap)", MSL ); + } + } + else + { + if( pexit->to_room + && !xIS_SET( pexit->exit_info, EX_SECRET ) + && ( !xIS_SET( pexit->exit_info, EX_WINDOW ) || xIS_SET( pexit->exit_info, EX_ISDOOR ) ) + && !xIS_SET( pexit->exit_info, EX_HIDDEN ) ) + { + found = true; + mudstrlcat( buf, " ", MSL ); + + mudstrlcat( buf, capitalize( dir_name[pexit->vdir] ), MSL ); + + if( xIS_SET( pexit->exit_info, EX_CLOSED ) ) + mudstrlcat( buf, "->(Closed)", MSL ); + if( IS_AFFECTED( ch, AFF_DETECTTRAPS ) && xIS_SET( pexit->to_room->room_flags, ROOM_DEATH ) ) + mudstrlcat( buf, "->(Deathtrap)", MSL ); + } + } + } + + if( !found ) + mudstrlcat( buf, " none]", MSL ); + else + mudstrlcat( buf, "]", MSL ); + mudstrlcat( buf, "\r\n", MSL ); + return buf; +} + +/* Clear one map coord */ +void clear_coord( int x, int y ) +{ + dmap[x][y].tegn = ' '; + dmap[x][y].vnum = 0; + dmap[x][y].depth = 0; + dmap[x][y].sector = -1; +// xCLEAR_BITS( dmap[x][y].info ); + dmap[x][y].can_see = true; +} + +/* Clear all exits for one room */ +void clear_room( int x, int y ) +{ + int dir, exitx, exity; + + /* + * Cycle through the four directions + */ + for( dir = 0; dir < 4; ++dir ) + { + /* + * Find next coord in this direction + */ + get_exit_dir( dir, &exitx, &exity, x, y ); + + /* + * If coord is valid, clear it + */ + if( !BOUNDARY( exitx, exity ) ) + clear_coord( exitx, exity ); + } +} + +/* This function is recursive, ie it calls itself */ +void map_exits( CHAR_DATA * ch, ROOM_INDEX_DATA * pRoom, int x, int y, int depth ) +{ + static char map_chars[11] = "|-|-UD/\\\\/"; + int door; + int exitx = 0, exity = 0; + int roomx = 0, roomy = 0; + EXIT_DATA *pExit; + + /* + * Setup this coord as a room - Change any symbols that can't be displayed here + */ + dmap[x][y].sector = pRoom->sector_type; + switch ( pRoom->sector_type ) + { + case SECT_INSIDE: + dmap[x][y].tegn = 'O'; + dmap[x][y].sector = -1; + break; + + case SECT_CITY: + dmap[x][y].tegn = ':'; + break; + + case SECT_FIELD: + case SECT_FOREST: + case SECT_HILLS: + dmap[x][y].tegn = '*'; + break; + + case SECT_MOUNTAIN: + dmap[x][y].tegn = '@'; + break; + + case SECT_WATER_SWIM: + case SECT_WATER_NOSWIM: + dmap[x][y].tegn = '='; + break; + + case SECT_AIR: + dmap[x][y].tegn = '~'; + break; + + case SECT_DESERT: + dmap[x][y].tegn = '+'; + break; + + default: + dmap[x][y].tegn = 'O'; + dmap[x][y].sector = -1; + bug( "%s: Bad sector type (%d) in room %d.", __FUNCTION__, pRoom->sector_type, pRoom->vnum ); + break; + } + + dmap[x][y].vnum = pRoom->vnum; + dmap[x][y].depth = depth; +// dmap[x][y].info = pRoom->room_flags; + dmap[x][y].can_see = room_is_dark( pRoom ); + + /* + * Limit recursion + */ + if( depth > MAXDEPTH ) + return; + + /* + * This room is done, deal with it's exits + */ + for( door = 0; door < 10; ++door ) + { + /* + * Skip if there is no exit in this direction + */ + if( !( pExit = get_exit( pRoom, door ) ) ) + continue; + + /* + * Skip up and down until I can figure out a good way to display it + */ + if( door == 4 || door == 5 ) + continue; + + /* + * Get the coords for the next exit and room in this direction + */ + get_exit_dir( door, &exitx, &exity, x, y ); + get_exit_dir( door, &roomx, &roomy, exitx, exity ); + + /* + * Skip if coords fall outside map + */ + if( BOUNDARY( exitx, exity ) || BOUNDARY( roomx, roomy ) ) + continue; + + /* + * Skip if there is no room beyond this exit + */ + if( !pExit->to_room ) + continue; + + /* + * Ensure there are no clashes with previously defined rooms + */ + if( ( dmap[roomx][roomy].vnum != 0 ) && ( dmap[roomx][roomy].vnum != pExit->to_room->vnum ) ) + { + /* + * Use the new room if the depth is higher + */ + if( dmap[roomx][roomy].depth <= depth ) + continue; + + /* + * It is so clear the old room + */ + clear_room( roomx, roomy ); + } + + /* + * No exits at MAXDEPTH + */ + if( depth == MAXDEPTH ) + continue; + + /* + * No need for exits that are already mapped + */ + if( dmap[exitx][exity].depth > 0 ) + continue; + + /* + * Fill in exit + */ + dmap[exitx][exity].depth = depth; + dmap[exitx][exity].vnum = pExit->to_room->vnum; +// dmap[exitx][exity].info = pExit->exit_info; + dmap[exitx][exity].tegn = map_chars[door]; + dmap[exitx][exity].sector = -1; + + /* + * More to do? If so we recurse + */ + if( depth < MAXDEPTH && ( ( dmap[roomx][roomy].vnum == pExit->to_room->vnum ) || ( dmap[roomx][roomy].vnum == 0 ) ) ) + { + /* + * Depth increases by one each time + */ + map_exits( ch, pExit->to_room, roomx, roomy, depth + 1 ); + } + } +} + +/* Reformat room descriptions to exclude undesirable characters */ +void reformat_desc( char *desc ) +{ + /* + * Index variables to keep track of array/pointer elements + */ + unsigned int i = 0; + int j = 0; + char buf[MSL], *p; + + buf[0] = '\0'; + + if( !desc ) + return; + + /* + * Replace all "\n" and "\r" with spaces + */ + for( i = 0; i <= strlen( desc ); ++i ) + { + if( ( desc[i] == '\r' ) || ( desc[i] == '\n' ) ) + desc[i] = ' '; + } + + /* + * Remove multiple spaces + */ + for( p = desc; *p != '\0'; ++p ) + { + buf[j] = *p; + ++j; + + /* + * Two or more consecutive spaces? + */ + if( ( *p == ' ' ) && ( *( p + 1 ) == ' ' ) ) + { + do + { + ++p; + } + while( *( p + 1 ) == ' ' ); + } + } + + buf[j] = '\0'; + + /* + * Copy to desc + */ + mudstrlcpy( desc, buf, MSL ); +} + +int get_line( char *desc, size_t max_len ) +{ + size_t i, j = 0; + + /* + * Return if it's short enough for one line + */ + if( strlen( desc ) <= max_len ) + return 0; + + /* + * Calculate end point in string without color + */ + for( i = 0; i <= strlen( desc ); ++i ) + { + char dst[20]; + int vislen; + + switch ( desc[i] ) + { + case '&': /* NORMAL, Foreground colour */ + case '^': /* BACKGROUND colour */ + case '}': /* BLINK Foreground colour */ + *dst = '\0'; + vislen = 0; + i += colorcode( &desc[i], dst, NULL, 20, &vislen ); /* Skip input token */ + j += vislen; /* Count output token length */ + break; /* this was missing - if you have issues, remove it */ + + default: /* No conversion, just count */ + ++j; + break; + } + + if( j > max_len ) + break; + } + + + + /* + * End point is now in i, find the nearest space + */ + for( j = i; j > 0; --j ) + { + if( desc[j] == ' ' ) + break; + } + + /* + * There could be a problem if there are no spaces on the line + */ + return j + 1; +} + +/* Display the map to the player */ +void show_map( CHAR_DATA * ch, char *text ) +{ + char buf[MSL * 2]; + int x, y, pos; + char *p; + bool alldesc = false; /* Has desc been fully displayed? */ + + if( !text ) + alldesc = true; + + pos = 0; + p = text; + buf[0] = '\0'; + + /* + * Show exits + */ + if( xIS_SET( ch->act, PLR_AUTOEXIT ) ) + snprintf( buf, MSL * 2, "%s%s", color_str( AT_EXITS, ch ), get_exits( ch ) ); + else + mudstrlcpy( buf, "", MSL * 2 ); + + /* + * Top of map frame + */ + mudstrlcat( buf, "&z+-----------+&w ", MSL * 2 ); + if( !alldesc ) + { + pos = get_line( p, 63 ); + if( pos > 0 ) + { + mudstrlcat( buf, color_str( AT_RMDESC, ch ), MSL * 2 ); + strncat( buf, p, pos ); + p += pos; + } + else + { + mudstrlcat( buf, color_str( AT_RMDESC, ch ), MSL * 2 ); + mudstrlcat( buf, p, MSL * 2 ); + alldesc = true; + } + } + mudstrlcat( buf, "\r\n", MSL * 2 ); + + /* + * Write out the main map area with text + */ + for( y = 0; y <= MAPY; ++y ) + { + mudstrlcat( buf, "&z|&D", MSL * 2 ); + + for( x = 0; x <= MAPX; ++x ) + { + switch ( dmap[x][y].tegn ) + { + case '-': + case '|': + case '\\': + case '/': + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&O%c&d", dmap[x][y].tegn ); + break; + + case '@': // Character is standing here + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&R%c&d", dmap[x][y].tegn ); + break; + + case 'O': // Indoors + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&w%c&d", dmap[x][y].tegn ); + break; + + case '=': + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&B%c&d", dmap[x][y].tegn ); + break; + + case '~': + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&C%c&d", dmap[x][y].tegn ); + break; + + case '+': + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&Y%c&d", dmap[x][y].tegn ); + break; + + case '*': + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&g%c&d", dmap[x][y].tegn ); + break; + + case 'X': + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&R%c&d", dmap[x][y].tegn ); + break; + + case ':': + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "&Y%c&d", dmap[x][y].tegn ); + break; + + default: // Empty space + snprintf( buf + strlen( buf ), ( MSL * 2 ) - strlen( buf ), "%c", dmap[x][y].tegn ); + break; + } + } + mudstrlcat( buf, "&z|&D ", MSL * 2 ); + + /* + * Add the text, if necessary + */ + if( !alldesc ) + { + pos = get_line( p, 63 ); + char col[10]; + + mudstrlcpy( col, color_str( AT_RMDESC, ch ), 10 ); + + if( pos > 0 ) + { + mudstrlcat( buf, col, MSL * 2 ); + strncat( buf, p, pos ); + p += pos; + } + else + { + mudstrlcat( buf, col, MSL * 2 ); + mudstrlcat( buf, p, MSL * 2 ); + alldesc = true; + } + } + mudstrlcat( buf, "\r\n", MSL * 2 ); + } + + /* + * Finish off map area + */ + mudstrlcat( buf, "&z+-----------+&D ", MSL * 2 ); + if( !alldesc ) + { + char col[10]; + pos = get_line( p, 63 ); + + mudstrlcpy( col, color_str( AT_RMDESC, ch ), 10 ); + + if( pos > 0 ) + { + mudstrlcat( buf, col, MSL * 2 ); + strncat( buf, p, pos ); + p += pos; + mudstrlcat( buf, "\r\n", MSL * 2 ); + } + else + { + mudstrlcat( buf, col, MSL * 2 ); + mudstrlcat( buf, p, MSL * 2 ); + alldesc = true; + } + } + + /* + * Deal with any leftover text + */ + if( !alldesc ) + { + char col[10]; + + do + { + /* + * Note the number - no map to detract from width + */ + pos = get_line( p, 78 ); + + mudstrlcpy( col, color_str( AT_RMDESC, ch ), 10 ); + + if( pos > 0 ) + { + mudstrlcat( buf, col, MSL * 2 ); + strncat( buf, p, pos ); + p += pos; + mudstrlcat( buf, "\r\n", MSL * 2 ); + } + else + { + mudstrlcat( buf, col, MSL * 2 ); + mudstrlcat( buf, p, MSL * 2 ); + alldesc = true; + } + } + while( !alldesc ); + } + mudstrlcat( buf, "&D\r\n", MSL * 2 ); + send_to_char( buf, ch ); +} + +/* Clear, generate and display the map */ +void draw_room_map( CHAR_DATA * ch, const char *desc ) +{ + int x, y; + static char buf[MSL]; + + mudstrlcpy( buf, desc, MSL ); + /* + * Remove undesirable characters + */ + reformat_desc( buf ); + + /* + * Clear map + */ + for( y = 0; y <= MAPY; ++y ) + { + for( x = 0; x <= MAPX; ++x ) + { + clear_coord( x, y ); + } + } + + /* + * Start with players pos at centre of map + */ + x = MAPX / 2; + y = MAPY / 2; + + dmap[x][y].vnum = ch->in_room->vnum; + dmap[x][y].depth = 0; + + /* + * Generate the map + */ + map_exits( ch, ch->in_room, x, y, 0 ); + + /* + * Current position should be a "X" + */ + dmap[x][y].tegn = '@'; + dmap[x][y].sector = -1; + + /* + * Send the map + */ + show_map( ch, buf ); +}