/******************************************************************************************
 *  New Training System by Cherun of Kyrandia, I noticed in my previouse alteration of the*
 *  Training system was lacking one of the functions :) so I redid it, updated it a bit,  *
 *  And made it a little bit neater for your use, below is the code and details on how to *
 *  Install it onto your mud, Only thing I ask is if you use this code please send me a   *
 *  Email at cherun@tampabay.net and tell me what you think of it. Thank You ^_^          *
 ******************************************************************************************/

 Ok First off we need to open up interp.c and interp.h so we can add the command
 In so you can use it on the mud.

 Open interp.c find this line
 {"train", do_train, POS_RESTING, 0, LOG_NORMAL, 1},
 You need to remove that line and replace it with the following 2 lines
{ "train",	    do_train_part_one,	POS_RESTING,	0,	LOG_NORMAL,	1},
{ "convert",	do_convert,	        POS_RESTING,	0,	LOG_NORMAL,	1},
Convert is the command that players will use to turn Expierence into 'Energy' that they
Then will use to train.

Next open up interp.h and find this line
DECLARE_DO_FUN(	do_train	);
Remove that line and replace it with the following lines
DECLARE_DO_FUN(	do_train_part_one);
DECLARE_DO_FUN(	do_train_part_two);
DECLARE_DO_FUN(	do_convert		 );
The reason we didnt make a command for do_train_part_two is becuase players dont use it :-P

Ok next we need to open up merc.h so we can put the required stuff into pc_data.

In merc.h find this line it should be in pc_data
int				last_level;
Underneath it you need to have the following
/* New Training code stuff */
	int				train_one;
	int				train_two;
	int				train_three;
	int				train_four;
	int				train_five;

Now find the line in pc_data that looks like this
char *			title;
Underneath that put
char *			train_target;

Ok now we need to open up save.c and put the stuff we added in merc.h in save.c so well it saves *bonk*
Ok now that save.c is open find this line
fprintf (fp, "Trai %d\n", ch->train);
Underneath it add the following
if (ch->pcdata->train_one != 0)
        fprintf (fp, "TrainOne %d\n", ch->pcdata->train_one);
if (ch->pcdata->train_two != 0)
		fprintf (fp, "TrainTwo %d\n", ch->pcdata->train_two);
if (ch->pcdata->train_three != 0)
        fprintf (fp, "TrainThree %d\n", ch->pcdata->train_three);
if (ch->pcdata->train_four != 0)
        fprintf (fp, "TrainFour %d\n", ch->pcdata->train_four);
if (ch->pcdata->train_five != 0)
        fprintf (fp, "TrainFive %d\n", ch->pcdata->train_five);

Now find the line 
KEY ("Trai", ch->train, fread_number (fp));
Underneat it add this

KEY ("TrainOne", ch->pcdata->train_one, fread_number (fp));
KEY ("TrainTwo", ch->pcdata->train_two, fread_number (fp));
KEY ("TrainThree", ch->pcdata->train_three, fread_number (fp));
KEY ("TrainFour", ch->pcdata->train_four, fread_number (fp));
KEY ("TrainFive", ch->pcdata->train_five, fread_number (fp));

Now find the line
fprintf (fp, "Titl %s~\n", ch->pcdata->title);

Put this underneath it
fprintf (fp, "TrainTarget %s~\n", ch->pcdata->train_target);

Now find the line
KEY ("Tru", ch->trust, fread_number (fp));

Underneath it put
KEY ("TrainTarget", ch->pcdata->train_target, fread_string (fp));

Ok next we need to open up act_move.c You need to find do_train and remove it from the code
Then you need to put this anywhere (preferablly towards the bottom) of act_move.c

/*
 * Kyrandia's Training System by Cherun
 */
void do_convert (CHAR_DATA * ch, char *argument)
{
	int value;
	int cost;

	if ((argument[0] = '\0'))
	{
	send_to_char("Convert your expierence into how many Energy?\n\r",ch);
	return;
	}

	if (!is_number (argument))
    {
        send_to_char ("Please Specify a numerical value of Energy.\n\r", ch);
        return;
    }

    value = atoi (argument);
    if (value < 1 || value > 10)
    {
        send_to_char ("You may only gain 1 to 10 energy at a time.\n\r", ch);
        return;
    }
	cost = value * 5000;

	if (ch->exp < cost)
		{
		act("You do not have enough for that conversion.\n\r",ch, NULL, NULL, TO_CHAR);
		return;
		}
	

	ch->exp -= cost;
	ch->train += value;
	act("You sucessfully convert expierence over into energy.\n\r",ch,NULL,NULL,TO_CHAR);
	act("$n converts $s expierence over into energy.\n\r",ch,NULL,NULL,TO_ROOM);
	WAIT_STATE(ch, 5);
	return;
}


Ok now we need to put the do_train_part_one function into the code
so players can enter the 'training sequence' the sequence just makes
things funner especially on kyrandia becuase its a PK mud written on
ROM so it makes for interesting RP effects with Player Killing.

void do_train_part_one (CHAR_DATA * ch, char *argument)
{
	char buf[MAX_STRING_LENGTH];

	if (IS_NPC(ch)) return;

	if (ch->train < 1)
	{
		send_to_char("You have no energy to train with!\n\r",ch);
		return;
	}

	if (argument[0] == '\0')
    {
        sprintf (buf, "You have %d Energy to train with.\n\rWhat shall you train?\n\r", ch->train);
        send_to_char (buf, ch);
		send_to_char("Hp, Mana, Move, Str, Dex, Con, Int, or Wis?\n\r",ch);
		return;
    }
	/*
	 * This is just to make sure that they dont go through the sequence and end up
	 * trying to train hello or something they put in
	 */
	else if (!str_cmp(argument, "hp"))
	{
	free_string(ch->pcdata->train_target);
	ch->pcdata->train_target = str_dup( argument );
	}
	else if (!str_cmp(argument, "mana"))
	{
	free_string(ch->pcdata->train_target);
	ch->pcdata->train_target = str_dup( argument );
	}
	else if (!str_cmp(argument, "move"))
	{
	free_string(ch->pcdata->train_target);
	ch->pcdata->train_target = str_dup( argument );
	}
	else if (!str_cmp(argument, "str"))
	{
	free_string(ch->pcdata->train_target);
	ch->pcdata->train_target = str_dup( argument );
	}
	else if (!str_cmp(argument, "dex"))
	{
	free_string(ch->pcdata->train_target);
	ch->pcdata->train_target = str_dup( argument );
	}
	else if (!str_cmp(argument, "int"))
	{
	free_string(ch->pcdata->train_target);
	ch->pcdata->train_target = str_dup( argument );
	}
	else if (!str_cmp(argument, "wis"))
	{
	free_string(ch->pcdata->train_target);
	ch->pcdata->train_target = str_dup( argument );
	}
	else if (!str_cmp(argument, "con"))
	{
	free_string(ch->pcdata->train_target);
	ch->pcdata->train_target = str_dup( argument );
	}
	else
	{
		do_train_part_one(ch,"");
		return;
	}

	ch->pcdata->train_one = 5;
	ch->pcdata->train_two = 10;
	ch->pcdata->train_three = 15;
	ch->pcdata->train_four = 20;
	ch->pcdata->train_five = 25;
	send_to_char("You begin to train using your energy",ch);
	return;
}

Then after that put in train_part_two

void do_train_part_two (CHAR_DATA * ch, char *argument)
{
    char buf[MAX_STRING_LENGTH];
    sh_int stat = -1;
    char *pOutput = NULL;
    int cost;

    if (IS_NPC (ch))
        return;
	/* Make sure the base cost equals something :-P */
    cost = 1;

    if (!str_cmp (argument, "str"))
    {
		cost = ch->perm_stat[STAT_STR] + 2;
        stat = STAT_STR;
        pOutput = "strength";
    }

    else if (!str_cmp (argument, "int"))
    {
		cost = ch->perm_stat[STAT_INT] + 2;
        stat = STAT_INT;
        pOutput = "intelligence";
    }

    else if (!str_cmp (argument, "wis"))
    {
		cost = ch->perm_stat[STAT_WIS] + 2;
        stat = STAT_WIS;
        pOutput = "wisdom";
    }

    else if (!str_cmp (argument, "dex"))
    {
		cost = ch->perm_stat[STAT_DEX] + 2;
        stat = STAT_DEX;
        pOutput = "dexterity";
    }

    else if (!str_cmp (argument, "con"))
    {
	
		cost = ch->perm_stat[STAT_CON] + 2;
        stat = STAT_CON;
        pOutput = "constitution";
    }

    else if (!str_cmp (argument, "hp"))
        cost = 1;

    else if (!str_cmp (argument, "mana"))
        cost = 1;

	else if (!str_cmp (argument, "move"))
		cost = 1;

    else
    {
        strcpy (buf, "You can train:");
        if (ch->perm_stat[STAT_STR] < get_max_train (ch, STAT_STR))
            strcat (buf, " str");
        if (ch->perm_stat[STAT_INT] < get_max_train (ch, STAT_INT))
            strcat (buf, " int");
        if (ch->perm_stat[STAT_WIS] < get_max_train (ch, STAT_WIS))
            strcat (buf, " wis");
        if (ch->perm_stat[STAT_DEX] < get_max_train (ch, STAT_DEX))
            strcat (buf, " dex");
        if (ch->perm_stat[STAT_CON] < get_max_train (ch, STAT_CON))
            strcat (buf, " con");
        strcat (buf, " hp mana move");

        if (buf[strlen (buf) - 1] != ':')
        {
            strcat (buf, ".\n\r");
            send_to_char (buf, ch);
        }
        else
        {
            send_to_char("You failed at training due to lack of Training Points.\n\r",ch);
        }

        return;
    }

    if (!str_cmp ("hp", argument))
    {
        if (cost > ch->train)
        {
            send_to_char ("You failed at training due to lack of Training Points.\n\r", ch);
            return;
        }

        ch->train -= cost;
		if (ch->perm_stat[STAT_CON] >= 5)
		{
		ch->pcdata->perm_hit += 15;
        ch->max_hit += 15;
        ch->hit += 15;
		}
		if (ch->perm_stat[STAT_CON] >= 10)
		{
		ch->pcdata->perm_hit += 20;
        ch->max_hit += 20;
        ch->hit += 20;
		}
		if (ch->perm_stat[STAT_CON] >= 15)
		{
		ch->pcdata->perm_hit += 25;
        ch->max_hit += 25;
        ch->hit += 25;
		}
		if (ch->perm_stat[STAT_CON] >= 20)
		{
		ch->pcdata->perm_hit += 30;
        ch->max_hit += 30;
        ch->hit += 30;
		}
		if (ch->perm_stat[STAT_CON] >= 25)
		{
		ch->pcdata->perm_hit += 35;
        ch->max_hit += 35;
        ch->hit += 35;
		}
		else
		{
        ch->pcdata->perm_hit += 10;
        ch->max_hit += 10;
        ch->hit += 10;
		}
        return;
    }

    if (!str_cmp ("mana", argument))
    {
        if (cost > ch->train)
        {
            send_to_char ("You failed at training due to lack of Training Points.\n\r", ch);
            return;
        }
		ch->train -= cost;
		if (ch->perm_stat[STAT_INT] >= 5)
		{
		ch->pcdata->perm_mana += 15;
		ch->max_mana += 15;
		ch->mana += 15;
		}
		if (ch->perm_stat[STAT_INT] >= 10)
		{
		ch->pcdata->perm_mana += 20;
		ch->max_mana += 20;
		ch->mana += 20;
		}
		if (ch->perm_stat[STAT_INT] >= 15)
		{
		ch->pcdata->perm_mana += 25;
		ch->max_mana += 25;
		ch->mana += 25;
		}
		if (ch->perm_stat[STAT_INT] >= 20)
		{
		ch->pcdata->perm_mana += 30;
		ch->max_mana += 30;
		ch->mana += 30;
		}
		if (ch->perm_stat[STAT_INT] >= 25)
		{
		ch->pcdata->perm_mana += 35;
		ch->max_mana += 35;
		ch->mana += 35;
		}
		else
		{
        ch->pcdata->perm_mana += 10;
        ch->max_mana += 10;
        ch->mana += 10;
		}
        return;
    }

	if (!str_cmp ("move", argument))
    {
        if (cost > ch->train)
        {
            send_to_char ("You failed at training due to lack of Training Points.\n\r", ch);
            return;
        }

        ch->train -= cost;
		if (ch->perm_stat[STAT_DEX] >= 5)
		{
		ch->pcdata->perm_move += 15;
		ch->max_move += 15;
		ch->move += 15;
		}
		if (ch->perm_stat[STAT_DEX] >= 10)
		{
		ch->pcdata->perm_move += 20;
		ch->max_move += 20;
		ch->move += 20;
		}
		if (ch->perm_stat[STAT_DEX] >= 15)
		{
		ch->pcdata->perm_move += 25;
		ch->max_move += 25;
		ch->move += 25;
		}
		if (ch->perm_stat[STAT_DEX] >= 20)
		{
		ch->pcdata->perm_move += 30;
		ch->max_move += 30;
		ch->move += 30;
		}
		if (ch->perm_stat[STAT_DEX] >= 25)
		{
		ch->pcdata->perm_move += 35;
		ch->max_move += 35;
		ch->move += 35;
		}
		else
		{
        ch->pcdata->perm_move += 10;
        ch->max_move += 10;
        ch->move += 10;
		}
        return;
    }

    if (ch->perm_stat[stat] >= get_max_train (ch, stat))
    {
        act ("Your $T is already at maximum.", ch, NULL, pOutput, TO_CHAR);
        return;
    }

    if (cost > ch->train)
    {
        send_to_char ("You failed at training due to lack of Training Points.\n\r", ch);
        return;
    }

    ch->train -= cost;

    ch->perm_stat[stat] += 1;
    return;
}

Now to open update.c In here we will put what ch->pcdata->train_one and those do
To make kind of a RolePlay effect of them actually training their stats up in a process.

Find the update_handler in update.c In that find this line
static int pulse_music;
Underneath that line you need to add the following
DESCRIPTOR_DATA *d;
CHAR_DATA *ch = NULL;

Now find these lines

 aggr_update ();
 tail_chain ();
 return;

Before the aggr_update (); you need to add the following

for ( d = descriptor_list; d != NULL; d = d->next )
		{
	    if ( d->connected == CON_PLAYING &&   (ch = d->character) != NULL &&  !IS_NPC(ch))
	    {

	if (ch->pcdata->train_one > 0)
		{
		    ch->pcdata->train_one--;
		    if (ch->pcdata->train_one < 1)
		    {
			    send_to_char("You begin to train.\n\r",ch);
			    act("$n begins to train.",ch,NULL,NULL,TO_ROOM);
			}
		}
	if (ch->pcdata->train_two > 0)
		{
		    ch->pcdata->train_two--;
		    if (ch->pcdata->train_two < 1)
		    {
			    send_to_char("Your training kicks up a bit.\n\r",ch);
			    act("$n's training begins to quicken.",ch,NULL,NULL,TO_ROOM);
			}
		}
	if (ch->pcdata->train_three > 0)
		{
		    ch->pcdata->train_three--;
		    if (ch->pcdata->train_three < 1)
		    {
			    send_to_char("Your training becomes more harsh.\n\r",ch);
			    act("$n's training becomes real harsh.",ch,NULL,NULL,TO_ROOM);
			}
		}
	if (ch->pcdata->train_four > 0)
		{
		    ch->pcdata->train_four--;
		    if (ch->pcdata->train_four < 1)
		    {
			    send_to_char("You begin to sweat alot.\n\r",ch);
			    act("$n begins to sweat alot.",ch,NULL,NULL,TO_ROOM);
			}
		}
	if (ch->pcdata->train_five > 0)
		{
		    ch->pcdata->train_five--;
		    if (ch->pcdata->train_five < 1)
		    {
			    send_to_char("You have compeleted your training.\n\r",ch);
			    act("$n has completed their training.",ch,NULL,NULL,TO_ROOM);
				do_train_part_two(ch, ch->pcdata->train_target );
			}
		}
		}
		}

Now we need to open up interp.c one last time you need to find the following line

if (ch->position < cmd_table[cmd].position)

It is located in void interpret (CHAR_DATA * ch, char *argument)

Ok now above the ch->position line add this

if (ch->pcdata->train_five > 0)
	{
	send_to_char("You must concentrate on training!\n\r",ch);
	return;
	}

Now Finally you may want to replace your old help train file if you have one with this

-1 TRAIN~
Syntax: train <str int wis dex con hp mana move>
In order to train a stat you must first CONVERT 
expierence over into energy used for training
Synax: convert <amount of energy>
You may only convert expierence into a max of 10 energy
it costs 5000 expierence per 1 energy

Str, int, wis, dex, and con
All raise in value as they go up in levels
Hp mana and Move all cost 1 energy
The more Int you have the more mana per train you recieve
The more Dex you have the more Move per train you recieve
The more Con you have the more Hp per train you recieve

New Train Done by Cherun
~