/************************************************************************** * 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; flag_t info; bool up; bool dn; }; 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].up = FALSE; map[x][y].dn = FALSE; map[x][y].info = 0; } 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); } } 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 = 'o'; map[x][y].vnum = pRoom->vnum; map[x][y].depth = depth; map[x][y].dn = FALSE; map[x][y].up = FALSE; if (!IS_NPC (ch) && getbit (ch->pcdata->explored, pRoom->vnum)) { map[x][y].info = pRoom->room_flags; if (pRoom->exit[DIR_DOWN] != NULL) map[x][y].dn = TRUE; if (pRoom->exit[DIR_UP] != NULL) map[x][y].up = TRUE; } 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].info = pExit->exit_info; 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 += 2; 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] == ANSI_KEY) { lcolor = desc[l + 1]; 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].symbol == 'o') { if (map[x][y].up && map[x][y].dn) map[x][y].symbol = 'O'; if (!map[x][y].up && map[x][y].dn) map[x][y].symbol = 'D'; if (map[x][y].up && !map[x][y].dn) map[x][y].symbol = 'U'; } sprintf (buf + strlen (buf), "%c", 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); } }