mud++0.35/etc/
mud++0.35/etc/guilds/
mud++0.35/help/propert/
mud++0.35/mudC/
mud++0.35/player/
mud++0.35/src/interface/
mud++0.35/src/os/cygwin32/
mud++0.35/src/os/win32/
mud++0.35/src/os/win32/bcppbuilder/
mud++0.35/src/osaddon/
mud++0.35/src/util/
/*
....[@@@..[@@@..............[@.................. 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@hom.net 
MUD++ development mailing list    mudpp@van.ml.org
------------------------------------------------------------------------------
char_combat.cc
*/

#include "config.h"
#include "bit.h"
#include "io.h"
#include "string.h"
#include "llist.h"
#include "hash.h"
#include "room.h"
#include "random.h"
#include "combat.h"
#include "char.h"

#include "global.h"


// Perform an attack
int Char::attack( Char *ch, int )
{
	String str;
	fighting = ch;
	Attack * this_atck;
	int success;
	int hits = 0;
	int dt;
	int dam;
	attacks.reset();

	if( isBusy() )
		return 0;

	while( ( this_atck = attacks.peek() ) )
	{
		dt = this_atck->getType();

		attacks.next();

		success = hit( ch, this_atck );
		switch( success )
		{
			case ALREADY_APPLIED:
				// victim had spec_fun that taken care of attack
				continue;

			case FUMBLE:
				// fumble - something bad happens

				continue;
	
			case MISSED:
				out( "You miss " );
				out( ch->getShort() );
				out( ".\n\r" );
				ch->out( shortdesc );
				ch->out( " swings at you but misses!\n\r" );
				continue;

			case DODGED:
				out( ch->shortdesc );
				out( " dodges your attack.\n\r" );
				ch->out( "You dodge " );
				ch->out( shortdesc );
				ch->out( "'s attack.\n\r" );
				continue;

			case HIT:
				hits++;
				dam = randgen.get( this_atck->getMin(), this_atck->getMax() );
				dam += getDamRoll();

				str.sprintf( "Your %s %s %s.\n\r",
							getDamTypeName( dt ),
							getDamRangeName( dam, true ),
							ch->getShort().chars() );

				out( str );

				str.sprintf( "%s's %s %s you.",
							getShort().chars(),
							getDamTypeName( dt ),
							getDamRangeName( dam, true ) );

				ch->out( str );
				ch->damage( dam, dt );
				break;

			case CRIT_HIT:
				hits++;
				dam = randgen.get( this_atck->getMin(), this_atck->getMax() );
				dam += getDamRoll();
				dam *= 2;
				out( "You strike a -FEARSOME- blow to " );
				out( ch->getShort() );
				out( "!\n\r" );
				ch->damage( dam, dt );
				ch->out( getShort() );
				ch->out( " deals you a -FEARSOME- blow!\n\r" );
				break;
		}
	}

	fighting = ch;
	return hits;
}


bool Char::die( MudObject * killer )
{
	String str;
	if ( this->TgKilled( killer ) )
		return false;
	if( killer->isChar() )
		((Char*)killer)->stopFighting();
	str << getShort() << " is DEAD!!\n\r";
	in_room->outAllCharExcept( str, this, 0 );
	out( "You have been KILLED!!!\n\r" );
	makeCorpse();
	stopFighting();
	setHP( -1 );
	return true;
}


// Do a single hit, calculate success
int Char::hit( Char * vict, Attack * attack)
{
	// Char * vict parameter is unused until we get serious here.

	if ( vict->TgHit( this, attack ) )
		return ALREADY_APPLIED;

	int success;

	success = randgen.get( 1000 ) + getHitRoll();

	if( success < 25 )
		return FUMBLE;
	else if( success < 200 )
		return MISSED;
	else if( success < 975 )
	{
		int dodged;

		dodged = randgen.get( 1000 );
		if( dodged >= success )
			return DODGED;
		else
			return HIT;
	}
	else
		return CRIT_HIT;
}


// Inflict damage and calculate percent that armor absorbs
int Char::damage( int dam, int )
{
	int actual_dam = dam;

	// Do immunity and armor calcs here and return actual damage taken
	actual_dam -= armor;
	hp -= actual_dam;
	return actual_dam;
}