I've fixed up some of the things from the ascii map on circlemud.org. Here's how to add the new one: -Rikishi 1. Open utils.h, somewhere in the file add this: #define MAPS(a, b, c) ((b) < (a) ? (a) : ((b) > (c) ? (c) : (b))) 2. close utils.h 3. Open act.informative.c, and: find send_to_char(ch, "%s", world[target_room].description); under that add: do_map(ch, " "); 4. now open Makefile. Then add the map.o, and map.c in the right spots. 5. now in interpreter.c define do_map as a command 6. open map.c, now that made a new file, now add this: #include "conf.h" #include "sysdep.h" #include "structs.h" #include "utils.h" #include "comm.h" #include "interpreter.h" #include "handler.h" #include "db.h" #include "spells.h" #include "house.h" #include "constants.h" #include "dg_scripts.h" #define MAX_MAP 72 #define MAX_MAP_DIR 4 #define SECT_MAX 22 extern struct room_data *world; int add_to_save_list(zone_vnum zone, int type); int can_edit_zone(struct char_data *ch, int number); int map[MAX_MAP][MAX_MAP]; int offsets[4][2] ={ {-1, 0},{ 0, 1},{ 1, 0},{ 0, -1} }; /* Heavily modified - Edward */ void MapArea(room_rnum room, struct char_data *ch, int x, int y, int min, int max) { room_rnum prospect_room; struct room_direction_data *pexit; int door; /* marks the room as visited */ map[x][y] = world[room].sector_type; /* Otherwise we get a nasty crash */ /* if (!IS_SET(world[ch->in_room].room_flags, ROOM_WILDERNESS)) return;*/ for ( door = 0; door < MAX_MAP_DIR; door++ ) { if ( (pexit = world[room].dir_option[door]) > 0 && (pexit->to_room > 0 ) && (!IS_SET(pexit->exit_info, EX_CLOSED))) { if ( (x < min) || ( y < min) || ( x > max ) || ( y >max) ) return; prospect_room = pexit->to_room; /* one way into area OR maze */ /* if not two way */ if ( world[prospect_room].dir_option[rev_dir[door]] && world[prospect_room].dir_option[rev_dir[door]]->to_room != room) { map[x][y] = SECT_MAX + 1; return; } /* end two way */ /* players cant see past these */ if ( (world[prospect_room].sector_type == SECT_CITY) ||(world[prospect_room].sector_type == SECT_HILLS) ||(world[prospect_room].sector_type == SECT_INSIDE)) { map[x+offsets[door][0]][y+offsets[door][1]] = world[prospect_room].sector_type; /* ^--two way into area */ } if ( map[x+offsets[door][0]][y+offsets[door][1]] == SECT_MAX ) { MapArea(pexit->to_room,ch,x + offsets[door][0], y + offsets[door][1], min, max); } } /* end if exit there */ } return; } /* mlk :: shows a map, specified by size */ void ShowMap( struct char_data* ch, int min, int max) { int x, y; /* every row */ for (x = min; x < max; ++x) { /* every column */ for (y = min; y < max; ++y) { if ( (y==min) || (map[x][y-1]!=map[x][y]) ) { switch(map[x][y]) { case SECT_MAX: send_to_char(ch," "); break; case SECT_FOREST: send_to_char(ch,"@g@"); break; case SECT_FIELD: send_to_char(ch,"@G\""); break; case SECT_HILLS: send_to_char(ch,"@G^"); break; case SECT_MOUNTAIN: send_to_char(ch,"@y^"); break; case SECT_WATER_SWIM: send_to_char(ch,"@B:"); break; case SECT_WATER_NOSWIM:send_to_char(ch,"@b:"); break; case SECT_INSIDE: send_to_char(ch,"@W@"); break; case SECT_CITY: send_to_char(ch,"@W#"); break; case (SECT_MAX+1): send_to_char(ch,"@D?"); break; default: send_to_char(ch,"@R*"); break; } } else { switch(map[x][y]) { case SECT_MAX: send_to_char(ch," "); break; case SECT_FOREST: send_to_char(ch,"@"); break; case SECT_FIELD: send_to_char(ch,"\""); break; case SECT_HILLS: send_to_char(ch,"^"); break; case SECT_MOUNTAIN: send_to_char(ch,"^"); break; case SECT_WATER_SWIM:send_to_char(ch,":"); break; case SECT_WATER_NOSWIM:send_to_char(ch,":"); break; case SECT_INSIDE: send_to_char(ch,"@"); break; case SECT_CITY: send_to_char(ch,"#"); break; case (SECT_MAX+1): send_to_char(ch,"?"); break; default: send_to_char(ch,"*"); } } } send_to_char(ch,"\n\r"); } return; } /* This is for simplicities sake, if the room's name if ** like An unfinished room, it will replace it with a fake ** room name here - Edward */ void get_room_name(struct char_data *ch, int argument) { char buf[500]; switch(argument) { case SECT_MAX: sprintf(buf,"&n &cThe Wilderness&n");break; case SECT_FOREST: sprintf(buf,"&n &cWithin a Forest&n");break; case SECT_FIELD: sprintf(buf,"&n &cOn an Open Field&n");break; case SECT_HILLS: sprintf(buf,"&n &cOn a Hill&n");break; case SECT_MOUNTAIN: sprintf(buf,"&n &cClimbing a Mountain&n");break; case SECT_WATER_SWIM: sprintf(buf,"&n &cIn Shallow Water&n");break; case SECT_WATER_NOSWIM: sprintf(buf,"&n &cAdrift In Deep Water&n");break; case SECT_INSIDE: sprintf(buf,"&n &cThe Wilderness&n");break; case SECT_CITY: sprintf(buf,"&n &cWithin a City&n");break; case (SECT_MAX+1): sprintf(buf,"&n &cThe Wilderness&n");break; default: sprintf(buf,"&n &cThe Wilderness&n");break; } send_to_char(ch, buf); } /* will put a small map with current room desc and title */ /* this is the main function to show the map, its do_map with " " */ /* Heavily modified - Edward */ void ShowRoom( struct char_data *ch, int min, int max) { int x, y; char buf[500]; char desc[500]; strcpy(desc,world[ch->in_room].description); /* mlk :: rounds edges */ map[min][min]=SECT_MAX;map[max-1][max-1]=SECT_MAX; map[min][max-1]=SECT_MAX;map[max-1][min]=SECT_MAX; /* every row */ for (x = min; x < max; ++x) { /* every column */ for (y = min; y < max; ++y) { if ( (y==min) || (map[x][y-1]!=map[x][y]) ) switch(map[x][y]) { case SECT_MAX: send_to_char(ch," "); break; case SECT_FOREST: send_to_char(ch,"@g@"); break; case SECT_FIELD: send_to_char(ch,"@G\""); break; case SECT_HILLS: send_to_char(ch,"@G^"); break; case SECT_MOUNTAIN: send_to_char(ch,"@y^"); break; case SECT_WATER_SWIM: send_to_char(ch,"@B:"); break; case SECT_WATER_NOSWIM: send_to_char(ch,"@b:"); break; case SECT_INSIDE: send_to_char(ch,"@W@"); break; case SECT_CITY: send_to_char(ch,"@W#"); break; case (SECT_MAX+1): send_to_char(ch,"@D?"); break; default: send_to_char(ch,"@R*"); break; } else switch(map[x][y]) { case SECT_MAX: send_to_char(ch," "); break; case SECT_FOREST:send_to_char(ch,"@"); break; case SECT_FIELD: send_to_char(ch,"\""); break; case SECT_HILLS: send_to_char(ch,"^"); break; case SECT_MOUNTAIN: send_to_char(ch,"^"); break; case SECT_WATER_SWIM: send_to_char(ch,":"); break; case SECT_WATER_NOSWIM: send_to_char(ch,":"); break; case SECT_INSIDE: send_to_char(ch,"@"); break; case SECT_CITY: send_to_char(ch,"#"); break; case (SECT_MAX+1): send_to_char(ch,"?"); break; default: send_to_char(ch,"*"); break; } } if (x == min) { if (!strcmp(world[ch->in_room].name, "The Wilderness") || !strcmp(world[ch->in_room].name, "An unfinished room")) get_room_name(ch, world[ch->in_room].sector_type); else { sprintf(buf," "); send_to_char(ch, buf); } if (GET_LEVEL(ch) >= LVL_IMMORT) { sprintf(buf," @c[@RRoom @Y%d@c]@n", world[ch->in_room].number); send_to_char(ch, buf); } } /* I removed the room descriptions from the ascii map, the map is descriptive enough ** I think - Edward. Just remove the comments if you want them back. else { start = str_pos; for (desc_pos = desc_pos ; desc[desc_pos]!='\0' ; desc_pos++) { if (desc[desc_pos]=='\n') { line[str_pos-start]='\0'; str_pos += 3; desc_pos += 2; break; } else if (desc[desc_pos]=='\r') { line[str_pos-start]='\0'; str_pos += 2; break; } else { line[str_pos-start]=desc[desc_pos]; str_pos += 1; } } line[str_pos-start]='\0'; if (x == min + 1) send_to_char(" ", ch); send_to_char(" &c", ch); send_to_char(line, ch); send_to_char("&n",ch); } */ send_to_char(ch,"\n\r"); } send_to_char(ch,"\n\r"); /* puts a line between contents/people */ return; } /* This is the main map function, do_map(ch, " ") is good to use */ /* do_map(ch "number") is for immortals to see the world map */ /* Edward: If you play with some of the values here you can make the normal ** map people see larger or smaller. size = URANGE(9, size, MAX_MAP), the 9 ** is the map size shown by default. Also look for: ShowMap (ch, min, max+1); ** and change the size of min and max and see what you like. */ void do_map( struct char_data *ch, char *argument ) { int size, center, x, y, min, max; char arg1[10]; one_argument( argument, arg1 ); size = atoi(arg1); size = MAPS(10,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_MAX; /* starts the mapping with the center room */ MapArea(ch->in_room, ch, center, center, min-1, max-1); /* marks the center, where ch is */ map[center][center] = SECT_MAX+2; /* can be any number above SECT_MAX+1 */ /* switch default will print out the * */ if ( (GET_LEVEL(ch) < LVL_IMMORT)||(IS_NPC(ch)) ) { /* if ( !IS_SET(world[ch->in_room].room_flags, ROOM_WILDERNESS) ) { send_to_char(ch, "&CYou can not do that here&n.\n\r");return;}*/ if ( IS_DARK(ch->in_room) ) { send_to_char(ch, "&bThe wilderness is pitch black at night... &n\n\r"); return; } else { ShowRoom(ch,MAX_MAP/2-3,MAX_MAP/2+3); return; } } /* mortals not in city, enter or inside will always get a ShowRoom */ if (GET_LEVEL(ch) >= LVL_IMMORT) { if (arg1[0] == '\0') ShowRoom (ch, min, max+1); else ShowMap (ch, min, max+1); return; } send_to_char(ch,"@CHuh?&n\n\r"); return; }