/* ....[@@@..[@@@..............[@.................. 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 ------------------------------------------------------------------------------ magic.cc */ #include "string.h" #include "llist.h" #include "room.h" #include "char.h" #include "affect.h" #include "spell.h" int str_cmp( const char *, const char * ); const Spell spell_lookup_table[] = { { "none", Spell::spell_none, 0 }, { "giant form", Spell::spell_giant_form, TAR_ANY }, { "lightning bolt", Spell::spell_lightning_bolt, TAR_ANY }, { "sanctuary", Spell::spell_sanctuary, TAR_ANY }, { "", 0, 0 } }; const Spell * spellNone = &spell_lookup_table[0]; // This function allows things like 'cast detec invi' // Checks abbreviations for each word instead of whole phrase. // Returns the remainder of str after matching // 'cast detect invi Fusion' returns ' Fusion' in remainder bool check_abbrev( const char * str, const char * compare, char* remainder ) { // Needs a little more work while( 1 ) { if( *str == ' ' ) while( *compare && !isspace( *compare ) ) compare++; if( !*compare ) { if( !*str ) return true; else if( !isspace( *str ) ) return false; while( *str && isspace( *str ) ) str++; if( !*str ) return true; strcpy( remainder, str ); return true; } if( !*str ) return true; if( *str != *compare ) return false; str++; compare++; } } // Single argument lookupSpell is not used for player spell parser. // Refer to the 2 argument version after this one. This version is used // by the database loading functions to match spell names to lookup // when we know the string only contains a name of a spell. const Spell * lookupSpell( const char * str ) { int i; if( !*str ) return &spell_lookup_table[0]; for( i=1; *spell_lookup_table[ i ].name; i++ ) { if( *spell_lookup_table[ i ].name != *str ) continue; if( !str_cmp( str, spell_lookup_table[ i ].name ) ) return &spell_lookup_table[ i ]; } return &spell_lookup_table[0]; } // char * target is a buffer passed to allow the lookup function to parse // the spell out and return the remainder of the string, most likely // the target of the spell. const Spell * lookupSpell( const char * str, char * target ) { int i; if( !*str ) return &spell_lookup_table[0]; // Preliminary // Will port my spell parser from Lost Realms later for( i=1; *spell_lookup_table[ i ].name; i++ ) { if( *spell_lookup_table[ i ].name != *str ) continue; if( check_abbrev( str, spell_lookup_table[ i ].name, target ) ) return &spell_lookup_table[ i ]; } return &spell_lookup_table[0]; } void Spell::spell_none( Thing *, Thing * ) { } void Spell::spell_giant_form( Thing *, Thing *target ) { if( target->affected( AFF_GIANT ) ) return; Affect * paf = new Affect( this, AFF_GIANT, 10 ); paf->addMod( MOD_STR, 10 ); paf->addMod( MOD_HP, 10 ); target->addAffect( paf ); target->out( "You feel stronger all of the sudden!\n\r" ); } void Spell::spell_sanctuary( Thing *, Thing *target ) { Char *vict; Object *obj; if( target->affected( AFF_SANCTUARY ) ) return; Affect * paf = new Affect( this, AFF_SANCTUARY, 10 ); paf->addMod( MOD_INT, 2 ); paf->addMod( MOD_HP, 10 ); if( ( vict = target->asChar() ) ) obj = 0; else obj = target->asObj(); if( vict ) { vict->addAffect( paf ); vict->out( "You begin to glow...\n\r" ); vict->inRoom()->outAllCharExcept( vict->getShort(), vict, 0 ); vict->inRoom()->outAllCharExcept( " begins to glow with a bright light.\n\r", vict, 0 ); } } void Spell::spell_lightning_bolt( Thing *, Thing *target ) { Char *vict; Object *obj; int dam; if( ( vict = target->asChar() ) ) obj = 0; else obj = target->asObj(); dam = 10; if( vict->affected( AFF_SANCTUARY ) ) { dam /= 2; } vict->damage( dam, 0 ); }