legend/
legend/area/
legend/player/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments 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          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/
/***************************************************************************
 *  God Wars Mud copyright (C) 1994, 1995, 1996 by Richard Woolcock        *
 *                                                                         *
 *  Legend of Chrystancia copyright (C) 1999, 2000, 2001 by Matthew Little *
 *  This mud is NOT to be copied in whole or in part, or to be run without *
 *  the permission of Matthew Little. Nobody else has permission to        *
 *  authorise the use of this code.                                        *
 ***************************************************************************/


#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif

#include <ctype.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <assert.h>
#include <unistd.h>
#include <stdarg.h>
#include <limits.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#include "merc.h"
#include "build.h"
#include "version.h"
#include "changes.h"
#include "quotes.h"

int MaxRetired;
RETIRED_DATA *retired_table;
NCLANS_DATA *nclans_table;

char *classname args ( (int Value) );

void load_retired (void)
{
   FILE *fp;
   int i;

   if (!(fp = fopen ("../db/retired.db", "r")))
   {
      bug ("Could not open retried file for reading.", 0);
      return;
   }

   fscanf (fp, "%d\n", &MaxRetired);

   /* Use malloc so we can realloc later on */
   retired_table = malloc (sizeof (RETIRED_DATA) * (MaxRetired + 1));

   for (i = 0; i < MaxRetired; i++)
   {
      retired_table[i].name = fread_string (fp);
      retired_table[i].title = fread_string (fp);
      retired_table[i].class = fread_number (fp);
      retired_table[i].pks = fread_number (fp);
      retired_table[i].pds = fread_number (fp);
      retired_table[i].mks = fread_number (fp);
      retired_table[i].mds = fread_number (fp);
      retired_table[i].als = fread_number (fp);
      retired_table[i].aws = fread_number (fp);
      retired_table[i].played = fread_number (fp);
      retired_table[i].creation = fread_string (fp);
      retired_table[i].retired = fread_string (fp);
      retired_table[i].clan = fread_string (fp);
      retired_table[i].generation = fread_number (fp);
      retired_table[i].status = fread_number (fp);
      retired_table[i].displayed = fread_number (fp);
   }

   fclose (fp);
   return;			/* just return */
}

void save_retired (void)
{
   FILE *fp;
   int i;

   if (!(fp = fopen ("../db/retired.db", "w")))
   {
      perror ("../db/retired.db");
      return;
   }

   fprintf (fp, "%d\n", MaxRetired);

   for (i = 0; i < MaxRetired; i++)
   {
      fprintf (fp, "%s~\n", retired_table[i].name); 
      fprintf (fp, "%s~\n", retired_table[i].title); 
      fprintf (fp, "%d\n", retired_table[i].class);
      fprintf (fp, "%d\n", retired_table[i].pks); 
      fprintf (fp, "%d\n", retired_table[i].pds); 
      fprintf (fp, "%d\n", retired_table[i].mks); 
      fprintf (fp, "%d\n", retired_table[i].mds);
      fprintf (fp, "%d\n", retired_table[i].als); 
      fprintf (fp, "%d\n", retired_table[i].aws); 
      fprintf (fp, "%d\n", retired_table[i].played); 
      fprintf (fp, "%s~\n", retired_table[i].creation); 
      fprintf (fp, "%s~\n", retired_table[i].retired); 
      fprintf (fp, "%s~\n", retired_table[i].clan); 
      fprintf (fp, "%d\n", retired_table[i].generation); 
      fprintf (fp, "%d\n", retired_table[i].status); 
      fprintf (fp, "%d\n", retired_table[i].displayed); 
      fprintf (fp, "\n");
   }
   fclose (fp);

   return;
}

void delete_retirement (int iArg)
{
   int i, j;
   RETIRED_DATA *new_table;

   new_table = malloc (sizeof (RETIRED_DATA) * MaxRetired);

   if (!new_table)
      return;

   for (i = 0, j = 0; i < MaxRetired + 1; i++)
   {
      if (i != iArg)
      {
	 new_table[j] = retired_table[i];
	 j++;
      }
   }

   free (retired_table);
   retired_table = new_table;
   MaxRetired--;
   save_retired ();
   return;
}

void do_retireset(CHAR_DATA *ch, char *argument)
{
  int num;
  char arg1[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];

  argument = one_argument (argument, arg1);
  argument = one_argument (argument, arg2);

  if(arg1[0]=='\0')
  {
    stc("Retireset [name] [option]\n\r",ch);
    stc("Option being one of: display delete\n\r",ch);
    return;
  }

  if(!str_cmp(arg2, "display"))
  {
    if(!dude_exists(arg1))
    {
      stc("Can't find them in the list...\n\r",ch);
      return;
    }

    num = fetch_dudenr(arg1);

    if(retired_table[num].displayed == 0)
    {
      retired_table[num].displayed = 1;
      stc("They are now displayed on the public command.\n\r",ch);
      save_retired();
      return;
    }
    else
    {
      retired_table[num].displayed = 0;
      stc("They are no longer displayed on the public command.\n\r",ch);
      save_retired();
      return;
    }
    return;
  }
  
  if (!str_cmp(arg2, "delete"))
  {
    if(!dude_exists(arg1))
    {
      stc("Can't find them in the list...\n\r",ch);
      return;
    }

    num = fetch_dudenr(arg1);
    delete_retirement(num);
    stc("That retirement is now wiped out.\n\r",ch);
    save_retired();
    return;
  }
  return;
}


void do_retire(CHAR_DATA *ch, char *argument)
{
  RETIRED_DATA *new_table;
  char buf[MSL];
  char ibuf[MSL];

  if(IS_NPC(ch)) return;

  if(ch->played < 360000)
  {
    stc("We don't retire players underneath 100 hours playtime.\n\r",ch);
    return;
  }

  if(argument[0]=='\0')
  {
    stc("Syntax: retire [password]\n\r",ch);
    stc("NOTE: #r#FWE WILL NOT REIMB YOU AFTER RETIREMENT!#n\n\r",ch);
    return;
  }

  if (strcmp (crypt (argument, ch->pcdata->pwd), ch->pcdata->pwd))
  {
    send_to_char ("Illegal password.\n\r", ch);
    WAIT_STATE (ch, 12);
    return;
  }

  MaxRetired++;
  new_table =
     realloc (retired_table, sizeof (RETIRED_DATA) * (MaxRetired + 1));

  if (!new_table)
  {				/* realloc failed */
     send_to_char ("Memory allocation failed. Brace for impact.\n\r", ch);
     return;
  }

  retired_table = new_table;

  retired_table[MaxRetired  - 1].name = str_dup(ch->name);
  retired_table[MaxRetired  - 1].title = str_dup(ch->pcdata->title);
  retired_table[MaxRetired  - 1].class = ch->class;
  retired_table[MaxRetired  - 1].pks = ch->pkill;
  retired_table[MaxRetired  - 1].pds = ch->pdeath;
  retired_table[MaxRetired  - 1].mks = ch->mkill;
  retired_table[MaxRetired  - 1].mds = ch->mdeath;
  retired_table[MaxRetired  - 1].aws = ch->awins;
  retired_table[MaxRetired  - 1].als = ch->alosses;
  retired_table[MaxRetired  - 1].played = ch->played;
  retired_table[MaxRetired  - 1].creation = str_dup(ch->createtime);
  retired_table[MaxRetired  - 1].retired = str_dup(new_date(current_time));
  retired_table[MaxRetired  - 1].clan = str_dup(nclans_table[ch->clannum].display);
  if(IS_IMMORTAL(ch))
  retired_table[MaxRetired  - 1].generation =  1337;
  else
  retired_table[MaxRetired  - 1].generation =  ch->pcdata->stats[UNI_GEN];
  if(IS_IMMORTAL(ch))
  retired_table[MaxRetired  - 1].status = ch->level;
  else
  retired_table[MaxRetired  - 1].status = ch->race;
  retired_table[MaxRetired  - 1].displayed = 0;
  save_retired();

  sprintf (buf, "%s has retired.", ch->name);
  log_string (buf, ch);
  sprintf (buf, "%s%s", PLAYER_DIR, capitalize (ch->name));
  ch->fight_timer = 0;
  ch->pcdata->login_timer = 0;
  char_from_room (ch);
  char_to_room (ch, get_room_index (ROOM_VNUM_LIMBO));
  sprintf(ibuf, "%s has retired theirself from gameplay!", ch->name);
  do_info(ch, ibuf);
  do_quit (ch, "");
  unlink (buf);
  return;
}

void do_showretired(CHAR_DATA *ch, char *argument)
{
   char buf[MSL];
   char show[MSL];
   int i;

   cprintf(buf, "#w[#r%-3s#w][#g%-13s#w][#y%-5s#w][#b%-7s#w][#p%-7s#w][#p%-7s#w][#p%-7s#w][#p%-7s#w][#p%-7s#w][#p%-9s#w]#n\n\r","Num", "Name", "Hours", "Pkills", "Pdeaths", "Mkills", "Mdeaths", "Awins", "Alosses", "Displayed" );
   stc(buf, ch);
  
   for (i = 1; i < MaxRetired; i++)
   {
        if(retired_table[i].displayed == 0)
          sprintf(show, "No");
        else
          sprintf(show, "Yes");

     	  cprintf(buf, "#w[#r%3d#w][#g%-13s#w][#y%-5d#w][#b%7d#w][#b%7d#w][#b%7d#w][#b%7d#w][#b%7d#w][#p%7d#w][#P%-9s#w]#n\n\r", 
        i, 
        retired_table[i].name, 
        (retired_table[i].played / 3600),
        retired_table[i].pks, 
        retired_table[i].pds,
        retired_table[i].mks,
        retired_table[i].mds,
        retired_table[i].aws,
        retired_table[i].als,
        show );
        stc(buf, ch);
   }
   return;
}

void do_halloffame( CHAR_DATA *ch, char *argument )
{
  int i=0, hit=0, page=0, display=0, actual=0;
  char buf[MSL], name[MSL];

  if (IS_NPC(ch)) return;

  for (i = 1; i < MaxRetired; i++)
  {
    if(retired_table[i].displayed == 0) continue;
    actual++;
  }

  if ((page = atoi(argument)) == 0) page = (actual + 2) / 3;

  stc("#C---------------#w=#r[#eC#w h r y s t a n c i a   #eH #wa l l   o f   #eF #wa m e#r]#w=#C---------------#n\n\r",ch);
  for (i = 1; i < MaxRetired; i++)
  {
    if(retired_table[i].displayed == 0) continue;

    display++;

    if (((display + 2) / 3) != page) continue;

    if(hit > 0)
      stc("#C=================================================================================#n\n\r",ch);
    cprintf(name, "#w%s#e %s#n", retired_table[i].name, retired_table[i].title);
    cprintf(buf, "#eName:#n %-30s #eCharacter creation: #w%s#n\n\r", name, retired_table[i].creation);
    stc(buf, ch);
    cprintf(name, "#w%d#e hours", (retired_table[i].played / 3600 ));
    cprintf(buf, "#ePlayed: %-28s #eCharacter retirement:#w %s#n\n\r", name, retired_table[i].retired);
    stc(buf, ch);
    stc("\n\r",ch);
    sprintf(buf, "#eClass: #w%-29s#e Clan: #w%s#n\n\r", classname(retired_table[i].class), retired_table[i].clan);
    stc(buf, ch);
    sprintf(buf, "                                     #eGeneration: #w%d#n\n\r", retired_table[i].generation);
    stc(buf, ch);
    stc("\n\r",ch);
    switch (retired_table[i].status)
    {
	 default:
	       cprintf (name, "#wKing #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 0:
	    cprintf (name,    "#wAvatar #e(#w0#e)#n");
	    break;
	 case 1:
	 case 2:
	 case 3:
	 case 4:
	    cprintf (name,    "#wPeasant #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 5:
	 case 6:
	 case 7:
	 case 8:
           if(retired_table[i].generation == 1337)
            cprintf(name, "#cBuilder#n");
           else
	    cprintf (name,    "#wPeasant #e(#w%d#e)#n", retired_table[i].status);
           break;
	 case 9:
           if(retired_table[i].generation == 1337)
            cprintf(name, "#CEnforcer#n");
           else
	    cprintf (name, "#wPage #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 10:
           if(retired_table[i].generation == 1337)
            cprintf(name, "#oJudge#n");
           else
	    cprintf (name, "#wPage #e(#w%d#e)#n", retired_table[i].status);
           break;
	 case 11:
           if(retired_table[i].generation == 1337)
            cprintf(name, "#yHigh Judge#n");
           else
	    cprintf (name, "#wPage #e(#w%d#e)#n", retired_table[i].status);
           break;
	 case 12:
           if(retired_table[i].generation == 1337)
            cprintf(name, "#rImplementor#n");
           else
	    cprintf (name, "#wPage #e(#w%d#e)#n", retired_table[i].status);
           break;
	 case 13:
           if(retired_table[i].generation == 1337)
            cprintf(name, "#rOWNER#n");
           else
	    cprintf (name, "#wPage #e(#w%d#e)#n", retired_table[i].status);
           break;
	 case 14:
	    cprintf (name, "#wApprentice #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 15:
	 case 16:
	 case 17:
	 case 18:
	 case 19:
	    cprintf (name, "#wScout #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 20:
	 case 21:
	 case 22:
	 case 23:
	 case 24:
	    cprintf (name, "#wSoldier #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 25:
	 case 26:
	 case 27:
	 case 28:
	 case 29:
	    cprintf (name, "#wLieutenant #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 30:
	 case 31:
	 case 32:
	 case 33:
	 case 34:
	    cprintf (name,   "#wCaptain #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 35:
	 case 36:
	 case 37:
	 case 38:
	 case 39:
	    cprintf (name,   "#wMajor #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 40:
	 case 41:
	 case 42:
	 case 43:
	 case 44:
	    cprintf (name,   "#wGeneral #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 45:
	 case 46:
	 case 47:
	 case 48:
	 case 49:
	    cprintf (name,    "#wKnight #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 50:
	 case 51:
	 case 52:
	 case 53:
	 case 54:
	       cprintf (name, "#wLord #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 55:
	 case 56:
	 case 57:
	 case 58:
	 case 59:
	       cprintf (name, "#wBaron #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 60:
	 case 61:
	 case 62:
	 case 63:
	 case 64:
	       cprintf (name, "#wViscount #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 65:
	 case 66:
	 case 67:
	 case 68:
	 case 69:
	       cprintf (name, "#wEarl #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 70:
	 case 71:
	 case 72:
	 case 73:
	 case 74:
	       cprintf (name, "#wDuke #e(#w%d#e)#n", retired_table[i].status);
	    break;
	 case 75:
	 case 76:
	 case 77:
	 case 78:
	 case 79:
	       cprintf (name, "#wPrince #e(#w%d#e)#n", retired_table[i].status);
    }
    if(retired_table[i].generation == 1337)
    {
      cprintf(buf, "#eStaff Position: #n%s\n\r", name);
      stc(buf, ch);
    }
    else
    {
      cprintf(buf, "#ePlayer kills:  #w%-21d #eStatus:#n %s\n\r", retired_table[i].pks, name);
      stc(buf, ch);
    }
    if(retired_table[i].generation < 1337)
    {
      sprintf(buf, "#ePlayer deaths: #w%d#n\n\r", retired_table[i].pds);
      stc(buf, ch);
      sprintf(buf, "#eMob kills:     #w%-21d #eArena Wins:   #w%d#n\n\r", retired_table[i].mks, retired_table[i].aws);
      stc(buf, ch);
      sprintf(buf, "#eMob deaths:    #w%-21d #eArena Losses: #w%d#n\n\r", retired_table[i].mds, retired_table[i].als);
      stc(buf, ch);
    }
    hit++;
  }
  if(hit == 0)
  {
  stc("#w There are currently no players worthy an entry in the Chrystancia Hall of Fame!\n\r",ch);
  stc("#C---------------------------------------------------------------------------------#n\n\r", ch);
  }
  else
  {
  cprintf(buf, "#C---------------------------------- Page %d of %d ----------------------------------#n\n\r", page, ((actual + 2) / 3));
  stc(buf, ch);
  }
  return;
}

char *classname( int Value )
{
  if( Value == CLASS_VAMPIRE )
   return "Vampire";
  else if ( Value == CLASS_WEREWOLF )
   return "Werewolf";
  else if ( Value == CLASS_DEMON )
   return "Demon";
  else if ( Value == CLASS_NINJA )
   return "Ninja";
  else if ( Value == CLASS_DROW )
   return "Drow";
  else if ( Value == CLASS_MONK )
   return "Monk";
  else if ( Value == CLASS_MAGE )
   return "Mage";
  else if ( Value == CLASS_HIGHLANDER )
   return "Highlander";
  else if ( Value == CLASS_FAE )
   return "Fae";
  else if ( Value == CLASS_DRAGON )
   return "Dragon";
  else if ( Value == CLASS_WRAITH )
   return "Wraith";
  else if ( Value == CLASS_PHOENIX )
   return "Phoenix";
  else return "Unclassed";
}

bool dude_exists( char *argument)
{
      int i, cnt=0;

      for (i = 0; i < MaxRetired; i++)
      {
	   if (!str_cmp(argument, retired_table[i].name))
  	   {
	  	cnt++;
         }
      }
      if ( cnt > 0 )
        return TRUE;
      else
	  return FALSE;
}

int fetch_dudenr( char *argument )
{
      int i, cnt=0;

      for (i = 0; i < MaxRetired; i++)
      {
	   if (!str_cmp(argument, retired_table[i].name))
  	   {
                cnt += i;
         }
      }
	return cnt;
}