/***************************************************************************
* Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe. *
* *
* Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* *
* Envy Diku Mud improvements copyright (C) 1994 by Michael Quan, David *
* Love, Guilherme 'Willie' Arnold, and Mitchell Tse. *
* *
* In order to use any part of this Envy Diku Mud, you must comply with *
* the original Diku license in 'license.doc', the Merc license in *
* 'license.txt', as well as the Envy license in 'license.nvy'. *
* In particular, you may not remove either of these copyright notices. *
* *
* Much time and thought has gone into this software and you are *
* benefitting. We hope that you share your changes too. What goes *
* around, comes around. *
***************************************************************************/
#define unix 1
#if defined( macintosh )
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
/*
* External functions.
*/
bool is_safe args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
void set_fighting args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
/*
* Local functions.
*/
void say_spell args( ( CHAR_DATA *ch, int sn ) );
int blood_count args( ( OBJ_DATA *list, int amount ) );
void magic_mob args( ( CHAR_DATA *ch, OBJ_DATA *obj, int vnum ) );
int slot_lookup args( ( int slot ) );
int sc_dam args( ( CHAR_DATA *ch, int dam ) );
/*
* "Permament sn's": slot loading for objects -- Altrag
*/
int slot_lookup( int slot )
{
int sn;
for ( sn = 0; skill_table[sn].name[0] != '\0'; sn++ )
if ( skill_table[sn].slot == slot )
return sn;
bug( "Slot_lookup: no such slot #%d", slot );
return 0;
}
/*
* Replacement for MAX_SKILL -- Altrag
*/
bool is_sn( int sn )
{
int cnt;
for ( cnt = 0; skill_table[cnt].name[0] != '\0'; cnt++ )
if ( cnt == sn )
return TRUE;
return FALSE;
}
void magic_mob ( CHAR_DATA *ch, OBJ_DATA *obj, int vnum )
{
CHAR_DATA *victim;
CHAR_DATA *zombie;
MOB_INDEX_DATA *ZombIndex;
MOB_INDEX_DATA *pMobIndex;
char *name;
char buf [MAX_STRING_LENGTH];
if ( !( pMobIndex = get_mob_index( vnum ) ) )
{
send_to_char(AT_BLUE, "Nothing happens.\n\r", ch);
return;
}
ZombIndex = get_mob_index( 3 );
victim = create_mobile( pMobIndex );
zombie = create_mobile( ZombIndex );
name = victim->short_descr;
sprintf( buf, zombie->short_descr, name );
free_string( zombie->short_descr );
zombie->short_descr = str_dup(buf);
sprintf( buf, zombie->long_descr, name );
free_string( zombie->long_descr );
zombie->long_descr = str_dup(buf);
victim->perm_hit /= 2;
victim->hit = MAX_HIT(victim);
zombie->mod_hit = victim->mod_hit;
zombie->perm_hit = victim->perm_hit;
zombie->hit = victim->hit;
zombie->level = victim->level;
SET_BIT( zombie->act, ACT_UNDEAD );
SET_BIT( zombie->act, ACT_PET );
SET_BIT( zombie->affected_by, AFF_CHARM );
char_to_room( zombie, ch->in_room );
add_follower( zombie, ch );
update_pos( zombie );
act( AT_BLUE, "$n passes $s hands over $p, $E slowly rises to serve $S new master.", ch, obj, zombie, TO_ROOM );
act( AT_BLUE, "You animate $p, it rises to serve you.", ch, obj, NULL, TO_CHAR );
char_to_room( victim, ch->in_room );
extract_char ( victim, TRUE );
return;
}
int blood_count( OBJ_DATA *list, int amount )
{
OBJ_DATA *obj;
int count;
OBJ_DATA *obj_next;
count = 0;
for ( obj = list; obj; obj = obj_next )
{
obj_next = obj->next_content;
if ( obj->deleted )
continue;
if ( ( obj->item_type == ITEM_BLOOD ) && ( count != amount ) )
{
count++;
extract_obj( obj );
}
}
return count;
}
void update_skpell( CHAR_DATA *ch, int sn )
{
int xp = 0;
char buf[MAX_STRING_LENGTH];
int adept;
if ( IS_NPC( ch ) )
return;
adept = IS_NPC( ch ) ? 100 :
class_table[prime_class( ch )].skill_adept;
if ( ch->pcdata->learned[sn] <= 0
|| ch->pcdata->learned[sn] >= adept )
return;
ch->pcdata->learned[sn] += ( get_curr_wis( ch ) / 5 );
if ( ch->pcdata->learned[sn] > adept )
ch->pcdata->learned[sn] = adept;
xp = ch->level / 5;
if ( xp < 2 )
xp = 2;
xp = number_range( xp * 2, ( xp * xp ) / 3 );
if (!(ch->fighting))
{
sprintf( buf, "You gain %d experience for your success with %s.\n\r",
xp, skill_table[sn].name );
send_to_char( C_DEFAULT, buf, ch );
}
gain_exp( ch, xp );
return;
}
int skill_lookup( const char *name )
{
int sn;
for ( sn = 0; skill_table[sn].name[0] != '\0'; sn++ )
{
if ( !skill_table[sn].name )
break;
if ( LOWER( name[0] ) == LOWER( skill_table[sn].name[0] )
&& !str_prefix( name, skill_table[sn].name ) )
return sn;
}
return -1;
}
/*
* Utter mystical words for an sn.
*/
void say_spell( CHAR_DATA *ch, int sn )
{
CHAR_DATA *rch;
char *pName;
char buf [ MAX_STRING_LENGTH ];
char buf2 [ MAX_STRING_LENGTH ];
int iSyl;
int length;
struct syl_type
{
char * old;
char * new;
};
static const struct syl_type syl_table [ ] =
{
{ " ", " " },
{ "ar", "abra" },
{ "au", "kada" },
{ "bless", "fido" },
{ "blind", "nose" },
{ "bur", "mosa" },
{ "cu", "judi" },
{ "de", "oculo" },
{ "en", "unso" },
{ "light", "dies" },
{ "lo", "hi" },
{ "mor", "zak" },
{ "move", "sido" },
{ "ness", "lacri" },
{ "ning", "illa" },
{ "per", "duda" },
{ "ra", "gru" },
{ "re", "candus" },
{ "son", "sabru" },
{ "tect", "infra" },
{ "tri", "cula" },
{ "ven", "nofo" },
{ "a", "a" }, { "b", "b" }, { "c", "q" }, { "d", "e" },
{ "e", "z" }, { "f", "y" }, { "g", "o" }, { "h", "p" },
{ "i", "u" }, { "j", "y" }, { "k", "t" }, { "l", "r" },
{ "m", "w" }, { "n", "i" }, { "o", "a" }, { "p", "s" },
{ "q", "d" }, { "r", "f" }, { "s", "g" }, { "t", "h" },
{ "u", "j" }, { "v", "z" }, { "w", "x" }, { "x", "n" },
{ "y", "l" }, { "z", "k" },
{ "", "" }
};
buf[0] = '\0';
for ( pName = skill_table[sn].name; *pName != '\0'; pName += length )
{
for ( iSyl = 0;
( length = strlen( syl_table[iSyl].old ) ) != 0;
iSyl++ )
{
if ( !str_prefix( syl_table[iSyl].old, pName ) )
{
strcat( buf, syl_table[iSyl].new );
break;
}
}
if ( length == 0 )
length = 1;
}
sprintf( buf2, "$n %s the words, '%s'.",
prime_class(ch) != CLASS_BARD ?
"utters" : "sings", buf );
sprintf( buf, "$n %s the words, '%s'.",
prime_class(ch) != CLASS_BARD ?
"utters" : "sings", skill_table[sn].name );
for ( rch = ch->in_room->people; rch; rch = rch->next_in_room )
{
if ( rch != ch )
act(AT_BLUE,
is_class( rch, prime_class(ch) )
? buf
: buf2, ch, NULL, rch, TO_VICT );
}
return;
}
/*
* Compute a saving throw.
* Negative apply's make saving throw better.
*/
bool saves_spell( int level, CHAR_DATA *victim )
{
int save;
int base = 20;
int savebase;
if ( IS_NPC( victim ) )
base += 30;
savebase = 0 - victim->saving_throw / 2;
if ( victim->race == RACE_DWARF )
savebase += 25 * savebase / 100;
if ( !IS_NPC( victim ) )
savebase /= 6;
else
savebase /= 2;
save = base + ( victim->level - level ) + savebase;
save = URANGE( 5, save, ( victim->race == RACE_DWARF ) ? 95 : 90 );
return number_percent( ) < save;
}
/*
* The kludgy global is for spells who want more stuff from command line.
*/
char *target_name;
void do_acspell ( CHAR_DATA *ch, OBJ_DATA *pObj, char *argument )
{
void *vo;
OBJ_DATA *obj = NULL;
CHAR_DATA *victim;
char arg1 [ MAX_INPUT_LENGTH ];
char arg2 [ MAX_INPUT_LENGTH ];
int sn;
int spec;
spec = skill_lookup( "astral walk" );
target_name = one_argument( argument, arg1 );
one_argument( target_name, arg2 );
if ( IS_NPC( ch ) )
if ( IS_SET( ch->affected_by, AFF_CHARM ) )
return;
if ( ( sn = skill_lookup( arg1 ) ) < 0)
{
send_to_char(AT_BLUE, "You can't do that.\n\r", ch );
return;
}
if ( ( sn == spec ) && ( is_name( ch, arg2, ch->name ) ) )
{
send_to_char( AT_BLUE, "You are already in the same room as yourself.\n\r", ch );
return;
}
/*
* Locate targets.
*/
victim = NULL;
obj = NULL;
vo = NULL;
switch ( skill_table[sn].target )
{
default:
bug( "Do_cast: bad target for sn %d.", sn );
return;
case TAR_GROUP_OFFENSIVE:
case TAR_GROUP_DEFENSIVE:
case TAR_GROUP_ALL:
case TAR_GROUP_OBJ:
case TAR_GROUP_IGNORE:
group_cast( sn, URANGE( 1, ch->level, LEVEL_HERO ), ch, arg2 );
return;
case TAR_IGNORE:
break;
case TAR_CHAR_OFFENSIVE:
if ( IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) )
{
send_to_char( AT_BLUE, "You failed.\n\r", ch );
return;
}
if ( arg2[0] == '\0' )
{
if ( !( victim = ch->fighting ) )
{
send_to_char(AT_BLUE, "Cast the spell on whom?\n\r", ch );
return;
}
}
else
{
if ( !( victim = get_char_room( ch, arg2 ) ) )
{
send_to_char(AT_BLUE, "They aren't here.\n\r", ch );
return;
}
}
if ( IS_AFFECTED(victim, AFF_PEACE) )
{
send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch);
return;
}
if ( IS_AFFECTED( ch, AFF_MUTE ))
{
send_to_char(AT_WHITE, "You have been silenced.\n\r", ch);
return;
}
if ( IS_AFFECTED( ch, AFF_PEACE) )
{
affect_strip( ch, skill_lookup("aura of peace") );
REMOVE_BIT( ch->affected_by, AFF_PEACE );
}
if ( is_safe(ch, victim) )
{
send_to_char(AT_BLUE,"You failed.\n\r",ch);
return;
}
vo = (void *) victim;
break;
case TAR_CHAR_DEFENSIVE:
if ( arg2[0] == '\0' )
{
victim = ch;
}
else
{
if ( !( victim = get_char_room( ch, arg2 ) ) )
{
send_to_char(AT_BLUE, "They aren't here.\n\r", ch );
return;
}
}
vo = (void *) victim;
break;
case TAR_CHAR_SELF:
if ( arg2[0] != '\0' && !is_name( ch, arg2, ch->name ) )
{
send_to_char(AT_BLUE, "You cannot cast this spell on another.\n\r", ch );
return;
}
vo = (void *) ch;
break;
case TAR_OBJ_INV:
if ( arg2[0] == '\0' )
{
send_to_char(AT_BLUE, "What should the spell be cast upon?\n\r", ch );
return;
}
if ( !( obj = get_obj_carry( ch, arg2 ) ) )
{
send_to_char(AT_BLUE, "You are not carrying that.\n\r", ch );
return;
}
vo = (void *) obj;
break;
}
WAIT_STATE( ch, skill_table[sn].beats );
if ( IS_SET( ch->in_room->room_flags, ROOM_NO_MAGIC ) )
{
send_to_char( AT_BLUE, "You failed.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) )
update_skpell( ch, sn );
(*skill_table[sn].spell_fun) ( sn, URANGE( 1, ch->level, LEVEL_HERO ),
ch, vo );
if ( vo )
{
oprog_invoke_trigger( pObj, ch, vo );
if ( skill_table[sn].target == TAR_OBJ_INV )
oprog_cast_sn_trigger( obj, ch, sn, vo );
rprog_cast_sn_trigger( ch->in_room, ch, sn, vo );
}
if ( skill_table[sn].target == TAR_CHAR_OFFENSIVE
&& victim->master != ch && victim != ch && IS_AWAKE( victim ) )
{
CHAR_DATA *vch;
for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
{
if ( vch->deleted )
continue;
if ( victim == vch && !victim->fighting )
{
multi_hit( victim, ch, TYPE_UNDEFINED );
break;
}
}
}
return;
}
void do_cast( CHAR_DATA *ch, char *argument )
{
void *vo;
OBJ_DATA *obj;
CHAR_DATA *victim;
char arg1 [ MAX_INPUT_LENGTH ];
char arg2 [ MAX_INPUT_LENGTH ];
int mana;
int sn;
bool IS_DIVINE;
/* int spec; */
/* char buf [ MAX_STRING_LENGTH ];*/
/* spec = skill_lookup( "astral walk" ); */
IS_DIVINE = FALSE;
target_name = one_argument( argument, arg1 );
if ( arg1[0] != '\0' )
if ( !str_prefix( arg1, "divine" ) && ch->level >= LEVEL_IMMORTAL )
{
IS_DIVINE = TRUE;
target_name = one_argument( target_name, arg1 );
}
one_argument( target_name, arg2 );
if ( arg1[0] == '\0' )
{
if ( prime_class(ch) != CLASS_BARD )
send_to_char(AT_BLUE, "Cast which what where?\n\r", ch );
else
send_to_char(AT_BLUE, "Sing what song?\n\r", ch );
return;
}
if ( IS_NPC( ch ) )
if ( IS_SET( ch->affected_by, AFF_CHARM ) )
return;
if ( !IS_NPC( ch ) )
if ( ( sn = skill_lookup( arg1 ) ) < 0
|| !can_use_skpell( ch, sn ) )
{
send_to_char(AT_BLUE, "You can't do that.\n\r", ch );
return;
}
if ( IS_AFFECTED( ch, AFF_MUTE ))
{
send_to_char(AT_WHITE, "You have been silenced.\n\r", ch);
return;
}
if ( IS_NPC( ch ) )
if ( ( sn = skill_lookup( arg1 ) ) < 0 )
return;
if ( ch->position < skill_table[sn].minimum_position )
{
send_to_char(AT_BLUE, "You can't concentrate enough.\n\r", ch );
return;
}
/*
if ( ch->level < LEVEL_IMMORTAL && ch->class == CLASS_VAMPIRE )
if ( !IS_SET( ch->in_room->room_flags, ROOM_INDOORS ) )
{
if ( time_info.hour > 6 && time_info.hour < 18 )
{
int chance;
chance = 15;
if (number_percent ( )< chance)
{
send_to_char(AT_RED, "The sun blocks your magic!\n\r", ch );
return;
}
}
}
*/
if ( IS_STUNNED( ch, STUN_MAGIC ) )
{
if ( prime_class(ch) != CLASS_BARD )
send_to_char(AT_LBLUE, "You're too stunned to cast spells.\n\r", ch );
else
send_to_char(AT_LBLUE, "You're too stunned to sing songs.\n\r", ch );
return;
}
if ( !IS_NPC( ch ) && ( !( ch->level > LEVEL_MORTAL ) ) )
{
mana = SPELL_COST( ch, sn );
if ( ch->race == RACE_ELF || ch->race == RACE_ELDER )
mana -= mana / 4;
}
else
mana = 0;
if ( skill_table[sn].spell_fun == spell_null )
{
send_to_char( AT_BLUE, "You can't do that.\n\r", ch );
return;
}
/*
* Locate targets.
*/
victim = NULL;
obj = NULL;
vo = NULL;
switch ( skill_table[sn].target )
{
default:
bug( "Do_cast: bad target for sn %d.", sn );
return;
case TAR_GROUP_OFFENSIVE:
case TAR_GROUP_DEFENSIVE:
case TAR_GROUP_ALL:
case TAR_GROUP_OBJ:
case TAR_GROUP_IGNORE:
group_cast( sn, URANGE( 1, ch->level, LEVEL_HERO ), ch, arg2 );
return;
case TAR_IGNORE:
break;
case TAR_CHAR_OFFENSIVE:
if ( IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) )
{
send_to_char( AT_BLUE, "You failed.\n\r", ch );
return;
}
if ( arg2[0] == '\0' )
{
if ( !( victim = ch->fighting ) )
{
if ( prime_class(ch) != CLASS_BARD )
send_to_char(AT_BLUE, "Cast the spell on whom?\n\r", ch );
else
send_to_char(AT_BLUE, "Sing the song to whom?\n\r", ch );
return;
}
}
else
{
if ( !( victim = get_char_room( ch, arg2 ) ) )
{
send_to_char(AT_BLUE, "They aren't here.\n\r", ch );
return;
}
}
if ( IS_AFFECTED(victim, AFF_PEACE) )
{
send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch);
return;
}
if ( IS_AFFECTED( ch, AFF_PEACE) )
{
affect_strip( ch, skill_lookup("aura of peace") );
REMOVE_BIT( ch->affected_by, AFF_PEACE );
}
if (is_safe(ch, victim ) )
{
send_to_char( AT_BLUE, "You failed.\n\r",ch);
return;
}
vo = (void *) victim;
break;
case TAR_CHAR_DEFENSIVE:
if ( arg2[0] == '\0' )
{
victim = ch;
}
else
{
if ( !( victim = get_char_room( ch, arg2 ) ) )
{
send_to_char(AT_BLUE, "They aren't here.\n\r", ch );
return;
}
}
vo = (void *) victim;
break;
case TAR_CHAR_SELF:
if ( arg2[0] != '\0' && !is_name( ch, arg2, ch->name ) )
{
if ( prime_class(ch) != CLASS_BARD )
send_to_char(AT_BLUE, "You cannot cast this spell on another.\n\r", ch );
else
send_to_char(AT_BLUE, "You cannot sing this song for others.\n\r", ch );
return;
}
vo = (void *) ch;
break;
case TAR_OBJ_INV:
if ( arg2[0] == '\0' )
{
send_to_char(AT_BLUE, "What should the spell be cast upon?\n\r", ch );
return;
}
if ( !(obj = get_obj_here( ch, arg2 ) ) )
{
send_to_char( AT_BLUE, "You can't find that.\n\r", ch );
return;
}
vo = (void *) obj;
break;
}
if ( !IS_NPC( ch ) )
if ( !is_class( ch, CLASS_VAMPIRE ) && ch->mana < mana )
{
send_to_char(AT_BLUE, "You don't have enough mana.\n\r", ch );
return;
}
else
if ( ( ch->bp < mana ) && ( is_class( ch, CLASS_VAMPIRE ) ) )
{
send_to_char(AT_RED, "You are to starved to cast, you must feed.\n\r", ch );
return;
}
if ( str_cmp( skill_table[sn].name, "ventriloquate" ) )
say_spell( ch, sn );
if ( IS_SET( ch->in_room->room_flags, ROOM_NO_MAGIC ) )
{
send_to_char( AT_BLUE, "You failed.\n\r", ch );
return;
}
if ( ( IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) ) && ( skill_table[sn].target == TAR_CHAR_OFFENSIVE ) )
{
send_to_char( AT_BLUE, "You failed.\n\r", ch );
return;
}
WAIT_STATE( ch, skill_table[sn].beats );
if ( !IS_NPC( ch ) )
if ( number_percent( ) > ch->pcdata->learned[sn] )
{
send_to_char(AT_BLUE, "You lost your concentration.\n\r", ch );
MT( ch ) -= mana / 2;
}
else
{
MT( ch ) -= mana;
if ( ( IS_AFFECTED2( ch, AFF_CONFUSED ) )
&& number_percent( ) < 10 )
{
act(AT_YELLOW, "$n looks around confused at what's going on.", ch, NULL, NULL, TO_ROOM );
send_to_char( AT_YELLOW, "You become confused and botch the spell.\n\r", ch );
return;
}
update_skpell( ch, sn );
(*skill_table[sn].spell_fun) ( sn,
IS_DIVINE ?
URANGE( 1, ch->level, LEVEL_HERO )*3 :
URANGE( 1, ch->level, LEVEL_HERO ) ,
ch, vo );
}
if ( IS_NPC( ch ) )
(*skill_table[sn].spell_fun) ( sn,
IS_DIVINE ?
URANGE( 1, ch->level, LEVEL_HERO )*3 :
URANGE( 1, ch->level, LEVEL_HERO ) ,
ch, vo );
if ( vo )
{
if ( skill_table[sn].target == TAR_OBJ_INV )
oprog_cast_sn_trigger( obj, ch, sn, vo );
rprog_cast_sn_trigger( ch->in_room, ch, sn, vo );
}
if ( skill_table[sn].target == TAR_CHAR_OFFENSIVE
&& victim->master != ch && victim != ch && IS_AWAKE( victim ) )
{
CHAR_DATA *vch;
for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
{
if ( vch->deleted )
continue;
if ( victim == vch && !victim->fighting )
{
multi_hit( victim, ch, TYPE_UNDEFINED );
break;
}
}
}
return;
}
/*
* Cast spells at targets using a magical object.
*/
void obj_cast_spell( int sn, int level, CHAR_DATA *ch, CHAR_DATA *victim,
OBJ_DATA *obj )
{
void *vo;
if ( sn <= 0 )
return;
if ( !is_sn(sn) || skill_table[sn].spell_fun == 0 )
{
bug( "Obj_cast_spell: bad sn %d.", sn );
return;
}
if ( IS_SET( ch->in_room->room_flags, ROOM_NO_MAGIC ) )
{
send_to_char( AT_BLUE, "The magic of the item fizzles.\n\r", ch );
return;
}
switch ( skill_table[sn].target )
{
default:
bug( "Obj_cast_spell: bad target for sn %d.", sn );
return;
case TAR_GROUP_OFFENSIVE:
case TAR_GROUP_DEFENSIVE:
case TAR_GROUP_ALL:
case TAR_GROUP_OBJ:
case TAR_GROUP_IGNORE:
group_cast( sn, URANGE( 1, level, LEVEL_HERO ), ch,
victim ? (void *)victim : (void *)obj );
return;
case TAR_IGNORE:
vo = NULL;
break;
case TAR_CHAR_OFFENSIVE:
if ( IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) )
{
send_to_char( AT_BLUE, "The magic of the item fizzles.\n\r", ch );
return;
}
if ( !victim )
victim = ch->fighting;
if ( !victim || ( !IS_NPC( victim ) && ch != victim ) )
{
send_to_char(AT_BLUE, "You can't do that.\n\r", ch );
return;
}
if ( ( ( ch->clan == 0 ) || ( ch->clan == 0 ) ) && ( !IS_NPC( victim ) ) )
return;
if ( IS_AFFECTED(victim, AFF_PEACE) )
{
send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch);
return;
}
if ( IS_AFFECTED( ch, AFF_PEACE) )
{
affect_strip( ch, skill_lookup("aura of peace") );
REMOVE_BIT( ch->affected_by, AFF_PEACE );
}
if ( ( ( ch->level - 9 > victim->level )
|| ( ch->level + 9 < victim->level ) )
&& ( !IS_NPC(victim) )
&& ( !IS_SET( victim->act2, PLR_WAR)))
{
send_to_char(AT_WHITE, "That is not in the pkill range... valid range is +/- 8 levels.\n\r", ch );
return;
}
vo = (void *) victim;
break;
case TAR_CHAR_DEFENSIVE:
if ( !victim )
victim = ch;
vo = (void *) victim;
break;
case TAR_CHAR_SELF:
vo = (void *) ch;
break;
case TAR_OBJ_INV:
if ( !obj )
{
send_to_char(AT_BLUE, "You can't do that.\n\r", ch );
return;
}
vo = (void *) obj;
break;
}
/* target_name = "";*/
(*skill_table[sn].spell_fun) ( sn, level, ch, vo );
if ( vo )
{
if ( skill_table[sn].target == TAR_OBJ_INV )
oprog_cast_sn_trigger( obj, ch, sn, vo );
rprog_cast_sn_trigger( ch->in_room, ch, sn, vo );
}
if ( skill_table[sn].target == TAR_CHAR_OFFENSIVE
&& victim->master != ch && ch != victim )
{
CHAR_DATA *vch;
for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
{
if ( vch->deleted )
continue;
if ( victim == vch && !victim->fighting )
{
multi_hit( victim, ch, TYPE_UNDEFINED );
break;
}
}
}
return;
}
/*
* Spell functions.
*/
void spell_acid_blast( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice( level, 8 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_animate( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
OBJ_DATA *obj_next;
if ( obj->item_type != ITEM_CORPSE_NPC )
{
send_to_char(AT_BLUE, "You cannot animate that.\n\r", ch );
return;
}
obj_next = obj->next;
if (obj->deleted)
return;
magic_mob( ch, obj, obj->ac_vnum );
extract_obj(obj);
return;
}
void spell_armor( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 24;
af.location = APPLY_AC;
af.modifier = -25;
af.bitvector = 0;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel someone protecting you.\n\r", victim );
return;
}
void spell_astral( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim;
CHAR_DATA *pet;
if ( !( victim = get_char_world( ch, target_name ) )
|| IS_SET( victim->in_room->room_flags, ROOM_SAFE )
|| IS_SET( victim->in_room->room_flags, ROOM_PRIVATE )
|| IS_SET( victim->in_room->room_flags, ROOM_SOLITARY )
|| IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_IN )
|| IS_SET( ch->in_room->room_flags, ROOM_NO_ASTRAL_OUT )
|| IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE )
|| IS_SET( victim->act, ACT_NOASTRAL )
|| IS_ARENA(ch)
|| victim->in_room->area == arena.area
|| IS_AFFECTED( victim, AFF_NOASTRAL ) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
for ( pet = ch->in_room->people; pet; pet = pet->next_in_room )
{
if ( IS_NPC( pet ) )
if ( IS_SET( pet->act, ACT_PET ) && ( pet->master == ch ) )
break;
}
act(AT_BLUE, "$n vanishes in a flash of blinding light.", ch, NULL, NULL, TO_ROOM );
if ( ch != victim )
{
if ( pet )
{
act( AT_BLUE, "$n vanishes in a flash of blinding light.", pet, NULL, NULL, TO_ROOM );
char_from_room( pet );
}
char_from_room( ch );
char_to_room( ch, victim->in_room );
}
act(AT_BLUE, "$n appears in a flash of blinding light.", ch, NULL,
NULL, TO_ROOM );
do_look( ch, "auto" );
if ( pet )
{
char_to_room( pet, victim->in_room );
act( AT_BLUE, "$n appears in a flash of blinding light.", pet, NULL, NULL, TO_ROOM );
}
return;
}
void spell_pass_plant ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim ;
CHAR_DATA *pet;
if ( IS_AFFECTED( ch, AFF_ANTI_FLEE ) )
{
send_to_char( AT_WHITE, "You cannot walk through the plants in your condition!\n\r", ch );
return;
}
if ( ch->in_room->sector_type == SECT_INSIDE
|| ch->in_room->sector_type == SECT_CITY
|| ch->in_room->sector_type == SECT_AIR
)
{
send_to_char(AT_GREEN, "There are no plants here.\n\r", ch );
return;
}
if ( IS_SET( ch->in_room->room_flags, ROOM_NO_SHADOW ) )
{
send_to_char(AT_GREEN, "The plants do not respond to your call.\n\r", ch);
return;
}
if ( !( victim = get_char_world( ch, target_name ) )
|| victim->in_room->area != ch->in_room->area
|| IS_SET( victim->in_room->room_flags, ROOM_PRIVATE )
|| IS_SET( victim->in_room->room_flags, ROOM_SOLITARY )
|| victim->in_room->sector_type == SECT_INSIDE
|| victim->in_room->sector_type == SECT_CITY
|| victim->in_room->sector_type == SECT_AIR
|| IS_AFFECTED( victim, AFF_NOASTRAL ) )
{
send_to_char(AT_GREEN, "The plants do not reach there.\n\r", ch );
return;
}
for ( pet = ch->in_room->people; pet; pet = pet->next_in_room )
{
if ( IS_NPC( pet ) )
if ( IS_SET( pet->act, ACT_PET ) && ( pet->master == ch ) )
break;
}
if ( ch != victim )
{
act(AT_GREEN, "$n melts into the surrounding plant life.", ch, NULL, NULL, TO_ROOM );
char_from_room( ch );
char_to_room( ch, victim->in_room );
act(AT_GREEN, "$n steps out of the surrounding plant life.", ch, NULL, NULL, TO_ROOM );
if ( pet )
{
act( AT_BLUE, "$n melts into the surrounding plant life.", pet, NULL, NULL, TO_ROOM );
char_from_room( pet );
char_to_room( pet, victim->in_room );
act( AT_BLUE, "$n steps out of the surrounding plant life.", pet, NULL, NULL, TO_ROOM );
}
}
do_look( ch, "auto" );
return;
}
void spell_aura( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_PEACE) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 8 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PEACE;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "You feel a wave of peace flow lightly over your body.\n\r", victim );
act(AT_BLUE, "$n looks very peaceful.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_bless( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 6 + level;
af.location = APPLY_HITROLL;
af.modifier = level / 8;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = 0 - level / 8;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel righteous.\n\r", victim );
return;
}
void spell_darkbless( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 20 + level;
af.location = APPLY_DAMROLL;
af.modifier = level / 6;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level * 3;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "You call forth the hand of oblivion.\n\r", ch );
send_to_char(AT_BLUE, "The hand of oblivion rests upon you.\n\r", victim );
return;
}
void spell_aid( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 8 + level;
af.location = APPLY_HITROLL;
af.modifier = level / 6;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = 0 - level / 6;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level * 3;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "You grant them divine aid.\n\r", ch );
send_to_char(AT_BLUE, "You feel divine aid reashure you.\n\r", victim );
return;
}
void spell_bio_acceleration( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 20 + level;
af.location = APPLY_HIT;
af.modifier = number_fuzzy ( level * 4 );
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_MOVE;
af.modifier = level * 2;
affect_to_char( victim, &af );
send_to_char( AT_BLUE, "You greatly enhance your bio-functions.\n\r", ch );
act(AT_BLUE, "$n's body shudders briefly.", ch, NULL, NULL, TO_ROOM);
return;
}
/*Decklarean*/
void spell_draw_strength( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( victim->position == POS_FIGHTING || is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 20 + level;
af.location = APPLY_MANA;
af.modifier = number_fuzzy ( level * 4 );
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = -af.modifier;
affect_to_char( victim, &af );
/* They still have hitpoints over there max hit points
get ride of them */
if ( MAX_HIT(victim) < victim->hit )
victim->hit = MAX_HIT(victim);
send_to_char( AT_BLUE, "You draw from your physical strength and
increase your energy reserve.\n\r", ch );
act(AT_BLUE, "$n's body weakens.", ch, NULL, NULL, TO_ROOM);
return;
}
/*
void spell_barkskin( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, sn))
return;
af.type = sn;
af.duration = 35;
af.location = APPLY_AC;
af.modifier = -30;
af.bitvector = 0;
affect_to_char( victim, &af);
af.location = APPLY_SAVING_SPELL;
af.modifier = 0 - LEVEL / 12;
affect_to_char( victim, &af);
if ( ch != victim )
send_to_char( "Ok.\n\r", ch );
send_to_char( "Your skin turns into a bark-like texture.\n\r",
victim, );
return;
}
*/
void spell_blindness( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_BLIND ) || saves_spell( level, victim ) )
{
send_to_char(AT_BLUE, "You have failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = 5;
af.location = APPLY_HITROLL;
af.modifier = -10;
af.bitvector = AFF_BLIND;
affect_to_char( victim, &af );
act(AT_WHITE, "$N is blinded!", ch, NULL, victim, TO_CHAR );
send_to_char(AT_WHITE, "You are blinded!\n\r", victim );
act(AT_WHITE, "$N is blinded!", ch, NULL, victim, TO_NOTVICT );
return;
}
void spell_blood_bath( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim;
if ( blood_count( ch->in_room->contents, 5 ) < 2 )
{
send_to_char( AT_RED, "There is not enough blood in the room.\n\r", ch );
return;
}
for ( victim = ch->in_room->people; victim; victim = victim->next_in_room )
{
if ( victim->deleted )
continue;
if ( IS_NPC( victim ) )
continue;
victim->hit = UMIN( victim->hit + 250, MAX_HIT(victim) );
update_pos( victim );
act( AT_RED, "You bath $N in the life giving fluid.", ch, NULL, victim, TO_CHAR );
act( AT_RED, "$n baths $N in blood.", ch, NULL, victim, TO_ROOM );
act( AT_RED, "$n baths you in blood.", ch, NULL, victim, TO_VICT );
}
send_to_char( AT_RED, "The blood bath is over.\n\r", ch );
return;
}
void spell_burning_hands( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 14, 17, 20, 23, 26, 29,
29, 29, 30, 30, 31, 31, 32, 32, 33, 33,
34, 34, 35, 35, 36, 36, 37, 37, 38, 38,
39, 39, 40, 40, 41, 41, 42, 42, 43, 43,
44, 44, 45, 45, 46, 46, 47, 47, 48, 48,
48, 48, 49, 49, 49, 49, 50, 50, 50, 51,
51, 51, 52, 52, 52, 53, 53, 53, 54, 54,
54, 54, 54, 54, 55, 55, 55, 55, 55, 55,
56, 56, 56, 56, 56, 57, 57, 58, 59, 60
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_call_lightning( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
int dam;
if ( !IS_OUTSIDE( ch ) )
{
send_to_char(AT_WHITE, "You must be out of doors.\n\r", ch );
return;
}
if ( weather_info.sky < SKY_RAINING )
{
send_to_char(AT_WHITE, "You need bad weather.\n\r", ch );
return;
}
dam = dice( level / 2, 8 );
send_to_char(AT_WHITE, "Lightning slashes out of the sky to strike your foes!\n\r", ch );
act(AT_WHITE, "$n calls lightning from the sky to strike $s foes!",
ch, NULL, NULL, TO_ROOM );
for ( vch = char_list; vch; vch = vch->next )
{
if ( vch->deleted || !vch->in_room )
continue;
if ( vch->in_room == ch->in_room )
{
if ( vch != ch
&& ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) ) )
{
dam = sc_dam( ch, dam );
damage( ch, vch, saves_spell( level, vch ) ? dam/2 : dam, sn );
}
continue;
}
if ( vch->in_room->area == ch->in_room->area
&& IS_OUTSIDE( vch )
&& IS_AWAKE( vch ) )
send_to_char(AT_LBLUE, "Lightning flashes in the sky.\n\r", vch );
}
return;
}
void spell_cause_light( int sn, int level, CHAR_DATA *ch, void *vo )
{
int dam = dice( 1, 8 ) + level / 3;
dam = sc_dam( ch, dam );
damage( ch, (CHAR_DATA *) vo, dam, sn );
return;
}
void spell_cause_critical( int sn, int level, CHAR_DATA *ch, void *vo )
{
int dam = dice( 3, 8 ) + level - 6;
dam = sc_dam( ch, dam );
damage( ch, (CHAR_DATA *) vo, dam, sn );
return;
}
void spell_cause_serious( int sn, int level, CHAR_DATA *ch, void *vo )
{
int dam = dice( 2, 8 ) + level / 2;
dam = sc_dam( ch, dam );
damage( ch, (CHAR_DATA *) vo, dam, sn );
return;
}
void spell_change_sex( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
af.type = sn;
af.level = level;
af.duration = 10 * level;
af.location = APPLY_SEX;
do
{
af.modifier = number_range( 0, 2 ) - victim->sex;
}
while ( af.modifier == 0 );
af.bitvector = 0;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_WHITE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel different.\n\r", victim );
return;
}
void spell_charm_person( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( victim == ch )
{
send_to_char(AT_BLUE, "You like yourself even better!\n\r", ch );
return;
}
if ( !IS_NPC( victim ) )
return;
if ( IS_AFFECTED( victim, AFF_CHARM )
|| IS_AFFECTED( ch, AFF_CHARM )
|| level < victim->level
|| saves_spell( level, victim ) )
return;
if(IS_SIMM(victim, IMM_CHARM))
return;
if ( victim->master )
stop_follower( victim );
add_follower( victim, ch );
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 6 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "Ok.\n\r", ch );
act(AT_BLUE, "Isn't $n just so nice?", ch, NULL, victim, TO_VICT );
return;
}
void spell_chill_touch( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
static const int dam_each [ ] =
{
0,
0, 0, 6, 7, 8, 9, 12, 13, 13, 13,
14, 14, 14, 15, 15, 15, 16, 16, 16, 17,
17, 17, 18, 18, 18, 19, 19, 19, 20, 20,
20, 21, 21, 21, 22, 22, 22, 23, 23, 23,
24, 24, 24, 25, 25, 25, 26, 26, 26, 27,
27, 27, 27, 28, 28, 28, 29, 29, 29, 30,
30, 30, 31, 31, 31, 32, 32, 33, 33, 33,
34, 34, 34, 35, 35, 35, 36, 36, 36, 37,
37, 37, 37, 37, 38, 38, 38, 38, 39, 39,
39, 39, 39, 40, 40, 40, 41, 41, 42, 43
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( !saves_spell( level, victim ) )
{
af.type = sn;
af.level = level;
af.duration = 6;
af.location = APPLY_STR;
af.modifier = -1;
af.bitvector = 0;
affect_join( victim, &af );
}
else
{
dam /= 2;
}
damage( ch, victim, dam, sn );
return;
}
void spell_colour_spray( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
30, 35, 40, 45, 50, 55, 55, 55, 56, 57,
58, 58, 59, 60, 61, 61, 62, 63, 64, 64,
65, 66, 67, 67, 68, 69, 70, 70, 71, 72,
73, 73, 74, 75, 76, 76, 77, 78, 79, 79,
79, 80, 80, 81, 81, 82, 82, 83, 83, 84,
84, 85, 85, 86, 86, 87, 87, 88, 88, 90,
90, 91, 91, 92, 92, 93, 93, 94, 94, 95,
95, 96, 96, 97, 97, 98, 98, 99, 99, 100,
100,101,102,102,103, 104,105,106,107,120
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_continual_light( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *light;
light = create_object( get_obj_index( OBJ_VNUM_LIGHT_BALL ), 0 );
obj_to_room( light, ch->in_room );
act(AT_BLUE, "You twiddle your thumbs and $p appears.", ch, light, NULL, TO_CHAR );
act(AT_BLUE, "$n twiddles $s thumbs and $p appears.", ch, light, NULL, TO_ROOM );
return;
}
void spell_control_weather( int sn, int level, CHAR_DATA *ch, void *vo )
{
if ( !str_cmp( target_name, "better" ) )
weather_info.change += dice( level / 3, 4 );
else if ( !str_cmp( target_name, "worse" ) )
weather_info.change -= dice( level / 3, 4 );
else
send_to_char (AT_BLUE, "Do you want it to get better or worse?\n\r", ch );
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
void spell_create_food( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *mushroom;
mushroom = create_object( get_obj_index( OBJ_VNUM_MUSHROOM ), 0 );
mushroom->value[0] = 5 + level;
obj_to_room( mushroom, ch->in_room );
act(AT_ORANGE, "$p suddenly appears.", ch, mushroom, NULL, TO_CHAR );
act(AT_ORANGE, "$p suddenly appears.", ch, mushroom, NULL, TO_ROOM );
return;
}
void spell_create_spring( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *spring;
spring = create_object( get_obj_index( OBJ_VNUM_SPRING ), 0 );
spring->timer = level;
obj_to_room( spring, ch->in_room );
act(AT_BLUE, "$p flows from the ground.", ch, spring, NULL, TO_CHAR );
act(AT_BLUE, "$p flows from the ground.", ch, spring, NULL, TO_ROOM );
return;
}
void spell_create_water( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
int water;
if ( obj->item_type != ITEM_DRINK_CON )
{
send_to_char(AT_BLUE, "It is unable to hold water.\n\r", ch );
return;
}
if ( obj->value[2] != LIQ_WATER && obj->value[1] != 0 )
{
send_to_char(AT_BLUE, "It contains some other liquid.\n\r", ch );
return;
}
water = UMIN( level * ( weather_info.sky >= SKY_RAINING ? 4 : 2 ),
obj->value[0] - obj->value[1] );
if ( water > 0 )
{
obj->value[2] = LIQ_WATER;
obj->value[1] += water;
if ( !is_name( NULL, "water", obj->name ) )
{
char buf [ MAX_STRING_LENGTH ];
sprintf( buf, "%s water", obj->name );
free_string( obj->name );
obj->name = str_dup( buf );
}
act(AT_BLUE, "$p is filled.", ch, obj, NULL, TO_CHAR );
}
return;
}
void spell_cure_blindness( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( !is_affected( victim, gsn_blindness ) )
return;
affect_strip( victim, gsn_blindness );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_WHITE, "Your vision returns!\n\r", victim );
return;
}
void spell_cure_critical( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = dice( 3, 8 ) + level - 6;
if ( ch->race == RACE_ANGEL )
heal = heal * 2;
victim->hit = UMIN( victim->hit + heal, MAX_HIT(victim)) ;
update_pos( victim );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel better!\n\r", victim );
return;
}
void spell_cure_light( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = dice( 1, 8 ) + level / 3;
if ( ch->race == RACE_ANGEL )
heal = heal * 2;
victim->hit = UMIN( victim->hit + heal, MAX_HIT(victim));
update_pos( victim );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel better!\n\r", victim );
return;
}
void spell_cure_poison( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( !is_affected( victim, gsn_poison ) )
return;
affect_strip( victim, gsn_poison );
send_to_char(AT_GREEN, "Ok.\n\r", ch );
send_to_char(AT_GREEN, "A warm feeling runs through your body.\n\r", victim );
act(AT_GREEN, "$N looks better.", ch, NULL, victim, TO_NOTVICT );
return;
}
void spell_cure_serious( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = dice( 2, 8 ) + level / 2 ;
if ( ch->race == RACE_ANGEL )
heal = heal * 2;
victim->hit = UMIN( victim->hit + heal, MAX_HIT(victim));
update_pos( victim );
send_to_char(AT_BLUE, "You feel better!\n\r", victim );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
void spell_curse( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_CURSE ) || saves_spell( level, victim ) )
{
send_to_char(AT_RED, "You have failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = 4 * level;
af.location = APPLY_HITROLL;
af.modifier = -1;
af.bitvector = AFF_CURSE;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = 1;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_RED, "Ok.\n\r", ch );
send_to_char(AT_RED, "You feel unclean.\n\r", victim );
return;
}
void spell_detect_evil( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_DETECT_EVIL ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DETECT_EVIL;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "Your eyes tingle.\n\r", victim );
return;
}
void spell_detect_hidden( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_DETECT_HIDDEN ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DETECT_HIDDEN;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "Your awareness improves.\n\r", victim );
return;
}
void spell_detect_invis( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_DETECT_INVIS ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DETECT_INVIS;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "Your eyes tingle.\n\r", victim );
return;
}
void spell_truesight( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2( victim, AFF_TRUESIGHT ) )
return;
af.type = sn;
af.level = level;
af.duration = level / 8;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_TRUESIGHT;
affect_to_char2( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "Your eyes tingle.\n\r", victim );
return;
}
void spell_detect_magic( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_DETECT_MAGIC ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DETECT_MAGIC;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "Your eyes tingle.\n\r", victim );
return;
}
void spell_detect_poison( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if ( obj->item_type == ITEM_DRINK_CON || obj->item_type == ITEM_FOOD )
{
if ( obj->value[3] != 0 )
send_to_char(AT_GREEN, "You smell poisonous fumes.\n\r", ch );
else
send_to_char(AT_GREEN, "It looks very delicious.\n\r", ch );
}
else
{
send_to_char(AT_GREEN, "It looks very delicious.\n\r", ch );
}
return;
}
/* Dispel Magic recoded by Thelonius for EnvyMud
look for the improved version below
void spell_dispel_magic ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA *paf;
if ( (victim == ch) || !IS_NPC( ch )
&& ( !IS_NPC( victim )
|| ( IS_AFFECTED( victim, AFF_CHARM )
&& is_same_group( ch, victim->master ) ) ) )
{
for ( paf = victim->affected; paf; paf = paf->next )
{
if ( paf->deleted )
continue;
affect_remove( victim, paf );
}
}
if ( victim == ch )
{
act(AT_BLUE, "You have removed all magic effects from yourself.",
ch, NULL, NULL, TO_CHAR );
act(AT_BLUE, "$n has removed all magic effects from $mself.",
ch, NULL, NULL, TO_ROOM );
}
else
{
act(AT_BLUE, "You have removed all magic effects from $N.",
ch, NULL, victim, TO_CHAR );
act(AT_BLUE, "$n has removed all magic effects from you.",
ch, NULL, victim, TO_VICT );
act(AT_BLUE, "$n has removed all magic effects from $N.",
ch, NULL, victim, TO_NOTVICT );
}
return;
}
else
{
for ( paf = victim->affected; paf; paf = paf->next )
{
if ( paf->deleted )
continue;
if ( !saves_spell( level, victim ) )
{
send_to_char(AT_BLUE, skill_table[paf->type].msg_off, victim );
send_to_char(AT_BLUE, "\n\r", victim );
act(AT_BLUE, "$n is no longer affected by '$t'.",
victim, skill_table[paf->type].name, NULL, TO_ROOM );
affect_strip( victim, paf->type );
break;
}
}
if ( IS_AFFECTED( victim, AFF_SANCTUARY)
&& !saves_spell( level, victim ) )
{
REMOVE_BIT( victim->affected_by, AFF_SANCTUARY );
send_to_char(AT_GREY, "The white aura around your body fades.\n\r",
victim );
act(AT_GREY, "The white aura around $n's body fades.",
victim, NULL, NULL, TO_ROOM );
}
if ( IS_AFFECTED( victim, AFF_FIRESHIELD)
&& !saves_spell( level, victim ) )
{
REMOVE_BIT( victim->affected_by, AFF_FIRESHIELD );
send_to_char(AT_RED, "The flames about your body have been doused.\n\r",
victim );
act(AT_RED, "The flames about $n's body burn out.",
victim, NULL, NULL, TO_ROOM );
}
if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD)
&& !saves_spell( level, victim ) )
{
REMOVE_BIT( victim->affected_by, AFF_SHOCKSHIELD );
send_to_char(AT_BLUE, "The electricity about your body flee's into the ground..\n\r",
victim );
act(AT_BLUE, "The electricity about $n's body flee's into the ground.",
victim, NULL, NULL, TO_ROOM );
}
if ( IS_AFFECTED( victim, AFF_ICESHIELD)
&& !saves_spell( level, victim ) )
{
REMOVE_BIT( victim->affected_by, AFF_ICESHIELD );
send_to_char(AT_LBLUE, "The icy crust about your body melts to a puddle..\n\r",
victim );
act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.",
victim, NULL, NULL, TO_ROOM );
}
if ( !victim->fighting || !is_same_group( ch, victim->fighting ) )
multi_hit( victim, ch, TYPE_UNDEFINED );
}
return;
}
*/
void spell_dispel_evil( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if ( !IS_NPC( ch ) && IS_EVIL( ch ) )
{
send_to_char(AT_RED, "You are too EVIL to cast this.\n\r", ch );
return;
}
if ( IS_GOOD( victim ) )
{
act(AT_BLUE, "God protects $N.", ch, NULL, victim, TO_ROOM );
return;
}
if ( IS_NEUTRAL( victim ) )
{
act(AT_BLUE, "$N does not seem to be affected.", ch, NULL, victim, TO_CHAR );
return;
}
dam = dice( level, 4 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_earthquake( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
send_to_char(AT_ORANGE, "The earth trembles beneath your feet!\n\r", ch );
act(AT_ORANGE, "$n makes the earth tremble and shiver.", ch, NULL, NULL, TO_ROOM );
for ( vch = char_list; vch; vch = vch->next )
{
if ( vch->deleted || !vch->in_room )
continue;
if ( vch->in_room == ch->in_room )
{
if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch )
: IS_NPC( vch ) ) )
damage( ch, vch, level + dice( 2, 8 ), sn );
continue;
}
if ( vch->in_room->area == ch->in_room->area )
send_to_char(AT_ORANGE, "The earth trembles and shivers.\n\r", vch );
}
return;
}
void spell_chain_lightning( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
send_to_char(AT_BLUE, "Bolts of electricity arc from your hands!\n\r", ch );
act(AT_BLUE, "Electrical energy bursts from $n's hands.", ch, NULL, NULL, TO_ROOM );
for ( vch = char_list; vch; vch = vch->next )
{
if ( vch->deleted || !vch->in_room )
continue;
if ( vch->in_room == ch->in_room )
{
if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch )
: IS_NPC( vch ) ) )
damage( ch, vch, level + dice( level, 6 ), sn );
continue;
}
if ( vch->in_room->area == ch->in_room->area )
send_to_char(AT_BLUE, "The air fills with static.\n\r", vch );
}
return;
}
/* RT version of chain
void spell_chain_lightning(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
CHAR_DATA *tmp_vict,*last_vict,*next_vict;
bool found;
int dam;
* first strike *
act(AT_BLUE, "A lightning bolt leaps from $n's hand and arcs to $N.",
ch,NULL,victim,TO_ROOM);
act(AT_BLUE, "A lightning bolt leaps from your hand and arcs to $N.",
ch,NULL,victim,TO_CHAR);
act(AT_BLUE, "A lightning bolt leaps from $n's hand and hits you!",
ch,NULL,victim,TO_VICT);
dam = level + dice(level,6);
if (saves_spell(level,victim))
dam /= 3;
damage(ch,victim,dam,sn);*,DAM_LIGHTNING);*
last_vict = victim;
level -= 4; * decrement damage *
* new targets *
while (level > 0)
{
found = FALSE;
for (tmp_vict = ch->in_room->people;
tmp_vict != NULL;
tmp_vict = next_vict)
{
if(tmp_vect->deleted) continue;
next_vict = tmp_vict->next_in_room;
if (*!is_safe_spell(ch,tmp_vict,TRUE) &&* tmp_vict != last_vict)
{
found = TRUE;
last_vict = tmp_vict;
act(AT_BLUE, "The bolt arcs to $n!",tmp_vict,NULL,NULL,TO_ROOM);
act(AT_BLUE, "The bolt hits you!",tmp_vict,NULL,NULL,TO_CHAR);
dam = level + dice(level,6);
if (saves_spell(level,tmp_vict))
dam /= 3;
damage(ch,tmp_vict,dam,sn);*,DAM_LIGHTNING);*
level -= 4; * decrement damage *
}
} * end target searching loop *
if (!found) * no target found, hit the caster *
{
if (ch == NULL)
return;
if (last_vict == ch) * no double hits *
{
act(AT_BLUE,
"The bolt seems to have fizzled out.",ch,NULL,NULL,TO_ROOM);
act(AT_BLUE, "The bolt grounds out through your body.",
ch,NULL,NULL,TO_CHAR);
return;
}
last_vict = ch;
act(AT_BLUE, "The bolt arcs to $n...whoops!",ch,NULL,NULL,TO_ROOM);
send_to_char(AT_BLUE, "You are struck by your own lightning!\n\r",ch);
dam = level + dice(level,6);
if (saves_spell(level,ch))
dam /= 3;
damage(ch,ch,dam,sn);*,DAM_LIGHTNING);*
level -= 4; * decrement damage *
if (ch == NULL)
return;
}
* now go back and find more targets *
}
}
*/
void spell_meteor_swarm( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
AFFECT_DATA af;
send_to_char(AT_RED, "Flaming meteors fly forth from your outstreched hands!\n\r", ch );
act(AT_RED, "Hundreds of flaming meteors fly forth from $n's hands.", ch, NULL, NULL, TO_ROOM );
for ( vch = char_list; vch; vch = vch->next )
{
if ( vch->deleted || !vch->in_room )
continue;
if ( vch->in_room == ch->in_room )
{
if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch )
: IS_NPC( vch ) ) )
damage( ch, vch, level + dice( level, 8 ), sn );
if ( vch != ch )
{
af.type = sn;
af.level = level;
af.duration = level / 8;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FLAMING;
affect_join( vch, &af );
send_to_char(AT_RED, "You body bursts into flame!\n\r", vch);
}
continue;
}
}
return;
}
void spell_enchant_weapon( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
AFFECT_DATA *paf;
if ( obj->item_type != ITEM_WEAPON
|| IS_OBJ_STAT( obj, ITEM_MAGIC )
|| ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) )
{
send_to_char(AT_BLUE, "That item cannot be enchanted.\n\r", ch );
return;
}
if ( !affect_free )
{
paf = alloc_perm( sizeof( *paf ) );
}
else
{
paf = affect_free;
affect_free = affect_free->next;
}
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_HITROLL;
paf->modifier = 1 + (level >= 18) + (level >= 25) + (level >= 45) + (level >= 65) +(level >= 90);
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
if ( !affect_free )
{
paf = alloc_perm( sizeof( *paf ) );
}
else
{
paf = affect_free;
affect_free = affect_free->next;
}
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_DAMROLL;
paf->modifier = 1 + (level >= 18) + (level >= 25) + (level >= 45) + (level >= 65) +(level >= 90);;
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
if ( IS_GOOD( ch ) )
{
SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL);
act(AT_BLUE, "$p glows.", ch, obj, NULL, TO_CHAR );
}
else if ( IS_EVIL( ch ) )
{
SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD );
act(AT_RED, "$p glows", ch, obj, NULL, TO_CHAR );
}
else
{
SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL );
SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD );
act(AT_YELLOW, "$p glows.", ch, obj, NULL, TO_CHAR );
}
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
void spell_flame_blade( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if ( obj->item_type != ITEM_WEAPON
|| IS_OBJ_STAT( obj, ITEM_MAGIC )
|| IS_OBJ_STAT( obj, ITEM_FLAME )
|| ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) )
{
send_to_char(AT_RED, "That item cannot be enchanted.\n\r", ch );
return;
}
SET_BIT( obj->extra_flags, ITEM_MAGIC);
SET_BIT( obj->extra_flags, ITEM_FLAME );
send_to_char(AT_RED, "Ok.\n\r", ch );
return;
}
void spell_chaos_blade( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if ( obj->item_type != ITEM_WEAPON
|| IS_OBJ_STAT( obj, ITEM_MAGIC )
|| IS_OBJ_STAT( obj, ITEM_CHAOS )
|| ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) )
{
send_to_char(AT_YELLOW, "That item cannot be enchanted.\n\r", ch );
return;
}
SET_BIT( obj->extra_flags, ITEM_MAGIC);
SET_BIT( obj->extra_flags, ITEM_CHAOS );
send_to_char(AT_YELLOW, "Ok.\n\r", ch );
return;
}
void spell_frost_blade( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
if ( obj->item_type != ITEM_WEAPON
|| IS_OBJ_STAT( obj, ITEM_MAGIC )
|| IS_OBJ_STAT( obj, ITEM_ICY )
|| ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) )
{
send_to_char(AT_LBLUE, "That item cannot be enchanted.\n\r", ch );
return;
}
SET_BIT( obj->extra_flags, ITEM_MAGIC);
SET_BIT( obj->extra_flags, ITEM_ICY );
send_to_char(AT_LBLUE, "Ok.\n\r", ch );
return;
}
void spell_holysword( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
AFFECT_DATA *paf;
if ( obj->item_type != ITEM_WEAPON
|| IS_OBJ_STAT( obj, ITEM_MAGIC )
|| ( obj->affected && !IS_OBJ_STAT( obj, ITEM_DWARVEN ) ) )
{
send_to_char(AT_BLUE, "That item cannot be consecrated.\n\r", ch );
return;
}
if ( !affect_free )
{
paf = alloc_perm( sizeof( *paf ) );
}
else
{
paf = affect_free;
affect_free = affect_free->next;
}
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_HITROLL;
paf->modifier = 6 + (level >= 18) + (level >= 25) + (level >= 40) + (level >= 60) +(level >= 90);
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
if ( !affect_free )
{
paf = alloc_perm( sizeof( *paf ));
}
else
{
paf = affect_free;
affect_free = affect_free->next;
}
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_DAMROLL;
paf->modifier = 6 + (level >= 18) + (level >= 25) + (level >= 45) + (level >= 65) +(level >= 90);;
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
if ( IS_GOOD( ch ) )
{
SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL);
act(AT_BLUE, "$p glows.", ch, obj, NULL, TO_CHAR );
}
else if ( IS_EVIL( ch ) )
{
SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD );
act(AT_RED, "$p glows", ch, obj, NULL, TO_CHAR );
}
else
{
SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL );
SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD );
act(AT_YELLOW, "$p glows.", ch, obj, NULL, TO_CHAR );
}
SET_BIT( obj->anti_class_flags, ITEM_ANTI_WARRIOR );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_MAGE );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_BARD );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_RANGER );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_VAMP );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_DRUID );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_PSI );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_THIEF );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_NECRO );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_WWF );
SET_BIT( obj->anti_class_flags, ITEM_ANTI_MONK );
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
/*
* Drain XP, MANA, HP.
* Caster gains HP.
*/
void spell_energy_drain( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if ( saves_spell( level, victim ) )
return;
/* ch->alignment = UMAX(-1000, ch->alignment - 200); */
if ( victim->level <= 2 )
{
dam = ch->hit + 1;
}
else
{
victim->mana /= 2;
victim->move /= 2;
dam = dice( 4, level );
if ( ( ch->hit + dam ) > ( MAX_HIT(ch) + 200 ) )
ch->hit = ( MAX_HIT(ch) + 200 );
else
ch->hit += dam;
}
dam = sc_dam( ch, dam );
damage( ch, victim, dam, sn );
return;
}
void spell_psychic_quake( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
send_to_char(AT_YELLOW, "You let the chaos free from your mind!\n\r", ch );
act(AT_YELLOW, "$n's face becomes blank and concentrated.", ch, NULL, NULL, TO_ROOM );
for ( vch = char_list; vch; vch = vch->next )
{
if ( vch->deleted || !vch->in_room )
continue;
if ( vch->in_room == ch->in_room )
{
if ( vch != ch && ( IS_NPC( ch ) ? !IS_NPC( vch )
: IS_NPC( vch ) ) )
if (vch != ch )
spell_energy_drain(sn, level/2, ch, vch);
continue;
}
if ( vch->in_room->area == ch->in_room->area )
send_to_char(AT_BLUE, "A wave of chaos brushes your mind.\n\r", vch );
}
return;
}
void spell_farsight( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim;
ROOM_INDEX_DATA *blah;
if ( !( victim = get_char_world( ch, target_name ) )
|| IS_SET( victim->in_room->room_flags, ROOM_SAFE )
|| IS_SET( victim->in_room->room_flags, ROOM_PRIVATE )
|| IS_SET( victim->in_room->room_flags, ROOM_SOLITARY )
|| IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_IN )
|| IS_SET( ch->in_room->room_flags, ROOM_NO_ASTRAL_OUT ) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
blah = ch->in_room;
if ( ch != victim )
{
char_from_room( ch );
char_to_room( ch, victim->in_room );
}
do_look( ch, "auto" );
if (ch != victim )
{
char_from_room( ch );
char_to_room( ch, blah );
}
return;
}
void spell_fireball( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 30, 35, 40, 45, 50, 55,
60, 65, 70, 75, 80, 82, 84, 86, 88, 90,
92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
112, 114, 116, 118, 120, 122, 124, 126, 128, 130,
132, 134, 136, 138, 140, 142, 144, 146, 148, 150,
152, 154, 156, 158, 160, 162, 164, 166, 168, 170,
172, 174, 176, 178, 180, 182, 184, 186, 188, 190,
192, 194, 196, 198, 200, 202, 204, 206, 208, 210,
215, 220, 225, 230, 235, 240, 245, 250, 255, 260
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 7 );
dam = sc_dam( ch, dam );
if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) )
dam /= 6;
if ( IS_AFFECTED( victim, AFF_ICESHIELD ) )
dam += dam/2;
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_molecular_unbind( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
if(saves_spell ( level, victim ))
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next )
{
char *msg;
obj_next = obj_lose->next_content;
if ( obj_lose->deleted )
continue;
if ( obj_lose->wear_loc == WEAR_NONE )
continue;
if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) )
continue;
switch ( obj_lose->item_type )
{
default:
msg = "Your $p gets ruined!";
extract_obj( obj_lose );
break;
case ITEM_DRINK_CON:
case ITEM_POTION:
case ITEM_CONTAINER:
case ITEM_LIGHT:
msg = "Your $p shatters!";
extract_obj( obj_lose );
break;
case ITEM_WEAPON:
case ITEM_ARMOR:
{
OBJ_DATA *pObj;
OBJ_INDEX_DATA *pObjIndex;
char *name;
char buf[MAX_STRING_LENGTH];
pObjIndex = get_obj_index(4);
pObj = create_object(pObjIndex, obj_lose->level);
name = obj_lose->short_descr;
sprintf(buf, pObj->description, name);
free_string(pObj->description);
pObj->description = str_dup(buf);
pObj->weight = obj_lose->weight;
pObj->timer = obj_lose->level;
msg = "$p has been destroyed!";
extract_obj( obj_lose );
obj_to_room ( pObj, victim->in_room );
break;
act(AT_YELLOW, msg, victim, obj_lose, NULL, TO_CHAR );
}
}
}
return;
}
void spell_shatter( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
if(saves_spell ( level, victim ))
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next )
{
char *msg;
obj_next = obj_lose->next_content;
if ( obj_lose->deleted )
continue;
if ( obj_lose->wear_loc == WEAR_NONE )
continue;
if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) )
continue;
switch ( obj_lose->item_type )
{
default:
msg = "Your $p gets ruined!";
extract_obj( obj_lose );
break;
case ITEM_DRINK_CON:
case ITEM_POTION:
case ITEM_CONTAINER:
case ITEM_LIGHT:
msg = "Your $p shatters!";
extract_obj( obj_lose );
break;
case ITEM_WEAPON:
case ITEM_ARMOR:
{
OBJ_DATA *pObj;
OBJ_INDEX_DATA *pObjIndex;
char *name;
char buf[MAX_STRING_LENGTH];
pObjIndex = get_obj_index(4);
pObj = create_object(pObjIndex, obj_lose->level);
name = obj_lose->short_descr;
sprintf(buf, pObj->description, name);
free_string(pObj->description);
pObj->description = str_dup(buf);
pObj->weight = obj_lose->weight;
pObj->timer = obj_lose->level;
msg = "$p has been destroyed!";
extract_obj( obj_lose );
obj_to_room ( pObj, victim->in_room );
break;
act(AT_YELLOW, msg, victim, obj_lose, NULL, TO_CHAR );
}
}
}
return;
}
void spell_fireshield( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 8 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FIRESHIELD;
affect_to_char( victim, &af );
send_to_char(AT_RED, "Your body is engulfed by unfelt flame.\n\r", victim );
act(AT_RED, "$n's body is engulfed in flames.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_flamestrike( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice( 6, level/2 );
dam = sc_dam( ch, dam );
if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) )
dam /= 2;
if ( IS_AFFECTED( victim, AFF_ICESHIELD ) )
dam += dam/4;
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_faerie_fire( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_FAERIE_FIRE ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_AC;
af.modifier = 2 * level;
af.bitvector = AFF_FAERIE_FIRE;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = 0 - level/10;
affect_to_char( victim, &af );
send_to_char(AT_PINK, "You are surrounded by a pink outline.\n\r", victim );
act(AT_PINK, "$n is surrounded by a pink outline.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_faerie_fog( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *ich;
send_to_char(AT_PURPLE, "You conjure a cloud of purple smoke.\n\r", ch );
act(AT_PURPLE, "$n conjures a cloud of purple smoke.", ch, NULL, NULL, TO_ROOM );
for ( ich = ch->in_room->people; ich; ich = ich->next_in_room )
{
if ( !IS_NPC( ich ) && IS_SET( ich->act, PLR_WIZINVIS ) )
continue;
if ( ich == ch || saves_spell( level, ich ) )
continue;
affect_strip ( ich, gsn_invis );
affect_strip ( ich, gsn_mass_invis );
affect_strip ( ich, gsn_sneak );
affect_strip ( ich, gsn_shadow );
affect_strip ( ich, skill_lookup("phase shift") );
affect_strip ( ich, skill_lookup("mist form") );
affect_strip ( ich, gsn_hide );
affect_strip ( ich, gsn_chameleon );
REMOVE_BIT ( ich->affected_by, AFF_HIDE );
REMOVE_BIT ( ich->affected_by, AFF_INVISIBLE );
REMOVE_BIT ( ich->affected_by, AFF_SNEAK );
REMOVE_BIT ( ich->affected_by2, AFF_PHASED );
act(AT_PURPLE, "$n is revealed!", ich, NULL, NULL, TO_ROOM );
send_to_char(AT_PURPLE, "You are revealed!\n\r", ich );
}
return;
}
void spell_fly( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_FLYING ) )
return;
af.type = sn;
af.level = level;
af.duration = level + 3;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FLYING;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "Your feet rise off the ground.\n\r", victim );
act(AT_BLUE, "$n's feet rise off the ground.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_gate( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *gch;
int npccount = 0;
int pccount = 0;
for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
{
if ( IS_NPC( gch ) && !IS_AFFECTED( gch, AFF_CHARM ) )
npccount++;
if ( !IS_NPC( gch ) ||
( IS_NPC( gch ) && IS_AFFECTED( gch, AFF_CHARM ) ) )
pccount++;
}
if ( npccount > pccount )
{
do_say( ch, "There are too many of us here! One must die!" );
return;
}
do_say( ch, "Come brothers! Join me in this glorious bloodbath!" );
char_to_room( create_mobile( get_mob_index( MOB_VNUM_DEMON1 ) ),
ch->in_room );
return;
}
/*
* Spell for mega1.are from Glop/Erkenbrand.
*/
void spell_general_purpose( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = number_range( 25, 100 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_giant_strength( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_STR;
af.modifier = 1 + (level >= 18) + (level >= 25);
af.bitvector = 0;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel stronger.\n\r", victim );
return;
}
void spell_eternal_intellect( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level/2;
af.location = APPLY_INT;
af.modifier = 1 + (level >= 18) + (level >= 25);
af.bitvector = 0;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel an unsurpased intelligence.\n\r", victim );
return;
}
void spell_golden_aura( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *)vo;
AFFECT_DATA af;
if ( IS_AFFECTED2( victim, AFF_GOLDEN ) )
return;
if ( !IS_NPC( ch )
&& !can_use_skpell( ch, sn ) )
{
send_to_char(AT_BLUE, "Nothing happens.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 8 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_GOLDEN;
affect_to_char2( victim, &af );
send_to_char( AT_YELLOW, "You are surrounded by a golden aura.\n\r", victim );
act(AT_YELLOW, "$n is surrounded by a golden aura.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_goodberry( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
OBJ_DATA *berry;
if ( obj->item_type != ITEM_FOOD
|| IS_OBJ_STAT( obj, ITEM_MAGIC ) )
{
send_to_char(AT_BLUE, "You can do nothing to that item.\n\r", ch );
return;
}
act(AT_BLUE, "You pass your hand over $p slowly.", ch, obj, NULL, TO_CHAR );
act(AT_BLUE, "$n has created a goodberry.", ch, NULL, NULL, TO_ROOM );
berry = create_object( get_obj_index( OBJ_VNUM_BERRY ), 0 );
berry->timer = ch->level;
berry->value[0] = ch->level * 3;
berry->value[1] = ch->level * 8;
extract_obj( obj );
obj_to_char( berry, ch );
return;
}
void spell_harm( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = UMAX( 20, victim->hit - dice( 1,4 ) );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam = UMIN( 50, dam / 4 );
dam = UMIN( 175, dam );
damage( ch, victim, dam, sn );
return;
}
void spell_heal( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = UMIN( (victim->hit + (ch->level*5)), MAX_HIT(victim) );
if ( ch->race == RACE_ANGEL )
heal = heal * 2;
if ( heal > MAX_HIT(victim))
heal = MAX_HIT( victim );
victim->hit = heal;
update_pos( victim );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "A warm feeling fills your body.\n\r", victim );
return;
}
/*
* Spell for mega1.are from Glop/Erkenbrand.
*/
void spell_high_explosive( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = number_range( 30, 120 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_iceshield( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_ICESHIELD ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 3 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_ICESHIELD;
affect_to_char( victim, &af );
send_to_char(AT_LBLUE, "An Icy crust forms about your body.\n\r", victim );
act(AT_LBLUE, "An icy crust forms about $n's body.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_icestorm( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice( level, 10 );
dam = sc_dam( ch, dam );
if ( IS_AFFECTED( victim, AFF_ICESHIELD ) )
dam /= 2;
if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) )
dam += dam/4;
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_holy_fires( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice( level, 10 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_identify( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
AFFECT_DATA *paf;
char buf [ MAX_STRING_LENGTH ];
int spn;
sprintf( buf,
"Object '%s' is type %s, extra flags %s %s %s.\n\r",
obj->name,
item_type_name( obj ),
obj->extra_flags ? extra_bit_name( obj->extra_flags ) : "",
obj->anti_race_flags ? antirace_bit_name(obj->anti_race_flags) : "",
obj->anti_class_flags ? anticlass_bit_name(obj->anti_class_flags) : "");
send_to_char(AT_CYAN, buf, ch );
#ifdef NEW_MONEY
sprintf( buf, "Weight : %d, level : %d.\n\r", obj->weight, obj->level );
send_to_char( AT_CYAN, buf, ch );
sprintf( buf, "Gold Value: %d Silver Value: %d Copper Value: %d\n\r",
obj->cost.gold, obj->cost.silver, obj->cost.copper );
#else
sprintf( buf,
"Weight : %d, value : %d, level : %d.\n\r",
obj->weight,
obj->cost,
obj->level );
#endif
send_to_char(AT_CYAN, buf, ch );
switch ( obj->item_type )
{
case ITEM_PILL:
case ITEM_SCROLL:
case ITEM_POTION:
sprintf( buf, "Level %d spells of:", obj->value[0] );
send_to_char(AT_CYAN, buf, ch );
if ( is_sn(obj->value[1]) )
{
send_to_char(AT_CYAN, " '", ch );
send_to_char(AT_WHITE, skill_table[obj->value[1]].name, ch );
send_to_char(AT_CYAN, "'", ch );
}
if ( is_sn(obj->value[2]) )
{
send_to_char(AT_CYAN, " '", ch );
send_to_char(AT_WHITE, skill_table[obj->value[2]].name, ch );
send_to_char(AT_CYAN, "'", ch );
}
if ( is_sn(obj->value[3]) )
{
send_to_char(AT_CYAN, " '", ch );
send_to_char(AT_WHITE, skill_table[obj->value[3]].name, ch );
send_to_char(AT_CYAN, "'", ch );
}
send_to_char(AT_CYAN, ".\n\r", ch );
break;
case ITEM_WAND:
case ITEM_LENSE:
case ITEM_STAFF:
if (!(obj->value[1] == -1 ) )
sprintf( buf, "Has %d(%d) charges of level %d",
obj->value[1], obj->value[2], obj->value[0] );
else
sprintf( buf, "Has unlimited charges of level %d", obj->value[0] );
send_to_char(AT_CYAN, buf, ch );
if ( is_sn(obj->value[3]) )
{
send_to_char(AT_CYAN, " '", ch );
send_to_char(AT_WHITE, skill_table[obj->value[3]].name, ch );
send_to_char(AT_CYAN, "'", ch );
}
send_to_char(AT_CYAN, ".\n\r", ch );
break;
case ITEM_WEAPON:
sprintf( buf, "Damage is %d to %d (average %d).\n\r",
obj->value[1], obj->value[2],
( obj->value[1] + obj->value[2] ) / 2 );
send_to_char(AT_RED, buf, ch );
break;
case ITEM_ARMOR:
sprintf( buf, "Armor class is %d.\n\r", obj->value[0] );
send_to_char(AT_CYAN, buf, ch );
break;
}
if ( obj->ac_type != 0 )
{
switch( obj->ac_type )
{
default: send_to_char(AT_CYAN, "Invoke Type Unknown.\n\r", ch ); break;
case 1 :
{
if ( obj->ac_charge[1] != -1 )
sprintf( buf, "Object creation invoke
, with [%d/%d] charges.\n\r",
obj->ac_charge[0], obj->ac_charge[1] );
else
sprintf( buf, "Object creation invoke, with unlimited charges.\n\r" );
send_to_char(AT_CYAN, buf, ch );
break;
}
case 2 :
{
if ( obj->ac_charge[1] != -1 )
sprintf( buf, "Monster creation invoke, with [%d/%d] charges.\n\r",
obj->ac_charge[0], obj->ac_charge[1] );
else
sprintf( buf, "Monster creation invoke, with unlimited charges.\n\r" );
send_to_char(AT_CYAN, buf, ch );
break;
}
case 3 :
{
if ( obj->ac_charge[1] != -1 )
sprintf( buf, "Transfer invoke, with [%d/%d] charges.\n\r",
obj->ac_charge[0], obj->ac_charge[1] );
else
sprintf( buf, "Transfer invoke, with unlimited charges.\n\r" );
send_to_char(AT_CYAN, buf, ch );
break;
}
case 4 :
{
if ( obj->ac_charge[1] != -1 )
sprintf( buf, "Object morph invoke, with [%d/%d] charges.\n\r",
obj->ac_charge[0], obj->ac_charge[1] );
else
sprintf( buf, "Object morph invoke, with unlimited charges.\n\r" );
send_to_char(AT_CYAN, buf, ch );
break;
}
case 5 :
{
if ( obj->ac_charge[1] != -1 )
sprintf( buf, "Spell invoke, has [%d/%d] charges of ",
obj->ac_charge[0], obj->ac_charge[1] );
else
sprintf( buf, "Spell invoke, with unlimited charges of " );
send_to_char(AT_CYAN, buf, ch );
spn = skill_lookup( obj->ac_spell );
if ( is_sn(spn) )
{
send_to_char(AT_CYAN, " '", ch );
send_to_char(AT_WHITE, spn ? obj->ac_spell : "(none)", ch );
send_to_char(AT_CYAN, "'\n\r", ch );
}
break;
}
}
}
for ( paf = obj->pIndexData->affected; paf; paf = paf->next )
{
if ( paf->location != APPLY_NONE && paf->modifier != 0 )
{
sprintf( buf, "Affects %s by %d.\n\r",
affect_loc_name( paf->location ), paf->modifier );
send_to_char(AT_BLUE, buf, ch );
}
}
for ( paf = obj->affected; paf; paf = paf->next )
{
if ( paf->location != APPLY_NONE && paf->modifier != 0 )
{
sprintf( buf, "Affects %s by %d.\n\r",
affect_loc_name( paf->location ), paf->modifier );
send_to_char(AT_BLUE, buf, ch );
}
}
return;
}
void spell_vibrate( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_VIBRATING ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 8 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_VIBRATING;
affect_to_char( victim, &af );
send_to_char(AT_LBLUE, "You set up a complex set of vibrations around your body.\n\r", victim );
act(AT_LBLUE, "$n's body begins to vibrate.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_infravision( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_INFRARED ) )
return;
af.type = sn;
af.level = level;
af.duration = 2 * level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_INFRARED;
affect_to_char( victim, &af );
send_to_char(AT_RED, "Your eyes glow.\n\r", victim );
act(AT_RED, "$n's eyes glow.\n\r", ch, NULL, NULL, TO_ROOM );
return;
}
void spell_incinerate( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( saves_spell( level, victim ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FLAMING;
affect_join( victim, &af );
if ( ch != victim )
send_to_char(AT_RED, "Ok.\n\r", ch );
send_to_char(AT_RED, "Your body bursts into flames!\n\r", victim );
return;
}
void spell_invis( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_INVISIBLE ) )
return;
af.type = sn;
af.level = level;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_INVISIBLE;
affect_to_char( victim, &af );
send_to_char(AT_GREY, "You fade out of existence.\n\r", victim );
act(AT_GREY, "$n fades out of existence.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_phase_shift( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2( victim, AFF_PHASED ) )
return;
af.type = sn;
af.level = level;
af.duration = ch->level/6;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PHASED;
affect_to_char2( victim, &af );
send_to_char(AT_GREY, "You phase into another plane.\n\r", victim );
act(AT_GREY, "$n phases out of reality.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_mist_form( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2( victim, AFF_PHASED ) )
return;
af.type = sn;
af.level = level;
af.duration = ch->level/6;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PHASED;
affect_to_char2( victim, &af );
send_to_char(AT_GREY, "You seem to feel transparent.\n\r", victim );
act(AT_GREY, "$n takes on the form of a mist.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_know_alignment( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
char *msg;
int ap;
ap = victim->alignment;
if ( ap > 700 ) msg = "$N has an aura as white as the driven snow.";
else if ( ap > 350 ) msg = "$N is of excellent moral character.";
else if ( ap > 100 ) msg = "$N is often kind and thoughtful.";
else if ( ap > -100 ) msg = "$N doesn't have a firm moral commitment.";
else if ( ap > -350 ) msg = "$N lies to $S friends.";
else if ( ap > -700 ) msg = "$N's slash DISEMBOWELS you!";
else msg = "I'd rather just not say anything at all about $N.";
act(AT_BLUE, msg, ch, NULL, victim, TO_CHAR );
return;
}
void spell_lightning_bolt( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 25, 28,
31, 34, 37, 40, 40, 41, 42, 42, 43, 44,
44, 45, 46, 46, 47, 48, 48, 49, 50, 50,
51, 52, 52, 53, 54, 54, 55, 56, 56, 57,
58, 58, 59, 60, 60, 61, 62, 62, 63, 64,
70, 72, 74, 76, 78, 80, 82, 84, 86, 88,
90, 92, 94, 96, 98, 100,102,104,106,108,
110,112,114,116,118, 120,122,124,126,128,
130,132,134,136,138, 140,142,144,146,148,
150,152,154,156,158, 160,162,164,166,170
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_locate_object( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj;
OBJ_DATA *in_obj;
char buf [ MAX_INPUT_LENGTH ];
bool found;
found = FALSE;
for ( obj = object_list; obj; obj = obj->next )
{
if ( !can_see_obj( ch, obj ) || !is_name( ch, target_name, obj->name ) )
continue;
if ( IS_SET( obj->extra_flags, ITEM_NO_LOCATE) && ( get_trust( ch ) < L_APP ) )
continue;
found = TRUE;
for ( in_obj = obj; in_obj->in_obj; in_obj = in_obj->in_obj )
;
if ( in_obj->carried_by )
{
sprintf( buf, "%s carried by %s.\n\r",
obj->short_descr, PERS( in_obj->carried_by, ch ) );
}
else if ( in_obj->stored_by )
{
sprintf( buf, "%s in storage.\n\r",
obj->short_descr );
}
else
{
sprintf( buf, "%s in %s.\n\r",
obj->short_descr, !in_obj->in_room
? "somewhere" : in_obj->in_room->name );
}
buf[0] = UPPER( buf[0] );
send_to_char(AT_BLUE, buf, ch );
}
if ( !found )
send_to_char(AT_WHITE, "Nothing like that in hell, earth, or heaven.\n\r", ch );
return;
}
void spell_magic_missile( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
3, 3, 4, 4, 5, 6, 6, 6, 6, 6,
7, 7, 7, 7, 7, 8, 8, 8, 8, 8,
9, 9, 9, 9, 9, 10, 10, 10, 10, 10,
11, 11, 11, 11, 11, 12, 12, 12, 12, 12,
13, 13, 13, 13, 13, 14, 14, 14, 14, 14,
15, 15, 15, 15, 15, 16, 16, 16, 16, 16,
18, 18, 18, 18, 18, 20, 20, 20, 20, 20,
21, 21, 21, 21, 21, 22, 22, 22, 22, 22,
24, 24, 24, 24, 24, 26, 26, 26, 26, 26,
28, 28, 28, 28, 28, 30, 31, 32, 33, 40
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_mana( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
victim->mana = UMIN( victim->mana + 70, MAX_MANA(victim) );
update_pos( victim );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel a surge of energy.\n\r", victim );
return;
}
void spell_mass_invis( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *gch;
AFFECT_DATA af;
for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
{
if ( !is_same_group( gch, ch ) || IS_AFFECTED( gch, AFF_INVISIBLE ) )
continue;
send_to_char(AT_GREY, "You slowly fade out of existence.\n\r", gch );
act(AT_GREY, "$n slowly fades out of existence.", gch, NULL, NULL, TO_ROOM );
af.type = sn;
af.level = level;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_INVISIBLE;
affect_to_char( gch, &af );
}
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
void spell_null( int sn, int level, CHAR_DATA *ch, void *vo )
{
send_to_char(AT_WHITE, "That's not a spell!\n\r", ch );
return;
}
void spell_pass_door( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED(victim, AFF_PASS_DOOR) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 4 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PASS_DOOR;
affect_to_char( victim, &af );
send_to_char(AT_GREY, "You turn translucent.\n\r", victim );
act(AT_GREY, "$n turns translucent.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_permenancy( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
/* AFFECT_DATA *paf;*/
if ( obj->item_type != ITEM_WAND
&& obj->item_type != ITEM_STAFF
&& obj->item_type != ITEM_LENSE )
{
send_to_char(AT_BLUE, "You cannot make that item permenant.\n\r", ch );
return;
}
obj->value[2] = -1;
obj->value[1] = -1;
act(AT_BLUE, "You run your finger up $p, you can feel it's power growing.", ch, obj, NULL, TO_CHAR );
act(AT_BLUE, "$n slowly runs $s finger up $p.", ch, obj, NULL, TO_ROOM );
return;
}
void spell_poison( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( saves_spell( level, victim ) || victim->race == RACE_GHOUL )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_STR;
af.modifier = -2;
af.bitvector = AFF_POISON;
affect_join( victim, &af );
if ( ch != victim )
send_to_char(AT_GREEN, "Ok.\n\r", ch );
send_to_char(AT_GREEN, "You feel very sick.\n\r", victim );
return;
}
void spell_polymorph( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
char buf [MAX_STRING_LENGTH];
AFFECT_DATA af;
if ( !(victim = get_char_world( ch, target_name ) )
|| victim == ch
|| saves_spell( level, victim)
|| IS_AFFECTED( ch, AFF_POLYMORPH ) )
{
send_to_char( AT_BLUE, "You failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = level/5;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_POLYMORPH;
affect_to_char2( ch, &af );
if (!IS_NPC(victim))
{
sprintf( buf, "%s %s", victim->name, victim->pcdata->title);
free_string( ch->long_descr );
ch->long_descr = str_dup(buf);
}
else
{
sprintf( buf, "%s", victim->long_descr );
free_string( ch->long_descr );
ch->long_descr = str_dup(buf);
}
act(AT_BLUE, "$n's form wavers and then resolidifies.", ch, NULL, NULL, TO_ROOM);
send_to_char(AT_BLUE, "You have succesfully polymorphed.\n\r", ch );
return;
}
void spell_portal( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *gate1;
OBJ_DATA *gate2;
int duration;
if ( !( victim = get_char_world( ch, target_name ) )
|| victim == ch
|| !victim->in_room
|| IS_SET( victim->in_room->room_flags, ROOM_SAFE )
|| IS_SET( victim->in_room->room_flags, ROOM_PRIVATE )
|| IS_SET( victim->in_room->room_flags, ROOM_SOLITARY )
|| IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_IN )
|| IS_SET( ch->in_room->room_flags, ROOM_NO_ASTRAL_OUT )
|| IS_ARENA(ch)
|| victim->in_room->area == arena.area
|| IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE ) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
duration = level/10;
gate1 = create_object( get_obj_index( OBJ_VNUM_PORTAL ), 0 );
gate2 = create_object( get_obj_index( OBJ_VNUM_PORTAL ), 0 );
gate1->timer = duration;
gate2->timer = duration;
gate2->value[0] = ch->in_room->vnum;
gate1->value[0] = victim->in_room->vnum;
act(AT_BLUE, "A huge shimmering gate rises from the ground.", ch, NULL, NULL, TO_CHAR );
act(AT_BLUE, "$n utters a few incantations and a gate rises from the ground.", ch, NULL, NULL, TO_ROOM );
obj_to_room( gate1, ch->in_room );
act(AT_BLUE, "A huge shimmering gate rises from the ground.", victim, NULL, NULL, TO_CHAR );
act(AT_BLUE, "A huge shimmering gate rises from the ground.", victim, NULL, NULL, TO_ROOM );
obj_to_room( gate2, victim->in_room );
return;
}
void spell_protection( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_PROTECT ) )
return;
af.type = sn;
af.level = level;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PROTECT;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel protected.\n\r", victim );
return;
}
void spell_refresh( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
victim->move = UMIN( victim->move + level + 50, MAX_MOVE(victim));
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel less tired.\n\r", victim );
return;
}
/* Expulsion of ITEM_NOREMOVE addition by Katrina */
void spell_remove_curse( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int iWear, SkNum;
int yesno = FALSE;
for ( iWear = 0; iWear < MAX_WEAR; iWear ++ )
{
if ( !( obj = get_eq_char( victim, iWear ) ) )
continue;
if ( IS_SET( obj->extra_flags, ITEM_NODROP ) )
{
REMOVE_BIT( obj->extra_flags, ITEM_NODROP );
send_to_char( AT_BLUE, "You feel a burden relieved.\n\r", ch );
yesno = TRUE;
}
if ( IS_SET( obj->extra_flags, ITEM_NOREMOVE ) )
{
unequip_char( victim, obj );
obj_from_char( obj );
obj_to_room( obj, victim->in_room );
act(AT_BLUE, "You toss $p to the ground.", victim, obj, NULL, TO_CHAR );
act(AT_BLUE, "$n tosses $p to the ground.", victim, obj, NULL, TO_ROOM );
yesno = TRUE;
}
}
SkNum=skill_lookup("incinerate");
if ( is_affected( victim, SkNum))
{
affect_strip( victim, SkNum);
send_to_char(AT_BLUE, "Your body has been extinguished.\n\r", ch);
yesno = TRUE;
}
SkNum=skill_lookup("curse");
if ( is_affected( victim, SkNum))
{
affect_strip( victim, SkNum);
send_to_char(AT_BLUE, "You feel better.\n\r", victim );
yesno = TRUE;
}
if ( ch != victim && yesno )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
void spell_sanctuary( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_SANCTUARY ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 8 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SANCTUARY;
affect_to_char( victim, &af );
send_to_char(AT_WHITE, "You are surrounded by a white aura.\n\r", victim );
act(AT_WHITE, "$n is surrounded by a white aura.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_web( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
if ( IS_AFFECTED( victim, AFF_ANTI_FLEE ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 10 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_ANTI_FLEE;
affect_to_char( victim, &af );
sprintf( buf, "%s lifts his hands and webs entanle you!\n\r", ch->name );
send_to_char(AT_WHITE, buf, victim );
act(AT_WHITE, "$n has been imobilized by a plethora of sticky webs.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_confusion( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
if ( IS_AFFECTED2( victim, AFF_CONFUSED ) )
return;
if ( saves_spell( level, victim ) )
{
send_to_char( AT_BLUE, "You failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 10 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_CONFUSED;
affect_to_char2( victim, &af );
sprintf( buf, "You feel disorientated.\n\r" );
send_to_char(AT_WHITE, buf, victim );
act(AT_WHITE, "$n stares around blankly.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_fumble( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
if ( IS_AFFECTED2( victim, AFF_FUMBLE ) )
return;
if ( saves_spell( level, victim ) )
{
send_to_char( AT_BLUE, "You failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 10 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FUMBLE;
affect_to_char2( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = 0 - level / 5;
af.bitvector = 0;
affect_to_char( victim, &af );
sprintf( buf, "You feel clumsy.\n\r" );
send_to_char(AT_WHITE, buf, victim );
act(AT_WHITE, "$n looks very clumsy.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_mind_probe( int sn, int level, CHAR_DATA *ch, void *vo )
{
AFFECT_DATA *paf;
CHAR_DATA *victim;
bool printed = FALSE;
char buf [ MAX_STRING_LENGTH ];
char buf1 [ MAX_STRING_LENGTH ];
if (!(victim = get_char_room( ch, target_name ) ) )
{
send_to_char(AT_BLUE, "You cannot find them.\n\r", ch );
return;
}
if ( victim->level >= LEVEL_IMMORTAL )
{
sprintf(buf1, "%s attempted to probe your mind.", ch->name );
send_to_char(AT_RED, buf1, victim );
send_to_char(AT_BLUE, "The mind of an immortal is beyond your understanding.", ch );
return;
}
sprintf(buf1, "You send your conciousness into %s's mind.\n\r", victim->name);
send_to_char(AT_RED, buf1, ch );
send_to_char(AT_RED, "You feel someone touch your mind.\n\r", victim );
buf1[0] = '\0';
if (IS_NPC(victim))
{
send_to_char (AT_WHITE, "The mind is to chaotic to merge with.\n\r", ch );
return;
}
sprintf( buf,
"You are %s%s.\n\r",
victim->name,
IS_NPC( victim ) ? "" : victim->pcdata->title );
send_to_char( AT_CYAN, buf, ch );
sprintf( buf,
"Level &C%d&c, %d years old (%d hours).\n\r",
victim->level,
get_age( victim ),
(get_age( victim ) - 17) * 4 );
send_to_char( AT_CYAN, buf, ch );
sprintf( buf, "You are a &Y%s&c and have chosen the vocation of a &Y%s&c.\n\r",
(get_race_data(victim->race))->race_full, class_short( victim ) );
send_to_char( AT_CYAN, buf, ch );
if ( victim->clan )
{
CLAN_DATA *clan;
clan = get_clan_index( victim->clan );
sprintf( buf, "You belong to the clan %s.\n\r", clan->name );
send_to_char( AT_WHITE, buf, ch );
}
if ( get_trust( victim ) != victim->level )
{
sprintf( buf, "You have been granted the powers of a level &R%d&W.\n\r",
get_trust( victim ) );
send_to_char( AT_WHITE, buf, ch );
}
if (!IS_NPC( victim ))
if ( get_trust( victim ) > LEVEL_IMMORTAL )
{
sprintf( buf, "Bamfin&r: &w%s.\n\r", victim->pcdata->bamfin );
send_to_char( AT_RED, buf, ch );
sprintf( buf, "Bamfout&r: &w%s.\n\r", victim->pcdata->bamfout );
send_to_char( AT_RED, buf, ch );
sprintf( buf, "Bamfusee&r: &w%s.\n\r", ch->pcdata->bamfusee );
send_to_char( AT_RED, buf, ch );
sprintf( buf, "Transto&r: &w%s.\n\r", ch->pcdata->transto );
send_to_char( AT_RED, buf, ch );
sprintf( buf, "Transfrom&r: &w%s.\n\r", ch->pcdata->transfrom );
send_to_char( AT_RED, buf, ch );
sprintf( buf, "Transvict&r: &w%s.\n\r", ch->pcdata->transvict );
send_to_char( AT_RED, buf, ch );
sprintf( buf, "Slayusee&r: &w%s.\n\r", ch->pcdata->slayusee );
send_to_char( AT_RED, buf, ch );
sprintf( buf, "Slayroom&r: &w%s.\n\r", ch->pcdata->slayroom );
send_to_char( AT_RED, buf, ch );
sprintf( buf, "Slayvict&r: &w%s.\n\r", ch->pcdata->slayvict );
send_to_char( AT_RED, buf, ch );
}
send_to_char( AT_CYAN, "You have", ch );
sprintf ( buf, " %d/%d(%d)", victim->hit,victim->perm_hit,MAX_HIT(victim) );
send_to_char( AT_YELLOW, buf, ch );
send_to_char( AT_CYAN, " hit, ", ch );
sprintf( buf, "%s%d/%d %s",
is_class( victim, CLASS_VAMPIRE ) ? "&R" : "&C",
MT( ch ), MT_MAX( ch ),
is_class( victim, CLASS_VAMPIRE ) ? " blood, " : "mana, " );
/*
if ( !is_class( victim, CLASS_VAMPIRE ) )
{
sprintf ( buf, "%d/%d(%d)",victim->mana,victim->perm_mana,MAX_MANA(victim));
send_to_char( AT_LBLUE, buf, ch );
send_to_char( AT_CYAN, " mana, ", ch );
}
else
{
sprintf ( buf, "%d/%d(%d)", victim->bp,victim->perm_bp, MAX_BP(victim));
send_to_char( AT_RED, buf, ch );
send_to_char( AT_CYAN, " blood, ", ch );
}
*/
sprintf ( buf, "%d/%d(%d)", victim->move, victim->perm_move, MAX_MOVE(victim));
send_to_char( AT_GREEN, buf, ch );
send_to_char( AT_CYAN, " movement, ", ch );
sprintf ( buf, "%d", victim->practice );
send_to_char( AT_WHITE, buf, ch );
send_to_char( AT_CYAN, " practices.\n\r", ch );
sprintf( buf,
"You are carrying %d/%d items with weight %d/%d kg.\n\r",
victim->carry_number, can_carry_n( victim ),
victim->carry_weight, can_carry_w( victim ) );
send_to_char( AT_CYAN, buf, ch );
sprintf( buf,
"Str: %d&p(&P%d&p)&P Int: %d&p(&P%d&p)&P Wis: %d&p(&P%d&p)&P Dex: %d&p(&P%d&p)&P Con: %d&p(&P%d&p)&P.\n\r",
IS_NPC(victim) ? 13: victim->pcdata->perm_str, IS_NPC(victim) ? 13: get_curr_str( victim ),
IS_NPC(victim) ? 13: victim->pcdata->perm_int, IS_NPC(victim) ? 13: get_curr_int( victim ),
IS_NPC(victim) ? 13: victim->pcdata->perm_wis, IS_NPC(victim) ? 13: get_curr_wis( victim ),
IS_NPC(victim) ? 13: victim->pcdata->perm_dex, IS_NPC(victim) ? 13: get_curr_dex( victim ),
IS_NPC(victim) ? 13: victim->pcdata->perm_con, IS_NPC(victim) ? 13: get_curr_con( victim ) );
send_to_char( AT_PINK, buf, ch );
send_to_char( AT_CYAN, "You have scored ", ch );
#ifdef NEW_MONEY
sprintf( buf, "&W%d &cexperience points.\n\r", victim->exp );
send_to_char( AT_WHITE, buf, ch );
sprintf( buf, "&cYou have accumulated &W%d &Ygold, &W%d &wsilver, &cand &W%d &Ocopper &ccoins.\n\r",
victim->money.gold, victim->money.silver, victim->money.copper );
send_to_char( AT_WHITE, buf, ch );
#else
sprintf( buf, "%d ", victim->exp );
send_to_char( AT_WHITE, buf, ch );
send_to_char( AT_CYAN, "exp, and have accumulated ", ch );
sprintf( buf, "%d ", victim->gold );
send_to_char( AT_YELLOW, buf, ch );
send_to_char( AT_CYAN, "gold coins.\n\r", ch );
#endif
if ( !IS_NPC( victim ) && victim->pcdata->condition[COND_DRUNK] > 10 )
send_to_char( AT_GREY, "You are drunk.\n\r", ch );
if ( !IS_NPC( victim ) && victim->pcdata->condition[COND_THIRST] == 0
&& victim->level >= LEVEL_IMMORTAL )
send_to_char( AT_BLUE, "You are thirsty.\n\r", ch );
if ( !IS_NPC( victim ) && victim->pcdata->condition[COND_FULL] == 0
&& victim->level >= LEVEL_IMMORTAL )
send_to_char( AT_ORANGE, "You are hungry.\n\r", ch );
switch ( victim->position )
{
case POS_DEAD:
send_to_char( (AT_RED + AT_BLINK), "You are DEAD!!\n\r", ch ); break;
case POS_MORTAL:
send_to_char( AT_RED, "You are mortally wounded.\n\r", ch ); break;
case POS_INCAP:
send_to_char( AT_RED, "You are incapacitated.\n\r", ch ); break;
case POS_STUNNED:
send_to_char( AT_RED, "You are stunned.\n\r", ch ); break;
case POS_SLEEPING:
send_to_char( AT_LBLUE, "You are sleeping.\n\r", ch ); break;
case POS_RESTING:
send_to_char( AT_LBLUE, "You are resting.\n\r", ch ); break;
case POS_STANDING:
send_to_char( AT_GREEN, "You are standing.\n\r", ch ); break;
case POS_FIGHTING:
send_to_char( AT_BLOOD, "You are fighting.\n\r", ch ); break;
}
if ( ch->level >= 20 )
{
sprintf( buf, "AC: %d. ", GET_AC( victim ) );
send_to_char( AT_CYAN, buf, ch );
}
send_to_char( AT_GREEN, "You are ", ch );
if ( GET_AC( victim ) >= 101 ) send_to_char( AT_GREEN, "WORSE than naked!\n\r", ch );
else if ( GET_AC( victim ) >= 20 ) send_to_char( AT_GREEN,
"naked.\n\r" , ch );
else if ( GET_AC( victim ) >= 0 ) send_to_char( AT_GREEN, "wearing
clothes.\n\r" , ch );
else if ( GET_AC( victim ) >= - 50 ) send_to_char( AT_GREEN, "slightly
armored.\n\r", ch );
else if ( GET_AC( victim ) >= -100 ) send_to_char( AT_GREEN, "somewhat
armored.\n\r", ch );
else if ( GET_AC( victim ) >= -250 ) send_to_char( AT_GREEN,
"armored.\n\r" , ch );
else if ( GET_AC( victim ) >= -500 ) send_to_char( AT_GREEN, "well
armored.\n\r" , ch );
else if ( GET_AC( victim ) >= -750 ) send_to_char( AT_GREEN, "strongly
armored.\n\r", ch );
else if ( GET_AC( victim ) >= -1000 ) send_to_char( AT_GREEN, "heavily
armored.\n\r" , ch );
else if ( GET_AC( victim ) >= -1200 ) send_to_char( AT_GREEN, "superbly
armored.\n\r", ch );
else if ( GET_AC( victim ) >= -1400 ) send_to_char( AT_GREEN, "divinely
armored.\n\r", ch );
else send_to_char( AT_GREEN, "invincible!\n\r", ch );
if ( ch->level >= 12 )
{
sprintf( buf, "Hitroll: " );
send_to_char(AT_BLOOD, buf, ch );
sprintf( buf, "%d", GET_HITROLL( victim ) );
send_to_char(AT_RED, buf, ch);
sprintf( buf, " Damroll: " );
send_to_char( AT_BLOOD, buf, ch );
sprintf( buf, "%d.\n\r", GET_DAMROLL( victim ) );
send_to_char( AT_RED, buf, ch );
}
if ( ch->level >= 8 )
{
sprintf( buf, "Alignment: %d. ", victim->alignment );
send_to_char( AT_CYAN, buf, ch );
}
send_to_char( AT_CYAN, "You are ", ch );
if ( victim->alignment > 900 ) send_to_char( AT_BLUE, "angelic.\n\r",ch );
else if ( victim->alignment > 700 ) send_to_char( AT_BLUE, "saintly.\n\r",ch );
else if ( victim->alignment > 350 ) send_to_char( AT_BLUE, "good.\n\r" ,ch );
else if ( victim->alignment > 100 ) send_to_char( AT_BLUE, "kind.\n\r" ,ch );
else if ( victim->alignment > -100 ) send_to_char( AT_YELLOW, "neutral.\n\r",ch );
else if ( victim->alignment > -350 ) send_to_char( AT_RED, "mean.\n\r" ,ch);
else if ( victim->alignment > -700 ) send_to_char( AT_RED, "evil.\n\r" ,ch);
else if ( victim->alignment > -900 ) send_to_char( AT_RED, "demonic.\n\r" ,ch);
else send_to_char( AT_RED, "satanic.\n\r" ,ch);
if ( !IS_NPC( victim ) && IS_IMMORTAL( victim ) )
{
sprintf( buf, "WizInvis level: %d WizInvis is %s\n\r",
victim->wizinvis,
IS_SET( victim->act, PLR_WIZINVIS ) ? "ON" : "OFF" );
send_to_char( AT_YELLOW, buf, ch );
sprintf( buf, "Cloaked level: %d Cloaked is %s\n\r",
victim->cloaked,
IS_SET( victim->act, PLR_CLOAKED ) ? "ON" : "OFF" );
send_to_char( AT_YELLOW, buf, ch );
}
if ( victim->affected )
{
for ( paf = victim->affected; paf; paf = paf->next )
{
if ( paf->deleted )
continue;
if ( !printed )
{
send_to_char( AT_CYAN, "You are affected by:\n\r", ch );
printed = TRUE;
}
sprintf( buf, "Spell: '%s'", skill_table[paf->type].name );
send_to_char( AT_WHITE, buf, ch );
if ( ch->level >= 20 )
{
sprintf( buf,
" modifies %s by %d for %d hours",
affect_loc_name( paf->location ),
paf->modifier,
paf->duration );
send_to_char(AT_WHITE, buf, ch );
}
send_to_char( AT_WHITE, ".\n\r", ch );
}
}
if ( victim->affected2 )
{
for ( paf = victim->affected2; paf; paf = paf->next )
{
if ( paf->deleted )
continue;
if ( !printed )
{
send_to_char( AT_CYAN, "You are affected by:\n\r", ch );
printed = TRUE;
}
sprintf( buf, "Spell: '%s'", skill_table[paf->type].name );
send_to_char( AT_WHITE, buf, ch );
if ( ch->level >= 20 )
{
sprintf( buf,
" modifies %s by %d for %d hours",
affect_loc_name( paf->location ),
paf->modifier,
paf->duration );
send_to_char(AT_WHITE, buf, ch );
}
send_to_char( AT_WHITE, ".\n\r", ch );
}
}
send_to_char( AT_RED, "The presence lifts from your mind.\n\r", victim );
return;
}
void spell_entangle( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
if ( IS_AFFECTED( victim, AFF_ANTI_FLEE ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 10 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_ANTI_FLEE;
affect_to_char( victim, &af );
sprintf( buf, "%s calls forth nature to hold you in place.\n\r", ch->name );
send_to_char(AT_GREEN, buf, victim );
act(AT_GREEN, "Hundreds of vines reach from the ground to entangle $n.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_scry( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_SCRY ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 4 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SCRY;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "Your vision improves.\n\r", victim );
return;
}
void spell_shield( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 8 + level;
af.location = APPLY_AC;
af.modifier = -30;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "You are surrounded by a force shield.\n\r", victim );
act(AT_BLUE, "$n is surrounded by a force shield.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_shocking_grasp( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 20, 25, 29, 33,
36, 39, 39, 39, 40, 40, 41, 41, 42, 42,
43, 43, 44, 44, 45, 45, 46, 46, 47, 47,
48, 48, 49, 49, 50, 50, 51, 51, 52, 52,
53, 53, 54, 54, 55, 55, 56, 56, 57, 57,
58, 58, 59, 60, 61, 62, 63, 64, 65, 66,
67, 68, 69, 70, 71, 72, 73, 74, 75, 76,
77, 78, 79, 80, 81, 82, 83, 84, 85, 86,
87, 88, 89, 90, 91, 92, 93, 94, 95, 96,
97, 98, 99,100,101, 102,103,104,105,106
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_shockshield( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 6 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SHOCKSHIELD;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "Sparks of electricity flow into your body.\n\r", victim );
act(AT_BLUE, "Bolts of electricity flow from the ground into $n's body.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_sleep( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_SLEEP )
|| level < victim->level
|| ( saves_spell(level + IS_SRES(victim, RES_MAGIC) ? -5 : 0, victim)
&& !(get_trust( ch ) > LEVEL_IMMORTAL) ) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
if(IS_SIMM(victim, IMM_MAGIC))
return;
af.type = sn;
af.level = level;
af.duration = 4 + level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SLEEP;
affect_join( victim, &af );
if ( IS_AWAKE( victim ) )
{
send_to_char(AT_BLUE, "You feel very sleepy ..... zzzzzz.\n\r", victim );
if ( victim->position == POS_FIGHTING )
stop_fighting( victim, TRUE );
do_sleep( victim, "" );
}
return;
}
void spell_spell_bind( int sn, int level, CHAR_DATA *ch, void *vo )
{
bool Charged = 0;
OBJ_DATA *obj = (OBJ_DATA *) vo;
if ( obj->item_type == ITEM_WAND
|| obj->item_type == ITEM_STAFF
|| obj->item_type == ITEM_LENSE )
{
if(obj->value[2] < obj->value[1])
{
obj->value[2]=obj->value[1];
Charged++;
}
}
else if (obj->ac_type==5 && obj->ac_spell)
{
if(obj->ac_charge[0] < obj->ac_charge[1] && obj->ac_charge[1]!=-1)
{
obj->ac_charge[0]++;
Charged++;
}
}
else
{
send_to_char(AT_BLUE, "You cannot bind magic to that item.\n\r", ch );
return;
}
if (!Charged)
{
send_to_char(AT_BLUE, "That item is at full charge.\n\r", ch );
return;
}
act(AT_BLUE, "You slowly pass your hand over $p, it vibrates slowly.", ch, obj, NULL, TO_CHAR );
act(AT_BLUE, "$n slowly passes $s hand over $p, it vibrates slowly.", ch, obj, NULL, TO_ROOM );
return;
}
void spell_stone_skin( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( ch, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_AC;
af.modifier = -45;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_GREY, "Your skin turns to stone.\n\r", victim );
act(AT_GREY, "$n's skin turns to stone.", victim, NULL, NULL, TO_ROOM );
return;
}
/*Decklarean*/
void spell_bark_skin( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( ch, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_AC;
af.modifier = -10 - level / 4;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_GREY, "Your skin turns to bark.\n\r", victim );
act(AT_GREY, "$n's skin turns to bark.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_summon( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim;
if ( !( victim = get_char_world( ch, target_name ) )
|| victim == ch
|| ch->in_room->area == arena.area
|| IS_ARENA(victim)
|| !victim->in_room
|| IS_SET( victim->in_room->room_flags, ROOM_SAFE )
|| IS_SET( victim->in_room->room_flags, ROOM_PRIVATE )
|| IS_SET( victim->in_room->room_flags, ROOM_SOLITARY )
|| IS_SET( victim->in_room->room_flags, ROOM_NO_RECALL )
|| IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_OUT )
|| victim->level >= level + 3
|| victim->fighting
|| ( IS_NPC( victim ) && saves_spell( level, victim ) )
|| IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE )
|| IS_AFFECTED( victim, AFF_NOASTRAL ) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
act(AT_BLUE, "$n disappears suddenly.", victim, NULL, NULL, TO_ROOM );
char_from_room( victim );
char_to_room( victim, ch->in_room );
act(AT_BLUE, "$n has summoned you!", ch, NULL, victim, TO_VICT );
act(AT_BLUE, "$n arrives suddenly.", victim, NULL, NULL, TO_ROOM );
send_to_char( AT_BLUE, "You feel a wave of nausia come over you.\n\r", ch );
ch->position = POS_STUNNED;
update_pos( ch );
STUN_CHAR( ch, 3, STUN_COMMAND );
do_look( victim, "auto" );
return;
}
void spell_teleport( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
CHAR_DATA *pet;
ROOM_INDEX_DATA *pRoomIndex;
if ( !victim->in_room
|| IS_SET( victim->in_room->room_flags, ROOM_NO_RECALL)
|| IS_SET( victim->in_room->room_flags, ROOM_NO_ASTRAL_OUT)
|| IS_SET( victim->in_room->area->area_flags, AREA_PROTOTYPE )
|| ( !IS_NPC( ch ) && victim->fighting )
|| ( victim != ch
&& ( saves_spell( level, victim )
|| saves_spell( level, victim ) ) ) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return;
}
for ( ; ; )
{
pRoomIndex = get_room_index( number_range( 0, 32767 ) );
if ( pRoomIndex )
if ( !IS_SET( pRoomIndex->room_flags, ROOM_PRIVATE )
&& !IS_SET( pRoomIndex->room_flags, ROOM_SOLITARY )
&& !IS_SET( pRoomIndex->room_flags, ROOM_NO_ASTRAL_IN )
&& !IS_SET( pRoomIndex->room_flags, ROOM_NO_RECALL)
&& !IS_SET( pRoomIndex->area->area_flags, AREA_PROTOTYPE ) )
break;
}
for ( pet = victim->in_room->people; pet; pet = pet->next_in_room )
{
if ( IS_NPC( pet ) )
if ( IS_SET( pet->act, ACT_PET ) && ( pet->master == victim ) )
break;
}
act(AT_BLUE, "$n glimmers briefly, then is gone.", victim, NULL, NULL, TO_ROOM );
if ( pet )
{
act( AT_BLUE, "$n glimmers briefly, then is gone.", pet, NULL, NULL, TO_ROOM );
char_from_room( pet );
}
char_from_room( victim );
char_to_room( victim, pRoomIndex );
act(AT_BLUE, "The air starts to sparkle, then $n appears from nowhere.", victim, NULL, NULL, TO_ROOM );
do_look( victim, "auto" );
if ( pet )
{
char_to_room( pet, pRoomIndex );
act( AT_BLUE, "The air starts to sparkle, then $n appears from nowhere.", pet, NULL, NULL, TO_ROOM );
}
return;
}
void spell_ventriloquate( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
char buf1 [ MAX_STRING_LENGTH ];
char buf2 [ MAX_STRING_LENGTH ];
char speaker [ MAX_INPUT_LENGTH ];
target_name = one_argument( target_name, speaker );
sprintf( buf1, "%s says '%s'.\n\r", speaker, target_name );
sprintf( buf2, "Someone makes %s say '%s'.\n\r", speaker, target_name );
buf1[0] = UPPER( buf1[0] );
for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
{
if ( !is_name( NULL, speaker, vch->name ) )
send_to_char(AT_CYAN, saves_spell( level, vch ) ? buf2 : buf1, vch );
}
return;
}
void spell_weaken( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) || saves_spell( level, victim ) )
return;
af.type = sn;
af.level = level;
af.duration = level / 2;
af.location = APPLY_STR;
af.modifier = -2;
af.bitvector = 0;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_GREEN, "Ok.\n\r", ch );
send_to_char(AT_GREEN, "You feel weaker.\n\r", victim );
return;
}
/*
* This is for muds that want scrolls of recall.
*/
void spell_word_of_recall( int sn, int level, CHAR_DATA *ch, void *vo )
{
do_recall( (CHAR_DATA *) vo, "" );
return;
}
/*
* NPC spells.
*/
void spell_acid_breath( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
int hpch;
if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) )
{
for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next )
{
obj_next = obj_lose->next_content;
if ( obj_lose->deleted )
continue;
if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) )
continue;
if ( number_bits( 2 ) != 0 )
continue;
switch ( obj_lose->item_type )
{
case ITEM_ARMOR:
if ( obj_lose->value[0] > 0 )
{
act(AT_GREEN, "$p is pitted and etched!",
victim, obj_lose, NULL, TO_CHAR );
/* if ( ( iWear = obj_lose->wear_loc ) != WEAR_NONE )
victim->armor -= apply_ac( obj_lose, iWear );
obj_lose->value[0] -= 1;*/
/* 5% -- Altrag */
#ifdef NEW_MONEY
obj_lose->cost.gold = (obj_lose->cost.gold > 0) ?
(obj_lose->cost.gold - (obj_lose->cost.gold/20)) : 0;
obj_lose->cost.silver = (obj_lose->cost.silver > 0) ?
(obj_lose->cost.silver - (obj_lose->cost.silver/20)) : 0;
obj_lose->cost.copper = (obj_lose->cost.copper > 0) ?
(obj_lose->cost.copper - (obj_lose->cost.copper/20)) : 0;
#else
obj_lose->cost -= (obj_lose->cost / 20);
#endif
/* if ( iWear != WEAR_NONE )
victim->armor += apply_ac( obj_lose, iWear );*/
}
break;
case ITEM_CONTAINER:
act(AT_GREEN, "$p fumes and dissolves!",
victim, obj_lose, NULL, TO_CHAR );
extract_obj( obj_lose );
break;
}
}
}
hpch = UMAX( 10, ch->hit );
dam = number_range( hpch / 8 + 1, hpch / 4 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_fire_breath( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
int hpch;
if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) )
{
for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next )
{
char *msg;
obj_next = obj_lose->next_content;
if ( obj_lose->deleted )
continue;
if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) )
continue;
if ( number_bits( 2 ) != 0 )
continue;
switch ( obj_lose->item_type )
{
default: continue;
case ITEM_CONTAINER: msg = "$p ignites and burns!"; break;
case ITEM_POTION: msg = "$p bubbles and boils!"; break;
case ITEM_SCROLL: msg = "$p crackles and burns!"; break;
case ITEM_STAFF: msg = "$p smokes and chars!"; break;
case ITEM_WAND: msg = "$p sparks and sputters!"; break;
case ITEM_LENSE: msg = "$p shrivels and dries!"; break;
case ITEM_FOOD: msg = "$p blackens and crisps!"; break;
case ITEM_PILL: msg = "$p melts and drips!"; break;
}
act(AT_GREEN, msg, victim, obj_lose, NULL, TO_CHAR );
extract_obj( obj_lose );
}
}
hpch = UMAX( 10, ch->hit );
dam = number_range( hpch / 8 + 1, hpch / 4 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_frost_breath( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
int hpch;
if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) )
{
for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next )
{
char *msg;
obj_next = obj_lose->next_content;
if ( obj_lose->deleted )
continue;
if ( IS_SET( obj_lose->extra_flags, ITEM_NO_DAMAGE ) )
continue;
if ( number_bits( 2 ) != 0 )
continue;
switch ( obj_lose->item_type )
{
default: continue;
case ITEM_CONTAINER:
case ITEM_DRINK_CON:
case ITEM_POTION: msg = "$p freezes and shatters!"; break;
}
act(AT_WHITE, msg, victim, obj_lose, NULL, TO_CHAR );
extract_obj( obj_lose );
}
}
hpch = UMAX( 10, ch->hit );
dam = number_range( hpch / 8 + 1, hpch / 4 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_gas_breath( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
int dam;
int hpch;
for ( vch = ch->in_room->people; vch; vch = vch_next )
{
vch_next = vch->next_in_room;
if ( vch->deleted )
continue;
if ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) )
{
hpch = UMAX( 10, ch->hit );
dam = number_range( hpch / 8 + 1, hpch / 4 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, vch ) )
dam /= 2;
spell_poison( gsn_poison, level, ch, vch );
damage( ch, vch, dam, sn );
}
}
return;
}
void spell_lightning_breath( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
int hpch;
hpch = UMAX( 10, ch->hit );
dam = number_range( hpch / 8 + 1, hpch / 4 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
/*
* Code for Psionicist spells/skills by Thelonius
*/
void spell_adrenaline_control ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level - 5;
af.location = APPLY_DEX;
af.modifier = 2;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_CON;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "You have given yourself an adrenaline rush!\n\r", ch );
act(AT_BLUE, "$n has given $mself an adrenaline rush!", ch, NULL, NULL,
TO_ROOM );
return;
}
void spell_agitation ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 12, 15, 18, 21, 24,
24, 24, 25, 25, 26, 26, 26, 27, 27, 27,
28, 28, 28, 29, 29, 29, 30, 30, 30, 31,
31, 31, 32, 32, 32, 33, 33, 33, 34, 34,
34, 35, 35, 35, 36, 36, 36, 37, 37, 37,
38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
58, 59, 60, 61, 62, 63, 64, 65, 66, 67,
68, 69, 70, 71, 72, 73, 74, 75, 76, 77,
78, 79, 80, 81, 82, 83, 84, 85, 86, 87
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_aura_sight ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
char *msg;
int ap;
ap = victim->alignment;
if ( ap > 700 ) msg = "$N has an aura as white as the driven snow.";
else if ( ap > 350 ) msg = "$N is of excellent moral character.";
else if ( ap > 100 ) msg = "$N is often kind and thoughtful.";
else if ( ap > -100 ) msg = "$N doesn't have a firm moral commitment.";
else if ( ap > -350 ) msg = "$N lies to $S friends.";
else if ( ap > -700 ) msg = "Don't bring $N home to meet your family.";
else msg = "Uh, check please!";
act(AT_BLUE, msg, ch, NULL, victim, TO_CHAR );
}
void spell_awe ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( victim->fighting == ch && !saves_spell( level, victim ) )
{
stop_fighting ( victim, TRUE);
act(AT_BLUE, "$N is in AWE of you!", ch, NULL, victim, TO_CHAR );
act(AT_BLUE, "You are in AWE of $n!",ch, NULL, victim, TO_VICT );
act(AT_BLUE, "$N is in AWE of $n!", ch, NULL, victim, TO_NOTVICT );
}
return;
}
void spell_ballistic_attack ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
3, 4, 4, 5, 6, 6, 6, 7, 7, 7,
7, 7, 8, 8, 8, 9, 9, 9, 10, 10,
10, 11, 11, 11, 12, 12, 12, 13, 13, 13,
14, 14, 14, 15, 15, 15, 16, 16, 16, 17,
17, 17, 18, 18, 18, 19, 19, 19, 20, 20,
21, 22, 23, 24, 25, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
41, 42, 43, 44, 45, 46, 47, 48, 49, 50,
51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
61, 62, 63, 64, 65, 66, 67, 68, 69, 70
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
act(AT_BLUE, "You chuckle as a stone strikes $N.", ch, NULL, victim,
TO_CHAR );
damage( ch, victim, dam, sn);
return;
}
void spell_biofeedback ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_SANCTUARY ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 8 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SANCTUARY;
affect_to_char( victim, &af );
send_to_char(AT_WHITE, "You are surrounded by a white aura.\n\r", victim );
act(AT_WHITE, "$n is surrounded by a white aura.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_cell_adjustment ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int SkNum;
if ( is_affected( victim, gsn_poison ) )
{
affect_strip( victim, gsn_poison );
send_to_char(AT_BLUE, "A warm feeling runs through your body.\n\r", victim );
act(AT_BLUE, "$N looks better.", ch, NULL, victim, TO_NOTVICT );
}
SkNum = skill_lookup("curse");
if ( is_affected( victim, SkNum ) )
{
affect_strip( victim, SkNum );
send_to_char(AT_BLUE, "You feel better.\n\r", victim );
}
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
void spell_chaosfield( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_CHAOS ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 6 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_CHAOS;
affect_to_char( victim, &af );
send_to_char(AT_YELLOW, "You call forth an instance of chaos from the order around you.\n\r", victim );
act(AT_YELLOW, "$n's body is veiled in an instance or pure chaos.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_bladebarrier( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2( victim, AFF_BLADE ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 6 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_BLADE;
affect_to_char2( victim, &af );
send_to_char(AT_GREY, "You bring forth thousands of tiny spinning blades about your body.\n\r", victim );
act(AT_GREY, "$n's body is surrounded by thousands of spinning blades.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_dancing_lights( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2( victim, AFF_DANCING ) )
return;
if ( IS_AFFECTED( victim, AFF_BLIND ) || saves_spell( level, victim ) )
{
send_to_char(AT_BLUE, "You have failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 6 );
af.location = APPLY_HITROLL;
af.modifier = level/6;
af.bitvector = AFF_DANCING;
affect_to_char2( victim, &af );
act(AT_WHITE, "&.Thou&.sand&.s &.of &.danci&.ng &.ligh&.ts &.surr&.ound &.you&.!&w", victim, NULL, victim, TO_VICT );
act(AT_GREY, "&W$n's &.body &.is &.surr&.ounded &.by d&.anci&.ng l&.ights.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_combat_mind ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
{
if ( victim == ch )
send_to_char(AT_BLUE, "You already understand battle tactics.\n\r",
victim );
else
act(AT_BLUE, "$N already understands battle tactics.",
ch, NULL, victim, TO_CHAR );
return;
}
af.type = sn;
af.level = level;
af.duration = level + 3;
af.location = APPLY_HITROLL;
af.modifier = level / 5;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = - level/2 - 10;
affect_to_char( victim, &af );
if ( victim != ch )
send_to_char(AT_BLUE, "OK.\n\r", ch );
send_to_char(AT_BLUE, "You gain a keen understanding of battle tactics.\n\r",
victim );
return;
}
/* psi people shouldn't have this powerful healing */
void spell_complete_healing ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = UMIN( victim->hit + 600, MAX_HIT(victim) );
if ( ch->race == RACE_ANGEL )
heal = heal * 2;
if ( heal > MAX_HIT(victim))
heal = MAX_HIT( victim );
victim->hit = heal;
update_pos( victim );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "Ahhhhhh...You feel MUCH better!\n\r", victim );
send_to_char(AT_BLUE, "Have a nice day.\n\r", victim);
return;
}
void spell_control_flames ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 0, 16, 20, 24,
28, 32, 35, 38, 40, 42, 44, 45, 45, 45,
46, 46, 46, 47, 47, 47, 48, 48, 48, 49,
49, 49, 50, 50, 50, 51, 51, 51, 52, 52,
52, 53, 53, 53, 54, 54, 54, 55, 55, 55,
56, 56, 57, 57, 58, 58, 59, 59, 60, 60,
62, 63, 63, 63, 64, 64, 64, 65, 65, 65,
72, 73, 73, 73, 74, 74, 74, 75, 75, 75,
82, 83, 83, 83, 84, 84, 84, 85, 85, 85,
92, 93, 93, 93, 94, 94, 94, 95, 95, 95
};
int dam;
if ( !get_eq_char( ch, WEAR_LIGHT ) )
{
send_to_char(AT_RED, "You must be carrying a light source.\n\r", ch );
return;
}
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 2 );
dam = sc_dam( ch, dam );
if ( IS_AFFECTED( victim, AFF_FIRESHIELD ) )
dam /= 2;
if ( IS_AFFECTED( victim, AFF_ICESHIELD ) )
dam += dam/4;
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_create_sound ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
char buf1 [ MAX_STRING_LENGTH ];
char buf2 [ MAX_STRING_LENGTH ];
char speaker [ MAX_INPUT_LENGTH ];
target_name = one_argument( target_name, speaker );
sprintf( buf1, "%s says '%s'.\n\r", speaker, target_name );
sprintf( buf2, "Someone makes %s say '%s'.\n\r", speaker, target_name );
buf1[0] = UPPER( buf1[0] );
for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
{
if ( !is_name( NULL, speaker, vch->name ) )
send_to_char(AT_RED, saves_spell( level, vch ) ? buf2 : buf1, vch );
}
return;
}
void spell_death_field ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
/* CHAR_DATA *vch_next; */
int dam;
int hpch;
if ( !IS_EVIL( ch ) )
{
send_to_char(AT_RED, "You are not evil enough to do that!\n\r", ch);
return;
}
send_to_char(AT_DGREY, "A black haze emanates from you!\n\r", ch );
act (AT_DGREY, "A black haze emanates from $n!", ch, NULL, ch, TO_ROOM );
for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
/*vch = vch_next ) */
{
/* vch_next = vch->next_in_room;*/
if ( vch->deleted )
continue;
if ( IS_NPC( ch ) )
continue;
if ( ch == vch )
continue;
if ( !IS_NPC( ch ) ? IS_NPC( vch ) : IS_NPC( vch ) )
{
hpch = URANGE( 10, ch->hit, 999 );
if ( !saves_spell( level, vch )
&& ( level <= vch->level + 5
&& level >= vch->level - 5 ) )
{
send_to_char(AT_DGREY, "The haze envelops you!\n\r", vch );
act(AT_DGREY, "The haze envelops $N!",
ch, NULL, vch, TO_NOTVICT );
dam = 4; /* Enough to compensate for sanct. and prot. */
vch->hit = 1;
damage( ch, vch, dam, sn );
update_pos( vch );
}
else
{
dam = number_range( hpch / 16 + 1, hpch / 8 );
dam = sc_dam( ch, dam );
damage( ch, vch, dam, sn );
}
}
}
return;
}
void spell_detonate ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if ( ch->race == RACE_ILLITHID )
ch->wait /= 2;
dam = dice( level, 13 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_disintegrate ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj_lose;
OBJ_DATA *obj_next;
if ( !IS_NPC(victim) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch);
return;
}
if ( number_percent( ) < 2 * level && !saves_spell( level, victim ) )
for ( obj_lose = victim->carrying; obj_lose; obj_lose = obj_next )
{
obj_next = obj_lose->next_content;
if ( obj_lose->deleted )
continue;
if ( number_bits( 2 ) != 0 )
continue;
act(AT_WHITE, "$p disintegrates!", victim, obj_lose, NULL, TO_CHAR );
act(AT_WHITE, "$n's $p disintegrates!", victim, obj_lose, NULL, TO_ROOM );
extract_obj( obj_lose ) ;
}
if ( !saves_spell( level, victim ) )
/*
* Disintegrate char, do not generate a corpse, do not
* give experience for kill. Extract_char will take care
* of items carried/wielded by victim. Needless to say,
* it would be bad to be a target of this spell!
* --- Thelonius (Monk)
*/
{
act(AT_WHITE, "You have DISINTEGRATED $N!", ch, NULL, victim, TO_CHAR );
act(AT_WHITE, "You have been DISINTEGRATED by $n!", ch, NULL, victim, TO_VICT );
act(AT_WHITE, "$n's spell DISINTEGRATES $N!", ch, NULL, victim, TO_ROOM );
if ( IS_NPC( victim ) )
extract_char( victim, TRUE );
else
extract_char( victim, FALSE );
}
return;
}
void spell_disrupt( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
CHAR_DATA *vch;
AFFECT_DATA af;
bool negchar = FALSE; /* Is a negative value good..? */
int val = 0;
af.type = sn;
af.duration = (level * 2) / 3;
af.level = level;
af.bitvector = 0;
while ( !val )
{
af.location = number_range( 1, 26 );
switch (af.location)
{
case APPLY_STR:
case APPLY_DEX:
case APPLY_INT:
case APPLY_WIS:
case APPLY_CON:
val = (level / 34) + 1;
break;
case APPLY_MANA:
val = ((level * 3) / 2) + 1;
break;
case APPLY_AC:
val = ((level * 3) / 2) + 1;
negchar = TRUE;
break;
case APPLY_HITROLL:
case APPLY_DAMROLL:
val = (level / 2) + 1;
break;
case APPLY_SAVING_PARA:
case APPLY_SAVING_ROD:
case APPLY_SAVING_PETRI:
case APPLY_SAVING_BREATH:
case APPLY_SAVING_SPELL:
val = ((level * 2) / 5) + 1;
negchar = TRUE;
break;
case APPLY_BP:
val = ((level * 3) / 10) + 1;
break;
}
}
for ( af.modifier = number_range( -val, val ); af.modifier == 0;
af.modifier = number_range( -val, val ) );
if ( negchar )
{
if ( af.modifier < 0 )
vch = ch;
else
vch = victim;
}
else
{
if ( af.modifier < 0 )
vch = victim;
else
vch = ch;
}
if ( af.location == APPLY_MANA && is_class( vch, CLASS_VAMPIRE ) )
{
af.modifier /= 4;
af.location = APPLY_BP;
}
if ( af.location == APPLY_BP && !is_class( vch, CLASS_VAMPIRE ) )
{
if ( af.modifier > 0 )
af.modifier = number_range( 1, (level * 3) / 2 );
else
af.modifier = number_range( -((level * 3) / 2), -1 );
af.location = APPLY_MANA;
}
if ( !is_affected( vch, sn ) && (vch != victim ||
!saves_spell( level, victim )) &&
number_bits( 8 ) == 0 )
{
affect_to_char( vch, &af );
if ( ch == vch )
{
act( AT_PINK, "You disrupt yourself!", ch, NULL, NULL, TO_CHAR );
act( AT_PINK, "$n disrupts $mself!", ch, NULL, NULL, TO_ROOM );
}
else
{
act( AT_PURPLE, "You disrupt $N!", ch, NULL, victim, TO_CHAR );
act( AT_PURPLE, "$n disrupts $N!", ch, NULL, victim, TO_NOTVICT );
act( AT_PURPLE, "$n disrupts you!", ch, NULL, victim, TO_VICT );
switch( af.location )
{
case APPLY_MANA:
vch->mana = URANGE( 0, vch->mana, MAX_MANA(vch));
break;
case APPLY_BP:
vch->bp = URANGE( 0, vch->bp, MAX_BP(vch));
break;
}
}
}
damage( ch, victim, number_range( (level * 2) / 3, level ), sn );
return;
}
void spell_displacement ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level - 4;
af.location = APPLY_AC;
af.modifier = 4 - level;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_GREY, "Your form shimmers, and you appear displaced.\n\r",
victim );
act(AT_GREY, "$N shimmers and appears in a different location.",
ch, NULL, victim, TO_NOTVICT );
return;
}
void spell_domination ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( victim == ch )
{
send_to_char(C_DEFAULT, "Dominate yourself? You're weird.\n\r", ch );
return;
}
if ( !IS_NPC( victim ) )
return;
if ( IS_AFFECTED( victim, AFF_CHARM )
|| IS_AFFECTED( ch, AFF_CHARM )
|| level < victim->level
|| saves_spell( level, victim ) )
return;
if ( victim->master )
stop_follower( victim );
add_follower( victim, ch );
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 4 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char( victim, &af );
act(AT_BLUE, "Your will dominates $N!", ch, NULL, victim, TO_CHAR );
act(AT_BLUE, "Your will is dominated by $n!", ch, NULL, victim, TO_VICT );
return;
}
void spell_ectoplasmic_form ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_PASS_DOOR ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 4 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PASS_DOOR;
affect_to_char( victim, &af );
send_to_char(AT_GREY, "You turn translucent.\n\r", victim );
act(AT_GREY, "$n turns translucent.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_ego_whip ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) || saves_spell( level, victim ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_HITROLL;
af.modifier = -2;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = 2;
affect_to_char( victim, &af );
af.location = APPLY_AC;
af.modifier = level / 2;
affect_to_char( victim, &af );
act(AT_BLUE, "You ridicule $N about $S childhood.", ch, NULL, victim, TO_CHAR );
send_to_char(AT_BLUE, "Your ego takes a beating.\n\r", victim );
act(AT_BLUE, "$N's ego is crushed by $n!", ch, NULL, victim, TO_NOTVICT );
return;
}
void spell_energy_containment ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level / 2 + 7;
af.modifier = -level / 3;
af.location = APPLY_SAVING_SPELL;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "You can now absorb some forms of energy.\n\r", ch );
return;
}
void spell_enhance_armor (int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj = (OBJ_DATA *) vo;
AFFECT_DATA *paf;
if ( obj->item_type != ITEM_ARMOR
|| IS_OBJ_STAT( obj, ITEM_MAGIC )
|| obj->affected )
{
send_to_char(AT_BLUE, "That item cannot be enhanced.\n\r", ch );
return;
}
if ( !affect_free )
{
paf = alloc_perm( sizeof( *paf ) );
}
else
{
paf = affect_free;
affect_free = affect_free->next;
}
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_AC;
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
if ( number_percent() < ch->pcdata->learned[sn]/2
+ 3 * ( ch->level - obj->level ) )
/* Good enhancement */
{
paf->modifier = -level / 5;
if ( IS_GOOD( ch ) )
{
SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL );
act(AT_BLUE, "$p glows.", ch, obj, NULL, TO_CHAR );
}
else if ( IS_EVIL( ch ) )
{
SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD );
act(AT_RED, "$p glows.", ch, obj, NULL, TO_CHAR );
}
else
{
SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL );
SET_BIT( obj->extra_flags, ITEM_ANTI_GOOD );
act(AT_YELLOW, "$p glows.", ch, obj, NULL, TO_CHAR );
}
send_to_char(AT_BLUE, "Ok.\n\r", ch );
}
else
/* Bad Enhancement ... opps! :) */
{
paf->modifier = level / 8;
#ifdef NEW_MONEY
obj->cost.gold = obj->cost.silver = obj->cost.copper = 0;
#else
obj->cost = 0;
#endif
SET_BIT( obj->extra_flags, ITEM_NODROP );
act(AT_DGREY, "$p turns black.", ch, obj, NULL, TO_CHAR );
}
return;
}
void spell_enhanced_strength ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_STR;
af.modifier = 1 + ( level >= 15 ) + ( level >= 25 );
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "You are HUGE!\n\r", victim );
return;
}
void spell_flesh_armor ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_AC;
af.modifier = -45;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "Your flesh turns to steel.\n\r", victim );
act(AT_BLUE, "$N's flesh turns to steel.", ch, NULL, victim, TO_NOTVICT);
return;
}
void spell_inertial_barrier ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *gch;
AFFECT_DATA af;
for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
{
if ( !is_same_group( gch, ch ) || IS_AFFECTED2( gch, AFF_INERTIAL ) )
continue;
act(AT_BLUE, "An inertial barrier forms around $n.", gch, NULL, NULL,
TO_ROOM );
send_to_char(AT_BLUE, "An inertial barrier forms around you.\n\r", gch );
af.type = sn;
af.level = level;
af.duration = 24;
af.modifier = 0;
af.location = APPLY_NONE;
af.bitvector = AFF_INERTIAL;
affect_to_char2( gch, &af );
}
return;
}
void spell_inflict_pain ( int sn, int level, CHAR_DATA *ch, void *vo )
{
int dam = dice( 2, 10 ) + level / 2;
dam = sc_dam( ch, dam );
damage( ch, (CHAR_DATA *) vo, dam, sn );
return;
}
void spell_intellect_fortress ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *gch;
AFFECT_DATA af;
for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
{
if ( !is_same_group( gch, ch ) || is_affected( gch, sn ) )
continue;
send_to_char(AT_BLUE, "A virtual fortress forms around you.\n\r", gch );
act(AT_BLUE, "A virtual fortress forms around $N.", gch, NULL, gch, TO_ROOM );
af.type = sn;
af.level = level;
af.duration = 24;
af.location = APPLY_AC;
af.modifier = -40;
af.bitvector = 0;
affect_to_char( gch, &af );
}
return;
}
void spell_lend_health ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int hpch;
if ( ch == victim )
{
send_to_char(AT_BLUE, "Lend health to yourself? Easily done.\n\r", ch );
return;
}
hpch = UMIN( 50, MAX_HIT(victim) - victim->hit );
if ( hpch == 0 )
{
act(AT_BLUE, "Nice thought, but $N doesn't need healing.", ch, NULL,
victim, TO_CHAR );
return;
}
if ( ch->hit-hpch < 50 )
{
send_to_char(AT_BLUE, "You aren't healthy enough yourself!\n\r", ch );
return;
}
victim->hit += hpch;
ch->hit -= hpch;
update_pos( victim );
update_pos( ch );
act(AT_BLUE, "You lend some of your health to $N.", ch, NULL, victim, TO_CHAR );
act(AT_BLUE, "$n lends you some of $s health.", ch, NULL, victim, TO_VICT );
return;
}
void spell_levitation ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_FLYING ) )
return;
af.type = sn;
af.level = level;
af.duration = level + 3;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FLYING;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "Your feet rise off the ground.\n\r", victim );
act(AT_BLUE, "$n's feet rise off the ground.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_mental_barrier ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 24;
af.location = APPLY_AC;
af.modifier = -20;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "You erect a mental barrier around yourself.\n\r",
victim );
return;
}
void spell_mind_thrust ( int sn, int level, CHAR_DATA *ch, void *vo )
{
int dam = dice( 1, 10 ) + level / 2;
dam = sc_dam( ch, dam );
damage( ch, (CHAR_DATA *) vo, dam, sn );
return;
}
void spell_project_force ( int sn, int level, CHAR_DATA *ch, void *vo )
{
int dam = dice( 4, 6 ) + level;
damage( ch, (CHAR_DATA *) vo, dam, sn );
return;
}
void spell_psionic_blast ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 45, 50, 55, 60,
64, 68, 72, 76, 80, 82, 84, 86, 88, 90,
92, 94, 96, 98, 100, 102, 104, 106, 108, 100,
112, 114, 116, 118, 120, 122, 124, 126, 128, 130,
132, 134, 136, 138, 140, 142, 144, 146, 148, 150,
152, 154, 156, 158, 160, 162, 164, 166, 168, 170,
182, 184, 186, 188, 190, 192, 194, 196, 198, 200,
202, 204, 206, 208, 210, 212, 214, 216, 218, 220,
222, 224, 226, 228, 230, 232, 234, 236, 238, 240
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] );
dam = sc_dam( ch, dam );
if ( saves_spell( level, victim ) && ch->race != RACE_ILLITHID )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_psychic_crush ( int sn, int level, CHAR_DATA *ch, void *vo )
{
int dam = dice( 3, 5 ) + level;
damage( ch, (CHAR_DATA *) vo, dam, sn );
return;
}
void spell_psychic_drain ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) || saves_spell( level, victim ) )
return;
af.type = sn;
af.level = level;
af.duration = level / 2;
af.location = APPLY_STR;
af.modifier = -1 - ( level >= 10 ) - ( level >= 20 ) - ( level >= 30 );
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_GREEN, "You feel drained.\n\r", victim );
act(AT_BLUE, "$n appears drained of strength.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_psychic_healing ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = dice( 3, 6 ) + 2 * level / 3 ;
victim->hit = UMIN( victim->hit + heal, MAX_HIT(victim) );
update_pos( victim );
send_to_char(AT_BLUE, "You feel better!\n\r", victim );
return;
}
void spell_share_strength ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( victim == ch )
{
send_to_char(AT_BLUE, "You can't share strength with yourself.\n\r", ch );
return;
}
if ( is_affected( victim, sn ) )
{
act(AT_BLUE, "$N already shares someone's strength.", ch, NULL, victim,
TO_CHAR );
return;
}
if ( get_curr_str( ch ) <= 5 )
{
send_to_char(AT_BLUE, "You are too weak to share your strength.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_STR;
af.modifier = 1 + ( level >= 20 ) + ( level >= 30 );
af.bitvector = 0;
affect_to_char( victim, &af );
af.modifier = -1 - ( level >= 20 ) - ( level >= 30 );
affect_to_char( ch, &af );
act(AT_BLUE, "You share your strength with $N.", ch, NULL, victim, TO_CHAR );
act(AT_BLUE, "$n shares $s strength with you.", ch, NULL, victim, TO_VICT );
return;
}
void spell_thought_shield ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_AC;
af.modifier = -20;
af.bitvector = 0;
affect_to_char( victim, &af );
send_to_char(AT_BLUE, "You have created a shield around yourself.\n\r", ch );
return;
}
void spell_ultrablast ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
int dam;
int hpch;
for ( vch = ch->in_room->people; vch; vch = vch_next )
{
vch_next = vch->next_in_room;
if ( vch->deleted )
continue;
if ( IS_NPC( ch ) ? !IS_NPC( vch ) : IS_NPC( vch ) )
{
hpch = UMAX( 10, ch->hit );
dam = number_range( hpch / 8, hpch / 3 );
dam = sc_dam( ch, dam );
if ( saves_spell( level, vch ) )
dam /= 2;
damage( ch, vch, dam, sn );
}
}
return;
}
/* XORPHOX summon mobs */
void spell_summon_swarm(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *mob;
CHAR_DATA *fch;
AFFECT_DATA af;
char buf [ MAX_STRING_LENGTH ];
int mana;
if(ch->summon_timer > 0)
{
send_to_char(AT_BLUE,
"You casted the spell, but nothing appears.\n\r", ch);
return;
}
mob = create_mobile(get_mob_index(MOB_VNUM_INSECTS));
mob->level = URANGE(15, level, 55) - 5;
mob->perm_hit = mob->level * 20 + dice(1,mob->level);
mob->hit = MAX_HIT(mob);
mob->summon_timer = level/5;
ch->summon_timer = 10;
char_to_room(mob, ch->in_room);
act(AT_BLUE, "You summon $N.", ch, NULL, mob, TO_CHAR);
mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2;
if ( MT( ch ) < mana )
{
sprintf( buf, "%sYou don't have enough %s to bind $N!",
(is_class( ch, CLASS_VAMPIRE )) ? "&r" : "&R",
(is_class( ch, CLASS_VAMPIRE )) ? "blood" : "mana" );
act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR );
extract_char( mob, TRUE );
return;
}
MT( ch ) -= mana;
act(AT_GREEN, "$n summons $N.", ch, NULL, mob, TO_ROOM);
mob->master = ch;
mob->leader = ch;
af.type = skill_lookup("charm person");
af.level = level;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char(mob, &af);
if(ch->position == POS_FIGHTING)
{
act(AT_BLUE, "$n rescues you!", mob, NULL, ch, TO_VICT );
act(AT_BLUE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT );
fch = ch->fighting;
stop_fighting(fch, FALSE );
stop_fighting( ch, FALSE );
fch->fighting = mob;
mob->fighting = fch;
/* set_fighting(mob, fch);
set_fighting(fch, mob);*/
}
return;
}
void spell_summon_pack(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *mob;
CHAR_DATA *fch;
AFFECT_DATA af;
char buf [ MAX_STRING_LENGTH ];
int mana;
if(ch->summon_timer > 0)
{
send_to_char(AT_BLUE,
"You casted the spell, but nothing appears.\n\r", ch);
return;
}
mob = create_mobile(get_mob_index(MOB_VNUM_WOLFS));
mob->level = URANGE(31, level, 90) - 5;
mob->perm_hit = mob->level * 20 + dice(1,mob->level);
mob->hit = MAX_HIT(mob);
mob->summon_timer = level/8;
ch->summon_timer = 15;
char_to_room(mob, ch->in_room);
act(AT_GREEN, "You summon $N.", ch, NULL, mob, TO_CHAR);
mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2;
if ( MT( ch ) < mana )
{
sprintf( buf, "%sYou don't have enough %s to bind $N!",
is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R",
is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" );
act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR );
extract_char( mob, TRUE );
return;
}
MT( ch ) -= mana;
act(AT_GREEN, "$N comes to $n aid.", ch, NULL, mob, TO_ROOM);
mob->master = ch;
mob->leader = ch;
af.type = skill_lookup("charm person");
af.level = level;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char(mob, &af);
if(ch->position == POS_FIGHTING)
{
act(AT_BLUE, "$n rescues you!", mob, NULL, ch, TO_VICT );
act(AT_BLUE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT );
fch = ch->fighting;
stop_fighting(fch, FALSE );
stop_fighting( ch, FALSE );
set_fighting(mob, fch);
set_fighting(fch, mob);
}
return;
}
void spell_summon_demon(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *mob;
CHAR_DATA *fch;
AFFECT_DATA af;
char buf [ MAX_STRING_LENGTH ];
int mana;
if(ch->summon_timer > 0)
{
send_to_char(AT_RED,
"You casted the spell, but nothing appears.\n\r", ch);
return;
}
mob = create_mobile(get_mob_index(MOB_VNUM_DEMON));
mob->level = URANGE(51, level, 100) - 5;
mob->perm_hit = mob->level * 20 + dice(1,mob->level);
mob->hit = MAX_HIT(mob);
mob->summon_timer = level/10;
ch->summon_timer = 16;
char_to_room(mob, ch->in_room);
act(AT_RED, "You summon $N from the abyss.", ch, NULL, mob, TO_CHAR);
mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2;
if ( MT( ch ) < mana )
{
sprintf( buf, "%sYou don't have enough %s to bind $N!",
is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R",
is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" );
act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR );
extract_char( mob, TRUE );
return;
}
MT( ch ) -= mana;
act(AT_RED, "$n summons $N from the abyss.", ch, NULL, mob, TO_ROOM);
mob->master = ch;
mob->leader = ch;
af.type = skill_lookup("charm person");
af.level = level;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char(mob, &af);
if(ch->position == POS_FIGHTING)
{
act(AT_RED, "$n rescues you!", mob, NULL, ch, TO_VICT );
act(AT_RED, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT );
fch = ch->fighting;
stop_fighting(fch, FALSE );
stop_fighting( ch, FALSE );
set_fighting(mob, fch);
set_fighting(fch, mob);
}
return;
}
void spell_summon_angel(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *mob;
CHAR_DATA *fch;
AFFECT_DATA af;
char buf[ MAX_STRING_LENGTH ];
int mana;
if(ch->summon_timer > 0)
{
send_to_char(AT_WHITE,
"You casted the spell, but nothing appears.\n\r", ch);
return;
}
mob = create_mobile(get_mob_index(MOB_VNUM_ANGEL));
mob->level = URANGE(51, level, 100) - 5;
mob->perm_hit = mob->level * 20 + dice(10,mob->level);
mob->hit = MAX_HIT(mob);
mob->summon_timer = level/10;
ch->summon_timer = 16;
char_to_room(mob, ch->in_room);
act(AT_WHITE, "You summon $N from heaven.", ch, NULL, mob, TO_CHAR);
mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2;
if ( MT( ch ) < mana )
{
sprintf( buf, "%sYou don't have enough %s to bind $N!",
is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R",
is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" );
act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR );
extract_char( mob, TRUE );
return;
}
MT( ch ) -= mana;
act(AT_WHITE, "$n calls forth $N from Heaven.", ch, NULL, mob, TO_ROOM);
mob->master = ch;
mob->leader = ch;
af.type = skill_lookup("charm person");
af.level = level;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char(mob, &af);
if(ch->position == POS_FIGHTING)
{
act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT );
act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT );
fch = ch->fighting;
stop_fighting(fch, FALSE );
stop_fighting( ch, FALSE );
set_fighting(mob, fch);
set_fighting(fch, mob);
}
return;
}
void spell_summon_shadow(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *mob;
CHAR_DATA *fch;
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
int mana;
if(ch->summon_timer > 0)
{
send_to_char(AT_WHITE,
"You casted the spell, but nothing appears.\n\r", ch);
return;
}
mob = create_mobile(get_mob_index(MOB_VNUM_SHADOW));
mob->level = URANGE(51, level, 100) - 20;
mob->perm_hit = mob->level * 20 + dice(10,mob->level);
mob->hit = MAX_HIT(mob);
mob->summon_timer = level/10;
ch->summon_timer = 16;
char_to_room(mob, ch->in_room);
act(AT_GREY, "You summon $N from the shadow plane.", ch, NULL, mob, TO_CHAR);
mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2;
if ( MT( ch ) < mana )
{
sprintf( buf, "%sYou don't have enough %s to bind $N!",
is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R",
is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" );
act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR );
extract_char( mob, TRUE );
return;
}
MT( ch ) -= mana;
act(AT_GREY, "$n calls forth $N from the shadow plane.", ch, NULL, mob, TO_ROOM);
mob->master = ch;
mob->leader = ch;
af.type = skill_lookup("charm person");
af.level = level;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char(mob, &af);
if(ch->position == POS_FIGHTING)
{
act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT );
act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT );
fch = ch->fighting;
stop_fighting(fch, FALSE );
stop_fighting( ch, FALSE );
set_fighting(mob, fch);
set_fighting(fch, mob);
}
return;
}
void spell_summon_trent(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *mob;
CHAR_DATA *fch;
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
int mana;
if(ch->summon_timer > 0)
{
send_to_char(AT_WHITE,
"You casted the spell, but nothing appears.\n\r", ch);
return;
}
mob = create_mobile(get_mob_index(MOB_VNUM_TRENT));
mob->level = URANGE(51, level, 100) - 10;
mob->perm_hit = mob->level * 20 + dice(20,mob->level);
mob->hit = MAX_HIT(mob);
mob->summon_timer = level/10;
ch->summon_timer = 16;
char_to_room(mob, ch->in_room);
act(AT_ORANGE, "You summon $N from the plane of nature.", ch, NULL, mob, TO_CHAR);
mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2;
if ( MT( ch ) < mana )
{
sprintf( buf, "%sYou don't have enough %s to bind $N!",
is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R",
is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" );
act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR );
extract_char( mob, TRUE );
return;
}
MT( ch ) -= mana;
act(AT_ORANGE, "$n calls forth $N from the plane of nature.", ch, NULL, mob, TO_ROOM);
mob->master = ch;
mob->leader = ch;
af.type = skill_lookup("charm person");
af.level = level;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char(mob, &af);
if(ch->position == POS_FIGHTING)
{
act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT );
act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT );
fch = ch->fighting;
stop_fighting(fch, FALSE );
stop_fighting( ch, FALSE );
set_fighting(mob, fch);
set_fighting(fch, mob);
}
return;
}
void spell_summon_beast(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *mob;
CHAR_DATA *fch;
AFFECT_DATA af;
char buf[MAX_STRING_LENGTH];
int mana;
char *beast;
if(ch->summon_timer > 0)
{
send_to_char(AT_WHITE,
"You casted the spell, but nothing appears.\n\r", ch);
return;
}
switch (number_bits( 4 ) )
{
case 0: beast = "horse"; break;
case 1: beast = "cow"; break;
case 2: beast = "bear"; break;
case 3: beast = "lion"; break;
case 4: beast = "bobcat"; break;
case 5: beast = "mongoose"; break;
case 6: beast = "rattle snake"; break;
case 7: beast = "monkey"; break;
default: beast = "tigeress"; break;
}
mob = create_mobile(get_mob_index(MOB_VNUM_BEAST));
sprintf(buf, mob->short_descr, beast);
free_string( mob->short_descr );
mob->short_descr = str_dup(buf);
sprintf(buf, mob->long_descr, beast, ch->name);
free_string( mob->long_descr );
mob->long_descr = str_dup(buf);
mob->level = URANGE(51, level, 100) - 20;
mob->perm_hit = mob->level * 20 + dice(10,mob->level);
mob->hit = MAX_HIT(mob);
mob->summon_timer = level/10;
ch->summon_timer = 16;
char_to_room(mob, ch->in_room);
act(AT_GREEN, "You call $N from the forests.", ch, NULL, mob, TO_CHAR);
mana = is_class( ch, CLASS_VAMPIRE ) ? level / 2 : level * 2;
if ( MT( ch ) < mana )
{
sprintf( buf, "%sYou don't have enough %s to bind $N!",
is_class( ch, CLASS_VAMPIRE ) ? "&r" : "&R",
is_class( ch, CLASS_VAMPIRE ) ? "blood" : "mana" );
act(AT_WHITE, buf, ch, NULL, mob, TO_CHAR );
extract_char( mob, TRUE );
return;
}
MT( ch ) -= mana;
act(AT_GREEN, "$n calls forth $N from the forests.", ch, NULL, mob, TO_ROOM);
mob->master = ch;
mob->leader = ch;
af.type = skill_lookup("charm person");
af.level = level;
af.duration = -1;
af.location = 0;
af.modifier = 0;
af.bitvector = AFF_CHARM;
affect_to_char(mob, &af);
if(ch->position == POS_FIGHTING)
{
act(AT_WHITE, "$n rescues you!", mob, NULL, ch, TO_VICT );
act(AT_WHITE, "$n rescues $N!", mob, NULL, ch, TO_NOTVICT );
fch = ch->fighting;
stop_fighting(fch, FALSE );
stop_fighting( ch, FALSE );
set_fighting(mob, fch);
set_fighting(fch, mob);
}
return;
}
void perm_spell(CHAR_DATA *victim, int sn)
{
AFFECT_DATA *af;
if(is_affected(victim, sn))
{
for(af = victim->affected; af != NULL; af = af->next)
{
if(af->type == sn)
{
af->duration = -1;
}
}
}
return;
}
int spell_duration(CHAR_DATA *victim, int sn)
{
AFFECT_DATA *af;
if(is_affected(victim, sn))
{
for(af = victim->affected; af != NULL; af = af->next)
{
if(af->type == sn)
{
return af->duration;
}
}
}
return -2;
}
/* RT save for dispels */
/* modified for envy -XOR */
bool saves_dispel(int dis_level, int spell_level, int duration)
{
int save;
if(duration == -1)
spell_level += 5;/* very hard to dispel permanent effects */
save = 50 + (spell_level - dis_level) * 5;
save = URANGE( 5, save, 95 );
return number_percent() < save;
}
/* co-routine for dispel magic and cancellation */
bool check_dispel(int dis_level, CHAR_DATA *victim, int sn)
{
AFFECT_DATA *af;
if (is_affected(victim, sn))
{
for(af = victim->affected; af != NULL; af = af->next)
{
if(af->type == sn)
{
if ( !saves_spell(dis_level,victim) )
/* if(!saves_dispel(dis_level,victim->level,af->duration))*/
{
affect_strip(victim,sn);
if(skill_table[sn].msg_off)
{
send_to_char(C_DEFAULT, skill_table[sn].msg_off, victim );
send_to_char(C_DEFAULT, "\n\r", victim );
if(skill_table[sn].room_msg_off)
{
act(C_DEFAULT, skill_table[sn].room_msg_off,
victim, NULL, NULL, TO_ROOM);
}
}
return TRUE;
}
else
af->level--;
}
}
}
return FALSE;
}
/* Mobs built with spells only have the flag.
* These function dispels those spells
* -Decklarean
*/
void check_dispel_aff( CHAR_DATA *victim, bool * found, int level, const char * spell, long vector )
{
int sn;
sn = skill_lookup(spell);
if(IS_AFFECTED(victim,vector)
&& !saves_spell(level, victim)
/* && !saves_dispel(level, victim->level,1) */
&& !is_affected(victim,sn) )
{
*found = TRUE;
REMOVE_BIT(victim->affected_by,vector);
if(skill_table[sn].msg_off)
{
act(C_DEFAULT, skill_table[sn].msg_off,
victim, NULL, NULL, TO_CHAR);
if(skill_table[sn].room_msg_off)
{
act(C_DEFAULT, skill_table[sn].room_msg_off,
victim, NULL, NULL, TO_ROOM);
}
}
if ( vector == AFF_FLYING )
check_nofloor( victim );
}
}
void check_dispel_aff2( CHAR_DATA *victim, bool * found, int level, const char * spell, long vector )
{
int sn;
sn = skill_lookup(spell);
if(IS_AFFECTED2(victim,vector)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,sn) )
{
*found = TRUE;
REMOVE_BIT(victim->affected_by2,vector);
if(skill_table[sn].msg_off)
{
act(C_DEFAULT, skill_table[sn].msg_off,
victim, NULL, NULL, TO_CHAR);
if(skill_table[sn].room_msg_off)
{
act(C_DEFAULT, skill_table[sn].room_msg_off,
victim, NULL, NULL, TO_ROOM);
}
}
if ( vector == AFF_FLYING )
check_nofloor( victim );
}
}
bool dispel_flag_only_spells( int level, CHAR_DATA * victim )
{
bool found;
found = FALSE;
check_dispel_aff ( victim, &found, level, "blindness",AFF_BLIND);
check_dispel_aff ( victim, &found, level, "charm person",AFF_CHARM);
check_dispel_aff ( victim, &found, level, "curse",AFF_CURSE);
check_dispel_aff ( victim, &found, level, "detect evil",AFF_DETECT_EVIL);
check_dispel_aff ( victim, &found, level, "detect hidden",AFF_DETECT_HIDDEN);
check_dispel_aff ( victim, &found, level, "detect invis",AFF_DETECT_INVIS);
check_dispel_aff ( victim, &found, level, "detect magic",AFF_DETECT_MAGIC);
check_dispel_aff ( victim, &found, level, "faerie fire",AFF_FAERIE_FIRE );
check_dispel_aff ( victim, &found, level, "fireshield", AFF_FIRESHIELD );
check_dispel_aff ( victim, &found, level, "flaming",AFF_FLAMING );
check_dispel_aff ( victim, &found, level, "fly",AFF_FLYING);
check_dispel_aff ( victim, &found, level, "haste",AFF_HASTE);
check_dispel_aff ( victim, &found, level, "iceshield",AFF_ICESHIELD );
check_dispel_aff ( victim, &found, level, "infravision",AFF_INFRARED );
check_dispel_aff ( victim, &found, level, "invis",AFF_INVISIBLE );
check_dispel_aff ( victim, &found, level, "pass door",AFF_PASS_DOOR );
check_dispel_aff ( victim, &found, level, "protection evil",AFF_PROTECT );
check_dispel_aff ( victim, &found, level, "sanctuary",AFF_SANCTUARY );
check_dispel_aff ( victim, &found, level, "shockshield",AFF_SHOCKSHIELD );
check_dispel_aff ( victim, &found, level, "sleep",AFF_SLEEP);
check_dispel_aff2( victim, &found, level, "detect good",AFF_DETECT_GOOD );
check_dispel_aff2( victim, &found, level, "field of decay", AFF_FIELD);
check_dispel_aff2( victim, &found, level, "protection good",AFF_PROTECTION_GOOD );
check_dispel_aff2( victim, &found, level, "true sight",AFF_TRUESIGHT );
return found;
}
/* New dispel magic by Decklarean
* The old way was just to stupid. :>
* This will dispel all magic spells.
*/
void spell_dispel_magic ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA *paf;
bool found;
if (saves_spell(level, victim))
{
send_to_char(AT_RED, "You feel a brief tingling sensation.\n\r",victim);
send_to_char(AT_RED, "The spell failed.\n\r",ch);
return;
}
found = FALSE;
/* Check dispel of spells that mobs where built with */
if (IS_NPC( victim ) )
found = dispel_flag_only_spells( level, victim );
/* Check dispel of spells cast */
for( paf = victim->affected; paf; paf = paf->next )
{
if (paf->deleted)
continue;
if ( skill_table[paf->type].spell_fun != spell_null
&& skill_table[paf->type].dispelable == TRUE )
if(check_dispel(level,victim,paf->type))
found = TRUE;
}
for( paf = victim->affected2; paf; paf = paf->next )
{
if (paf->deleted)
continue;
if ( skill_table[paf->type].spell_fun != spell_null
&& skill_table[paf->type].dispelable == TRUE )
if(check_dispel(level,victim,paf->type))
found = TRUE;
}
if(found)
{
send_to_char(AT_RED, "You feel a brief tingling sensation.\n\r",victim);
send_to_char(AT_YELLOW,
"Unraveled magical energy ripple away at your succes.\n\r",ch);
}
else
send_to_char(AT_RED, "The spell failed.\n\r",ch);
}
/* modified by XOR */
/* Rom2 modified for enhanced use */
/*
void spell_dispel_magic ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
bool found = FALSE;
if(saves_spell(level, victim))
{
send_to_char(C_DEFAULT, "You feel a brief tingling sensation.\n\r",victim);
send_to_char(C_DEFAULT, "You failed.\n\r", ch);
}
*/
/* begin running through the spells */
/*
if(check_dispel(level,victim,skill_lookup("armor")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("bless")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("blindness")))
{
found = TRUE;
act(C_DEFAULT, "$n is no longer blinded.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("change sex")))
{
found = TRUE;
act(C_DEFAULT, "$n looks more like $mself again.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("charm person")))
{
found = TRUE;
act(C_DEFAULT, "$n regains $s free will.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("chill touch")))
{
found = TRUE;
act(C_DEFAULT, "$n looks warmer.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("curse")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("detect evil")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("detect hidden")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("detect invis")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("detect magic")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("faerie fire")))
{
found = TRUE;
act(C_DEFAULT, "$n's outline fades.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("fly")))
{
found = TRUE;
act(C_DEFAULT, "$n falls to the ground!",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("giant strength")))
{
found = TRUE;
act(C_DEFAULT, "$n no longer looks so mighty.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("infravision")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("invis")))
{
found = TRUE;
act(C_DEFAULT, "$n fades into existance.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("mass invis")))
{
found = TRUE;
act(C_DEFAULT, "$n fades into existance.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("pass door")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("protection")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("sanctuary")))
{
found = TRUE;
act(C_DEFAULT, "The white aura around $n's body vanishes.",
victim,NULL,NULL,TO_ROOM);
}
if(IS_AFFECTED(victim,AFF_SANCTUARY)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,skill_lookup("sanctuary")))
{
found = TRUE;
REMOVE_BIT(victim->affected_by,AFF_SANCTUARY);
act(C_DEFAULT, "The white aura around $n's body vanishes.",
victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("shield")))
{
found = TRUE;
act(C_DEFAULT, "The shield protecting $n vanishes.",
victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("sleep")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("stone skin")))
{
act(C_DEFAULT, "$n's skin regains its normal texture.",
victim,NULL,NULL,TO_ROOM);
found = TRUE;
}
if(check_dispel(level,victim,skill_lookup("weaken")))
{
act(C_DEFAULT, "$n looks stronger.",victim,NULL,NULL,TO_ROOM);
found = TRUE;
}
if(check_dispel(level,victim,skill_lookup("fireshield")))
{
found = TRUE;
act(AT_RED, "The flames about $n's body burn out.",
victim, NULL, NULL, TO_ROOM );
}
if(IS_AFFECTED(victim,AFF_FIRESHIELD)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,skill_lookup("fireshield")))
{
found = TRUE;
REMOVE_BIT(victim->affected_by,AFF_FIRESHIELD);
act(AT_RED, "The flames about $n's body burn out.",
victim, NULL, NULL, TO_ROOM );
}
if(check_dispel(level,victim,skill_lookup("shockshield")))
{
found = TRUE;
act(AT_BLUE, "The electricity about $n's body flee's into the ground.",
victim, NULL, NULL, TO_ROOM );
}
if(IS_AFFECTED(victim,AFF_SHOCKSHIELD)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,skill_lookup("shockshield")))
{
found = TRUE;
REMOVE_BIT(victim->affected_by,AFF_SHOCKSHIELD);
act(AT_BLUE, "The electricity about $n's body flee's into the ground.",
victim, NULL, NULL, TO_ROOM );
}
if(check_dispel(level,victim,skill_lookup("iceshield")))
{
found = TRUE;
act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.",
victim, NULL, NULL, TO_ROOM);
}
if(IS_AFFECTED(victim,AFF_ICESHIELD)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,skill_lookup("iceshield")))
{
found = TRUE;
REMOVE_BIT(victim->affected_by,AFF_ICESHIELD);
act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.",
victim, NULL, NULL, TO_ROOM );
}
if(found)
send_to_char(C_DEFAULT, "Ok.\n\r",ch);
else
send_to_char(C_DEFAULT, "Spell failed.\n\r",ch);
*/
/*
if ( !victim->fighting || !is_same_group( ch, victim->fighting ) )
multi_hit( victim, ch, TYPE_UNDEFINED );
*/
/* return;
}*/
/* New cancellation by Decklarean
* The old way was just to stupid. :>
* This will dispell all magic spells.
*/
void spell_cancellation(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA *paf;
bool found;
if((!IS_NPC(ch) && IS_NPC(victim)
&& !(IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim))
|| (IS_NPC(ch) && !IS_NPC(victim))
|| !is_same_group(ch, victim))
{
send_to_char(C_DEFAULT, "You failed, try dispel magic.\n\r",ch);
return;
}
found = FALSE;
/* Check dispel of spells that mobs where built with */
if (IS_NPC( victim ) )
found = dispel_flag_only_spells( level, victim );
/* Check dispel of spells cast */
for( paf = victim->affected; paf; paf = paf->next )
{
if ( skill_table[paf->type].spell_fun != spell_null
&& skill_table[paf->type].spell_fun != spell_poison
)
if( check_dispel(level,victim,paf->type) )
found = TRUE;
}
for( paf = victim->affected2; paf; paf = paf->next )
{
if ( skill_table[paf->type].spell_fun != spell_null
&& skill_table[paf->type].spell_fun != spell_poison
)
if( check_dispel(level,victim,paf->type) )
found = TRUE;
}
if(found)
send_to_char(AT_YELLOW,
"Unraveled magical energy ripple away at your succes.\n\r",ch);
else
send_to_char(AT_RED, "The spell failed.\n\r",ch);
}
/*
void spell_cancellation(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
bool found = FALSE;
level += 2;
if((!IS_NPC(ch) && IS_NPC(victim)
&& !(IS_AFFECTED(ch, AFF_CHARM) && ch->master == victim))
|| (IS_NPC(ch) && !IS_NPC(victim))
|| !is_same_group(ch, victim))
{
send_to_char(C_DEFAULT, "You failed, try dispel magic.\n\r",ch);
return;
}
*/
/* unlike dispel magic, victim gets NO save */
/* begin running through the spells */
/*
if(check_dispel(level,victim,skill_lookup("armor")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("bless")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("blindness")))
{
found = TRUE;
act(C_DEFAULT, "$n is no longer blinded.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("change sex")))
{
found = TRUE;
act(C_DEFAULT, "$n looks more like $mself again.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("charm person")))
{
found = TRUE;
act(C_DEFAULT, "$n regains $s free will.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("chill touch")))
{
found = TRUE;
act(C_DEFAULT, "$n looks warmer.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("curse")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("detect evil")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("detect hidden")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("detect invis")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("detect magic")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("faerie fire")))
{
found = TRUE;
act(C_DEFAULT, "$n's outline fades.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("fly")))
{
found = TRUE;
act(C_DEFAULT, "$n falls to the ground!",victim,NULL,NULL,TO_ROOM);
check_nofloor( ch );
}
if(check_dispel(level,victim,skill_lookup("giant strength")))
{
found = TRUE;
act(C_DEFAULT, "$n no longer looks so mighty.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("infravision")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("invis")))
{
found = TRUE;
act(C_DEFAULT, "$n fades into existance.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("mass invis")))
{
found = TRUE;
act(C_DEFAULT, "$n fades into existance.",victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("pass door")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("protection")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("sanctuary")))
{
found = TRUE;
act(C_DEFAULT, "The white aura around $n's body vanishes.",
victim,NULL,NULL,TO_ROOM);
}
if(IS_AFFECTED(victim,AFF_SANCTUARY)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,skill_lookup("sanctuary")))
{
found = TRUE;
REMOVE_BIT(victim->affected_by,AFF_SANCTUARY);
act(C_DEFAULT, "The white aura around $n's body vanishes.",
victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("shield")))
{
found = TRUE;
act(C_DEFAULT, "The shield protecting $n vanishes.",
victim,NULL,NULL,TO_ROOM);
}
if(check_dispel(level,victim,skill_lookup("sleep")))
found = TRUE;
if(check_dispel(level,victim,skill_lookup("stone skin")))
{
act(C_DEFAULT, "$n's skin regains its normal texture.",
victim,NULL,NULL,TO_ROOM);
found = TRUE;
}
if(check_dispel(level,victim,skill_lookup("weaken")))
{
act(C_DEFAULT, "$n looks stronger.",victim,NULL,NULL,TO_ROOM);
found = TRUE;
}
if(check_dispel(level,victim,skill_lookup("fireshield")))
{
found = TRUE;
act(AT_RED, "The flames about $n's body burn out.",
victim, NULL, NULL, TO_ROOM );
}
if(IS_AFFECTED(victim,AFF_FIRESHIELD)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,skill_lookup("fireshield")))
{
found = TRUE;
REMOVE_BIT(victim->affected_by,AFF_FIRESHIELD);
act(AT_RED, "The flames about $n's body burn out.",
victim, NULL, NULL, TO_ROOM );
}
if(check_dispel(level,victim,skill_lookup("shockshield")))
{
found = TRUE;
act(AT_BLUE, "The electricity about $n's body flee's into the ground.",
victim, NULL, NULL, TO_ROOM );
}
if(IS_AFFECTED(victim,AFF_SHOCKSHIELD)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,skill_lookup("shockshield")))
{
found = TRUE;
REMOVE_BIT(victim->affected_by,AFF_SHOCKSHIELD);
act(AT_BLUE, "The electricity about $n's body flee's into the ground.",
victim, NULL, NULL, TO_ROOM );
}
if(check_dispel(level,victim,skill_lookup("iceshield")))
{
found = TRUE;
act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.",
victim, NULL, NULL, TO_ROOM);
}
if(IS_AFFECTED(victim,AFF_ICESHIELD)
&& !saves_dispel(level, victim->level,-1)
&& !is_affected(victim,skill_lookup("iceshield")))
{
found = TRUE;
REMOVE_BIT(victim->affected_by,AFF_ICESHIELD);
act(AT_LBLUE, "The icy crust about $n's body melts to a puddle.",
victim, NULL, NULL, TO_ROOM );
}
if(found)
send_to_char(C_DEFAULT, "Ok.\n\r",ch);
else
send_to_char(C_DEFAULT, "Spell failed.\n\r",ch);
return;
}*/
/*
* Turn undead and mental block by Altrag
*/
void spell_turn_undead( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int chance;
if ( !IS_NPC(victim) || !IS_SET(victim->act, ACT_UNDEAD))
{
send_to_char(C_DEFAULT, "Spell failed.\n\r", ch );
return;
}
chance = (level * (10 + IS_GOOD(ch) ? 15 : IS_EVIL(ch) ? 0 : 10) );
chance /= victim->level;
if (number_percent( ) < chance && !saves_spell( level, victim ))
{
act(AT_WHITE,"$n has turned $N!",ch,NULL,victim,TO_ROOM);
act(AT_WHITE,"You have turned $N!",ch,NULL,victim,TO_CHAR);
raw_kill(ch,victim);
return;
}
send_to_char(C_DEFAULT,"Spell failed.\n\r",ch);
return;
}
void spell_mental_block( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim,sn) )
return;
af.type = sn;
af.level = level;
af.duration = number_range( level / 4, level / 2 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_NOASTRAL;
affect_to_char( victim, &af );
send_to_char( AT_BLUE, "Your mind feels free of instrusion.\n\r",victim);
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r",ch);
}
/* END */
void spell_protection_good(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *)vo;
AFFECT_DATA af;
if ( IS_AFFECTED2(ch, AFF_PROTECTION_GOOD) )
return;
af.type = sn;
af.level = level;
af.duration = 24;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_PROTECTION_GOOD;
affect_to_char2( victim, &af );
if ( ch != victim )
send_to_char( AT_BLUE, "Ok.\n\r",ch);
send_to_char(AT_BLUE, "You feel protected.\n\r",victim);
return;
}
void spell_detect_good(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *)vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_DETECT_GOOD ) )
return;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DETECT_GOOD;
affect_to_char2(ch, &af);
if ( ch != victim)
send_to_char(AT_BLUE, "Ok.\n\r",ch);
send_to_char(AT_BLUE, "Your eyes tingle.\n\r",victim);
return;
}
void spell_holy_strength(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if(victim->position == POS_FIGHTING || is_affected(victim, sn))
return;
af.type = sn;
af.level = level;
af.duration = 6 + level;
af.location = APPLY_HITROLL;
af.modifier = level / 4;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_DAMROLL;
af.modifier = level / 4;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = level / 50;
affect_to_char( victim, &af );
if(ch != victim)
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "The strength of the gods fills you.\n\r", victim);
return;
}
void spell_curse_of_nature(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim, sn) )
{
send_to_char(AT_RED, "You have failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = 6 + level;
af.location = APPLY_HITROLL;
af.modifier = 0 - level * 2 / 3;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_DAMROLL;
af.modifier = 0 - level * 2 / 3;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = 0 - level / 30;
affect_to_char( victim, &af );
if(ch != victim)
send_to_char(AT_GREEN, "Ok.\n\r", ch );
send_to_char(AT_GREEN, "The wrath of nature wrecks you.\n\r", victim);
return;
}
void spell_enchanted_song(int sn, int level, CHAR_DATA *ch, void *vo)
{
CHAR_DATA *victim = (CHAR_DATA *)vo;
CHAR_DATA *rch = get_char(ch);
if ( ch == victim )
{
act( AT_BLUE, "$n sings an enchanting song.", ch, NULL, NULL, TO_ROOM );
send_to_char(AT_BLUE, "You sing a song.\n\r", ch );
}
act( AT_BLUE, "Your song pacifies $N.", ch, NULL, victim, TO_CHAR );
act( AT_BLUE, "$n's song pacifies $N.", ch, NULL, victim, TO_NOTVICT );
act( AT_BLUE, "$n's song slows your reactions.", ch, NULL, victim, TO_VICT );
STUN_CHAR( victim, 1, STUN_TOTAL );
for ( rch = ch->in_room->people; rch; rch = rch->next_in_room )
{
if ( rch->fighting )
stop_fighting( rch, TRUE );
}
return;
}
/* RT haste spell */
void spell_haste( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) || IS_AFFECTED(victim,AFF_HASTE)
/* || IS_SET(victim->off_flags,OFF_FAST)*/)
{
if (victim == ch)
send_to_char(C_DEFAULT, "You can't move any faster!\n\r",ch);
else
act(C_DEFAULT, "$N is already moving as fast as $e can.",
ch,NULL,victim,TO_CHAR);
return;
}
af.type = sn;
af.level = level;
if (victim == ch)
af.duration = level/2;
else
af.duration = level/4;
af.location = APPLY_DEX;
af.modifier = 1 + (level >= 18) + (level >= 25) + (level >= 32);
af.bitvector = AFF_HASTE;
affect_to_char( victim, &af );
send_to_char(C_DEFAULT,
"You feel yourself moving more quickly.\n\r", victim );
act(C_DEFAULT, "$n is moving more quickly.",victim,NULL,NULL,TO_ROOM);
if ( ch != victim )
send_to_char(C_DEFAULT, "Ok.\n\r", ch );
return;
}
void spell_healing_hands( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *)vo;
int divisor = 1;
int heal = 0;
if ( ch == victim )
{
int mana;
/* Refund mana lost by casting. Make it seem like a new target type. */
mana = SPELL_COST( ch, sn );
MT( ch ) -= mana;
send_to_char(AT_BLUE, "You cannot cast this spell on yourself.\n\r", ch );
return;
}
if ( victim->hit >= MAX_HIT(victim) )
{
act(AT_BLUE, "You heal $N.", ch, NULL, victim, TO_CHAR );
return;
}
if ( IS_NEUTRAL( ch ) )
divisor = 2;
if ( IS_EVIL( ch ) )
divisor = 4;
/* divisos += 2;*/
heal = (MAX_HIT(victim) - victim->hit) / divisor;
victim->hit += heal;
act(AT_BLUE, "You heal $N.", ch, NULL, victim, TO_CHAR);
act(AT_BLUE, "$n heals you.", ch, NULL, victim, TO_VICT);
act(AT_BLUE, "$n heals $N.", ch, NULL, victim, TO_NOTVICT);
return;
}
void spell_hex( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_BLIND + AFF_CURSE )
&& IS_AFFECTED2( victim, AFF_CONFUSED ) )
{
act( AT_DGREY, "$N is already hexed.", ch, NULL, victim, TO_CHAR );
return;
}
if ( saves_spell( level, victim ) )
{
act( AT_DGREY, "$N resists the hex.", ch, NULL, victim, TO_CHAR );
return;
}
af.type = sn;
af.level = level;
af.duration = ( 2 * level / 3 + 20 ) / 2;
af.location = APPLY_HITROLL;
af.modifier = -10;
af.bitvector = AFF_BLIND;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = -1;
af.bitvector = AFF_CURSE;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = 1;
af.bitvector = AFF_CURSE;
affect_to_char( victim, &af );
af.location = APPLY_STR;
af.modifier = -1 - ( level >= 20 ) - ( level >= 40 ) - ( level >= 60 ) - ( level >= 80 );
affect_to_char( victim, &af );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_CONFUSED;
affect_to_char2( victim, &af );
send_to_char( AT_DGREY, "You have hexed your opponent.\n\r", ch );
send_to_char( AT_DGREY, "A hex has been placed upon your soul.\n\r", victim );
return;
}
void spell_dark_ritual( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj;
int mana;
bool found = FALSE;
for ( obj = ch->in_room->contents; obj; obj = obj->next )
{
if ( obj->deleted )
continue;
if ( obj->item_type == ITEM_CORPSE_NPC )
{
found = TRUE;
break;
}
}
if ( found == TRUE )
{
mana = UMAX( 30, number_fuzzy( level / 2 ) );
ch->mana += mana;
ch->mana = UMIN( MAX_MANA(ch), ch->mana );
send_to_char( AT_DGREY, "You extract the last of the energy from the corpse.\n\r",
ch );
act( AT_DGREY, "$n saps away the last of the mystical energies from the $p.",
ch, obj, NULL, TO_ROOM );
extract_obj( obj );
}
else
send_to_char( AT_DGREY, "You must have a corpse to sacrifice to perform a dark ritual.\n\r", ch );
return;
}
void spell_field_of_decay( int sn, int level, CHAR_DATA *ch, void *vo )
{
AFFECT_DATA af;
if ( IS_AFFECTED2( ch, AFF_FIELD ) )
return;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 5 );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FIELD;
affect_to_char2( ch, &af );
send_to_char( AT_DGREY, "You summon the power of the dead and a black haze envelops you.\n\r", ch );
act( AT_DGREY, "A black haze emanates from $n's body and envelops $m.",
ch, NULL, NULL, TO_ROOM );
return;
}
void spell_stench_of_decay( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 30, 35, 40, 45, 50, 55,
60, 65, 70, 75, 80, 82, 84, 86, 88, 90,
92, 94, 96, 98, 100, 102, 104, 106, 108, 110,
112, 114, 116, 118, 120, 122, 124, 126, 128, 130,
132, 134, 136, 138, 140, 142, 144, 146, 148, 150,
152, 154, 156, 158, 160, 162, 164, 166, 168, 170,
172, 174, 176, 178, 180, 182, 184, 186, 188, 190,
192, 194, 196, 198, 200, 202, 204, 206, 208, 210,
215, 220, 225, 230, 235, 240, 245, 250, 255, 260
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1 );
level = UMAX( 0, level );
dam = number_range( dam_each[level] / 2, dam_each[level] * 7 );
dam = sc_dam( ch, dam );
if ( IS_AFFECTED2( victim, AFF_FIELD ) )
dam /= 6;
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
return;
}
void spell_soul_bind( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *soulgem;
if ( !IS_NPC(victim) || saves_spell( level, victim ) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch);
return;
}
soulgem = create_object( get_obj_index( OBJ_VNUM_SOULGEM ), 0 );
soulgem->ac_vnum = victim->pIndexData->vnum;
soulgem->level = ch->level;
soulgem->timer = ch->level / 4;
#ifdef NEW_MONEY
soulgem->cost.silver = soulgem->cost.copper = 0;
soulgem->cost.gold = victim->level * 10;
#else
soulgem->cost = victim->level * 10;
#endif
soulgem->ac_charge[0] = soulgem->ac_charge[1] = 1;
obj_to_char( soulgem , ch );
act(AT_BLUE, "You tear out $Ns soul, binding it to form a Soulgem.", ch, NULL, victim, TO_CHAR);
act(AT_BLUE, "$n tears out $Ns soul, binding it to form a Soulgem.", ch, NULL, victim, TO_ROOM);
act(AT_BLUE, "$N screams in agony as it slowly dissipates into nothingness!", ch, NULL, victim, TO_CHAR);
act(AT_BLUE, "$N screams in agony as it slowly dissipates into nothingness!", ch, NULL, victim, TO_ROOM);
act(AT_WHITE, "Your SOUL is STOLEN by $n!", ch, NULL, victim, TO_VICT);
if ( IS_NPC( victim ) )
extract_char( victim, TRUE );
else
extract_char( victim, FALSE );
return;
}
/* MONK SPELLS */
void spell_iron_skin( int sn, int level, CHAR_DATA *ch, void *vo )
{
AFFECT_DATA af;
if ( is_affected( ch, sn ) )
return;
send_to_char( AT_GREY, "Your skin turns to iron.\n\r", ch );
act( AT_GREY, "$n's skin turns to iron.", ch, NULL, NULL, TO_ROOM );
af.type = sn;
af.level = ch->level;
af.duration = ch->level / 6;
af.location = APPLY_AC;
af.modifier = 0 - number_fuzzy( ch->level ) / 2;
af.bitvector = AFF_INERTIAL;
affect_to_char2( ch, &af );
return;
}
void spell_chi_shield( int sn, int level, CHAR_DATA *ch, void *vo )
{
AFFECT_DATA af;
if ( is_affected( ch, sn ) )
return;
send_to_char( AT_BLUE, "You tap into your chi and use it to raise a chi shield.\n\r", ch );
act( AT_BLUE, "$n is surrounded by a chi shield.", ch, NULL, NULL, TO_ROOM );
af.type = sn;
af.level = ch->level * 2;
af.duration = ch->level / 4;
af.location = APPLY_SAVING_SPELL;
af.modifier = 0 - ch->level/4;
af.bitvector = AFF_PROTECT;
affect_to_char( ch, &af );
af.location = APPLY_SAVING_BREATH;
af.modifier = 0 - ch->level / 4;
af.bitvector = AFF_PROTECTION_GOOD;
affect_to_char2( ch, &af );
return;
}
/* Adds + dam to spells for having spellcraft skill */
int sc_dam( CHAR_DATA *ch, int dam )
{
float mod;
if ( ch->level < 50 )
mod = 82.6; /* x1.15 */
else if ( ch->level < 60 )
mod = 73.07; /* x1.3 */
else if ( ch->level < 70 )
mod = 65.51; /* x1.45 */
else if ( ch->level < 80 )
mod = 55.88; /* x1.7 */
else if ( ch->level < 90 )
mod = 51.35; /* x1.85 */
else if ( ch->level < 95 )
mod = 47.5; /* x2 */
else
mod = 38; /* x2.5 */
if ( !IS_NPC( ch ) && ch->pcdata->learned[gsn_spellcraft] > 0 )
{
dam += dam * ch->pcdata->learned[gsn_spellcraft] / mod;
update_skpell( ch, gsn_spellcraft );
}
return dam;
}
void spell_thunder_strike( int sn, int level, CHAR_DATA *ch, void *vo )
{
AFFECT_DATA af;
CHAR_DATA *victim = (CHAR_DATA *) vo;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 150, 155, 160, 165, 170, 175,
185, 190, 195, 200, 205, 207, 209, 211, 213, 215,
222, 224, 226, 228, 230, 232, 234, 236, 238, 240,
247, 249, 251, 253, 255, 257, 259, 261, 263, 265,
272, 274, 276, 278, 280, 282, 284, 286, 288, 290,
297, 299, 301, 303, 305, 307, 309, 311, 313, 315,
322, 324, 326, 328, 330, 332, 334, 336, 338, 340,
347, 349, 351, 353, 355, 357, 359, 361, 363, 365,
375, 380, 385, 390, 395, 400, 405, 410, 415, 420
};
int dam;
level = UMIN( level, sizeof( dam_each ) / sizeof( dam_each[0] ) - 1);
level = UMAX( 0, level );
dam = number_range( dam_each[level], dam_each[level] * 8 );
dam = sc_dam( ch, dam );
if ( IS_AFFECTED( victim, AFF_SHOCKSHIELD) )
dam /= 2;
if ( saves_spell( level, victim ) )
dam /= 2;
damage( ch, victim, dam, sn );
if ( IS_AFFECTED( victim, AFF_BLIND )
&& IS_AFFECTED2( victim, AFF_CONFUSED ) )
{
return;
}
af.type = sn;
af.level = level;
af.duration = level / 50;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_BLIND;
affect_to_char( victim, &af );
act( AT_YELLOW,
"A brilliant flash of lightning strikes $N !",
ch, NULL, victim, TO_CHAR );
send_to_char(AT_YELLOW,
"A flash of lightning makes everything dark!\n\r",
victim );
act(AT_YELLOW,
"A tremendous bolt of lightning has blinded $N !",
ch, NULL, victim, TO_NOTVICT );
af.type = sn;
af.level = level;
af.duration = 2;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_CONFUSED;
affect_to_char2( victim, &af );
STUN_CHAR( ch, 3, STUN_COMMAND );
act(AT_WHITE,
"Booming thunder causes momentary confusion to $N!",
ch,NULL, victim, TO_CHAR );
send_to_char(AT_WHITE,
"Loud thunder wracks your ears and leaves you confused in the midst of battle!\n\r",
victim );
act(AT_WHITE,
"$N looks confused!",
ch, NULL, victim, TO_NOTVICT );
return;
}
/*
* Bard spells -- Thanks Arkhane :>
*/
void spell_inspiration( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf [ MAX_STRING_LENGTH ];
act( AT_YELLOW, "$n sings a song about great battles and brave heros.",
ch, NULL, NULL, TO_ROOM );
for( victim = ch->in_room->people; victim; victim = victim->next_in_room )
{
if ( ( victim->deleted ) || !is_same_group( ch, victim ) )
continue;
if ( IS_NPC( victim ) )
continue;
if( is_affected( victim, sn ) )
{
if( victim == ch )
send_to_char( AT_WHITE, "You have already been inspired.\n\r", victim );
else
act( AT_WHITE, "$N has been inspired already.", ch, NULL, victim,
TO_CHAR );
/* return; (still want to loop through rest of chars so just continue) */
continue;
}
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_HITROLL;
af.modifier = level / 6;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_DAMROLL;
af.modifier = level / 6;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = - level / 2;
affect_to_char( victim, &af );
if ( victim != ch)
{
sprintf( buf, "You become inspired by %s's song.\n\r", ch->name );
send_to_char( AT_CYAN, buf, victim );
sprintf( buf, "%s becomes inspired by your song.\n\r", victim->name );
send_to_char( AT_CYAN, buf, ch );
}
else
send_to_char( AT_CYAN, "You inspire yourself to greater heights.\n\r",
ch );
}
return;
}
void spell_war_cry( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
act( AT_BLOOD,
"$n's cry for the death of $s enemies pierces through the room!",
ch, NULL, NULL, TO_ROOM );
if ( saves_spell( level, victim ) )
{
act( AT_WHITE, "$N ignores your cry for blood.",
ch, NULL, victim, TO_CHAR );
return;
}
af.type = sn;
af.level = level;
af.duration = 3;
af.location = APPLY_HITROLL;
af.modifier = - level / 20;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_DAMROLL;
af.modifier = - level / 20;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char( AT_BLOOD,
"Your cry for war sends fear into your opponent!\n\r",
ch );
send_to_char( AT_BLOOD, "A bloodthirsty cry sends shivers down your spine.\n\r",
victim );
return;
}
void spell_group_healing( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
act( AT_WHITE, "$n sings a soothing song.", ch, NULL, NULL, TO_ROOM );
for( victim = ch->in_room->people; victim; victim = victim->next_in_room )
{
if ( IS_NPC( victim ) || ( victim->deleted ) ||
( !is_same_group( ch, victim ) ) )
continue;
victim->hit = UMIN( victim->hit + 150, MAX_HIT(victim) + 50 );
update_pos( victim );
if( ch != victim )
send_to_char( AT_BLUE, "Ok.\n\r", ch );
}
send_to_char( AT_BLUE, "You have completed your song.\n\r", ch );
return;
}
void spell_chant( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
send_to_char(AT_BLUE, "You begin your loud chant of destruction!\n\r", ch );
act(AT_BLUE, "$n's chant wreaks havoc everywhere!", ch, NULL, NULL, TO_ROOM );
for ( victim = ch->in_room->people; victim; victim = victim->next_in_room )
{
if ( victim->deleted )
continue;
if ( victim != ch && ( IS_NPC( ch ) ? !IS_NPC( victim )
: IS_NPC( victim ) ) )
damage( ch, victim, 1.5 * level + dice( level, 6 ), sn );
}
return;
}
/*Decklarean*/
void spell_blur ( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected( victim, sn ) )
return;
af.type = sn;
af.level = level;
af.duration = 3 + level;
af.location = APPLY_AC;
af.modifier = 0 - level/2;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = 0 - level / 3;
affect_to_char( victim, &af );
send_to_char(AT_GREY, "Your form blurs.\n\r",
victim );
act(AT_GREY, "$N form becomes blurred, shifting and wavering before you.",
ch, NULL, victim, TO_NOTVICT );
return;
}
/*Decklarean*/
void spell_firewall( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE )
|| IS_SET( ch->in_room->room_flags, ROOM_NO_OFFENSIVE ) )
send_to_char( AT_BLUE, "The spell fails to ignite.", ch );
send_to_char(AT_RED, "A wall of fire explodes out in all direction from you!\n\r", ch );
act(AT_RED, "A wall of fire explodes out from $n!", ch, NULL, NULL, TO_ROOM );
for ( vch = ch->in_room->people; vch; vch = vch->next_in_room )
{
if ( vch->deleted )
continue;
if ( vch != ch )
damage( ch, vch, level + dice( level, 20 ), sn );
}
return;
}
void spell_purify( int sn, int level, CHAR_DATA *ch, void *vo )
{
OBJ_DATA *obj;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int yesno = FALSE;
for ( obj = ch->carrying; obj; obj = obj->next_content )
{
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_MAGE ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_MAGE );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_CLERIC ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_CLERIC );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_THIEF ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_THIEF );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_WARRIOR ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_WARRIOR );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_PSI ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_PSI );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_DRUID ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_DRUID );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_RANGER ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_RANGER );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_PALADIN ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_PALADIN );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_BARD ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_BARD );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_VAMP ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_VAMP );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_NECRO ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_NECRO );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_WWF ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_WWF );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_CLASS( obj, ITEM_ANTI_MONK ) )
{
REMOVE_BIT( obj->anti_class_flags, ITEM_ANTI_MONK );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_HUMAN ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_HUMAN );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_ELF ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_ELF );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_DWARF ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_DWARF );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_PIXIE ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_PIXIE );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_HALFLING ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_HALFLING );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_DROW ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_DROW );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_ELDER ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_ELDER );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_OGRE ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_OGRE );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_LIZARDMAN ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_LIZARDMAN );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_DEMON ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_DEMON );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_GHOUL ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_GHOUL );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_ILLITHID ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_ILLITHID );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_MINOTAUR ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_MINOTAUR );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_TROLL ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_TROLL );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_SHADOW ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_SHADOW );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
if ( IS_ANTI_RACE( obj, ITEM_ANTI_TABAXI ) )
{
REMOVE_BIT( obj->anti_race_flags, ITEM_ANTI_TABAXI );
act(AT_WHITE, "$p glows white.", victim, obj, NULL, TO_CHAR );
yesno = TRUE;
}
}
if ( ch != victim && yesno )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
void spell_silence( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_MUTE ) || saves_spell( level, victim ) )
{
send_to_char(AT_BLUE, "You have failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = 2;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_MUTE;
affect_to_char( victim, &af );
act(AT_WHITE, "$N is silenced!", ch, NULL, victim, TO_CHAR );
send_to_char(AT_WHITE, "You are silenced!\n\r", victim );
act(AT_WHITE, "$N is silenced!", ch, NULL, victim, TO_NOTVICT );
return;
}
void spell_image( int sn, int level, CHAR_DATA *ch, void *vo )
{
AFFECT_DATA af;
if ( ch->combat_timer )
{
send_to_char(AT_BLUE, "You can't right now.\n\r",ch);
return;
}
if (is_affected(ch, gsn_image) )
return;
af.location = APPLY_NONE;
af.modifier = 0;
af.duration = ch->level;
af.bitvector = 0;
af.type = sn;
affect_to_char( ch, &af );
send_to_char(AT_CYAN, "You are surrounded by images of yourself.\n\r", ch);
act(AT_CYAN, "$n suddenly splits into many images.",ch,NULL,NULL,TO_ROOM);
return;
}
void spell_hallucinate( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2( victim, AFF_HALLUCINATING ) )
return;
if ( IS_AFFECTED( victim, AFF_BLIND ) || saves_spell( level, victim ))
{
send_to_char(AT_BLUE, "You have failed.\n\r", ch );
return;
}
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 6 );
af.location = APPLY_INT;
af.modifier = -4;
af.bitvector = AFF_HALLUCINATING;
affect_to_char2( victim, &af );
act(AT_WHITE, "&.Thou&.sand&.s &.of &.danci&.ng &.ligh&.ts &.surr&.ound &.you&.!&w", victim, NULL, victim, TO_VICT );
act(AT_GREY, "&W$n's &.body &.is &.surr&.ounded &.by d&.anci&.ng l&.ights.", victim, NULL, NULL, TO_ROOM );
return;
}
void spell_unholystrength( int sn, int level, CHAR_DATA *ch, void *vo )
{
AFFECT_DATA af;
if ( ch->combat_timer )
{
send_to_char(AT_BLUE, "You can't right now.\n\r",ch);
return;
}
if ( ch->fighting || IS_AFFECTED2(ch, AFF_UNHOLYSTRENGTH ) )
{
send_to_char(C_DEFAULT, "You failed.\n\r",ch);
return;
}
af.type = sn;
af.level = ch->level;
af.duration = ch->level/4;
af.location = APPLY_STR;
af.modifier = 4;
af.bitvector = AFF_UNHOLYSTRENGTH;
affect_to_char2(ch, &af);
/* ch->ctimer = 17;*/
send_to_char(AT_DGREEN, "You feel the strength of the Unholy Plague run through you.\n\r",ch);
return;
}
void spell_manabomb( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
EXIT_DATA *pexit;
ROOM_INDEX_DATA *original;
CHAR_DATA *vch_next;
ROOM_INDEX_DATA * room;
int max_distance;
int distance;
int dir;
max_distance = UMAX( 2, ch->level/20 );
room = ch->in_room;
original = ch->in_room;
send_to_char( AT_WHITE,
"You explode in a massive ball of magical energy!\n\r", ch );
for (dir = 0; dir < 6; dir++) /* look in every direction */
{
char_from_room( ch );
char_to_room( ch, original );
room = ch->in_room;
for (distance = 0 ; distance < max_distance; distance++)
{
pexit = room->exit[dir]; /* find the door to the next room */
if ((pexit == NULL) || (pexit->to_room == NULL) ||
(IS_SET(pexit->exit_info, EX_CLOSED)))
break; /* exit not there OR points to nothing OR is closed */
act( AT_WHITE, "$n explodes violently, sending magical flames in all directions!",
ch, NULL, NULL, TO_ROOM );
for( vch = ch->in_room->people; vch; vch = vch_next)
{
vch_next = vch->next_in_room;
if ( vch == NULL )
continue;
if(vch->deleted)
continue;
if (vch == ch )
continue;
if ( !IS_NPC( vch ) )
damage( ch, vch,
number_range ( ch->mana, ch->mana + ch->level ),
sn );
else
damage( ch, vch,
number_range ( ch->mana, ch->mana + ch->level )*4,
sn );
}
room = pexit->to_room;
char_from_room( ch );
char_to_room( ch, room );
} /* for distance */
} /* for dir */
char_from_room( ch );
char_to_room( ch, original );
if ( ch->level < 110 )
raw_kill( ch, ch );
return;
}
void spell_vaccinate( int sn, int level, CHAR_DATA *ch, void *vo )
{
AFFECT_DATA af;
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( is_affected( victim, gsn_plague ) )
affect_strip( victim, gsn_plague );
if ( IS_SET( victim->affected_by2, AFF_VACCINATE ))
return;
send_to_char(AT_GREEN, "Ok.\n\r", ch );
send_to_char(AT_GREEN, "A warm feeling runs through your body.\n\r", victim );
act(AT_GREEN, "$N looks better.", ch, NULL, victim, TO_NOTVICT );
af.type = sn;
af.level = ch->level;
af.duration = ch->level/3;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_VACCINATE;
affect_to_char2(victim, &af);
return;
}