void do_map( CHAR_DATA *ch, char *argument ) { int size,center,x,y,min,max; char arg1[10]; one_argument( argument, arg1 ); size = atoi (arg1); size=URANGE(7,size,72); 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]=NULL; /* starts the mapping with the center room */ MapArea(ch->in_room, ch, center, center, min, max); /* marks the center, where ch is */ map[center][center]="{R*"; ShowMap (ch, min, max); return; }
void MapArea (ROOM_INDEX_DATA *room, CHAR_DATA *ch, int x, int y, int min, int max) { ROOM_INDEX_DATA *prospect_room; EXIT_DATA *pexit; int door; /* marks the room as visited */ switch (room->sector_type) { case SECT_INSIDE: map[x][y]="{WI"; break; case SECT_CITY: map[x][y]="{cC"; break; case SECT_FIELD: map[x][y]="{G\""; break; case SECT_FOREST: map[x][y]="{g@"; break; case SECT_HILLS: map[x][y]="{G^"; break; case SECT_MOUNTAIN: map[x][y]="{y^"; break; case SECT_WATER_SWIM: map[x][y]="{B-"; break; case SECT_WATER_NOSWIM: map[x][y]="{b~"; break; case SECT_UNUSED: map[x][y]="{DX"; break; case SECT_AIR: map[x][y]="{C#"; break; case SECT_DESERT: map[x][y]="{Y+"; break; case SECT_UNDERGROUND: map[x][y]="{wU"; break; case SECT_ROAD: map[x][y]="{RR"; break; default: map[x][y]="{m|"; } for ( door = 0; door < MAX_MAP_DIR; door++ ) { if ( (pexit = room->exit[door]) != NULL && pexit->u1.to_room != NULL && can_see_room(ch,pexit->u1.to_room) /* optional */ && !IS_SET(pexit->exit_info, EX_CLOSED) ) { /* if exit there */ prospect_room = pexit->u1.to_room; if ( prospect_room->exit[rev_dir[door]] && prospect_room->exit[rev_dir[door]]->u1.to_room!=room) { /* if not two way */ if ((prospect_room->sector_type==SECT_CITY) || (prospect_room->sector_type==SECT_INSIDE)) map[x][y]="{W@"; else map[x][y]="{D?"; return; } /* end two way */ if ((x<=min)||(y<=min)||(x>=max)||(y>=max)) return; if (map[x+offsets[door][0]][y+offsets[door][1]]==NULL) { MapArea (pexit->u1.to_room,ch, x+offsets[door][0], y+offsets[door][1],min,max); } } /* end if exit there */ } return; }
/* Display a string with the map beside it */ void str_and_map(char *str, struct char_data *ch, room_vnum target_room ) { int size, centre, x, y, min, max, char_size; int ew_size=0, ns_size=0; bool worldmap; /* Check MUDs map config options - if disabled, just show room decsription */ if (!can_see_map(ch)) { send_to_char(ch, "%s", strfrmt(str, GET_SCREEN_WIDTH(ch), 1, FALSE, FALSE, FALSE)); return; } worldmap = show_worldmap(ch); if(!PRF_FLAGGED(ch, PRF_AUTOMAP)) { send_to_char(ch, "%s", strfrmt(str, GET_SCREEN_WIDTH(ch), 1, FALSE, FALSE, FALSE)); return; } size = CONFIG_MINIMAP_SIZE; centre = MAX_MAP/2; min = centre - 2*size; max = centre + 2*size; for (x = 0; x < MAX_MAP; ++x) for (y = 0; y < MAX_MAP; ++y) map[x][y]= (!(y%2) && !worldmap) ? DOOR_NONE : SECT_EMPTY; /* starts the mapping with the center room */ MapArea(target_room, ch, centre, centre, min, max, ns_size/2, ew_size/2, worldmap ); map[centre][centre] = SECT_HERE; /* char_size = rooms + doors + padding */ if(worldmap) char_size = size * 4 + 5; else char_size = 3*(size+1) + (size) + 4; if(worldmap) send_to_char(ch, "%s", WorldMap(centre, size, MAP_CIRCLE, MAP_COMPACT)); // send_to_char(ch, "%s", strpaste(strfrmt(str, GET_SCREEN_WIDTH(ch) - char_size, size*2 + 1, // FALSE, TRUE, TRUE), WorldMap(centre, size, MAP_CIRCLE, MAP_COMPACT), " \tn")); else send_to_char(ch, "%s", strpaste(strfrmt(str, GET_SCREEN_WIDTH(ch) - char_size, size*2 + 1, FALSE, TRUE, TRUE), CompactStringMap(centre, size), " \tn")); }
/* Display a nicely formatted map with a legend */ void perform_map( struct char_data *ch, char *argument, bool worldmap ) { int size = DEFAULT_MAP_SIZE; int centre, x, y, min, max; char arg1[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH], buf[MAX_STRING_LENGTH], buf1[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH]; int count = 0; int ew_size=0, ns_size=0; int mapshape = MAP_CIRCLE; two_arguments( argument, arg1 , arg2 ); if(*arg1) { size = atoi(arg1); } if (*arg2) { if (is_abbrev(arg2, "normal")) worldmap=FALSE; else if (is_abbrev(arg2, "world")) worldmap=TRUE; else { send_to_char(ch, "Usage: \tymap <distance> [ normal | world ]\tn"); return; } } if(size<0) { size = -size; mapshape = MAP_RECTANGLE; } size = URANGE(1,size,MAX_MAP_SIZE); centre = MAX_MAP/2; if(worldmap) { min = centre - 2*size; max = centre + 2*size; } else { min = centre - size; max = centre + size; } /* Blank the map */ for (x = 0; x < MAX_MAP; ++x) for (y = 0; y < MAX_MAP; ++y) map[x][y]= (!(y%2) && !worldmap) ? DOOR_NONE : SECT_EMPTY; /* starts the mapping with the centre room */ MapArea(IN_ROOM(ch), ch, centre, centre, min, max, ns_size/2, ew_size/2, worldmap); /* marks the center, where ch is */ map[centre][centre] = SECT_HERE; /* Feel free to put your own MUD name or header in here */ send_to_char(ch, " \tb--\tB= \tCLuminari Map System \tB=\tb--\tn\r\n" "\tD .-.__--.,--.__.-.\tn\r\n" ); count += sprintf(buf + count, "\tn\tn\tn%s Up\\\\", door_info[NUM_DOOR_TYPES + DOOR_UP].disp); count += sprintf(buf + count, "\tn\tn\tn%s Down\\\\", door_info[NUM_DOOR_TYPES + DOOR_DOWN].disp); count += sprintf(buf + count, "\tn%s You\\\\", map_info[SECT_HERE].disp); count += sprintf(buf + count, "\tn%s Inside\\\\", map_info[SECT_INSIDE].disp); count += sprintf(buf + count, "\tn%s City\\\\", map_info[SECT_CITY].disp); count += sprintf(buf + count, "\tn%s Field\\\\", map_info[SECT_FIELD].disp); count += sprintf(buf + count, "\tn%s Forest\\\\", map_info[SECT_FOREST].disp); count += sprintf(buf + count, "\tn%s Hills\\\\", map_info[SECT_HILLS].disp); count += sprintf(buf + count, "\tn%s Mountain\\\\", map_info[SECT_MOUNTAIN].disp); count += sprintf(buf + count, "\tn%s Water\\\\", map_info[SECT_WATER_SWIM].disp); count += sprintf(buf + count, "\tn%s Deep Water\\\\", map_info[SECT_WATER_NOSWIM].disp); count += sprintf(buf + count, "\tn%s Air\\\\", map_info[SECT_FLYING].disp); count += sprintf(buf + count, "\tn%s Underwater\\\\", map_info[SECT_UNDERWATER].disp); count += sprintf(buf + count, "\tn%s Zone Entry\\\\", map_info[SECT_ZONE_START].disp); count += sprintf(buf + count, "\tn%s Road N-S\\\\", map_info[SECT_ROAD_NS].disp); count += sprintf(buf + count, "\tn%s Road E-W\\\\", map_info[SECT_ROAD_EW].disp); count += sprintf(buf + count, "\tn%s Intersect\\\\", map_info[SECT_ROAD_INT].disp); count += sprintf(buf + count, "\tn%s Desert\\\\", map_info[SECT_DESERT].disp); count += sprintf(buf + count, "\tn%s Ocean\\\\", map_info[SECT_OCEAN].disp); count += sprintf(buf + count, "\tn%s Marsh\\\\", map_info[SECT_MARSHLAND].disp); count += sprintf(buf + count, "\tn%s High Mount\\\\", map_info[SECT_HIGH_MOUNTAIN].disp); count += sprintf(buf + count, "\tn%s Planes\\\\", map_info[SECT_PLANES].disp); strcpy(buf, strfrmt(buf, LEGEND_WIDTH, CANVAS_HEIGHT + 2, FALSE, TRUE, TRUE)); /* Start with an empty column */ strcpy(buf1, strfrmt("",0, CANVAS_HEIGHT + 2, FALSE, FALSE, TRUE)); /* Paste the legend */ strcpy(buf2, strpaste(buf1, buf, "\tD | \tn")); /* Set up the map */ memset(buf, ' ', CANVAS_WIDTH); count = (CANVAS_WIDTH); if(worldmap) count += sprintf(buf + count , "\r\n%s", WorldMap(centre, size, mapshape, MAP_NORMAL)); else count += sprintf(buf + count , "\r\n%s", StringMap(centre, size)); memset(buf + count, ' ', CANVAS_WIDTH); strcpy(buf + count + CANVAS_WIDTH, "\r\n"); /* Paste it on */ strcpy(buf2, strpaste(buf2, buf, "\tD | \tn")); /* Paste on the right border */ strcpy(buf2, strpaste(buf2, buf1, " ")); /* Print it all out */ send_to_char(ch, "%s", buf2); send_to_char(ch, "\tD `.-.__--.,-.__.-.-'\tn\r\n"); return; }
/* MapArea function - create the actual map */ static void MapArea(room_rnum room, struct char_data *ch, int x, int y, int min, int max, sh_int xpos, sh_int ypos, bool worldmap) { room_rnum prospect_room; struct room_direction_data *pexit; int door, ew_size=0, ns_size=0, x_exit_pos=0, y_exit_pos=0; sh_int prospect_xpos, prospect_ypos; if (map[x][y] < 0) return; /* this is a door */ /* marks the room as visited */ if(room == IN_ROOM(ch)) map[x][y] = SECT_HERE; else map[x][y] = SECT(room); if ( (x < min) || ( y < min) || ( x > max ) || ( y > max) ) return; /* Check for exits */ for ( door = 0; door < MAX_MAP_DIR; door++ ) { if( door < MAX_MAP_FOLLOW && xpos+door_offsets[door][0] >= 0 && xpos+door_offsets[door][0] <= ns_size && ypos+door_offsets[door][1] >= 0 && ypos+door_offsets[door][1] <= ew_size) { /* Virtual exit */ map[x+door_offsets[door][0]][y+door_offsets[door][1]] = vdoor_marks[door] ; if (map[x+offsets[door][0]][y+offsets[door][1]] == SECT_EMPTY ) MapArea(room,ch,x + offsets[door][0], y + offsets[door][1], min, max, xpos+door_offsets[door][0], ypos+door_offsets[door][1], worldmap); continue; } if ( (pexit = world[room].dir_option[door]) != NULL && (pexit->to_room > 0 ) && (pexit->to_room != NOWHERE) && (!IS_SET(pexit->exit_info, EX_CLOSED)) && (!IS_SET(pexit->exit_info, EX_HIDDEN) || PRF_FLAGGED(ch, PRF_HOLYLIGHT)) ) { /* A real exit */ /* But is the door here... */ switch (door) { case NORTH: if(xpos > 0 || ypos!=y_exit_pos) continue; break; case SOUTH: if(xpos < ns_size || ypos!=y_exit_pos) continue; break; case EAST: if(ypos < ew_size || xpos!=x_exit_pos) continue; break; case WEST: if(ypos > 0 || xpos!=x_exit_pos) continue; break; case NORTHWEST: if(xpos > 0 || ypos!=y_exit_pos || ypos > 0 || xpos!=x_exit_pos) continue; break; case NORTHEAST: if(xpos > 0 || ypos!=y_exit_pos || ypos < ew_size || xpos!=x_exit_pos) continue; break; case SOUTHEAST: if(xpos < ns_size || ypos!=y_exit_pos || ypos < ew_size || xpos!=x_exit_pos) continue; break; case SOUTHWEST: if(xpos < ns_size || ypos!=y_exit_pos || ypos > 0 || xpos!=x_exit_pos) continue; break; } /* if ( (x < min) || ( y < min) || ( x > max ) || ( y > max) ) return;*/ prospect_room = pexit->to_room; /* one way into area OR maze */ if ( world[prospect_room].dir_option[rev_dir[door]] && world[prospect_room].dir_option[rev_dir[door]]->to_room != room) { map[x][y] = SECT_STRANGE; return; } if(!worldmap) { if ((map[x+door_offsets[door][0]][y+door_offsets[door][1]] == DOOR_NONE) || (map[x+door_offsets[door][0]][y+door_offsets[door][1]] == SECT_EMPTY) ) { map[x+door_offsets[door][0]][y+door_offsets[door][1]] = door_marks[door]; } else { if ( ((door == NORTHEAST) && (map[x+door_offsets[door][0]][y+door_offsets[door][1]] == DOOR_UP)) || ((door == UP) && (map[x+door_offsets[door][0]][y+door_offsets[door][1]] == DOOR_DIAGNE)) ) { map[x+door_offsets[door][0]][y+door_offsets[door][1]] = DOOR_UP_AND_NE; } else if ( ((door == SOUTHEAST) && (map[x+door_offsets[door][0]][y+door_offsets[door][1]] == DOOR_DOWN)) || ((door == DOWN) && (map[x+door_offsets[door][0]][y+door_offsets[door][1]] == DOOR_DIAGNW)) ) { map[x+door_offsets[door][0]][y+door_offsets[door][1]] = DOOR_DOWN_AND_SE; } } } prospect_xpos = prospect_ypos = 0; switch (door) { case NORTH: prospect_xpos = ns_size; case SOUTH: prospect_ypos = world[prospect_room].dir_option[rev_dir[door]] ? y_exit_pos : ew_size/2; break; case WEST: prospect_ypos = ew_size; case EAST: prospect_xpos = world[prospect_room].dir_option[rev_dir[door]] ? x_exit_pos : ns_size/2; break; case NORTHEAST: case NORTHWEST: case SOUTHEAST: case SOUTHWEST: prospect_xpos = world[prospect_room].dir_option[rev_dir[door]] ? x_exit_pos : ns_size/2; prospect_ypos = world[prospect_room].dir_option[rev_dir[door]] ? y_exit_pos : ew_size/2; break; } if(worldmap) { if ( door < MAX_MAP_FOLLOW && map[x+offsets_worldmap[door][0]][y+offsets_worldmap[door][1]] == SECT_EMPTY ) MapArea(pexit->to_room,ch,x + offsets_worldmap[door][0], y + offsets_worldmap[door][1], min, max, prospect_xpos, prospect_ypos, worldmap); } else { if ( door < MAX_MAP_FOLLOW && map[x+offsets[door][0]][y+offsets[door][1]] == SECT_EMPTY ) MapArea(pexit->to_room,ch,x + offsets[door][0], y + offsets[door][1], min, max, prospect_xpos, prospect_ypos, worldmap); } } /* end if exit there */ } return; }