/************************************************************************** * 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> #if !defined(WIN32) #include <sys/time.h> #endif #include <stdio.h> #include <string.h> #include <stdlib.h> #include <ctype.h> #include <time.h> #include "merc.h" int bitcount(char c) { int count = 0; if (c & BIT_A) count++; if (c & BIT_B) count++; if (c & BIT_C) count++; if (c & BIT_D) count++; if (c & BIT_E) count++; if (c & BIT_F) count++; if (c & BIT_G) count++; if (c & BIT_H) count++; return count; } int roomcount(CHAR_DATA * ch) { int pIndex = 0, count = 0; if (IS_NPC(ch)) return top_room; for (pIndex = 0; pIndex < MAX_EXPLORE_HASH; pIndex++) { count += bitcount(ch->pcdata->explored[pIndex]); } return count; } void update_explored(CHAR_DATA * ch) { vnum_t vnum; ROOM_INDEX_DATA *pRoom; int nMatch = 0; for (vnum = 0; nMatch < top_room; vnum++) { if ((pRoom = get_room_index(vnum)) != NULL) { nMatch++; if (IS_SET(pRoom->room_flags, ROOM_NOEXPLORE) && STR_IS_SET(ch->pcdata->explored, vnum)) STR_REMOVE_BIT(ch->pcdata->explored, vnum); } else { if (STR_IS_SET(ch->pcdata->explored, vnum)) STR_REMOVE_BIT(ch->pcdata->explored, vnum); } } } int areacount(CHAR_DATA * ch, AREA_DATA * area) { vnum_t pIndex = 0, count = 0; if (IS_NPC(ch)) return top_room; if (ch == NULL || area == NULL) return 0; for (pIndex = area->min_vnum; pIndex <= area->max_vnum; pIndex++) { count += STR_IS_SET(ch->pcdata->explored, pIndex) ? 1 : 0; } return count; } int arearooms(AREA_DATA * area) { int count = 0; vnum_t pIndex = 0; ROOM_INDEX_DATA *pRoom; if (!area) return 0; for (pIndex = area->min_vnum; pIndex <= area->max_vnum; pIndex++) { if ((pRoom = get_room_index(pIndex)) != NULL && !IS_SET(pRoom->room_flags, ROOM_NOEXPLORE)) count++; } return count; } void fwrite_rle(char *explored, FILE * fp) { vnum_t pIndex; int bit = 0; int count = 0; fprintf(fp, "RoomRLE %d", bit); for (pIndex = 0; pIndex < MAX_VNUM; pIndex++) { if ((STR_IS_SET(explored, pIndex) ? 1 : 0) == bit) count++; else { fprintf(fp, " %d", count); count = 1; bit = (STR_IS_SET(explored, pIndex)) ? 1 : 0; } } fprintf(fp, " %d -1\n", count); return; } void fread_rle(char *explored, FILE * fp) { vnum_t pIndex; int bit = 0; int count = 0; vnum_t pos = 0; pIndex = 0; bit = fread_number(fp); for (;;) { count = fread_number(fp); if (count < 0) break; if (count == 0) continue; do { if (bit == 1) { STR_SET_BIT(explored, pIndex); } pIndex++; } while (pIndex < pos + count); pos = pIndex; bit = (bit == 1) ? 0 : 1; } return; } struct area_index { AREA_DATA *area; double percent; }; typedef struct area_index AREA_INDEX; int compare_area_explored(const void *v1, const void *v2) { AREA_INDEX area1 = *(AREA_INDEX *) v1; AREA_INDEX area2 = *(AREA_INDEX *) v2; return (int) (area2.percent - area1.percent); } CH_CMD(do_explored) { int line = 1, i = 0, c = 0, rcnt; double rooms, percent; AREA_DATA *pArea; AREA_INDEX *list; if (!ch || IS_NPC(ch)) return; if (IS_NULLSTR(argument)) { rcnt = roomcount(ch); rooms = (double) top_explored; percent = UMIN((double) rcnt / (rooms / 100), 100); chprintf(ch, "ROM has {G%d{x explorable rooms.", top_explored); chprintf(ch, "You have explored {G%d (%.2f%%){x of the mud{x", rcnt, percent); rcnt = areacount(ch, ch->in_room->area); rooms = (double) (arearooms(ch->in_room->area)); percent = UMIN((double) rcnt / (rooms / 100), 100); chprintf(ch, "\n\rThis area has {G%.0f{x explorable rooms.", rooms); chprintf(ch, "You have explored {G%d (%.2f%%){x rooms in this area.{x", rcnt, percent); } else if (is_exact_name(argument, "reset")) { memset(ch->pcdata->explored, 0, MAX_EXPLORE_HASH); chprintln(ch, "Your explored rooms were set to 0."); } else if (!str_prefix(argument, "list")) { alloc_mem(list, AREA_INDEX, top_area); for (pArea = area_first; pArea != NULL; pArea = pArea->next) { rcnt = areacount(ch, pArea); rooms = (double) (arearooms(pArea)); percent = UMIN((double) rcnt / (rooms / 100), 100); list[i].area = pArea; list[i].percent = percent; i++; } qsort(list, i, sizeof(AREA_INDEX), compare_area_explored); for (c = 0; c < i; c++) { pArea = list[c].area; percent = list[c].percent; chprintf(ch, "{D[{Y%3.0f{y%%{D]{x %-32s", percent, pArea->name); if (line >= 2) { line = 0; chprintln(ch, ""); } line++; } if (line >= 2) chprintln(ch, ""); free_mem(list); } else { chprintln(ch, "Syntax: explored - show current area and world."); chprintln(ch, " : explored list - list percentages for all areas."); chprintln(ch, " : explored reset - reset explored rooms."); } }