/*
....[@@@..[@@@..............[@.................. 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.h
*/

#ifndef _AFFECT_H
#define _AFFECT_H

#include "llist.h"
#include "file.h"
#include "streamable.h"

int getAffectType( const char * );
const char * getAffectName( int );
int getModType( const char * );
const char * getModName( int );


const int AFF_INVIS = 1;
const int AFF_BLIND	= 2;
const int AFF_SANCTUARY = 3;
const int AFF_SLEEP = 4;
const int AFF_CHARM = 5;
const int AFF_POISON = 6;
const int AFF_CURSE = 7;
const int AFF_GIANT = 8;


const int MOD_STR = 1;
const int MOD_DEX = 2;
const int MOD_INT = 3;
const int MOD_WIS = 4;
const int MOD_CON = 5;
const int MOD_SPEED = 6;
const int MOD_HP = 7;
const int MOD_MANA = 8;
const int MOD_ENERGY = 9;
const int MOD_AGE = 10;
const int MOD_WEIGHT = 11;
const int MOD_ALIGN = 12;
const int MOD_ARMOR = 13;
const int MOD_DAMROLL = 14;
const int MOD_HITROLL = 15;


// Stat modifiers that aren't specifically finite in duration or
// resulting from a spell affect. Magic items that take affect when
// worn will apply Modifiers to the char which are negated when
// removed. There is no actual list data stucture -on- the char to
// hold Mods, rather the list of mods on an item is applied and negated
// when worn/removed


class Modifier
{
	private:
		int type;			// What does it modify? (str,int,hp)
		int amt;			// By how much does it mod?

	public:
		Modifier()
		:	type( 0 ), amt( 0 )
		{
		}

		Modifier( int t, int a )
		:	type( t ), amt( a )
		{
		}

		int getType() const { return type; }
		int getAmt() const { return amt; }
		const char * getName() { return getModName( type ); }
};


class Spell;

class Affect : public Streamable
{
	private:
		const Spell *spell;
		int type;					// const int affect types 
		int duration;				// How long it lasts, in hours.

	public:
		LList< Modifier > mods;	// List of attribute mods

		Affect()
		:	spell(0), type(0), duration(0)
		{
		}

		// The preferred way to create affects
		// Example:
		//
		//	SPELL( spell_giant_form )	
		//  {
		//		if( victim->isAffected( AFF_GIANT )
		//			return;
		//
		//		Affect *paf = new Affect( spell, AFF_GIANT, 10 );
		//
		//		paf->addMod( MOD_STR, 2 );
		//		paf->addMod( MOD_DEX, -1 );
		//		paf->addMod( MOD_HP, 100 );
		//
		//		victim->addAffect( paf );
		//	}

		Affect( const Spell *sp, int t, int d )
		:	spell( sp ), type( t ), duration( d )
		{
		}

		int writeTo( OutFile & ) const;
		int readFrom( InFile & );
		int writeProtoTo( OutFile & ) const { return -1; }
		int readProtoFrom( InFile & ) { return -1; }

		int pulse() { return --duration; }
		void addMod( int, int );
		int getType() { return type; }
		int getTimer() { return duration; }
		const Spell * getSpell() { return spell; }
};


inline void Affect::addMod( int t, int a ) 
{
	Modifier *pmod = new Modifier( t, a );
	mods.add( pmod );
}

#endif