/***************************************************************************
* 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. *
* *
* In order to use any part of this Merc Diku Mud, you must comply with *
* both the original Diku license in 'license.doc' as well the Merc *
* license in 'license.txt'. 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. *
***************************************************************************/
/***************************************************************************
* ROM 2.4 is copyright 1993-1996 Russ Taylor *
* ROM has been brought to you by the ROM consortium *
* Russ Taylor (rtaylor@pacinfo.com) *
* Gabrielle Taylor (gtaylor@pacinfo.com) *
* Brian Moore (rom@rom.efn.org) *
* By using this code, you have agreed to follow the terms of the *
* ROM license, in the file Tartarus/doc/rom.license *
***************************************************************************/
/***************************************************************************
* Tartarus code is copyright (C) 1997-1998 by Daniel Graham *
* In using this code you agree to comply with the Tartarus license *
* found in the file /Tartarus/doc/tartarus.doc *
***************************************************************************/
#include "include.h"
char *target_name;
void spell_self_immolation(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
if (is_affected(ch,sn))
{
send_to_char("You are already immolating.\n\r",ch);
return;
}
init_affect(&af);
af.type = sn;
af.aftype = AFT_SPELL;
af.duration = ch->level / 4;
af.modifier = 0;
af.bitvector = 0;
af.where = TO_AFFECTS;
af.affect_list_msg = str_dup("sears you and opponents who strike at you");
af.location = 0;
af.owner_name = str_dup(ch->original_name);
affect_to_char(ch, &af);
act("$n suddenly bursts into flames!", ch,NULL,NULL,TO_ROOM);
act("You suddenly burst into flames!", ch,NULL,NULL,TO_CHAR);
}
void spell_shield_of_bubbles( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim,gsn_shield_of_bubbles))
{
if (victim == ch)
send_to_char("You are already surrounded in a shield of bubbles.\n\r",ch);
else
act("$N is already surrounded by a shield of bubbles.",ch,NULL,victim,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = 18;
af.location = APPLY_DAM_MOD;
af.modifier = -3;
af.affect_list_msg = str_dup("grants immunity to drowning attacks");
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = 0;
af.modifier = 0;
af.affect_list_msg = str_dup("reduces damage taken by 3%");
affect_to_char( victim, &af );
act( "A protective shield of bubbles envelops $n.", victim, NULL, NULL, TO_ROOM );
send_to_char( "A protective shield of bubbles envelops you.\n\r", victim );
return;
}
void spell_shield_of_flames( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim,gsn_shield_of_flames))
{
if (victim == ch)
send_to_char("You are already surrounded in a shield of flames.\n\r",ch);
else
act("$N is already surrounded by a shield of flames.",ch,NULL,victim,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = 18;
af.location = APPLY_DAM_MOD;
af.modifier = -3;
af.affect_list_msg = str_dup("grants immunity to fire and heat attacks");
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = 0;
af.modifier = 0;
af.affect_list_msg = str_dup("reduces damage taken by 3%");
affect_to_char( victim, &af );
act( "A shield of flames flares into existence around $n.", victim, NULL, NULL, TO_ROOM );
send_to_char( "A shield of flames flares into existence around you.\n\r", victim );
return;
}
void spell_shield_of_frost( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim,gsn_shield_of_frost))
{
if (victim == ch)
send_to_char("You are already surrounded in a shield of frost.\n\r",ch);
else
act("$N is already surrounded by a shield of frost.",ch,NULL,victim,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = 18;
af.location = APPLY_DAM_MOD;
af.affect_list_msg = str_dup("grants immunity to cold attacks");
af.modifier = -3;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = 0;
af.modifier = 0;
af.affect_list_msg = str_dup("reduces damage taken by 3%");
affect_to_char( victim, &af );
act( "The temperature around $n drops suddenly and forms a shield of frost about $m.", victim, NULL, NULL, TO_ROOM );
send_to_char( "The temperature around you drops suddenly and forms a shield of frost about you.\n\r", victim );
return;
}
void spell_shield_of_lightning( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim,gsn_shield_of_lightning))
{
if (victim == ch)
send_to_char("You are already surrounded in a shield of lightning.\n\r",ch);
else
act("$N is already surrounded by a shield of lightning.",ch,NULL,victim,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = 18;
af.location = APPLY_DAM_MOD;
af.modifier = -3;
af.affect_list_msg = str_dup("grants immunity to lightning attacks");
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = 0;
af.modifier = 0;
af.affect_list_msg = str_dup("reduces damage taken by 3%");
affect_to_char( victim, &af );
act( "A shield of lightning crackles into existence around $n.", victim, NULL, NULL, TO_ROOM );
send_to_char( "A shield of lightning crackles into existence around you.\n\r", victim );
return;
}
void spell_shield_of_wind( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim,gsn_shield_of_wind))
{
if (victim == ch)
send_to_char("You are already surrounded in a shield of wind.\n\r",ch);
else
act("$N is already surrounded by a shield of wind.",ch,NULL,victim,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = 18;
af.location = APPLY_DAM_MOD;
af.affect_list_msg = str_dup("grants immunity to wind attacks");
af.modifier = -3;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = 0;
af.modifier = 0;
af.affect_list_msg = str_dup("reduces damage taken by 3%");
affect_to_char( victim, &af );
act( "Strong winds coalesce about $n in a shield of wind.", victim, NULL, NULL, TO_ROOM );
send_to_char( "Strong winds coalesce about you in a shield of wind.\n\r", victim );
return;
}
void spell_shield_of_dust( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if ( is_affected(victim,gsn_shield_of_dust))
{
if (victim == ch)
send_to_char("You are already surrounded in a shield of dust.\n\r",ch);
else
act("$N is already surrounded by a shield of dust.",ch,NULL,victim,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = 18;
af.location = APPLY_DAM_MOD;
af.affect_list_msg = str_dup("grants immunity to dirt and dust attacks");
af.modifier = -3;
af.bitvector = 0;
affect_to_char( victim, &af );
af.location = 0;
af.modifier = 0;
af.affect_list_msg = str_dup("reduces damage taken by 3%");
affect_to_char( victim, &af );
act( "The dust picks up from the earth, forming a shield of dust around $n.", victim, NULL, NULL, TO_ROOM );
send_to_char( "The dust picks up from the earth, forming a shield of dust around you.\n\r", victim );
return;
}
void spell_hydrolic_ram( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim;
int dam;
int chance;
victim = (CHAR_DATA *) vo;
if (victim == NULL)
victim = ch->fighting;
dam = dice(level,3) + level;
act("You fire a concentrated jet of water at $N!",ch,NULL,victim,TO_CHAR);
act("$n fires a concentrated jet of water at $N!",ch,NULL,victim,TO_NOTVICT);
act("$n fires a concentrated jet of water at you!",ch,NULL,victim,TO_VICT);
damage_old(ch,victim,dam,sn, DAM_DROWNING, TRUE);
chance = get_skill(ch,sn);
if (number_percent() > chance)
return;
act("Your hydrolic ram blasts $N off $S feet!",ch,NULL,victim,TO_CHAR);
act("$n's hydrolic ram blasts you off your feet!",ch,NULL,victim,TO_VICT);
act("$n's hydrolic ram knocks $N off $S feet!",ch,NULL,victim,TO_NOTVICT);
WAIT_STATE(victim, PULSE_VIOLENCE);
}
void spell_spontanious_combustion(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
act("$n screams in agony as flames engulf $s body.",victim,0,0,TO_ROOM);
send_to_char("You feel a sudden intense pain throughout your body as you are engulfed in flames!\n\r",victim);
dam = dice(level,10) + 3 * ch->level;
damage_old(ch,victim,saves_spell(level,victim,DAM_FIRE) ? dam/2 : dam,sn,DAM_FIRE,TRUE);
return;
}
void spell_shockwave(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
char buf[MAX_STRING_LENGTH];
int lag;
WAIT_STATE(ch,2 * PULSE_VIOLENCE);
act("$n stomps $s foot and the ground begins to shake!",ch,NULL,NULL,TO_ROOM);
act("You stomp your foot and the ground begins to shake!",ch,NULL,NULL,TO_CHAR);
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if (is_same_group(vch,ch) )
continue;
if (!IS_NPC(ch) && !IS_NPC(vch)
&& (ch->fighting == NULL || vch->fighting == NULL))
{
switch(number_range(0,2))
{
case (0):
case (1):
sprintf(buf,"Die, %s you sorcerous dog!",PERS(ch,vch));
break;
case (2):
sprintf(buf,"Help! %s is casting a spell on me!",PERS(ch,vch));
}
if (vch != ch)
do_myell(vch,buf);
}
if (vch->position != POS_FIGHTING)
{
vch->position = POS_FIGHTING;
vch->fighting = ch;
}
if (ch->position != POS_FIGHTING)
{
ch->position = POS_FIGHTING;
ch->fighting = vch;
}
lag = number_range(0,3);
if (lag && !IS_AFFECTED(vch,AFF_FLYING))
{
act("$n is knocked of $s feet by the shockwave!",vch,NULL,NULL,TO_ROOM);
act("You are knocked off your feet by the shockwave!",vch,NULL,NULL,TO_CHAR);
WAIT_STATE(vch,lag * PULSE_VIOLENCE);
}
}
}
void spell_static_charge( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,gsn_static_charge) )
{
send_to_char("You are already fully charged!\n\r",victim);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = gsn_static_charge;
af.level = level;
af.duration = number_range(1,5);
af.affect_list_msg = str_dup("charges you with static for one attack");
af.modifier = 0;
af.location = 0;
af.bitvector = 0;
affect_to_char(victim, &af);
send_to_char("You charge yourself with static electricity!\n\r",victim);
act("$n begins to glow softly as $s hair begins to stand on end.",victim,NULL,NULL,TO_ROOM);
return;
}
void spell_flicker(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
ROOM_INDEX_DATA *pRoomIndex;
int chance;
int count;
chance = get_skill(ch,sn);
chance -= 10;
if (ch->position==POS_FIGHTING)
{
chance -= 50;
}
if (number_percent() > chance)
{
send_to_char("You begin to flicker but nothing happens.\n\r",ch);
act("$n seems to flicker for a moment but nothing happens.",ch,0,0,TO_ROOM);
return;
}
if (ch->in_room->vnum == 23610 || ch->in_room->vnum == ROOM_FORCE_DUEL)
{
send_to_char("You fail.\n\r",ch);
return;
}
count = 0; //keep the game from hanging if it never finds a room
while (TRUE)
{
count++;
if (count > 30000)
{
send_to_char("you fail.\n\r",ch);
return;
}
pRoomIndex = get_room_index(number_range(0,30000));
if (pRoomIndex != NULL)
if (pRoomIndex->area == ch->in_room->area
&& !IS_SET(pRoomIndex->room_flags,ROOM_PRIVATE)
&& !IS_SET(pRoomIndex->room_flags,ROOM_NO_RECALL)
&& (pRoomIndex->guild == 0)
&& can_see_room(ch,pRoomIndex)
&& !IS_SET(pRoomIndex->room_flags,ROOM_SOLITARY)
&& ch->in_room->vnum != 1212
&& pRoomIndex->vnum != 1212)
break;
}
act("$n begins to flicker and suddenly dissapears!",ch,0,0,TO_ROOM);
send_to_char("You begin to flicker and suddenly find yourself somewhere else!\n\r",ch);
char_from_room(ch);
char_to_room(ch,pRoomIndex);
act("The likeness of $n flickers into being.",ch,0,0,TO_ROOM);
do_look(ch,"auto");
return;
}
void spell_smoke(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (IS_AFFECTED(victim,AFF_BLIND))
{
send_to_char("They are already blind.\n\r",ch);
return;
}
act("$n breathes a puff of smoke into $N's face!",ch,NULL,victim,TO_NOTVICT);
act("$n breaths a puff of smoke into your face!",ch,NULL,victim,TO_VICT);
act("You breath a puff of smoke into $N's face!",ch,NULL,victim,TO_CHAR);
if (saves_spell(level,victim,DAM_OTHER))
{
act("$n manages to keep the smoke out of their eyes.",victim,NULL,NULL,TO_ROOM);
act("You manage to keep the smoke out of your eyes.",victim,NULL,NULL,TO_CHAR);
return;
}
if (victim->race==race_lookup("lich"))
{
act("$n doesn't seem to be affected by the smoke.",victim,NULL,NULL,TO_ROOM);
act("The smoke doesn't seem to affect you.",victim,NULL,NULL,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.location = APPLY_HITROLL;
af.modifier = -4;
af.duration = 1;
af.bitvector = AFF_BLIND;
affect_to_char( victim, &af );
send_to_char( "The smoke gets in your eyes and blinds you!\n\r", victim );
act("$n is blinded by the smoke.",victim,NULL,NULL,TO_ROOM);
return;
}
void spell_nullify_sound(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (ch == victim)
{
send_to_char("That would not be wise.\n\r",ch);
return;
}
if (is_affected(victim,sn))
{
act("$N cannot hear anything already.",ch,NULL,victim,TO_CHAR);
return;
}
if (saves_spell(level,victim, DAM_NONE))
return;
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = 3;
af.modifier = 0;
af.location = 0;
af.bitvector = 0;
affect_to_char(victim,&af);
act("You have destroyed all sound near $N!",ch,NULL,victim,TO_CHAR);
send_to_char("The world suddenly grows very silent!\n\r",victim);
}
void spell_displacement(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (ch != victim)
{
send_to_char("You can only cast this spell on yourself.\n\r",ch);
return;
}
if (is_affected(ch,sn))
{
act("Your true location is already masked.",ch,NULL,NULL,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = 10;
af.modifier = 0;
af.location = 0;
af.affect_list_msg = str_dup("grants a chance to avoid attacks completely");
af.bitvector = 0;
affect_to_char(victim,&af);
act("Your body begins to flicker with translucency.",ch,NULL,victim,TO_CHAR);
}
void spell_detect_illusion(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int dur;
dur = ch->level / 3;
if (victim != ch)
dur /= 2;
if (is_affected(ch,sn))
{
act("Your senses are already enhanced.",ch,NULL,NULL,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = dur;
af.modifier = 0;
af.location = 0;
af.bitvector = 0;
affect_to_char(victim,&af);
act("Your eyes gleam with a heightened awareness of illusion.",victim,NULL,NULL,TO_CHAR);
}
void spell_ice_slick(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
ROOM_AFFECT_DATA raf;
if ( is_affected( ch, sn ) )
{
send_to_char("You cannot make another ice slick so soon.\n\r", ch);
return;
}
if ( is_affected_room( ch->in_room, sn ))
{
send_to_char("The ground is already frozen.\n\r",ch);
return;
}
if (number_range(1,100) > ch->pcdata->learned[sn])
{
send_to_char("You attempt to freeze the ground but fail.\n\r",ch);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.type = sn;
af.aftype = AFT_SPELL;
af.level = ch->level;
af.affect_list_msg = str_dup("restricts casting of Ice Slick");
af.duration = 48;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
init_affect_room(&raf);
raf.where = TO_ROOM_AFFECTS;
raf.aftype = AFT_SPELL;
raf.type = sn;
raf.level = ch->level;
raf.duration = ch->level/5;
raf.modifier = 0;
raf.bitvector = AFF_ROOM_ICE_SLICK;
affect_to_room( ch->in_room, &raf );
send_to_char("You freeze the ground around you!\n\r", ch);
act("The ground becomes frozen and slick!",ch,NULL,NULL,TO_ROOM);
}
void spell_create_vacume(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
ROOM_AFFECT_DATA raf;
if ( is_affected( ch, sn ) )
{
send_to_char("You cannot create another vacume yet.\n\r", ch);
return;
}
if ( is_affected_room( ch->in_room, sn ))
{
send_to_char("There already is a vacume here.\n\r",ch);
return;
}
if (number_range(1,100) > ch->pcdata->learned[sn])
{
send_to_char("You attempt to pull all the air out of the room but fail.\n\r",ch);
WAIT_STATE(ch, PULSE_TICK / 2);
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = ch->level;
af.duration = 60;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
init_affect_room(&raf);
raf.where = TO_ROOM_AFFECTS;
raf.aftype = AFT_SPELL;
raf.type = sn;
raf.level = ch->level;
raf.duration = 4;
raf.modifier = 0;
raf.bitvector = AFF_ROOM_VACUME;
affect_to_room( ch->in_room, &raf );
send_to_char("You suck all the air out of this place and make a vacume!\n\r", ch);
act("You feel a slight breeze and relize that there is no longer any air around you!",ch,NULL,NULL,TO_ROOM);
WAIT_STATE(ch, PULSE_TICK);
}
void spell_hellfire(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int dam;
int dambase;
dambase=320;
if (!IS_NPC(ch) && check_spellcraft(ch,sn))
{
dambase=350;
level+=2;
}
dam=dambase+number_percent();
if (saves_spell(level+1,victim,DAM_FIRE))
dam-=200;
act("$N is consumed by hellish flames.",ch,0,victim,TO_NOTVICT);
act("You are consumed by hellish flames.",ch,0,victim,TO_VICT);
act("$N is consumed by hellish flames.",ch,0,victim,TO_CHAR);
damage_old(ch,victim,dam,sn,DAM_FIRE,TRUE);
if (is_affected(victim,sn))
return;
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.modifier = 0;
af.location = 0;
af.affect_list_msg = str_dup("induces major burns");
af.bitvector = 0;
af.duration = 4;
af.level = level;
af.owner_name = str_dup(ch->original_name);
affect_to_char(victim,&af);
return;
}
void spell_pyrotechnics(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
CHAR_DATA *vch;
CHAR_DATA *vch_next;
char buf[MAX_STRING_LENGTH];
int dam;
int dambase;
dambase=150;
if (!IS_NPC(ch) && check_spellcraft(ch,sn))
{
dambase=350;
level+=2;
}
act("Sparks and flames begin to spew forth from $n's outstreched hands.",ch,0,0,TO_ROOM);
act("The air fills with sparks and fire scorching everything in sight!",ch,0,0,TO_ROOM);
for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
{
vch_next = vch->next_in_room;
if (is_same_group(vch,ch) || is_safe(ch,vch))
continue;
if (ch->cabal>0 && vch->cabal>0 && ch->cabal==vch->cabal)
continue;
if (!IS_NPC(vch) && (ch->fighting == NULL || vch->fighting == NULL))
{
sprintf(buf,"Die, %s, you sorcerous dog!",PERS(ch,vch));
do_myell(vch,buf);
}
dam=dambase+number_percent();
dam+=number_percent()*1.3;
if (saves_spell(level+1,vch,DAM_FIRE))
dam*=.66;
damage_old(ch,vch,dam,sn,DAM_FIRE,TRUE);
}
WAIT_STATE(ch,PULSE_VIOLENCE*2);
return;
}
//New implementation since the old one was missing - Zornath
void spell_ball_lightning(int sn,int level,CHAR_DATA *ch,void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo, *rch, *rch_next;
int target_dam = 225 + number_range(10,20), offtarget_dam = 185 + number_range(5,15), dam;
if (victim == ch) return send_to_char("Logic prevails and prevents you from doing that.\n\r",ch);
if (check_spellcraft(ch,skill_lookup("ball lightning"))) {
target_dam += spellcraft_dam(20,5);
offtarget_dam += spellcraft_dam(20,7);
}
act("You release a ball of lightning towards $N!",ch,0,victim,TO_CHAR);
act("$n releases a ball of lightning towards $N!",ch,0,victim,TO_NOTVICT);
act("$n releases a ball of lightning towards you!",ch,0,victim,TO_VICT);
for (rch = victim->in_room->people; rch != NULL; rch = rch_next) {
rch_next = rch->next_in_room;
if (is_same_group(rch,victim) && rch != victim) {
act("The ball of lightning explodes into a dazzling array of light near you!",ch,0,rch,TO_VICT);
act("Your ball of lightning explodes into a dazzling array of light near $N!",ch,0,rch,TO_CHAR);
act("$n's ball of lightning explodes into a dazzling array of light near $N!",ch,0,rch,TO_NOTVICT);
dam = offtarget_dam;
if (saves_spell(level,rch,DAM_LIGHTNING)) dam *= 0.66;
damage_newer(ch,rch,dam,skill_lookup("ball lightning"),DAM_LIGHTNING,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"ball of lightning",PLURAL,DAM_POSSESSIVE,NULL,FALSE);
}
if (rch == victim) {
act("The ball of lightning slams directly into you, exploding into an array of dazzling light!",ch,0,rch,TO_VICT);
act("Your ball of lightning slams directly into $N, exploding into an array of dazzling light!",ch,0,rch,TO_CHAR);
act("$n's ball of lightning slams directly into $N, exploding into an array of dazzling light!!",ch,0,rch,TO_NOTVICT);
dam = target_dam;
if (saves_spell(level,rch,DAM_LIGHTNING)) dam *= 0.66;
damage_newer(ch,rch,dam,skill_lookup("ball lightning"),DAM_LIGHTNING,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"ball of lightning",PLURAL,DAM_POSSESSIVE,NULL,FALSE);
}
}
return;
}
void spell_fatigue( int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam = number_range(100,150);
int saved = FALSE;
if(saves_spell(level,victim,DAM_MENTAL))
{ dam-=40; saved=TRUE; }
if(!saved)
{
act("$n looks fatigued.",victim,0,0,TO_ROOM);
act("You feel very fatigued.",victim,0,0,TO_CHAR);
victim->move -= dice(level,3);
}
damage_old(ch,victim,dam,sn,DAM_MENTAL,TRUE);
}
void spell_cleanse(int sn,int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
//Difficulty modifier: 1 easy 2 medium 3 hard 4 very hard
sn=skill_lookup("blindness");
if(number_percent() < number_range(40,60))
{
if(is_affected(victim,sn) && cleansed(ch,victim,1,sn))
{
if(victim!=ch)
act("$n is no longer blinded.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("poison");
if(is_affected(victim,sn) && cleansed(ch,victim,2,sn))
{
if(victim!=ch)
act("$n looks less ill.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("weaken");
if(is_affected(victim,sn) && cleansed(ch,victim,1,sn))
{
if(victim!=ch)
act("$n looks stronger.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("plague");
if(is_affected(victim,sn) && cleansed(ch,victim,2,sn))
{
if(victim!=ch)
act("$n looks less diseased.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("slow");
if(is_affected(victim,sn) && cleansed(ch,victim,2,sn))
{
if(victim!=ch)
act("$n starts moving at normal speed again.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("forget");
if(is_affected(victim,sn) && cleansed(ch,victim,4,sn))
{
if(victim!=ch)
act("$n looks like $e's just had a rush of memory.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("rot");
if(is_affected(victim,sn) && cleansed(ch,victim,3,sn))
{
if(victim!=ch)
act("$n's body stops wasting away.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("garble");
if(is_affected(victim,sn) && cleansed(ch,victim,3,sn))
{
if(victim!=ch)
act("$n's tongue uncontorts.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("confuse");
if(is_affected(victim,sn) && cleansed(ch,victim,3,sn))
{
if(victim!=ch)
act("$n looks less confused.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("curse");
if(is_affected(victim,sn) && cleansed(ch,victim,2,sn))
{
if(victim!=ch)
act("$n's curse wears off.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("incinerate");
if(is_affected(victim,sn) && cleansed(ch,victim,4,sn))
{
if(victim!=ch)
act("$n stops burning.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim );
send_to_char("\n\r", victim);
affect_strip(victim,sn);
}
sn=skill_lookup("impale");
if(is_affected(victim,sn) && cleansed(ch,victim,4,sn))
{
if(victim!=ch)
act("$n stops bleeding.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim);
send_to_char("\n\r",victim);
affect_strip(victim,sn);
}
sn=skill_lookup("hellfire");
if(is_affected(victim,sn) && cleansed(ch,victim,4,sn))
{
if(victim!=ch)
act("$n's helfire subsides.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim);
send_to_char("\n\r",victim);
affect_strip(victim,sn);
}
sn=skill_lookup("haunting");
if(is_affected(victim,sn) && cleansed(ch,victim,4,sn))
{
if(victim!=ch)
act("$n looks less frightened.",victim,0,ch,TO_ROOM);
send_to_char(skill_table[sn].msg_off, victim);
send_to_char("\n\r",victim);
affect_strip(victim,sn);
}
}
check_improve(ch,skill_lookup("cleanse"),TRUE,1);
return;
}
bool cleansed(CHAR_DATA *ch, CHAR_DATA *victim,int diffmodifier, int sn)
{
int chance=0, snlevel;
chance=100/diffmodifier;
snlevel=get_affect_level(victim,sn);
if(snlevel<0)
return FALSE;
chance-=(snlevel-ch->level)*2;
if(number_percent()>chance)
return FALSE;
return TRUE;
}
int get_affect_level(CHAR_DATA *ch, int sn)
{
AFFECT_DATA *paf;
//Go through all affects on ch and return the level of the one that matches sn.
for ( paf = ch->affected; paf != NULL; paf = paf->next )
if(paf->type==sn)
return paf->level;
return -1;
}
void spell_rot(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn)) {
act("$N is already decomposing.",ch,NULL,victim,TO_CHAR);
return;
}
if (saves_spell(level,victim,DAM_DISEASE) ||
(IS_NPC(victim) && IS_SET(victim->act,ACT_UNDEAD)))
{
act("$N's body resists the decomposition.",ch,NULL,victim,TO_CHAR);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_MALADY;
af.type = sn;
af.level = level;
af.duration = (get_curr_stat(victim,STAT_CON)*6)/5;
af.location = APPLY_CON;
af.modifier = -1;
af.bitvector = 0;
af.owner_name = str_dup(ch->original_name);
affect_to_char(victim,&af);
send_to_char("You feel your body begin to decompose.\n\r",victim);
act("$n looks like $e is decomposing.",victim,NULL,NULL,TO_ROOM);
return;
}
void spell_cure_deafness(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (!is_affected(victim,gsn_deafen))
{
if (victim == ch)
send_to_char("You aren't deaf.\n\r",ch);
else
act("$N doesn't appear to be deafened.",ch,NULL,victim,TO_CHAR);
return;
}
if (check_dispel(level,victim,gsn_deafen))
{
send_to_char("Your hearing returns!\n\r", victim );
act("$n is no longer deafened.",victim,NULL,NULL,TO_ROOM);
} else {
send_to_char("You failed.\n\r",ch);
}
return;
}
void spell_remove_paralysis(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (!is_affected(victim,skill_lookup("hold person")))
{
if (victim == ch)
send_to_char("You aren't paralyzed.\n\r",ch);
else
act("$N doesn't appear to be paralyzed.",ch,NULL,victim,TO_CHAR);
return;
}
if (check_dispel(level,victim,skill_lookup("hold person")))
{
send_to_char("The feeling in your body returns!\n\r", victim );
act("$n is no longer paraylzed.",victim,NULL,NULL,TO_ROOM);
} else {
send_to_char("You failed.\n\r",ch);
}
return;
}
void spell_awaken(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (IS_AWAKE(victim))
{
act("$N is already awake.", ch, NULL, victim, TO_CHAR);
return;
}
if (is_affected(victim,skill_lookup("sleep")))
{
if (check_dispel(level,victim,skill_lookup("sleep")))
{
send_to_char( "You suddenly awaken.\n\r", victim );
act("$n suddenly awakens.",victim,NULL,NULL,TO_ROOM);
do_stand(victim,"");
} else {
send_to_char("You failed.\n\r",ch);
}
return;
} else if (is_affected(victim,gsn_garrotte)) {
if (check_dispel(level,victim,gsn_garrotte))
{
send_to_char( "You suddenly awaken.\n\r", victim );
act("$n suddenly awakens.",victim,NULL,NULL,TO_ROOM);
do_stand(victim,"");
} else {
send_to_char("You failed.\n\r",ch);
}
return;
} else if (is_affected(victim,gsn_blackjack)) {
if (check_dispel(level,victim,gsn_blackjack))
{
send_to_char( "You suddenly awaken.\n\r", victim );
act("$n suddenly awakens.",victim,NULL,NULL,TO_ROOM);
do_stand(victim,"");
} else {
send_to_char("You failed.\n\r",ch);
}
return;
} else if (is_affected(victim,gsn_choke)) {
if (check_dispel(level,victim,gsn_choke))
{
send_to_char( "You suddenly awaken.\n\r", victim );
act("$n suddenly awakens.",victim,NULL,NULL,TO_ROOM);
do_stand(victim,"");
} else {
send_to_char("You failed.\n\r",ch);
}
return;
} else if (is_affected(victim,gsn_choke)) {
if (check_dispel(level,victim,gsn_choke))
{
send_to_char( "You suddenly awaken.\n\r", victim );
act("$n suddenly awakens.",victim,NULL,NULL,TO_ROOM);
do_stand(victim,"");
} else {
send_to_char("You failed.\n\r",ch);
}
return;
} else if (is_affected(victim,gsn_stun)) {
if (check_dispel(level,victim,gsn_stun))
{
send_to_char( "You suddenly awaken.\n\r", victim );
act("$n suddenly awakens.",victim,NULL,NULL,TO_ROOM);
do_stand(victim,"");
} else {
send_to_char("You failed.\n\r",ch);
}
return;
} else {
send_to_char("They don't seem to be in deep sleep.\n\r",ch);
return;
}
return;
}
void spell_resist_heat(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already resisting heat.\n\r",ch);
else
act("$E is already resisting heat.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You feel resistant to heat.\n\r",victim);
act("$n is resistant to heat.",victim,NULL,NULL,TO_ROOM);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = sn;
af.modifier = 0;
af.level = level;
af.duration = 4 + ch->level/5;
af.bitvector = RES_FIRE;
af.location = 0;
affect_to_char(victim,&af);
return;
}
void spell_resist_cold(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already resisting cold.\n\r",ch);
else
act("$E is already resisting cold.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You feel resistant to cold.\n\r",victim);
act("$n is resistant to cold.",victim,NULL,NULL,TO_ROOM);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = sn;
af.modifier = 0;
af.level = level;
af.duration = 4 + ch->level/5;
af.bitvector = RES_COLD;
af.location = 0;
affect_to_char(victim,&af);
return;
}
void spell_resist_lightning(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already resisting lightning.\n\r",ch);
else
act("$E is already resisting lightning.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You feel resistant to lightning.\n\r",victim);
act("$n is resistant to lightning.",victim,NULL,NULL,TO_ROOM);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = sn;
af.modifier = 0;
af.level = level;
af.duration = 4 + ch->level/5;
af.bitvector = RES_LIGHTNING;
af.location = 0;
affect_to_char(victim,&af);
return;
}
void spell_resist_mental(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already resisting mental attacks.\n\r",ch);
else
act("$E is already resisting mental attacks.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You feel resistant to mental attacks.\n\r",victim);
act("$n is resistant to mental attacks.",victim,NULL,NULL,TO_ROOM);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = sn;
af.modifier = 0;
af.level = level;
af.duration = 4 + ch->level/5;
af.bitvector = RES_MENTAL;
af.location = 0;
affect_to_char(victim,&af);
return;
}
void spell_resist_acid(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already resisting acid.\n\r",ch);
else
act("$E is already resisting acid.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You feel resistant to acid.\n\r",victim);
act("$n is resistant to acid.",victim,NULL,NULL,TO_ROOM);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = sn;
af.modifier = 0;
af.level = level;
af.duration = 4 + ch->level/5;
af.bitvector = RES_ACID;
af.location = 0;
affect_to_char(victim,&af);
return;
}
void spell_resist_negative(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already resisting negative damage.\n\r",ch);
else
act("$E is already resisting negative damage.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You feel resistant to negative damage.\n\r",victim);
act("$n is resistant to negative damage.",victim,NULL,NULL,TO_ROOM);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = sn;
af.modifier = 0;
af.level = level;
af.duration = 4 + ch->level/5;
af.bitvector = RES_NEGATIVE;
af.location = 0;
affect_to_char(victim,&af);
return;
}
void spell_resist_paralysis(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already resisting paralysis.\n\r",ch);
else
act("$E is already resisting paralysis.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You feel resistant to paralysis.\n\r",victim);
act("$n is resistant to paralysis.",victim,NULL,NULL,TO_ROOM);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = sn;
af.modifier = 0;
af.level = level;
af.duration = 4 + ch->level/5;
af.bitvector = RES_MAGIC;
af.location = 0;
affect_to_char(victim,&af);
return;
}
void spell_resist_weapon(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,sn))
{
if (victim == ch)
send_to_char("You are already resisting weapons.\n\r",ch);
else
act("$E is already resisting weapons.",ch,NULL,victim,TO_CHAR);
return;
}
send_to_char("You feel resistant to weapons.\n\r",victim);
act("$n is resistant to weapons.",victim,NULL,NULL,TO_ROOM);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = sn;
af.modifier = 0;
af.level = level;
af.duration = 4 + ch->level/5;
af.bitvector = RES_WEAPON|RES_BASH|RES_SLASH|RES_PIERCE;
af.location = 0;
affect_to_char(victim,&af);
return;
}
/* Psi Blast for Illithids -- Ceial */
void spell_psi_blast(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int dam;
if (is_affected(ch,gsn_psi_blast))
{
send_to_char("Your mind hasn't regained strength enough to assault minds.",ch);
return;
}
if (saves_spell(level-4,victim,DAM_NEGATIVE) )
{
act("$n reels but is not over come by your mind.",victim,NULL,NULL,TO_ROOM);
act("Your mind is brutally assaulted, but you resist.",victim,NULL,NULL,TO_CHAR);
WAIT_STATE(ch,PULSE_VIOLENCE*1);
return;
}
if (check_spellcraft(ch,sn))
dam = spellcraft_dam(6 + level / 1.5,9);
else
dam = dice(6 + level / 2, 8);
if ( saves_spell( level, victim,DAM_MENTAL) )
dam /= 2;
damage_old( ch, victim, dam, sn, DAM_MENTAL ,TRUE);
act("$N reels as their mind is brutally assaulted!",ch,NULL,victim,TO_NOTVICT);
act("$N reels from your mental blast!",ch,NULL,victim,TO_CHAR);
send_to_char("Your reels from the brutal assault.",victim);
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = gsn_psi_blast;
af.bitvector = 0;
af.level = level;
af.duration = 10;
affect_to_char(ch,&af);
WAIT_STATE(victim,PULSE_VIOLENCE*3);
return;
}
void spell_group_teleport(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
ROOM_INDEX_DATA *old_room;
CHAR_DATA *group;
CHAR_DATA *g_next;
old_room = ch->in_room;
spell_teleport(skill_lookup("teleport"), level, ch, ch, (int)NULL);
if (ch->in_room != old_room) {
for (group = old_room->people; group != NULL; group = g_next)
{
g_next = group->next_in_room;
if (!is_same_group(group,ch) || (group->fighting != NULL) || group == ch)
continue;
if (group == ch )
continue;
send_to_char("You have been teleported!\n\r",group);
act("$n vanishes!", group, NULL, NULL, TO_ROOM );
char_from_room(group);
char_to_room(group, ch->in_room);
act("$n slowly fades into existence.", group, NULL, NULL, TO_ROOM);
do_look(group, "auto");
}
}
return;
}
void spell_strength( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
AFFECT_DATA af;
if(is_affected(ch,sn))
{
send_to_char("You are as sure of your faith as you will ever get.\n\r",ch);
return;
}
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.duration = ch->level*2;
af.location = 0;
af.modifier = 0;
af.bitvector = RES_HOLY;
af.level = level;
af.type = sn;
affect_to_char(ch,&af);
send_to_char("You fast for a period of time, building up your absolute faith in the strength of your Deity.\n\r",ch);
act("$n meditates for a period of time, building up $s faith in $s Deity.",ch,0,0,TO_ROOM);
}
/*
void spell_soften( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if(is_affected(victim,sn))
{
send_to_char("They are already softened.\n\r",ch);
ch->mana-=30;
WAIT_STATE(ch,PULSE_VIOLENCE*2);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.type = sn;
af.level = level;
af.location = APPLY_NONE;
af.aftype = AFT_SPELL;
af.affect_list_msg = str_dup("increases damage received by 30%");
af.modifier = 0;
af.duration = 1;
af.bitvector = 0;
affect_to_char(victim,&af);
act("$n looks frail.",victim,0,0,TO_ROOM);
send_to_char("You feel more frail.\n\r",victim);
}
*/
void spell_duo_dimension(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
AFFECT_DATA af;
int sn_fog, sn_fire, sn_dew;
sn_fog = skill_lookup("faerie fog");
sn_fire = skill_lookup("faerie fire");
sn_dew = skill_lookup("dew");
if (is_affected(ch,sn_fog) || is_affected(ch,sn_fire))
{
send_to_char("You are glowing too much for duo dimension.\n\r",ch);
return;
}
if (is_affected(ch,sn_dew))
{
send_to_char("You cannot step out of the dimension while covered in dew.\n\r",ch);
return;
}
act("You blink and $n is gone.",ch,0,0,TO_ROOM);
send_to_char("You lose a dimension and disappear from view.\n\r",ch);
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = gsn_duo;
af.level = level;
af.modifier = 0;
af.bitvector = 0;
af.affect_list_msg = str_dup("grants improved invisibility");
af.duration = (level/5);
af.location = 0;
affect_to_char(ch,&af);
return;
}
bool fumble_obj( CHAR_DATA *victim, OBJ_DATA *obj_drop, int level, bool drop )
{
if ( drop )
{
if ( !can_drop_obj( victim, obj_drop ) )
return FALSE;
}
else
{
if ( IS_OBJ_STAT( obj_drop, ITEM_NOREMOVE ) )
return FALSE;
}
if ( saves_spell( level, victim, DAM_NONE ) )
{
act( "You nearly $T $p, but manage to keep your grip.",
victim, obj_drop, drop ? "drop" : "lose hold of", TO_CHAR );
act( "$n nearly $T $p, but manages to keep $s grip.",
victim, obj_drop, drop ? "drops" : "loses hold of", TO_ROOM );
return FALSE;
}
if ( drop )
{
obj_from_char( obj_drop );
obj_to_room( obj_drop, victim->in_room );
}
else
{
unequip_char( victim, obj_drop );
}
act( "You fumble and $T $p!",
victim, obj_drop, drop ? "drop" : "lose hold of", TO_CHAR );
act( "$n fumbles and $T $p!",
victim, obj_drop, drop ? "drops" : "loses hold of", TO_ROOM );
return TRUE;
}
void spell_fumble( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
OBJ_DATA *obj;
OBJ_DATA *obj_drop;
int carry;
int check;
int count;
int drop;
bool fumbled = FALSE;
if ( !IS_AWAKE( victim ) )
return;
carry = 0;
for ( obj = victim->carrying; obj; obj = obj->next_content )
carry++;
drop = carry - can_carry_n( victim ) + 5;
for ( check = 0; check < drop; check++ )
{
obj_drop = NULL;
count = 0;
for ( obj = victim->carrying; obj; obj = obj->next_content )
{
if ( obj->wear_loc == WEAR_NONE
&& number_range( 0, count++ ) == 0 )
obj_drop = obj;
}
if ( !obj_drop )
break;
fumbled = fumble_obj( victim, obj_drop, level, TRUE ) || fumbled;
}
if ( ( obj_drop = get_eq_char( victim, WEAR_HOLD ) ) )
fumbled = fumble_obj( victim, obj_drop, level, FALSE ) || fumbled;
if ( ( obj_drop = get_eq_char( victim, WEAR_LIGHT ) ) )
fumbled = fumble_obj( victim, obj_drop, level, FALSE ) || fumbled;
if ( ( obj_drop = get_eq_char( victim, WEAR_WIELD ) ) )
fumbled = fumble_obj( victim, obj_drop, level, FALSE ) || fumbled;
if ( !fumbled )
{
send_to_char( "You stumble momentarily, but quickly recover.\n\r",
victim );
act( "$n stumbles momentarily, but quickly recovers.",
victim, NULL, NULL, TO_ROOM );
}
return;
}
void spell_knock( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
char pick_obj[MAX_INPUT_LENGTH];
OBJ_DATA *obj;
int door;
obj = NULL;
target_name = one_argument(target_name, pick_obj);
if (pick_obj[0] == '\0')
{
send_to_char("What would you like to try to unlock?\n\r",ch);
return;
}
if ( (obj = get_obj_here( ch,pick_obj)) != NULL)
{
if (obj->item_type != ITEM_CONTAINER)
{
send_to_char("That's not a container.\n\r",ch);
return;
}
if (!IS_SET(obj->value[1], CONT_CLOSED))
{
send_to_char( "It's not closed.\n\r",ch);
return;
}
if ( obj->value[2] < 0)
{
send_to_char( "It can't be unlocked.\n\r",ch);
return;
}
if ( !IS_SET(obj->value[1], CONT_LOCKED))
{
send_to_char( "It's already unlocked.\n\r",ch);
return;
}
if ( IS_SET(obj->value[1], CONT_PICKPROOF))
{
send_to_char( "Spell failed.\n\r",ch);
return;
}
REMOVE_BIT(obj->value[1], CONT_LOCKED);
send_to_char( "*Click*\n\r",ch);
return;
}
if ( ( door = find_door( ch, pick_obj) ) >= 0)
{
ROOM_INDEX_DATA *to_room;
EXIT_DATA *pexit;
EXIT_DATA *pexit_rev;
pexit = ch->in_room->exit[door];
if ( !IS_SET(pexit->exit_info, EX_CLOSED))
{
send_to_char( "It's not closed.\n\r",ch);
return;
}
if ( pexit->key < 0 && !IS_IMMORTAL(ch))
{
send_to_char("That lock can't be opened.\n\r",ch);
return;
}
if ( !IS_SET(pexit->exit_info, EX_LOCKED))
{
send_to_char("It's already unlocked.\n\r",ch);
return;
}
if ( IS_SET(pexit->exit_info, EX_PICKPROOF) && !IS_IMMORTAL(ch))
{
send_to_char("Spell failed.\n\r",ch);
return;
}
REMOVE_BIT(pexit->exit_info, EX_LOCKED);
send_to_char("*Click*\n\r",ch);
/* pick lock on other side of door as well */
if ( ( to_room = pexit->u1.to_room ) != NULL
&& ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL
&& pexit_rev->u1.to_room == ch->in_room)
{
REMOVE_BIT( pexit_rev->exit_info, EX_LOCKED);
}
}
return;
}
void spell_protection(int sn,int level,CHAR_DATA *ch,void *vo, int target)
{
AFFECT_DATA af;
if(is_affected(ch,gsn_protection))
return send_to_char("You are already protected.\n\r",ch);
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = get_spell_aftype(ch);
af.type = gsn_protection;
af.level = level;
af.duration = 24;
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char( ch, &af );
send_to_char( "You feel protected.\n\r", ch);
return;
}
void spell_prismatic_spray( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
AFFECT_DATA af;
CHAR_DATA *victim = (CHAR_DATA *) vo;
int i;
int type = 0;
if (ch->fighting)
{
int dam = dice(level, 6 + (ch->level > 30) + (ch->level > 40));
victim = ch->fighting;
if (check_spellcraft(ch,sn))
dam = spellcraft_dam(level, 13);
else
dam = dice(level,13);
if ( saves_spell( level, victim, DAM_OTHER ) )
dam /= 2;
i = number_range(1, 8);
switch(i)
{
case 1: type = DAM_OTHER;
send_to_char("A rainbow of colors shoots out from your hand.\n\r",ch);
act("A rainbow of colors shoots out from $n's hand.",ch,NULL,victim,TO_ROOM);
act("A red beam of light hits $N!",ch,NULL,victim,TO_ROOM);
act("A red beam of light hits you!",ch,NULL,victim,TO_VICT);
act("A red beam of light hits $N!",ch,NULL,victim,TO_CHAR);
damage_old(ch, victim, number_range(100,135), sn, type, TRUE);
break;
case 2: type = DAM_OTHER;
send_to_char("A rainbow of colors shoots out from your hand.\n\r",ch);
act("A rainbow of colors shoots out from $n's hand.", ch, NULL,victim,TO_ROOM);
act("A orange beam of light hits $N!",ch,NULL,victim,TO_ROOM);
act("A orange beam of light hits you!",ch,NULL,victim,TO_VICT);
act("A orange beam of light hits $N!",ch,NULL,victim,TO_CHAR);
damage_old(ch, victim, number_range(160,250), sn, type, TRUE);
break;
case 3: type = DAM_OTHER;
send_to_char("A rainbow of colors shoots out from your hand.\n\r",ch);
act("A rainbow of colors shoots out from $n's hand.", ch, NULL,victim,TO_ROOM);
act("A yellow beam of light hits $N!",ch,NULL,victim,TO_ROOM);
act("A yellow beam of light hits you!",ch,NULL,victim,TO_VICT);
act("A yellow beam of light hits $N!",ch,NULL,victim,TO_CHAR);
damage_old(ch, victim, number_range(250,330), sn, type, TRUE);
break;
case 4: type = DAM_OTHER;
send_to_char("A rainbow of colors shoots out from your hand.\n\r",ch);
act("A rainbow of colors shoots out from $n's hand.", ch, NULL,victim,TO_ROOM);
act("A green beam of light hits $N!",ch,NULL,victim,TO_ROOM);
act("A green beam of light hits you!",ch,NULL,victim,TO_VICT);
act("A green beam of light hits $N!",ch,NULL,victim,TO_CHAR);
spell_poison( gsn_poison, ch->level, ch, victim,TARGET_CHAR);
damage_old(ch, victim, dam, sn, type, TRUE);
break;
case 5: type = DAM_OTHER;
send_to_char("A rainbow of colors shoots out from your hand.\n\r",ch);
act("A rainbow of colors shoots out from $n's hand.", ch, NULL,victim,TO_ROOM);
act("A white beam of light hits $N!",ch,NULL,victim,TO_ROOM);
act("A white beam of light hits you!",ch,NULL,victim,TO_VICT);
act("A white beam of light hits $N!",ch,NULL,victim,TO_CHAR);
spell_blindness( gsn_blindness, ch->level, ch, victim,TARGET_CHAR);
damage_old(ch, victim, dam, sn, type, TRUE);
break;
case 6: type = DAM_OTHER;
send_to_char("A rainbow of colors shoots out from your hand.\n\r",ch);
act("A rainbow of colors shoots out from $n's hand.", ch, NULL,victim,TO_ROOM);
act("A blue beam of light hits $N!",ch,NULL,victim,TO_ROOM);
act("A blue beam of light hits you!",ch,NULL,victim,TO_VICT);
act("A blue beam of light hits $N!",ch,NULL,victim,TO_CHAR);
init_affect(&af);
af.where = TO_AFFECTS;
af.type = sn;
af.aftype = AFT_SPELL;
af.level = ch->level;
af.location = APPLY_SAVING_PETRI;
af.modifier = 60;
affect_to_char( victim,&af );
damage_old(ch, victim, dam, sn, type, TRUE);
break;
case 7: type = DAM_OTHER;
send_to_char("A rainbow of colors shoots out from your hand.\n\r",ch);
act("A rainbow of colors shoots out from $n's hand.", ch, NULL,victim,TO_ROOM);
act("A indigo beam of light hits $N!",ch,NULL,victim,TO_ROOM);
act("A indigo beam of light hits you!",ch,NULL,victim,TO_VICT);
act("A indigo beam of light hits $N!",ch,NULL,victim,TO_CHAR);
damage_old(ch, victim, number_range(330, 380), sn, type, TRUE);
break;
case 8: type = DAM_OTHER;
send_to_char("A rainbow of colors shoots out from your hand.\n\r",ch);
act("A rainbow of colors shoots out from $n's hand.", ch, NULL,victim,TO_ROOM);
act("A violet beam of light hits $N!",ch,NULL,victim,TO_ROOM);
act("A violet beam of light hits you!",ch,NULL,victim,TO_VICT);
act("A violet beam of light hits $N!",ch,NULL,victim,TO_CHAR);
damage_old(ch, victim, number_range(400, 600), sn, type, TRUE);
break;
}
return;
}
}
void spell_haunting(int sn,int level,CHAR_DATA *ch,void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
int dam;
if (victim == ch)
{
send_to_char("Now thats just stupid talk.\n\r",ch);
return;
}
if (saves_spell(level+15, victim,DAM_NEGATIVE))
{
send_to_char("You failed to invoke haunting thoughts.\n\r",ch);
return;
}
dam = dice( level/3, 7 );
damage_old( ch, victim, dam, gsn_haunting,DAM_MENTAL,TRUE);
act("$n narrows $s eyes and plagues $N's mind with haunting images!",ch,NULL,victim,TO_NOTVICT);
act("$n plagues your mind with haunting images!",ch,NULL,victim,TO_VICT);
act("You plague $N's mind with haunting images!",ch,NULL,victim,TO_CHAR);
if (!is_affected(victim,gsn_haunting))
{
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_MALADY;
af.type = gsn_haunting;
af.level = level;
af.duration = 10;
af.location = 0;
af.modifier = 0;
af.owner_name = str_dup(ch->original_name);
af.affect_list_msg = str_dup("induces painful, haunting thoughts");
af.bitvector = 0;
affect_to_char( victim,&af );
af.location = APPLY_SAVES;
af.modifier = 10+number_range(5,12);
affect_to_char( victim,&af );
}
return;
}
void spell_spire_of_flames( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam = level*2 + dice( 10, 40 );
if (saves_spell (level, victim, DAM_FIRE))
dam /= 2;
if (get_skill(ch,gsn_spire_of_flames) == 100)
dam *= 1.2;
act("You create a swirling column of incinerating flames and unleash it flying towards $N.", ch,NULL,victim,TO_CHAR );
act("$n creates a swirling column of incinerating flames and unleash it flying towards you.",ch,NULL,NULL,TO_ROOM);
damage_new(ch,victim,dam,TYPE_UNDEFINED,DAM_FIRE,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"spire of flames");
}
void spell_worldbind(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if(is_affected(victim,sn))
{
send_to_char("They are already bound to this world.\n\r",ch);
return;
}
if(saves_spell(level-2,victim,DAM_NEGATIVE))
{
act("You failed to bind $N to this world.",ch,0,victim,TO_CHAR);
return;
}
act("You sever $N's ties to the spiritual world!",ch,0,victim,TO_CHAR);
act("$n severs $N's ties to the spiritual world!",ch,0,victim,TO_NOTVICT);
act_new("$n severs your ties to the spiritual world!",ch,0,victim,TO_VICT,POS_DEAD);
init_affect(&af);
af.where = TO_AFFECTS;
af.type = sn;
af.aftype = AFT_SPELL;
af.level = level;
af.duration = 3;
af.affect_list_msg = str_dup("restricts the ability to commune");
af.location = 0;
af.modifier = 0;
af.bitvector = 0;
affect_to_char(victim,&af);
}
void spell_icy_shards( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
int num;
if (check_spellcraft(ch,sn))
dam = spellcraft_dam(level/2,11);
else
dam = dice( level/2, 10 );
if (saves_spell(level,victim,DAM_COLD) )
dam /= 2;
act("$n releases an orb of icy cold shards towards $N!", ch,NULL,victim,TO_ROOM);
act("You release an orb of icy cold shards towards $N!", ch,NULL,victim,TO_CHAR);
act("$n releases an orb of icy cold shards towards you!", ch,NULL,victim,TO_VICT);
for (num = 0; num < 6; num++)
{
if (is_safe(victim, ch))
return;
if (number_percent() < 100 - num*5)
damage_new(ch,victim,dam,TYPE_UNDEFINED,DAM_COLD,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"icy shards");
dam = dam - dam/5;
}
return;
}
void spell_sunray(int sn,int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam=100;
AFFECT_DATA af;
if(ch->in_room->sector_type==SECT_INSIDE)
{
send_to_char("You can't see the sun to use it to burn people.\n\r",ch);
return;
}
if(weather_info.sunlight==SUN_DARK)
dam=65;
if(weather_info.sunlight==SUN_RISE)
dam=110;
if(weather_info.sunlight==SUN_LIGHT)
dam=150;
if(weather_info.sunlight==SUN_SET)
dam=100;
if(weather_info.sky==SKY_CLOUDLESS)
dam*=1.7;
if(weather_info.sky==SKY_CLOUDY)
dam*=1;
if(weather_info.sky==SKY_RAINING)
dam*=.8;
if(weather_info.sky==SKY_LIGHTNING)
dam*=1;
//Fuzz it up.
act("$n burns $N with the light of the sun!",ch,0,victim,TO_NOTVICT);
act("$n burns you with the light of the sun!",ch,0,victim,TO_VICT);
act("You burn $N with the light of the sun!",ch,0,victim,TO_CHAR);
if(dam>120 && number_percent()>80)
{
act("$n appears to be blinded by the sun in $s eyes!",victim,0,0,TO_ROOM);
act("You are blinded by the sun in your eyes!",victim,0,0,TO_CHAR);
init_affect(&af);
af.where = TO_AFFECTS;
af.type = sn;
af.aftype = AFT_COMMUNE;
af.duration = level/12;
af.location = APPLY_HITROLL;
af.modifier = -6;
af.level = level;
af.bitvector = AFF_BLIND;
affect_to_char(victim,&af);
af.bitvector = 0;
af.location = 0;
af.modifier = 0;
af.affect_list_msg = str_dup("induces blindness");
}
damage_old(ch,victim,dam,sn,DAM_LIGHT,TRUE);
}
void spell_vampiric_touch(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
int dam;
if (victim == ch)
return;
dam=number_range(level*3,level*6);
if (saves_spell(level,victim,DAM_NEGATIVE))
dam*=.6;
damage(ch,victim,dam,gsn_vampiric_touch,DAM_NEGATIVE,TRUE);
if (!IS_SET(victim->imm_flags,IMM_NEGATIVE))
ch->hit+=dam;
return;
}
void spell_create_fire_elemental(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = get_char_world(ch, target_name);
CHAR_DATA *elemental;
n_logf("Spell_create_fire_elemental: target name '%s'", target_name);
if(!str_cmp(target_name,""))
return send_to_char("You must provide a target for the fire elemental.\n\r",ch);
if(!victim)
{
send_to_char("They aren't here.\n\r",ch);
return;
}
elemental = create_mobile( get_mob_index(28025));
if(!elemental)
return;
char_to_room(elemental,victim->in_room);
act("You conjure forth a greater fire elemental to destroy $N!",ch,0,victim,TO_CHAR);
act("A greater fire elemental arrives in a pillar of searing flames!",victim,0,0,TO_ALL);
elemental->hunting = victim;
multi_hit(elemental,victim,TYPE_UNDEFINED);
}
void spell_enlarge(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if(is_affected(victim,gsn_enlarge) || victim->size>=SIZE_GIANT)
{
if(victim!=ch)
send_to_char("They are already enlarged.\n\r",ch);
if(victim==ch)
send_to_char("You are already enlarged.\n\r",ch);
return;
}
if (!is_same_group(ch, victim))
return send_to_char("You can only use this spell on groupmates.\n\r", ch);
if(is_affected(victim,gsn_reduce))
{
send_to_char("You grow to your normal size.\n\r",ch);
act("$n grows to $s normal size!",victim,0,ch,TO_ROOM);
affect_strip(victim,gsn_reduce);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = gsn_enlarge;
af.level = level;
af.duration = level/8;
af.location = APPLY_SIZE;
af.modifier = 1;
af.affect_list_msg = str_dup("increases size by 1");
af.bitvector = 0;
affect_to_char(victim,&af);
af.aftype = AFT_INVIS;
af.location = APPLY_DAM_MOD;
af.modifier = 20;
affect_to_char(victim,&af);
send_to_char("Your entire body and gear rapidly grow in size, but you feel somewhat more frail afterward.\n\r",victim);
act("$n suddenly swells in all directions, expanding to half $s normal size!",victim,0,0,TO_ROOM);
return;
}
void spell_reduce(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if(is_affected(victim,gsn_reduce) || victim->size<=SIZE_TINY)
{
if(victim!=ch)
send_to_char("They are already reduced.\n\r",ch);
if(victim==ch)
send_to_char("You are already reduced.\n\r",ch);
return;
}
if (!is_same_group(ch, victim))
return send_to_char("You can only use this spell on groupmates.\n\r", ch);
if(is_affected(victim,gsn_enlarge))
{
send_to_char("You shrink down to your normal size.\n\r",ch);
act("$n shrinks down to $s normal size.",victim,0,ch,TO_ROOM);
affect_strip(victim,gsn_enlarge);
return;
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = gsn_reduce;
af.level = level;
af.duration = level/8;
af.location = APPLY_SIZE;
af.modifier = -1;
af.affect_list_msg = str_dup("decreases size by 1");
af.bitvector = 0;
affect_to_char(victim,&af);
af.aftype = AFT_INVIS;
af.location = APPLY_DAM_MOD;
af.modifier = -20;
affect_to_char(victim,&af);
send_to_char("Your entire body suddenly contracts, leaving you significantly smaller but somehow sturdier.\n\r",victim);
act("$n rapidly shrinks to two-thirds of $s original size!",victim,0,0,TO_ROOM);
return;
}
void spell_shield_of_purity(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
if (is_affected(ch,gsn_shield_of_purity) || is_affected(ch,gsn_shield_of_redemption) || is_affected(ch,gsn_shield_of_justice) || is_affected(ch,gsn_shield_of_truth))
return send_to_char("Your god already guides your shield.\n\r",ch);
if (get_eq_char(ch,WEAR_SHIELD) == NULL)
return send_to_char("You must be wearing a shield to call upon the power of your god.\n\r",ch);
init_affect(&af);
af.where = TO_AFFECTS;
af.duration = 6;
af.level = level;
af.aftype = AFT_COMMUNE;
af.type = gsn_shield_of_purity;
af.affect_list_msg = str_dup("channels the power of Purity through your shield");
affect_to_char(ch,&af);
return send_to_char("Your god guides your shield, protecting you from harm.\n\r",ch);
}
void spell_shield_of_redemption(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
if (is_affected(ch,gsn_shield_of_purity) || is_affected(ch,gsn_shield_of_redemption) || is_affected(ch,gsn_shield_of_justice) || is_affected(ch,gsn_shield_of_truth))
return send_to_char("Your god already guides your shield.\n\r",ch);
if (get_eq_char(ch,WEAR_SHIELD) == NULL)
return send_to_char("You must be wearing a shield to call upon the power of your god.\n\r",ch);
init_affect(&af);
af.where = TO_AFFECTS;
af.duration = 6;
af.level = level;
af.aftype = AFT_COMMUNE;
af.affect_list_msg = str_dup("channels the power of Redemption through your shield");
af.type = gsn_shield_of_redemption;
affect_to_char(ch, &af);
return send_to_char("Your god channels his energy through your shield to strike down the unfaithful.\n\r",ch);
}
void spell_shield_of_justice(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
if (is_affected(ch,gsn_shield_of_purity) || is_affected(ch,gsn_shield_of_redemption) || is_affected(ch,gsn_shield_of_justice) || is_affected(ch,gsn_shield_of_truth))
return send_to_char("Your god already guides your shield.\n\r",ch);
if (get_eq_char(ch,WEAR_SHIELD) == NULL)
return send_to_char("You must be wearing a shield to call upon the power of your god.\n\r",ch);
init_affect(&af);
af.where = TO_AFFECTS;
af.duration = 6;
af.level = level;
af.aftype = AFT_COMMUNE;
af.affect_list_msg = str_dup("channels the power of Justice through your shield");
af.type = gsn_shield_of_justice;
affect_to_char(ch, &af);
return send_to_char("Your god channels his energy through your shield to crush the unholy.\n\r",ch);
}
void spell_shield_of_truth(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
if (is_affected(ch,gsn_shield_of_purity) || is_affected(ch,gsn_shield_of_redemption) || is_affected(ch,gsn_shield_of_justice) || is_affected(ch,gsn_shield_of_truth))
return send_to_char("Your god already guides your shield.\n\r",ch);
if (get_eq_char(ch,WEAR_SHIELD) == NULL)
return send_to_char("You must be wearing a shield to call upon the power of your god.\n\r",ch);
init_affect(&af);
af.where = TO_AFFECTS;
af.duration = 6;
af.level = level;
af.affect_list_msg = str_dup("channels the power of Truth through your shield");
af.aftype = AFT_COMMUNE;
af.type = gsn_shield_of_truth;
affect_to_char(ch, &af);
return send_to_char("Your god channels his energy through your shield to protect you.\n\r",ch);
}
void spell_water_breathing(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
AFFECT_DATA af;
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (is_affected(ch,gsn_water_breathing))
return send_to_char("You can already breathe underwater.\n\r",ch);
if (ch->class==class_lookup("druid") && victim != ch)
return send_to_char("You cannot commune this supplication on another.\n\r",ch);
if (ch->class==class_lookup("elementalist") && victim != ch)
return send_to_char("You cannot cast this spell on another.\n\r",ch);
init_affect(&af);
if (ch->class==class_lookup("druid") || ch->class==class_lookup("healer"))
af.aftype = AFT_COMMUNE;
else
af.aftype = AFT_SPELL;
af.duration = 9;
af.level = level;
af.affect_list_msg = str_dup("allows you to breath underwater");
af.type = gsn_water_breathing;
af.where = TO_AFFECTS;
affect_to_char(victim, &af);
if (is_affected(ch,gsn_drowning))
affect_strip(ch,gsn_drowning);
if (ch != victim)
act("$N is able to breathe water as $E would air.\n\r",ch,0,victim,TO_CHAR);
return send_to_char("You feel able to breathe water as you would air.\n\r",victim);
}
void spell_mana_disruption(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim;
char arg1[MIL], arg2[MIL];
target_name = one_argument(target_name,arg1);
one_argument(target_name,arg2);
if ((victim = get_char_room(ch,arg1)) == NULL)
return send_to_char("They aren't here.\n\r",ch);
if (arg2[0] == '\0')
return send_to_char("How much mana will you channel?\n\r",ch);
int manaChannel = atoi(arg2);
if (manaChannel <= 0)
return send_to_char("You must channel more than 0 mana!\n\r",ch);
if (ch->mana < manaChannel)
return send_to_char("You do not have that much mana to channel.\n\r",ch);
act("You channel your mana through $N, disrupting his mind!",ch,0,victim,TO_CHAR);
act("$n channels $s mana through you, disrupting your mind!",ch,0,victim,TO_VICT);
act("$n channels $s mana through $N, disrupting $S mind!",ch,0,victim,TO_NOTVICT);
act("You lose control of your mental faculties and the mana runs rampant through your body!",ch,0,victim,TO_VICT);
act("$N loses control of $S mental faculties and the mana runs rampant through $S body!",ch,0,victim,TO_CHAR);
act("$N loses control of $S mental faculties and the mana runs rampant through $S body!",ch,0,victim,TO_NOTVICT);
victim->mana -= manaChannel * 3 / 4;
ch->mana -= manaChannel;
if (ch->mana < 0)
ch->mana = 0;
if (victim->mana < 0)
victim->mana = 0;
damage_new(ch,victim,manaChannel * 3 / 4,TYPE_UNDEFINED,DAM_TRUESTRIKE,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"mana disruption");
return;
}
void spell_mana_shield(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (ch != victim)
return send_to_char("You cannot cast that on another.\n\r",ch);
if (is_affected(ch,skill_lookup("mental exhaustion")))
return send_to_char("Your mind is not yet ready to conjure another mana shield.\n\r",ch);
AFFECT_DATA af;
init_affect(&af);
af.aftype = AFT_SPELL;
af.type = skill_lookup("mana shield");
af.duration = ch->level / 5;
af.level = ch->level;
af.affect_list_msg = str_dup("substitutes mana damage for hp damage");
affect_to_char(ch,&af);
act("You use your mana as a shield from attacks.",ch,0,0,TO_CHAR);
act("$n concentrates and the air around $m quivers slightly.",ch,0,0,TO_ROOM);
return;
}
void spell_doublecast(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
char spell1[MIL], spell2[MIL], target1[MIL], target2[MIL], spellOnePass[MSL], spellTwoPass[MSL];
char *spellOne, *spellTwo, *targetOne, *targetTwo;
spellOne = one_argument(target_name, spell1);
targetOne = one_argument(spellOne,target1);
spellTwo = one_argument(targetOne, spell2);
targetTwo = one_argument(spellTwo, target2);
act("Drawing an arcane rune in the air, you channel your mana to cast two spells!",ch,0,0,TO_CHAR);
act("Drawing an arcane rune in the air, $n channels $s mana to cast two spells!",ch,0,0,TO_ROOM);
if (spell1[0] == '\0')
return send_to_char("You need to specify a first spell to doublecast.\n\r",ch);
if (target1[0] == '\0')
return send_to_char("Cast the first spell on whom?\n\r",ch);
if (spell2[0] == '\0')
return send_to_char("You need to specify a second spell to doublecast.\n\r",ch);
if (target2[0] == '\0')
return send_to_char("Cast the second spell on whom?\n\r",ch);
sprintf(spellOnePass, "'%s' %s", spell1, target1);
do_cast(ch,spellOnePass);
sprintf(spellTwoPass, "'%s' %s", spell2, target2);
do_cast(ch,spellTwoPass);
return;
}
void spell_group_sanctuary(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *gch;
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if (((IS_NPC(ch) && IS_NPC(gch)) ||
(!IS_NPC(ch) && !IS_NPC(gch))) && is_same_group(ch,gch) && !IS_AFFECTED(gch,AFF_SANCTUARY)
&& !is_affected(gch,skill_lookup("sanctuary")))
{
spell_sanctuary(skill_lookup("sanctuary"),level,ch,(void *) gch,TARGET_CHAR);
}
}
return;
}
void spell_group_recall(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *gch;
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if (is_same_group(ch,gch) && gch != ch)
{
spell_word_of_recall(skill_lookup("word of recall"),level,ch,(void *) gch,TARGET_CHAR);
}
}
spell_word_of_recall(skill_lookup("word of recall"),level,ch,(void *) ch,TARGET_CHAR);
return;
}
/*Pretty much total copy and paste of venueport spell.*/
void spell_group_gate(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim;
CHAR_DATA *group;
CHAR_DATA *arrival;
CHAR_DATA *g_next;
ROOM_INDEX_DATA *VENUEPORT;
CHAR_DATA *last_to_venue;
int numb;
char buf[MSL];
if (affect_find(ch->affected,gsn_insect_swarm) != NULL)
{
send_to_char( "You attempt to transport yourself to safety but lose your concentration as you are bitten by yet another insect.\n\r", ch);
return;
}
last_to_venue = ch;
victim = get_char_world( ch, target_name );
if ( victim == NULL
|| victim == ch
|| victim->in_room == NULL
|| IS_SET(ch->in_room->room_flags, ROOM_NO_RECALL)
|| !can_see_room(ch,victim->in_room)
|| (victim->in_room->cabal != 0 && victim->in_room->cabal != CABAL_ARCANA)
|| ch->in_room->guild != 0
|| victim->in_room->guild != 0
|| (IS_NPC(victim) && IS_SET(victim->imm_flags,IMM_SUMMON))
|| IS_SET(victim->in_room->room_flags, ROOM_SAFE)
|| IS_SET(victim->in_room->room_flags, ROOM_PRIVATE)
|| IS_SET(victim->in_room->room_flags, ROOM_SOLITARY)
|| IS_SET(victim->in_room->room_flags, ROOM_NO_RECALL)
|| victim->level >= level + 9
|| (saves_spell( level, victim,DAM_OTHER) )
|| (!IS_NPC(victim) && !can_pk(ch,victim) && IS_SET(victim->act,PLR_NOSUMMON)))
{
send_to_char( "You failed.\n\r", ch );
return;
}
if (victim->in_room == ch->in_room)
{
send_to_char("You are already there.\n\r",ch);
return;
}
VENUEPORT = get_room_index(ROOM_VNUM_VENUEPORT);
numb = 1;
for (group = ch->in_room->people; group != NULL; group = g_next)
{
g_next = group->next_in_room;
if (!is_same_group(group,ch) || (group->fighting != NULL) )
continue;
if (group == ch )
continue;
numb++;
affect_strip(group,gsn_ambush);
sprintf(buf,"%s closes his eyes momentarily and a massive tear in space explodes into the room and consumes you!\n\r", !IS_NPC(ch) ? ch->name : ch->short_descr);
send_to_char(buf,group);
send_to_char("Your stomach lurches as the gate disappears, leaving you somewhere else.\n\r",group);
char_from_room(group);
char_to_room(group,victim->in_room);
act("$n arrives through a gate in the fabric of reality.",group,NULL,NULL,TO_ROOM);
char_from_room(group);
char_to_room(group, VENUEPORT);
last_to_venue = group;
if (is_affected(group,gsn_earthfade))
{
affect_strip(group, gsn_earthfade);
}
}
act("$n closes his eyes and a massive tear in space explodes into the room and consumes $m!",ch,NULL,NULL,TO_ROOM);
send_to_char("You close your eyes momentarily and a massive tear in space explodes into the room and consumes you!\n\r",ch);
send_to_char("Your stomach lurches as the gate disappears, leaving you somewhere else.\n\r",ch);
char_from_room(ch);
char_to_room(ch,victim->in_room);
act("$n arrives through a gate in the fabric of reality.",ch,NULL,NULL,TO_ROOM);
un_earthfade(ch,NULL);
if (last_to_venue == ch)
{
do_look(ch,"auto");
return;
}
for (arrival = last_to_venue->in_room->people; arrival != NULL; arrival = g_next)
{
g_next = arrival->next_in_room;
if (arrival == ch)
continue;
if ((is_same_group(arrival,ch)) && (arrival != ch) )
{
char_from_room(arrival);
char_to_room(arrival,ch->in_room);
}
}
for (arrival = ch->in_room->people; arrival != NULL; arrival = arrival->next_in_room)
{
do_look(arrival,"auto");
if (--numb == 0)
break;
}
return;
}
void spell_coalesce_resistance(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,skill_lookup("coalesce resistance")))
return send_to_char("They are already resistant.\n\r",ch);
init_affect(&af);
af.where = TO_RESIST;
af.aftype = AFT_COMMUNE;
af.type = skill_lookup("coalesce resistance");
af.duration = ch->level / 13;
af.bitvector = RES_FIRE;
affect_to_char(victim,&af);
af.bitvector = RES_COLD;
affect_to_char(victim,&af);
af.bitvector = RES_LIGHTNING;
affect_to_char(victim,&af);
af.bitvector = RES_MENTAL;
affect_to_char(victim,&af);
af.bitvector = RES_ACID;
affect_to_char(victim,&af);
af.bitvector = RES_NEGATIVE;
affect_to_char(victim,&af);
af.bitvector = RES_MAGIC;
affect_to_char(victim,&af);
af.bitvector = RES_WEAPON|RES_BASH|RES_PIERCE|RES_SLASH;
affect_to_char(victim,&af);
if (ch != victim) {
act("You feel much more resistant as $n's god grants you their favor.",ch,0,victim,TO_VICT);
act("Your god smiles upon $N and grants $M their favor.",ch,0,victim,TO_CHAR);
}
else
act("You feel much more resistant as your god grants you their favor.",ch,0,victim,TO_CHAR);
act("$N looks much more resistant to damage.",ch,0,victim,TO_ROOM);
return;
}
void spell_bulwark_of_blades(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (ch != victim)
return send_to_char("You cannot cast that on another.\n\r",ch);
if (is_affected(ch, skill_lookup("bulwark of blades")))
return send_to_char("You are already surrounding by a blade barrier.\n\r",ch);
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_COMMUNE;
af.type = skill_lookup("bulwark of blades");
af.duration = ch->level / 8;
af.affect_list_msg = str_dup("causes considerable harm to close-range attackers");
affect_to_char(ch,&af);
act("Blades fade into existence and form a protective barrier around you.",ch,0,0,TO_CHAR);
act("A barrier of blades fades into existence around $n.",ch,0,0,TO_ROOM);
return;
}
void spell_resurrect(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *search;
OBJ_DATA *corpse;
char *obj_name, *dead_name;
AFFECT_DATA res;
char buf[MSL];
if (is_affected(ch,skill_lookup("resurrect timer")))
return send_to_char("You are not yet able to resurrect the dead.\n\r",ch);
obj_name = str_dup(target_name);
corpse = get_obj_here(ch, obj_name);
if (!corpse)
return send_to_char("That corpse is not here.\n\r",ch);
dead_name = corpse->owner;
if (!dead_name) return send_to_char("They don't seem to exist.\n\r",ch);
if (corpse->timer < 2) return send_to_char("That corpse will decay long before the ritual is complete.\n\r",ch);
for (search = char_list; search != NULL; search = search->next)
{
if (!IS_NPC(search) && !str_cmp(dead_name,search->original_name)) {
if (search == ch) return send_to_char("Resurrect yourself?\n\r",ch);
if (search->ghost == 0) return send_to_char("They have no connection to the afterlife.\n\r",ch);
if (search->ghost < 2) return send_to_char("Their connection to the afterlife grows too tenuous.\n\r",ch);
send_to_char("You feel a gentle tug at your soul...\n\r",search);
act("You begin a ritual to bring $N back from the dead.",ch,0,search,TO_CHAR);
act("$n begins a ritual to bring $N back from the dead.",ch,0,search,TO_ROOM);
sprintf(buf,"resurrecting %s",search->original_name);
init_affect(&res);
res.aftype = AFT_COMMUNE;
res.level = ch->level;
res.type = skill_lookup("resurrect");
res.owner_name = str_dup(search->original_name);
res.affect_list_msg = str_dup(buf);
res.duration = 1;
affect_to_char(ch,&res);
res.type = skill_lookup("resurrect timer");
res.duration = 60;
res.affect_list_msg = str_dup("prevents usage of resurrect");
affect_to_char(ch,&res);
return;
}
}
send_to_char("They don't seem to exist.\n\r",ch);
return;
}
void spell_divine_transferrance(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
char buf[MSL];
if (ch == victim) return send_to_char("You can only cast that on others.\n\r",ch);
if (is_affected(ch, skill_lookup("divine transferrance timer")))
return send_to_char("You are unable to form a bond yet.\n\r",ch );
if (is_affected(victim,skill_lookup("divine transferrer")))
return send_to_char("They are already protected.\n\r",ch);
if (is_affected(ch,skill_lookup("divine transferree")))
return send_to_char("You are already using your faith to protect one individual.\n\r",ch);
sprintf(buf,"transfers half of all damage received to %s",ch->original_name);
init_affect(&af);
af.where = TO_AFFECTS;
af.type = skill_lookup("divine transferrer");
af.aftype = AFT_COMMUNE;
af.duration = ch->level / 10;
af.affect_list_msg = str_dup(buf);
af.name = str_dup("divine transferrance");
af.owner_name = str_dup(ch->original_name);
affect_to_char(victim,&af);
free_string(buf);
sprintf(buf,"receiving half of all damage taken by %s",victim->original_name);
af.type = skill_lookup("divine transferree");
af.affect_list_msg = str_dup(buf);
af.owner_name = str_dup(victim->original_name);
affect_to_char(ch,&af);
af.type = skill_lookup("divine transferrance timer");
af.name = str_dup("divine transferrance");
af.affect_list_msg = str_dup("prevents usage of divine transferrance");
af.duration = ch->level / 5;
affect_to_char(ch,&af);
act("Using your faith, you produce a bond between yourself and $N to share pain!",ch,0,victim,TO_CHAR);
act("Using $s faith, $n produces a bond between you to share pain!",ch,0,victim,TO_VICT);
act("Using $s faith, $n produces a bond between $mself and $N to share pain!",ch,0,victim,TO_NOTVICT);
return;
}
void spell_bastion_of_elements(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *victim = (CHAR_DATA *) vo;
if (is_affected(victim,skill_lookup("bastion of elements")))
return send_to_char("They are already protected by a bastion of elements.\n\r",ch);
AFFECT_DATA af;
init_affect(&af);
af.where = TO_AFFECTS;
af.type = skill_lookup("bastion of elements");
af.name = str_dup("bastion of elements");
af.duration = 8;
af.location = APPLY_DAM_MOD;
af.modifier = -18;
affect_to_char(victim,&af);
if (ch != victim)
act("$N is now protected by a bastion of elements.",ch,0,victim,TO_CHAR);
act("You are now protected by a bastion of elements.",ch,0,victim,TO_VICT);
act("$N is now protected by a bastion of elements.",ch,0,victim,TO_NOTVICT);
af.location = APPLY_NONE;
af.modifier = 0;
if (!is_affected(victim,skill_lookup("shield of flames"))) {
af.type = skill_lookup("shield of flames");
af.affect_list_msg = str_dup("grants immunity to fire and heat attacks");
affect_to_char(victim,&af);
if (ch != victim)
act("$N is surrounded by a shield of flames.",ch,0,victim,TO_CHAR);
act("You are surrounded by a shield of flames.",ch,0,victim,TO_VICT);
} else {
if (ch != victim)
act("$N is already surrounded by a shield of flames.",ch,0,victim,TO_CHAR);
act("You are already surrounded by a shield of flames.",ch,0,victim,TO_VICT);
}
if (!is_affected(victim,skill_lookup("shield of wind"))) {
af.type = skill_lookup("shield of wind");
af.affect_list_msg = str_dup("grants immunity to wind attacks");
affect_to_char(victim,&af);
if (ch != victim)
act("$N is surrounded by a shield of wind.",ch,0,victim,TO_CHAR);
act("You are surrounded by a shield of wind.",ch,0,victim,TO_VICT);
} else {
if (ch != victim)
act("$N is already surrounded by a shield of wind.",ch,0,victim,TO_CHAR);
act("You are already surrounded by a shield of wind.",ch,0,victim,TO_VICT);
}
if (!is_affected(victim,skill_lookup("shield of frost"))) {
af.type = skill_lookup("shield of frost");
af.affect_list_msg = str_dup("grants immunity to cold attacks");
affect_to_char(victim,&af);
if (ch != victim)
act("$N is surrounded by a shield of frost.",ch,0,victim,TO_CHAR);
act("You are surrounded by a shield of frost.",ch,0,victim,TO_VICT);
} else {
if (ch != victim)
act("$N is already surrounded by a shield of frost.",ch,0,victim,TO_CHAR);
act("You are already surrounded by a shield of frost.",ch,0,victim,TO_VICT);
}
if (!is_affected(victim,skill_lookup("shield of lightning"))) {
af.type = skill_lookup("shield of lightning");
af.affect_list_msg = str_dup("grants immunity to lightning attacks");
affect_to_char(victim,&af);
if (ch != victim)
act("$N is surrounded by a shield of lightning.",ch,0,victim,TO_CHAR);
act("You are surrounded by a shield of lightning.",ch,0,victim,TO_VICT);
} else {
if (ch != victim)
act("$N is already surrounded by a shield of lightning.",ch,0,victim,TO_CHAR);
act("You are already surrounded by a shield of lightning.",0,0,victim,TO_VICT);
}
if (!is_affected(victim,skill_lookup("shield of dust"))) {
af.type = skill_lookup("shield of dust");
af.affect_list_msg = str_dup("grants immunity to dust and dirt attacks");
affect_to_char(victim,&af);
if (ch != victim)
act("$N is surrounded by a shield of dust.",ch,0,victim,TO_CHAR);
act("You are surrounded by a shield of dust.",ch,0,victim,TO_VICT);
} else {
if (ch != victim)
act("$N is already surrounded by a shield of dust.",ch,0,victim,TO_CHAR);
act("You are already surrounded by a shield of dust.",ch,0,victim,TO_VICT);
}
if (!is_affected(victim,skill_lookup("shield of bubbles"))) {
af.type = skill_lookup("shield of bubbles");
af.affect_list_msg = str_dup("grants immunity to drowning attacks");
affect_to_char(victim,&af);
if (ch != victim)
act("$N is surrounded by a shield of bubbles.",ch,0,victim,TO_CHAR);
act("You are surrounded by a shield of bubbles.",ch,0,victim,TO_VICT);
} else {
if (ch != victim)
act("$N is already surrounded by a shield of bubbles.",ch,0,victim,TO_CHAR);
act("You are already surrounded by a shield of bubbles.",ch,0,victim,TO_VICT);
}
return;
}
void spell_maelstrom(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
if (is_affected(victim,skill_lookup("maelstrom"))) return send_to_char("They are already affected by the elemental maelstrom.\n\r",ch);
if (saves_spell(ch->level,victim,DAM_OTHER)) {
act("You resist the effects of $n's elemental maelstrom.",ch,0,victim,TO_VICT);
return send_to_char("They resisted the effects of your maelstrom.\n\r",ch);
}
act("You unleash an elemental maelstrom upon $N, leaving $M defenseless to the elements!",ch,0,victim,TO_CHAR);
act("$n unleashes an elemental maelstrom upon $N, leaving $M defenseless to the elements!",ch,0,victim,TO_NOTVICT);
act("$n unleashes an elemental maelstrom upon you, leaving you defenseless to the elements!",ch,0,victim,TO_VICT);
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_MALADY;
af.type = skill_lookup("maelstrom");
af.duration = 10;
af.affect_list_msg = str_dup("afflicted with a vulnerability to all elemental damage, bypassing immunities and resistances");
affect_to_char(victim,&af);
return;
}
void spell_shatter_armor(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
bool saved = FALSE;
if (is_affected(victim,skill_lookup("shatter armor")))
return act("$S armor is already shattered.",ch,0,victim,TO_CHAR);
if (saves_spell(ch->level,victim,DAM_PIERCE)) {
act("You partially resist $n's shatter armor spell!",ch,0,victim,TO_VICT);
act("$N partially resists your shatter armor spell!",ch,0,victim,TO_CHAR);
act("$N partially resists $n's shatter armor spell!",ch,0,victim,TO_NOTVICT);
saved = TRUE;
}
int modifier = (-9 * GET_AC(victim,AC_EXOTIC)) / 10;
if (modifier < 0)
modifier = -1 * modifier;
if (!saved) {
init_affect(&af);
af.where = TO_AFFECTS;
af.duration = 5;
af.type = skill_lookup("shatter armor");
af.location = APPLY_AC;
af.modifier = modifier;
affect_to_char(victim,&af);
}
act("You clench your hand into a fist and will $N's armor to shatter around $M!",ch,0,victim,TO_CHAR);
act("$n clenches $s hand into a fist and wills your armor to shatter around you!",ch,0,victim,TO_VICT);
act("$n clenches $s hand into a fist and wills $N's armor to shatter around $M!",ch,0,victim,TO_NOTVICT);
damage_newer(ch,victim,modifier / 4,TYPE_UNDEFINED,DAM_PIERCE,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"the shattered armor fragments",SINGULAR,DAM_NOT_POSSESSIVE,NULL,FALSE);
return;
}
void spell_hurricane(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *victim = (CHAR_DATA *) vo;
ROOM_AFFECT_DATA raf;
CHAR_DATA *rch, *rch_next;
EXIT_DATA *ex;
int exits, throw_attempts_max = 10, throw_attempts = 0;
bool exitsOpen = FALSE, thrownOut = FALSE;
if (IS_NPC(victim)) return send_to_char("Their movements are too erratic for you to summon a hurricane around.\n\r",ch);
if (ch == victim) return send_to_char("Something tells you that would be a bad idea.\n\r",ch);
if (is_affected(ch,skill_lookup("hurricane"))) return send_to_char("You aren't ready to summon another hurricane.\n\r",ch);
if (is_affected_room(ch->in_room,skill_lookup("hurricane"))) return send_to_char("There is already a hurricane here.\n\r",ch);
for (exits = 0; exits < MAX_DIR; exits++) {
ex = ch->in_room->exit[exits];
if (ex) {
if (!IS_SET(ex->exit_info,EX_CLOSED)) {
exitsOpen = TRUE;
}
}
}
if (!exitsOpen) return send_to_char("You have no room to form a hurricane here.\n\r",ch);
act("Focusing intently on the wind, $n conjures a powerful hurricane!",ch,0,0,TO_ROOM);
act("Focusing intently on the wind, you conjure a powerful hurricane!",ch,0,0,TO_CHAR);
damage_newer(ch,victim,ch->level * number_range(2,3),TYPE_UNDEFINED,DAM_WIND,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"hurricane",PLURAL,DAM_POSSESSIVE,NULL,FALSE);
for (rch = ch->in_room->people; rch != NULL; rch = rch_next ) {
thrownOut = FALSE;
rch_next = rch->next_in_room;
if (IS_NPC(rch)) continue;
if (rch == ch) continue;
if (rch == victim) continue;
if (IS_IMMORTAL(rch)) continue;
while (!thrownOut) {
for (exits = number_range(0,5); !thrownOut && throw_attempts < throw_attempts_max; exits = number_range(0,5)) {
ex = ch->in_room->exit[exits];
if (ex) {
if (!IS_SET(ex->exit_info,EX_CLOSED)) {
int was_in = rch->in_room->vnum;
switch (exits) {
case DIR_NORTH: do_north(rch, ""); if (rch->in_room->vnum != was_in) thrownOut = TRUE; else break;
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_ROOM);
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_CHAR);
act("You are violently blown out of the room by the billowing winds!",rch,0,0,TO_CHAR); break;
case DIR_EAST: do_east(rch, ""); if (rch->in_room->vnum != was_in) thrownOut = TRUE; else break;
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_ROOM);
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_CHAR);
act("You are violently blown out of the room by the billowing winds!",rch,0,0,TO_CHAR); break;
case DIR_WEST: do_west(rch, ""); if (rch->in_room->vnum != was_in) thrownOut = TRUE; else break;
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_ROOM);
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_CHAR);
act("You are violently blown out of the room by the billowing winds!",rch,0,0,TO_CHAR); break;
case DIR_SOUTH: do_south(rch, ""); if (rch->in_room->vnum != was_in) thrownOut = TRUE; else break;
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_ROOM);
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_CHAR);
act("You are violently blown out of the room by the billowing winds!",rch,0,0,TO_CHAR); break;
case DIR_DOWN: do_down(rch, ""); if (rch->in_room->vnum != was_in) thrownOut = TRUE; else break;
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_ROOM);
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_CHAR);
act("You are violently blown out of the room by the billowing winds!",rch,0,0,TO_CHAR); break;
case DIR_UP: do_up(rch, ""); if (rch->in_room->vnum != was_in) thrownOut = TRUE; else break;
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_ROOM);
act("$N is violently blown out of the room by the billowing winds!",ch,0,rch,TO_CHAR);
act("You are violently blown out of the room by the billowing winds!",rch,0,0,TO_CHAR); break;
}
}
}
}
if (throw_attempts >= throw_attempts_max) {
act("$N is thrown against the ground by the billowing winds!",ch,0,rch,TO_CHAR);
act("$N is thrown against the ground by the billowing winds!",ch,0,rch,TO_NOTVICT);
act("You are thrown against the ground by the billowing winds!",ch,0,rch,TO_VICT);
damage_newer(ch, victim,number_range(212,335),TYPE_UNDEFINED,DAM_WIND,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"the billowing winds",SINGULAR,DAM_NOT_POSSESSIVE,NULL,FALSE);
thrownOut = TRUE;
}
}
}
init_affect_room(&raf);
raf.duration = 3;
raf.type = skill_lookup("hurricane");
raf.level = ch->level;
affect_to_room(ch->in_room, &raf);
}
void spell_vorpal_bolt(int sn, int level, CHAR_DATA *ch, void *vo, int target) {
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
bool found = TRUE;
char buf[MSL];
int gsn;
//type - 0 head - 1 legs - 2 arms - 3 chest
int type = number_range(0,3);
act("$n brings $s arms together and thrusts them powerfully towards $N!",ch,0,victim,TO_NOTVICT);
act("In a flash of light, a bolt of black lightning streaks out of $n's hands and passes through $N!",ch,0,victim,TO_NOTVICT);
act("$n brings $s arms together and thrusts them powerfully towards you!",ch,0,victim,TO_VICT);
act("In a flash of light, a bolt of black lightning streaks out of $n's hands and passes through you!",ch,0,victim,TO_VICT);
act("You bring your arms together and thrust them powerfully towards $N!",ch,0,victim,TO_CHAR);
act("In a flash of light, a bolt of black lightning streaks out of your hands and passes through $N!",ch,0,victim,TO_CHAR);
damage_new(ch,victim,ch->level * number_range(4,6),TYPE_UNDEFINED,DAM_LIGHTNING,TRUE,HIT_UNBLOCKABLE,HIT_NOADD,HIT_NOMULT,"vorpal bolt");
switch (type) {
case 0: if (!is_affected(victim,skill_lookup("vorpal bolt head"))) found = FALSE; gsn = skill_lookup("vorpal bolt head"); break;
case 1: if (!is_affected(victim,skill_lookup("vorpal bolt leg"))) found = FALSE; gsn = skill_lookup("vorpal bolt leg"); break;
case 2: if (!is_affected(victim,skill_lookup("vorpal bolt arm"))) found = FALSE; gsn = skill_lookup("vorpal bolt arm"); break;
case 3: if (!is_affected(victim,skill_lookup("vorpal bolt chest"))) found = FALSE; gsn = skill_lookup("vorpal bolt chest"); break;
}
if (!found) {
sprintf(buf,"$N yells out in agony as the bolt penetrates through $S %s!",
type == 0 ? "head" :
type == 1 ? "legs" :
type == 2 ? "arms" : "chest"
);
act(buf,ch,0,victim,TO_NOTVICT);
act(buf,ch,0,victim,TO_CHAR);
free_string(buf);
sprintf(buf,"You yell out in agony as the bolt penetrates through your %s!",
type == 0 ? "head" :
type == 1 ? "legs" :
type == 2 ? "arms" : "chest"
);
act(buf,ch,0,victim,TO_VICT);
init_affect(&af);
af.where = TO_AFFECTS;
af.type = gsn;
af.duration = 5;
if (gsn == skill_lookup("vorpal bolt arm")) {
af.location = APPLY_HITROLL;
af.modifier = -1 * GET_HITROLL(victim);
affect_to_char(victim,&af);
af.location = APPLY_STR;
af.modifier = (-1 * victim->perm_stat[STAT_STR]) / 3;
affect_to_char(victim,&af);
}
else if (gsn == skill_lookup("vorpal bolt head")) {
af.location = APPLY_MANA;
af.modifier = (-1 * victim->mana) / 3;
affect_to_char(victim,&af);
}
else if (gsn == skill_lookup("vorpal bolt leg")) {
af.location = APPLY_HITROLL;
af.modifier = -1 * GET_HITROLL(victim);
affect_to_char(victim,&af);
af.location = APPLY_DEX;
af.modifier = (-1 * victim->perm_stat[STAT_DEX]) / 3;
affect_to_char(victim,&af);
}
else {
af.owner_name = str_dup(ch->original_name);
af.affect_list_msg = str_dup("induces severe burns");
affect_to_char(victim,&af);
}
}
return;
}
void spell_ward_of_magnetism(int sn, int level, CHAR_DATA *ch, void *vo, int target)
{
CHAR_DATA *victim = (CHAR_DATA *) vo;
AFFECT_DATA af;
OBJ_DATA *obj;
int metal_obj_count = 0;
int metal_obj_weight_total = 0;
if (is_affected(ch, sn)) return send_to_char("You are already surrounded by a field of electromagnetic energy.\n\r", ch);
for (obj = ch->carrying; obj != NULL; obj = obj->next_content) {
if (IS_METAL(obj)) {
metal_obj_weight_total += obj->weight;
metal_obj_count++;
}
}
if (metal_obj_count > 5 || metal_obj_weight_total > 20) {
return send_to_char("It would be dangerous to cast this spell while handling so many metal objects.\n\r", ch);
}
init_affect(&af);
af.where = TO_AFFECTS;
af.aftype = AFT_SPELL;
af.type = sn;
af.level = level;
af.duration = level/5;
af.modifier = 0;
af.location = 0;
af.affect_list_msg = str_dup("provides a ward of magnetism");
af.bitvector = 0;
affect_to_char(victim, &af);
act("You feel a strange pull as an invisible field of electromagnetic energy forms around you.",ch,NULL,victim,TO_CHAR);
return;
}