/***************************************************************************
* 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. *
***************************************************************************/
/*$Id: magic.c,v 1.57 2005/04/04 16:02:46 ahsile Exp $*/
#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 ) );
/*
* Local functions.
*/
void set_fighting args( ( CHAR_DATA *ch, CHAR_DATA *victim ) );
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 ) );
/*
* "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->max_hit /= 2;
victim->hit = victim->max_hit;
zombie->max_hit = victim->max_hit;
zombie->hit = victim->hit;
zombie->level = victim->level;
SET_BIT( zombie->act, PLR_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 override )
{
int pct = 0;
int gain = 1;
if (IS_NPC(ch))
return;
if( override == 0 )
{
if( ch->pcdata->learned[sn] == 0 )
{
return;
}
if( ch->pcdata->learned[sn] <= 100 )
{
pct = 100 + ( skill_table[sn].is_spell ? int_app[get_curr_int(ch)].bonus : dex_app[get_curr_dex(ch)].bonus );
gain = number_fuzzy( 10 );
}
else if( ch->pcdata->learned[sn] <= 200 )
{
pct = 95 + ( skill_table[sn].is_spell ? int_app[get_curr_int(ch)].bonus : dex_app[get_curr_dex(ch)].bonus );
gain = number_fuzzy( 9 );
}
else if( ch->pcdata->learned[sn] <= 300 )
{
pct = 90 + ( skill_table[sn].is_spell ? int_app[get_curr_int(ch)].bonus : dex_app[get_curr_dex(ch)].bonus );
gain = number_fuzzy( 8 );
}
else if( ch->pcdata->learned[sn] <= 400 )
{
pct = 85 + ( skill_table[sn].is_spell ? int_app[get_curr_int(ch)].bonus : dex_app[get_curr_dex(ch)].bonus );
gain = number_fuzzy( 7 );
}
else if( ch->pcdata->learned[sn] <= 500 )
{
pct = 75 + ( skill_table[sn].is_spell ? int_app[get_curr_int(ch)].bonus : dex_app[get_curr_dex(ch)].bonus );
gain = number_fuzzy( 6 );
}
else if( ch->pcdata->learned[sn] <= 600 )
{
pct = 65 + ( skill_table[sn].is_spell ? int_app[get_curr_int(ch)].bonus : dex_app[get_curr_dex(ch)].bonus );
gain = number_fuzzy( 4 );
}
else if( ch->pcdata->learned[sn] <= 750 )
{
pct = ( 125 - ( ch->pcdata->learned[sn] / 10 ) )
+ ( skill_table[sn].is_spell ? int_app[get_curr_int(ch)].bonus : dex_app[get_curr_dex(ch)].bonus );
gain = number_fuzzy( 2 );
}
else
{
pct = ( ( 125 - ( ch->pcdata->learned[sn] / 10 ) ) / 2 )
+ ( skill_table[sn].is_spell ? int_app[get_curr_int(ch)].bonus : dex_app[get_curr_dex(ch)].bonus );
gain = 1;
}
if( gain < 1 )
gain = 1;
}
else
{
gain = override;
pct = 101;
}
if ( number_percent() < pct )
{
if ( ch->pcdata->learned[sn] < 1000 )
{
if( ( ch->level < LEVEL_HERO && number_percent( ) <= 50 ) || ch->level >= LEVEL_HERO || override != 0 )
{
char buf[MAX_STRING_LENGTH];
ch->pcdata->learned[sn] += gain;
if( ch->pcdata->learned[sn] > 1000 )
ch->pcdata->learned[sn] = 1000;
sprintf(buf, "Your %s \"%s\" improves to %3.1f%%!\n\r", skill_table[sn].is_spell ? "spell" : "skill" , skill_table[sn].name, ch->pcdata->learned[sn] / 10.0f );
send_to_char(AT_CYAN, buf, ch );
if( ch->pcdata->learned[sn] >= 1000 )
{
sprintf(buf, "Congratulations! Your %s \"%s\" has reached grandmaster level!\n\r", skill_table[sn].is_spell ? "spell" : "skill" , skill_table[sn].name );
send_to_char(AT_CYAN, buf, ch );
}
}
}
}
return;
}
int skill_lookup( const char *name )
{
// char buf[MAX_STRING_LENGTH];
int sn;
if (!str_cmp(name,""))
return -1;
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;
}
/*
sprintf(buf, "Skill Lookup: Can't find skill: \"%s\"", name);
bug(buf,0);
*/
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 utters the words, '%s'.", buf );
sprintf( buf, "$n utters the words, '%s'.", skill_table[sn].name );
for ( rch = ch->in_room->people; rch; rch = rch->next_in_room )
{
if ( rch != ch )
act(AT_BLUE, ch->class==rch->class ? 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 < -440 ? -440 : victim->saving_throw);
if ( !IS_NPC( victim ) )
savebase /= 8;
else
savebase /= 2;
save = base + ( victim->level - level ) + savebase;
save = URANGE( 5, save, 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;
int dmg = 0;
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( 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_DEMIGOD ), 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, "Your spell has 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_pkillable( ch, 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_AFFECTED2( ch, AFF_SHADOW_PLANE) )
{
send_to_char(AT_WHITE, "You must exit the shadow realm.\n\r", ch);
return;
}
if ( IS_AFFECTED2( victim, AFF_SHADOW_PLANE) )
{
send_to_char(AT_WHITE, "You can not attack someone who is in the shadow realm.\n\r", ch);
return;
}
if ( IS_AFFECTED4( ch, AFF_BURROW) )
{
send_to_char(AT_WHITE, "You must wait for the earth to heal you!\n\r", ch);
return;
}
if ( IS_AFFECTED4( victim, AFF_BURROW) )
{
send_to_char(AT_WHITE, "You can not attack someone who is burrowed.\n\r", ch);
return;
}
if (!IS_NPC(victim))
{
if (victim->pkill == TRUE)
ch->pkill_timer = 0;
}
if ( IS_AFFECTED( ch, AFF_PEACE) )
{
affect_strip( ch, skill_lookup("aura of peace") );
REMOVE_BIT( ch->affected_by, AFF_PEACE );
}
vo = (void *) victim;
if (!pk_combat_check(ch, victim))
return;
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;
if (!pk_combat_check(ch, victim))
return;
break;
case TAR_CHAR_SELF:
if ( arg2[0] != '\0' && !is_name( 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;
}
dmg = (*skill_table[sn].spell_fun) ( sn, URANGE( 1, ch->level, LEVEL_DEMIGOD ), ch, vo );
if (dmg > SKPELL_NO_DAMAGE)
damage(ch, victim, dmg, sn);
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;
}
bool pk_combat_check(CHAR_DATA *ch, CHAR_DATA *victim)
{
CHAR_DATA * rch;
bool found = FALSE;
if (!victim->fighting || IS_NPC( victim ) || IS_NPC( ch ) )
return TRUE;
if (IS_SET(ch->in_room->room_flags, ROOM_PKILL ) &&
IS_SET(victim->in_room->room_flags, ROOM_PKILL ))
{
ch->pkill_timer = 0;
victim->pkill_timer = 0;
return TRUE;
}
for( rch= ch->in_room->people; rch; rch= rch->next_in_room )
{
if (rch->deleted || !rch->fighting || rch == victim
|| rch == ch || IS_NPC(rch) )
continue;
/* ok, a player in the room is fighting the victim, should we
allow the spell? allow the spell and set their pk timer?
or not allow the spell? */
if (rch->fighting == victim && rch != ch )
{
/*peacefuls shouldn't get involved*/
if (ch->pkill == 0)
{
send_to_char(AT_WHITE, "You can't get involved in pkill battles!\r\n", ch);
return FALSE;
}
else if ( abs( ch->level - rch->level ) > PKILL_RANGE ||
abs( ch->level - victim->level ) > PKILL_RANGE )
{
send_to_char(AT_RED, "You can't get involved in this pk battle\r\nValid Range is +/- 8 levels.\r\n", ch);
return FALSE;
}
else if (abs( ch->level - rch->level ) <= PKILL_RANGE ||
abs( ch->level - victim->level) <= PKILL_RANGE )
{
/*This target is in range, so, set the found flag,
there may still be other out of range ppl in the fight. */
found = TRUE;
}
}
}
/*if we get to here, then it's ok to cast the spell, if we found a pk
fight along the way, reset the caster's pk timer */
if (found)
ch->pkill_timer = 0;
return TRUE;
}
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 = 0;
int spec;
int intreq = 0;
int intreq1 = 0;
int intreq2 = 0;
spec = skill_lookup( "astral walk" );
target_name = one_argument( argument, arg1 );
one_argument( target_name, arg2 );
if ( arg1[0] == '\0' )
{
send_to_char(AT_BLUE, "Cast which what where?\n\r", ch );
return;
}
if ( !IS_NPC( ch ) )
if ( IS_AFFECTED4( ch, AFF_BURROW ) )
{
send_to_char(AT_RED, "You cannot cast while burrowed!\n\r", ch);
return;
}
if ( IS_NPC( ch ) )
if ( IS_SET( ch->affected_by, AFF_CHARM ) )
return;
if (IS_NPC( ch ) )
if (ch->mana == 0)
return;
if ( !IS_NPC( ch ) )
if ( ( sn = skill_lookup( arg1 ) ) < 0
|| ( ch->level < skill_table[sn].skill_level[ch->class]
&& ch->level < skill_table[sn].skill_level[ch->multied] ) )
{
send_to_char(AT_BLUE, "You can't do that.\n\r", ch );
return;
}
if (!skill_table[sn].is_spell)
{
send_to_char(AT_WHITE, "Casting a skill? Try using it...\n\r", ch);
return;
}
if ( !IS_NPC( ch ) )
if ( ch->class == CLASS_BARBARIAN || ch->multied == CLASS_BARBARIAN )
{
if ( skill_table[sn].skill_level[ch->class] > 60
&& skill_table[sn].skill_level[ch->multied] > 60 )
{
send_to_char(C_DEFAULT, "Barbarians can not cast magic of such high level.\n\r", ch );
return;
}
}
if ( !IS_NPC( ch ) )
if ( ( ch->race == 10 && IS_EVIL( ch ) ) ||
( ch->race == 10 && IS_NEUTRAL( ch ) ) ||
( ch->race == 15 && IS_GOOD( ch ) ) ||
( ch->race == 15 && IS_NEUTRAL( ch ) ) ||
( ch->class == CLASS_CLERIC && IS_EVIL( ch ) ) ||
( ch->multied == CLASS_CLERIC && IS_EVIL( ch ) ) ||
( ch->class == CLASS_PALADIN && IS_EVIL( ch ) ) ||
( ch->multied == CLASS_PALADIN && IS_EVIL( ch ) ) ||
( ch->class == CLASS_ANTI_PALADIN && IS_GOOD( ch ) ) ||
( ch->multied == CLASS_ANTI_PALADIN && IS_GOOD( ch ) ) ||
( ch->class == CLASS_DARKPRIEST && IS_GOOD( ch ) ) ||
( ch->multied == CLASS_DARKPRIEST && IS_GOOD( ch ) ) )
{
send_to_char(AT_BLUE, "You can not cast when you are that alignment.\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 IS_AFFECTED2( ch, AFF_SLIT)
{
send_to_char(AT_BLOOD, "Your throat is slit, you can not cast.\n\r", ch );
return;
}
if ( IS_STUNNED( ch, STUN_MAGIC ) )
{
send_to_char(AT_LBLUE, "You're too stunned to cast spells.\n\r", ch );
return;
}
mana = 0;
if(!IS_NPC( ch ) && ch->level >= skill_table[sn].skill_level[ch->multied] )
{
mana = MANA_COST_MULTI(ch, sn );
intreq1 = ( skill_table[sn].skill_level[ch->multied] / 2 ) - 5;
if( intreq1 >= 40 )
{
intreq1 = 40;
}
}
if(!IS_NPC( ch ) && ch->level >= skill_table[sn].skill_level[ch->class] )
{
mana = MANA_COST( ch, sn );
intreq2 = ( skill_table[sn].skill_level[ch->class] / 2) - 5;
if( intreq2 >= 40 )
{
intreq2 = 40;
}
}
intreq = UMIN(intreq1, intreq2);
if ( ch->class == CLASS_VAMPIRE || ch->class == CLASS_ANTI_PALADIN )
{
mana /= 4;
}
if(ch->class != CLASS_CLERIC && ch->class != CLASS_DARKPRIEST )
{
if( get_curr_int( ch ) < intreq )
{
send_to_char(AT_BLUE, "You do not have the required intelligence.\n\r", ch );
return;
}
}
if(ch->class == CLASS_CLERIC || ch->class == CLASS_DARKPRIEST )
{
if( get_curr_wis (ch ) < intreq )
{
send_to_char(AT_BLUE, "You do not have the required wisdom.\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_DEMIGOD ), 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_pkillable(ch, victim ) ) {
return;
}
if (!IS_NPC(victim))
ch->pkill_timer = 0;
if ( IS_AFFECTED(victim, AFF_PEACE) )
{
send_to_char(AT_WHITE, "A wave of peace overcomes you.\n\r", ch);
return;
}
if ( IS_AFFECTED2( ch, AFF_SHADOW_PLANE) )
{
send_to_char(AT_WHITE, "You must exit the shadow realm.\n\r", ch);
return;
}
if ( IS_AFFECTED2( victim, AFF_SHADOW_PLANE) )
{
send_to_char(AT_WHITE, "You can not attack someone who is in the shadow realm.\n\r", ch);
return;
}
if ( IS_AFFECTED4( ch, AFF_BURROW) )
{
send_to_char(AT_WHITE, "You must wait for the earth to heal you!\n\r", ch);
return;
}
if ( IS_AFFECTED4( victim, AFF_BURROW) )
{
send_to_char(AT_WHITE, "You can not attack someone who is burrowed.\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;
}
if (!pk_combat_check(ch, victim))
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;
if (!pk_combat_check(ch, victim))
return;
break;
case TAR_CHAR_SELF:
if ( arg2[0] != '\0' && !is_name( 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_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 ( ( ch->class != 9 ) && ( ch->class != 11) && ( ch->mana < mana ) )
{
send_to_char(AT_BLUE, "You don't have enough mana.\n\r", ch );
return;
}
else
if ( ( ch->bp < mana ) && (( ch->class == 9 )||( ch->class == 11)) )
{
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;
}
if ( !IS_NPC( ch ) )
{
if ( number_percent( ) > ( ch->pcdata->learned[sn] / 10 ) )
{
send_to_char(AT_BLUE, "You lost your concentration.\n\r", ch );
if (( ch->class != 9 )&&( ch->class != 11))
ch->mana -= mana / 2;
else
ch->bp -= mana / 2;
if( ch->pcdata->learned[sn] <= 750 )
update_skpell( ch, sn, 0 );
if( !ch->fighting )
{
if( ch->class == CLASS_CLERIC || ch->class == CLASS_DARKPRIEST )
{
WAIT_STATE( ch, skill_table[sn].beats / ( get_curr_wis( ch ) / 10 ) );
}
else
{
WAIT_STATE( ch, skill_table[sn].beats / ( get_curr_int( ch ) / 10 ) );
}
}
else
{
WAIT_STATE( ch, skill_table[sn].beats );
}
}
else
{
int dam = 0;
WAIT_STATE( ch, skill_table[sn].beats );
if (( ch->class != 9 )&&(ch->class != 11))
ch->mana -= mana;
else
ch->bp -= 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;
}
if (ch->pcdata->learned[skill_lookup("psionic casting")])
update_skpell(ch, skill_lookup("psionic casting"), 0);
dam = (*skill_table[sn].spell_fun) ( sn,
URANGE( 1, ch->level, LEVEL_DEMIGOD ),
ch, vo );
if (dam > SKPELL_NO_DAMAGE )
{
damage( ch, victim, dam, sn );
}
else if ( dam == SKPELL_MISSED || dam == SKPELL_BOTCHED )
{
// something
}
if (dam >= SKPELL_NO_DAMAGE)
update_skpell( ch, sn, 0 );
}
}
if ( IS_NPC( ch ) )
{
int dam = 0;
if ((dam = (*skill_table[sn].spell_fun) ( sn, URANGE( 1, ch->level, LEVEL_DEMIGOD ), ch, vo )) > SKPELL_NO_DAMAGE)
{
damage(ch, victim, dam, sn );
}
}
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;
}
void do_quickburst( 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= -1;
int spec;
int intreq = 0;
int intreq1 = 0;
int intreq2 = 0;
spec = skill_lookup( "astral walk" );
target_name = one_argument( argument, arg1 );
one_argument( target_name, arg2 );
if ( ( !IS_NPC( ch )
&& ((ch->level < skill_table[skill_lookup("quickburst")].skill_level[ch->class] )
&& (ch->level < skill_table[skill_lookup("quickburst")].skill_level[ch->multied]))))
{
send_to_char(C_DEFAULT,
"You'd better leave the spellcasting to the spellcasters.\n\r", ch );
return;
}
if ( IS_NPC( ch ) )
if ( IS_SET( ch->affected_by, AFF_CHARM ) )
return;
if ( arg1[0] == '\0' )
{
send_to_char(AT_BLUE, "Cast which what where?\n\r", ch );
return;
}
if ( !ch->fighting )
{
send_to_char(C_DEFAULT, "You aren't fighting anyone.\n\r", ch );
return;
}
if (!IS_NPC(ch) && (ch->pcdata->learned[skill_lookup("quickburst")] == 0))
{
send_to_char(C_DEFAULT, "You can't do that.\n\r", ch );
return;
}
else
{
if ( !IS_NPC( ch ) )
if ( ( sn = skill_lookup( arg1 ) ) < 0
|| ((ch->level < skill_table[sn].skill_level[ch->class]) &&
(ch->level < skill_table[sn].skill_level[ch->multied]) ))
{
send_to_char(AT_BLUE, "You can't do that.\n\r", ch );
return;
}
if (!skill_table[sn].is_spell)
{
send_to_char(AT_WHITE, "Casting a skill? Try using it...\n\r", ch);
return;
}
if ( !IS_NPC( ch ) )
if ( ch->class == CLASS_BARBARIAN || ch->multied == CLASS_BARBARIAN )
{
if ( skill_table[sn].skill_level[ch->class] > 60
&& skill_table[sn].skill_level[ch->multied] > 60 )
{
send_to_char(C_DEFAULT, "Barbarians can not cast magic of such high level.\n\r", ch );
return;
}
}
if ( !IS_NPC( ch ) )
if ( ( ch->race == 10 && IS_EVIL( ch ) ) ||
( ch->race == 10 && IS_NEUTRAL( ch ) ) ||
( ch->race == 15 && IS_GOOD( ch ) ) ||
( ch->race == 15 && IS_NEUTRAL( ch ) ) ||
( ch->class == CLASS_CLERIC && IS_EVIL( ch ) ) ||
( ch->multied == CLASS_CLERIC && IS_EVIL( ch ) ) ||
( ch->class == CLASS_PALADIN && IS_EVIL( ch ) ) ||
( ch->multied == CLASS_PALADIN && IS_EVIL( ch ) ) ||
( ch->class == CLASS_ANTI_PALADIN && IS_GOOD( ch ) ) ||
( ch->multied == CLASS_ANTI_PALADIN && IS_GOOD( ch ) ) ||
( ch->class == CLASS_DARKPRIEST && IS_GOOD( ch ) ) ||
( ch->multied == CLASS_DARKPRIEST && IS_GOOD( ch ) ) )
{
send_to_char(AT_BLUE, "You can not cast when you are that alignment.\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 IS_AFFECTED2( ch, AFF_SLIT)
{
send_to_char(AT_BLOOD, "Your throat is slit, you can not cast.\n\r", ch );
return;
}
if ( IS_STUNNED( ch, STUN_MAGIC ) )
{
send_to_char(AT_LBLUE, "You're too stunned to cast spells.\n\r", ch );
return;
}
victim = ch->fighting;
mana = 0;
if ( !IS_NPC( ch ) && ch->level >= skill_table[sn].skill_level[ch->multied] )
{
mana = MANA_COST_MULTI( ch, sn );
intreq1 = ( skill_table[sn].skill_level[ch->multied] / 2 ) - 5;
if( intreq1 >= 40 )
{
intreq1 = 40;
}
}
if ( !IS_NPC( ch ) && ch->level >= skill_table[sn].skill_level[ch->class] )
{
mana = MANA_COST( ch, sn );
intreq2 = ( skill_table[sn].skill_level[ch->class] / 2 ) - 5;
if( intreq2 >= 40 )
{
intreq2 = 40;
}
}
intreq = UMIN( intreq1, intreq2 );
if ( ch->class == CLASS_VAMPIRE || ch->class == CLASS_ANTI_PALADIN )
{
mana /= 4;
}
if(ch->class != CLASS_CLERIC && ch->class != CLASS_DARKPRIEST )
{
if( get_curr_int( ch ) < intreq )
{
send_to_char(AT_BLUE, "You do not have the required intelligence.\n\r", ch );
return;
}
}
if(ch->class == CLASS_CLERIC || ch->class == CLASS_DARKPRIEST)
{
if( get_curr_wis( ch ) < intreq )
{
send_to_char(AT_BLUE, "You do not have the required wisdom.\n\r", ch );
return;
}
}
update_skpell( ch, skill_lookup("quickburst"), 0 );
/*
* 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_DEMIGOD ), 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_AFFECTED2( ch, AFF_SHADOW_PLANE) )
{
send_to_char(AT_WHITE, "You must exit the shadow realm.\n\r", ch);
return;
}
if ( IS_AFFECTED2( victim, AFF_SHADOW_PLANE) )
{
send_to_char(AT_WHITE, "You can not attack someone who is in the shadow realm.\n\r", ch);
return;
}
if ( IS_AFFECTED4( ch, AFF_BURROW) )
{
send_to_char(AT_WHITE, "You must wait for the earth to heal you!\n\r", ch);
return;
}
if ( IS_AFFECTED4( victim, AFF_BURROW) )
{
send_to_char(AT_WHITE, "You can not attack someone who is burrowed.\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;
if (!pk_combat_check(ch, victim))
return;
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;
if (!pk_combat_check(ch, victim))
return;
break;
case TAR_CHAR_SELF:
if ( arg2[0] != '\0' && !is_name( 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_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 ( ( ch->class != 9 ) && ( ch->class != 11) && ( ch->mana < mana ) )
{
send_to_char(AT_BLUE, "You don't have enough mana.\n\r", ch );
return;
}
else
if ( ( ch->bp < mana ) && (( ch->class == 9 )||( ch->class == 11)) )
{
send_to_char(AT_RED, "You are to starved to cast, you must feed.\n\r", ch );
return;
}
}
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 / 2);
if ( !IS_NPC( ch ) )
{
if ( number_percent( ) > ( ch->pcdata->learned[sn] / 10 ) || ( number_percent( ) > ch->pcdata->learned[skill_lookup("quickburst")] / 10 ) )
{
send_to_char(AT_BLUE, "You lost your concentration.\n\r", ch );
if (( ch->class != 9 )&&( ch->class != 11))
ch->mana -= mana / 2;
else
ch->bp -= mana / 2;
if( ch->pcdata->learned[sn] <= 750 )
update_skpell( ch, sn, 0 );
}
else
{
int dmg = 0;
if (( ch->class != 9 )&&(ch->class != 11))
ch->mana -= mana;
else
ch->bp -= 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;
}
if (ch->pcdata->learned[skill_lookup("psionic casting")])
update_skpell(ch, skill_lookup("psionic casting"), 0);
say_spell( ch, sn );
dmg = (*skill_table[sn].spell_fun) ( sn,
URANGE( 1, ch->level, LEVEL_DEMIGOD ),
ch, vo );
if ( dmg > SKPELL_NO_DAMAGE )
{
/*
Insert level adjustment code here
*/
damage(ch, victim, dmg, sn);
} else if ( dmg == SKPELL_BOTCHED || dmg == SKPELL_MISSED )
{
/* do something for failed skills, maybe*/
}
if (dmg >= SKPELL_NO_DAMAGE)
update_skpell( ch, sn, 0 );
}
}
if ( IS_NPC( ch ) )
{
int dmg = 0;
if ( (dmg = (*skill_table[sn].spell_fun) ( sn, URANGE( 1, ch->level, LEVEL_DEMIGOD ), ch, vo )) > SKPELL_NO_DAMAGE )
damage( ch, victim, dmg, sn);
}
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;
int dam = 0;
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_DEMIGOD ), 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 && victim->deleted)
return;
/*
if ( !victim || ( !IS_NPC( victim ) && ch != victim ) )
{
send_to_char(AT_BLUE, "You can't do that.\n\r", ch );
return;
}
*/
if (!victim)
{
send_to_char(AT_BLUE, "You cannot find a target.\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_AFFECTED2( ch, AFF_SHADOW_PLANE) )
{
send_to_char(AT_WHITE, "You must exit the shadow realm.\n\r", ch);
return;
}
if ( IS_AFFECTED2( victim, AFF_SHADOW_PLANE) )
{
send_to_char(AT_WHITE, "You can not attack someone who is in the shadow realm.\n\r", ch);
return;
}
if ( IS_AFFECTED4( ch, AFF_BURROW) )
{
send_to_char(AT_WHITE, "You must wait for the earth to heal you!\n\r", ch);
return;
}
if ( IS_AFFECTED4( victim, AFF_BURROW) )
{
send_to_char(AT_WHITE, "You can not attack someone who is burrowed.\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_pkillable( ch, victim ) ) {
return;
}
vo = (void *) victim;
if (!pk_combat_check(ch, victim))
return;
break;
case TAR_CHAR_DEFENSIVE:
if ( !victim )
victim = ch;
if (!pk_combat_check(ch, victim))
return;
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 = "";*/
dam = (*skill_table[sn].spell_fun) ( sn, level, ch, vo );
if (dam > SKPELL_NO_DAMAGE)
{
damage( ch, victim, dam, sn);
} else if( dam == SKPELL_BOTCHED || dam == SKPELL_MISSED)
{
// something
}
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;
}
/* Control spells. All the extra checks are JUST IN CASE... heh */
void do_control_switch( CHAR_DATA *ch, char *argument )
{
CHAR_DATA *victim;
char arg [ MAX_INPUT_LENGTH ];
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
send_to_char(AT_WHITE, "Switch into whom?\n\r", ch );
return;
}
if ( !ch->desc )
return;
if ( ch->desc->original )
{
send_to_char(AT_WHITE, "You are already switched.\n\r", ch );
return;
}
if ( !( victim = get_char_world( ch, arg ) ) )
{
send_to_char(AT_WHITE, "They aren't here.\n\r", ch );
return;
}
if ( victim == ch )
{
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return;
}
if ( !IS_NPC( victim ) )
{
send_to_char(AT_WHITE, "You cannot switch into a player!\n\r", ch );
return;
}
if ( victim->desc )
{
send_to_char(AT_WHITE, "Character in use.\n\r", ch );
return;
}
ch->pcdata->switched = TRUE;
ch->desc->character = victim;
ch->desc->original = ch;
victim->desc = ch->desc;
victim->prompt = ch->prompt;
victim->deaf = ch->deaf;
ch->desc = NULL;
send_to_char(AT_BLUE, "Ok.\n\r", victim );
return;
}
/*
* Spell functions.
*/
int spell_acid_blast( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice( level, 8 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int 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 SKPELL_BOTCHED;
}
obj_next = obj->next;
if (obj->deleted)
return SKPELL_MISSED;
magic_mob( ch, obj, obj->ac_vnum );
extract_obj(obj);
return SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = level / 2;
af.location = APPLY_AC;
af.modifier = -50;
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 SKPELL_NO_DAMAGE;
}
int 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_AFFECTED( victim, AFF_NOASTRAL )
|| IS_AFFECTED4( victim, AFF_DECEPTION) )
{
send_to_char(AT_BLUE, "You failed.\n\r", ch );
return SKPELL_MISSED;
}
if ( IS_SET(ch->in_room->area->area_flags, AREA_PRESENT)
&& (IS_SET( victim->in_room->area->area_flags, AREA_FUTURE )
|| IS_SET( victim->in_room->area->area_flags, AREA_PAST ) ) )
{
send_to_char(AT_BLUE, "You can't astral walk through time.\n\r", ch );
return SKPELL_MISSED;
}
if ( IS_SET(ch->in_room->area->area_flags, AREA_FUTURE)
&& (IS_SET( victim->in_room->area->area_flags, AREA_PRESENT )
|| IS_SET( victim->in_room->area->area_flags, AREA_PAST ) ) )
{
send_to_char(AT_BLUE, "You can't astral walk through time.\n\r", ch );
return SKPELL_MISSED;
}
if ( IS_SET(ch->in_room->area->area_flags, AREA_PAST)
&& (IS_SET( victim->in_room->area->area_flags, AREA_FUTURE )
|| IS_SET( victim->in_room->area->area_flags, AREA_PRESENT ) ) )
{
send_to_char(AT_BLUE, "You can't astral walk through time.\n\r", ch );
return SKPELL_MISSED;
}
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level / 5 );
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 SKPELL_NO_DAMAGE;
}
int spell_shadow_plane( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED2( victim, AFF_SHADOW_PLANE) )
return SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = number_fuzzy( level );
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_SHADOW_PLANE;
affect_to_char2( victim, &af );
send_to_char(AT_BLUE, "You phase out of reality and into the shadow realm.\n\r", victim );
act(AT_BLUE, "$n's phases out of reality and enters the shadow plane.", victim, NULL, NULL, TO_ROOM );
return SKPELL_NO_DAMAGE;
}
int 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 SKPELL_BOTCHED;
af.type = sn;
af.level = level;
af.duration = level / 2;
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 );
if ( ch != victim )
send_to_char(AT_BLUE, "Ok.\n\r", ch );
send_to_char(AT_BLUE, "You feel righteous.\n\r", victim );
return SKPELL_NO_DAMAGE;
}
int 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 SKPELL_BOTCHED;
af.type = sn;
af.level = level;
af.duration = 40 + level;
af.location = APPLY_DAMROLL;
af.modifier = level / 5;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = APPLY_HITROLL;
af.modifier = level / 5;
affect_to_char( victim, &af );
af.location = APPLY_HIT;
af.modifier = level * 8;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_BOTCHED;
af.type = sn;
af.level = level;
af.duration = 40 + level;
af.location = APPLY_HIT;
af.modifier = number_fuzzy ( level * 10 );
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 SKPELL_NO_DAMAGE;
}
int spell_blindness( 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 )
|| IS_AFFECTED2( victim, AFF_BLINDFOLD ) )
{
send_to_char(AT_BLUE, "You have failed.\n\r", ch );
return SKPELL_BOTCHED;
}
af.type = sn;
af.level = level;
af.duration = level / 20;
af.location = APPLY_HITROLL;
af.modifier = -50;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
}
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 + 500, victim->max_hit );
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 SKPELL_NO_DAMAGE;
}
int 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 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int spell_call_lightning( int sn, int level, CHAR_DATA *ch, void *vo )
{
//CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
static const int dam_each [ ] =
{
0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 36, 42, 48, 54, 60, 66,
72, 78, 84, 90, 96, 102, 104, 106, 107, 108,
110, 113, 115, 117, 120, 122, 124, 127, 129, 132,
134, 137, 139, 142, 144, 147, 149, 152, 154, 157,
159, 162, 164, 167, 169, 172, 174, 177, 179, 182,
184, 187, 189, 192, 194, 196, 198, 200, 202, 204,
206, 208, 210, 212, 214, 216, 218, 220, 222, 224,
226, 228, 230, 231, 232, 233, 234, 235, 236, 237,
238, 239, 240, 242, 244, 246, 248, 250, 255, 260
};
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 );
if ( !IS_OUTSIDE( ch ) )
{
send_to_char(AT_WHITE, "You must be out of doors.\n\r", ch );
return SKPELL_BOTCHED;
}
if ( weather_info.sky < SKY_RAINING )
{
send_to_char(AT_WHITE, "You need bad weather for this spell to be effective.\n\r", ch );
dam /= 2;
}
if ( weather_info.sky > SKY_RAINING )
{
send_to_char(AT_WHITE, "The Lightning in the air increases the spells power!\n\r", ch );
dam *= 2;
}
send_to_char(AT_WHITE, "Lightning slashes out of the sky to strike your foe!\n\r", ch );
act(AT_WHITE, "$n calls lightning from the sky to strike $s foe!",
ch, NULL, NULL, TO_ROOM );
//damage( ch, victim, dam, sn );
return dam;
}
int spell_cause_light( int sn, int level, CHAR_DATA *ch, void *vo )
{
//damage( ch, (CHAR_DATA *) vo, dice( 5, 10 ) + level / 3, sn );
return (dice(5,10)+level/3);
}
int spell_cause_critical( int sn, int level, CHAR_DATA *ch, void *vo )
{
//damage( ch, (CHAR_DATA *) vo, dice( 20, 10 ) + level, sn );
return (dice(20,10) + level);
}
int spell_cause_serious( int sn, int level, CHAR_DATA *ch, void *vo )
{
//damage( ch, (CHAR_DATA *) vo, dice( 10, 10 ) + level, sn );
return (dice(10,10)+level);
}
int 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 = 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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
}
if ( !IS_NPC( victim ) )
return SKPELL_BOTCHED;
if ( IS_AFFECTED( victim, AFF_CHARM )
|| IS_AFFECTED( ch, AFF_CHARM )
|| level < victim->level
|| ( saves_spell(level + IS_SRES(victim, RES_CHARM) ? -5 : 0, victim)
&& !(get_trust( ch ) > 100) ) )
return SKPELL_MISSED;
if(IS_SIMM(victim, IMM_CHARM))
return SKPELL_MISSED;
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 );
send_to_char(AT_BLUE, "Ok.\n\r", ch );
act(AT_BLUE, "Isn't $n just so nice?", ch, NULL, victim, TO_VICT );
return SKPELL_NO_DAMAGE;
}
int 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 );
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 dam;
}
int 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] * 4 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int 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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_BOTCHED;
}
if ( obj->value[2] != LIQ_WATER && obj->value[1] != 0 )
{
send_to_char(AT_BLUE, "It contains some other liquid.\n\r", ch );
return SKPELL_BOTCHED;
}
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( "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 SKPELL_NO_DAMAGE;
}
int spell_cure_blindness( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( !is_affected( victim, skill_lookup("blindness") ) )
return SKPELL_MISSED;
affect_strip( victim, skill_lookup("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 SKPELL_NO_DAMAGE;
}
int spell_cure_critical( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = (int)(victim->max_hit * 0.08);
victim->hit = UMIN( victim->hit + heal, victim->max_hit );
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 SKPELL_NO_DAMAGE;
}
int spell_cure_light( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = (int)(victim->max_hit * 0.02);
heal = UMIN(heal, 400);
victim->hit = UMIN( victim->hit + heal, victim->max_hit );
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 SKPELL_NO_DAMAGE;
}
int spell_cure_poison( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if ( !is_affected( victim, skill_lookup("poison") ) )
return SKPELL_MISSED;
victim->poison_level -= number_fuzzy(ch->level/10);
if( victim->poison_level <= 0 )
{
victim->poison_level = 0;
affect_strip( victim, skill_lookup("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 SKPELL_NO_DAMAGE;
}
int spell_create_illusion( int sn, int level, CHAR_DATA *ch, void *vo )
{
char speaker[ MAX_INPUT_LENGTH ];
CHAR_DATA *victim = NULL;
char buf[ MAX_STRING_LENGTH ];
target_name = one_argument( target_name, speaker );
victim = get_char_world( ch, target_name );
if ((victim = get_char_world(ch, speaker)))
{
send_to_char( AT_GREY, target_name, victim );
send_to_char( AT_GREY, "\n\r", victim );
sprintf( buf, "Create Illusion (%s): %s: Sent to %s", ch->name, target_name, victim->name );
log_string( buf, CHANNEL_LOG, -1 );
}
else
{
send_to_char(AT_GREY, "You do not find them.\n\r", ch);
}
return SKPELL_NO_DAMAGE;
}
int spell_cure_serious( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = (int)(victim->max_hit * 0.05);
victim->hit = UMIN( victim->hit + heal, victim->max_hit );
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 SKPELL_NO_DAMAGE;
}
int spell_curse( 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, "A curse has already been inflicted.\n\r", ch );
return SKPELL_MISSED;
}
if (saves_spell( level, victim )) {
send_to_char(AT_RED, "You have failed.\n\r", ch);
return SKPELL_BOTCHED;
}
af.type = sn;
af.level = level;
af.duration = level / 5;
af.location = APPLY_HITROLL;
af.modifier = -50;
af.bitvector = AFF_CURSE;
affect_to_char( victim, &af );
af.location = APPLY_SAVING_SPELL;
af.modifier = 100;
affect_to_char( victim, &af );
if ( ch != victim )
send_to_char(AT_RED, "You have inflicted a curse.\n\r", ch );
send_to_char(AT_RED, "You feel unclean.\n\r", victim );
act(AT_RED, "$n has cursed $N!", ch, NULL, victim, TO_ROOM);
return SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = level / 6;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
}
if ( IS_GOOD( victim ) )
{
act(AT_BLUE, "God protects $N.", ch, NULL, victim, TO_ROOM );
return SKPELL_MISSED;
}
if ( IS_NEUTRAL( victim ) )
{
act(AT_BLUE, "$N does not seem to be affected.", ch, NULL, victim, TO_CHAR );
return SKPELL_MISSED;
}
dam = dice( level, 4 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int 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 );
if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE))
{
send_to_char(AT_WHITE, "You are in a safe room!!!!", ch);
return SKPELL_MISSED;
}
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 SKPELL_NO_DAMAGE;
}
int 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 );
if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE))
{
send_to_char(AT_WHITE, "You are in a safe room!!!!", ch);
return SKPELL_MISSED;
}
for ( vch = char_list; vch; vch = vch->next )
{
if ( vch->deleted || !vch->in_room )
continue;
if ( vch->in_room == ch->in_room && vch != ch )
{
damage( ch, vch, level + dice( level, level/4 ), 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 SKPELL_NO_DAMAGE;
}
int 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 )
: 1 ) )
if (vch != ch )
damage( ch, vch, level + dice( level, 6 ), sn );
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 SKPELL_NO_DAMAGE;
}
int spell_meteor_swarm( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *vch;
AFFECT_DATA af;
if ( IS_SET( ch->in_room->room_flags, ROOM_SAFE))
{
send_to_char(AT_WHITE, "You are in a safe room!!!!\n\r", ch);
return SKPELL_MISSED;
}
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 && vch != ch && vch->position != POS_GHOST )
{
damage( ch, vch, level + dice( level/2, level/2 ), sn );
if ( vch != ch && !is_affected(vch, sn) && !IS_AFFECTED4(vch,AFF_BURROW))
{
af.type = sn;
af.level = level;
af.duration = level / 20;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_FLAMING;
affect_join( vch, &af );
send_to_char(AT_RED, "Your body bursts into flames!\n\r", vch);
}
continue;
}
}
return SKPELL_NO_DAMAGE;
}
int 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 )
{
send_to_char(AT_BLUE, "That item cannot be enchanted.\n\r", ch );
return SKPELL_MISSED;
}
paf = new_affect();
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;
paf = new_affect();
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 SKPELL_NO_DAMAGE;
}
int 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 )
{
send_to_char(AT_RED, "That item cannot be enchanted.\n\r", ch );
return SKPELL_BOTCHED;
}
SET_BIT( obj->extra_flags, ITEM_MAGIC);
SET_BIT( obj->extra_flags, ITEM_FLAME );
send_to_char(AT_RED, "Ok.\n\r", ch );
return SKPELL_NO_DAMAGE;
}
/*
void spell_acid_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_ACID )
|| obj->affected )
{
send_to_char(AT_GREEN, "That item cannot be enchanted.\n\r", ch );
return;
}
SET_BIT( obj->extra_flags, ITEM_MAGIC);
SET_BIT( obj->extra_flags, ITEM_ACID );
send_to_char(AT_GREEN, "You bestow the enchantment of acid blade.\n\r", ch );
return;
}
*/
int spell_dispel_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_STAT2( obj, ITEM_DISPEL )
|| obj->affected )
{
send_to_char(AT_RED, "That item cannot be enchanted.\n\r", ch );
return SKPELL_BOTCHED;
}
SET_BIT( obj->extra_flags, ITEM_MAGIC);
SET_BIT( obj->extra_flags2, ITEM_DISPEL );
send_to_char(AT_RED, "Ok.\n\r", ch );
return SKPELL_NO_DAMAGE;
}
int 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 )
{
send_to_char(AT_YELLOW, "That item cannot be enchanted.\n\r", ch );
return SKPELL_BOTCHED;
}
SET_BIT( obj->extra_flags, ITEM_MAGIC);
SET_BIT( obj->extra_flags, ITEM_CHAOS );
send_to_char(AT_YELLOW, "Ok.\n\r", ch );
return SKPELL_NO_DAMAGE;
}
int 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 )
{
send_to_char(AT_LBLUE, "That item cannot be enchanted.\n\r", ch );
return SKPELL_BOTCHED;
}
SET_BIT( obj->extra_flags, ITEM_MAGIC);
SET_BIT( obj->extra_flags, ITEM_ICY );
send_to_char(AT_LBLUE, "Ok.\n\r", ch );
return SKPELL_NO_DAMAGE;
}
int 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 )
{
send_to_char(AT_BLUE, "That item cannot be consecrated.\n\r", ch );
return SKPELL_BOTCHED;
}
paf = new_affect();
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_HITROLL;
paf->modifier = 16 + (level >= 18) + (level >= 25) + (level >= 40) + (level >= 60) +(level >= 90);
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
paf = new_affect();
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_DAMROLL;
paf->modifier = 16 + (level >= 18) + (level >= 25) + (level >= 45) + (level >= 65) +(level >= 90);;
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
paf = new_affect();
paf->type = sn;
paf->duration = -1;
paf->location = APPLY_HIT;
paf->modifier = 90 + ( (level >=18) * 10) + ( (level >=25) * 10) + ( (level >= 45) * 10) + ( (level >= 65) * 10) + ( ( level >= 90) * 10);
paf->bitvector = 0;
paf->next = obj->affected;
obj->affected = paf;
obj->ac_type = 5;
obj->ac_spell = skill_table[skill_lookup("holy enchantment")].name;
obj->ac_charge[0] = 1;
obj->ac_charge[1] = 1;
if ( IS_GOOD( ch ) )
{
SET_BIT( obj->extra_flags, ITEM_ANTI_EVIL);
act(AT_YELLOW, "$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_WHITE, "$p glows.", ch, obj, NULL, TO_CHAR );
}
if( ch->multied == CLASS_MAGE || ch->class == CLASS_MAGE ) { SET_BIT( obj->extra_flags3, ITEM_PRO_MAGE ); }
if( ch->multied == CLASS_CLERIC || ch->class == CLASS_CLERIC ) { SET_BIT( obj->extra_flags3, ITEM_PRO_CLERIC ); }
if( ch->multied == CLASS_THIEF || ch->class == CLASS_THIEF ) { SET_BIT( obj->extra_flags3, ITEM_PRO_THIEF ); }
if( ch->multied == CLASS_WARRIOR || ch->class == CLASS_WARRIOR ) { SET_BIT( obj->extra_flags3, ITEM_PRO_WARRIOR ); }
if( ch->multied == CLASS_PSIONICIST || ch->class == CLASS_PSIONICIST ) { SET_BIT( obj->extra_flags3, ITEM_PRO_PSI ); }
if( ch->multied == CLASS_DRUID || ch->class == CLASS_DRUID ) { SET_BIT( obj->extra_flags3, ITEM_PRO_DRUID ); }
if( ch->multied == CLASS_RANGER || ch->class == CLASS_RANGER ) { SET_BIT( obj->extra_flags3, ITEM_PRO_RANGER ); }
if( ch->multied == CLASS_PALADIN || ch->class == CLASS_PALADIN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_PALADIN ); }
if( ch->multied == CLASS_BARD || ch->class == CLASS_BARD ) { SET_BIT( obj->extra_flags3, ITEM_PRO_BARD ); }
if( ch->multied == CLASS_VAMPIRE || ch->class == CLASS_VAMPIRE ) { SET_BIT( obj->extra_flags3, ITEM_PRO_VAMP ); }
if( ch->multied == CLASS_WEREWOLF || ch->class == CLASS_WEREWOLF ) { SET_BIT( obj->extra_flags3, ITEM_PRO_WEREWOLF ); }
if( ch->multied == CLASS_ANTI_PALADIN || ch->class == CLASS_ANTI_PALADIN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_ANTIPAL ); }
if( ch->multied == CLASS_ASSASSIN || ch->class == CLASS_ASSASSIN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_ASSASSIN ); }
if( ch->multied == CLASS_MONK || ch->class == CLASS_MONK ) { SET_BIT( obj->extra_flags3, ITEM_PRO_MONK ); }
if( ch->multied == CLASS_BARBARIAN || ch->class == CLASS_BARBARIAN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_BARBARIAN ); }
if( ch->multied == CLASS_ILLUSIONIST || ch->class == CLASS_ILLUSIONIST ) { SET_BIT( obj->extra_flags3, ITEM_PRO_ILLUSIONIST ); }
if( ch->multied == CLASS_NECROMANCER || ch->class == CLASS_NECROMANCER ) { SET_BIT( obj->extra_flags3, ITEM_PRO_NECROMANCER ); }
if( ch->multied == CLASS_DEMONOLOGIST || ch->class == CLASS_DEMONOLOGIST ) { SET_BIT( obj->extra_flags3, ITEM_PRO_DEMONOLOGIST ); }
if( ch->multied == CLASS_SHAMAN || ch->class == CLASS_SHAMAN ) { SET_BIT( obj->extra_flags3, ITEM_PRO_SHAMAN ); }
if( ch->multied == CLASS_DARKPRIEST || ch->class == CLASS_DARKPRIEST ) { SET_BIT( obj->extra_flags3, ITEM_PRO_DARKPRIEST ); }
send_to_char(AT_BLUE, "Ok.\n\r", ch );
return SKPELL_NO_DAMAGE;
}
/*
* Drain XP, MANA, HP.
* Caster gains HP.
*/
int 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 SKPELL_ZERO_DAMAGE;
if ( victim->level <= 2 )
{
dam = ch->hit + 1;
}
else
{
dam = dice( 4, level );
if ( ( ch->hit + dam ) > ( ch->max_hit + 200 ) )
ch->hit = ( ch->max_hit + 200 );
else
ch->hit += dam;
if (victim->move - dam >= 0)
victim->move -= dam;
else
victim->move = 0;
if (ch->move + dam > ch->max_move + 200)
ch->move = ch->move + 200;
else
ch->move += dam;
}
//damage( ch, victim, dam, sn );
return dam;
}
int 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 SKPELL_MISSED;
}
if ( IS_SET(ch->in_room->area->area_flags, AREA_PRESENT)
&& (IS_SET( victim->in_room->area->area_flags, AREA_FUTURE )
|| IS_SET( victim->in_room->area->area_flags, AREA_PAST ) ) )
{
send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch );
return SKPELL_MISSED;
}
if ( IS_SET(ch->in_room->area->area_flags, AREA_FUTURE)
&& (IS_SET( victim->in_room->area->area_flags, AREA_PRESENT )
|| IS_SET( victim->in_room->area->area_flags, AREA_PAST ) ) )
{
send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch );
return SKPELL_MISSED;
}
if ( IS_SET(ch->in_room->area->area_flags, AREA_PAST)
&& (IS_SET( victim->in_room->area->area_flags, AREA_FUTURE )
|| IS_SET( victim->in_room->area->area_flags, AREA_PRESENT ) ) )
{
send_to_char(AT_BLUE, "You cannot!!!!!!!\n\r", ch );
return SKPELL_MISSED;
}
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 SKPELL_NO_DAMAGE;
}
int 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] * 6 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int 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 SKPELL_MISSED;
}
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 );
act(AT_YELLOW, msg, victim, obj_lose, NULL, TO_CHAR );
act(AT_YELLOW, "You destroyed $p!", ch, obj_lose, NULL, TO_CHAR );
break;
}
}
return SKPELL_NO_DAMAGE;
}
return SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
}
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 );
act(AT_YELLOW, msg, victim, obj_lose, NULL, TO_CHAR );
act(AT_YELLOW, "You destroyed $p!", ch, obj_lose, NULL, TO_CHAR );
break;
}
}
return SKPELL_NO_DAMAGE;
}
return SKPELL_NO_DAMAGE;
}
int 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 ) )
{
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 );
}
act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT);
victim->shields -= 1;
return SKPELL_NO_DAMAGE;
}
if ( !IS_SHIELDABLE( victim ) )
return SKPELL_MISSED;
af.type = sn;
af.level = level;
/* af.duration = number_fuzzy( level / 8 );*/
af.duration = -1;
af.location = APPLY_DAM_WATER;
af.modifier = 75;
af.bitvector = AFF_FIRESHIELD;
affect_to_char( victim, &af );
victim->shields += 1;
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 SKPELL_NO_DAMAGE;
}
int spell_demonshield( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED3( victim, AFF_DEMONSHIELD ) )
{
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 );
}
act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT);
victim->shields -= 1;
return SKPELL_NO_DAMAGE;
}
if ( !IS_SHIELDABLE( victim ) )
return SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = -1;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_DEMONSHIELD;
affect_to_char3( victim, &af );
victim->shields += 1;
send_to_char(AT_RED, "Your body is engulfed by swirling demons.\n\r",
victim );
act(AT_RED, "$n's body is engulfed by demons.", victim, NULL, NULL,
TO_ROOM );
return SKPELL_NO_DAMAGE;
}
int spell_acid_shield( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED3( victim, AFF_ACIDSHIELD ) )
{
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 );
}
act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT);
victim->shields -= 1;
return SKPELL_NO_DAMAGE;
}
if ( !IS_SHIELDABLE( victim ) )
return SKPELL_NO_DAMAGE;
af.type = sn;
af.level = level;
af.duration = -1;
af.location = APPLY_DAM_ACID;
af.modifier = 30;
af.bitvector = AFF_ACIDSHIELD;
affect_to_char3( victim, &af );
victim->shields += 1;
send_to_char(AT_GREEN, "Your body is surrounded by bubbling acid.\n\r", victim );
act(AT_GREEN, "$n's body is drenched in bubbling acid.", victim, NULL,
NULL, TO_ROOM );
return SKPELL_NO_DAMAGE;
}
int spell_flamestrike( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice( 6, level/2 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int 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 SKPELL_MISSED;
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 SKPELL_NO_DAMAGE;
}
int 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, skill_lookup("invis") );
affect_strip ( ich, skill_lookup("improved invis") );
affect_strip ( ich, skill_lookup("mass invis") );
affect_strip ( ich, skill_lookup("sneak") );
affect_strip ( ich, skill_lookup("shadow") );
affect_strip ( ich, skill_lookup("phase shift") );
affect_strip ( ich, skill_lookup("shadow plane") );
REMOVE_BIT ( ich->affected_by, AFF_HIDE );
REMOVE_BIT ( ich->affected_by, AFF_INVISIBLE );
REMOVE_BIT ( ich->affected_by2, AFF_IMPROVED_INVIS );
REMOVE_BIT ( ich->affected_by, AFF_SNEAK );
REMOVE_BIT ( ich->affected_by2, AFF_SHADOW_PLANE );
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 SKPELL_NO_DAMAGE;
}
int spell_fly( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected( victim, sn ) )
return SKPELL_MISSED;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_NO_DAMAGE;
}
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 SKPELL_NO_DAMAGE;
}
/*
* Spell for mega1.are from Glop/Erkenbrand.
*/
int 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 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int 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 SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_STR;
af.modifier = 1 + (level >= 18) + (level >= 25) + (level >= 32) + (level >= 39) + (level >=46) + (level >= 70) + (level >= 100);
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 SKPELL_NO_DAMAGE;
}
int spell_titan_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 SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = level;
af.location = APPLY_STR;
af.modifier = ch->level/7;
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 much stronger.\n\r", victim );
return SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
}
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 * 2;
berry->value[1] = ch->level * 5;
extract_obj( obj );
obj_to_char( berry, ch );
return SKPELL_NO_DAMAGE;
}
int 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 ) );
if ( saves_spell( level, victim ) )
dam = UMIN( 50, dam / 4 );
dam = UMIN( 175, dam );
//damage( ch, victim, dam, sn );
return dam;
}
int spell_heal( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int heal;
heal = (int)(victim->max_hit * 0.12);
victim->hit = UMIN( victim->hit + heal, victim->max_hit );
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 SKPELL_NO_DAMAGE;
}
/*
* Spell for mega1.are from Glop/Erkenbrand.
*/
int 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 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int 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 ) )
{
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 );
}
act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT);
victim->shields -= 1;
return SKPELL_NO_DAMAGE;
}
if ( !IS_SHIELDABLE( victim ) )
return SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = -1;
af.location = APPLY_DAM_FIRE;
af.modifier = 75;
af.bitvector = AFF_ICESHIELD;
affect_to_char( victim, &af );
victim->shields += 1;
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 SKPELL_NO_DAMAGE;
}
int spell_icestorm( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice( level, 10 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int spell_holy_fires( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
dam = dice( level, 20 );
if ( saves_spell( level, victim ) )
dam /= 2;
//damage( ch, victim, dam, sn );
return dam;
}
int 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 * 4];
int spn;
sprintf( buf,
"Object '%s' is type %s, extra flags %s %s %s %s.\n\r",
obj->name,
item_type_name( obj ),
extra_bit_name( obj->extra_flags ),
extra_bit_name2( obj->extra_flags2 ),
extra_bit_name3( obj->extra_flags3 ),
extra_bit_name4( obj->extra_flags4 ));
send_to_char(AT_CYAN, buf, ch );
sprintf( buf,
"Weight : %d, value : %d, level : %d.\n\r",
obj->weight,
obj->cost,
obj->level );
send_to_char(AT_CYAN, buf, ch );
sprintf( buf, "Durability: [%d/%d]\n\r", obj->durability_cur, obj->durability_max);
send_to_char(AT_CYAN, buf, ch );
switch ( obj->item_type )
{
case ITEM_RUNE:
sprintf( buf, "Destination: Unmarked.\n\r" );
if( obj->value[0] != 0 )
{
if (get_room_index(obj->value[0]))
sprintf( buf, "Destination: %s.\n\r", get_room_index(obj->value[0] )->name );
else
sprintf( buf, "Destination: Unknown Location.\n\r" );
}
send_to_char(AT_CYAN, buf, ch );
break;
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_BOOK:
sprintf( buf, "Gain %3.1f%% of:", obj->value[0] / 10.0f );
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_SKIN:
sprintf(buf, "Leather: %d yards\n\r", obj->value[1]);
send_to_char(AT_CYAN, buf, ch);
sprintf(buf, "Quality: %d (%s)", obj->value[0], flag_string(quality_flags, obj->value[0]));
send_to_char(AT_CYAN, buf, ch);
break;
case ITEM_BULLET:
case ITEM_BOLT:
case ITEM_ARROW:
sprintf(buf, "Remaining: %d. ", obj->value[0]);
send_to_char(AT_CYAN, buf, ch );
sprintf(buf, "Damage Class: %s. ", flag_string( damage_flags, obj->value[1]) );
send_to_char(AT_CYAN, buf, ch );
sprintf(buf, "Damage Bonus: %d to %d (average %d).\n\r", obj->value[2], obj->value[3], ( (obj->value[2] + obj->value[3]) / 2 ) );
send_to_char(AT_CYAN, buf, 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_GUN:
if (!(obj->value[1] == -1 ) )
sprintf( buf, "Has %d(%d) shots of level %d",
obj->value[1], obj->value[2], obj->value[0] );
else
sprintf( buf, "Has unlimited shots 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 )
{
char buf2[MAX_STRING_LENGTH];
if (paf->location > PERM_SPELL_BEGIN)
strcpy(buf2, "Affects '%s' by %d.\n\r");
else
strcpy(buf2, "Affects %s by %d.\n\r");
sprintf( buf, buf2, affect_loc_name( paf->location ), paf->modifier );
send_to_char(AT_BLUE, buf, ch );
}
}
return SKPELL_NO_DAMAGE;
}
int spell_inertial( int sn, int level, CHAR_DATA *ch, void *vo )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( IS_AFFECTED( victim, AFF_INERTIAL ) )
{
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 );
}
act(C_DEFAULT, skill_table[sn].msg_off_room, victim, NULL, NULL, TO_NOTVICT);
victim->shields -= 1;
return SKPELL_NO_DAMAGE;
}
if ( !IS_SHIELDABLE( victim ) )
return SKPELL_MISSED;
af.type = sn;
af.level = level;
af.duration = -1;
af.location = APPLY_NONE;
af.modifier = 0;
af.bitvector = AFF_INERTIAL;
affect_to_char( victim, &af );
victim->shields += 1;
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 SKPELL_NO_DAMAGE;
}
int 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 SKPELL_MISSED;
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 SKPELL_NO_DAMAGE;
}