/************************************************************************** * 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; }