legend/
legend/area/
legend/player/
/******************************************************************************
 *
 *	File:			new_train.c
 *
 *	Function:		New Updated Train Function for Legend of Chrystancia
 *
 *	Author(s):		Queen Serenity of the Moon Kingdom
 *
 *	Copyright:		Copyright (c) 1995-2003
 *					Silver Aerie Codeworks
 *
 *	Source:			Complete hack/slash/delete rewrite of boring train code from stock
 *
 *	Notes:			Yeah umm it's done.
 *
 *	Change History:
 *			03_29_08_001	Attempted to go live.
 *                      03_14_09_002    Removed QP costs for Stats/Immunities 
 *                                      (Unique/Matthew)
 *	
 *****************************************************************************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "player.h"

void do_avatar_announce (CHAR_DATA * ch, char *argument)
{
   DESCRIPTOR_DATA *d;
   char buf[MAX_STRING_LENGTH];
   FILE *fp;
   char *nstr;
   char buf2[MSL];
   time_t nowtime;
   struct tm *t;
   char *strtime;   

   nstr = switch_char (argument, '>', ' ');
   argument = nstr;
/*
   nowtime = time (&current_time);
   t = localtime (&nowtime);
//   strftime (buf2, 100, "%d/%m %H:%M:%S", t);
   strftime (buf2, 100, "%d-%b-%Y %T", t);
*/
  nowtime = time (&current_time);
   t = localtime (&nowtime);
   buf2[0] = '\0';
       
    strtime = asctime(gmtime(&current_time));
    strtime[strlen(strtime)-1] = '\0';
    strcat(buf2, datestring(strtime));
       
   if (argument[0] == '\0')
      return;

   for (d = first_descriptor; d != NULL; d = d->next)
   {
      if (d->connected == CON_PLAYING
	  && !IS_SET (d->character->deaf, CHANNEL_INFO))
      {
	 sprintf (buf,
		  "^1#7-->#n ^1#3AVATAR#n ^1#7<--#n %s ^1#7-->#n ^1#3AVATAR#n ^1#7<--#n #n\n\r",
		  argument);
	 cent_to_char (buf, d->character);
      }
   }

   if (!(fp = fopen (INFO_FILE, "a+")))
   {
      bug ("Cannot open INFO_FILE!", 0);
      return;
   }
   fprintf (fp, ">#w[#r%s#w]#n #w%s#n\r\n", buf2, argument);
   fclose (fp);
   return;
}

void do_legend_announce (CHAR_DATA * ch, char *argument)
{
   DESCRIPTOR_DATA *d;
   char buf[MAX_STRING_LENGTH];
   FILE *fp;
   char *nstr;
   char buf2[MSL];
   time_t nowtime;
   struct tm *t;
char *strtime;
   nstr = switch_char (argument, '>', ' ');
   argument = nstr;

  nowtime = time (&current_time);
   t = localtime (&nowtime);
   buf2[0] = '\0';

    strtime = asctime(gmtime(&current_time));
    strtime[strlen(strtime)-1] = '\0';
    strcat(buf2, datestring(strtime));

   if (argument[0] == '\0')
      return;

   for (d = first_descriptor; d != NULL; d = d->next)
   {
      if (d->connected == CON_PLAYING
	  && !IS_SET (d->character->deaf, CHANNEL_INFO))
      {
	 sprintf (buf,
		  "^4#2-->#n ^4#cRENOWN#n ^4#2<--#n %s ^4#2-->#n ^4#cRENOWN#n ^4#2<--#n #n\n\r",
		  argument);
	 cent_to_char (buf, d->character);
      }
   }

   if (!(fp = fopen (INFO_FILE, "a+")))
   {
      bug ("Cannot open INFO_FILE!", 0);
      return;
   }
   fprintf (fp, ">#w[#r%s#w]#n #w%s#n\r\n", buf2, argument);
   fclose (fp);
   return;
}

void seren_banner_to_char (char *txt, CHAR_DATA * ch)
{
   int lspace = 0;
   int rspace = 0;
   int ltotal = 0;
   char work_buf_1[50000];
   char work_buf_2[50000];

   ltotal = 25 - col_str_len (txt);

   if (ltotal < 0)
      ltotal = 0;

   lspace = (ltotal / 2) + (ltotal % 2);
   rspace = (ltotal - lspace);

   sprintf (work_buf_1,
	    "#R-----------------------=#w[#y %%%ds%%s%%%ds #w]#R=-----------------------",
	    lspace, rspace);
   sprintf (work_buf_2, work_buf_1, " ", txt, " ");

   cent_to_char (work_buf_2, ch);
   return;
}


void do_train (CHAR_DATA * ch, char *argument)
{
   char arg1[MAX_STRING_LENGTH];	// Holds first argument, usually what is trained
   char arg2[MAX_STRING_LENGTH];	// Holds second argument usually how much is trained (amount)
   sh_int *pAbility=0;		// Location of what is being trained
   char *pOutput=NULL;		// Title of what is being trained
   int xp_cost=0;			// Used to just be cost, now this is how much exp it takes to train something -- Serenity
   int qp_cost=0;			// Used to just be cost2, now this is how much qp it takes to train something -- Serenity
   int earnt_qp=0;		// Used to be used as cost3, now this is how much earned qp it takes to train something -- Serneity
   int immcost=0;			// How much experience it costs immunities to be trained???
   int statcap=0;			// Used to be hpcap, manacap, movecap, now this is the maximum amount you can improve hp/mana/move
   int max_stat = 18;		// Maximum s/i/w/d/c scores by default
   bool is_ok = FALSE;		// found a legal train area?
   char legbuf[MSL];		// A simple output buffer for legend titles
   int train_loop = 0;		// A simple integer for loops
   bool train_all = FALSE;	// Utilize all on-hand experience for training this area if applicable, (only on hp/mana/move)
   int amount = 1;		// Amount desired vs actually improved, default to 1
   int trained_amount = 0;	// Amount actually improved vs desired
   int combo_var = 0;		// Used for displaying combinations of things like a - b etc.

   bool VITALS_TRAIN = FALSE;	// Improving Str, Int, Wis, Dex, Con
   bool HPMPMV_TRAIN = FALSE;	// Improving Hp Mana Move
   bool PRIMAL_TRAIN = FALSE;	// Improving Primal
   bool STATUS_TRAIN = FALSE;	// Improving Legend
   bool AVATAR_TRAIN = FALSE;	// Going avatar
   bool MORTAL_TRAIN = FALSE;	// Going to mortal
   bool AMAGIC_TRAIN = FALSE;	// Anti-Magic Train
   bool SILVER_TRAIN = FALSE;	// Silver Train
   bool GNOSIS_TRAIN = FALSE;	// Gnosis Train
   bool VAMPYR_TRAIN = FALSE;	// Vampire Generation Train
   bool DRAGON_TRAIN = FALSE;	// Dragon Age Train
   bool MFOCUS_TRAIN = FALSE;	// Monk Focus Train
   bool HQUICK_TRAIN = FALSE;	// Highlander Quickening Train
   bool IMMUNE_TRAIN = FALSE;	// Immunities/Resistances Train
   bool CHAR_DIRTY = FALSE;	// Character got modified

   if (IS_NPC (ch))
      return;

   if ((IS_SET (ch->garou1, GAROU_WHELP2))
       || (IS_SET (ch->garou1, GAROU_WHELP1)))
   {
      stc ("You are unable to train with whelps curse affecting you.\n\r",
	   ch);
      return;
   }

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

/*   --- New stat cap proposal, utiilizes the 15000 + ((x(x+1)/2)*1000) method.
 *   --- where x = lstatus + 1.
 1, 1+2, 1+2+3, 1+2+3+4
 x+1;((x(x+1)/2)
 
 x=0  0+1=1  (1(1+1)/2) -> (1(2)/2) -> (2/2)  -> 1
 x=1  1+1=2  (2(2+1)/2) -> (2(3)/2) -> (6/2)  -> 3
 x=2  2+1=3  (3(3+1)/2) -> (3(4)/2) -> (12/2) -> 6
 x=3  3+1=4  (4(4+1)/2) -> (4(5)/2) -> (20/2) -> 10
 x=4  4+1=5  (5(5+1)/2) -> (5(6)/2) -> (30/2) -> 15
       Current         Gained            Planned       Gained    
      0 -  15000     0 -      0        0 -  15000    0 -      0
      1 -  16000     1 -   1000        1 -  16000    1 -   1000
      2 -  17000     2 -   2000        2 -  18000    2 -   3000
      3 -  18000     3 -   3000        3 -  21000    3 -   6000
      4 -  19000     4 -   4000        4 -  25000    4 -  10000
      5 -  20000     5 -   5000        5 -  30000    5 -  15000
      6 -  21000     6 -   6000        6 -  36000    6 -  21000
      7 -  22000     7 -   7000        7 -  43000    7 -  28000
      8 -  23000     8 -   8000        8 -  61000    8 -  36000
      9 -  24000     9 -   9000        9 -  70000    9 -  45000
     10 - 150000    10 - 135000       10 - 150000   10 - 135000
     11 - 150000    11 - 135000       11 - 150000   11 - 135000
*/
   if (ch->lstatus < 1)
      statcap = 15000;
   if (ch->lstatus < 10)
      statcap =
	 15000 + (1000 * ((ch->lstatus + 1) * ((ch->lstatus + 1) + 1) / 2)) +
	 (200 * ch->race);
   else
      statcap = 150000 + (500 * ch->race);

   if (ch->level >= 3)
      max_stat = 20;
   if (IS_CLASS (ch, CLASS_MONK))
      max_stat = 25;
   if (IS_CLASS (ch, CLASS_HIGHLANDER))
      max_stat = 30;
   if (IS_CLASS (ch, CLASS_DRAGON))
      max_stat = 35;

   if (arg1[0] == '\0')
   {
      // ok so just display what we can train eh?
      stc ("\n\r", ch);
      cent_to_char ("#wYou can improve in the following areas:#n", ch);

      seren_banner_to_char ("VITAL STATISTICS", ch);
      {
	 int xp_str_cost = ((ch->pcdata->perm_str + 1) * 500);
	 int xp_int_cost = ((ch->pcdata->perm_int + 1) * 500);
	 int xp_wis_cost = ((ch->pcdata->perm_wis + 1) * 500);
	 int xp_dex_cost = ((ch->pcdata->perm_dex + 1) * 500);
	 int xp_con_cost = ((ch->pcdata->perm_con + 1) * 500);
/*
			int qp_str_cost = ( ( ch->pcdata->perm_str + 1 ) * 25);
			int qp_int_cost = ( ( ch->pcdata->perm_int + 1 ) * 25);
			int qp_wis_cost = ( ( ch->pcdata->perm_wis + 1 ) * 25);
			int qp_dex_cost = ( ( ch->pcdata->perm_dex + 1 ) * 25);
			int qp_con_cost = ( ( ch->pcdata->perm_con + 1 ) * 25);
			int eqp_str_req = ( ( ( ch->pcdata->perm_str + 1 ) * ( ( ch->pcdata->perm_str + 1 ) + 1) / 2) * 25);
			int eqp_int_req = ( ( ( ch->pcdata->perm_int + 1 ) * ( ( ch->pcdata->perm_int + 1 ) + 1) / 2) * 25);
			int eqp_wis_req = ( ( ( ch->pcdata->perm_wis + 1 ) * ( ( ch->pcdata->perm_wis + 1 ) + 1) / 2) * 25);
			int eqp_dex_req = ( ( ( ch->pcdata->perm_dex + 1 ) * ( ( ch->pcdata->perm_dex + 1 ) + 1) / 2) * 25);
			int eqp_con_req = ( ( ( ch->pcdata->perm_con + 1 ) * ( ( ch->pcdata->perm_con + 1 ) + 1) / 2) * 25);
*/
// removal of earned qp costs
/*
			int qp_str_cost = 0;
			int qp_int_cost = 0;
			int qp_wis_cost = 0;
			int qp_dex_cost = 0;
			int qp_con_cost = 0;
			int eqp_str_req = 0;
			int eqp_int_req = 0;
			int eqp_wis_req = 0;
			int eqp_dex_req = 0;
			int eqp_con_req = 0;
*/
	 int hp_cost = 0;
	 int mp_cost = 0;
	 int mv_cost = 0;

	 hp_cost = (ch->max_hit - (ch->pcdata->perm_con * 4));
	 mp_cost = (ch->max_mana - (ch->pcdata->perm_wis * 4));
	 mv_cost = (ch->max_move - (ch->pcdata->perm_dex * 4));

	 if (IS_CLASS (ch, CLASS_HIGHLANDER))
	 {
	    if (IS_DEMPOWER (ch, HPOWER_BLADESPIN))
	       hp_cost *= 0.55;
	    if (IS_DEMPOWER (ch, HPOWER_ANCESTRAL))
	       mp_cost *= 0.55;
	    if (IS_DEMPOWER (ch, HPOWER_SWORDCRAFT))
	       mv_cost *= 0.55;
	 }

	 if (hp_cost < 1)
	    hp_cost = 1;
	 if (mp_cost < 1)
	    mp_cost = 1;
	 if (mv_cost < 1)
	    mv_cost = 1;

	 if (ch->pcdata->perm_str < max_stat)
	    stcf (ch, "#c%-20s#g : #y%d to Max, #g%d exp#y, for next.#n\n\r",
		  "Strength", (max_stat - ch->pcdata->perm_str), xp_str_cost);
	 else
	    stcf (ch, "#c%-20s#g : #y0 to Max, #g0 exp#y, for next.#n\n\r",
		  "Strength");
	 if (ch->pcdata->perm_int < max_stat)
	    stcf (ch, "#c%-20s#g : #y%d to Max, #g%d exp#y, for next.#n\n\r",
		  "Intelligence", (max_stat - ch->pcdata->perm_int),
		  xp_int_cost);
	 else
	    stcf (ch, "#c%-20s#g : #y0 to Max, #g0 exp#y, for next.#n\n\r",
		  "Intelligence");
	 if (ch->pcdata->perm_wis < max_stat)
	    stcf (ch, "#c%-20s#g : #y%d to Max, #g%d exp#y, for next.#n\n\r",
		  "Wisdom", (max_stat - ch->pcdata->perm_wis), xp_wis_cost);
	 else
	    stcf (ch, "#c%-20s#g : #y0 to Max, #g0 exp#y, for next.#n\n\r",
		  "Wisdom");
	 if (ch->pcdata->perm_dex < max_stat)
	    stcf (ch, "#c%-20s#g : #y%d to Max, #g%d exp#y, for next.#n\n\r",
		  "Dexterity", (max_stat - ch->pcdata->perm_dex),
		  xp_dex_cost);
	 else
	    stcf (ch, "#c%-20s#g : #y0 to Max, #g0 exp#y, for next.#n\n\r",
		  "Dexterity");
	 if (ch->pcdata->perm_con < max_stat)
	    stcf (ch, "#c%-20s#g : #y%d to Max, #g%d exp#y, for next.#n\n\r",
		  "Constitution", (max_stat - ch->pcdata->perm_con),
		  xp_con_cost);
	 else
	    stcf (ch, "#c%-20s#g : #y0 to Max, #g0 exp#y, for next.#n\n\r",
		  "Constitution");
	 stc ("\n\r", ch);

         if (ch->max_hit < (statcap + ch->xhit))
	    stcf (ch,
		  "#c%-20s#g : #g%d exp#y.  %d points away from Stamina Cap.#n\n\r",
                  "Stamina  (HP)", hp_cost, ((statcap + ch->xhit) - ch->max_hit));
	 else
	    stcf (ch,
		  "#c%-20s#g : #g%d exp#y.  You are at your Stamina Cap.#n\n\r",
		  "Stamina  (HP)", 0);

         if (ch->max_mana < (statcap + ch->xmana))
	    stcf (ch,
		  "#c%-20s#g : #g%d exp#y.  %d points away from Spirit Cap.#n\n\r",
                  "Spirit   (MP)", mp_cost, ((statcap + ch->xmana) - ch->max_mana));
	 else
	    stcf (ch,
		  "#c%-20s#g : #g%d exp#y.  You are at your Spirit Cap.#n\n\r",
		  "Spirit   (MP)", 0);

         if (ch->max_move < (statcap + ch->xmove))
	    stcf (ch,
		  "#c%-20s#g : #g%d exp#y.  %d points away from Vitality Cap.#n\n\r",
                  "Vitality (MV)", mv_cost, ((statcap + ch->xmove) - ch->max_move));
	 else
	    stcf (ch,
		  "#c%-20s#g : #g%d exp#y.  You are at your Vitality Cap.#n\n\r",
		  "Vitality (MV)", 0);

	 stc ("\n\r", ch);
      }

      if (ch->level <= 2)
      {
	 int the_cost = 0;

	 seren_banner_to_char ("PK READINESS", ch);
	 if (ch->level == 1)
	 {
	    stcf (ch, "#c%-20s#g : #y<--- You.#n\n\r", "Newbie", the_cost);
	 }
	 if (ch->level == 2)
	 {
	    if (ch->lstatus < 4)
	       the_cost = 4000;
	    else if (ch->lstatus < 6)
	       the_cost = 2000;
	    else if (ch->lstatus < 8)
	       the_cost = 1000;
	    else if (ch->lstatus < 10)
	       the_cost = 500;
	    else
	       the_cost = 0;
	    stcf (ch, "#c%-20s#g : #g%d exp#y.#n\n\r", "Avatar", the_cost);
	 }

	 if ((ch->level >= 3)
	     && ((ch->race < 1) && (ch->class == CLASS_NONE)
		 && (!IS_IMMORTAL (ch))))
	    stcf (ch, "#c%-20s#g : #g%d exp#y.#n\n\r", "Mortal", 0);
	 else if (IS_IMMORTAL (ch))
	    stcf (ch, "#c%-20s#g : #g%d exp#y.#n\n\r", "Mortal", 0);
	 stc ("\n\r", ch);
      }

      seren_banner_to_char ("QUEST/CLASS", ch);
      {
	 int the_cost = 0;

	 the_cost = (ch->practice + 1) * 500;
	 if (ch->practice < 9999)
	    stcf (ch, "#c%-20s#g : #g%d exp#y.  %d to Max.#n\n\r",
		  "Primal Energy", the_cost, (9999 - ch->practice));
	 else
	    stcf (ch, "#c%-20s#g : #y0 exp.  At Maximum.#n\n\r",
		  "Primal Energy");

	 if (IS_CLASS (ch, CLASS_WEREWOLF))
	 {
	    the_cost = (ch->pcdata->powers[WPOWER_SILVER] + 1) * 2500;
	    if (ch->pcdata->powers[WPOWER_SILVER] < 100)
	       stcf (ch, "#c%-20s#g : #g%d exp#y.  %d to Max.#n\n\r",
		     "Silver Tolerance", the_cost,
		     (100 - ch->pcdata->powers[WPOWER_SILVER]));
	    else
	       stcf (ch, "#c%-20s#g : #y0 exp.  At Maximum.#n\n\r",
		     "Silver Tolerance");

	    the_cost = (ch->gnosis[GMAXIMUM] + 1) * 25000;
	    if (ch->gnosis[GMAXIMUM] < 20)
	       stcf (ch, "#c%-20s#g : #g%d exp#y.  %d to Max.#n\n\r",
		     "Gnosis Points", the_cost, (20 - ch->gnosis[GMAXIMUM]));
	    else
	       stcf (ch, "#c%-20s#g : #y0 exp.  At Maximum.#n\n\r",
		     "Gnosis Points");

	 }

	 if (IS_CLASS (ch, CLASS_MONK))
	 {
	    the_cost = (ch->focus[MAXIMUM] + 1) * 50000;
	    if (ch->focus[MAXIMUM] < 100)
	       stcf (ch, "#c%-20s#g : #g%d exp#y.  %d to Max.#n\n\r",
		     "Mental Focus", the_cost, (100 - ch->focus[MAXIMUM]));
	    else
	       stcf (ch, "#c%-20s#g : #y0 exp.  At Maximum.#n\n\r",
		     "Mental Focus");
	 }

	 if (IS_CLASS (ch, CLASS_HIGHLANDER))
	 {
	    int work_amt =
	       (((ch->quickening[1] + 1) * ((ch->quickening[1] + 1) +
					    1)) / 2);
	    int the_xp_cost = 0;
	    int the_qp_cost = 0;

	    if (work_amt == 0)
	       work_amt = 1;

	    the_xp_cost = work_amt * 100000;
	    the_qp_cost = work_amt * 50;

	    if (ch->quickening[1] < 50)
	       stcf (ch,
		     "#c%-20s#g : #g%d exp and %d quest points#y.  %d to Max.#n\n\r",
		     "Quickening", the_xp_cost, the_qp_cost,
		     (50 - ch->quickening[1]));
	    else
	       stcf (ch,
		     "#c%-20s#g : #g0 exp and 0 quest points#y.  At Maximum.#n\n\r",
		     "Quickening");
	 }

	 if (IS_CLASS (ch, CLASS_DRAGON))
	 {
	    the_cost = (ch->pcdata->dragonage + 1) * 3000000;
            if (ch->pcdata->dragonage < SUPREME && ch->pcdata->dragonage == GET_AGE(ch))
	       stcf (ch, "#c%-20s#g : #g%d exp#y.  %d to Oldest.#n\n\r",
		     "Dragonage", the_cost,
		     (SUPREME - ch->pcdata->dragonage));
	    else
	       stcf (ch, "#c%-20s#g : #y0 exp.  At Oldest.#n\n\r",
		     "Dragonage");
	 }

	 if (IS_CLASS (ch, CLASS_VAMPIRE))
	 {
	    the_cost = (ch->pcdata->rank + 1) * 2500000;
	    if (ch->pcdata->rank < AGE_METHUSELAH)
	       stcf (ch,
		     "#c%-20s#g : #g%d exp#y.  %d to Moste Anciente.#n\n\r",
		     "Vampiric Lineage", the_cost,
		     (AGE_METHUSELAH - ch->pcdata->rank));
	    else
	       stcf (ch, "#c%-20s#g : #y0 exp.  At Moste Anciente.#n\n\r",
		     "Vampiric Lineage");
	 }

	 if (IS_CLASS (ch, CLASS_DROW))
	 {
	    the_cost = (ch->pcdata->stats[DROW_MAGIC] + 1) * 100;
	    if (ch->pcdata->stats[DROW_MAGIC] < 100)
	       stcf (ch, "#c%-20s#g : #y%d drow points.  %d to Max.#n\n\r",
		     "Magic Resistance", the_cost,
		     (100 - ch->pcdata->stats[DROW_MAGIC]));
	    else
	       stcf (ch, "#c%-20s#g : #y0 drow points.  At Max.#n\n\r",
		     "Magic Resistance");
	 }

	 stc ("\n\r", ch);
      }

      seren_banner_to_char ("LEGENDARY RENOWN", ch);
      {
	 int the_lexp = (2000000 + (3000000 * ch->lstatus));
	 int the_lquest = (1000 * ch->lstatus);
	 int the_learnt = 0;

	 switch (ch->lstatus + 1)
	 {
	 default:
	    sprintf (legbuf, "Unknown");
	    break;
	 case 1:
	    sprintf (legbuf, "Citizen");
	    the_learnt = 0;
	    break;
	 case 2:
	    sprintf (legbuf, "Savior");
	    the_learnt = 1000;
	    break;
	 case 3:
	    sprintf (legbuf, "Myth");
	    the_learnt = 3000;
	    break;
	 case 4:
	    sprintf (legbuf, "Legend");
	    the_learnt = 6000;
	    break;
	 case 5:
	    sprintf (legbuf, "Titan");
	    the_learnt = 10000;
	    break;
	 case 6:
	    sprintf (legbuf, "Immortal");
	    the_learnt = 15000;
	    break;
	 case 7:
	    sprintf (legbuf, "Oracle");
	    the_learnt = 21000;
	    break;
	 case 8:
	    sprintf (legbuf, "Demi God");
	    the_learnt = 28000;
	    break;
	 case 9:
	    sprintf (legbuf, "Deity");
	    the_learnt = 36000;
	    break;
	 case 10:
	    sprintf (legbuf, "Almighty");
	    the_learnt = 45000;
	    break;
	 }

	 if (ch->lstatus < 10)
	    stcf (ch,
		  "#c%-20s#g : #y%d to Max, #g%d exp#y, %d(%d) qp(earned) for %s.#n\n\r",
		  "Legendary Status", (10 - ch->lstatus), the_lexp,
		  the_lquest, the_learnt, legbuf);
	 else
	    stcf (ch,
		  "#c%-20s#g : #yAt Max, 0 exp, 0(0) qp(earned) for next.#n\n\r",
		  "Legendary Status");

	 stc ("\n\r", ch);
      }

      seren_banner_to_char ("RESISTANCES", ch);
      {
	 int the_imm_tot = 0;
	 int imm_xp_cost = 0;
	 int imm_qp_cost = 0;
	 int weapcount = 0;
	 int magicount = 0;
	 int affecount = 0;
	 int skilcount = 0;

	 the_imm_tot = count_imms (ch);
	 imm_xp_cost = (the_imm_tot + 1) * 25000;
//                      imm_qp_cost = ( the_imm_tot + 1 ) * 25;
	 imm_qp_cost = 0;
	 if (!IS_IMMUNE (ch, IMM_SLASH))
	    weapcount++;
	 if (!IS_IMMUNE (ch, IMM_STAB))
	    weapcount++;
	 if (!IS_IMMUNE (ch, IMM_SMASH))
	    weapcount++;
	 if (!IS_IMMUNE (ch, IMM_ANIMAL))
	    weapcount++;
	 if (!IS_IMMUNE (ch, IMM_MISC))
	    weapcount++;

	 if (!IS_IMMUNE (ch, IMM_HEAT))
	    magicount++;
	 if (!IS_IMMUNE (ch, IMM_COLD))
	    magicount++;
	 if (!IS_IMMUNE (ch, IMM_LIGHTNING))
	    magicount++;
	 if (!IS_IMMUNE (ch, IMM_ACID))
	    magicount++;
	 if (!IS_IMMUNE (ch, IMM_DRAIN))
	    magicount++;

	 if (!IS_IMMUNE (ch, IMM_CHARM))
	    affecount++;
	 if (!IS_IMMUNE (ch, IMM_SLEEP))
	    affecount++;
	 if (!IS_IMMUNE (ch, IMM_VOODOO))
	    affecount++;

	 if (!IS_IMMUNE (ch, IMM_HURL))
	    skilcount++;
	 if (!IS_IMMUNE (ch, IMM_BACKSTAB))
	    skilcount++;
	 if (!IS_IMMUNE (ch, IMM_KICK))
	    skilcount++;
	 if (!IS_IMMUNE (ch, IMM_DISARM))
	    skilcount++;
	 if (!IS_IMMUNE (ch, IMM_STEAL))
	    skilcount++;

	 stcf (ch, "#c%-20s#g : #y", "WEAPONS");
	 if (weapcount)
	 {
	    if (!IS_IMMUNE (ch, IMM_SLASH))
	    {
	       send_to_char ("#wSlash", ch);
	       weapcount--;
	       if (weapcount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_STAB))
	    {
	       send_to_char ("#wStab", ch);
	       weapcount--;
	       if (weapcount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_SMASH))
	    {
	       send_to_char ("#wSmash", ch);
	       weapcount--;
	       if (weapcount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_ANIMAL))
	    {
	       send_to_char ("#wBeast", ch);
	       weapcount--;
	       if (weapcount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_MISC))
	       send_to_char ("#wBind", ch);
	 }
	 else
	    stc ("Finished.", ch);

	 stc ("\n\r", ch);
//                      divide6_to_char( ch );
	 stcf (ch, "#c%-20s#g : #y", "MAGICS");
	 if (magicount)
	 {
	    if (!IS_IMMUNE (ch, IMM_HEAT))
	    {
	       send_to_char ("#wFire", ch);
	       magicount--;
	       if (magicount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_COLD))
	    {
	       send_to_char ("#wWater", ch);
	       magicount--;
	       if (magicount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_LIGHTNING))
	    {
	       send_to_char ("#wWind", ch);
	       magicount--;
	       if (magicount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_ACID))
	    {
	       send_to_char ("#wEarth", ch);
	       magicount--;
	       if (magicount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_DRAIN))
	       send_to_char ("#wDark", ch);
	 }
	 else
	    stc ("Finished.", ch);

	 stc ("\n\r", ch);
//                      divide6_to_char( ch );
	 stcf (ch, "#c%-20s#g : #y", "AFFECTS");
	 if (affecount)
	 {
	    if (!IS_IMMUNE (ch, IMM_CHARM))
	    {
	       send_to_char ("#wControl", ch);
	       affecount--;
	       if (affecount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_SLEEP))
	    {
	       send_to_char ("#wEnchant", ch);
	       affecount--;
	       if (affecount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_VOODOO))
	       send_to_char ("#wVoodoo", ch);
	 }
	 else
	    stc ("Finished.", ch);

	 stc ("\n\r", ch);
//                      divide6_to_char( ch );
	 stcf (ch, "#c%-20s#g : #y", "SKILLS");
	 if (skilcount)
	 {
	    if (!IS_IMMUNE (ch, IMM_HURL))
	    {
	       send_to_char ("#wHurl", ch);
	       skilcount--;
	       if (skilcount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_BACKSTAB))
	    {
	       send_to_char ("#wBackstab", ch);
	       skilcount--;
	       if (skilcount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_KICK))
	    {
	       send_to_char ("#wPhysical", ch);
	       skilcount--;
	       if (skilcount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_DISARM))
	    {
	       send_to_char ("#wDisarm", ch);
	       skilcount--;
	       if (skilcount)
		  stc (", ", ch);
	    }
	    if (!IS_IMMUNE (ch, IMM_STEAL))
	       send_to_char ("#wSteal", ch);
	 }
	 else
	    stc ("Finished.", ch);

	 stc ("\n\r", ch);
	 if (the_imm_tot < 18)
	    stcf (ch, "#c%-20s   %d Remain, #g%d exp#y, for next resistance",
		  "", (18 - the_imm_tot), imm_xp_cost);
	 else
	    stcf (ch, "#c%-20s   0 Remain, 0 exp, for next resistance", "");

	 stc ("\n\r", ch);
	 stc ("#R -----------------------------------------------------------------------------#n\n\r", ch);
      }
      return;
   }

   if (!str_prefix (arg1, "strength"))
      is_ok = TRUE;
   else if (!str_prefix (arg1, "intelligence"))
      is_ok = TRUE;
   else if (!str_prefix (arg1, "wisdom"))
      is_ok = TRUE;
   else if (!str_prefix (arg1, "dexterity"))
      is_ok = TRUE;
   else if (!str_prefix (arg1, "constitution"))
      is_ok = TRUE;
   else if (!str_cmp (arg1, "hp") || !str_cmp (arg1, "stamina"))
      is_ok = TRUE;
   else if (!str_cmp (arg1, "mana") || !str_cmp (arg1, "spirit"))
      is_ok = TRUE;
   else if (!str_cmp (arg1, "move") || !str_cmp (arg1, "vitality"))
      is_ok = TRUE;
   else if (!str_cmp (arg1, "primal"))
      is_ok = TRUE;
   else if (!str_cmp (arg1, "legend"))
      is_ok = TRUE;
   else
      is_ok = FALSE;

   if (IS_CLASS (ch, CLASS_WEREWOLF))
   {
      if (!str_cmp (arg1, "silver"))
	 is_ok = TRUE;
      if (!str_cmp (arg1, "gnosis"))
	 is_ok = TRUE;
   }

   if (IS_CLASS (ch, CLASS_MONK))
   {
      if (!str_cmp (arg1, "focus"))
	 is_ok = TRUE;
   }

   if (IS_CLASS (ch, CLASS_VAMPIRE))
   {
      if (!str_cmp (arg1, "lineage"))
	 is_ok = TRUE;
   }

   if (IS_CLASS (ch, CLASS_DROW))
   {
      if (!str_cmp (arg1, "magic"))
	 is_ok = TRUE;
   }

   if (IS_CLASS (ch, CLASS_DRAGON))
   {
      if ((!str_cmp (arg1, "dragonage")) && ch->pcdata->dragonage < SUPREME && ch->pcdata->dragonage == GET_AGE(ch))
	 is_ok = TRUE;
   }

   if (IS_CLASS (ch, CLASS_HIGHLANDER))
   {
      if (!str_cmp (arg1, "quickening"))
	 is_ok = TRUE;
   }

   if ((arg2[0] != '\0') && (is_ok))
   {
      amount = 0;

      if (!str_cmp (arg2, "all"))
	 train_all = TRUE;

      if ((!is_number (arg2)) && (!train_all))
      {
	 send_to_char ("Please enter a numeric value.#n\n\r", ch);
	 return;
      }

      if (!train_all)
	 amount = atoi (arg2);

      if (((str_cmp (arg1, "hp")) && (str_cmp (arg1, "mana"))
	   && (str_cmp (arg1, "move"))) && ((str_cmp (arg1, "stamina"))
					    && (str_cmp (arg1, "spirit"))
					    && (str_cmp (arg1, "vitality"))))
      {
	 if (train_all)
	 {
	    stcf (ch,
		  "You can't use train all with %s, only hp/mana/move.#n\n\r",
		  arg1);
	    return;
	 }
	 if ((amount < 1) || (amount > 250))
	 {
	    send_to_char ("Please enter a value between 1 and 250.#n\n\r",
			  ch);
	    return;
	 }
      }
      else
      {
	 if (!train_all)
	 {
	    if (amount < 1 || amount > 1000)
	    {
	       send_to_char ("Please enter a value between 1 and 1000.#n\n\r",
			     ch);
	       return;
	    }
	 }
      }
   }

   if (!str_prefix (arg1, "strength"))
   {
      pAbility = &ch->pcdata->perm_str;
      pOutput = "strength";
      VITALS_TRAIN = TRUE;
   }
   else if (!str_prefix (arg1, "intelligence"))
   {
      pAbility = &ch->pcdata->perm_int;
      pOutput = "intelligence";
      VITALS_TRAIN = TRUE;
   }
   else if (!str_prefix (arg1, "wisdom"))
   {
      pAbility = &ch->pcdata->perm_wis;
      pOutput = "wisdom";
      VITALS_TRAIN = TRUE;
   }
   else if (!str_prefix (arg1, "dexterity"))
   {
      pAbility = &ch->pcdata->perm_dex;
      pOutput = "dexterity";
      VITALS_TRAIN = TRUE;
   }
   else if (!str_prefix (arg1, "constitution"))
   {
      pAbility = &ch->pcdata->perm_con;
      pOutput = "constitution";
      VITALS_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, vitals didn't change.
      VITALS_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (VITALS_TRAIN)
   {
      bool FAIL = FALSE;
      trained_amount = 0;

      if ((*pAbility + amount) > max_stat)
	 amount = max_stat - *pAbility;
      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

/*		y = x+1; (y(y+1)/2)*25
x=0     y = 0+1; (y(y+1)/2)*25 -> y = 1; (y(y+1)/2)*25 -> (1(1+1)/2)*25 -> (1(2)/2)*25 -> ( 2/2)*25 ->  1*25 ->  25
x=1     y = 1+1; (y(y+1)/2)*25 -> y = 2; (y(y+1)/2)*25 -> (2(2+1)/2)*25 -> (2(3)/2)*25 -> ( 6/2)*25 ->  3*25 ->  75
x=2     y = 2+1; (y(y+1)/2)*25 -> y = 3; (y(y+1)/2)*25 -> (3(3+1)/2)*25 -> (3(4)/2)*25 -> (12/2)*25 ->  6*25 -> 150
x=3     y = 3+1; (y(y+1)/2)*25 -> y = 4; (y(y+1)/2)*25 -> (4(4+1)/2)*25 -> (4(5)/2)*25 -> (20/2)*25 -> 10*25 -> 250
x=4     y = 4+1; (y(y+1)/2)*25 -> y = 5; (y(y+1)/2)*25 -> (5(5+1)/2)*25 -> (5(6)/2)*25 -> (30/2)*25 -> 15*25 -> 375
*/
      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 xp_cost = ((*pAbility + 1) * 500);
	 qp_cost = ((*pAbility + 1) * 25);
	 earnt_qp = (((*pAbility + 1) * ((*pAbility + 1) + 1) / 2) * 25);

	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
/*
			if ( ch->pcdata->quest < qp_cost )
			{
				combo_var = qp_cost - ch->pcdata->quest;
				FAIL = TRUE;
				stcf( ch, "You need another %d quest points to increase %s from %d to %d.#n\n\r", combo_var, pOutput, *pAbility, ( *pAbility + 1 ) );
			}
			if ( ch->pcdata->score[SCORE_QUEST] < earnt_qp )
			{
				combo_var = earnt_qp - ch->pcdata->score[SCORE_QUEST];
				FAIL = TRUE;
				stcf( ch, "You need another#g %d earned quest points to increase %s from %d to %d.#n\n\r", combo_var, pOutput, *pAbility, ( *pAbility + 1 ) );
			}
*/
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
//                              ch->pcdata->quest -= qp_cost;
	    *pAbility += 1;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s by %d points.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for VITALS_TRAIN, let's do HPMPMV_TRAIN next.
   if (!str_cmp (arg1, "hp") || !str_cmp (arg1, "stamina"))
   {
      pAbility = &ch->max_hit;
      pOutput = "stamina";
      HPMPMV_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "mana") || !str_cmp (arg1, "spirit"))
   {
      pAbility = &ch->max_mana;
      pOutput = "spirit";
      HPMPMV_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "move") || !str_cmp (arg1, "vitality"))
   {
      pAbility = &ch->max_move;
      pOutput = "vitality";
      HPMPMV_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, HPMPMV didn't change.
      HPMPMV_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (HPMPMV_TRAIN)
   {
      int newstatcap = statcap;
      bool FAIL = FALSE;
      trained_amount = 0;

      if (!str_cmp(pOutput, "stamina"))
         newstatcap += ch->xhit;
      else if (!str_cmp(pOutput, "spirit"))
         newstatcap += ch->xmana;
      else if (!str_cmp(pOutput, "vitality"))
         newstatcap += ch->xmove;

      if ((*pAbility + amount) > newstatcap)
         amount = newstatcap - *pAbility;

      if ((amount <= 0) && (!train_all))
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      if (train_all)
	 amount = 150000;
      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 if (!str_cmp (arg1, "hp"))
            xp_cost = ((ch->max_hit - ch->xhit) - (ch->pcdata->perm_con * 4));
	 if (!str_cmp (arg1, "stamina"))
            xp_cost = ((ch->max_hit - ch->xhit) - (ch->pcdata->perm_con * 4));
	 if (!str_cmp (arg1, "mana"))
            xp_cost = ((ch->max_mana - ch->xmana) - (ch->pcdata->perm_wis * 4));
	 if (!str_cmp (arg1, "spirit"))
            xp_cost = ((ch->max_mana - ch->xmana) - (ch->pcdata->perm_wis * 4));
	 if (!str_cmp (arg1, "move"))
            xp_cost = ((ch->max_move - ch->xmove) - (ch->pcdata->perm_dex * 4));
	 if (!str_cmp (arg1, "vitality"))
            xp_cost = ((ch->max_move - ch->xmove) - (ch->pcdata->perm_dex * 4));
	 if (IS_CLASS (ch, CLASS_HIGHLANDER))
	 {
	    if ((IS_DEMPOWER (ch, HPOWER_BLADESPIN))
		&& (!str_cmp (arg1, "hp")))
	       xp_cost *= 0.55;
	    if ((IS_DEMPOWER (ch, HPOWER_ANCESTRAL))
		&& (!str_cmp (arg1, "mana")))
	       xp_cost *= 0.55;
	    if ((IS_DEMPOWER (ch, HPOWER_SWORDCRAFT))
		&& (!str_cmp (arg1, "move")))
	       xp_cost *= 0.55;
	    if ((IS_DEMPOWER (ch, HPOWER_BLADESPIN))
		&& (!str_cmp (arg1, "stamina")))
	       xp_cost *= 0.55;
	    if ((IS_DEMPOWER (ch, HPOWER_ANCESTRAL))
		&& (!str_cmp (arg1, "spirit")))
	       xp_cost *= 0.55;
	    if ((IS_DEMPOWER (ch, HPOWER_SWORDCRAFT))
		&& (!str_cmp (arg1, "vitality")))
	       xp_cost *= 0.55;
	 }
	 if (xp_cost < 1)
	    xp_cost = 1;

	 if (FAIL)
	    continue;
         if ((*pAbility) >= newstatcap)
	    FAIL = TRUE;

	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    *pAbility += 1;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s by %d points.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for HPMPMV_TRAIN, let's do PRIMAL_TRAIN next.
   if (!str_cmp (arg1, "primal"))
   {
      pAbility = &ch->practice;
      pOutput = "primal energy";
      PRIMAL_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, primal didn't change.
      PRIMAL_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (PRIMAL_TRAIN)
   {
      bool FAIL = FALSE;
      trained_amount = 0;

      if ((*pAbility + amount) > 9999)
	 amount = 9999 - *pAbility;
      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 xp_cost = (*pAbility + 1) * 500;
	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    *pAbility += 1;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s by %d points.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for PRIMAL_TRAIN, let's do STATUS_TRAIN next.
   if (!str_cmp (arg1, "legend"))
   {
      pAbility = &ch->lstatus;
      pOutput = "legendary reknown";
      STATUS_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, legend didn't change.
      STATUS_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (STATUS_TRAIN)
   {
      bool FAIL = FALSE;
      trained_amount = 0;

      if ((*pAbility + amount) > 10)
	 amount = 10 - *pAbility;

      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 if (FAIL)
	    continue;

	 xp_cost = (2000000 + (3000000 * ch->lstatus));
	 qp_cost = (1000 * ch->lstatus);

	 if (ch->lstatus == 0)
	    earnt_qp = 0;
	 if (ch->lstatus == 1)
	    earnt_qp = 1000;
	 if (ch->lstatus == 2)
	    earnt_qp = 3000;
	 if (ch->lstatus == 3)
	    earnt_qp = 6000;
	 if (ch->lstatus == 4)
	    earnt_qp = 10000;
	 if (ch->lstatus == 5)
	    earnt_qp = 15000;
	 if (ch->lstatus == 6)
	    earnt_qp = 21000;
	 if (ch->lstatus == 7)
	    earnt_qp = 28000;
	 if (ch->lstatus == 8)
	    earnt_qp = 36000;
	 if (ch->lstatus == 9)
	    earnt_qp = 45000;
/*
	 if (ch->lstatus == 10)
	 {
	    xp_cost = 2000000000;	// 2.00 billion Exp                                             -- Serenity
	    qp_cost = 500000;	// 0.50 million Qp on Hand                              -- Serenity
	    earnt_qp = 750000;	// 0.75 million Qp earned                               -- Serenity
	 }
*/
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (ch->pcdata->quest < qp_cost)
	 {
	    combo_var = qp_cost - ch->pcdata->quest;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another %d quest points to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (ch->pcdata->score[SCORE_QUEST] < earnt_qp)
	 {
	    combo_var = earnt_qp - ch->pcdata->score[SCORE_QUEST];
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d earned quest points to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (ch->lstatus == 10)
	 {
	    if (ch->max_hit < 150000)
	    {
	       combo_var = 150000 - ch->max_hit;
	       FAIL = TRUE;
	       stcf (ch,
		     "You need another#g %d stamina to increase %s from %d to %d.#n\n\r",
		     combo_var, pOutput, *pAbility, (*pAbility + 1));
	    }
	    if (ch->max_mana < 150000)
	    {
	       combo_var = 150000 - ch->max_mana;
	       FAIL = TRUE;
	       stcf (ch,
		     "You need another#g %d spirit to increase %s from %d to %d.#n\n\r",
		     combo_var, pOutput, *pAbility, (*pAbility + 1));
	    }
	    if (ch->max_move < 150000)
	    {
	       combo_var = 150000 - ch->max_move;
	       FAIL = TRUE;
	       stcf (ch,
		     "You need another#g %d vitality to increase %s from %d to %d.#n\n\r",
		     combo_var, pOutput, *pAbility, (*pAbility + 1));
	    }
	 }
	 if (!FAIL)
	 {
	    char announce_buf[500];

	    switch (ch->lstatus + 1)
	    {
	    default:
	       sprintf (legbuf, "Unknown");
	       break;
	    case 1:
	       sprintf (legbuf, "a Citizen");
	       break;
	    case 2:
	       sprintf (legbuf, "a Savior");
	       break;
	    case 3:
	       sprintf (legbuf, "a Myth");
	       break;
	    case 4:
	       sprintf (legbuf, "a Legend");
	       break;
	    case 5:
	       sprintf (legbuf, "a Titan");
	       break;
	    case 6:
	       sprintf (legbuf, "an Immortal");
	       break;
	    case 7:
	       sprintf (legbuf, "an Oracle");
	       break;
	    case 8:
	       sprintf (legbuf, "a Demi God");
	       break;
	    case 9:
	       sprintf (legbuf, "a Deity");
	       break;
	    case 10:
	       sprintf (legbuf, "an Almighty Entity");
	       break;
	    }
	    trained_amount++;
	    ch->exp -= xp_cost;
	    ch->pcdata->quest -= qp_cost;
	    *pAbility += 1;
	    sprintf (announce_buf, "#r%s #wis %s", ch->name, legbuf);
	    do_legend_announce (ch, announce_buf);
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s by %d points.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for STATUS_TRAIN, let's do AVATAR_TRAIN next.
   if (!str_cmp (arg1, "avatar"))
   {
      pAbility = &ch->level;
      pOutput = "pk readiness";
      AVATAR_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, avatar didn't change.
      AVATAR_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (AVATAR_TRAIN)
   {
      bool FAIL = FALSE;
      char avatar_buf[1500];

      trained_amount = 0;
      amount = 1;

      if ((*pAbility + amount) > 3)
	 amount = 3 - *pAbility;

      if (*pAbility == 1)
      {
	 stcf (ch,
	       "Your %s should not be a matter of concern to you at this time.#n\n\r",
	       pOutput);
	 return;
      }

      if (*pAbility != 2)
	 amount = 0;

      if (amount > 1)
	 amount = 1;

      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 if (ch->lstatus < 4)
	    xp_cost = 4000;
	 else if (ch->lstatus < 6)
	    xp_cost = 2000;
	 else if (ch->lstatus < 8)
	    xp_cost = 1000;
	 else if (ch->lstatus < 10)
	    xp_cost = 500;
	 else
	    xp_cost = 0;

	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    *pAbility += 1;

	    if (IS_CLASS (ch, CLASS_DEMON))
	       ch->alignment = -1000;
	    if (IS_CLASS (ch, CLASS_HIGHLANDER))
	    {
	       do_remove (ch, "all");
	       do_wear (ch, "all");
	    }

	    ch->captimer = 0;

	    if (ch->level < ch->trust)
	       ch->level = ch->trust;

	    if (!IS_NPC (ch) && IS_VAMPAFF (ch, VAM_MORTAL))
	       do_mortalvamp (ch, "");

	    if (IS_CLASS (ch, CLASS_DEMON))
	       sprintf (avatar_buf, "#r%s #whas embraced Lucifer as father.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_MAGE))
	       sprintf (avatar_buf,
			"#r%s #whas once again hit the library for books.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_WEREWOLF))
	       sprintf (avatar_buf, "#r%s #whas joined the fight for Gaia.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_VAMPIRE))
	       sprintf (avatar_buf, "#r%s #whas let the beast consume them.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_HIGHLANDER))
	    {
	       sprintf (avatar_buf,
			"#r%s #whas taken up the sacred arts of the katana.",
			ch->name);
	       clear_stats (ch);
	    }
	    else if (IS_CLASS (ch, CLASS_DROW))
	       sprintf (avatar_buf,
			"#r%s #whas selected Lloth as guide and guardian.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_MONK))
	       sprintf (avatar_buf,
			"#r%s #whas left the monastary seeking enlightenment.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_DRAGON))
	       sprintf (avatar_buf,
			"#r%s #whas transformed into a gigantic Wyrm.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_NINJA))
	       sprintf (avatar_buf, "#r%s #whas vanished into the night.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_FAE))
	       sprintf (avatar_buf,
			"#r%s #whas rejoined the dreaming and faerie court.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_CHOOSE))
	       sprintf (avatar_buf,
			"#r%s #whas rejoined the dreaming and faerie court.",
			ch->name);
	    else if (IS_CLASS (ch, CLASS_WRAITH))
	       sprintf (avatar_buf, "#r%s #whas died... Again.", ch->name);
	    else
	       sprintf (avatar_buf,
			"#r%s #whas become an avatar.#n",
			ch->name);

	    do_avatar_announce (ch, avatar_buf);
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch, "You were unable to increase your %s.#n\n\r", pOutput);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s to maximum.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for AVATAR_TRAIN, let's do MORTAL_TRAIN next.
   if (!str_cmp (arg1, "mortal"))
   {
      if (IS_IMMORTAL (ch))
      {
	 stc ("Immortals have no need to train mortal!\n\r", ch);
	 return;
      }
      pAbility = &ch->level;
      pOutput = "mortality";
      MORTAL_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, mortality didn't change.
      MORTAL_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (MORTAL_TRAIN)
   {
      bool FAIL = FALSE;
      trained_amount = 0;

      xp_cost = 0;
      amount = *pAbility - 2;

      if ((*pAbility - amount) < 2)
	 amount = *pAbility - 2;

      if (*pAbility == 1)
      {
	 stcf (ch,
	       "Your %s should not be a matter of concern to you at this time.#n\n\r",
	       pOutput);
	 return;
      }

      if (*pAbility == 2)
	 amount = 0;

      if ((ch->race > 0) && (!IS_IMMORTAL (ch)))
      {
	 stcf (ch, "You can't embrace %s fully while you have status.#n\n\r",
	       pOutput);
	 return;
      }

      if (ch->fight_timer > 0)
      {
	 send_to_char ("Not until your fight timer expires.#n\n\r", ch);
	 return;
      }

      if (IS_SET (ch->war, WARRING))
      {
	 stc ("Not while in a war!\n\r", ch);
	 return;
      }

      if (IS_SET (ch->flag2, AFF2_INARENA))
      {
	 stc ("Not while you're in the arena.#n\n\r", ch);
	 return;
      }

      if ((ch->class != CLASS_NONE) && (!IS_IMMORTAL (ch)))
      {
	 stcf (ch, "You are unable to embrace %s any longer.#n\n\r", pOutput);
	 return;
      }

      if (amount <= 0)
      {
	 stcf (ch, "You've already embraced your %s.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {

	 if (ch->lstatus < 4)
	    xp_cost = 4000;
	 else if (ch->lstatus < 6)
	    xp_cost = 2000;
	 else if (ch->lstatus < 8)
	    xp_cost = 1000;
	 else if (ch->lstatus < 10)
	    xp_cost = 500;
	 else
	    xp_cost = 0;

	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to embrace your %s.#n\n\r",
		  combo_var, pOutput);
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    ch->level = 2;
	    ch->trust = 0;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch, "You were unable to embrace your %s.#n\n\r", pOutput);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to emrabce your %s.#n\n\r", pOutput);
      else
	 stcf (ch, "You embraced your %s.#n\n\r", pOutput);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for MORTAL_TRAIN, let's do AMAGIC_TRAIN next.
   if (!str_cmp (arg1, "magic") && (IS_CLASS (ch, CLASS_DROW)))
   {
      pAbility = &ch->pcdata->stats[DROW_MAGIC];
      pOutput = "magic resistance";
      AMAGIC_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, magic resistance didn't change.
      AMAGIC_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (AMAGIC_TRAIN)
   {
      bool FAIL = FALSE;
      trained_amount = 0;

      if ((*pAbility + amount) > 100)
	 amount = 100 - *pAbility;
      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 xp_cost = (*pAbility + 1) * 100;
	 if (FAIL)
	    continue;

	 if (ch->pcdata->stats[DROW_POWER] < xp_cost)
	 {
//	    combo_var = ch->pcdata->stats[DROW_POWER] - ch->exp;
            combo_var = ch->pcdata->stats[DROW_MAGIC] + 1 * 100;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another %d drow points to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->pcdata->stats[DROW_POWER] -= combo_var;
	    *pAbility += 1;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s by %d percent.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for AMAGIC_TRAIN, let's do SILVER_TRAIN next.
   if (!str_cmp (arg1, "silver") && (IS_CLASS (ch, CLASS_WEREWOLF)))
   {
      pAbility = &ch->pcdata->powers[WPOWER_SILVER];
      pOutput = "silver tolerance";
      SILVER_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, silver tolerance didn't change.
      SILVER_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (SILVER_TRAIN)
   {
      bool FAIL = FALSE;
      trained_amount = 0;

      if ((*pAbility + amount) > 100)
	 amount = 100 - *pAbility;
      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 xp_cost = (*pAbility + 1) * 2500;
	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    *pAbility += 1;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s by %d percent.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for SILVER_TRAIN, let's do GNOSIS_TRAIN next.
   if (!str_cmp (arg1, "gnosis") && (IS_CLASS (ch, CLASS_WEREWOLF)))
   {
      pAbility = &ch->gnosis[GMAXIMUM];
      pOutput = "gnosis points";
      GNOSIS_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, gnosis didn't change.
      GNOSIS_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (GNOSIS_TRAIN)
   {
      bool FAIL = FALSE;
      trained_amount = 0;

      if ((*pAbility + amount) > 20)
	 amount = 20 - *pAbility;
      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 xp_cost = (*pAbility + 1) * 25000;
	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    *pAbility += 1;
	    ch->gnosis[GCURRENT]++;	// Associated ability
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s by %d points.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for GNOSIS_TRAIN, let's do VAMPYR_TRAIN next.
   if (!str_cmp (arg1, "lineage") && (IS_CLASS (ch, CLASS_VAMPIRE)))
   {
      pAbility = &ch->pcdata->rank;
      pOutput = "ancient lineage";
      VAMPYR_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, lineage didn't change.
      VAMPYR_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (VAMPYR_TRAIN)
   {
      bool FAIL = FALSE;
      char *word_buf;

      trained_amount = 0;

      if ((*pAbility + amount) > AGE_METHUSELAH)
	 amount = AGE_METHUSELAH - *pAbility;
      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at the best.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 switch (ch->pcdata->rank + 1)
	 {
	 default:
	    {
	       word_buf = "Unknown";
	       xp_cost = 0;
	       break;
	    }			// Free?
	 case AGE_CHILDE:
	    {
	       word_buf = "Childe";
	       xp_cost = 0;
	       break;
	    }			// Free
	 case AGE_NEONATE:
	    {
	       word_buf = "Neonate";
	       xp_cost = 2500000;
	       break;
	    }			// 2.5 mil
	 case AGE_ANCILLA:
	    {
	       word_buf = "Ancilla";
	       xp_cost = 5000000;
	       break;
	    }			// 5 mil
	 case AGE_ELDER:
	    {
	       word_buf = "Elder";
	       xp_cost = 7500000;
	       break;
	    }			// 7.5 mil
	 case AGE_METHUSELAH:
	    {
	       word_buf = "Methuselah";
	       xp_cost = 10000000;
	       break;
	    }			// 10 mil
	 }

	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to improve your %s to %s Vampire.#n\n\r",
		  combo_var, pOutput, word_buf);
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    *pAbility += 1;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You improved your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to improve your %s.#n\n\r", pOutput);
      else
	 stcf (ch, "You improved your %s by %d ranks.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }

   // Finished with checking for VAMPYR_TRAIN, let's do DRAGON_TRAIN next.
   if (str_cmp (arg1, "dragonage") || (!IS_CLASS (ch, CLASS_DRAGON)))
   {
      // Worry about something else here-after, dragonage didn't change.
      DRAGON_TRAIN = FALSE;
   }
   else
   {
      int temp = GET_AGE(ch);
      pOutput = "maturity";
      DRAGON_TRAIN = TRUE;
      bool FAIL = FALSE;
      char *age_buf[13] =
	 { "New", "Hatchling", "Dragon Whelp", "Juvenile Dragon",
"Young Adult Dragon",
	 "Adult Dragon", "Mature Adult Dragon", "Elder Dragon",
	    "Venerable Dragon",
	 "Ancient Dragon", "Lesser Wyrm", "Greater Wyrm", "Supreme Wyrm"
      };

      trained_amount = 0;

      if ((temp + amount) > ((14-ch->pcdata->stats[UNI_GEN])*2)-1)
         amount = (((14-ch->pcdata->stats[UNI_GEN])*2)-1) - temp;
      else if ((temp + amount) > SUPREME)
         amount = SUPREME - temp;

      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its limit.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
         xp_cost = (temp + 1) * 3000000;
	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcprintf (ch,
		       "You need another#g %d experience to increase your %s from %s to %s.#n\n\r",
                       combo_var, pOutput, age_buf[temp],
                       age_buf[(temp + 1)]);
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
            ch->pcdata->dragonage += 1;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d age bands you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s.#n\n\r", pOutput);
      else
	 stcf (ch, "You increased your %s by %d age bands.#n\n\r", pOutput,
	       trained_amount);

      if (ch->pcdata->dragonage > 12) ch->pcdata->dragonage = 12;

      stcprintf (ch, "You are now a %s.#n\n\r", age_buf[ch->pcdata->dragonage]);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }
   // Finished with checking for DRAGON_TRAIN, let's do MFOCUS_TRAIN next.
   if (!str_cmp (arg1, "focus") && (IS_CLASS (ch, CLASS_MONK)))
   {
      pAbility = &ch->focus[MAXIMUM];
      pOutput = "mental focus";
      MFOCUS_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, focus didn't change.
      MFOCUS_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (MFOCUS_TRAIN)
   {
      bool FAIL = FALSE;
      trained_amount = 0;

      if ((*pAbility + amount) > 100)
	 amount = 100 - *pAbility;
      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 xp_cost = (*pAbility + 1) * 50000;
	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    *pAbility += 1;
	    ch->focus[CURRENT]++;	// Associated Ability
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You increased your %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to increase your %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You increased your %s by %d points.#n\n\r", pOutput,
	       trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }
   // Finished with checking for MFOCUS_TRAIN, let's do HQUICK_TRAIN next.

   if (!str_cmp (arg1, "quickening") && (IS_CLASS (ch, CLASS_HIGHLANDER)))
   {
      pAbility = &ch->quickening[1];
      pOutput = "quickening";
      HQUICK_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, focus didn't change.
      HQUICK_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (HQUICK_TRAIN)
   {
      bool FAIL = FALSE;
      int work_amt;

      trained_amount = 0;

      if ((*pAbility + amount) > 50)
	 amount = 50 - *pAbility;

      if (ch->quickening[1] > 49)
      {
	 stc ("Go kill an avatar or something it'll be cheaper.#n\n\r", ch);
	 return;
      }

      if (!IS_DEMPOWER (ch, HPOWER_EMPOWER))
      {
	 stc ("You don't know how to improve your quickening without killing.#n\n\r", ch);
	 return;
      }

      if (amount <= 0)
      {
	 stcf (ch, "Your %s is already at its peak.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 work_amt = (((*pAbility + 1) * ((*pAbility + 1) + 1)) / 2);

	 if (work_amt == 0)
	    work_amt = 1;

	 xp_cost = work_amt * 100000;
	 qp_cost = work_amt * 50;

	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another#g %d experience to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (ch->pcdata->quest < qp_cost)
	 {
	    combo_var = qp_cost - ch->pcdata->quest;
	    FAIL = TRUE;
	    stcf (ch,
		  "You need another %d quest points to increase %s from %d to %d.#n\n\r",
		  combo_var, pOutput, *pAbility, (*pAbility + 1));
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
	    ch->pcdata->quest -= qp_cost;
	    *pAbility += 1;
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch,
	       "You improved your maximum level of %s only %d of the %d times you requested.#n\n\r",
	       pOutput, trained_amount, amount);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch,
	       "You were unable to improve your maximum level of %s at all.#n\n\r",
	       pOutput);
      else
	 stcf (ch, "You improve your maximum level of %s by %d points.#n\n\r",
	       pOutput, trained_amount);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }
   // Finished with checking for HQUICK_TRAIN, let's do IMMUNE_TRAIN next.

   if (!str_cmp (arg1, "slash"))
   {
      pOutput = "resistance to slashing weapons";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "stab"))
   {
      pOutput = "resistance to stabbing weapons";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "smash"))
   {
      pOutput = "resistance to smashing weapons";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "beast"))
   {
      pOutput = "resistance to beastial weapons";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "bind"))
   {
      pOutput = "resistance to binding weapons";
      IMMUNE_TRAIN = TRUE;
   }

   else if (!str_cmp (arg1, "fire"))
   {
      pOutput = "resistance to fire magic";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "water"))
   {
      pOutput = "resistance to water magic";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "wind"))
   {
      pOutput = "resistance to wind magic";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "earth"))
   {
      pOutput = "resistance to earth magic";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "dark"))
   {
      pOutput = "resistance to dark magic";
      IMMUNE_TRAIN = TRUE;
   }

   else if (!str_cmp (arg1, "control"))
   {
      pOutput = "resistance to controlling magics";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "enchant"))
   {
      pOutput = "resistance to enchantment spells";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "voodoo"))
   {
      pOutput = "resistance to voodoo abilities";
      IMMUNE_TRAIN = TRUE;
   }

   else if (!str_cmp (arg1, "hurl"))
   {
      pOutput = "resistance to hurling attacks";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "backstab"))
   {
      pOutput = "resistance to backstab attacks";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "physical"))
   {
      pOutput = "resistance to some physical attacks";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "disarm"))
   {
      pOutput = "better understanding of your weapon";
      IMMUNE_TRAIN = TRUE;
   }
   else if (!str_cmp (arg1, "steal"))
   {
      pOutput = "higher awareness of those around you";
      IMMUNE_TRAIN = TRUE;
   }
   else
   {
      // Worry about something else here-after, Immunities didn't change.
      IMMUNE_TRAIN = FALSE;
   }
   // after checking stats either train and quit or continue checking
   if (IMMUNE_TRAIN)
   {
      bool FAIL = FALSE;
      int train_which = 0;
      int amt_req_1 = 0;
      int amt_req_2 = 0;
      int amt_req_3 = 0;
      char *name_req_1=NULL;
      char *name_req_2=NULL;
      char *name_req_3=NULL;
      sh_int *loc_req_1=0;
      sh_int *loc_req_2=0;
      sh_int *loc_req_3=0;
      bool USE_AMT_1 = FALSE;
      bool USE_AMT_2 = FALSE;
      bool USE_AMT_3 = FALSE;

      trained_amount = 0;
      pAbility = &ch->immune;

      if (amount > 1)
	 amount = 1;

      if (!str_cmp (arg1, "slash"))
      {
	 train_which = IMM_SLASH;
	 name_req_1 = "skill with slicing weapons";
	 name_req_2 = "skill with slashing weapons";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->wpn[1];
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 175;
	 loc_req_2 = &ch->wpn[3];
	 USE_AMT_2 = TRUE;
      }
      else if (!str_cmp (arg1, "stab"))
      {
	 train_which = IMM_STAB;
	 name_req_1 = "skill with stabbing weapons";
	 name_req_2 = "skill with piercing weapons";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->wpn[2];
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 175;
	 loc_req_2 = &ch->wpn[11];
	 USE_AMT_2 = TRUE;
      }
      else if (!str_cmp (arg1, "smash"))
      {
	 train_which = IMM_SMASH;
	 name_req_1 = "skill with blasting weapons";
	 name_req_2 = "skill with pounding weapons";
	 name_req_3 = "skill with crushing weapons";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->wpn[6];
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 175;
	 loc_req_2 = &ch->wpn[7];
	 USE_AMT_2 = TRUE;
	 amt_req_3 = 175;
	 loc_req_3 = &ch->wpn[8];
	 USE_AMT_3 = TRUE;
      }
      else if (!str_cmp (arg1, "beast"))
      {
	 train_which = IMM_ANIMAL;
	 name_req_1 = "skill with claws";
	 name_req_2 = "skill with fangs";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->wpn[5];
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 175;
	 loc_req_2 = &ch->wpn[10];
	 USE_AMT_2 = TRUE;
      }
      else if (!str_cmp (arg1, "bind"))
      {
	 train_which = IMM_MISC;
	 name_req_1 = "skill with whipping weapons";
	 name_req_2 = "skill with grepping weapons";
	 name_req_3 = "skill with sucking weapons";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->wpn[4];
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 175;
	 loc_req_2 = &ch->wpn[9];
	 USE_AMT_2 = TRUE;
	 amt_req_3 = 175;
	 loc_req_3 = &ch->wpn[12];
	 USE_AMT_3 = TRUE;
      }

      else if (!str_cmp (arg1, "fire"))
      {
	 train_which = IMM_HEAT;
	 name_req_1 = "skill with red magic";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->spl[1];
	 USE_AMT_1 = TRUE;
      }
      else if (!str_cmp (arg1, "water"))
      {
	 train_which = IMM_COLD;
	 name_req_1 = "skill with blue magic";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->spl[2];
	 USE_AMT_1 = TRUE;
      }
      else if (!str_cmp (arg1, "wind"))
      {
	 train_which = IMM_LIGHTNING;
	 name_req_1 = "skill with yellow magic";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->spl[4];
	 USE_AMT_1 = TRUE;
      }
      else if (!str_cmp (arg1, "earth"))
      {
	 train_which = IMM_ACID;
	 name_req_1 = "skill with green magic";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->spl[3];
	 USE_AMT_1 = TRUE;
      }
      else if (!str_cmp (arg1, "dark"))
      {
	 train_which = IMM_DRAIN;
	 name_req_1 = "skill with purple magic";
	 amt_req_1 = 175;
	 loc_req_1 = &ch->spl[0];
	 USE_AMT_1 = TRUE;
      }

      else if (!str_cmp (arg1, "control"))
      {
	 train_which = IMM_CHARM;
	 name_req_1 = "skill with blue magic";
	 name_req_2 = "wisdom";
	 amt_req_1 = 200;
	 loc_req_1 = &ch->spl[2];
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 20;
	 loc_req_2 = &ch->pcdata->perm_wis;
	 USE_AMT_2 = TRUE;
      }
      else if (!str_cmp (arg1, "enchant"))
      {
	 train_which = IMM_SLEEP;
	 name_req_1 = "skill with green magic";
	 name_req_2 = "skill with yellow magic";
	 amt_req_1 = 200;
	 loc_req_1 = &ch->spl[3];
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 200;
	 loc_req_2 = &ch->spl[4];
	 USE_AMT_2 = TRUE;
      }
      else if (!str_cmp (arg1, "voodoo"))
      {
	 train_which = IMM_VOODOO;
	 name_req_1 = "skill with purple magic";
	 name_req_2 = "skill with red magic";
	 amt_req_1 = 200;
	 loc_req_1 = &ch->spl[0];
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 200;
	 loc_req_2 = &ch->spl[1];
	 USE_AMT_2 = TRUE;
      }
//changed the 15k req to 5k
      else if (!str_cmp (arg1, "hurl"))
      {
	 train_which = IMM_HURL;
	 name_req_1 = "stamina";
	 name_req_2 = "strength";
	 amt_req_1 = 5000;
	 loc_req_1 = &ch->max_hit;
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 20;
	 loc_req_2 = &ch->pcdata->perm_str;
	 USE_AMT_2 = TRUE;
      }
      else if (!str_cmp (arg1, "backstab"))
      {
	 train_which = IMM_BACKSTAB;
	 name_req_1 = "vitality";
	 name_req_2 = "dexterity";
	 amt_req_1 = 5000;
	 loc_req_1 = &ch->max_move;
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 20;
	 loc_req_2 = &ch->pcdata->perm_dex;
	 USE_AMT_2 = TRUE;
      }
      else if (!str_cmp (arg1, "physical"))
      {
	 train_which = IMM_KICK;
	 name_req_1 = "stamina";
	 name_req_2 = "constitution";
	 name_req_3 = "strength";
	 amt_req_1 = 5000;
	 loc_req_1 = &ch->max_hit;
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 20;
	 loc_req_2 = &ch->pcdata->perm_con;
	 USE_AMT_2 = TRUE;
	 amt_req_3 = 20;
	 loc_req_3 = &ch->pcdata->perm_str;
	 USE_AMT_3 = TRUE;
      }
      else if (!str_cmp (arg1, "disarm"))
      {
	 train_which = IMM_DISARM;
	 name_req_1 = "vitality";
	 name_req_2 = "dexterity";
	 name_req_3 = "strength";
	 amt_req_1 = 5000;
	 loc_req_1 = &ch->max_move;
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 20;
	 loc_req_2 = &ch->pcdata->perm_dex;
	 USE_AMT_2 = TRUE;
	 amt_req_3 = 20;
	 loc_req_3 = &ch->pcdata->perm_str;
	 USE_AMT_3 = TRUE;
      }
      else if (!str_cmp (arg1, "steal"))
      {
	 train_which = IMM_STEAL;
	 name_req_1 = "wisdom";
	 name_req_2 = "intelligence";
	 name_req_3 = "dexterity";
	 amt_req_1 = 20;
	 loc_req_1 = &ch->pcdata->perm_wis;
	 USE_AMT_1 = TRUE;
	 amt_req_2 = 20;
	 loc_req_2 = &ch->pcdata->perm_int;
	 USE_AMT_2 = TRUE;
	 amt_req_3 = 20;
	 loc_req_3 = &ch->pcdata->perm_dex;
	 USE_AMT_3 = TRUE;
      }

      if (IS_SET (*pAbility, train_which))
      {
	 stcf (ch, "Your already have a %s.#n\n\r", pOutput);
	 return;
      }

      for (train_loop = 0; train_loop < amount; train_loop++)
      {
	 immcost = count_imms (ch);
	 xp_cost = (immcost + 1) * 25000;
	 qp_cost = (immcost + 1) * 25;

	 if (FAIL)
	    continue;
	 if (ch->exp < xp_cost)
	 {
	    combo_var = xp_cost - ch->exp;
	    FAIL = TRUE;
	    stcf (ch, "You need another#g %d experience to gain a %s.#n\n\r",
		  combo_var, pOutput);
	 }
/*
			if ( ch->pcdata->quest < qp_cost )
			{
				combo_var = qp_cost - ch->pcdata->quest;
				FAIL = TRUE;
				stcf( ch, "You need another#g %d quest points to gain a %s.#n\n\r", combo_var, pOutput );
			}
*/
	 if (USE_AMT_1)
	 {
	    if (*loc_req_1 < amt_req_1)
	    {
	       FAIL = TRUE;
	       stcf (ch, "You need another %d %s to gain a %s.#n\n\r",
		     (amt_req_1 - *loc_req_1), name_req_1, pOutput);
	    }
	 }
	 if (USE_AMT_2)
	 {
	    if (*loc_req_2 < amt_req_2)
	    {
	       FAIL = TRUE;
	       stcf (ch, "You need another %d %s to gain a %s.#n\n\r",
		     (amt_req_2 - *loc_req_2), name_req_2, pOutput);
	    }
	 }
	 if (USE_AMT_3)
	 {
	    if (*loc_req_3 < amt_req_3)
	    {
	       FAIL = TRUE;
	       stcf (ch, "You need another %d %s to gain a %s.#n\n\r",
		     (amt_req_3 - *loc_req_3), name_req_3, pOutput);
	    }
	 }
	 if (!FAIL)
	 {
	    trained_amount++;
	    ch->exp -= xp_cost;
//                              ch->pcdata->quest -= qp_cost;
	    SET_BIT (ch->immune, train_which);
	    CHAR_DIRTY = TRUE;
	 }
      }
      if ((FAIL) && (trained_amount > 0))
	 stcf (ch, "You gained a %s.#n\n\r", pOutput);
      else if ((FAIL) && (trained_amount == 0))
	 stcf (ch, "You were unable to to gain a %s.#n\n\r", pOutput);
      else
	 stcf (ch, "You gained a %s.#n\n\r", pOutput);
      if (CHAR_DIRTY)
	 save_char_obj (ch);
      return;
   }
   // Finished with checking for IMMUNE_TRAIN, nothing left to do really.

   if ((VITALS_TRAIN) || (HPMPMV_TRAIN) || (PRIMAL_TRAIN) || (STATUS_TRAIN)
       || (AVATAR_TRAIN) || (MORTAL_TRAIN) || (AMAGIC_TRAIN) || (SILVER_TRAIN)
       || (GNOSIS_TRAIN) || (VAMPYR_TRAIN) || (DRAGON_TRAIN) || (MFOCUS_TRAIN)
       || (HQUICK_TRAIN) || (IMMUNE_TRAIN))
   {
      stc ("Finished training.  Should have already exited.  Please report to Serenity what you trained to see this message.#n\n\r", ch);
      return;
   }

   do_train (ch, "");		// If we got here do this just to show the syntax.      
   return;
}