FlCodebase3.1/
FlCodebase3.1/bounty/
FlCodebase3.1/challenge/
FlCodebase3.1/clans/
FlCodebase3.1/gods/
FlCodebase3.1/mobprogs/
FlCodebase3.1/player/
FlCodebase3.1/savemud/
/***************************************************************************
 *  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 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.                                                  * 
 *                                                                         *
 *      ROM 2.4 is copyright 1993-1998 Russ Taylor                         *
 *      ROM has been brought to you by the ROM consortium                  *
 *          Russ Taylor (rtaylor@hypercube.org)                            *
 *          Gabrielle Taylor (gtaylor@hypercube.org)                       *
 *          Brian Moore (zump@rom.org)                                     *
 *      By using this code, you have agreed to follow the terms of the     *
 *      ROM license, in the file Rom24/doc/rom.license                     *
 *                                                                         *
 * Code Adapted and Improved by Abandoned Realms Mud                       *
 * and Aabahran: The Forsaken Lands Mud by Virigoth                        *
 *                                                                         *
 * Continued Production of this code is available at www.flcodebase.com    *
 ***************************************************************************/

#include <sys/types.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"
#include "magic.h"
#include "cabal.h"
#include "recycle.h"
#include "interp.h"

char *target_name;

/* manalock effect for dispel/cancellation */
/* TRUE on removal of mana lock */
bool effect_manalock(int sn, int level, CHAR_DATA* ch, CHAR_DATA* victim)
{

  int upkeep = UMAX(5, (get_skill(victim, gsn_dispel_magic) - get_skill(ch, sn)) * 2);
  int chance = 50 +  (get_skill(ch, gsn_mana_lock) - 60) * 2;

  /*
    ch is the character attempting to dispel
    victim is holder of manalock
  */

//roll if we block iwth mana lock.
  if (number_percent() < chance)
    {
      //check upkeep.
      if (victim->mana < upkeep)
	{
	  send_to_char("Unable to sustain your manalock you lose control.\n\r", victim);
	  affect_strip(victim, gsn_mana_lock);//VERY important to strip it first :)
	  spell_dispel_magic(sn, victim->level + 8, victim, victim, TARGET_CHAR);
	  act("The area around $n shimmers and blurs.", victim, NULL, NULL, TO_ROOM);
	  return TRUE;
	}
      else
	victim->mana -= upkeep;

   //do messages
      if (ch == victim)
	act("Your manalock seems to interfere.", ch, NULL, victim, TO_CHAR);
      else
	{
	  act("You feed energy to your manalock and negate $n's spell.", ch, NULL, victim, TO_VICT);
	  act("$N's manalock seems to negate your spell.", ch, NULL, victim, TO_CHAR);
	}
      check_improve(ch, gsn_mana_lock, TRUE, 1);
      return FALSE;
    }

  check_improve(ch, gsn_mana_lock, FALSE, 1);  
  if (check_dispel(level,victim,gsn_mana_lock)){
      return FALSE;
    }
  return FALSE;
}

void spell_cancellation( int sn, int level, CHAR_DATA *ch, void *vo,int target ){
  CHAR_DATA *victim;
  AFFECT_DATA* paf, *paf_next;
  char arg1[MIL];
  int csn = 0; //0 means cancell all
  bool found = FALSE;

  target_name = one_argument( target_name, arg1);

/* get the victim first */
  /* CASE: null spell arguments */
  if (IS_NULLSTR(arg1))
    victim = ch;
  /* CASE: one argument (must select if it is a person or a spell)*/
  else if (IS_NULLSTR(target_name)){
    /* decide between spell or victim target */
    if ( (victim = get_char_room( ch, NULL, arg1)) == NULL){
      victim = ch;
      /* check for spell */
      if ( (csn = skill_lookup(arg1)) < 1){
	send_to_char("No such spell or skill.\n\r",ch);
	return;
      }
    }
    else
      csn = 0; //cancel all spells
  }
  /* CASE: first and second argument */
  else{
    if ( (victim = get_char_room( ch, NULL, arg1)) == NULL){
      send_to_char("They aren't here.\n\r", ch);
      return;
    }
    if ( (csn = skill_lookup(target_name)) < 1){
      send_to_char("No such spell or skill.\n\r",ch);
      return;
    }
  }

  /* victim check */
  if (ch != victim && (victim->master == NULL || victim->master != ch)){
    send_to_char("They are not following you.\n\r", ch);
    return;
  }

  /* csn checks */
  if (csn){
    char *spell_name = IS_GEN(csn) ? effect_table[GN_POS(csn)].name : skill_table[csn].name;
    if (!IS_GNBIT(csn, GN_CANCEL)){
      sendf(ch, "%s cannot be cancelled.\n\r", spell_name);
	    
      return;
    }
    if (!is_affected(victim, csn)){
      if (victim == ch){
	sendf(ch, "You are not affected by %s.\n\r", spell_name);
	return;
      }
      else{
	sendf(ch, "They are not affected by %s.\n\r", spell_name);
	return;
      }
    }
  }//end csn checks

  /* now we cancel the spell/spells */
  /* check if there is anything to dispel */
  if (csn < 1){
    for (paf = victim->affected; paf; paf = paf_next){
      paf_next = paf->next;

      /* check if we can dispel */
      if (IS_GNBIT(paf->type, GN_CANCEL))
	break;
    }
    if (paf == NULL){
      send_to_char("There are no more spells to cancel.\n\r", ch);
      return;
    }
  }

  /* look for mana lock */
  if (is_affected(victim, gsn_mana_lock)){
    if (effect_manalock(sn, level, ch, victim))
      found = TRUE;
    else
      return;
  }
  
  /* begin checking spells */
  for (paf = victim->affected; paf; paf = paf_next){
    paf_next = paf->next;
    /* always skip to the last duplicate affect */
    if (paf_next && paf_next->type == paf->type)
      continue;
    if (csn && paf->type != csn)
      continue;

    /* check if we can dispel */
    if (!IS_GNBIT(paf->type, GN_CANCEL))
      continue;

    /* can dispel, check */
    if (check_dispel(level, victim, paf->type)){
      found = TRUE;
    }
  }
  if (found){
    send_to_char("Ok.\n\r",ch);
    /* CONTINENCY */
    check_contingency(victim, NULL, CONT_DISPEL);
  }
  else
    send_to_char("Spell failed.\n\r",ch);
}

void spell_dispel_magic( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{

  CHAR_DATA *victim = (CHAR_DATA *) vo;
  AFFECT_DATA* paf, *paf_next;
  bool found = FALSE;

  /* quick check to make sure there is anything left to dispel */
  /* begin checking spells */
  for (paf = victim->affected; paf; paf = paf_next){
    paf_next = paf->next;
    if (IS_GNBIT(paf->type, GN_DISPEL))
      break;
  }
  if (paf == NULL){
    send_to_char("There is nothing left to dispel.\n\r", ch);
    return;
  }
  /* check saves */
  if (ch == victim 
      || (psiamp_failed(ch, victim, level, DAM_MENTAL, skill_table[sn].spell_type, skill_table[sn].flags)
	  && saves_spell(level, victim,DAM_MENTAL, skill_table[sn].spell_type))
      )
    {
      send_to_char( "You feel a brief tingling sensation.\n\r",victim);
      send_to_char( "You failed.\n\r", ch);
      return;
    }
  /* look for mana lock */
  if (is_affected(victim, gsn_mana_lock)){
    if (effect_manalock(sn, level, ch, victim))
      found = TRUE;
    else
      return;
  }
  
  /* begin checking spells */
  for (paf = victim->affected; paf; paf = paf_next){
    paf_next = paf->next;
    /* always skip to the last duplicate affect */
    if (paf_next && paf_next->type == paf->type)
      continue;
    /* check if we can dispel */
    if (!IS_GNBIT(paf->type, GN_DISPEL))
      continue;

    /* can dispel, check */
    if (check_dispel(level, victim, paf->type)){
      found = TRUE;
    }
  }

  if (found){
    send_to_char("Ok.\n\r",ch);
    /* CONTINENCY */
    check_contingency(victim, NULL, CONT_DISPEL);
  }
  else
    send_to_char("Spell failed.\n\r",ch);
}

/*effect_freeze_weapon*/
/*only in magic2.c*/
bool effect_freeze_weapon(CHAR_DATA* ch, CHAR_DATA* victim, int gsn)
{
//The effect causes a weapon of an opponent to crumble due to 
//intense temp. change.

  //We will need these for item.s
  OBJ_DATA* wield;
  OBJ_DATA* dual;

  //And an int for chance.
  int chance = 45;
  const int luck_mod = 2;

//Few saftey checks.
  if (ch == NULL || victim == NULL)
    return FALSE;

//Currently this only works for icestorm.
  if (gsn != skill_lookup("ice storm"))
    return FALSE;

  //Ad finaly we go on.
  //first run the check if we succeed.
  chance += (16 - get_curr_stat(victim, STAT_LUCK))*luck_mod;

  //and now we roll.
  if (number_percent() < chance)
    {
      //Ok now do the evil work.
      if ( (wield = get_eq_char(victim,WEAR_WIELD)) != NULL)
	{
	  //we check for ice as weapon material 
	  //(everything else is destroyed, as even the magic fueling 
	  //magical weapons is extinguished inthe terrible cold :)
	  if ( (wield->item_type == ITEM_WEAPON 
		|| wield->item_type == ITEM_WAND
		|| wield->item_type == ITEM_STAFF
		|| wield->item_type == ITEM_POTION
		|| wield->item_type == ITEM_THROW
		|| wield->item_type == ITEM_ARMOR) 
	       && strcmp(wield->material, "ice"))
	    {
	      if (!IS_OBJ_STAT(wield,ITEM_BURN_PROOF)
		  && !IS_OBJ_STAT(wield,ITEM_HAS_OWNER)){
		act("$p shatters into a hundred icy shards in $n's hands.", victim, wield, NULL, TO_ROOM);
		act("Due to intense temperature stress $p shatters in your hands.", ch, wield, victim, TO_VICT);
		//we destroy it!
		extract_obj(wield);
	      }
	    }//END IF PROPER ITEM
	}//END IF wield!=null.
    }//end if <chance

  //and now we roll AGAIn for the second item.
  if (number_percent() > chance)
    return FALSE;
  //Ok now do more of the evil work.

  if (( dual = get_eq_char(victim,WEAR_SHIELD)) == NULL) 
    {
      if  (( dual = get_eq_char(victim,WEAR_SECONDARY)) == NULL)
	dual = get_eq_char(victim,WEAR_HOLD);
    }
    if (dual != NULL)
      {
//we check for ice as weapon material 
//(everything else is destroyed, as even the magic fueling 
//magical weapons is extinguished inthe terrible cold :)
	if ( (dual->item_type == ITEM_WEAPON 
	  || dual->item_type == ITEM_WAND
	  || dual->item_type == ITEM_STAFF
	  || dual->item_type == ITEM_POTION
	  || dual->item_type == ITEM_THROW
          || dual->item_type == ITEM_ARMOR) 
          && strcmp(dual->material, "ice"))
	{
	  if (!IS_OBJ_STAT(dual,ITEM_BURN_PROOF)
	      && !IS_OBJ_STAT(dual,ITEM_HAS_OWNER)){
	    act("$p shatters into a hundred icy shards in $N's hands.", victim, dual, victim, TO_ROOM);
	    act("Due to intense temperature stress $p shatters in your hands.", ch,dual, victim, TO_VICT);
	    //we destroy it!
	    extract_obj(dual);
	  }
	}//END IF PROPER ITEM
    }//END IF wield!=null.
  return TRUE;
}//END EFFECT_FREEZE_WQEAPON

void spell_ice_storm( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    CHAR_DATA *vch, *vch_next;
    static const sh_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,
	115, 120, 125, 130, 135,	137, 139, 142, 145, 150
    };
    int dam;
    level	= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
    level	= UMAX(0, level);
    dam		= number_range( 3 * dam_each[level] / 2, 5 * dam_each[level] / 2 );
    act("You summon the elemental force of ice to your aid.", ch,NULL,NULL,TO_CHAR );
    act("$n calls upon the forces of nature and creates a vortex of subzero temperature.",ch,NULL,NULL,TO_ROOM);
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
        vch_next = vch->next_in_room;
	if ( vch != ch && !is_area_safe(ch,vch))
	{
	  m_yell(ch,vch,FALSE);
	  if ( saves_spell( level, vch, DAM_COLD,skill_table[sn].spell_type) )
	    dam = 4 * dam / 5;
	  else
	    effect_freeze_weapon(ch, vch, sn);
	  damage( ch, vch, dam, sn, DAM_COLD ,TRUE);    
	}
    }
}


/*FireStorm*/
/*linked only to magic2.c*/
void spell_firestorm( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
  //The caster creates a standing storm of fire in the room.
  //Intial damage is done as per table.
  //update of firestorm(combat and regular) done by effect_firestorm_update(..)
  //blinding effect done by effect_firebreath
  //in fight.c, and act_move.c

  CHAR_DATA *vch, *vch_next;
  AFFECT_DATA af;

  static const sh_int dam_each[] = 
  {
    0,
    0,   0,   0,   0,   0,  0,   0,   0,   0,   0,
    0,   0,   0,   0,  40, 45,  50,  55,  60,  65,
    70,  75,  80,  85,  90, 92,  94,  96,  98, 100,
    102, 104, 106, 108, 110,112, 114, 116, 118, 120,
    122, 124, 126, 128, 130,135, 140, 145, 150, 150
  };
  int dam;
  level= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
  level= UMAX(0, level);
  dam= number_range( 2 * dam_each[level]/3,  dam_each[level] * 2 );
  
  if(is_affected(ch, gen_firestorm))
    {
      act("You cause the firestorm to violently expand.", ch,NULL,NULL,TO_CHAR );
      act("The firestorm explodes in hellish fury!",ch,NULL,NULL,TO_ROOM);
//we cut the damage down.
      dam = 3 * dam / 5;
    }
  else
    {
      act("You create a vortex of fire, sulfur, and brimstone overhead.", ch,NULL,NULL,TO_CHAR );
      act("$n calls upon the forces of Hell and raises a Firestorm!",ch,NULL,NULL,TO_ROOM);
    }
//We attach the firestorm effect to the caster.  Now effect_update_firestorm will check this
  //when appropriate and do damage/clear it etc.
  //The modifier is the room vnum, TO_NONE prevent this from being shown on casters aff.
if (!is_affected(ch, gen_firestorm))
  {
    af.where        = TO_AFFECTS;
    af.type         = gen_firestorm;
    af.level        = level;
    af.duration     = number_range(0, 1);
    af.location     = APPLY_NONE;
    af.modifier     = ch->in_room->vnum;
    af.bitvector    = 0;
    affect_to_char(ch,&af);
  }
  
//We run through all the people in the room.
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
      {
        vch_next = vch->next_in_room;
        if ( saves_spell( level, vch, DAM_FIRE,skill_table[sn].spell_type) )
	  dam /= 2;
	
//And we do damage unless safe.
	  if ( vch != ch && !is_area_safe(ch,vch))
	    {
	      m_yell(ch,vch,FALSE);
//Now we do the chance to blind effect.
//the effect blinds unless victim svs at (lvl/4 +dam/15) lvl.
	      fire_effect(vch, ch->level, 2 * dam, TARGET_CHAR);
	      damage( ch, vch, dam, sn, DAM_FIRE ,TRUE);    
	    }//end if safe
      }//end for vch
}//end spell_firestorm


/*New druid spell. Testing. Don't touch. -Shadow */

void spell_arms_of_gaia( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if (((IS_GOOD(ch) && IS_EVIL(victim)) || (IS_EVIL(ch) &&
    IS_GOOD(victim))) && !IS_IMMORTAL(ch))
    {
        sendf(ch, "It would go against your beliefs to aid %s.\n\r",
        PERS(victim,ch));
	return;
    }
    if (ch->in_room->sector_type != SECT_FOREST)
    {
        send_to_char("You cannot seem to surround yourself outside of a forest.\n\r",ch);
        return;
    }

    if (is_affected(victim, sn))
    {
      send_to_char("You are already within Gaia's arms.\n\r", ch);
      return;
    }

    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 5 + level;
    af.location  = APPLY_AC;
    af.modifier  = -50;
    af.bitvector = 0;
    affect_to_char( victim, &af );
    act_new( "You surround yourself in the Arms of Gaia.", victim, NULL, NULL, TO_CHAR, POS_DEAD );
    act( "$n bows $s head and proffers a blessing to the Earth Mother.", victim, NULL, NULL, TO_ROOM );
}

void spell_protective_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You are already shielded.\n\r",ch);
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = number_fuzzy( level/6);
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = AFF_PROTECT_SHIELD;
    affect_to_char( victim, &af );
    act( "You surround yourself in a protective shell of magic.", ch, NULL, NULL, TO_CHAR );
    act( "$n is surrounded by a protective shell of magic.", ch, NULL, NULL, TO_ROOM );
}

void spell_missile_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target){
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;

    if ( is_affected( ch, sn ) ){
      send_to_char("You are already shielded.\n\r",ch);
      return;
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 24;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( victim, &af );
    act( "You are now protected from ranged weapons.", ch, NULL, NULL, TO_CHAR );
    act( "$n is surrounded by a missile shield.", ch, NULL, NULL, TO_ROOM );
}

void spell_jet_steam( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int dam;
    OBJ_DATA *fountain;
    bool found = FALSE;

    //test for weather
    if (ch->in_room->sector_type == SECT_WATER_SWIM 
	||  ch->in_room->sector_type == SECT_WATER_NOSWIM
	|| ( mud_data.weather_info.sky >= SKY_RAINING &&  temp_adjust( ch->in_room->temp ) > 35))
      found = TRUE;
    //if still nto found, test for fountain.
    if (!found)
      for ( fountain = ch->in_room->contents; fountain != NULL; fountain = fountain->next_content )
	if ( fountain->item_type == ITEM_FOUNTAIN )
	  {
	    found = TRUE;   
	    break;
	  }
    //now if we havent found anythign by this time then we fail.
    if ( !found )
      {
        send_to_char("You need a source of water to cast that spell.\n\r",ch);
        return;
      }

    dam = 50 + dice( 6, 3 ) * level/10;
    if ( saves_spell( level, victim, DAM_DROWNING,skill_table[sn].spell_type ) )
	dam /= 2;
    act("You make the water sizzle with heat.", ch,NULL,NULL,TO_CHAR );
    act("$n channels energy into the water.",ch,NULL,NULL,TO_ROOM);
    damage( ch, victim, dam, sn,DAM_DROWNING,TRUE);
}

void spell_mystic_tendrils( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    int m_gain = number_range(level/2, level) + int_app[get_curr_stat(ch,STAT_INT)].practice * 2,
    chance = number_percent(), dam = number_range(level/2, 2 * level / 3);
    chance += (dam - level) /10;
    chance += 2*(get_curr_stat(ch,STAT_LUCK) - 16);
    if ( ch->hit < dam)
    {
    	send_to_char( "You tear into your physical body.\n\r", ch );
	damage(ch,ch,dam,sn, DAM_NONE,TRUE);
    }
    else
    {
    	send_to_char( "You tear into your physical body.\n\r", ch );
	damage( ch, ch, dam, sn,DAM_NONE,TRUE);
	if (chance < 20)
	{
	    send_to_char("Something disturbs you and you lose the spell.\n\r",ch);
	    m_gain = 0;
	}
	else if (chance < 60)
	{
	    send_to_char("You regain some mental strength.\n\r",ch);
	    m_gain /= 2;
	}
	else if (chance < 90)
	{
	    send_to_char("You regain more mental strength.\n\r",ch);
	}
	else
	{
	    send_to_char("Yes! You feel a sudden surge of mental strength.\n\r",ch);
	    m_gain *= 2;
	}
    	ch->mana = UMIN(ch->max_mana, ch->mana + m_gain);
    }
}

void spell_ice_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if ( IS_AFFECTED2(victim, AFF_FIRE_SHIELD) || IS_AFFECTED2(victim, AFF_ICE_SHIELD) || IS_AFFECTED2(victim,AFF_MANA_SHIELD))
    {
        send_to_char("You are already surrounded by a shield.\n\r",ch);
        return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = number_fuzzy( level/7);
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = AFF_ICE_SHIELD;
    affect_to_char( victim, &af );
    act( "An icy blue shell of cold revolves around you.", ch, NULL, NULL, TO_CHAR );
    act( "$n is surrounded by an icy blue shell.", ch, NULL, NULL, TO_ROOM );
}

void spell_fire_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if ( IS_AFFECTED2(victim, AFF_FIRE_SHIELD) || IS_AFFECTED2(victim, AFF_ICE_SHIELD) || IS_AFFECTED2(victim,AFF_MANA_SHIELD))
    {
        send_to_char("You are already surrounded by a shield.\n\r",ch);
        return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = number_fuzzy( level/7);
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = AFF_FIRE_SHIELD;
    affect_to_char( victim, &af );
    act( "A flaming sphere revolves around you.", ch, NULL, NULL, TO_CHAR );
    act( "$n is surrounded by a sphere of flames.", ch, NULL, NULL, TO_ROOM );
}

void spell_mana_shield( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  AFFECT_DATA af;
  if ( IS_AFFECTED2(victim, AFF_FIRE_SHIELD) || IS_AFFECTED2(victim, AFF_ICE_SHIELD) || IS_AFFECTED2(victim,AFF_MANA_SHIELD))
    {
      send_to_char("You are already surrounded by a shield.\n\r",ch);
      return;
    }
  af.where     = TO_AFFECTS2;
  af.type      = sn;
  af.level     = level;
  af.duration  = number_fuzzy( level/7);
  af.location  = 0;
  af.modifier  = 0;
  af.bitvector = AFF_MANA_SHIELD;
  affect_to_char( victim, &af );
  act( "A shimmering sphere of magic encases you.", ch, NULL, NULL, TO_CHAR );
  act( "$n is encased by a shimmering sphere of magic.", ch, NULL, NULL, TO_ROOM );
}

void spell_hellstream( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  AFFECT_DATA* paf;
  OBJ_DATA *obj_melt;

  
  bool issave = FALSE;
  const int base_chance = 3;
  const int glow_mod = 4;
  const int hum_mod = 4;
  const int enchant_mod = 18;
  const int svs_mod = 12;
    
  const int melt_check = 40;  //chance to start melting when svs fail.
  
  int dam = (7 * level / 2) + (level / 5) * (dice( 3, 6 ) + 2);

  if ( saves_spell(level + 2, victim, DAM_ENERGY,skill_table[sn].spell_type ) )
    {
      issave = TRUE;
      dam /= 2;
    }
  act("You bow your head as you call forth the full power of the arcane.", victim,NULL,ch,TO_VICT );
  act("The ground erupts as you are caught in a searing beam of arcane light.",victim,NULL,ch,TO_CHAR);
  act("The ground erupts as $n is caught in a searing beam of arcane light.",victim,NULL,NULL,TO_ROOM);

  
  //Check if we should start meltint
  if (number_percent() < melt_check && !issave
      && check_immune(victim, DAM_ENERGY, FALSE) != IS_IMMUNE)
    {
      int chance = 0;
      //Begin cycling through all items and melting.
      for ( obj_melt = victim->carrying; obj_melt != NULL; obj_melt = obj_melt->next_content)
	{
	  bool has_saves = FALSE;
	  chance = base_chance;
	  //we add up modifiers
	  if (IS_OBJ_STAT(obj_melt, ITEM_GLOW))
	    chance += glow_mod;
	  if (IS_OBJ_STAT(obj_melt, ITEM_HUM))
	    chance += hum_mod;
	  //Now we check for saves vs spell or aff.
	  if (obj_melt->enchanted)
	    chance+= enchant_mod;
	  else //Item is NOT enchanted 
	    {
	      //Begin searching throgh paf's for svs
	      for ( paf = obj_melt->pIndexData->affected; paf != NULL; paf = paf->next )
		if( (paf->location == APPLY_SAVING_AFFL) ||  (paf->location == APPLY_SAVING_SPELL) )
		  has_saves = TRUE;
	    }//end non-enchant check.
	  //check regular affects unless we already found one
	  if (!has_saves)
	    for ( paf = obj_melt->affected; paf != NULL; paf = paf->next )
	      if( (paf->location == APPLY_SAVING_AFFL) ||  (paf->location == APPLY_SAVING_SPELL) )
		has_saves = TRUE;
	  
	  //Finaly now if there are saves we apply the mod.
	  if (has_saves)
	    chance+= svs_mod;
	  
	  //We check if we blow it.
	  if ( ( number_percent() < chance) 
	       && !IS_OBJ_STAT(obj_melt,ITEM_BURN_PROOF)
	       && !IS_OBJ_STAT(obj_melt,ITEM_HAS_OWNER))
	    {
	      if (has_saves)
		act("$p shudders under the stress and explodes.",ch,obj_melt,NULL, TO_ALL);
	      else
		{
		  act("$p crumbles in $n's hellstream.",ch,obj_melt,NULL,TO_ROOM);
		  act("$p crumbles in your hellstream.",ch,obj_melt,NULL,TO_CHAR);
		}//end else (has saves)
	      
	      //check if we spill items.	    
	      if (obj_melt->item_type == ITEM_CONTAINER)
		{
		  OBJ_DATA *t_obj, *n_obj;
		  act("The items in $p scatter to the ground.",victim,obj_melt,NULL,TO_CHAR);            
		  for (t_obj = obj_melt->contains; t_obj != NULL; t_obj = n_obj)
		    {
		      n_obj = t_obj->next_content;
		      obj_from_obj(t_obj);            
		      if ((number_bits(2) == 0 || victim->in_room == NULL) 
			  && !IS_OBJ_STAT(t_obj,ITEM_BURN_PROOF))
			extract_obj(t_obj);
		      else
			obj_to_room(t_obj,victim->in_room);
		    }//end for t_obj
		}//end if CONTAINER
	      extract_obj(obj_melt);
	    }//end if blow
	}//end for obj_melt
    }//end if notsave
  damage( ch, victim, dam, sn,DAM_ENERGY,TRUE);
}//edn spell_hellstream

void spell_flesh_golem( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    AFFECT_DATA af;
    CHAR_DATA *mob;
    int dur = (is_affected(ch, gsn_soul_tap) ? 6 : 12);

/* cap to ignore spell level boost */
    level = UMIN(ch->level, level);
    
    if (get_summoned(ch, MOB_VNUM_FLESH_GOLEM) > 0)
    {
	send_to_char("Your flesh golem is already in existence.\n\r",ch);
	return;
    }
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You do not feel up to creating another flesh golem.\n\r",ch);
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = dur;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );
    act ("You create a flesh golem!", ch, NULL, NULL, TO_CHAR);
    act ("$n creates a flesh golem!", ch, NULL, NULL, TO_ROOM);
    mob = create_mobile( get_mob_index( MOB_VNUM_FLESH_GOLEM ) );
    char_to_room(mob,ch->in_room);
    mob->level      = level;
    mob->max_hit    = ch->level*17;
    mob->hit        = mob->max_hit;
    mob->alignment = ch->alignment;
    SET_BIT(mob->affected_by, AFF_CHARM);
    mob->comm = COMM_NOTELL|COMM_NOYELL|COMM_NOCHANNELS;
    mob->summoner = ch;
    mob->hitroll        = ch->level/5;
    mob->damroll        = ch->level/5 + 5;
    mob->damage[DICE_NUMBER]    = URANGE(2,(ch->level/10),4);
    mob->damage[DICE_TYPE]      = (ch->level/10) +4;
    add_follower(mob,ch);
    mob->leader=ch;
}

void spell_stone_golem( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    AFFECT_DATA af;
    CHAR_DATA *mob;
    int dur = (is_affected(ch, gsn_soul_tap) ? 6 : 12);

/* cap to ignore spell level boost */
    level = UMIN(ch->level, level);

    if (!can_follow(ch, ch))
      return;

    if (get_summoned(ch, MOB_VNUM_STONE_GOLEM) > 0)
    {
	send_to_char("Your stone golem is already in existence.\n\r",ch);
	return;
    }
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You do not feel up to creating another stone golem.\n\r",ch);
	return;
    }
    level = UMIN(ch->level, level);
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = dur;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );
    act ("You create a stone golem!", ch, NULL, NULL, TO_CHAR);
    act ("$n creates a stone golem!", ch, NULL, NULL, TO_ROOM);
    mob = create_mobile( get_mob_index( MOB_VNUM_STONE_GOLEM ) );
    char_to_room(mob,ch->in_room);
    mob->level      = level;
    mob->max_hit    = level*17;
    mob->hit        = mob->max_hit;
    mob->alignment = ch->alignment;
    SET_BIT(mob->affected_by, AFF_CHARM);
    mob->comm = COMM_NOTELL|COMM_NOYELL|COMM_NOCHANNELS;
    mob->summoner = ch;
    mob->hitroll        = level/5 + 5;
    mob->damroll        = (level/5)*2 + 7;
    mob->damage[DICE_NUMBER]    = URANGE(3,(level/10),5);
    mob->damage[DICE_TYPE]      = (level/10)*2 + 1;
    add_follower(mob,ch);
    mob->leader=ch;
}

void spell_soul_capture(int sn,int level,CHAR_DATA *ch, void *vo,int target)
{
    OBJ_DATA *obj = (OBJ_DATA *) vo, *newobj;
    CHAR_DATA *victim;
    char buf[MSL];
    bool found = FALSE;
    if (obj->item_type == ITEM_CORPSE_NPC 
	|| obj->owner == 0 
	|| obj->condition < 2
	|| obj->pIndexData->vnum == OBJ_VNUM_FAKE_CORPSE)
    {
        send_to_char("You cannot seem to find a soul.\n\r",ch);
	return;
    }
    if (obj->item_type != ITEM_CORPSE_PC)
    {
        send_to_char("There's no soul in that!\n\r",ch);
	return;
    }
    if (obj->level < 15 && !IS_IMMORTAL(ch))
    {
	send_to_char("Not on that corpse.\n\r",ch);
	return;
    }
    if (!can_loot(ch, obj)){
      act("$g's power shields $p from your greedy fingers.", ch, obj, NULL, TO_CHAR);
      return;
    }
    for (victim = player_list; victim != NULL; victim = victim->next_player)
        if (victim->id == obj->owner)
        {
	    found = TRUE;
	    break;
	}
    if (!found)
    {
        send_to_char("The soul has faded away.\n\r",ch);
        return;
    }
    newobj = create_object(get_obj_index(OBJ_VNUM_SOUL),0);
    free_string( newobj->short_descr );
    sprintf( buf, "the soul of %s", victim->name);
    newobj->short_descr = str_dup( buf );
    free_string( newobj->description );
    sprintf( buf, "The soul of %s has been captured.", victim->name);
    newobj->description = str_dup( buf );
    obj_to_char( newobj, ch );
    sprintf( buf, "You capture the soul of %s.", victim->name);
    act (buf, ch, NULL, NULL, TO_CHAR);
    sprintf( buf, "$n captures the soul of %s.", victim->name);
    act (buf, ch, NULL, NULL, TO_ROOM);

    free_string(obj->description);
    obj->description = str_dup("A desiccated corpse lies here.");
    obj->condition = 1;
}

void spell_vampiric_touch( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int dam = dice( 20, 2 );
    int gain = 0;

    
    if ( saves_spell( level, victim, DAM_ENERGY,skill_table[sn].spell_type ) )
	dam /= 2;
    if (ch != victim){
      gain = 20 + dice ( 7, 5 );
      /* scale gain by level */
      gain = UMAX(1, victim->level) * gain / ch->level;
    }
    else
      gain = 0;

    if ( damage( ch, victim, dam, sn,DAM_ENERGY,TRUE)){
      ch->hit = UMIN( ch->max_hit, ch->hit + gain);
    }
}

void spell_hold_undead( 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't hold yourself.\n\r",ch);
        return;
    }
    if (!IS_UNDEAD(victim))
    {
        sendf( ch, "%s is unaffected by your spell.\n\r", PERS(victim,ch) );
        multi_hit( victim, ch, TYPE_UNDEFINED );
	return;
    }
    if ( IS_AFFECTED2(victim, AFF_HOLD) )
    {
        sendf(ch, "%s is already as calm as can be.\n\r", PERS(victim,ch));
        return;
    }
    if ( saves_spell( level, victim, DAM_CHARM,skill_table[sn].spell_type ) )
    {
        sendf(ch, "You failed to hold %s.\n\r", PERS(victim,ch));
        multi_hit( victim, ch, TYPE_UNDEFINED );
        return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level	 = level;
    af.duration  = number_fuzzy( 1 );
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = AFF_HOLD;
    affect_to_char( victim, &af );
    af.where     = TO_AFFECTS;
    af.bitvector = AFF_SLOW;
    affect_to_char( victim, &af );
    act_new( "Your body stops responding as $n bars you from your agressive nature.", ch,NULL,victim,TO_VICT,POS_DEAD );
    act("$n exerts $s presence over $N.",ch,NULL,victim,TO_NOTVICT);
    act("$N freezes and calms down as you exert your presence.",ch,NULL,victim,TO_CHAR);
}
CHAR_DATA* create_zombie(CHAR_DATA* ch, CHAR_DATA* victim, OBJ_DATA* obj)
{
  CHAR_DATA* mob;
  int i;
  char buf[MSL];

  AFFECT_DATA af;

  mob = create_mobile( get_mob_index( MOB_VNUM_ZOMBIE ) );
  mob->level      = UMIN(52, victim->level);
  mob->alignment  = ch->alignment;
  mob->sex        = victim->sex;
  mob->class      = victim->class;
  mob->size       = victim->size;
  
  //check for origins npc/pc
  if (obj->item_type == ITEM_CORPSE_NPC)
    {
      if (victim->max_hit != 0)
	mob->max_hit = UMIN(2000,victim->max_hit /3);
      else
	mob->max_hit = 1;
      mob->hit        = mob->max_hit;
      if (victim->hitroll != 0)
	mob->hitroll = UMIN(40, victim->hitroll / 2);
      else
	mob->hitroll = 0;
      if (victim->damroll != 0)
	mob->damroll = URANGE(1, victim->damroll / 2, 45);
      else
	mob->damroll = 0;


      for (i = 0; i < 4; i++)
	{
	  if (victim->armor[i] != 0)
	    mob->armor[i] = victim->armor[i];
	  else
	    mob->armor[i] = 0;
	}
      
      //set stats
      for (i = 0; i < MAX_STATS; i++)
	{
	  mob->perm_stat[i]     = victim->perm_stat[i]/2;
	  mob->mod_stat[i]      = victim->mod_stat[i]/2;
	}
      
      //set dam and acts.
      mob->dam_type   = victim->dam_type;
      mob->act        = victim->act;
      mob->off_flags  = victim->off_flags;
      
      //remove unneccessary flags
      REMOVE_BIT(mob->off_flags,ASSIST_ALL);
      REMOVE_BIT(mob->off_flags,ASSIST_ALIGN);
      REMOVE_BIT(mob->off_flags,ASSIST_RACE);
      REMOVE_BIT(mob->off_flags,ASSIST_PLAYERS);
      REMOVE_BIT(mob->off_flags,ASSIST_GUARD);
      REMOVE_BIT(mob->off_flags,ASSIST_VNUM);
      REMOVE_BIT(mob->off_flags,CABAL_GUARD);
      REMOVE_BIT(mob->off_flags,GUILD_GUARD);
      REMOVE_BIT(mob->off_flags,OFF_AREA_ATTACK);
      REMOVE_BIT(mob->act,ACT_SCAVENGER);
      REMOVE_BIT(mob->act,ACT_IS_HEALER);
      REMOVE_BIT(mob->act,ACT_TRAIN);
      REMOVE_BIT(mob->act,ACT_PRACTICE);
      REMOVE_BIT(mob->act,ACT_TOO_BIG);
      SET_BIT(mob->act,ACT_UNDEAD);
      
      //setup combat stats
      for (i = 0; i < 3; i++)
	{
	  if (victim->damage[i] != 0)
	    mob->damage[i] = UMAX(1, victim->damage[i]/2);
	  else
	    mob->damage[i] = 0;
	}
    }//END IF NPC
  else
    {
      mob->max_hit = 20 * victim->level;
      mob->hit        = mob->max_hit;
      
      //DAM/HIT
      mob->hitroll = victim->level/10;
      mob->damroll = 2*victim->level/5;
      
      //ARMOR
      for (i = 0; i < 3; i++)
	mob->armor[i] = interpolate(victim->level,100,-100);;
      mob->armor[3] = interpolate(victim->level,100,0);;
      
      //STATS      
      for (i = 0; i < MAX_STATS; i++)
	{
	  mob->perm_stat[i]     = victim->perm_stat[i];
	  mob->mod_stat[i]      = victim->mod_stat[i];
	}
      if (obj->level != 0)
	mob->damage[0] = obj->level/7;
      else
	mob->damage[0] = 0;
      mob->damage[1] = 5;
      mob->damage[2] = 1;
    }//END PC 
  
  
  //SETUP COMON THINGS
  obj->short_descr[0] = LOWER(obj->short_descr[0]);
  sprintf( buf, "A zombie of %s", obj->short_descr);
  str_replace( buf, "the corpse of ", "" );
  free_string( mob->short_descr );
  mob->short_descr = str_dup( buf );
  sprintf( buf, "A zombie of %s stands here serving %s master.\n\r", obj->short_descr, (ch->sex == 2) ? "her" : "his");
  str_replace( buf, "the corpse of ", "" );
  free_string( mob->long_descr );
  mob->long_descr = str_dup( buf );
  
//Load Zombie into room
  char_to_room(mob,ch->in_room);
  SET_BIT(mob->affected_by, AFF_CHARM);
  mob->comm = COMM_NOTELL|COMM_NOYELL|COMM_NOCHANNELS;
  
//Setup the stats.
  mob->summoner = ch;
  add_follower(mob,ch);
  mob->leader=ch;

  //check inv.
  empty_obj(obj);
  //add an effect to store original mobs vnum.
  //bitvector stores the offense flags seton the zombie, acts' are done manualy when loading
  af.type = skill_lookup("animate corpse");
  af.level = 60;
  af.duration = -1;

  /* store current offense flags in bitvector */
  af.where = TO_NONE;
  af.bitvector = mob->off_flags;
  /* store original vnum in modifier (if PC corpse, then just zombie vnum) */
  af.location = APPLY_NONE;
  af.modifier = IS_NPC(victim) ? victim->pIndexData->vnum : mob->pIndexData->vnum;
  affect_to_char(mob, &af);
  return mob;
}//end Create zombie


void spell_animate_corpse(int sn,int level,CHAR_DATA *ch, void *vo,int target)
{
    OBJ_DATA *obj = (OBJ_DATA *) vo;
    AFFECT_DATA af;
    CHAR_DATA  *victim;
    bool found = FALSE;
    bool fAdv = is_affected(ch, gsn_soul_tap);
    int dur = 12;
    int chance = 0;

    if (get_summoned(ch, MOB_VNUM_ZOMBIE) >= UMAX(1,(ch->level/10)-2) && !IS_IMMORTAL(ch))
    {
	send_to_char("You can't control another zombie.\n\r",ch);
	return;
    }
    if (!can_follow(ch, ch))
      return;
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You are too drained to animate anything.\n\r",ch);
	return;
    }
    if (obj->item_type != ITEM_CORPSE_PC && obj->item_type != ITEM_CORPSE_NPC)
    {
        send_to_char("That's not a corpse.\n\r",ch);
	return;
    }
    if (obj->owner == 0 || obj->pIndexData->vnum == OBJ_VNUM_FAKE_CORPSE)
    {
	send_to_char("There is not enough power left in that corpse.\n\r",ch);
	return;
    }
    if (obj->item_type == ITEM_CORPSE_PC)
    {
    	if (obj->level < 15 && !IS_IMMORTAL(ch))
    	{
	    send_to_char("Not on that corpse.\n\r",ch);
	    return;
    	}
	if (!can_loot(ch, obj)){
	  act("$g's power shields $p from your greedy fingers.", ch, obj, NULL, TO_CHAR);
	  return;
	}
	for (victim = player_list; victim != NULL; victim = victim->next_player)
	    if (victim->id == obj->owner)
	    {
		found = TRUE;
		break;
	    }
	if (!found)
	{
	    send_to_char("There is not enough power left in that corpse.\n\r",ch);
	    return;
	}
    }
    else if (obj->item_type == ITEM_CORPSE_NPC && obj->owner == 3)
    {
	send_to_char("There is not enough power left in that corpse.\n\r",ch);
	return;
    }
    else
	victim = create_mobile( get_mob_index( obj->owner ) );

    
    if (fAdv)
      chance = 125;
    else
      chance = get_skill(ch,sn);

    if (chance < 1)
      chance = 75;

    if (obj->level - ch->level > 10 
	|| obj->level > 52
	|| number_percent() > chance + 5*(ch->level - obj->level) - 25 + (get_curr_stat(ch,STAT_LUCK)-16))
    {
    	af.where     = TO_AFFECTS2;
    	af.type      = sn;
    	af.level     = level;
    	af.duration  = dur/2;
    	af.location  = 0;
    	af.modifier  = 0;
    	af.bitvector = 0;
    	affect_to_char( ch, &af );
        act("You destroyed the corpse.",ch,NULL,NULL,TO_CHAR);
        act("$n destroyed the corpse.",ch,NULL,NULL,TO_ROOM);

	//empty obj
	empty_obj(obj);
	obj_from_room ( obj );
	extract_obj ( obj );
    }
    else
    {
    	af.where     = TO_AFFECTS2;
    	af.type      = sn;
    	af.level     = level;
    	af.duration  = dur;
    	af.location  = 0;
    	af.modifier  = 0;
    	af.bitvector = 0;
    	affect_to_char( ch, &af );
        act ("You raise the dead into the form of a zombie!", ch, NULL, NULL, TO_CHAR);
        act ("$n raises the dead!", ch, NULL, NULL, TO_ROOM);

	create_zombie(ch, victim, obj);
	if (IS_NPC(victim))
	  extract_char(victim,TRUE);
	obj_from_room ( obj );
	extract_obj ( obj );
    }
}

void spell_shatter( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
  //This is the new shatter spell.

  /*
EFFECTS:
0 = Arms (-lvl/7 str, -lvl/5 hit/dam )
1 = Legs (-lvl/7 dex, enfeeble)
2 = Pelvis(-lvl/2% Mvs, +lvl/3% Damage, lvl%/2 Dysentry) 
3 = Skull ( - (lvl to 3 *lvl/2)% mana, + lvl/3% damage, lvl/2% misdirection)
4 = Spleen (Drained, -lvl%2Mv, +1/8 Hp Dam) 
  */

    static const sh_int dam_each[] = 
    {
	  0,
	  0,   0,   0,   0,   0,	  0,   0,   0,   0,   0,
	 15,   15,   15,   15,  15,	 18,  20,  21,  22,  23,
	 24,  25,  26,  27,  28,	 29,  30,  40,  50,  60,
	 62,  64,  66,  68,  70,  	 72,  74,  76,  78,  70,
	 81,  82,  83,  84,  85,	 95, 105, 115, 130, 145
    };

  //POINTERS
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
  //BUFFERS
    char part[MSL], buf[MSL];

  //DATA
    int dam;
    int number = number_range(0,4);
  //CONST
    //arm
    const int arm_str = number_fuzzy(8);
    const int arm_hit = number_fuzzy(8);
    const int arm_dam = number_fuzzy(8);
    const int arm_dur = number_fuzzy(8);
    //legs
    const int leg_dex = number_fuzzy(8);
    const int leg_mov = 1;
    const int leg_enf = 2;
    const int leg_dur = number_fuzzy(8);

    //pelvis
    const int pel_mov = 2;
    const int pel_dam = 3;
    const int pel_dys = 2;
    const int pel_dur = 2;

    //skull
    const int sku_dam = 3;
    const int sku_mis = 2;
    const int sku_dur = 5;

    //spleen
    const int spl_mov = 2;
    const int spl_dam = 8;
    const int spl_dur = 5;

  //FLAGS
    bool fAutoFail = FALSE;

  //Get current damage
    level	= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
    level	= UMAX(0, level);
    dam		= number_range(3 * dam_each[level] / 4, dam_each[level]);

    //check if we fail.
    if (is_affected( victim, sn ))
      fAutoFail = TRUE;
    else if ( saves_spell( level, victim, DAM_NEGATIVE,skill_table[sn].spell_type ) )
      fAutoFail = TRUE;

    //Display teh fail message.
    if (fAutoFail)
	send_to_char("You failed to shatter their bones.\n\r", ch);
    else
      {
	switch(number) 
	  {
/* ARMS */
	  case (0) :
	    sprintf(part, "arms");
	    
	    af.type      = sn;
	    af.level     = level;
	    af.duration  = level/arm_dur;
	    af.bitvector = 0;

	    
	    af.where     = TO_AFFECTS2;
	    af.location  = APPLY_HITROLL;
	    af.modifier  = -level/arm_hit;
	    affect_to_char( victim, &af );

	    af.where = TO_AFFECTS2;
	    af.location  = APPLY_DAMROLL; 
	    af.modifier  = -level/arm_dam;      
	    affect_to_char( victim, &af );

	    af.where = TO_AFFECTS2;
	    af.location  = APPLY_STR; 
	    af.modifier  = -level/arm_str;      
	    affect_to_char( victim, &af );

	    break;

/* LEGS */
	  case (1) :
	    sprintf(part, "legs");
	    victim->move -= (level / leg_mov) * victim->move / 100;
	    
	    af.type      = sn;
	    af.level     = level;
	    af.duration  = level/leg_dur;
	    af.bitvector = 0;

	    af.where = TO_AFFECTS2;
	    af.location  = APPLY_DEX; 
	    af.modifier  = -level/leg_dex;      
	    affect_to_char( victim, &af );
	    
	    //check for chance to enfeeble.
	    if (number_percent() < level / leg_enf)
	      spell_enfeeblement(skill_lookup("enfeeblement"), level, ch, victim, TARGET_CHAR);
	    break;
	    
/* PELVIS */
	  case (2) :
	    sprintf(part, "pelvis");
	    dam += (level / pel_dam) * dam / 100;
	    victim->move -=  (level / pel_mov) * victim->move / 100;
	    
	    af.type      = sn;
	    af.level     = level;
	    af.duration  = level/pel_dur;
	    af.bitvector = 0;
	    af.where = TO_AFFECTS;
	    af.location = APPLY_NONE;
	    affect_to_char( victim, &af );
	    
	    //chance for dysentry
	    if (number_percent() < level / pel_dys)
	      spell_dysentery(skill_lookup("dysentery"), level, ch, victim, TARGET_CHAR);
	    break;
	    
/* SKULL */
	  case (3) :
	    
	    sprintf(part, "skull");
	    dam += (level / sku_dam) * dam / 100;
	    victim->mana -= (number_range(level, 3 * level / 2)) * victim->mana / 100;

	    af.type      = sn;
	    af.level     = level;
	    af.duration  = level/sku_dur;
	    af.bitvector = 0;
	    af.where     = TO_AFFECTS2;
	    af.location  = APPLY_NONE;
	    af.modifier  = level;
	    affect_to_char( victim, &af );
//check for misdiretion
	    if (number_percent() < level / sku_mis)
	      {
	    af.type      = gsn_misdirection;
	    af.level     = level;
	    af.duration  = level/sku_dur;
	    af.bitvector = 0;
	    af.where     = TO_NONE;
	    af.location  = APPLY_NONE;
	    af.modifier  = level;
	    affect_to_char( victim, &af );
	  }

	    break;

/* SPLEEN */
	  case (4) :
	    sprintf(part, "spleen");        
	    
	    dam += victim->hit / spl_dam;
	    victim->move -= UMAX(0, (level / spl_mov) * victim->move / 100);

	    af.type      = sn;
	    af.level     = level;
	    af.duration  = level/spl_dur;
	    af.location = APPLY_NONE;
	    af.where = TO_AFFECTS;
	    af.modifier = 0;
	    af.bitvector = 0;
	    affect_to_char( victim, &af );

	    if (!is_affected(victim, gsn_drained))
	      {
		af.type = gsn_drained;
		af.where     = TO_NONE;
		af.location = APPLY_NONE;
		af.modifier = 0;
		affect_to_char( victim, &af );
	      }
	    break;
	  }

//floor the mvoe and mana properly.
	if (victim->mana < 0)victim->mana = 0;
	if (victim->move < 0)victim->move = 0;

	sprintf(buf, "You shatter $N's %s!", part);
	act(buf,ch,NULL,victim,TO_CHAR);
	sprintf(buf, "You feel a sharp pain in your %s!", part);
	act(buf,ch,NULL,victim,TO_VICT);
	sprintf(buf, "$n shatters $N's %s!", part);
	act(buf,ch,NULL,victim,TO_NOTVICT);

	damage( ch, victim, number_fuzzy(dam), sn,DAM_NEGATIVE,TRUE);
      }//end if 
}//end do shatter.

void spell_chorus_of_anguish( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    CHAR_DATA *vch, *vch_next;  
    int dam;
    act("The cries of the damned fill the air.",ch,NULL,NULL,TO_ALL);
    dam = level * 1.5 + dice(3,15);
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
        vch_next = vch->next_in_room;
        if (saves_spell(level,vch,DAM_NEGATIVE,skill_table[sn].spell_type))
	    dam /= 2;
        if (vch != ch && !is_area_safe(ch,vch))
        {
            send_to_char("You can't stand the cries of the damned.\n\r",vch);
	    m_yell(ch,vch,FALSE);
            damage(ch,vch,dam,sn,DAM_NEGATIVE,TRUE);
        }
    }
}

void spell_strength_damned( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    int dur = (is_affected(ch, gsn_soul_tap) ? 30 : 60);

    if (!IS_NPC(victim))
    {
        send_to_char("Not on players.\n\r",ch);
        return;
    }
    if (!IS_AFFECTED(victim,AFF_CHARM) || ch != victim->master || victim->pIndexData->vnum != MOB_VNUM_ZOMBIE)
    {
        sendf(ch, "You don't have control over %s.\n\r", PERS(victim,ch));
        return;
    }
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You can't seem to find a source of unholy strength.\n\r",ch);
        return;
    }
    if ( is_affected( victim, sn ) )
    {
        sendf(ch, "You can't strengthen %s any further.\n\r", PERS(victim,ch));
        return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = dur + 2 * (50 - level);
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );
    af.duration  = -1;
    affect_to_char( victim, &af );
    act("$N's wounds close as $E grows larger with unholy strength.",ch,NULL,victim,TO_ALL);
    victim->max_hit  = 3 * victim->max_hit / 2;
    victim->hit      =  victim->max_hit;
    victim->damage[0] = UMAX(1, 3*victim->damage[0]/2);
    victim->damage[1] = UMAX(1, 3*victim->damage[1]/2);
    victim->perm_stat[STAT_STR] = UMIN(25, 5 * victim->perm_stat[STAT_STR]/2);
    victim->mod_stat[STAT_STR] = UMIN(25, 3 * victim->mod_stat[STAT_STR]/2);
    victim->perm_stat[STAT_DEX] = UMIN(25, 3 * victim->perm_stat[STAT_DEX]/2);
    victim->mod_stat[STAT_DEX] = UMIN(25, 3 * victim->mod_stat[STAT_DEX]/2);
}

void spell_death_grasp( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af, *paf;
    int dam = number_fuzzy(level);
    for ( paf = victim->affected; paf != NULL; paf = paf->next )
        if (paf->type == gsn_death_grasp)
            if (paf->modifier >= 5)
            {
                send_to_char("You can't drain any more vitality.\n\r",ch);
                return;
            }

    level += (ch->tattoo == deity_lookup("cycle") ? level/10 : 0);
    level += (20 - get_curr_stat(victim, STAT_CON));
/* the below is done, so each 2% of skill over 75 results in -1 save to spell*/
    level += (get_skill(ch, sn) - 75) / 5;

    if ( !saves_spell( level, victim, DAM_NEGATIVE,skill_table[sn].spell_type ) )
    {
        af.where     = TO_AFFECTS2;
        af.type      = gsn_death_grasp;
        af.level     = level;
        af.duration  = level/10;
        af.location  = 0;
        af.modifier  = 1;
        af.bitvector = 0;
        affect_join( victim, &af );

        act("Rotting hands erupt from the ground and drain your vitality.",ch,NULL,victim,TO_VICT);
        act("Rotting hands erupt from the ground and claw at $N.",victim,NULL,victim,TO_ROOM);

    }
    damage( ch, victim, dam, sn,DAM_NEGATIVE,TRUE);
}

void spell_powerword_kill( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA *paf;
//DATA
    int times = 0;
    int chance = 0;
    int skill = get_skill(ch, skill_lookup("powerword kill"));
    int dam = number_fuzzy(100) + dice(10,15);
//CONST
    const int luck_mod = 2;
    const int grasp_mod = 7;
    const int lvl_mod = 2;
    const int skill_mod = 1;
    const int skill_med = 75;
 
//begin calulating chances.


//Get the number of times target was grasped.
    for ( paf = victim->affected; paf != NULL; paf = paf->next )
      if (paf->type == gsn_death_grasp)
	times += paf->modifier;

//calculate the chance:
    chance += (get_curr_stat(victim,STAT_LUCK) - get_curr_stat(ch,STAT_LUCK)) / luck_mod;
    chance += grasp_mod * times;
    chance += (UMAX(0, victim->level - ch->level)) / lvl_mod * UMAX(1, times);

    if (IS_NPC(victim))
      chance += 15;
    else
      chance += skill_mod * (skill - skill_med) / 100;

    if (chance > 60) chance = 60;

    //give chance con bonus (not affected by ceiling)
    chance = 20 * chance / get_curr_stat(victim, STAT_CON);

    if (victim->level > 50 || (!IS_NPC(victim) && times < 2))
      chance = 0;
    
    if (IS_IMMORTAL(ch))
      chance = 100;

    //special checks.
    if (IS_UNDEAD(victim))
      chance = 0;
    //    sendf(ch, "chance: %d\n\r", chance);

    if ( (number_percent() < chance 
	  && !IS_IMMORTAL(victim)) 
	 && (!IS_NPC(victim) || !IS_SET(victim->act,ACT_TOO_BIG))){
        act("You point your finger at $N and $E crumples to the ground.",ch,NULL,victim,TO_CHAR);
        act("$n points a finger at you and utters Word of Death.",ch,NULL,victim,TO_VICT);
        act("$N crumples to the ground, face frozen and contorted in fear.",ch,NULL,victim,TO_NOTVICT);
	act( "$n is DEAD!!", victim, NULL, NULL, TO_ROOM );
	act_new( "You have been KILLED!!", victim, NULL, NULL, TO_CHAR, POS_DEAD );
        raw_kill(ch, victim);
	do_autos(ch);
        victim->hit = 1;
	victim->mana = 1;
	return;
    }
    else
    {
        act("Spell failed.",ch,NULL,victim,TO_CHAR);
        act_new("Your heart stops beating for a split second.",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
	if (paf){
	  paf->modifier -= 2;
	  if (paf->modifier < 1)
	    affect_strip(victim, gsn_death_grasp);
	}
    }
    damage( ch, victim, dam, sn, DAM_NEGATIVE ,TRUE);
}

void spell_knock( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    int door = (int) vo, np = number_percent();
    ROOM_INDEX_DATA *to_room;
    CHAR_DATA *gch;
    EXIT_DATA *pexit = ch->in_room->exit[door], *pexit_rev;
    if ( door < 0 )
        return;
    for ( gch = ch->in_room->people; gch; gch = gch->next_in_room )
	if ( IS_NPC(gch) && IS_AWAKE(gch) && ch->level + 5 < gch->level )
	{
            act( "$N is standing too close to the lock.",ch, NULL, gch, TO_CHAR );
	    return;
	}
    if ( !IS_SET(pexit->exit_info, EX_CLOSED) && !IS_IMMORTAL(ch))
        { send_to_char( "It's not closed.\n\r",        ch ); return; }
    if ( pexit->key < 0 && !IS_IMMORTAL(ch))
        { send_to_char( "It can't be picked.\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( "You failed to open the door.\n\r", ch ); return; }
    if ( !IS_SET(pexit->exit_info, EX_EASY) )
        np = 2*np/3;
    if ( !IS_SET(pexit->exit_info, EX_HARD) )
        np = 3*np/2;
    if ( !IS_SET(pexit->exit_info, EX_INFURIATING) )
        np *= 2;
    if ( !IS_NPC(ch) && UMAX(1,np - 2*(get_curr_stat(ch,STAT_LUCK) - 16)) > get_skill(ch,sn))
    {
        send_to_char( "You failed to open the door.\n\r", ch);
	return;
    }
    REMOVE_BIT(pexit->exit_info, EX_LOCKED);
    act( "An arcane hand raps gently upon the $d as the lock glows.", ch, NULL, pexit->keyword, TO_ALL );
    if ( ( to_room = pexit->to_room ) != NULL && ( pexit_rev = to_room->exit[rev_dir[door]] ) != NULL
    && pexit_rev->to_room == ch->in_room )
        REMOVE_BIT( pexit_rev->exit_info, EX_LOCKED );
}

void spell_blur( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You are already blurred.\n\r",ch);
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = number_fuzzy( level / 2);
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = AFF_BLUR;
    affect_to_char( victim, &af );
    act( "Your physical contours become distorted.", ch, NULL, NULL, TO_CHAR );
    act( "$n's contours become blurred.", ch, NULL, NULL, TO_ROOM );
}

void spell_phantasmal_griffon( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if (victim == ch)
    {
	send_to_char("You can't fool yourself.\n\r",ch);
	return;
    }
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You can't create that illusion right now.\n\r",ch);
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = gsn_phantasmal_griffon;
    af.level     = 100;
    af.duration  = -1;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );
    act("You call your phantasmal griffon to your aid!",ch,NULL,victim,TO_CHAR);
    act("A griffon screams from above!",ch,NULL,victim,TO_ALL);
    damage( ch, victim, 0, sn,DAM_NONE,FALSE);
}

void spell_illusionary_spectre( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if (victim == ch)
    {
	send_to_char("You can't fool yourself.\n\r",ch);
	return;
    }
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You can't create that illusion right now.\n\r",ch);
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = gsn_illusionary_spectre;
    af.level     = 100;
    af.duration  = -1;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );
    act("You send an illusionary spectre into the battle!",ch,NULL,victim,TO_CHAR);
    act("A spectre materializes from the Nexus!",ch,NULL,victim,TO_ALL);
    damage( ch, victim, 0, sn,DAM_NONE,FALSE);
}

void spell_phantom_dragon( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if (victim == ch)
    {
	send_to_char("You can't fool yourself.\n\r",ch);
	return;
    }
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You can't create that illusion right now.\n\r",ch);
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = gsn_phantom_dragon;
    af.level     = 100;
    af.duration  = -1;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );
    act("You send an esoteric phantasm into battle!",ch,NULL,victim,TO_CHAR);
    act("An esoteric phantasm takes form and assails your senses!",ch,NULL,victim,TO_ALL);
    damage( ch, victim, 0, sn,DAM_NONE,FALSE);
}

void spell_shrink( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if  (saves_spell( level, victim, DAM_MALED,skill_table[sn].spell_type ))
      {
	send_to_char("You failed.\n\r", ch);
	return;
      }

    if ( is_affected( victim, sn ) || victim->size <= SIZE_TINY)
    {
	if (victim == ch)
            act("You are already as small as possible.",ch,NULL,victim,TO_CHAR);
 	else
            act("$N can't be shrunken any further.", ch,NULL,victim,TO_CHAR);
        return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = level / 6;
    af.location  = APPLY_SIZE;
    af.modifier  = -1;
    af.bitvector = 0;
    affect_to_char( victim, &af );
    af.location  = APPLY_CON;
    af.modifier  = -2;
    affect_to_char( victim, &af );
    af.location  = APPLY_STR;
    af.modifier  = -2;
    affect_to_char( victim, &af );
    af.location  = APPLY_DAMROLL;
    af.modifier  = -3;
    affect_to_char( victim, &af );
    act_new( "The world and everything around you gets bigger.", victim,NULL,NULL,TO_CHAR,POS_DEAD );
    act("$n shrinks in size.",victim,NULL,NULL,TO_ROOM);
}

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, sn ) || victim->size >= SIZE_HUGE)
    {
	if (victim == ch)
            act("You are already enlarged.",ch,NULL,victim,TO_CHAR);
 	else
            act("You can't make $N any larger.", ch,NULL,victim,TO_CHAR);
        return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = level / 6;
    af.location  = APPLY_SIZE;
    af.modifier  = 1;
    af.bitvector = 0;
    affect_to_char( victim, &af );
    af.location  = APPLY_CON;
    af.modifier  = 2;
    affect_to_char( victim, &af );
    af.location  = APPLY_STR;
    af.modifier  = 2;
    affect_to_char( victim, &af );
    af.location  = APPLY_DAMROLL;
    af.modifier  = 3;
    affect_to_char( victim, &af );
    act_new( "The world and everything around you seem to shrink.", victim,NULL,NULL,TO_CHAR,POS_DEAD );
    act("$n dwarfs everything around $m as $e grows.",victim,NULL,NULL,TO_ROOM);
}

void spell_veil( 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)
            act("You are as veiled as it gets.",ch,NULL,victim,TO_CHAR);
 	else
            act("$N is already surrounded by the dark walls.", ch,NULL,victim,TO_CHAR);
        return;
    }
    if ( saves_spell( level, victim, DAM_MALED,skill_table[sn].spell_type ))
    {
	sendf(ch, "You failed to veil %s in darkness.\n\r", PERS(victim,ch));
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = (level / 6) + 1;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = AFF_TERRAIN;
    affect_to_char( victim, &af );

    act("Thick shadows veil $n from outside world.", victim, NULL, NULL, TO_ROOM);
    act("Thick walls of darkness veil you from the outside world.",ch, NULL, victim, TO_VICT);
}

void spell_prismatic_spray( int sn, int level, CHAR_DATA *ch, void *vo, int target ) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    static const sh_int dam_each[] = 
    {
	 0,
	 0,  0,  0,  0,  0,	 0,  0,  0, 30, 41,
	42, 43, 44, 44, 45,	45, 46, 46, 47, 48,
	49, 50, 51, 51, 52,	52, 53, 53, 54, 55,
	56, 57, 58, 58, 59,	59, 60, 60, 61, 62,
	63, 64, 65, 65, 66,	66, 67, 67, 68, 69 
    };
    int dam;
    level	= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
    level	= UMAX(0, level);
    dam		= number_range( dam_each[level], dam_each[level] * 2 );
    act("A prism of colors shoot out from your hands.", ch,NULL,NULL,TO_CHAR );
    act("A prism of colors shoot out from $n's hands.",ch,NULL,NULL,TO_ROOM);
    switch(number_range(0,9))
    {
	case 0 :
	act_new("You are struck by a beam of violet light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
	act("$n is struck by a beam of violet light.",victim,NULL,NULL,TO_ROOM);
    	if ( saves_spell( level, victim, DAM_LIGHT,SPELL_AFFLICTIVE ) )
	    dam /= 2;
	break;
	case 1 :
	act_new("You are struck by a beam of orange light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
	act("$n is struck by a beam of orange light.",victim,NULL,NULL,TO_ROOM);
    	if ( saves_spell( level, victim, DAM_MALED,SPELL_MALEDICTIVE ) )
	    dam /= 2;
	else
            spell_slow(skill_lookup("slow"), level, ch, (void *) victim,TARGET_CHAR);
	break;
	case 2 :
	act_new("You are struck by a beam of yellow light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
	act("$n is struck by a beam of yellow light.",victim,NULL,NULL,TO_ROOM);
    	if ( saves_spell( level, victim, DAM_MALED,SPELL_MALEDICTIVE ) )
	    dam /= 2;
        else
	    spell_blindness(gsn_blindness, level, ch, (void *) victim,TARGET_CHAR);
	break;
	case 3 :
	act_new("You are struck by a beam of green light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
	act("$n is struck by a beam of green light.",victim,NULL,NULL,TO_ROOM);
    	if ( saves_spell( level, victim, DAM_POISON,SPELL_MALEDICTIVE ) )
	    dam /= 2;
        else
	    spell_poison(gsn_poison, level, ch, (void *) victim,TARGET_CHAR);
	break;
	case 4 :
	act_new("You are struck by a beam of blue light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
	act("$n is struck by a beam of blue light.",victim,NULL,NULL,TO_ROOM);
    	if ( saves_spell( level, victim, DAM_MALED,SPELL_MALEDICTIVE ) )
	    dam /= 2;
        else
	    spell_weaken(skill_lookup("weaken"), level, ch, (void *) victim,TARGET_CHAR);
	break;
	case 5 :
	act_new("You are struck by a beam of violet light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
	act("$n is struck by a beam of violet light.",victim,NULL,NULL,TO_ROOM);
    	if ( saves_spell( level, victim, DAM_LIGHT,SPELL_AFFLICTIVE ) )
	    dam /= 2;
	break;
	case 6 :
	act_new("You are struck by a beam of white light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
	act("$n is struck by a beam of white light.",victim,NULL,NULL,TO_ROOM);
	dam = 3 * dam /2;
    	if ( saves_spell( level, victim, DAM_LIGHT,SPELL_AFFLICTIVE ) )
	    dam /= 2;
	break;
	default :
	act_new("You are struck by a beam of red light.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
	act("$n is struck by a beam of red light.",victim,NULL,NULL,TO_ROOM);
	dam /= 2;
    	if ( saves_spell( level, victim, DAM_LIGHT,SPELL_AFFLICTIVE ) )
	    dam /= 2;
	break;
    }
    damage( ch, victim, dam, sn, DAM_LIGHT, TRUE);
}

void spell_misdirection( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;

    act("With a flash of arcane energy a mighty thunderclap explodes beside $N.", ch, NULL, victim, TO_NOTVICT);
    act("With a flash of arcane energy a mighty thunderclap explodes beside you.", ch, NULL, victim, TO_VICT);

    damage(ch, victim, level, gsn_misdirection, DAM_SOUND, TRUE);

//deafen if vuln to sound. (damage or spell)
    if (check_immune(victim,DAM_SOUND, TRUE) == IS_VULNERABLE
	|| check_immune(victim,DAM_SOUND,FALSE) == IS_VULNERABLE)
      spell_silence(gsn_silence, level + 5, ch, victim, TARGET_CHAR );

    if ( is_affected( victim, sn ) )
    {
	if (victim == ch)
            act("You are already dazed.",ch,NULL,victim,TO_CHAR);
 	else
            act("$N already is dazed and confused.", ch,NULL,victim,TO_CHAR);
        return;
    }
    if ( saves_spell( level, victim, DAM_SOUND,skill_table[sn].spell_type ))
    {
      act("$n covers $s ears just in time!", victim, NULL, NULL, TO_ROOM);
      act("You cover your ears just in time!", victim, NULL, NULL, TO_CHAR);
      return;
    }

      act("$s ears trickling with blood, $n looks around dazed and confused.", victim, NULL, NULL, TO_ROOM);
      act("The mighty force of explosion dazes your senses and confuses your mind.", victim, NULL, NULL, TO_CHAR);

    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = number_range(0,5);
    af.duration  = level / 10 - 1;
    af.location  = APPLY_DEX;
    af.modifier  = -1;
    af.bitvector = AFF_MISDIRECTION;
    affect_to_char( victim, &af );
    af.level     = number_range(0,5);
    af.location  = APPLY_INT;
    af.modifier  = -1;
    af.bitvector = AFF_MISDIRECTION;
    affect_to_char( victim, &af );

}

void spell_deluge_water( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int dam = level + dice( 10, 5 );
    if ( saves_spell( level, victim, DAM_DROWNING,skill_table[sn].spell_type ) )
	dam /= 2;
    act("You create a cube of water.", ch,NULL,NULL,TO_CHAR );
    act("$n creates a cube of water.",ch,NULL,NULL,TO_ROOM);
    damage( ch, victim, dam, sn,DAM_DROWNING,TRUE);
}

void spell_shadowform( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    if ( is_affected( ch, sn ) )
    {
        send_to_char("You are already in shadowform.\n\r",ch);
	return;
    }
    if (get_charmed_by(ch))
    {
        send_to_char( "You can't hide yourself when you have followers.\n\r", ch);
        return;
    }
    if ( IS_AFFECTED(ch, AFF_FAERIE_FOG) || IS_AFFECTED(ch, AFF_FAERIE_FIRE))
    {
        send_to_char( "You can't change your form while glowing.\n\r", ch);
        return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = get_skill(ch, sn) < 1 ? number_fuzzy(7) : 12;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = AFF_SHADOWFORM;
    affect_to_char( victim, &af );
    af.bitvector = AFF_PASS_DOOR;
    act( "Your body loses its substance as you take on an ethereal form.", ch, NULL, NULL, TO_CHAR );
    act( "$n's body loses its substance, and $e dematerializes.", ch, NULL, NULL, TO_ROOM ); 
}

void spell_feeblemind( 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)
            act("You are already feebleminded.",ch,NULL,victim,TO_CHAR);
 	else
            act("$N already under the effects of feeblemind.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if ( saves_spell( level, victim, DAM_MENTAL,skill_table[sn].spell_type ) )
    {
        sendf(ch, "You failed to feeblemind %s.\n\r", PERS(victim,ch));
        return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = level/5;
    af.location  = APPLY_INT;
    af.modifier  = -(level-5)/3;
    af.bitvector = 0;
    affect_to_char( victim, &af );
    af.location  = APPLY_WIS;
    af.modifier  = -level/5;
    affect_to_char( victim, &af );
    act_new("You feel your mind slipping away.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
    act("$n gets a blank look on $s face.",victim,NULL,NULL,TO_ROOM);
}

void spell_flame_arrow(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    static const sh_int dam_each[] = 
    {
	 0,
	 0,  0,  0,  0,  0,	 0,  0,  0, 40, 41,
	42, 43, 44, 45, 46,	47, 48, 49, 50, 51,
	52, 53, 54 ,55, 56,	60, 63, 69, 70, 71,
	72, 74, 76, 78, 80,	81, 82, 83, 84, 85,
	85, 85, 85, 85, 85,	90, 92, 94, 98, 100 
    };
    int dam;
    level	= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
    level	= UMAX(0, level);
    dam		= number_range( dam_each[level], 3 * dam_each[level] / 2 );
    act("You create a flaming arrow and send it streaking towards $N.",ch,NULL,victim,TO_CHAR);
    act("$n creates a flaming arrow and points it towards you.",ch,NULL,victim,TO_VICT);
    act("$n creates a flaming arrow.",ch,NULL,victim,TO_NOTVICT);
    if (IS_AFFECTED2(ch, AFF_FIRE_SHIELD) 
	&& check_immune(victim, DAM_FIRE, TRUE) != IS_VULNERABLE)
      dam += (10 + 2 * dam / 10);
    if ( saves_spell( level, victim,DAM_FIRE,skill_table[sn].spell_type) )
	dam /= 2;
    damage( ch, victim, dam, sn, DAM_FIRE ,TRUE);
}

void spell_iceball( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA *vch, *vch_next;
    static const sh_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,
	 90,  90,  90,  90,  90,  	 92,  94,  96,  98, 100,
	101, 102, 103, 104, 105,	106, 107, 108, 109, 110
    };
    int dam;
    level	= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
    level	= UMAX(0, level);
    dam		= number_range(3 * dam_each[level] / 4, 2 * dam_each[level]);
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
        vch_next = vch->next_in_room;
        if ( saves_spell( level, vch, DAM_COLD,skill_table[sn].spell_type) )
	    dam = 80 * dam / 100;
	if ( vch != ch && !is_area_safe(ch,vch))
	{
	    m_yell(ch,vch,FALSE);
            damage( ch, vch, dam, sn, DAM_COLD ,TRUE);
	}
    }
}

void spell_icicle(int sn,int level,CHAR_DATA *ch,void *vo,int target)
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    static const sh_int dam_each[] = 
    {
	 0,
	 0,  0,  0,  0,  0,	 0,  0,  0, 30, 31,
	32, 33, 34, 35, 36,	37, 38, 39, 40, 41,
	42, 43, 44 ,45, 46,	50, 52, 53, 54, 55,
	66, 67, 68, 68, 69,	70, 72, 74, 78, 80,
	85, 86, 87, 88, 89,	90, 92, 94, 98, 100 
    };
    int dam;
    level	= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
    level	= UMAX(0, level);
    dam		= number_range( dam_each[level], 3 * dam_each[level] / 2 );
    act("You conjure a magical bolt of ice and launch it at $N.",ch,NULL,victim,TO_CHAR);
    act("$n conjures a magical bolt of ice and launches it at you.",ch,NULL,victim,TO_VICT);
    act("$n conjures a magical bolt.",ch,NULL,victim,TO_NOTVICT);
    if (IS_AFFECTED2(ch, AFF_ICE_SHIELD) 
	&& check_immune(victim, DAM_COLD, TRUE) != IS_VULNERABLE)
      dam += (10 + 2 * dam / 10);
    if ( saves_spell( level, victim,DAM_COLD,skill_table[sn].spell_type) )
	dam /= 2;
    damage( ch, victim, dam, sn, DAM_COLD ,TRUE);
}

/* void spell_ranger_staff( int sn, int level, CHAR_DATA *ch, void *vo,int target)
{
    OBJ_DATA *staff = create_object( get_obj_index( OBJ_VNUM_RANGER_STAFF ), 0);
    AFFECT_DATA *paf;
    staff->value[1] = number_range(level -6, level)/3 + 2;
    staff->value[2] = 2;
    staff->level = level;
    staff->timer = 24;
    if (IS_EVIL(ch))
    {
        SET_BIT(staff->extra_flags,ITEM_ANTI_GOOD);
        SET_BIT(staff->extra_flags,ITEM_ANTI_NEUTRAL);
    }
    else if (IS_GOOD(ch))
    {
        SET_BIT(staff->extra_flags,ITEM_ANTI_EVIL);
        SET_BIT(staff->extra_flags,ITEM_ANTI_NEUTRAL);
    }
    else
    {
        SET_BIT(staff->extra_flags,ITEM_ANTI_GOOD);
        SET_BIT(staff->extra_flags,ITEM_ANTI_EVIL);
    }
    paf = new_affect();
    paf->type       = sn;
    paf->level      = level;
    paf->duration   = -1;
    paf->location   = APPLY_HITROLL;
    paf->modifier   = level/5;
    paf->bitvector  = 0;
    paf->next       = staff->affected;
    staff->affected   = paf;
    paf = new_affect();
    paf->type       = sn;
    paf->level      = level;
    paf->duration   = -1;
    paf->location   = APPLY_DAMROLL;
    paf->modifier   = level/5;
    paf->bitvector  = 0;
    paf->next       = staff->affected;
    staff->affected   = paf;
    obj_to_char(staff, ch);
    act( "You create $p.", ch, staff, NULL, TO_CHAR );
    act( "$n creates $p.", ch, staff, NULL, TO_ROOM );
}*/

void spell_wrath(int sn, int level, CHAR_DATA *ch, void *vo,int target){
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  const int holy_w = skill_lookup("holy word");
  int dam = 0;
  bool fHoly = is_affected(ch, holy_w);
  int chance = fHoly ? 66 : 33;

  if (victim->hit > ch->level * 8)
    dam = number_range(14 * level / 5, 28 * level / 5);
  else{
    /* holy word allows for single powerful hit */
    if (fHoly){
      act_new(skill_table[holy_w].msg_off,ch,NULL,NULL,TO_CHAR,POS_DEAD);
      affect_strip(ch, holy_w);
      dam = number_range(14 * level / 5, 28 * level / 5);
    }
    else{
      dam = UMIN(victim->hit, dice (ch->level, 5));
    }
  }
  if (IS_GOOD(victim) ){
    act("$N follows the path of goodness and is not affected by your wrath.\n\r", ch, NULL, victim, TO_CHAR);
    act("$n attempts to wrath you, but you are unaffected.",ch,NULL,victim,TO_VICT);
    act("$N is unaffected by $n's wrath.",ch,NULL,victim,TO_NOTVICT);
    return;
  }
  if (IS_NEUTRAL(victim) )
    dam /= 3;
  if ( saves_spell( level, victim,DAM_HOLY,skill_table[sn].spell_type) ){
    dam /= 2;
  }
  if ( is_affected(ch,gsn_heroism) )
    dam = 4 * dam / 3;

  if (IS_EVIL(victim) 
      && !is_affected(victim,gsn_curse) 
      && number_percent() < chance){
    spell_curse(gsn_curse, level, ch, (void *) victim,TARGET_CHAR);
  }
  damage( ch, victim, dam, sn, DAM_HOLY ,TRUE);
}

void spell_ikuzachi( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int dam = level + dice(11,10);
    if ( saves_spell( level, victim, DAM_ENERGY,skill_table[sn].spell_type ) )
        dam /= 2;
    act("You focus your mind to invoke the ancient arts.", ch,NULL,victim,TO_CHAR);
    act("$n closes $s eyes for a moment then glares in your direction.",ch,NULL,victim,TO_VICT);
    act("$n closes $s eyes for a moment in deep concentration.",ch,NULL,victim,TO_NOTVICT);
    damage( ch, victim, dam, sn,DAM_ENERGY,TRUE);
}

void spell_silence( 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)
            act("Your world is already dead silent.",ch,NULL,victim,TO_CHAR);
 	else
            act("$N has already been silenced.", ch,NULL,victim,TO_CHAR);
        return;
    }
    if ( saves_spell( level, victim, IS_NPC(victim) ? DAM_MENTAL : DAM_CHARM,skill_table[sn].spell_type ))
    {
	sendf(ch, "You failed to silence %s.\n\r", PERS(victim,ch));
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = level / 8;
    af.location  = APPLY_NONE;
    af.modifier  = 0;
    af.bitvector = AFF_SILENCE;
    affect_to_char( victim, &af );
    if (victim == ch)
        send_to_char("Your world suddenly becomes dead silent.\n\r",ch);
    else
    {
        act("$N has been silenced.",ch,NULL,victim,TO_CHAR);
        act_new("Your world suddenly becomes dead silent.",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
    }
}


void spell_damnation( 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 damned.",ch,NULL,victim,TO_CHAR);
        return;
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 3*level;
    af.location  = APPLY_HITROLL;
    af.modifier  = -1 * (level / 8);
    af.bitvector = 0;
    affect_to_char( victim, &af );
    act_new( "The Gods have forsaken you.", ch,NULL,victim,TO_CHARVICT,POS_DEAD );
    if ( ch != victim )  
        act("$N looks very uncomfortable.",ch,NULL,victim,TO_CHAR);
}

void spell_flashfire( int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
    CHAR_DATA* vch;
    CHAR_DATA* vch_next;

    AFFECT_DATA af;
    act("You create a bright flash of light.",ch,NULL,NULL,TO_CHAR);
    act("$n sends a brilliant sphere of light spiraling down!",ch,NULL,NULL,TO_ROOM);


    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
      {
	vch_next = vch->next_in_room;
	if ( vch != ch && !is_area_safe(ch,vch) )

	  {
	    /* skip mirror image too */
	    if (IS_NPC(vch) && vch->master && vch->master == ch)
	      continue;
	    m_yell(ch,vch,FALSE);
	    if (!vch->fighting)
	      multi_hit( vch, ch, TYPE_UNDEFINED);
	    
	  }
	else
	  continue;

	if ( IS_AFFECTED(vch, AFF_BLIND))
	  continue;
	
	if ( saves_spell(level, vch, DAM_OTHER,skill_table[sn].spell_type) )
	  {	
	    act_new("You squint your eyes, unaffected by the glare.",ch,NULL,vch,TO_CHARVICT,POS_DEAD);
	    act("$N avoids the glare.",ch,NULL,vch,TO_CHAR);
	    continue;
	  }
	else 
	  {
	    act_new("You have been blinded by the flash of light!",ch,NULL,vch,TO_CHARVICT,POS_DEAD);
	    act("$n is blinded by the flashfire!",vch,NULL,vch,TO_ROOM);
	  }
	
	af.where     = TO_AFFECTS; 
	af.type      = gsn_blindness;
	af.level     = level;
	af.location  = APPLY_HITROLL;
	af.duration  = level / 8 + UMAX(0, (get_skill(ch, sn) - 75) / 5);
	af.bitvector = AFF_BLIND;
	if (!IS_NPC(vch) && number_percent() < get_skill(vch,gsn_blind_fighting)){
	  if (is_affected(vch, gsn_battletrance))
	    af.modifier      = 0;
	  else
	    af.modifier      = -3;
	}
	else
	  af.modifier      = -6;
	affect_to_char(vch,&af);
	af.location     = APPLY_AC;
	if (!IS_NPC(vch) && number_percent() < get_skill(vch,gsn_blind_fighting)){
	  if (is_affected(vch, gsn_battletrance))
	    af.modifier      = 0;
	  else
	    af.modifier      = 5;   
	}
	else
	  af.modifier      = 15;
	affect_to_char(vch,&af);
	
      }
}

void spell_thunder_storm( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    CHAR_DATA *vch, *vch_next;
    static const sh_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,	105, 110, 115, 120, 125,
	127, 129, 131, 133, 135,	140, 145, 150, 150, 150
    };
    int dam;
    int armor = 0;
    level	= UMIN(level, sizeof(dam_each)/sizeof(dam_each[0]) - 1);
    level	= UMAX(0, level);
    dam		= number_range( 2 * dam_each[level]/3, dam_each[level] * 2 );
        if ( !IS_OUTSIDE(ch) )
    {
        send_to_char( "Inside? Are you joking?!.\n\r", ch );
        return;
    }
    if ( ( mud_data.weather_info.sky < SKY_RAINING
           || temp_adjust( ch->in_room->temp ) <= 35)
         && !IS_IMMORTAL(ch))
    {
        send_to_char( "The sky seems a bit too clear.\n\r", ch );
        return;
    }
    act("You summon the force of thunder storm to your aid.",ch,NULL,NULL,TO_CHAR );
    act("$n calls upon the forces of nature and calls forth a thunder storm.",ch,NULL,NULL,TO_ROOM);
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
        vch_next = vch->next_in_room;
        if ( saves_spell( level, vch, DAM_LIGHTNING,skill_table[sn].spell_type) )
	    dam /= 2;
//We give bonus to the spell for the ac person has. (ac is n've so we subtr.)
//bonus is 1/2 value over 150, and regular over 200.
	armor = -(vch->armor[0] + vch->armor[1] +vch->armor[2])/3;
	if (armor > 200)
	  act("Sparks arc around $n's armor!", vch, NULL, NULL, TO_ROOM);
	dam += UMAX(0 ,(armor-150)/2);
	dam += UMAX(0, (armor - 200));
	dam = UMIN(300, dam);
//And we apply damage.
	if ( vch != ch && !is_area_safe(ch,vch))
	{
	    m_yell(ch,vch,FALSE);
            damage( ch, vch, dam, sn, DAM_LIGHTNING,TRUE);    
	}
    }
}

void spell_esuna( int sn, int level, CHAR_DATA *ch, void *vo, int target )
{
    bool found = FALSE;
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    if (IS_EVIL(victim))
    {
	sendf(ch,"Your god does not like %s.\n\r",PERS(victim,ch));
	return;
    }
    if (victim != ch)
    {
    	act("$n soothes you with a glow of white light.",ch,NULL,victim,TO_VICT);
    	act("You cure $N of $S ailments.",ch,NULL,victim,TO_CHAR);
    }
    if (check_dispel(level+2,victim,gsn_poison))
	found = TRUE;
    if (check_dispel(level+2,victim,gsn_death_grasp))
	found = TRUE;
    if (check_dispel(level+2,victim,gsn_plague))
	found = TRUE;
    if (!is_song_affected(victim,gsn_unforgiven) && check_dispel(level+2,victim,gsn_curse))
	found = TRUE;
    if (check_dispel(level+2,victim,gsn_blindness))
	found = TRUE;
    if (check_dispel(level+2,victim,gsn_sleep))
	found = TRUE;
    if (check_dispel(level+2,victim,gsn_silence))
	found = TRUE;
    if (check_dispel(level+2,victim,gsn_blasphemy))
	found = TRUE;
    if (check_dispel(level+2,victim,gsn_hysteria))
	found = TRUE;
    if (check_dispel(level+2,victim,skill_lookup("weaken")))
	found = TRUE;
    if (check_dispel(level+2,victim,gsn_insomnia))
	found = TRUE;
    if (check_dispel(level+2,victim,skill_lookup("dysentery")))
	found = TRUE;
    if (check_dispel(level,victim,gsn_ecstacy))
	found = TRUE;
    if (check_dispel(level,victim,gsn_drug_use))
	found = TRUE;
    if (found)
    {
	act("$n looks more relieved.",victim,NULL,NULL,TO_ROOM);
	send_to_char("A warm glow runs through your body.\n\r",victim);
        if (!IS_NPC(ch) && !IS_NPC(victim) && ch->class == class_lookup("healer") &&  ch != victim)
            gain_exp(ch,number_range(1,ch->level/8));
    }
    else
    {
	act("$N does not seem to be affected.",ch,NULL,victim,TO_CHAR);
	send_to_char("You don't feel any different.\n\r",victim);
    }
}

void spell_holy_water(int sn,int level,CHAR_DATA *ch, void *vo,int target)
{
    OBJ_DATA *obj = (OBJ_DATA *) vo;
    AFFECT_DATA af;
    int liquid = obj->value[2];
    if( is_affected(ch,sn) )
    {
	send_to_char("You are not ready to bless more water yet.\n\r",ch);
	return;
    }
    if (obj->item_type != ITEM_DRINK_CON)
    {
        send_to_char("That isn't a drink container.\n\r",ch);
        return;
    }
    if (obj->wear_loc != -1)
    {
        send_to_char("The item must be carried to be blessed.\n\r",ch);
        return;
    }
    if ( obj->value[1] <= 0 )
    {
        send_to_char( "It is already empty.\n\r", ch );
        return;
    }
    if ( obj->value[1] > 250 )
    {
        send_to_char( "There is too much water for you to bless.\n\r", ch );
        return;
    }
    if ( liquid != 0 )
    {
	send_to_char("You can only bless pure water.\n\r",ch);
	return;
    }
    act("The water in $p glows as you bless it with your faith.",ch,obj,NULL,TO_CHAR);
    act("The water in $p glows as $n prays with $s hand over it.",ch,obj,NULL,TO_ROOM);
    obj->value[2] = 1;
    obj->value[3] = 0;
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 48;
    af.modifier  = 0;  
    af.location  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );
}

void spell_barrier( 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("You are already surrounded by a shield.\n\r",ch);
        return;
    }
    if (is_affected(victim, skill_lookup("divine retribution")))
    {
	send_to_char("You must wait for your divine retribution to wear off.\n\r",ch);
	return;
    }
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = number_fuzzy( level/9);
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = AFF_BARRIER;
    affect_to_char( victim, &af );
    act( "You are enclosed in a physical barrier.", ch, NULL, NULL, TO_CHAR );
    act( "$n is encased by a transparent sphere.", ch, NULL, NULL, TO_ROOM );
}

void spell_vitalize( 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 (ch != victim)
	    send_to_char("Their metabolism has already been increased.\n\r",ch);
	else
	    send_to_char("Your metabolism is at its peak!\n\r",ch);
	return;
    }
    if (IS_GOOD(ch) && IS_EVIL(victim))
    {
	sendf(ch,"Your god does not like %s.\n\r",PERS(victim,ch));
	return;
    }
    if (IS_GOOD(victim) && IS_EVIL(ch))
    {
	sendf(ch,"Your god does not like %s.\n\r",PERS(victim,ch));
	return;
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = number_fuzzy( level/5);
    af.location  = APPLY_CON;
    af.modifier  = 2;
    af.bitvector = 0;
    affect_to_char( victim, &af );
    if (ch != victim)
	act("You vitalize $N's metabolism.",ch,NULL,victim,TO_CHAR);
    send_to_char("You are filled with energy as your metabolism increases!\n\r",victim);
    act("$n seems to be more energetic.",victim,NULL,NULL,TO_ROOM);
}

void spell_sacrifice( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;   
    if (is_affected(ch,sn))
    {
        send_to_char("Your body has not recovered from the last sacrifice!\n\r",ch);
        return;
    }
    if (ch == victim)
    {
        send_to_char("This spell must be casted on someone else.\n\r",ch); 
	return;
    }
    if (ch->hit < ch->max_hit/3 || ch->mana < ch->max_mana/3 || ch->move < ch->max_move/3)
    {
	send_to_char("You body is in no condition to perform a sacrifice.\n\r",ch);
	return;
    }
    if (IS_EVIL(victim))
    {
	sendf(ch,"Your god does not like %s.\n\r",PERS(victim,ch));
	return;
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 24;
    af.location  = 0;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );
    af.type	 = gsn_drained;
    af.duration  = 5;
    affect_to_char( ch, &af );
    ch->hit = UMAX(1,ch->max_hit * .05);
    ch->mana = UMAX(1,ch->max_mana * .05);
    ch->move = UMAX(1,ch->max_move * .05);
    ch->position = POS_RESTING;
    affect_strip(victim,gsn_plague);
    affect_strip(victim,gsn_poison);
    affect_strip(victim,gsn_blindness);
    victim->hit = victim->max_hit;
    victim->mana = victim->max_mana;
    victim->move = victim->max_move;
    update_pos(victim);
    act("You sacrifice your own health to restore $N!",ch,NULL,victim,TO_CHAR);
    act("$n passes on $s life energy into your body!",ch,NULL,victim,TO_VICT);
    act("$n slumps to the ground as $e passes $s life onto $N.",ch,NULL,victim,TO_NOTVICT);
}

void spell_heavens_gate( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    char arg[MIL];
    bool gate_pet;
    ROOM_INDEX_DATA *room;
    if (IS_NPC(ch))
	return;
    one_argument(target_name, arg);
    if (arg[0] == '\0')
    {
    	if (ch->pcdata->beacon == 0 || (room = get_room_index(ch->pcdata->beacon)) == NULL)
    	{
	    send_to_char("You do not have a marker set.\n\r",ch);
	    return;
    	}

	if (!IS_NPC(ch) && ch->pcdata->pStallion != NULL)
	  {
	    send_to_char("Your mount refuses to enter the gate.\n\r",ch);
	    return;
	  }
    	if ( IS_SET(room->room_flags, ROOM_SAFE)
    	|| IS_SET(room->room_flags, ROOM_PRIVATE)
    	|| IS_SET(room->room_flags, ROOM_SOLITARY)
    	|| IS_SET(room->room_flags, ROOM_NO_GATEIN)
    	|| IS_SET(ch->in_room->room_flags, ROOM_NO_GATEOUT)
    	|| IS_SET(ch->in_room->room_flags, ROOM_NO_INOUT)
        || is_affected(ch, gsn_tele_lock)
    	|| IS_SET(room->room_flags, ROOM_NO_INOUT))
    	{
    	    send_to_char("You failed to create a portal.\n\r",ch);
    	    return;
    	}
	else if (is_affected(ch,gen_ensnare)){
	  send_to_char("You sense a powerful magical field preventing your departure.\n\r", ch);
	  return;
	}
    	if (ch->pet != NULL && ch->in_room == ch->pet->in_room)
    	    gate_pet = TRUE;
    	else
    	    gate_pet = FALSE;
    	act("$n steps through a dark portal and vanishes.",ch,NULL,NULL,TO_ROOM);
    	act("You step through a dark portal and vanish.",ch,NULL,NULL,TO_CHAR);
    	char_from_room(ch);
    	char_to_room(ch,room);
    	act("$n has arrived through a gate.",ch,NULL,NULL,TO_ROOM);
    	do_look(ch,"auto");
    	if (gate_pet)
    	{
    	    act("$n steps through a dark portal and vanishes.",ch->pet,NULL,NULL,TO_ROOM);
    	    act("You step through a dark portal and vanish.",ch->pet,NULL,NULL,TO_CHAR);
    	    char_from_room(ch->pet);
    	    char_to_room(ch->pet,room);
    	    act("$n has arrived through a gate.",ch->pet,NULL,NULL,TO_ROOM);
    	    do_look(ch->pet,"auto");
    	}
    }
    else if (!str_cmp(arg, "marker"))
    {
    	if (ch->in_room == NULL)
	    return;
    	if ( IS_SET(ch->in_room->room_flags, ROOM_SAFE)
    	|| IS_SET(ch->in_room->room_flags, ROOM_PRIVATE)
    	|| IS_SET(ch->in_room->room_flags, ROOM_SOLITARY)
    	|| IS_SET(ch->in_room->room_flags, ROOM_NO_GATEIN)
    	|| IS_SET(ch->in_room->room_flags, ROOM_NO_INOUT))
    	{
    	    send_to_char("You failed to set a marker.\n\r",ch);
    	    return;
    	}
    	send_to_char("You mark the area for future use.\n\r",ch);
    	ch->pcdata->beacon = ch->in_room->vnum;
    }
    else
	send_to_char("To place a marker, <syntax: ca 'portal' marker>.\n\r",ch);
}

void spell_rejuvenate( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int heal = dice(3, 20) + level + 30;
    victim->hit = UMIN( victim->hit + heal, victim->max_hit ); 
    update_pos( victim );
    act_new("A jolt of energy runs through you!", ch,NULL,victim,TO_CHARVICT,POS_DEAD );
    if ( ch != victim )
        act("You rejuvenate $N's health.", ch,NULL,victim,TO_CHAR );
}

void spell_prayer( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;  
    if (IS_NPC(victim))
	return;
    if (IS_AFFECTED(victim,AFF_RAGE) || IS_AFFECTED(victim,AFF_BERSERK) || is_affected(victim,skill_lookup("frenzy")))
    {
        if (victim == ch)
            send_to_char("Your prayers cannot reach your gods in your state of mind.",ch); 
        else
	    send_to_char("Your prayer will not reach one in an unstable state of mind.\n\r",ch);
        return;
    }
    if (is_affected(victim,sn))
    {
	if (victim == ch)
	    send_to_char("You are already blessed with a prayer.\n\r",ch);
	else
	    act("$N is already blessed with a prayer.",ch,NULL,victim,TO_CHAR);
	return;
    }
    if (!IS_GOOD(victim))
    {
        act("Your god doesn't seem to like $N",ch,NULL,victim,TO_CHAR);
        return;
    }
    if ( is_affected( victim, gsn_blasphemy ) )
    {   
        sendf(ch, "%s's faith have been lost.\n\r", PERS(victim,ch));
        return;
    }
    if (is_fight_delay(victim,90))
    {
	if (ch == victim)
	    send_to_char("You are too worked up to start a prayer.\n\r",ch);
	else
	    act("$N is too worked up to listen to your prayer.",ch,NULL,victim,TO_CHAR);
	return;
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = level / 2;
    af.modifier  = level / 2;
    af.bitvector = 0;
    af.location  = APPLY_MANA;
    affect_to_char(victim,&af);
    af.modifier  = -level / 10;
    af.location  = APPLY_DAMROLL;
    affect_to_char(victim,&af);
    af.modifier  = level / 12;
    af.location  = APPLY_LUCK;
    affect_to_char(victim,&af);
    af.modifier  = -10 * (level / 12);
    af.location  = APPLY_AC;
    affect_to_char(victim,&af);
    act_new("You are filled with serenity by the prayer.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
    act("$n's eyes are filled with serenity.",victim,NULL,NULL,TO_ROOM);
}

void spell_spirit_shield( 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("You already have a spirit shield.\n\r",victim);
	return;
    }
    act_new("You create a spirit shield on your arm.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
    act("$n creates a spirit shield on $s arm.",victim,NULL,NULL,TO_ROOM);
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = level/10;
    af.modifier  = 0;
    af.bitvector = 0;
    af.location  = 0;
    affect_to_char(victim,&af);
}

void spell_invigorate( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *vch, *vch_next;
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
        vch_next = vch->next_in_room;
	if (vch->master == ch || is_same_group(vch, ch))
        {
	    if (IS_EVIL(vch))
	    {
		sendf(ch,"Your god does not like %s.\n\r",PERS(vch,ch));
		return;
	    }
	    vch->move = vch->max_move;
	    check_dispel(level,vch,skill_lookup("enfeeblement"));
	    act_new("Your weariness is alleviated from your feet.", ch,NULL,vch,TO_CHARVICT,POS_DEAD );
	    if ( ch != vch )
	        act("You renergize the strength of $N's feet.", ch,NULL,vch,TO_CHAR );
	}
    }
}

void spell_group_recall( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *vch, *vch_next;
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
        vch_next = vch->next_in_room;
	if ( vch->pCabal && IS_CABAL(get_parent(vch->pCabal), CABAL_NOMAGIC))
	  continue;
	if (vch->master == ch || is_same_group(vch, ch))
	  spell_word_of_recall(skill_lookup("word of recall"),level,ch,(void *) vch,TARGET_CHAR);
    }
}

void spell_blasphemy( 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's faith has already been shaken.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if ( saves_spell(level, victim, DAM_OTHER,skill_table[sn].spell_type) )
    {	
	if ( ch != victim )
	    act("You fail to taint $N's faith.",ch,NULL,victim,TO_CHAR);
	send_to_char("You remain true to your faith.\n\r",victim);
	return;
    }
    act_new("Your faith shatters as you have doubts about your religion!",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
    if ( ch != victim )
        act("$N is plagued by doubts of $s own faith!",ch,NULL,victim,TO_CHAR);
    af.where     = TO_AFFECTS; 
    af.type      = sn;
    af.level     = level;
    af.location  = 0;
    af.duration  = level/8;
    af.bitvector = 0;
    af.modifier  = 0;
    affect_to_char(victim,&af);
}

void spell_demonic_visage( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    OBJ_DATA *obj;
    AFFECT_DATA af;
    if ( ch == victim )
    {
	send_to_char("You try to scare yourself without much success.\n\r",ch);
	return;
    }
    if ( is_affected(victim, sn))
    {
        act("$N still cannot shake the images of demons from $s mind.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if (!can_see(victim,ch) || ch->position <= POS_SLEEPING)
    {
        act("$N cannot see your demonic visage.",ch,NULL,victim,TO_CHAR);
        return;
    }
    send_to_char("You peel away your face to reveal your demonic image.\n\r",ch);
    act("$n peels $s face away to reveal $s demonic image.",ch,NULL,NULL,TO_ROOM);
    if ( ( obj = get_eq_char( victim, WEAR_WIELD ) ) == NULL && ( obj = get_eq_char( victim, WEAR_SECONDARY ) ) == NULL )
    {
	send_to_char("Your opponent is not using a weapon.\n\r",ch);
        return;
    }
    if ( saves_spell(level, victim, DAM_OTHER,skill_table[sn].spell_type) )
    {	
	act("$N is not affected by your demonic appearance.",ch,NULL,victim,TO_CHAR);
	act("$n's demonic appearance does not affect you.",ch,NULL,victim,TO_VICT);
	return;
    }
    send_to_char("You drop your weapon as you are taken back by the horrifying image!\n\r",victim);
    act( "$n almost drops $p.", victim, obj, NULL, TO_ROOM );
    unequip_char( ch, obj );
    af.where     = TO_AFFECTS; 
    af.type      = sn;
    af.level     = level;
    af.location  = 0;
    af.duration  = 2;
    af.bitvector = 0;
    af.modifier  = 0;
    affect_to_char(victim,&af);
}

void spell_blanket_darkness( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    ROOM_INDEX_DATA * room;
    AFFECT_DATA af;
    int np = number_percent();
    if (ch->in_room == NULL)
	return;
    room = ch->in_room;
    if (is_affected(ch,sn))
    {
	send_to_char("You are not ready to blanket another room.\n\r",ch);
	return;
    }
    if (room->sector_type == SECT_CITY || IS_SET(room->area->area_flags,AREA_CITY))
    {
	send_to_char("There are too many lights in the city.\n\r",ch);
	return;
    }
    if (room->pCabal)
    {
	send_to_char("Not in a cabal.\n\r",ch);
	return;
    }
    if (np - 2*(get_curr_stat(ch,STAT_LUCK) - 16) < 50)
    {
	send_to_char("You failed to blanket this room in darkness.\n\r",ch);
    	af.where     = TO_AFFECTS; 
    	af.type      = sn;
    	af.level     = level;
    	af.location  = 0;
    	af.duration  = 12;
    	af.bitvector = 0;
    	af.modifier  = 0;
    	affect_to_char(ch,&af);    
	return;
    }
    if (IS_SET(room->room_flags,ROOM_NO_SCAN))
    {
	send_to_char("This room is already covered in darkness.\n\r",ch);
	return;
    }
    send_to_char("You enshroud the room with a blanket of darkness.\n\r",ch);
    act("A blanket of darkness enshrouds the room.",ch,NULL,NULL,TO_ROOM);
    SET_BIT(room->room_flags,ROOM_NO_SCAN);
    SET_BIT(room->room_flags,ROOM_DARK);
    SET_BIT(room->room_flags,ROOM_NOWHERE);
    SET_BIT(room->room_flags,ROOM_INDOORS);
    SET_BIT(room->room_flags,ROOM_NO_INOUT);
    af.where     = TO_AFFECTS; 
    af.type      = sn;
    af.level     = level;
    af.location  = 0;
    af.duration  = 100;
    af.bitvector = 0;
    af.modifier  = 0;
    affect_to_char(ch,&af);    
}

void spell_enfeeblement( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    int dam;
    if ( ch != victim )
        act("You drain the strength from $N's legs!",ch,NULL,victim,TO_CHAR);
    send_to_char("Your legs feel sluggish as their strength are drained.\n\r",victim);
    dam = UMAX( 1 * victim->move / 10, 15);
    victim->move = UMAX(0, (victim->move - dam));
    if ( !is_affected(victim, sn) && !saves_spell(level, victim, DAM_OTHER,skill_table[sn].spell_type) )
    {
	if (ch != victim )
	   act("$N's legs are exhausted by your enfeeblement.",ch,NULL,victim,TO_CHAR);
	send_to_char("Your legs collapse from exhaustion.\n\r",victim);
    	af.where     = TO_AFFECTS; 
    	af.type      = sn;
    	af.level     = level;
    	af.location  = 0;
    	af.duration  = level / 8;
    	af.bitvector = 0;
    	af.modifier  = 0;
    	affect_to_char(victim,&af);
    }
}
void spell_hysteria( 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 in hysteria.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if ( saves_spell(level - 3, victim, DAM_OTHER,skill_table[sn].spell_type) )
    {	
	if ( ch != victim )
	    act("You fail to bring $N into hysteria.",ch,NULL,victim,TO_CHAR);
	send_to_char("You momentarily filled with anxiety but manage to keep your wits together.\n\r",victim);
	return;
    }
    act_new("You start to panic as you enter a state of hysteria!",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
    if ( ch != victim )
        act("$N starts to panic from $S hysteria!",ch,NULL,victim,TO_CHAR);
    af.where     = TO_AFFECTS; 
    af.type      = sn;
    af.level     = level;
    af.location  = 0;
    af.duration  = 5;
    af.bitvector = 0;
    af.modifier  = 0;
    affect_to_char(victim,&af);
}
/* SPELL MASS HYSTERIA
   General effects: hysteria, area.
   Coded By:        Athaekeetha
*/

void spell_mass_hysteria (int sn, int level, CHAR_DATA *ch, void *vo,int target )
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  CHAR_DATA *vch, *vch_next;

  /* first hit the target */
  spell_hysteria( gsn_hysteria, level, ch, victim, target) ;

  /* then anyone grouped with target */
  for (vch = victim->in_room->people; vch; vch = vch_next){
    vch_next = vch->next_in_room;
    
    if (!is_same_group(vch, victim))
      continue;
    else if (vch == victim)
      continue;
    else if (is_area_safe_quiet( vch, ch))
      continue;
    else
      spell_hysteria( gsn_hysteria, level, ch, vch, target) ;
    m_yell(ch,vch,FALSE);
    if (vch->fighting == NULL)
      set_fighting(vch, ch );
  }
}

void spell_ethereal_passage( int sn, int level, CHAR_DATA *ch, void *vo,int target) {
  ROOM_INDEX_DATA* old;
  char arg[MIL];
  int door;
  bool fClear = TRUE;
  
  target_name = one_argument( target_name, arg );
  
  if ( arg[0] == '\0' ){
    send_to_char("What direction? <north/east/south/west/up/down>\n\r",ch);
    return;
  }
  if (!IS_NPC(ch) && ch->pcdata->pStallion != NULL){
    send_to_char("Your mount refuses to enter the passage.\n\r",ch);
    return;
  }
  if (!str_cmp(arg,"north") || !str_cmp(arg,"n"))
    door = DIR_NORTH;
  else if (!str_cmp(arg,"east") || !str_cmp(arg,"e"))
    door = DIR_EAST;
  else if (!str_cmp(arg,"south") || !str_cmp(arg,"s"))
    door = DIR_SOUTH;
  else if (!str_cmp(arg,"west") || !str_cmp(arg,"w"))
    door = DIR_WEST;
  else if (!str_cmp(arg,"up") || !str_cmp(arg,"u"))
    door = DIR_UP;
  else if (!str_cmp(arg,"down") || !str_cmp(arg,"d"))
    door = DIR_DOWN;
  else
    {
      send_to_char("That direction does not exist. <north/east/south/west/up/down>\n\r",ch);
      return;
    }
  act("$n creates an ethereal passage.",ch,NULL,NULL,TO_ROOM);
  act("You create an ethereal passage.",ch,NULL,NULL,TO_CHAR);

  if (!IS_AFFECTED(ch, AFF_PASS_DOOR)){
    SET_BIT(ch->affected_by, AFF_PASS_DOOR );
    fClear = TRUE;
  }
  old = ch->in_room;
  move_char( ch, door, FALSE );

  if (fClear){
   REMOVE_BIT(ch->affected_by, AFF_PASS_DOOR );
   affect_check(ch, TO_AFFECTS, AFF_PASS_DOOR);
  }
  if (ch->in_room == old)
    act("An ethereal passage fizzles and closes.",ch,NULL,NULL,TO_ALL);
  else
    act("An ethereal passage opens and $n steps out.",ch,NULL,NULL,TO_ROOM);

}

void spell_insomnia( 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 already has insomnia.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if ( saves_spell(level, victim, DAM_OTHER,skill_table[sn].spell_type) )
    {	
	if ( ch != victim )
	    act("You fail to deprive $N of sleep.",ch,NULL,victim,TO_CHAR);
	send_to_char("You resist the plague of insomnia.\n\r",victim);
	return;
    }
    act_new("You no longer feel the need to sleep!",ch,NULL,victim,TO_CHARVICT,POS_DEAD);
    if ( ch != victim )
        act("You manage to infect $N with insomnia!",ch,NULL,victim,TO_CHAR);
    af.where     = TO_AFFECTS; 
    af.type      = sn;
    af.level     = level;
    af.location  = 0;
    af.duration  = 12;
    af.bitvector = 0;
    af.modifier  = 0;
    affect_to_char(victim,&af);
}

void spell_dysentery( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af, *paf;
    if ( is_affected(victim, sn))
    {
        act("$N already has dysentery.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if (IS_NPC(victim))
    {
	send_to_char("Mobs are not affected by nutrition.\n\r",ch);
	return;
    }
    if ( ch == victim || saves_spell(level, victim, DAM_DISEASE,skill_table[sn].spell_type) )
    {	
	if ( ch != victim )
	    act("You fail to disrupt $N's bowel movements.",ch,NULL,victim,TO_CHAR);
	send_to_char("Your stomach rumbles softly, but you manage to suppress the urge.\n\r",victim);
	return;
    }
    victim->position = POS_SITTING;
    update_pos(victim);
    act_new("You feel drained as your intestinal tracks goes haywire!",ch,NULL,victim,TO_CHARVICT,POS_DEAD);    
    act("$n's face changes color as $e grabs $s stomach in agonizing pain!",victim,NULL,NULL,TO_ROOM);    
    send_to_char("You quickly crouch on the ground as fecal matter explodes from your rear.\n\r",victim);
    act("$n crouches on the ground wincing painfully as fecal matter is expelled from $s rear.",victim,NULL,NULL,TO_ROOM);
    act("A strong odor fills the room.",victim,NULL,NULL,TO_ROOM);
    victim->pcdata->condition[COND_HUNGER] = 2;
    defecate(victim);
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.location  = 0;
    af.duration  = 8;
    af.bitvector = 0;
    af.modifier  = 0;
    paf = affect_to_char(victim,&af);
    if (!IS_NPC(ch))
      string_to_affect( paf, ch->name );
}

void spell_phantom_grasp( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af, *paf;
    int dam = number_range( 1, 5);
    int mod = (get_skill(ch, sn ) - 75) * 2;
    int chance = 50 + mod;

    act("You consume $N with the phantoms of the underworld.",ch,NULL,victim,TO_CHAR);
    act("You are consumed by the phantoms of the underworld.",victim,NULL,NULL,TO_CHAR);
    act("$N is consumed by the phantoms of the underworld.",ch,NULL,victim,TO_NOTVICT);

    paf = affect_find(victim->affected,sn);

    if ( saves_spell( level + (mod / 10), victim,DAM_NEGATIVE,skill_table[sn].spell_type) ){

      chance /= 2;
    }
    damage( ch, victim, dam, sn, DAM_NEGATIVE ,TRUE);
    if (number_percent() < chance ){
	af.where     = TO_AFFECTS2;
	af.type      = sn;
	af.level     = level;
	af.duration  = number_range(1, 3);
	af.location  = APPLY_SAVING_SPELL;
	af.modifier  = number_range(1, 3);;
	af.bitvector = 0;
	if (paf == NULL){
	  affect_to_char( victim, &af );	
	}
	else{
	  if (paf->duration > 24)
	    af.duration = 0;
	  if (paf->modifier > 14)
	    af.modifier = 0;
	  else{
	    act("The phantoms drains $n of $s magical resistence.",victim,NULL,NULL,TO_ROOM);
	    act("The phantoms drains you of your magical resistence.",victim,NULL,NULL,TO_CHAR);
	  }
	  affect_join( victim, &af );	
	}

    }
    else{
      send_to_char("You failed.\n\r", ch);
    } 
}

void spell_dark_shroud( 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("You are already surrounded by a dark shroud.\n\r",victim);
        return;
    }
    send_to_char("You envelop yourself in a dark shroud.\n\r",ch);
    act("$n is enveloped in a dark shroud.",ch,NULL,NULL,TO_ROOM);
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.location  = 0;
    af.modifier  = 0;
    af.duration  = level/2;
    af.bitvector = 0;
    affect_to_char(victim,&af);
}

void spell_deteriorate( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    int saves = 0;

    if ( is_affected(victim, sn))
    {
        act("$N is already deteriorated.",ch,NULL,victim,TO_CHAR);
        return;
    }

    //calc_saves reports saves chance with the base 40 included (5-95)
    saves = URANGE(0, calc_saves(level, victim, DAM_OTHER, skill_table[sn].spell_type) - 40, 55);

/* the spell level increases past 30 saves at rate of 2 level for 3 saves over 30.
   this results in final svs change of -2 per save over 30.
   At  0:  0 + 60 = 60
   At 10: 10 + 40 = 50
   At 20: 20 + 20 = 40
   At 30: 30 -  0 = 30
   At 40: 40 - 20 = 20
   At 50: 50 - 40 = 10
   At 55: 55 - 50 =  5
*/
    if ( saves_spell(level + 2 * (saves - 30) / 3, victim, DAM_OTHER, skill_table[sn].spell_type) ){
      if ( ch != victim )
	act("You fail to deteriorate $N.",ch,NULL,victim,TO_CHAR);
      act("You resist $n's deterioration.",ch,NULL,victim,TO_VICT);
      return;
    }
    if (ch != victim )
      act("You deteriorate $N's defenses.",ch,NULL,victim,TO_CHAR);
    send_to_char("You defense lowers from deterioration.\n\r",victim);
    
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.location  = APPLY_AC;
    af.modifier  = level;
    af.duration  = number_range(10, 24);
    af.bitvector = 0;
    affect_to_char(victim,&af);
    af.location  = APPLY_SAVING_SPELL;   
    af.modifier  = 4 * saves / 10;
    affect_to_char( victim, &af );
}

void spell_cure_dysentery( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    if ( !is_affected( victim, skill_lookup("dysentery") ) )
    {
        if (victim == ch)
            act("You don't have dysentery.",ch,NULL,victim,TO_CHAR);
        else
            act("$N doesn't seem to have dysentery.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if (check_dispel(level - 3,victim,skill_lookup("dysentery")))
    {
        act_new("A feeling of relieve runs through your body.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
        act("$n looks relieved.",victim,NULL,NULL,TO_ROOM);   
    }
    else
        act("You failed to cure $N of dysentery.",ch,NULL,victim,TO_CHAR); 
}

void spell_cure_insomnia( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    if ( !is_affected( victim, gsn_insomnia ) )
    {
        if (victim == ch)
            act("You don't have insomnia.",ch,NULL,victim,TO_CHAR);
        else
            act("$N doesn't seem to have insomnia.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if (check_dispel(level-3,victim,gsn_insomnia))
    {
        act_new("A familiar feeling of fatigue returns to your body.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
        act("$n looks more relaxed.",victim,NULL,NULL,TO_ROOM);   
    }
    else
        act("You failed to cure $N of insomnia.",ch,NULL,victim,TO_CHAR); 
}

void spell_remove_hysteria( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    if ( !is_affected( victim, gsn_hysteria ) )
    {
        if (victim == ch)
            act("You are not affected by hysteria.",ch,NULL,victim,TO_CHAR);
        else
            act("$N doesn't appear to be affected by hysteria.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if (check_dispel(level,victim,gsn_hysteria))
    {
        act_new("You recollect your thoughts and your wits.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
        act("$n looks steadier.",victim,NULL,NULL,TO_ROOM);   
    }
    else
        act("You failed to remove $N of $s hysteria.",ch,NULL,victim,TO_CHAR); 
}

void spell_accession( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    AFFECT_DATA af;
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    int dur;
    if (IS_NPC(victim))
    {
	send_to_char("Mobs cannot be affected.\n\r",ch);
	return;
    }
    if ( is_affected( victim, sn ) )
    {
        if (victim == ch)
            act("You are not ready tap into your hidden potential.",ch,NULL,victim,TO_CHAR);
        else
            act("$N is not ready to tap into $S hidden potential.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if (IS_EVIL(victim))
    {
	send_to_char("It is against your belief to help evils.\n\r",ch);
	return;
    }
    send_to_char("Your hidden potential is unleashed.\n\r",victim);
    dur = number_fuzzy(level/7);
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.location  = 0;
    af.modifier  = 0;
    af.duration  = dur+6;
    af.bitvector = 0;
    affect_to_char( victim, &af );
    af.duration  = dur;
    if (ch == victim )
    {
    	af.location  = APPLY_DAMROLL;
    	af.modifier  = level / 15;
   	affect_to_char( victim, &af );
    	af.location  = APPLY_HITROLL;
    	af.modifier  = level / 15;
   	affect_to_char( victim, &af );
    	af.location  = APPLY_SAVING_SPELL;   
    	af.modifier  = - level / 5;
    	affect_to_char( victim, &af );
    	af.location  = APPLY_AC;
    	af.modifier  = - level;
    	affect_to_char(victim,&af);
    	af.location  = APPLY_MOVE;   
    	af.modifier  = 2*level;
    	affect_to_char( victim, &af );
    	af.location  = APPLY_MANA;   
    	af.modifier  = level;
    	affect_to_char( victim, &af );
    	af.location  = APPLY_HIT;   
    	af.modifier  = level;
	victim->hit += level;
	victim->mana += level;
	victim->move += 2*level;
    	affect_to_char( victim, &af );
    	af.location  = APPLY_CON;
    	af.modifier  = level / 25;
   	affect_to_char( victim, &af );
    	af.location  = APPLY_DEX;
    	af.modifier  = level / 15;
   	affect_to_char( victim, &af );
    	af.location  = APPLY_WIS;
    	af.modifier  = level / 8;
   	affect_to_char( victim, &af );
    	af.location  = APPLY_INT;
    	af.modifier  = level / 10;
   	affect_to_char( victim, &af );
    	af.location  = APPLY_STR;
    	af.modifier  = level / 20;
   	affect_to_char( victim, &af );
    }
    else
    {
    	act("You unleash $N's hidden potential.",ch,NULL,victim,TO_CHAR);
	level = victim->level;
    	if (victim->class == class_lookup("warrior"))
    	{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 7;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - level / 2;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = level / 2;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level / 5;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level/2;
	    affect_to_char( victim, &af );
	    victim->hit += level/2;
	    victim->mana += level/5;
	    victim->move += level/2;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 18;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	}
    	else if (victim->class == class_lookup("berserker"))
    	{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 7;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 12;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - level/3;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = level / 3;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level;
	    affect_to_char( victim, &af );
	    victim->hit += level;
	    victim->mana += level/15;
	    victim->move += level/3;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 25;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 25;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	}
    	else if (victim->class == class_lookup("thief") || victim->class == class_lookup("bard"))
    	{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 7;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - level;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = 3*level/2 ;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level / 3;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level / 3;
	    affect_to_char( victim, &af );
	    victim->hit += level/3;
	    victim->mana += level/3;
	    victim->move += level/2;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 18;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 18;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	}
    	else if (victim->class == class_lookup("ranger"))
    	{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 11;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 11;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 6;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - 2*level/3;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = level;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level / 4;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level / 2;
	    affect_to_char( victim, &af );
	    victim->hit += level;
	    victim->mana += level/4;
	    victim->move += level/2;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 17;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	}
    	else if (victim->class == class_lookup("ninja"))
    	{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 5;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - 2*level/3;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = level / 2;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level / 3;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level / 3;
	    affect_to_char( victim, &af );
	    victim->hit += level/3;
	    victim->mana += level/3;
	    victim->move += level/2;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 17;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	}
    	else if (victim->class == class_lookup("paladin"))
    	{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 8;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - level/2;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = level / 2;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level / 3;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level / 3;
	    affect_to_char( victim, &af );
	    victim->hit += level/3;
	    victim->mana += level/3;
	    victim->move += level/2;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	}
    	else if (victim->class == class_lookup("healer"))
    	{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 7;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - level/2;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = level;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level/2;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level/2;
	    affect_to_char( victim, &af );
	    victim->hit += level/2;
	    victim->mana += level/2;
	    victim->move += level;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	}
    	else if (victim->class == class_lookup("battlemage") || victim->class == class_lookup("invoker"))
    	{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 4;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - level;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = level;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level / 5;
	    affect_to_char( victim, &af );
	    victim->hit += level/5;
	    victim->mana += level;
	    victim->move += level;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 25;
	    affect_to_char( victim, &af );
	}
	else{
	    af.location  = APPLY_DAMROLL;
	    af.modifier  = level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HITROLL;
	    af.modifier  = level / 7;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_SAVING_SPELL;   
	    af.modifier  = - level / 10;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_AC;
	    af.modifier  = - level / 2;
	    affect_to_char(victim,&af);
	    af.location  = APPLY_MOVE;   
	    af.modifier  = level / 2;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_MANA;   
	    af.modifier  = level / 5;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_HIT;   
	    af.modifier  = level/2;
	    affect_to_char( victim, &af );
	    victim->hit += level/2;
	    victim->mana += level/5;
	    victim->move += level/2;
	    af.location  = APPLY_CON;
	    af.modifier  = level / 15;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_DEX;
	    af.modifier  = level / 18;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_WIS;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_INT;
	    af.modifier  = level / 20;
	    affect_to_char( victim, &af );
	    af.location  = APPLY_STR;
	    af.modifier  = level / 12;
	    affect_to_char( victim, &af );
	}
    }
}

void spell_morph( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    char arg[MIL];
    int chance = number_percent();
    AFFECT_DATA af;
    target_name = one_argument(target_name, arg);
    if (is_affected(ch,gsn_bat_form) || is_affected(ch,gsn_wolf_form) || is_affected(ch,gsn_mist_form))
    {
	send_to_char("You are already morphed.\n\r",ch);
	return;
    }
    if (arg[0] == '\0')
    {
        send_to_char("syntax: cast 'morph' <form>.\n\r",ch);
        return;
    }

    chance -= 2*(get_curr_stat(ch,STAT_LUCK) - 16);
    if (!str_cmp(arg, "bat") && chance < get_skill(ch,gsn_bat_form))
    {
      const int cost = skill_table[gsn_bat_form].min_mana;
      if (ch->mana < cost){
	send_to_char("You cannot concentrate sufficiently.\n\r", ch);
	return;
      }
      else
	ch->mana -= cost;

      affect_strip(ch, gen_conceal);
	send_to_char("You submit yourself to the sweet agony of transformation and take form of a bat.\n\r",ch);
	act("Shadows thicken around $n as his flesh melds itself into a bat.",ch,NULL,NULL,TO_ROOM);
    	af.where     = TO_AFFECTS;
    	af.type      = gsn_bat_form;
    	af.level     = level;
    	af.duration  = 12;
    	af.location  = APPLY_SIZE;
    	af.modifier  = -2;  
	af.bitvector = 0;
    	affect_to_char( ch, &af );

    	af.where     = TO_AFFECTS;
    	af.location  = APPLY_DAMROLL;
    	af.modifier  = -20;  
    	af.bitvector = AFF_FLYING;
    	affect_to_char( ch, &af );

	af.where = TO_VULN;
	af.bitvector = VULN_SOUND;
    	af.location  = APPLY_HITROLL;
    	af.modifier  = -15;  
    	affect_to_char( ch, &af );

    	af.location  = APPLY_CON;
    	af.modifier  = -7;  
    	affect_to_char( ch, &af );

    	af.location  = APPLY_DEX;
    	af.modifier  = 5;  
    	affect_to_char( ch, &af );

    	af.location  = APPLY_STR;
    	af.modifier  = -10;  
    	affect_to_char( ch, &af );

	ch->short_descr = str_dup("a vampire bat");
	ch->dam_type = 10;
	check_improve(ch,gsn_bat_form,TRUE,1);
	return;
    }
    else if (!str_cmp(arg, "wolf") && chance < get_skill(ch,gsn_wolf_form))
    {
      const int cost = skill_table[gsn_wolf_form].min_mana;
      if (ch->mana < cost){
	send_to_char("You cannot concentrate sufficiently.\n\r", ch);
	return;
      }
      else
	ch->mana -= cost;
      affect_strip(ch, gen_conceal);
	send_to_char("You submit yourself to the sweet agony of transformation and take form of a wolf.\n\r",ch);
	act("Shadows thicken around $n as his flesh melds itself into a giant wolf.",ch,NULL,NULL,TO_ROOM);
	check_social(ch, "howl", "");
    	af.where     = TO_AFFECTS2;
    	af.type      = gsn_wolf_form;
    	af.level     = level;
    	af.duration  = 12;
    	af.modifier  = 0;  
    	af.location  = APPLY_NONE;
    	af.bitvector = AFF_KEEN_SIGHT;
    	affect_to_char( ch, &af );
    	af.bitvector = 0;
    	af.location  = APPLY_DAMROLL;
    	af.modifier  = - ch->level / 5;
    	affect_to_char( ch, &af );
    	af.location  = APPLY_HITROLL;
    	af.modifier  = ch->level/4;  
    	affect_to_char( ch, &af );
    	af.location  = APPLY_AC;
    	af.modifier  = -ch->level*3;  
    	affect_to_char( ch, &af );
    	af.location  = APPLY_DEX;
    	af.modifier  = 5;  
    	affect_to_char( ch, &af );
    	af.location  = APPLY_STR;
    	af.modifier  = -1;  
    	affect_to_char( ch, &af );
	ch->short_descr = str_dup("a vampire wolf");
	ch->dam_type = 5;
	check_improve(ch,gsn_wolf_form,TRUE,1);
	return;
    }
    else if (!str_cmp(arg, "mist") && chance < get_skill(ch,gsn_mist_form))
    {
      const int cost = skill_table[gsn_mist_form].min_mana;
      if (ch->mana < cost){
	send_to_char("You cannot concentrate sufficiently.\n\r", ch);
	return;
      }
      else
	ch->mana -= cost;
      affect_strip(ch, gen_conceal);
	send_to_char("You submit yourself to the sweet agony of transformation and disperse into fine mist.\n\r",ch);
	act("$n evaporates into a fine cloud of mist.",ch,NULL,NULL,TO_ROOM);
    	af.where     = TO_AFFECTS;
    	af.type      = gsn_mist_form;
    	af.level     = level;
    	af.duration  = 12;
    	af.modifier  = 0;  
    	af.location  = APPLY_NONE;
    	af.bitvector = AFF_PASS_DOOR;
    	affect_to_char( ch, &af );
    	af.bitvector = 0;
    	af.location  = APPLY_DAMROLL;
    	af.modifier  = -ch->damroll;  
    	af.bitvector = AFF_FLYING;
    	affect_to_char( ch, &af );
    	af.location  = APPLY_HITROLL;
    	af.modifier  = -ch->hitroll;  
    	affect_to_char( ch, &af );
    	af.location  = APPLY_CON;
    	af.modifier  = -5;  
    	affect_to_char( ch, &af );
    	af.location  = APPLY_DEX;
    	af.modifier  = -5;  
    	affect_to_char( ch, &af );
    	af.location  = APPLY_STR;
    	af.modifier  = -10;  
    	affect_to_char( ch, &af );

	ch->short_descr = str_dup("a cloud of mist");
	check_improve(ch,gsn_mist_form,TRUE,1);
	return;
    }
    else
    {
	send_to_char("You failed to begin the Transformation.\n\r",ch);
	return;
    }
}

void spell_dark_meta( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    AFFECT_DATA af;
    AFFECT_DATA* paf;
    OBJ_DATA* obj = (OBJ_DATA*) vo;

  if (obj->item_type != ITEM_WEAPON)
    {
      send_to_char("That item is not a weapon.\n\r",ch);
      return;
    }

  if (obj->wear_loc == WEAR_NONE)
    {
      send_to_char("You must have the item equipped.\n\r", ch);
      return;
    }

    if ( (paf = affect_find(obj->affected, gen_dark_meta)) != NULL)
    {
      if (paf->modifier++ < 3)
	{
	  act("You fortify your link to $p.",ch, obj, NULL, TO_CHAR);
	  act("$p's surface ripples slightly.", ch, obj, NULL, TO_ROOM);
	  paf->duration += 2;
	}
      else
	send_to_char("You have reached the limit of your abilities.\n\r", ch);
	  return;
    }

    act("You transform $p and attune it to your hunger.",ch, obj, NULL, TO_CHAR);
    act("$p's surface ripples and it seems to meld itself into $n's hand.", ch, obj, NULL, TO_ROOM);

    af.where     = TO_NONE;
    af.type      = gen_dark_meta;
    af.level     = level;
    af.duration  = 6;
    af.location  = APPLY_NONE;
    af.modifier  = 0;  
    af.bitvector = 0;
    affect_to_obj( obj, &af );
}

void spell_soul_steal( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    OBJ_DATA *obj = (OBJ_DATA *) vo;
    if ( obj->item_type != ITEM_CORPSE_PC && obj->item_type != ITEM_CORPSE_NPC)
    {
        send_to_char( "There is no life force in that.\n\r",ch);
        return;
    }
    if ( obj->condition < 2)
      {
        send_to_char( "There is no life force in that.\n\r",ch);
        return;
      }
    if (obj->item_type == ITEM_CORPSE_PC && obj->level < 15 && !IS_IMMORTAL(ch))
      {
        send_to_char("Not that corpse.\n\r",ch);
        return;
      }
    if (obj->pIndexData->vnum == OBJ_VNUM_FAKE_CORPSE)
    {
        send_to_char("Not that corpse.\n\r",ch);
        return;
    }
    if (!can_loot(ch, obj)){
      act("$g's power shields $p from your greedy maw.", ch, obj, NULL, TO_CHAR);
      return;
    }
    act("You suck the life force from $p.",ch,obj,NULL,TO_CHAR);
    act("$n sucks the life force from $p.",ch,obj,NULL,TO_ROOM);
    
    act("You are empowered by cosuming their life force.", ch,NULL,NULL,TO_CHAR);
    ch->mana = UMIN( ch->mana + number_range(obj->level, 3 * obj->level), ch->max_mana );
    update_pos( ch );
    act("$p withers into a desiccated carcass.",ch,obj,NULL,TO_ALL);
    free_string(obj->description);
    obj->description = str_dup("A desiccated corpse lies here.");
    obj->condition = 1;
}

void spell_bloodlust( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = NULL, *vch, *vch_next;
    AFFECT_DATA af;
    bool found = FALSE;
    if (is_affected( ch, sn ) )
    {
	send_to_char("You are already in a rage of lust.\n\r",ch);
	return;
    }
    if (IS_NPC(ch))
	return;
    for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
    {
        vch_next = vch->next_in_room;
        if ( vch != ch && !is_safe(ch,vch) && !IS_SET(vch->act,ACT_UNDEAD))
        {
	    victim = vch;
	    found = TRUE;
	    break;
	}
    }
    if (!found)
    {
	send_to_char("Nothing here interests you.\n\r",ch);
	return;
    }
    send_to_char("Your senses goes haywire as you lust for blood amplifies!\n\r",ch);
    act("$n's eyes flood crimson red.",ch,NULL,NULL,TO_ROOM);
    m_yell(ch,victim,FALSE);
    multi_hit(ch,victim,TYPE_UNDEFINED);
    ch->pcdata->condition[COND_HUNGER] = 0;
    af.where     = TO_AFFECTS2;
    af.type      = sn;
    af.level     = level;
    af.duration  = number_fuzzy(level/5);
    af.location  = APPLY_NONE;
    af.modifier  = 0;  
    af.bitvector = AFF_KEEN_SIGHT;
    affect_to_char( ch, &af );
    af.where     = TO_AFFECTS;
    af.location  = APPLY_NONE;
    af.modifier  = 0;  
    af.bitvector = AFF_DETECT_HIDDEN;
    affect_to_char( ch, &af );
    af.bitvector = AFF_DETECT_INVIS;
    af.location  = APPLY_DAMROLL;
    af.modifier  = ch->level/6;  
    af.bitvector = 0;
    affect_to_char( ch, &af );
    af.location  = APPLY_HITROLL;
    affect_to_char( ch, &af );
}

void spell_twilight_shift( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
  char arg[MIL];
  CHAR_DATA *victim = NULL, *mob;
  int chance = number_percent(), skill =get_skill(ch,skill_lookup("twilight shift")) ;
  ROOM_INDEX_DATA *pRoomIndex = NULL;
  int count = 0, number = number_argument( target_name, arg );

  if (target_name == NULL)
    {
      send_to_char("Shift to what?\n\r", ch);
      return;
    }
  if (chance > skill)
    {
      send_to_char("You fail to complete the Transformation.\n\r", ch);
      return;
    }
  if (chance < 100 - skill){
    int e_r1[] = {ROOM_NO_TELEPORTIN, ROOM_NO_GATEIN, ROOM_NO_SUMMONIN};
    int va = ch->in_room->area->vnum;
    int area_pool = 1;
    /* get the random room */
    pRoomIndex =  get_rand_room(va,va,	//area range (0 to ignore)
				0,0,		//room ramge (0 to ignore)
				NULL,0,	//areas to choose from
				NULL,0,	//areas to exclude
				NULL,0,	//sectors required
				NULL,0,	//sectors to exlude
				NULL,0,	//room1 flags required
				e_r1,2,	//room1 flags to exclude
				NULL,0,	//room2 flags required
				NULL,0,	//room2 flags to exclude
				area_pool,	//number of seed areas
				FALSE,	//exit required?
				FALSE,	//Safe?
				ch);		//Character for room checks
    
  }
  /* scan through the mobs in this area and see if we match anyone */
  for (mob = char_list; mob; mob = mob->next){
    if (mob->in_room == NULL || mob->in_room->area != ch->in_room->area)
      continue;
    else if ( !can_see( ch, mob ) )
      continue;      
    else if (!is_auto_name(arg, mob->name) )
      continue;
    
    if ( ++count == number ){
      victim = mob;
      break;
    }
  }
  
  if(victim == NULL){
    send_to_char("You fail to locate your target\n\r", ch);
    return;
  }
  else if ( (victim == ch || victim->in_room == NULL)
	    || 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_GATEIN)
	    || IS_SET(ch->in_room->room_flags, ROOM_NO_GATEOUT)  
	    || IS_SET(victim->in_room->room_flags, ROOM_NO_INOUT)
	    || IS_SET(ch->in_room->room_flags, ROOM_NO_INOUT)){
    send_to_char("You fail to locate a safe path to your target\n\r", ch);
    return;
  }
  else if ( (victim->level >= level + 5)
	    || (!IS_NPC(victim) && victim->level > LEVEL_HERO)
	    || (!IS_IMMORTAL(ch) && IS_IMMORTAL(victim))
	    || is_affected(victim,gsn_coffin)
	    || is_affected(victim,gsn_entomb)
	    || is_affected(victim, gsn_tele_lock)
	    || is_affected(victim, gsn_burrow)){
    send_to_char("Something interferes with your spell.\n\r",ch);
    return;
  }
  else if (pRoomIndex == NULL)
    pRoomIndex = victim->in_room;
  
  act("$n scatters into a swarm of bats and disperses into the night.",ch,NULL,NULL,TO_ROOM);
  act("Your body dissolves into a swarm of bats.",ch,NULL,NULL,TO_CHAR);
  char_from_room(ch);
  char_to_room(ch,pRoomIndex);
  do_look(ch,"auto");
  act("Your body takes shape as the bats rejoins to mold your form.",ch,NULL,NULL,TO_CHAR);
  act("The sky darkens as a swarm of bats swoop in and converges into the form of $n.",ch,NULL,NULL,TO_ROOM);
}

void spell_ecstacy( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    int opp = 0;
    bool fElder = get_skill(ch, gsn_unholy_gift) > 1;

    if ( is_affected(victim, sn) )
    {
        act( "$N is already in a state of ecstacy.", ch, NULL, victim, TO_CHAR);
        return;
    }
    if ( victim == ch )
    {
        send_to_char( "You can't fool yourself!\n\r", ch );
        return;
    }
    if (is_affected(victim, gen_watchtower)){
      sendf( ch, "%s is shielded within the Watchtower.\n\r", PERS(victim, ch ));
      return;
    }
    if ( (ch->sex == 1 && victim->sex == 2) || (ch->sex == 2 && victim->sex == 1))
	opp = 3;
    else if ( (ch->sex == 1 && victim->sex == 1) || (ch->sex == 2 && victim->sex == 2))
      opp = 0;
    if (IS_AWAKE(victim) || IS_UNDEAD(victim)){
      if ( victim->fighting != NULL 
	   || (IS_NPC(victim) 
	       && IS_SET(victim->act,ACT_UNDEAD)) 
	   || (IS_NPC(victim) 
	       && IS_SET(victim->act,ACT_TOO_BIG))
	   || saves_spell( level + 2 * opp, victim, DAM_CHARM, skill_table[sn].spell_type) )
	{
	  act( "You fail to induce $N into ecstacy.", ch, NULL, victim, TO_CHAR);
	  return;
	}
      
      if (is_affected(victim, gsn_horse) && monk_good(victim, WEAR_HEAD) && !IS_NPC(victim) && !IS_IMMORTAL(ch))
	{
	  if (fElder){
	  act( "You try to reverse $n's attempt to charm you, and fail!", ch, NULL, victim, TO_VICT );
	  act("$N tries to reverse your charm, and fails!", ch, NULL, victim, TO_CHAR );
	  }
	  else{
	    act( "You reverse $n's attempt to charm you, and charm $M instead!", ch, NULL, victim, TO_VICT );
	    act("$N reverses your charm, and charms you instead!", ch, NULL, victim, TO_CHAR );
	    
	    af.where     = TO_AFFECTS;
	    af.type      = sn;
	    af.level     = level;
	    af.duration  = 0;
	    af.location  = APPLY_NONE;
	    af.modifier  = 0;
	    af.bitvector = 0;
	    affect_to_char( ch, &af );
	    
	    send_to_char( "Your wildest fantasy comes true right in front of your eyes!\n\r", ch );
	    act("$n's eyes wanders dreamily as a wide grin stretches across $s face.",ch,NULL,NULL,TO_ROOM);
	    stop_follower(ch);
	    return; 
	  }
	}
    }
    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = 1 + number_fuzzy( level / 15);
    af.location  = APPLY_NONE;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( victim, &af );
    send_to_char( "Your wildest fantasy comes true right in front of your eyes!\n\r", victim );
    act("$n's eyes wanders dreamily as a wide grin stretches across $s face.",victim,NULL,NULL,TO_ROOM);
    stop_follower(victim);
}

void spell_shadowstalk( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    AFFECT_DATA af;
    CHAR_DATA *shadow;
    OBJ_DATA *wield;
    int i;
    char buf[MSL];
    char *name;
    bool fElder = get_skill(ch, gsn_unholy_gift) > 1;

    if ( is_affected(ch, sn) )
    {
	send_to_char("You are not ready to give life to another shadow yet.\n\r",ch);
        return; 
    }
    if ( ( victim = get_char_world( ch, target_name ) ) == NULL
    ||   victim == ch || IS_NPC(victim) || is_safe(ch,victim))
    {
        send_to_char("You failed.\n\r", ch);
        return;
    }
    send_to_char("You mark a mystical symbol on the ground, and your shadow takes form!\n\r",ch);
    act("$n marks a strange symbol on the ground, and $s shadow comes to life!",ch,NULL,NULL,TO_ROOM);
    shadow = create_mobile( get_mob_index(MOB_VNUM_SHADOW) );
    for (i=0;i < MAX_STATS; i++)
        shadow->perm_stat[i] = ch->perm_stat[i];

//We spiff up some of the stats as mobs are weaker by nature.
    shadow->max_hit = (4 * ch->max_hit) / 3;
    shadow->hit = shadow->max_hit;
    shadow->max_mana = (4 * ch->max_mana) / 3;
    shadow->mana = shadow->max_mana;
    shadow->level = fElder ? ch->level + 3: ch->level;
    for (i=0; i < 3; i++)
      shadow->armor[i] = ch->armor[i];
    shadow->armor[3] =ch->armor[3];
    shadow->sex = ch->sex;  
    shadow->gold = 0;
    
//Now we copy over little things like weapon stats.
    shadow->damroll = ch->damroll;
    shadow->hitroll = ch->hitroll;
    
if ( (wield = get_eq_char(ch,WEAR_WIELD)) != NULL)
  {
    shadow->damage[DICE_NUMBER] = wield->value[1];
    shadow->damage[DICE_TYPE] = wield->value[2];
    shadow->dam_type = wield->value[3];
  }

    name = IS_NPC(ch) ? ch->short_descr : ch->name;
    sprintf( buf, shadow->short_descr, name );
    free_string( shadow->short_descr );
    shadow->short_descr = str_dup( buf );
    sprintf( buf, shadow->long_descr, name );
    free_string( shadow->long_descr );
    shadow->long_descr = str_dup( buf );
    sprintf( buf, shadow->description, name );
    free_string( shadow->description );
    shadow->description = str_dup( buf );
    char_to_room(shadow,ch->in_room);
    shadow->hunting = victim;

    shadow->pCabal = ch->pCabal;
    shadow->leader = ch;

    af.where     = TO_AFFECTS;
    af.type      = sn;
    af.level     = level;
    af.duration  = fElder ? 12 : 24;
    af.location  = APPLY_NONE;
    af.modifier  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );

    /* make sure its killed in 24 hours, if not by sun */
    af.type = gsn_timer;
    af.where     = TO_AFFECTS;
    af.level     = level;
    af.duration  = fElder ? 48 : 24;
    af.modifier  = 0;  
    af.location  = 0;
    af.bitvector = 0;
    affect_to_char( shadow, &af );



}

void spell_restore_faith( int sn, int level, CHAR_DATA *ch, void *vo,int target) 
{
    CHAR_DATA *victim = (CHAR_DATA *) vo;
    if ( !is_affected( victim, gsn_blasphemy ) )
    {
        if (victim == ch)
            act("You did not lose your faith.",ch,NULL,victim,TO_CHAR);
        else
            act("$N doesn't seem to have lost $s faith.",ch,NULL,victim,TO_CHAR);
        return;
    }
    if (check_dispel(level-5,victim,gsn_blasphemy))
    {
        act_new("You once again have faith in your religion.",victim,NULL,NULL,TO_CHAR,POS_DEAD);
        act("$n looks more determined.",victim,NULL,NULL,TO_ROOM);   
    }
    else
        act("You failed to restore $N's faith.",ch,NULL,victim,TO_CHAR); 
}

//03-25 13:00 Viri: Changed bat morp messages, will do the rest once
//I get to those forms.
//03-31-00 Added Arms_of_gaia spell for druids. -Shadow
//03-1-23:00 Viri: remmed out arms_of_gaia code so I can compile my stuff:)
//rem it back in when you debug it:)
//04-01 9:00 Ath: Added spell_mass_hysteria
//04-03 23:00 Viri: Fixed the bug in blood lust that removed detet invis.
//04-03 23:50 viri: Added Keensight to wolf_form for vamps.
//04-13 10:30 Viri: Made thnder storm do bonus damage for high AC.
//04-13 11:00 Viri: Gave ice storm chance to crumble a weapon.
//created effect_freeze_weapon(..) for that.
//04-24 Viri: modfifed iceball for steadied damage
//04-24 Viri: reworked Hellstream for different item busting effect.