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