/*
....[@@@..[@@@..............[@.................. MUD++ is a written from
....[@..[@..[@..[@..[@..[@@@@@....[@......[@.... scratch multi-user swords and
....[@..[@..[@..[@..[@..[@..[@..[@@@@@..[@@@@@.. sorcery game written in C++.
....[@......[@..[@..[@..[@..[@....[@......[@.... This server is an ongoing
....[@......[@..[@@@@@..[@@@@@.................. development project.  All 
................................................ contributions are welcome. 
....Copyright(C).1995.Melvin.Smith.............. Enjoy. 
------------------------------------------------------------------------------
Melvin Smith (aka Fusion)         msmith@falcon.mercer.peachnet.edu 
MUD++ development mailing list    mudpp-list@spice.com
------------------------------------------------------------------------------
affect.cc
*/

#include <string.h>

#include "bit.h"
#include "affect.h"
#include "spell.h"


const bitType affect_type_list[] =
{
	{	"invisibility",	AFF_INVIS },
	{	"blindness",	AFF_BLIND },
	{	"sanctuary",	AFF_SANCTUARY },
	{	"sleep",		AFF_SLEEP },
	{	"charm",		AFF_CHARM },
	{	"poison",		AFF_POISON },
	{	"curse",		AFF_CURSE },
	{	"giant",		AFF_GIANT },
	{	0,				-1 }
};

const bitType mod_type_list[] =
{
	{ "strength",		MOD_STR },
	{ "dexterity",		MOD_DEX },
	{ "intelligence",	MOD_INT }, 
	{ "wisdom",			MOD_WIS },
	{ "constitution",	MOD_CON },
	{ "speed",			MOD_SPEED },
	{ "hp",				MOD_HP },
	{ "hitpoints",		MOD_HP },
	{ "mana",			MOD_MANA },
	{ "energy",			MOD_ENERGY },
	{ "age",		 	MOD_AGE },
	{ "weight",			MOD_WEIGHT },
	{ "alignment",		MOD_ALIGN },
	{ "armor",			MOD_ARMOR },
	{ "damroll",		MOD_DAMROLL },
	{ "hitroll",		MOD_HITROLL },
	{ 0,				-1 }
};


int getAffectType( const char * str )
{
	if( !*str )
		return -1;

	int len = strlen( str );
	for( int i = 0; affect_type_list[i].name; i++ )
	{
		if( !strncmp( str, affect_type_list[i].name, len ) )
			return affect_type_list[i].val;
	}

	return -1;
}


const char * getAffectName( int type )
{
	for( int i = 0; affect_type_list[i].name; i++ )
		if( type == affect_type_list[i].val )
			return affect_type_list[i].name;

	return "";
}

int getModType( const char * str )
{
	if( !*str )
		return -1;

	int len = strlen( str );
	for( int i = 0; mod_type_list[i].name; i++ )
	{
		if( !strncmp( str, mod_type_list[i].name, len ) )
			return mod_type_list[i].val;
	}

	return -1;
}


const char * getModName( int type )
{
	for( int i = 0; mod_type_list[i].name; i++ )
		if( type == mod_type_list[i].val )
			return mod_type_list[i].name;

	return "";
}


int Affect::writeTo( OutFile & out ) const
{
	Modifier *mod;

	out << '{' << getAffectName( type ) << ' ' << duration << ' ';
	if( spell )
		out << spell->getName() << '~';
	else
		out << "none~";

	mods.reset();
	while( ( mod = mods.peek() ) )
	{
		mods.next();
		out << "\nM{" << mod->getName() << ' ' << mod->getAmt() << "}";
	}
	
	out << "\n}\n";
	return 0;
}


int Affect::readFrom( InFile & in )
{
	char buf[ 256 ];
	Modifier *mod;
	int modAmt;
	int modType;

	in.getword( buf );
	in.getword( buf );
	type = getAffectType( buf );
	duration = in.getnum();

	if( strcmp( in.getstring( buf ), "none" ) )
		spell = lookupSpell( buf );

	for( ; ; )
	{
		switch( *in.getword( buf ) )
		{
			default:	return -1;
			case '}':	return 0;
			case 'M':	in.getword( buf );
						in.getword( buf );
						modAmt = in.getnum();
						if( ( modType = getModType( buf ) ) != -1 )
						{
							mod = new Modifier( modType, modAmt );
							if( mod )
								mods.add( mod );
							else
								in.error( "allocationg new Modifier" );
						}

						in.getword( buf );
		}
	}

	return 0;
}