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>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#if !defined(WIN32)
#include <unistd.h>
#endif
#include "merc.h"
#include "interp.h"
#include "recycle.h"

STAT_DATA *stat_list;

void update_statlist (CHAR_DATA * ch, bool pdelete)
{
	STAT_DATA *prev;
	STAT_DATA *curr;
	int i;

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

	prev = NULL;

	for (curr = stat_list; curr != NULL; prev = curr, curr = curr->next)
	{
		if (!str_cmp (ch->name, curr->name))
		{
			if (prev == NULL)
				stat_list = stat_list->next;
			else
				prev->next = curr->next;

			free_stat_data (curr);
			save_statlist ();
		}
	}
	if (pdelete)
	{
		return;
	}

	curr = new_stat_data ();
	curr->name = str_dup (ch->name);
	for (i = 0; i < MAX_GAMESTAT; i++)
		curr->gamestat[i] = ch->pcdata->gamestat[i];

	curr->next = stat_list;
	stat_list = curr;
	save_statlist ();
	return;
}

CH_CMD (do_showstats)
{
	int option;
	char arg[MIL];

	argument = one_argument (argument, arg);

	if (arg[0] == '\0')
	{
		chprintln (ch, "      {ROPTIONS AVAILABLE:{x");
		chprintln (ch, "      {G1{x - Ranking of Player Killers (pkills)");
		chprintln (ch, "      {G2{x - Ranking of Player Deaths (pdeaths)");
		chprintln (ch, "      {G3{x - Ranking of Mob Kills (mkills)");
		chprintln (ch, "      {G4{x - Ranking of Mob Deaths (mdeaths)");
		if (IS_IMMORTAL (ch))
			chprintln (ch, "      {Gdelete <name>{x - deletes from statlist");
		return;
	}
	option = atoi (arg);

	if (!str_cmp (arg, "delete") && IS_IMMORTAL (ch))
	{
		STAT_DATA *prev = NULL;
		STAT_DATA *curr = NULL;
		bool found = FALSE;

		for (curr = stat_list; curr != NULL; prev = curr, curr = curr->next)
		{
			if (!str_cmp (argument, curr->name))
			{
				if (prev == NULL)
					stat_list = stat_list->next;
				else
					prev->next = curr->next;

				free_stat_data (curr);
				save_statlist ();
				found = TRUE;
			}
		}
		if (!found)
			chprintf (ch, "Error deleting %s.\n\r", argument);
	}
	else if (option == 1 || !str_prefix (arg, "pkills"))
		show_game_stats (ch, PK_KILLS);
	else if (option == 3 || !str_prefix (arg, "mkills"))
		show_game_stats (ch, MOB_KILLS);
	else if (option == 2 || !str_prefix (arg, "pdeaths"))
		show_game_stats (ch, PK_DEATHS);
	else if (option == 4 || !str_prefix (arg, "mdeaths"))
		show_game_stats (ch, MOB_DEATHS);
	else
		do_showstats (ch, "");

	return;
}

int compare_type;

int compare_stats (const void *v1, const void *v2)
{
	STAT_DATA *stat1 = *(STAT_DATA **) v1;
	STAT_DATA *stat2 = *(STAT_DATA **) v2;

	if (!stat2)
		return 1;
	if (!stat1)
		return 2;

	return stat2->gamestat[compare_type] - stat1->gamestat[compare_type];
}

int count_statlist ()
{
	STAT_DATA *stat;
	int i = 0;

	for (stat = stat_list; stat != NULL; stat = stat->next)
		i++;

	return i;
}

void show_game_stats (CHAR_DATA * ch, int type)
{
	STAT_DATA *curr;
	BUFFER *output;
	char buf[MSL];
	STAT_DATA **top;
	int count, pos, loop;
	bool found = FALSE;
	int topstat = count_statlist ();
	const char *stat_name[MAX_GAMESTAT] = {
		"PLAYER KILLERS",
		"MOB KILLERS",
		"PK DEATHS",
		"MOB DEATHS",
	};

	output = new_buf ();
	count = 0;
	pos = 0;
	compare_type = type;

	alloc_mem (top, STAT_DATA *, topstat);

	sprintf (buf, "{CRANKING OF %s{x", stat_name[type]);
	add_buf (output, buf);
	add_buf (output, "\n\r");
	loop = 0;
	loop = 0;
	for (curr = stat_list; curr != NULL; curr = curr->next)
	{
		top[count] = curr;
		count++;
		found = TRUE;
	}

	if (found)
	{
		qsort (top, count, sizeof (*top), compare_stats);

		for (loop = 0; loop < count; loop++)
		{
			if (loop >= 50)
				break;

			sprintf (buf, "{G%2d{w){W %-20s {w[{R%8ld{W]{x    ",
					 loop + 1, top[loop]->name, top[loop]->gamestat[type]);
			add_buf (output, buf);
			if (++pos % 2 == 0)
			{
				add_buf (output, "\n\r");
				pos = 0;
			}
		}
	}
	if (!found)
		add_buf (output, "\n\rNo one found yet.\n\r");
	else if (pos % 2 != 0)
		add_buf (output, "\n\r");
	page_to_char (buf_string (output), ch);
	free_mem (top);
	free_buf (output);
	return;
}