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