/**************************************************************************
* 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 "interp.h"
#include "recycle.h"
#include "data_table.h"
DataTable stat_data_table[] = {
{"name", FIELD_STRING, (void *) &stat_zero.name, NULL, NULL},
{"stats", FIELD_LONG_ARRAY, (void *) &stat_zero.gamestat,
(const void *) MAX_GAMESTAT, (const void *) 0},
{"version", FIELD_INT, (void *) &stat_zero.version, NULL, NULL},
{NULL, (field_t) - 1, NULL, NULL, NULL}
};
TableSave_Fun (rw_stat_data)
{
rw_list (type, STAT_FILE, StatData, stat);
}
void
update_statlist (CharData * ch, bool pdelete)
{
StatData *prev;
StatData *curr;
int i;
if (IsNPC (ch) || IsImmortal (ch))
return;
prev = NULL;
for (curr = stat_first; curr != NULL; curr = prev)
{
prev = curr->next;
if (!str_cmp (ch->name, curr->name))
{
if (curr->version < mud_info.stats.version)
{
memset (curr->gamestat, 0, MAX_GAMESTAT);
memset (ch->pcdata->gamestat, 0, MAX_GAMESTAT);
}
UnLink (curr, stat, next, prev);
free_stat (curr);
}
}
if (pdelete || IsNPC (ch) || IsImmortal (ch))
{
rw_stat_data (act_write);
return;
}
curr = new_stat ();
curr->name = str_dup (ch->name);
curr->version = mud_info.stats.version;
for (i = 0; i < MAX_GAMESTAT; i++)
curr->gamestat[i] = GetStat (ch, i);
Link (curr, stat, next, prev);
rw_stat_data (act_write);
return;
}
const char *
print_stat (CharData * ch, const char *head, long value)
{
return FORMATF ("{W%-19.19s {w[{R%10.10ld{w]", head, value);
}
Do_Fun (do_showstats)
{
int option;
char arg[MIL];
argument = one_argument (argument, arg);
if (NullStr (arg))
{
chprintln (ch, " {ROPTIONS AVAILABLE:{x");
chprintln (ch, " {G0{x - Show general {n stats. (gstats)");
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)");
chprintln (ch, " {G5{x - Personal Rankings (personal)");
if (IsImmortal (ch))
chprintln (ch, " {Gdelete <name>{x - deletes from statlist");
return;
}
option = atoi (arg);
if (!str_cmp (arg, "delete") && IsImmortal (ch))
{
StatData *prev = NULL;
StatData *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, next, prev);
free_stat (curr);
rw_stat_data (act_write);
found = true;
}
}
if (!found)
chprintlnf (ch, "Error deleting %s.", argument);
}
else if (option == 0 || !str_prefix (arg, "gstats"))
{
Column *Cd;
Buffer *b;
Cd = new_column ();
b = new_buf ();
set_cols (Cd, ch, 2, COLS_BUF, b);
bprintln (b,
stringf (ch, 0, Center, "{R-{r=",
"{C[ %s Stats ]", mud_info.name));
print_cols (Cd, print_stat (ch, "Logins", mud_info.stats.logins));
print_cols (Cd, print_stat (ch, "Quests", mud_info.stats.quests));
print_cols (Cd,
print_stat (ch, "Quests Complete",
mud_info.stats.qcomplete));
print_cols (Cd, print_stat (ch, "Levels", mud_info.stats.levels));
print_cols (Cd, print_stat (ch, "Newbies", mud_info.stats.newbies));
print_cols (Cd, print_stat (ch, "Deletions", mud_info.stats.deletions));
print_cols (Cd,
print_stat (ch, "Mob Deaths", mud_info.stats.mobdeaths));
print_cols (Cd, print_stat (ch, "Auctions", mud_info.stats.auctions));
print_cols (Cd,
print_stat (ch, "Auctions Sold", mud_info.stats.aucsold));
print_cols (Cd, print_stat (ch, "Player Deaths", mud_info.stats.pdied));
print_cols (Cd, print_stat (ch, "Player Kills", mud_info.stats.pkill));
print_cols (Cd, print_stat (ch, "Notes", mud_info.stats.notes));
print_cols (Cd, print_stat (ch, "Remorts", mud_info.stats.remorts));
print_cols (Cd, print_stat (ch, "Wars", mud_info.stats.wars));
print_cols (Cd,
print_stat (ch, "Global Quests", mud_info.stats.gquests));
print_cols (Cd,
print_stat (ch, "Connections", mud_info.stats.connections));
print_cols (Cd,
print_stat (ch, "Connects this Boot",
mud_info.stats.boot_connects));
print_cols (Cd,
print_stat (ch, "Online Record", mud_info.stats.online));
print_cols (Cd,
print_stat (ch, "Web Hits", mud_info.stats.web_requests));
print_cols (Cd,
print_stat (ch, "Channel Messages",
mud_info.stats.chan_msgs));
cols_nl (Cd);
bprintln (b,
stringf (ch, 0, Center, "{R-{r=",
"{C[ Stats since: %s ]",
str_time (mud_info.stats.lastupdate,
GetTzone (ch), NULL)));
sendpage (ch, buf_string (b));
free_buf (b);
free_column (Cd);
return;
}
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 if (option == 5 || !str_prefix (arg, "personal"))
{
StatData *curr;
Column Cd;
Buffer b;
int i = 0;
const char *stat_self[MAX_GAMESTAT] = {
"PLAYER KILLS",
"MOB KILLS",
"PK DEATHS",
"MOB DEATHS",
};
update_statlist (ch, false);
for (curr = stat_first; curr != NULL; curr = curr->next)
if (!str_cmp (ch->name, curr->name))
break;
if (!curr)
{
chprintln (ch, "You have no stats yet.");
return;
}
set_cols (&Cd, ch, 2, COLS_BUF, &b);
bprintln (&b, stringf (ch, 0, Center, "{r-{R=",
"{C[ RANKING OF PERSONAL BESTS ]"));
for (i = 0; i < MAX_GAMESTAT; i++)
{
print_cols (&Cd, "{G%2d{w){W %s{x", i + 1,
print_stat (ch, stat_self[i], curr->gamestat[i]));
}
cols_nl (&Cd);
bprintln (&b, draw_line (ch, "{r-{R=", 0));
sendpage (ch, buf_string (&b));
return;
}
else
do_showstats (n_fun, ch, "");
return;
}
int compare_type;
int
compare_stats (const void *v1, const void *v2)
{
StatData *stat1 = *(StatData **) v1;
StatData *stat2 = *(StatData **) v2;
if (!stat2)
return 1;
if (!stat1)
return 2;
return stat2->gamestat[compare_type] - stat1->gamestat[compare_type];
}
void
show_game_stats (CharData * ch, int type)
{
StatData *curr;
Buffer *output;
StatData **top;
Column *Cd, c;
int count, loop;
bool found = false;
const char *stat_name[MAX_GAMESTAT] = {
"PLAYER KILLERS",
"MOB KILLERS",
"PK DEATHS",
"MOB DEATHS",
};
output = new_buf ();
Cd = &c;
set_cols (Cd, ch, 2, COLS_BUF, output);
count = 0;
compare_type = type;
alloc_mem (top, StatData *, top_stat);
bprintln (output, stringf (ch, 0, Center, "{R-{r=",
"{C[ RANKING OF %s ]", stat_name[type]));
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;
print_cols (Cd,
"{G%2d{w){W %-20s {w[{R%8ld{W]{x", loop + 1,
top[loop]->name, top[loop]->gamestat[type]);
}
}
if (!found)
bprintln (output, "No one found yet.");
else
cols_nl (Cd);
bprintln (output, draw_line (ch, "{R-{r=", 0));
sendpage (ch, buf_string (output));
free_mem (top);
free_buf (output);
free_column (Cd);
return;
}