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