1stMud4.5.3/
1stMud4.5.3/backup/
1stMud4.5.3/bin/
1stMud4.5.3/bin/extras/
1stMud4.5.3/data/i3/
1stMud4.5.3/doc/1stMud/
1stMud4.5.3/doc/Diku/
1stMud4.5.3/doc/MPDocs/
1stMud4.5.3/doc/Rom/
1stMud4.5.3/notes/
/**************************************************************************
*  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-2004 by Markanth                *
*            http://www.firstmud.com/  <markanth@firstmud.com>            *
*         By using this code you have agreed to follow the term of        *
*             the 1stMud license in ../doc/1stMud/LICENSE                 *
***************************************************************************/

#include "merc.h"
#include "recycle.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(CharData * ch)
{
	int pIndex = 0, count = 0;

	if (IsNPC(ch))
		return top_room_index;

	for (pIndex = 0; pIndex < MAX_EXPLORE_HASH; pIndex++)
	{
		count += bitcount(ch->pcdata->explored[pIndex]);
	}

	return count;
}

void update_explored(CharData * ch)
{
	vnum_t vnum;
	RoomIndex *pRoom;
	int nMatch = 0;

	for (vnum = 0; nMatch < top_room_index; vnum++)
	{
		if ((pRoom = get_room_index(vnum)) != NULL)
		{
			nMatch++;
			if (IsSet(pRoom->room_flags, ROOM_NOEXPLORE)
				&& StrIsSet(ch->pcdata->explored, vnum))
				StrRemBit(ch->pcdata->explored, vnum);
		}
		else
		{
			if (StrIsSet(ch->pcdata->explored, vnum))
				StrRemBit(ch->pcdata->explored, vnum);
		}
	}
}

int areacount(CharData * ch, AreaData * area)
{
	vnum_t pIndex = 0;
	int count = 0;

	if (ch == NULL || area == NULL)
		return 0;

	if (IsNPC(ch))
		return top_room_index;

	for (pIndex = area->min_vnum; pIndex <= area->max_vnum; pIndex++)
	{
		count += StrIsSet(ch->pcdata->explored, pIndex) ? 1 : 0;
	}

	return count;
}

int arearooms(AreaData * area)
{
	int count = 0;
	vnum_t pIndex = 0;
	RoomIndex *pRoom;

	if (!area)
		return 0;

	for (pIndex = area->min_vnum; pIndex <= area->max_vnum; pIndex++)
	{
		if ((pRoom = get_room_index(pIndex)) != NULL
			&& !IsSet(pRoom->room_flags, ROOM_NOEXPLORE))
			count++;
	}

	return count;
}

void write_rle(char *explored, FileData * fp)
{
	vnum_t pIndex;
	int bit = 0;
	int count = 0;

	f_writef(fp, "RoomRLE", "%d", bit);

	for (pIndex = 0; pIndex < top_vnum_room; pIndex++)
	{
		if ((StrIsSet(explored, pIndex) ? 1 : 0) == bit)
			count++;
		else
		{
			f_printf(fp, " %d", count);
			count = 1;
			bit = (StrIsSet(explored, pIndex)) ? 1 : 0;
		}
	}
	f_printf(fp, " %d -1" LF, count);
	return;
}

void read_rle(char *explored, FileData * fp)
{
	vnum_t index;
	int bit = 0;
	int count = 0;
	vnum_t pos = 0;

	index = 0;

	bit = read_number(fp);

	for (;;)
	{
		count = read_number(fp);

		if (count < 0)
			break;
		if (count == 0)
			continue;

		do
		{
			if (bit == 1)
			{
				StrSetBit(explored, index);
			}
			index++;
		}
		while (index < pos + count);

		pos = index;
		bit = (bit == 1) ? 0 : 1;
	}
	return;
}

int compare_area_explored(const void *v1, const void *v2)
{
	AreaIndex area1 = *(AreaIndex *) v1;
	AreaIndex area2 = *(AreaIndex *) v2;

	return (int) (area2.percent - area1.percent);
}

Do_Fun(do_explored)
{
	int i = 0, c = 0;
	double rooms, rcnt, percent;
	AreaData *pArea;
	AreaIndex *list;

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

	if (NullStr(argument))
	{
		rcnt = (double) roomcount(ch);
		rooms = (double) top_explored;

		chprintlnf(ch, "ROM has {G%d{x explorable rooms.", top_explored);
		chprintlnf(ch, "You have explored {G%.0f (%.2f%%){x of the mud{x",
				   rcnt, Percent(rcnt, rooms));

		rcnt = (double) areacount(ch, ch->in_room->area);
		rooms = (double) (arearooms(ch->in_room->area));

		chprintlnf(ch, "This area has {G%.0f{x explorable rooms.", rooms);
		chprintlnf(ch,
				   "You have explored {G%.0f (%.2f%%){x rooms in this area.{x",
				   rcnt, Percent(rcnt, rooms));
	}
	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"))
	{
		Buffer *output = new_buf();
		Column *Cd = new_column();

		set_cols(Cd, ch, 2, COLS_BUF, output);
		alloc_mem(list, AreaIndex, top_area);

		for (pArea = area_first; pArea != NULL; pArea = pArea->next)
		{
			rcnt = (double) (areacount(ch, pArea));
			rooms = (double) (arearooms(pArea));
			list[i].area = pArea;
			list[i].percent = Percent(rcnt, rooms);
			i++;
		}
		qsort(list, i, sizeof(AreaIndex), compare_area_explored);

		for (c = 0; c < i; c++)
		{
			pArea = list[c].area;
			percent = list[c].percent;

			print_cols(Cd, "{D[{Y%3.0f{y%%{D]{x %s", percent, pArea->name);
		}
		cols_nl(Cd);
		sendpage(ch, buf_string(output));
		free_buf(output);
		free_column(Cd);
		free_mem(list);
	}
	else
	{
		cmd_syntax(ch, NULL, n_fun, "        - show current area and world.",
				   "list    - list percentages for all areas.",
				   "reset   - reset explored rooms.", NULL);
	}
}