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"

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_first; curr != NULL; curr = prev)
	{
		prev = curr->next;

		if (!str_cmp(ch->name, curr->name))
		{
			UNLINK(curr, stat_first, stat_last, next, prev);
			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];

	LINK(curr, stat_first, stat_last, next, prev);
	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_first; curr != NULL; curr = prev)
		{
			prev = curr->next;

			if (!str_cmp(argument, curr->name))
			{
				UNLINK(curr, stat_first, stat_last, next, prev);
				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_first; 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_first; 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;
}