lpmud/mudlib/
lpmud/mudlib/doc/
lpmud/mudlib/doc/LPC/
lpmud/mudlib/log/
lpmud/mudlib/players/
lpmud/mudlib/room/maze1/
lpmud/mudlib/room/sub/
#include "os.h"
#include "wiz_list.h"

/* comm1.c */
extern void add_message(char *fmt, ...);

/* simulate.c */
extern void fatal(char *fmt, ...);

/* main.c */
extern void *xalloc(int size);
extern char *string_copy(char *str);

/*
 * Maintain the wizards high score list about most popular castle.
 */
static struct wiz_list *all_wiz;

static struct wiz_list *insert (struct wiz_list *w, struct wiz_list *wl);
static void rebuild_list (void);
static struct wiz_list *find_wiz (char *name);
static void add_score(char *name, int score);

/*
 * Sort the wiz list in ascending order.
 */
static struct wiz_list *insert (struct wiz_list *w, struct wiz_list *wl)
{
  if (wl == 0) {
    w->next = 0;
    return w;
  }
  if (w->score > wl->score) {
    wl->next = insert (w, wl->next);
    return wl;
  }
  w->next = wl;
  return w;
}

static void rebuild_list (void)
{
  struct wiz_list *wl, *w, *new_list = 0;

  for (w = all_wiz; w; w = wl) {
    wl = w->next;
    new_list = insert (w, new_list);
  }
  all_wiz = new_list;
}

/*
 * Find the data, if it exists.
 */
static struct wiz_list *find_wiz (char *name)
{
  int length;
  struct wiz_list *wl;

  length = strlen (name);
  for (wl = all_wiz; wl; wl = wl->next)
    if (wl->length == length && strcmp (wl->name, name) == 0)
      return wl;
  return 0;
}

/*
 * Check that a name exists. Add it, if it doesn't.
 */
struct wiz_list *add_name (char *str)
{
  struct wiz_list *wl;

  wl = find_wiz (str);
  if (wl)
    return wl;
  wl = (struct wiz_list *) xalloc (sizeof (struct wiz_list));
  str = string_copy (str);
  wl->name = str;
  wl->length = strlen (str);
  wl->score = 0;
  wl->cost = 0;
  wl->heart_beats = 0;
  wl->total_worth = 0;
  wl->next = all_wiz;
  all_wiz = wl;
  return wl;
}

/*
 * Add score to an existing name.
 */
static void add_score (char *name, int score)
{
  struct wiz_list *wl;

  wl = find_wiz (name);
  if (!wl)
    fatal ("Add_score: could not find wizard %s\n", name);
  wl->score += score;
}

/*
 * This one is called at every complete walkaround of reset.
 */
void wiz_decay (void)
{
  struct wiz_list *wl;

  for (wl = all_wiz; wl; wl = wl->next) {
    wl->score = wl->score * 99 / 100;
    wl->total_worth = wl->total_worth * 99 / 100;
    wl->cost = wl->cost * 9 / 10;
    wl->heart_beats = wl->heart_beats * 9 / 10;
  }
}

/*
 * Load the wizlist file.
 */
void load_wiz_file (void)
{
  char buff[1000];              /* I hate not knowing how much I need. */
  FILE *f;

  f = fopen ("WIZLIST", "r");
  if (f == NULL)
    return;
  while (fgets (buff, sizeof buff, f)) {
    char *p;
    p = strchr (buff, ' ');
    if (p == 0) {
      fprintf (stderr, "Bad WIZLIST file.\n");
      break;
    }
    *p = '\0';
    p++;
    if (*p == '\0') {
      fprintf (stderr, "Bad WIZLIST file.\n");
      break;
    }
    (void) add_name (buff);
    add_score (buff, atoi (p));
  }
  fclose (f);
}

/*
 * Save the wizlist file.
 */
void save_wiz_file (void)
{
  struct wiz_list *wl;
  FILE *f;

  f = fopen ("WIZLIST", "w");
  if (f == NULL) {
    fprintf (stderr, "Could not open WIZLIST for write\n");
    return;
  }
  for (wl = all_wiz; wl; wl = wl->next)
    fprintf (f, "%s %d %d\n", wl->name, wl->score, wl->total_worth);
  fclose (f);
}

/* Print out the wizlist file */

void wizlist (void)
{
  struct wiz_list *wl;
  int total = 0, num = 0;

  rebuild_list ();
  for (wl = all_wiz; wl; wl = wl->next) {
    total += wl->score;
    num++;
  }
  add_message ("\nWizard top score list\n\n");
  for (wl = all_wiz; wl; wl = wl->next) {
    if (wl->score)
      add_message ("%-15s %5d %2d%% (%d)\t[%3dk,%5d] %d\n", wl->name,
        wl->score, wl->score * 100 / total, num,
        wl->cost / 1000, wl->heart_beats, wl->total_worth);
    num--;
  }
  add_message ("\nTotal         %7d\n\n", total);
}