alRom/bin/
alRom/data/class/
alRom/data/command/
alRom/data/guild/
alRom/data/help/
alRom/data/lang/
alRom/data/race/
alRom/data/religion/
alRom/data/skill/
alRom/note/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,	   *
 *  Michael Seifert, Hans Henrik Stfeldt, 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.						   *
 ***************************************************************************/
 
/***************************************************************************
*	ROM 2.4 is copyright 1993-1998 Russ Taylor			   *
*	ROM has been brought to you by the ROM consortium		   *
*	    Russ Taylor (rtaylor@hypercube.org)				   *
*	    Gabrielle Taylor (gtaylor@hypercube.org)			   *
*	    Brian Moore (zump@rom.org)					   *
*	By using this code, you have agreed to follow the terms of the	   *
*	ROM license, in the file Rom24/doc/rom.license			   *
***************************************************************************/

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

bool skedit_new args( ( CHAR_DATA *ch, char *argument ) );



void do_skills(CHAR_DATA *ch, char *argument)
{
    BUFFER *buffer;
    char arg[MAX_INPUT_LENGTH];
    char skill_list[LEVEL_HERO + 1][MAX_STRING_LENGTH];
    char skill_columns[LEVEL_HERO + 1];
    int sn, level, min_lev = 1, max_lev = LEVEL_HERO;
    bool fAll = FALSE, found = FALSE;
    char buf[MAX_STRING_LENGTH];
 
    if (IS_NPC(ch))
      return;

    if (argument[0] != '\0')
    {
	fAll = TRUE;

	if (str_prefix(argument,"all"))
	{
	    argument = one_argument(argument,arg);
	    if (!is_number(arg))
	    {
		send_to_char("Arguments must be numerical or all.\n\r",ch);
		return;
	    }
	    max_lev = atoi(arg);

	    if (max_lev < 1 || max_lev > LEVEL_HERO)
	    {
		sprintf(buf,"Levels must be between 1 and %d.\n\r",LEVEL_HERO);
		send_to_char(buf,ch);
		return;
	    }

	    if (argument[0] != '\0')
	    {
		argument = one_argument(argument,arg);
		if (!is_number(arg))
		{
		    send_to_char("Arguments must be numerical or all.\n\r",ch);
		    return;
		}
		min_lev = max_lev;
		max_lev = atoi(arg);

		if (max_lev < 1 || max_lev > LEVEL_HERO)
		{
		    sprintf(buf,
			"Levels must be between 1 and %d.\n\r",LEVEL_HERO);
		    send_to_char(buf,ch);
		    return;
		}

		if (min_lev > max_lev)
		{
		    send_to_char("That would be silly.\n\r",ch);
		    return;
		}
	    }
	}
    }


    /* initialize data */
    for (level = 0; level < LEVEL_HERO + 1; level++)
    {
        skill_columns[level] = 0;
        skill_list[level][0] = '\0';
    }
 
    for (sn = 0; sn < MAX_SKILL; sn++)
    {
        if (skill_table[sn].name == NULL )
	    break;

	if ( (level = skill_level(ch, sn)) < LEVEL_HERO + 1 
	&&  (fAll || level <= ch->level)
	&&  level >= min_lev && level <= max_lev
	&&  ch->pcdata->learned[sn] > 0)
        {
	    found = TRUE;
	    level = skill_level(ch, sn);
	    if (ch->level < level)
	    	sprintf(buf,"%-18s n/a      ", skill_table[sn].name);
	    else
	    	sprintf(buf,"%-18s %3d%%      ",skill_table[sn].name,
		    ch->pcdata->learned[sn]);
 
	    if (skill_list[level][0] == '\0')
          	sprintf(skill_list[level],"\n\rLevel %2d: %s",level,buf);
	    else /* append */
	    {
          	if ( ++skill_columns[level] % 2 == 0)
		    strcat(skill_list[level],"\n\r          ");
          	strcat(skill_list[level],buf);
	    }
	}
    }
 
    /* return results */
 
    if (!found)
    {
      	send_to_char("No skills found.\n\r",ch);
      	return;
    }

    buffer = new_buf();
    for (level = 0; level < LEVEL_HERO + 1; level++)
      	if (skill_list[level][0] != '\0')
	    add_buf(buffer,skill_list[level]);
    add_buf(buffer,"\n\r");
    page_to_char(buf_string(buffer),ch);
    free_buf(buffer);
}

/* shows skills, groups and costs (only if not bought) */

int exp_per_level(CHAR_DATA *ch, int points)
{
    if (IS_NPC(ch))
	return 1000; 

	return UMAX(1, ch->level) * 1000;
}


int exp_to_level(CHAR_DATA *ch)
{	long total =1000;
	int i;
	
	if (ch->level == 1 || IS_NPC(ch))
		return 1000;
	for(i = 1; i <= ch->level ; i++)
		total += i*1000;
	return total - ch->exp;
}
/* checks for skill improvement */
void check_improve( CHAR_DATA *ch, int sn, bool success, int multiplier )
{
    int chance;
    char buf[100];

    if (IS_NPC(ch))
	return;

    if (!can_use_skpell(ch, sn)
    ||  skill_rating(ch, sn) < 1
    ||  ch->pcdata->learned[sn] == 0
    ||  ch->pcdata->learned[sn] == 100)
	return;  /* skill is not known */ 

    /* check to see if the character has a chance to learn */
    chance = 10 * int_app[get_curr_stat(ch,STAT_INT)].learn;
    chance /= (		multiplier
		*	skill_rating(ch, sn) 
		*	4);
    chance += ch->level;

    if (number_range(1,1000) > chance)
	return;

    /* now that the character has a CHANCE to learn, see if they really have */	

    if (success)
    {
	chance = URANGE(5,100 - ch->pcdata->learned[sn], 95);
	if (number_percent() < chance)
	{
	    sprintf(buf,"You have become better at %s!\n\r",
		    skill_table[sn].name);
	    send_to_char(buf,ch);
	    ch->pcdata->learned[sn]++;
	    gain_exp(ch,2 * skill_rating(ch, sn));
	}
    }

    else
    {
	chance = URANGE(5,ch->pcdata->learned[sn]/2,30);
	if (number_percent() < chance)
	{
	    sprintf(buf,
		"You learn from your mistakes, and your %s skill improves.\n\r",
		skill_table[sn].name);
	    send_to_char(buf,ch);
	    ch->pcdata->learned[sn] += number_range(1,3);
	    ch->pcdata->learned[sn] = UMIN(ch->pcdata->learned[sn],100);
	    gain_exp(ch,2 * skill_rating(ch, sn));
	}
    }
}

GROUP_DATA *group_lookup( const char *name )
{	GROUP_DATA *pGrp;

	for (pGrp = group_list;pGrp ; pGrp = pGrp->next)
	{	if(LOWER(pGrp->name[0]) == LOWER(name[0]) 
		&& !str_prefix(name, pGrp->name) )
			return pGrp;
	}
	return NULL;
}

void set_char_groups(CHAR_DATA *ch, int type )
{	GROUP_DATA *pGrp;
	int i, sn;

	if(IS_NPC(ch))
		return;

	switch (type)
	{	case TYPE_CLAN:
			if(!is_clan(ch))
				return;
			pGrp = group_lookup(clan_table[ch->clan].name);
			break;
		case TYPE_RELIGION:
			if(!ch->pcdata->religion)
				return;
			pGrp = group_lookup(ch->pcdata->religion->name );
			break;
		case TYPE_CLASS:
			pGrp = group_lookup(class_table[ch->clss].name );
			break;
		case TYPE_RACE:
			pGrp = group_lookup(pc_race_table[ch->race].name);
			break;
	}
	if(!pGrp)
	{	logf2("Group bad for %s on type %d.", ch->name, type);
		return;
	}

	for( i = 0 ; i < MAX_IN_GROUP ; i++ )
	{	if(!str_cmp(pGrp->spells[i], "reserved" ) )
			continue;
		if( ( sn = skill_lookup(pGrp->spells[i]) ) == -1 )
		{	logf2("set_char_groups: Invalid spell! %s",pGrp->spells[i]);
			continue;
		}
		ch->pcdata->learned[sn] = 1;
	}
	return;
}

void strip_group(CHAR_DATA *ch, int type )
{	GROUP_DATA *pGrp;
	int i, sn;

	if(IS_NPC(ch))
		return;

	switch (type)
	{	case TYPE_CLAN:
			if(!is_clan(ch))
				return;
			pGrp = group_lookup(clan_table[ch->clan].name);
			break;
		case TYPE_RELIGION:
			if(!ch->pcdata->religion)
				return;
			pGrp = group_lookup(ch->pcdata->religion->name );
			break;
		case TYPE_CLASS:
			pGrp = group_lookup(class_table[ch->clss].name );
			break;
		case TYPE_RACE:
			pGrp = group_lookup(pc_race_table[ch->race].name);
			break;
	}

	if(!pGrp)
	{	logf2("Group bad for %s on type %d.", ch->name, type);
		return;
	}

	for( i = 0 ; i < MAX_IN_GROUP ; i++ )
	{	if(!str_cmp(pGrp->spells[i], "reserved" ) )
			continue;
		if( ( sn = skill_lookup(pGrp->spells[i]) ) == -1 )
		{	logf2("strip_group: Invalid spell! %s",pGrp->spells[i]);
			continue;
		}
		ch->pcdata->learned[sn] = 0;
	}
	return;
}