/************************************************************************** * Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, * * Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. * * * * Merc Diku Mud improvements 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. * * * * Much time and thought has gone into this software and you are * * benefiting. We hope that you share your changes too. What goes * * around, comes around. * *************************************************************************** * ROM 2.4 is copyright 1993-1998 Russ Taylor * * ROM has been brought to you by the ROM consortium * * Russ Taylor (rtaylor@hypercube.org) * * Gabrielle Taylor (gtaylor@hypercube.org) * * Brian Moore (zump@rom.org) * * By using this code, you have agreed to follow the terms of the * * ROM license, in the file Rom24/doc/rom.license * *************************************************************************** * 1stMUD ROM Derivative (c) 2001-2002 by Ryan Jennings * * http://1stmud.dlmud.com/ <r-jenn@shaw.ca> * ***************************************************************************/ #include <sys/types.h> #include <ctype.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <time.h> #include "merc.h" char map_chars[5] = "|-|-"; char lcolor = 'x'; #define MAXDEPTH 4 #define MAPX 10 #define MAPY 8 #define BOUNDARY(x, y) (((x) < 0) || ((y) < 0) || \ ((x) > MAPX) || ((y) > MAPY)) struct map_type { char symbol; vnum_t vnum; int depth; ROOM_INDEX_DATA *pRoom; }; typedef struct map_type MAP_DATA; MAP_DATA map[MAPX + 1][MAPY + 1]; void get_exit_dir(int dir, int *x, int *y, int xorig, int yorig) { switch (dir) { case 0: *x = xorig; *y = yorig - 1; break; case 1: *x = xorig + 1; *y = yorig; break; case 2: *x = xorig; *y = yorig + 1; break; case 3: *x = xorig - 1; *y = yorig; break; default: *x = -1; *y = -1; break; } } void clear_coord(int x, int y) { map[x][y].symbol = ' '; map[x][y].vnum = 0; map[x][y].depth = 0; map[x][y].pRoom = NULL; } void clear_room(int x, int y) { int dir, exitx, exity; for (dir = DIR_NORTH; dir <= DIR_WEST; dir++) { get_exit_dir(dir, &exitx, &exity, x, y); if (!BOUNDARY(exitx, exity)) clear_coord(exitx, exity); } } struct sector_color_type { int bit; const char *display_color; char display_symbol; }; const struct sector_color_type sector_color_table[] = { {SECT_INSIDE, "{w", 'o'}, {SECT_CITY, "{w", 'o'}, {SECT_FIELD, "{G", '*'}, {SECT_FOREST, "{g", '*'}, {SECT_HILLS, "{y", '*'}, {SECT_MOUNTAIN, "{W", '@'}, {SECT_WATER_SWIM, "{B", '='}, {SECT_WATER_NOSWIM, "{b", '='}, {SECT_UNUSED, "{w", 'o'}, {SECT_AIR, "{C", '~'}, {SECT_DESERT, "{y", '+'}, {SECT_MAX, "{w", 'o'} }; const char *get_sector_color(int sector) { int looper; for (looper = 0;; looper++) if ((sector_color_table[looper].bit == sector) || (sector_color_table[looper].bit == SECT_MAX)) break; return (sector_color_table[looper].display_color); } char get_sector_symbol(int sector) { int looper; for (looper = 0;; looper++) if ((sector_color_table[looper].bit == sector) || (sector_color_table[looper].bit == SECT_MAX)) break; return (sector_color_table[looper].display_symbol); } void map_exits(CHAR_DATA * ch, ROOM_INDEX_DATA * pRoom, int x, int y, int depth) { int door; int exitx = 0, exity = 0; int roomx = 0, roomy = 0; EXIT_DATA *pExit; if (!can_see_room(ch, pRoom)) return; map[x][y].symbol = get_sector_symbol(pRoom->sector_type); map[x][y].vnum = pRoom->vnum; map[x][y].depth = depth; map[x][y].pRoom = pRoom; if (depth >= MAXDEPTH) return; for (door = DIR_NORTH; door <= DIR_DOWN; door++) { if ((pExit = pRoom->exit[door]) == NULL) continue; if (pExit->u1.to_room == NULL) continue; if (!can_see_room(ch, pExit->u1.to_room)) continue; get_exit_dir(door, &exitx, &exity, x, y); get_exit_dir(door, &roomx, &roomy, exitx, exity); if (BOUNDARY(exitx, exity) || BOUNDARY(roomx, roomy)) continue; if ((map[roomx][roomy].vnum != 0) && (map[roomx][roomy].vnum != pExit->u1.to_room->vnum) /* only clear exits and rooms of higher depth */ && map[roomx][roomy].depth > depth && depth < MAXDEPTH) { clear_room(roomx, roomy); } if (depth == MAXDEPTH) continue; map[exitx][exity].depth = depth; map[exitx][exity].vnum = pExit->u1.to_room->vnum; map[exitx][exity].symbol = map_chars[door]; map[exitx][exity].pRoom = pExit->u1.to_room; if ((depth < MAXDEPTH) && ((map[roomx][roomy].vnum == pExit->u1.to_room->vnum) || (map[roomx][roomy].vnum == 0))) { depth++; map_exits(ch, pExit->u1.to_room, roomx, roomy, depth + 1); depth--; } } } void reformat_desc(char *desc) { char *p; unsigned int l, m; char buf[MSL * 2]; l = 0; m = 0; buf[0] = '\0'; if (desc[0] == '\0') return; /* remove all \n & \r */ for (m = 0; m <= strlen(desc); m++) if (desc[m] == '\n' || desc[m] == '\r') desc[m] = ' '; /* remove multiple spaces */ for (p = desc; *p != '\0'; p++) { if (*p == ' ' && *(p + 1) == ' ') { buf[l] = *p; l++; do { p++; } while (*p == ' '); } buf[l] = *p; l++; } buf[l] = '\0'; sprintf(desc, buf); return; } unsigned int get_line(char *desc, unsigned int max_len) { unsigned int m; unsigned int l; char buf[MSL]; if (strlen(desc) <= max_len) return 0; buf[0] = '\0'; l = 0; for (m = 0; m <= strlen(desc); m++) { if (desc[m] == ANSI_KEY) { m++; lcolor = desc[m]; m++; } else if (desc[m] == ANSI_CUSTOM) { while (desc[m] != ANSI_END) m++; m++; } l++; if (l > max_len) break; } for (l = m; l > 0; l--) if (desc[l] == ' ') break; return l + 1; } void show_map(CHAR_DATA * ch, char *text) { char buf[MSL * 2]; int x, y, pos; char *p; bool alldesc = FALSE; int rcnt = areacount(ch); double rooms = (double) (arearooms(ch)); double percent = (double) rcnt / (rooms / 100); int maxlen = (ch->desc && ch->desc->scr_width > 0) ? ch->desc->scr_width - 2 : 78; int maplen = maxlen - 15; if (IS_NULLSTR(text)) alldesc = TRUE; pos = 0; p = text; buf[0] = '\0'; lcolor = 'x'; if (IS_NPC(ch) || IS_SET(ch->in_room->room_flags, ROOM_NOEXPLORE)) sprintf(buf, "{R+------------+{%c ", lcolor); else sprintf(buf, "{R+-----[{x%3.0f%%{R]+{%c ", percent, lcolor); if (!alldesc) { pos = get_line(p, maplen); if (pos > 0) { strncat(buf, p, pos); p += pos; } else { strcat(buf, p); alldesc = TRUE; } } strcat(buf, "\n\r"); for (y = 0; y <= MAPY; y++) { strcat(buf, "{R|{x"); for (x = 0; x <= MAPX; x++) { if (map[x][y].pRoom) { if (map[x][y].symbol == get_sector_symbol(map[x][y].pRoom->sector_type) && !IS_NPC(ch) && getbit(ch->pcdata->explored, map[x][y].pRoom->vnum)) { if (map[x][y].pRoom->exit[DIR_UP] && map[x][y].pRoom->exit[DIR_DOWN]) map[x][y].symbol = 'O'; else if (!map[x][y].pRoom->exit[DIR_UP] && map[x][y].pRoom->exit[DIR_DOWN]) map[x][y].symbol = 'D'; else if (map[x][y].pRoom->exit[DIR_UP] && !map[x][y].pRoom->exit[DIR_DOWN]) map[x][y].symbol = 'U'; } sprintf(buf + strlen(buf), "%s%c", get_sector_color(map[x][y].pRoom->sector_type), map[x][y].symbol); } else strcat(buf, &map[x][y].symbol); } strcat(buf, "{R| {"); strcat(buf, &lcolor); if (!alldesc) { pos = get_line(p, maplen); if (pos > 0) { strncat(buf, p, pos); p += pos; } else { strcat(buf, p); alldesc = TRUE; } } strcat(buf, "\n\r"); } strcat(buf, "{R+-----------+{"); strcat(buf, &lcolor); strcat(buf, " "); if (!alldesc) { pos = get_line(p, maplen); if (pos > 0) { strncat(buf, p, pos); p += pos; } else { strcat(buf, p); alldesc = TRUE; } } if (!alldesc) { do { pos = get_line(p, maxlen); if (pos > 0) { strncat(buf, p, pos); p += pos; } else { strcat(buf, p); alldesc = TRUE; } } while (!alldesc); } chprintln(ch, buf); } void draw_map(CHAR_DATA * ch, const char *desc) { int x, y; static char buf[MSL]; sprintf(buf, desc); reformat_desc(buf); for (y = 0; y <= MAPY; y++) { for (x = 0; x <= MAPX; x++) { clear_coord(x, y); } } x = MAPX / 2; y = MAPY / 2; map[x][y].vnum = ch->in_room->vnum; map[x][y].depth = 0; map_exits(ch, ch->in_room, x, y, 0); map[x][y].symbol = 'X'; show_map(ch, buf); } CH_CMD(do_automap) { if (IS_NPC(ch)) return; if (IS_SET(ch->act, PLR_AUTOMAP)) { chprintln(ch, "Automap removed."); REMOVE_BIT(ch->act, PLR_AUTOMAP); } else { chprintln(ch, "Automap on."); SET_BIT(ch->act, PLR_AUTOMAP); } }