1stMUD/corefiles/
1stMUD/gods/
1stMUD/player/
1stMUD/win32/
1stMUD/win32/ROM/
/**************************************************************************
*  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"

void setbit (char *explored, vnum_t pIndex)
{
	SET_BIT (explored[pIndex / 8], (1 << (pIndex % 8)));
	return;
}

int getbit (char *explored, vnum_t pIndex)
{
	return (IS_SET (explored[pIndex / 8], (1 << (pIndex % 8))) != 0);
}

void rembit (char *explored, vnum_t pIndex)
{
	REMOVE_BIT (explored[pIndex / 8], (1 << (pIndex % 8)));
	return;
}

int bitcount (char ch)
{
	int bit, count = 0;

	for (bit = 1 << 7; bit > 0; bit >>= 1)
	{
		if (IS_SET (ch, bit))
			count++;
	}

	return count;
}

int roomcount (CHAR_DATA * ch)
{
	int pIndex = 0, count = 0;

	if (IS_NPC (ch))
		return 0;

	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)
				&& getbit (ch->pcdata->explored, vnum))
				rembit (ch->pcdata->explored, vnum);
		}
		else
		{
			if (getbit (ch->pcdata->explored, vnum))
				rembit (ch->pcdata->explored, vnum);
		}
	}
}

int areacount (CHAR_DATA * ch)
{
	vnum_t pIndex = 0, count = 0;

	if (IS_NPC (ch))
		return 0;

	if ((ch->in_room == NULL) || (ch->in_room->area == NULL))
		return 0;

	for (pIndex = ch->in_room->area->min_vnum;
		 pIndex <= ch->in_room->area->max_vnum; pIndex++)
	{
		count += getbit (ch->pcdata->explored, pIndex);
	}

	return count;
}

int arearooms (CHAR_DATA * ch)
{
	int count = 0;
	vnum_t pIndex = 0;
	ROOM_INDEX_DATA *pRoom;

	if (IS_NPC (ch))
		return 0;

	if ((ch->in_room == NULL) || (ch->in_room->area == NULL))
		return 0;

	for (pIndex = ch->in_room->area->min_vnum;
		 pIndex <= ch->in_room->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_EXPLORE_HASH * 8) - 1; pIndex++)
	{
		if (getbit (explored, pIndex) == bit)
			count++;
		else
		{
			fprintf (fp, " %d", count);
			count = 1;
			bit = getbit (explored, pIndex);
		}
	}
	fprintf (fp, " %d -1\n", count);
	return;
}

void fread_rle (char *explored, FILE * fp)
{
	vnum_t pIndex;
	int bit = 0;
	int count = 0;
	int 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)
				SET_BIT (explored[pIndex / 8], (1 << (pIndex % 8)));
			pIndex++;
		}
		while (pIndex < pos + count);
		pos = pIndex;
		bit = (bit == 1) ? 0 : 1;
	}
	return;
}

CH_CMD (do_explored)
{
	int rcnt;
	double rooms, percent;

	if (!ch || IS_NPC (ch))
		return;

	rcnt = roomcount (ch);
	rooms = (double) top_explored;
	percent = (double) rcnt / (rooms / 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);
	rooms = (double) (arearooms (ch));
	percent = (double) rcnt / (rooms / 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);

	return;
}