legend/
legend/area/
legend/player/
/**************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/
/***************************************************************************
 *  God Wars Mud copyright (C) 1994, 1995, 1996 by Richard Woolcock        *
 *                                                                         *
 *  Legend of Chrystancia copyright (C) 1999, 2000, 2001 by Matthew Little *
 *  This mud is NOT to be copied in whole or in part, or to be run without *
 *  the permission of Matthew Little. Nobody else has permission to        *
 *  authorise the use of this code.                                        *
 ***************************************************************************/

#if defined(macintosh)
#include <types.h>
#else
#include <sys/types.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "merc.h"

/*
 * Local functions.
 */
NCLANS_DATA *nclans_table;
int wyncount;

void adv_spell_damage args ((CHAR_DATA * ch, OBJ_DATA * book, OBJ_DATA * page, char *argument));
void adv_spell_affect args ((CHAR_DATA * ch, OBJ_DATA * book, OBJ_DATA * page, char *argument));
void adv_spell_action args ((CHAR_DATA * ch, OBJ_DATA * book, OBJ_DATA * page, char *argument));

#define rune_combo( RUNE, GLYPH, SIGIL )         ( (int) RUNE + ( (int) GLYPH * 10000 ) + ( (int) SIGIL * 10000000 ) )
#define rune_combo2( RUNE, GLYPH, SIGIL )         ( (int) SIGIL + ( (int) GLYPH * 10 ) + ( (int) RUNE * 10000 ) )

void do_magepowers (CHAR_DATA * ch, char *argument)
{

   if (IS_NPC (ch))
      return;

   if (!IS_CLASS (ch, CLASS_MAGE))
   {
      do_rand_typo (ch);
      return;
   }

   stc ("#b{{============================================================================}}#n\n\r", ch);
   cent_to_char ("#w-[ Mage Powers ]-#n", ch);
   stc ("#b{{============================================================================}}#n\n\r", ch);
   stc ("#pCorrespondence: #n", ch);
   if (ch->spheres[MCOR] < 1)
      stc ("None \n\r", ch);
   if (ch->spheres[MCOR] >= 1)
      stc ("Perception ", ch);
   if (ch->spheres[MCOR] >= 2)
      stc ("Objectgate ", ch);
   if (ch->spheres[MCOR] >= 3)
      stc ("Mgate ", ch);
   if (ch->spheres[MCOR] >= 4)
      stc ("Eternal<Permanent Rifts> ", ch);
   if (ch->spheres[MCOR] >= 5)
      stc ("Polyappear", ch);
   stc ("#p\n\rEntropy: #nDamage reduction", ch);
   stc ("#p\n\rForces: #n", ch);
   if (ch->spheres[MFOR] < 1)
      stc ("None \n\r", ch);
   if (ch->spheres[MFOR] >= 1)
      stc ("Discharge ", ch);
   if (ch->spheres[MFOR] >= 2)
      stc ("Telekinesis ", ch);
   if (ch->spheres[MFOR] >= 3)
      stc ("Calllightning Controlweather ", ch);
   if (ch->spheres[MFOR] >= 4)
      stc ("Earthembrace ", ch);
   if (ch->spheres[MFOR] >= 5)
      stc ("Tempest", ch);
   stc ("#p\n\rLife: #n", ch);
   if (ch->spheres[MLIF] < 1)
      stc ("None \n\r", ch);
   if (ch->spheres[MLIF] >= 1)
      stc ("Hotienchi ", ch);
   if (ch->spheres[MLIF] >= 2)
      stc ("Littledeath ", ch);
   if (ch->spheres[MLIF] >= 3)
      stc ("Betterbody ", ch);
   if (ch->spheres[MLIF] >= 4)
      stc ("Shapechange ", ch);
   if (ch->spheres[MLIF] >= 5)
      stc ("Layhands", ch);
   stc ("#p\n\rMatter: #n", ch);
   if (ch->spheres[MMAT] < 1)
      stc ("None \n\r", ch);
   if (ch->spheres[MMAT] >= 1)
      stc ("Analyze ", ch);
   if (ch->spheres[MMAT] >= 2)
      stc ("Alterstate ", ch);
   if (ch->spheres[MMAT] >= 3)
      stc ("Alterweight ", ch);
   if (ch->spheres[MMAT] >= 4)
      stc ("Enchantarmor ", ch);
   if (ch->spheres[MMAT] >= 5)
      stc ("Hover", ch);
   stc ("#p\n\rMind: #n", ch);
   if (ch->spheres[MMIN] < 1)
      stc ("None \n\r", ch);
   if (ch->spheres[MMIN] >= 1)
      stc ("Shield ", ch);
   if (ch->spheres[MMIN] >= 2)
      stc ("Impulse ", ch);
   if (ch->spheres[MMIN] >= 3)
      stc ("Probe ", ch);
   if (ch->spheres[MMIN] >= 4)
      stc ("Possession ", ch);
   if (ch->spheres[MMIN] >= 5)
      stc ("Untether", ch);
   stc ("#p\n\rPrime: #n", ch);
   if (ch->spheres[MPRI] < 1)
      stc ("None \n\r", ch);
   if (ch->spheres[MPRI] >= 1)
      stc ("Quintessence ", ch);
   if (ch->spheres[MPRI] >= 2)
      stc ("Enchant ", ch);
   if (ch->spheres[MPRI] >= 3)
      stc ("Rubbing ", ch);
   if (ch->spheres[MPRI] >= 4)
      stc ("Purification ", ch);
   if (ch->spheres[MPRI] >= 5)
      stc ("Qblast", ch);
   stc ("#p\n\rSpirit: #n", ch);
   if (ch->spheres[MSPI] < 1)
      stc ("None \n\r", ch);
   if (ch->spheres[MSPI] >= 1)
      stc ("Callspirit ", ch);
   if (ch->spheres[MSPI] >= 2)
      stc ("Spiritkiss ", ch);
   if (ch->spheres[MSPI] >= 3)
      stc ("Awaken ", ch);
   if (ch->spheres[MSPI] >= 4)
      stc ("Spiritblast ", ch);
   if (ch->spheres[MSPI] >= 5)
      stc ("Breach", ch);
   stc ("#p\n\rTime: #nIncreased spellcasting speed\n\r", ch);
   stc ("#p\n\rOther: #nColor, Magickalshield, dimmak, drainmove\n\r", ch);
   stc ("#b{{============================================================================}}#n\n\r", ch);
   return;
}


void do_chant (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   OBJ_DATA *book;
   OBJ_DATA *page;
   OBJ_DATA *obj;
   char arg[MAX_INPUT_LENGTH];
   bool victim_target = FALSE;
   bool object_target = FALSE;
   bool global_target = FALSE;	/* Target object/victim may be anywhere */

   int spellno = 1;

   int spellcount = 0;
   int spelltype;
   int sn = 0;
   int level;

   one_argument (argument, arg);

   if (!IS_CLASS (ch, CLASS_MAGE) || ch->level < LEVEL_APPRENTICE
       || ch->trust < LEVEL_APPRENTICE)
   {
      stc ("The Arcane words Baffle you!\n\r", ch);
      return;
   }
   if (IS_SET (ch->extra2, AURA_NO_MAGIC))
      do_auranomagic (ch, "");
if (!IS_NPC (ch) && IS_AFFECTED(ch, AFF_ETHEREAL) )    
   {
        REMOVE_BIT(ch->affected_by, AFF_ETHEREAL);
        stc("You fade into the real world!\n\r", ch);
        //return;
   }
   if ((book = get_eq_char (ch, WEAR_WIELD)) == NULL
       || book->item_type != ITEM_BOOK)
   {
      if ((book = get_eq_char (ch, WEAR_HOLD)) == NULL
	  || book->item_type != ITEM_BOOK)
      {
         if ((book = get_eq_char (ch, WEAR_DUAL)) == NULL
             || book->item_type != ITEM_BOOK)
         {
            send_to_char ("First you must hold a spellbook.\n\r", ch);
            return;
         }
      }
   }
   if (IS_SET (book->value[1], CONT_CLOSED))
   {
      send_to_char ("First you better open the book.\n\r", ch);
      return;
   }

   if (book->value[2] < 1)
   {
      send_to_char ("There are no spells on the index page!\n\r", ch);
      return;
   }
   if ((page = get_page (book, book->value[2])) == NULL)
   {
      send_to_char ("The current page seems to have been torn out!\n\r", ch);
      return;
   }
    if ( IS_HEAD(ch, LOST_TONGUE) )
    {
        send_to_char( "You can't chant without a tongue!\n\r", ch );
	return;
    }
    if ( IS_EXTRA(ch, GAGGED) )
    {
        send_to_char( "You can't chant with a gag on!\n\r", ch );
	return;
    }
    if (ch->in_room != NULL && IS_SET(ch->in_room->added_flags, ROOM2_SILENCE))
    {
	send_to_char( "Your words make no sound!\n\r", ch );
	return;
    }

   spellcount =
      ((page->value[1] * 10000) + (page->value[2] * 10) + page->value[3]);

   ch->pcdata->powers[MAGE_CHAIN] = 0;
   act ("You chant the arcane words from $p.", ch, book, NULL, TO_CHAR);
   act ("$n chants some arcane words from $p.", ch, book, NULL, TO_ROOM);

   if (IS_SET (page->quest, QUEST_MASTER_RUNE))
   {
      ch->spectype = 0;

      if (str_cmp (page->questmaker, ch->name))
      {
	 if (ch->level < LEVEL_ARCHMAGE)
	 {
	    stcf (ch,
		  "You find that you do not understand the symbols that %s wrote.\n\r",
		  page->questmaker);
	    return;
	 }
      }

      if (IS_SET (page->spectype, ADV_FAILED)
	  || !IS_SET (page->spectype, ADV_FINISHED) || page->points < 1)
	 send_to_char ("The spell failed.\n\r", ch);
      else if (IS_SET (page->spectype, ADV_DAMAGE))
	 adv_spell_damage (ch, book, page, argument);
      else if (IS_SET (page->spectype, ADV_AFFECT))
	 adv_spell_affect (ch, book, page, argument);
      else if (IS_SET (page->spectype, ADV_ACTION))
	 adv_spell_action (ch, book, page, argument);
      else
	 send_to_char ("The spell failed.\n\r", ch);
      return;
   }
   switch (spellcount)
   {
      /* RUNE SPELLS START HERE */
   default:
      send_to_char ("Nothing happens.\n\r", ch);
      return;
   case 40024:
      /* EARTH + DESTRUCTION + AREA */
      sn = skill_lookup ("earthquake");
      spellno = 3;
      break;
   case 10022:
      /* FIRE + DESTRUCTION + TARGETING */
      sn = skill_lookup ("fireball");
      victim_target = TRUE;
      spellno = 2;
      break;
   case 640322:
      /* LIFE + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("heal");
      victim_target = TRUE;
      spellno = 3;
      break;
   case 1280044:
      /* DEATH + SUMMONING + AREA */
      sn = skill_lookup ("guardian");
      spellno = 3;
      break;
   case 2565128:
      /* MIND + INFORMATION + OBJECT */
      sn = skill_lookup ("identify");
      object_target = TRUE;
      global_target = TRUE;
      break;
   case 5120328:
      /* SPIRIT + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("enchant weapon");
      object_target = TRUE;
      break;
   case 10328:
      /* FIRE + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("resistance");
      object_target = TRUE;
      break;
   case 20022:
      /* AIR + DESTRUCTION + TARGETING */
      sn = skill_lookup ("chill touch");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 20024:
      /* AIR + DESTRUCTION + AREA */
      sn = skill_lookup ("call lightning");
      spellno = 2;
      break;
   case 20322:
      /* AIR + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("fly");
      victim_target = TRUE;
      break;
   case 20328:
      /* AIR + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("spellproof");
      object_target = TRUE;
      global_target = TRUE;
      break;
   case 40321:
      /* EARTH + ENHANCEMENT + SELF */
      sn = skill_lookup ("stone skin");
      break;
   case 40322:
      /* EARTH + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("giant strength");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 40018:
      /* EARTH + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("fix");
      break;
   case 80018:
      /* WATER + CREATION + OBJECT */
      sn = skill_lookup ("create spring");
      break;
   case 80024:
      /* WATER + DESCRUTION + AREA */
      sn = skill_lookup ("gas breath");
      spellno = 2;
      break;
   case 80321:
      /* WATER + ENHANCEMENT + SELF */
      sn = skill_lookup ("mana");
      spellno = 3;
      break;
   case 160022:
      /* DARK + DESCRUTION + TARGETING */
      sn = skill_lookup ("harm");
      spellno = 3;
      victim_target = TRUE;
      break;
   case 160162:
      /* DARK + TRANSPORTATION + TARGETING */
      sn = skill_lookup ("curse");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 160321:
      /* DARK + ENHANCEMENT + SELF */
      sn = skill_lookup ("frenzy");
      break;
   case 160322:
      /* DARK + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("darkblessing");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 160642:
      /* DARK + REDUCTION + TARGETING */
      sn = skill_lookup ("poison");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 161284:
      /* DARK + CONTROL + AREA */
      sn = skill_lookup ("sleep");
      victim_target = TRUE;
      break;
   case 320018:
      /* LIGHT + CREATION + OBJECT */
      sn = skill_lookup ("continual light");
      spellno = 2;
      break;
   case 320022:
      /* LIGHT + DESCRUTION + TARGETING */
      sn = skill_lookup ("colour spray");
      victim_target = TRUE;
      spellno = 3;
      break;
   case 320321:
      /* LIGHT + ENHANCEMENT + SELF */
      sn = skill_lookup ("sanctuary");
      break;
   case 320322:
      /* LIGHT + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("bless");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 322561:
      /* LIGHT + PROTECTION + SELF */
      sn = skill_lookup ("protection");
      break;
   case 322562:
      /* LIGHT + PROTECTION + TARGETING */
      sn = skill_lookup ("armor");
      victim_target = TRUE;
      break;
   case 322364:
      /* LIGHT + PROTECTION + AREA */
      sn = skill_lookup ("shield");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 640018:
      /* LIFE + CREATION + OBJECT */
      sn = skill_lookup ("create food");
      spellno = 3;
      break;
   case 640022:
      /* LIFE + DESCRUTION + TARGERTING */
      sn = skill_lookup ("dispel evil");
      victim_target = TRUE;
      global_target = TRUE;
      spellno = 2;
      break;
   case 640321:
      /* LIFE + ENHANCEMENT + SELF */
      sn = skill_lookup ("refresh");
      spellno = 3;
      break;
   case 640324:
      /* LIFE + ENHANCEMENT + AREA */
      sn = skill_lookup ("heal");
      victim_target = TRUE;
      global_target = TRUE;
      spellno = 2;
      break;
   case 640642:
      /* LIFE + REDUCTION + TARGETING */
      sn = skill_lookup ("energy drain");
      victim_target = TRUE;
      global_target = TRUE;
      spellno = 2;
      break;
   case 645122:
      /* LIFE + INFORMATION + TARGETING */
      sn = skill_lookup ("know alignment");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 1280348:
      /* DEATH + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("preserve");
      object_target = TRUE;
      global_target = TRUE;
      break;
   case 1280642:
      /* DEATH + REDUCTION + TARGETING */
      sn = skill_lookup ("weaken");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 1280644:
      /* DEATH + REDUCTION + AREA */
      sn = skill_lookup ("remove curse");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 2560642:
      /* MIND + REDUCTION + TARGETING */
      sn = skill_lookup ("dispel magic");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 5120018:
      /* SPIRIT + CREATION + OBJECT */
      sn = skill_lookup ("soulblade");
      spellno = 2;
      break;
   case 5120044:
      /* SPIRIT + SUMMONING + AREA */
      sn = skill_lookup ("summoning");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 5120161:
      /* SPIRIT + TRANSPORTATION + SELF */
      sn = skill_lookup ("teleport");
      break;
   case 5120321:
      /* SPIRIT + ENHANCEMENT + SELF */
      sn = skill_lookup ("pass door");
      break;
   case 5120642:
      /* SPIRIT + REDUCTION + TARGETING */
      sn = skill_lookup ("faerie fire");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 5121284:
      /* SPIRIT + CONTROL + AREA */
      sn = skill_lookup ("faerie fog");
      break;
   case 2565122:
      /* MIND + INFORMATION + TARGETING */
      sn = skill_lookup ("read aura");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case rune_combo2 ((RUNE_LIFE + RUNE_DEATH), (GLYPH_SUMMONING + GLYPH_DESTRUCTION + GLYPH_TRANSFORMATION), (SIGIL_TARGETING + SIGIL_SELF)):
      /* LIFE + DEATH + SUMMONING + DESTRUCTION + TRANSFORMATION + TARGETING + SELF */
      {
	 ROOM_INDEX_DATA *t_room;
	 char t_buf[500];
	 char *restricted;

	 restricted = "";	// Empty for now;

	 if (ch->mana < 35000)
	 {
	    stc ("You need 35000 mana to attempt this spell.\n\r", ch);
	    return;
	 }
	 if ((victim = get_char_world_noabbr (ch, arg)) == NULL)
	 {
	    stc ("They are not here.\n\r", ch);
	    return;
	 }
	 if (IS_NPC (victim))
	 {
	    stc ("Spell failed.\n\r", ch);
	    return;
	 }
	 ch->mana -= 35000;
	 if (is_name (ch->name, restricted))
	 {
	    stc ("The gods laugh at your feeble motions.\n\r", ch);
	    paradox (ch);
	    return;
	 }
	 if (dice (1, 100) <= 40)	//LOWERED the chance of it Actually happening
	 {
	    stc ("You misread the spell.\n\r", ch);
	    return;
	 }
	 sprintf (t_buf, "decap %s", victim->name);
	 t_room = ch->in_room;
	 char_from_room (ch);
	 char_to_room (ch, victim->in_room);
	 interpret (ch, t_buf);
	 char_from_room (ch);
	 char_to_room (ch, t_room);
	 WAIT_STATE (ch, 12);	//Lets add some lag so they cant use it OVER AND OVER??
	 return;
      }
   }
   if (arg[0] == '\0' && (victim_target == TRUE || object_target == TRUE))
   {
      send_to_char ("Please specify a target.\n\r", ch);
      return;
   }

   if (victim_target && sn > 0)
   {
      if (!global_target && (victim = get_char_room (ch, arg)) == NULL)
      {
	 send_to_char ("They are not here.\n\r", ch);
	 return;
      }
      else if (global_target && (victim = get_char_world (ch, arg)) == NULL)
      {
	 send_to_char ("They are not here.\n\r", ch);
	 return;
      }
      if (IS_ITEMAFF (victim, ITEMA_REFLECT))
      {
	 send_to_char ("You are unable to focus your spell on them.\n\r", ch);
	 return;
      }

      if (IS_SET (victim->extra2, AURA_NO_MAGIC) && victim != ch)
      {
	 send_to_char ("Their aura of no magic dissipates your spell!\n\r",
		       ch);
	 return;
      }

      if ( !IS_SET( page->spectype, ADV_DAMAGE ) )
      {
      if (IS_CLASS (victim, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 3)
	    {
	       victim->quickening[0] -= 3;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		    victim);
               if (!IS_IMMORTAL (ch))
                  WAIT_STATE (ch, skill_table[sn].beats);
	       return;
	    }
	 }
      }
      }
/*
   if ( victim_target )
   {
	if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim ) && ( get_hours( victim ) > 9 ) ) )
	{
		stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
		stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim );
		return;
	}
   }
*/
      spelltype = (skill_table[sn].target);
      level = ch->spl[spelltype] * 0.25;
      (*skill_table[sn].spell_fun) (sn, level, ch, victim);
      if (spellno > 1)
	 (*skill_table[sn].spell_fun) (sn, level, ch, victim);
      if (spellno > 2)
	 (*skill_table[sn].spell_fun) (sn, level, ch, victim);
      if (!IS_IMMORTAL (ch))
	 WAIT_STATE (ch, skill_table[sn].beats);
   }
   else if (object_target && sn > 0)
   {
      if (!global_target && (obj = get_obj_carry (ch, arg)) == NULL)
      {
	 send_to_char ("You are not carrying that object.\n\r", ch);
	 return;
      }
      else if (global_target && (obj = get_obj_world (ch, arg)) == NULL)
      {
	 send_to_char ("You cannot find any object like that.\n\r", ch);
	 return;
      }
      spelltype = (skill_table[sn].target);
      level = ch->spl[spelltype] * 0.25;
      (*skill_table[sn].spell_fun) (sn, level, ch, obj);
      if (spellno > 1)
	 (*skill_table[sn].spell_fun) (sn, level, ch, obj);
      if (spellno > 2)
	 (*skill_table[sn].spell_fun) (sn, level, ch, obj);
      if (!IS_IMMORTAL (ch))
	 WAIT_STATE (ch, skill_table[sn].beats);
   }
   else if (sn > 0)
   {
      spelltype = (skill_table[sn].target);
      if (spelltype == TAR_OBJ_INV)
      {
	 send_to_char ("Nothing happens.\n\r", ch);
	 return;
      }
      level = ch->spl[spelltype] * 0.25;
      (*skill_table[sn].spell_fun) (sn, level, ch, ch);
      if (spellno > 1)
	 (*skill_table[sn].spell_fun) (sn, level, ch, ch);
      if (spellno > 2)
	 (*skill_table[sn].spell_fun) (sn, level, ch, ch);
      if (!IS_IMMORTAL (ch))
	 WAIT_STATE (ch, skill_table[sn].beats);
   }
   else
      send_to_char ("Nothing happens.\n\r", ch);
   return;
}

void do_cloakchant (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   OBJ_DATA *book;
   OBJ_DATA *page;
   OBJ_DATA *obj;
   char arg[MAX_INPUT_LENGTH];
   bool victim_target = FALSE;
   bool object_target = FALSE;
   bool global_target = FALSE;	/* Target object/victim may be anywhere */

   int spellno = 1;

   int spellcount = 0;
   int spelltype;
   int sn = 0;
   int level;

   one_argument (argument, arg);

   if (!IS_CLASS (ch, CLASS_MAGE) || ch->level < LEVEL_APPRENTICE
       || ch->trust < LEVEL_APPRENTICE || !WORN_ARTIFACT(ch, ARTI_CLOAK_OF_THE_ARCHMAGI))
   {
      do_rand_typo (ch);
      return;
   }

   if (IS_SET (ch->extra2, AURA_NO_MAGIC))
      do_auranomagic (ch, "");

   if ((book = get_eq_char (ch, WEAR_CLOAK)) == NULL
       || book->item_type != ITEM_BOOK)
   {
      send_to_char ("First you must stash a spellbook.\n\r", ch);
      return;
   }
   if (IS_SET (book->value[1], CONT_CLOSED))
   {
      send_to_char ("First you better open the book.\n\r", ch);
      return;
   }

   if (book->value[2] < 1)
   {
      send_to_char ("There are no spells on the index page!\n\r", ch);
      return;
   }
   if ((page = get_page (book, book->value[2])) == NULL)
   {
      send_to_char ("The current page seems to have been torn out!\n\r", ch);
      return;
   }
    if ( IS_HEAD(ch, LOST_TONGUE) )
    {
        send_to_char( "You can't chant without a tongue!\n\r", ch );
	return;
    }
    if ( IS_EXTRA(ch, GAGGED) )
    {
        send_to_char( "You can't chant with a gag on!\n\r", ch );
	return;
    }
    if (ch->in_room != NULL && IS_SET(ch->in_room->added_flags, ROOM2_SILENCE))
    {
	send_to_char( "Your words make no sound!\n\r", ch );
	return;
    }

   spellcount =
      ((page->value[1] * 10000) + (page->value[2] * 10) + page->value[3]);

   ch->pcdata->powers[MAGE_CHAIN] = 0;
   act ("You chant the arcane words from $p.", ch, book, NULL, TO_CHAR);
   act ("$n chants some arcane words from $p.", ch, book, NULL, TO_ROOM);

   if (IS_SET (page->quest, QUEST_MASTER_RUNE))
   {
      ch->spectype = 0;

      if (str_cmp (page->questmaker, ch->name))
      {
	 if (ch->level < LEVEL_ARCHMAGE)
	 {
	    stcf (ch,
		  "You find that you do not understand the symbols that %s wrote.\n\r",
		  page->questmaker);
	    return;
	 }
      }

      if (IS_SET (page->spectype, ADV_FAILED)
	  || !IS_SET (page->spectype, ADV_FINISHED) || page->points < 1)
	 send_to_char ("The spell failed.\n\r", ch);
      else if (IS_SET (page->spectype, ADV_DAMAGE))
	 adv_spell_damage (ch, book, page, argument);
      else if (IS_SET (page->spectype, ADV_AFFECT))
	 adv_spell_affect (ch, book, page, argument);
      else if (IS_SET (page->spectype, ADV_ACTION))
	 adv_spell_action (ch, book, page, argument);
      else
	 send_to_char ("The spell failed.\n\r", ch);
      return;
   }
   switch (spellcount)
   {
      /* RUNE SPELLS START HERE */
   default:
      send_to_char ("Nothing happens.\n\r", ch);
      return;
   case 40024:
      /* EARTH + DESTRUCTION + AREA */
      sn = skill_lookup ("earthquake");
      spellno = 3;
      break;
   case 10022:
      /* FIRE + DESTRUCTION + TARGETING */
      sn = skill_lookup ("fireball");
      victim_target = TRUE;
      spellno = 2;
      break;
   case 640322:
      /* LIFE + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("heal");
      victim_target = TRUE;
      spellno = 3;
      break;
   case 1280044:
      /* DEATH + SUMMONING + AREA */
      sn = skill_lookup ("guardian");
      spellno = 3;
      break;
   case 2565128:
      /* MIND + INFORMATION + OBJECT */
      sn = skill_lookup ("identify");
      object_target = TRUE;
      global_target = TRUE;
      break;
   case 5120328:
      /* SPIRIT + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("enchant weapon");
      object_target = TRUE;
      break;
   case 10328:
      /* FIRE + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("resistance");
      object_target = TRUE;
      break;
   case 20022:
      /* AIR + DESTRUCTION + TARGETING */
      sn = skill_lookup ("chill touch");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 20024:
      /* AIR + DESTRUCTION + AREA */
      sn = skill_lookup ("call lightning");
      spellno = 2;
      break;
   case 20322:
      /* AIR + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("fly");
      victim_target = TRUE;
      break;
   case 20328:
      /* AIR + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("spellproof");
      object_target = TRUE;
      global_target = TRUE;
      break;
   case 40321:
      /* EARTH + ENHANCEMENT + SELF */
      sn = skill_lookup ("stone skin");
      break;
   case 40322:
      /* EARTH + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("giant strength");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 40018:
      /* EARTH + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("fix");
      break;
   case 80018:
      /* WATER + CREATION + OBJECT */
      sn = skill_lookup ("create spring");
      break;
   case 80024:
      /* WATER + DESCRUTION + AREA */
      sn = skill_lookup ("gas breath");
      spellno = 2;
      break;
   case 80321:
      /* WATER + ENHANCEMENT + SELF */
      sn = skill_lookup ("mana");
      spellno = 3;
      break;
   case 160022:
      /* DARK + DESCRUTION + TARGETING */
      sn = skill_lookup ("harm");
      spellno = 3;
      victim_target = TRUE;
      break;
   case 160162:
      /* DARK + TRANSPORTATION + TARGETING */
      sn = skill_lookup ("curse");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 160321:
      /* DARK + ENHANCEMENT + SELF */
      sn = skill_lookup ("frenzy");
      break;
   case 160322:
      /* DARK + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("darkblessing");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 160642:
      /* DARK + REDUCTION + TARGETING */
      sn = skill_lookup ("poison");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 161284:
      /* DARK + CONTROL + AREA */
      sn = skill_lookup ("sleep");
      victim_target = TRUE;
      break;
   case 320018:
      /* LIGHT + CREATION + OBJECT */
      sn = skill_lookup ("continual light");
      spellno = 2;
      break;
   case 320022:
      /* LIGHT + DESCRUTION + TARGETING */
      sn = skill_lookup ("colour spray");
      victim_target = TRUE;
      spellno = 3;
      break;
   case 320321:
      /* LIGHT + ENHANCEMENT + SELF */
      sn = skill_lookup ("sanctuary");
      break;
   case 320322:
      /* LIGHT + ENHANCEMENT + TARGETING */
      sn = skill_lookup ("bless");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 322561:
      /* LIGHT + PROTECTION + SELF */
      sn = skill_lookup ("protection");
      break;
   case 322562:
      /* LIGHT + PROTECTION + TARGETING */
      sn = skill_lookup ("armor");
      victim_target = TRUE;
      break;
   case 322364:
      /* LIGHT + PROTECTION + AREA */
      sn = skill_lookup ("shield");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 640018:
      /* LIFE + CREATION + OBJECT */
      sn = skill_lookup ("create food");
      spellno = 3;
      break;
   case 640022:
      /* LIFE + DESCRUTION + TARGERTING */
      sn = skill_lookup ("dispel evil");
      victim_target = TRUE;
      global_target = TRUE;
      spellno = 2;
      break;
   case 640321:
      /* LIFE + ENHANCEMENT + SELF */
      sn = skill_lookup ("refresh");
      spellno = 3;
      break;
   case 640324:
      /* LIFE + ENHANCEMENT + AREA */
      sn = skill_lookup ("heal");
      victim_target = TRUE;
      global_target = TRUE;
      spellno = 2;
      break;
   case 640642:
      /* LIFE + REDUCTION + TARGETING */
      sn = skill_lookup ("energy drain");
      victim_target = TRUE;
      global_target = TRUE;
      spellno = 2;
      break;
   case 645122:
      /* LIFE + INFORMATION + TARGETING */
      sn = skill_lookup ("know alignment");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 1280348:
      /* DEATH + ENHANCEMENT + OBJECT */
      sn = skill_lookup ("preserve");
      object_target = TRUE;
      global_target = TRUE;
      break;
   case 1280642:
      /* DEATH + REDUCTION + TARGETING */
      sn = skill_lookup ("weaken");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 1280644:
      /* DEATH + REDUCTION + AREA */
      sn = skill_lookup ("remove curse");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 2560642:
      /* MIND + REDUCTION + TARGETING */
      sn = skill_lookup ("dispel magic");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 5120018:
      /* SPIRIT + CREATION + OBJECT */
      sn = skill_lookup ("soulblade");
      spellno = 2;
      break;
   case 5120044:
      /* SPIRIT + SUMMONING + AREA */
      sn = skill_lookup ("summoning");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 5120161:
      /* SPIRIT + TRANSPORTATION + SELF */
      sn = skill_lookup ("teleport");
      break;
   case 5120321:
      /* SPIRIT + ENHANCEMENT + SELF */
      sn = skill_lookup ("pass door");
      break;
   case 5120642:
      /* SPIRIT + REDUCTION + TARGETING */
      sn = skill_lookup ("faerie fire");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case 5121284:
      /* SPIRIT + CONTROL + AREA */
      sn = skill_lookup ("faerie fog");
      break;
   case 2565122:
      /* MIND + INFORMATION + TARGETING */
      sn = skill_lookup ("read aura");
      victim_target = TRUE;
      global_target = TRUE;
      break;
   case rune_combo2 ((RUNE_LIFE + RUNE_DEATH), (GLYPH_SUMMONING + GLYPH_DESTRUCTION + GLYPH_TRANSFORMATION), (SIGIL_TARGETING + SIGIL_SELF)):
      /* LIFE + DEATH + SUMMONING + DESTRUCTION + TRANSFORMATION + TARGETING + SELF */
      {
	 ROOM_INDEX_DATA *t_room;
	 char t_buf[500];
	 char *restricted;

	 restricted = "";	// Empty for now;

	 if (ch->mana < 35000)
	 {
	    stc ("You need 35000 mana to attempt this spell.\n\r", ch);
	    return;
	 }
	 if ((victim = get_char_world_noabbr (ch, arg)) == NULL)
	 {
	    stc ("They are not here.\n\r", ch);
	    return;
	 }
	 if (IS_NPC (victim))
	 {
	    stc ("Spell failed.\n\r", ch);
	    return;
	 }
	 ch->mana -= 35000;
	 if (is_name (ch->name, restricted))
	 {
	    stc ("The gods laugh at your feeble motions.\n\r", ch);
	    paradox (ch);
	    return;
	 }
	 if (dice (1, 100) <= 40)	//LOWERED the chance of it Actually happening
	 {
	    stc ("You misread the spell.\n\r", ch);
	    return;
	 }
	 sprintf (t_buf, "decap %s", victim->name);
	 t_room = ch->in_room;
	 char_from_room (ch);
	 char_to_room (ch, victim->in_room);
	 interpret (ch, t_buf);
	 char_from_room (ch);
	 char_to_room (ch, t_room);
	 WAIT_STATE (ch, 12);	//Lets add some lag so they cant use it OVER AND OVER??
	 return;
      }
   }
   if (arg[0] == '\0' && (victim_target == TRUE || object_target == TRUE))
   {
      send_to_char ("Please specify a target.\n\r", ch);
      return;
   }
   if (victim_target && sn > 0)
   {
      if (!global_target && (victim = get_char_room (ch, arg)) == NULL)
      {
	 send_to_char ("They are not here.\n\r", ch);
	 return;
      }
      else if (global_target && (victim = get_char_world (ch, arg)) == NULL)
      {
	 send_to_char ("They are not here.\n\r", ch);
	 return;
      }
      if (IS_ITEMAFF (victim, ITEMA_REFLECT))
      {
	 send_to_char ("You are unable to focus your spell on them.\n\r", ch);
	 return;
      }

      if (IS_SET (victim->extra2, AURA_NO_MAGIC) && victim != ch)
      {
	 send_to_char ("Their aura of no magic dissipates your spell!\n\r",
		       ch);
	 return;
      }

      if (IS_CLASS (victim, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 3)
	    {
	       victim->quickening[0] -= 3;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		    victim);
               if (!IS_IMMORTAL (ch))
                  WAIT_STATE (ch, skill_table[sn].beats);
	       return;
	    }
	 }
      }

      spelltype = (skill_table[sn].target);
      level = ch->spl[spelltype] * 0.25;
      (*skill_table[sn].spell_fun) (sn, level, ch, victim);
      if (spellno > 1)
	 (*skill_table[sn].spell_fun) (sn, level, ch, victim);
      if (spellno > 2)
	 (*skill_table[sn].spell_fun) (sn, level, ch, victim);
      if (!IS_IMMORTAL (ch))
	 WAIT_STATE (ch, skill_table[sn].beats);
   }
   else if (object_target && sn > 0)
   {
      if (!global_target && (obj = get_obj_carry (ch, arg)) == NULL)
      {
	 send_to_char ("You are not carrying that object.\n\r", ch);
	 return;
      }
      else if (global_target && (obj = get_obj_world (ch, arg)) == NULL)
      {
	 send_to_char ("You cannot find any object like that.\n\r", ch);
	 return;
      }
      spelltype = (skill_table[sn].target);
      level = ch->spl[spelltype] * 0.25;
      (*skill_table[sn].spell_fun) (sn, level, ch, obj);
      if (spellno > 1)
	 (*skill_table[sn].spell_fun) (sn, level, ch, obj);
      if (spellno > 2)
	 (*skill_table[sn].spell_fun) (sn, level, ch, obj);
      if (!IS_IMMORTAL (ch))
	 WAIT_STATE (ch, skill_table[sn].beats);
   }
   else if (sn > 0)
   {
      spelltype = (skill_table[sn].target);
      if (spelltype == TAR_OBJ_INV)
      {
	 send_to_char ("Nothing happens.\n\r", ch);
	 return;
      }
      level = ch->spl[spelltype] * 0.25;
      (*skill_table[sn].spell_fun) (sn, level, ch, ch);
      if (spellno > 1)
	 (*skill_table[sn].spell_fun) (sn, level, ch, ch);
      if (spellno > 2)
	 (*skill_table[sn].spell_fun) (sn, level, ch, ch);
      if (!IS_IMMORTAL (ch))
	 WAIT_STATE (ch, skill_table[sn].beats);
   }
   else
      send_to_char ("Nothing happens.\n\r", ch);
   return;
}


OBJ_DATA *get_page (OBJ_DATA * book, int page_num)
{
   OBJ_DATA *page;
   OBJ_DATA *page_next;

   if (page_num < 1)
      return NULL;
   for (page = book->contains; page != NULL; page = page_next)
   {
      page_next = page->next_content;
      if (page->value[0] == page_num)
	 return page;
   }
   return NULL;
}

// Stock DAMAGE
void origadv_spell_damage (CHAR_DATA * ch, OBJ_DATA * book, OBJ_DATA * page,
			   char *argument)
{
   char arg[MAX_STRING_LENGTH];
   char buf[MAX_STRING_LENGTH];
   OBJ_DATA *page_next;
   ROOM_INDEX_DATA *old_room = ch->in_room;
   char next_par[MAX_INPUT_LENGTH];
   int mana_cost = page->points;
   int min = page->value[1];
   int max = page->value[2];
   int dam;
   int level;
   bool area_affect = FALSE;
   bool victim_target = FALSE;
   bool global_target = FALSE;
   bool next_page = FALSE;
   bool parameter = FALSE;
   bool not_caster = FALSE;
   bool no_players = FALSE;
   bool cast_message = FALSE;
   bool reversed = FALSE;
   bool only_players = FALSE;	// New by Serenity
   bool only_group = FALSE;	// New by Serenity
   bool only_kingdom = FALSE;	// New by Serenity
   bool no_group = FALSE;	// New by Serenity
   bool no_kingdom = FALSE;	// New by Serenity

   if (ch->mana < mana_cost)
   {
      send_to_char ("You have insufficient mana to chant this spell.\n\r",
		    ch);
      return;
   }

   if (min < 1 || max < 1)
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }

   if (!reversed && (IS_SET (ch->in_room->room_flags, ROOM_SAFE)))
   {
      send_to_char
	 ("Something in the air prevents you from casting that spell.\n\r",
	  ch);
      return;
   }
   if (IS_SET (page->spectype, ADV_NEXT_PAGE) &&
       IS_SET (page->spectype, ADV_SPELL_FIRST))
   {
      if (strlen (page->chpoweroff) < 2
	  || !str_cmp (page->chpoweroff, "(null)"))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page->spectype, ADV_PARAMETER))
      {
	 if (!str_cmp (page->chpoweron, "(null)"))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 else
	    strcpy (next_par, page->chpoweron);
      }
      else
	 strcpy (next_par, arg);
      if (page->specpower < page->value[0])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if ((page_next = get_page (book, page->specpower)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page_next->quest, QUEST_MASTER_RUNE))
      {
	 if (IS_SET (page_next->spectype, ADV_DAMAGE))
	    adv_spell_damage (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_AFFECT))
	    adv_spell_affect (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_ACTION))
	    adv_spell_action (ch, book, page_next, next_par);
	 else
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }

   one_argument (argument, arg);

   if (strlen (page->victpoweron) > 0
       || str_cmp (page->victpoweron, "(null)"))
   {
      if (strlen (page->victpoweroff) > 0
	  || str_cmp (page->victpoweroff, "(null)"))
	 cast_message = TRUE;
   }


   if (IS_SET (page->spectype, ADV_AREA_AFFECT))
      area_affect = TRUE;
   if (IS_SET (page->spectype, ADV_VICTIM_TARGET))
      victim_target = TRUE;
   if (IS_SET (page->spectype, ADV_GLOBAL_TARGET))
      global_target = TRUE;
   if (IS_SET (page->spectype, ADV_NEXT_PAGE))
      next_page = TRUE;
   if (IS_SET (page->spectype, ADV_PARAMETER))
      parameter = TRUE;
   if (IS_SET (page->spectype, ADV_NOT_CASTER))
      not_caster = TRUE;
   if (IS_SET (page->spectype, ADV_NO_PLAYERS))
      no_players = TRUE;
   if (IS_SET (page->spectype, ADV_REVERSED))
      reversed = TRUE;

   if (IS_SET (page->spectype, ADV_NO_GROUP))
      no_group = TRUE;
   if (IS_SET (page->spectype, ADV_NO_KINGDOM))
      no_kingdom = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_GROUP))
      only_group = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_KINGDOM))
      only_kingdom = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_PLAYERS))
      only_players = TRUE;

   if (victim_target)
   {
      CHAR_DATA *victim;

      if (!global_target && (victim = get_char_room (ch, arg)) == NULL)
      {
	 send_to_char ("They are not here.\n\r", ch);
	 return;
      }
      else if (global_target && (victim = get_char_world (ch, arg)) == NULL)
      {
	 send_to_char ("They are not here.\n\r", ch);
	 return;
      }
      if (IS_NPC (victim) && IS_SET (ch->in_room->room_flags, ROOM_GOD))
      {
	 send_to_char
	    ("Something in the air prevents you from attacking.\n\r", ch);
	 return;
      }
      if (is_safe (ch, victim))
      {
	 return;
      }
      if (reversed)
	 level = ch->spl[BLUE_MAGIC];
      else
	 level = ch->spl[RED_MAGIC];
      if (ch->in_room == victim->in_room)
	 dam = number_range (min, max) + level;
      else
	 dam = number_range (min, max);
      if (ch->spectype < 1000)
      {
	 ch->spectype += dam;
	 if (IS_ITEMAFF (victim, ITEMA_RESISTANCE) && dam > 1 && !reversed)
	    dam = number_range (1, dam);
	 if (dam < 5)
	    dam = 1;
	 else
	    dam *= 0.2;
      }
      else
	 dam = 0;
      if (victim->in_room != NULL && victim->in_room != ch->in_room)
      {
	 char_from_room (ch);
	 char_to_room (ch, victim->in_room);
      }
      if (!reversed)
      {
	 if (is_safe (ch, victim))
	 {
	    char_from_room (ch);
	    char_to_room (ch, old_room);
	    return;
	 }
      }
      else if (IS_ITEMAFF (victim, ITEMA_REFLECT))
      {
	 send_to_char ("You are unable to focus your spell on them.\n\r", ch);
	 char_from_room (ch);
	 char_to_room (ch, old_room);
	 return;
      }
      if (IS_SET (victim->extra2, AURA_NO_MAGIC))
      {
	 send_to_char ("Their aura of no magic dissipates your spell!\n\r",
		       ch);
	 char_from_room (ch);
	 char_to_room (ch, old_room);
	 return;
      }
      char_from_room (ch);
      char_to_room (ch, old_room);
      if (cast_message)
      {
	 strcpy (buf, page->victpoweron);
	 act2 (buf, ch, NULL, victim, TO_CHAR);
	 strcpy (buf, page->victpoweroff);
	 act2 (buf, ch, NULL, victim, TO_ROOM);
      }
      if (reversed)
      {
	 victim->hit += dam;
	 if (victim->hit > victim->max_hit)
	    victim->hit = victim->max_hit;
      }
      else
      {
         int otimer = victim->fight_timer;
         adv_damage (ch, victim, dam);
	 sprintf (buf, "Your %s strikes $N incredibly hard! #w[#r%d#w]#n",
		  page->chpoweroff, dam);
	 act2 (buf, ch, NULL, victim, TO_CHAR);
	 sprintf (buf, "$n's %s strikes $N incredably hard! #w[#r%d#w]#n",
		  page->chpoweroff, dam);
	 act2 (buf, ch, NULL, victim, TO_NOTVICT);
	 sprintf (buf, "$n's %s strikes you incredably hard! #w[#r%d#w]#n",
		  page->chpoweroff, dam);
	 act2 (buf, ch, NULL, victim, TO_VICT);
	 hurt_person (ch, victim, dam);
         if (ch->in_room != victim->in_room) victim->fight_timer = otimer;
      }
      if (!IS_IMMORTAL (ch))
      {
	 WAIT_STATE (ch, 12);

	 if (ch->level >= LEVEL_ARCHMAGE)
	    ch->mana -= (mana_cost / 3);
	 else if (ch->level == LEVEL_MAGE)
	    ch->mana -= (mana_cost / 2);
	 else
	    ch->mana -= mana_cost;
      }
   }
   else if (area_affect)
   {
      CHAR_DATA *vch = ch;
      CHAR_DATA *vch_next;

      if (ch->pcdata->powers[MAGE_CHAIN] > 2)
      {
	 stc ("Spell failed.\n\r", ch);
	 return;
      }

      if (reversed)
	 level = ch->spl[BLUE_MAGIC];
      else
	 level = ch->spl[RED_MAGIC];
      dam = number_range (min, max) + (level * 0.5);
      if (ch->spectype < 1000)
      {
	 ch->spectype += dam;
      }
      else
	 dam = 0;
      if (IS_SET (ch->in_room->room_flags, ROOM_SAFE) && !reversed)
      {
	 send_to_char ("You cannot fight in a safe room.\n\r", ch);
	 return;
      }
      if (cast_message)
      {
	 strcpy (buf, page->victpoweron);
	 act2 (buf, ch, NULL, vch, TO_CHAR);
	 strcpy (buf, page->victpoweroff);
	 act2 (buf, ch, NULL, vch, TO_ROOM);
      }

      for (vch = char_list; vch != NULL; vch = vch_next)
      {
	 vch_next = vch->next;	// pointless line
	 if (vch->in_room == NULL)
	    continue;
	 if ((ch == vch) && (not_caster))
	    continue;
	 if ((!IS_NPC (vch)) && (no_players))
	    continue;

	 if ((IS_NPC (vch)) && (only_players))
	    continue;		// New -- Serenity
	 if ((!is_same_group (ch, vch)) && (only_group))
	    continue;		// New -- Serenity
	 if ((is_same_group (ch, vch)) && (no_group))
	    continue;		// New -- Serenity

	 if (!reversed)
	 {
	    if (is_safe (ch, vch))
	       continue;
	 }

	 if (IS_ITEMAFF (vch, ITEMA_REFLECT))
	 {
	    send_to_char ("You are unable to focus your spell on them.\n\r",
			  ch);
	    continue;
	 }
	 if (IS_ITEMAFF (vch, ITEMA_PEACE))
	 {
	    send_to_char ("You are unable to focus your spell on them.\n\r",
			  ch);
	    continue;
	 }
	 if (vch->in_room == ch->in_room)
	 {
	    if (reversed)
	    {
	       vch->hit += dam;
	       if (vch->hit > vch->max_hit)
		  vch->hit = vch->max_hit;
	    }
	    else
	    {
               int otimer = vch->fight_timer;
	       adv_damage (ch, vch, dam);
	       sprintf (buf,
			"Your %s strikes $N incredibly hard! #w[#r%d#w]#n",
			page->chpoweroff, dam);
	       act2 (buf, ch, NULL, vch, TO_CHAR);
	       sprintf (buf,
			"$n's %s strikes $N incredibly hard! #w[#r%d#w]#n",
			page->chpoweroff, dam);
	       act2 (buf, ch, NULL, vch, TO_NOTVICT);
	       sprintf (buf,
			"$n's %s strikes you incredibly hard! #w[#r%d#w]#n",
			page->chpoweroff, dam);
	       act2 (buf, ch, NULL, vch, TO_VICT);
	       if (IS_ITEMAFF (vch, ITEMA_RESISTANCE) && dam > 1)
		  hurt_person (ch, vch, number_range (1, dam));
	       else
		  hurt_person (ch, vch, dam);
               if (ch->in_room != vch->in_room && !IS_NPC(vch)) vch->fight_timer = otimer;
	    }
	    continue;
	 }
      }
      if (!IS_IMMORTAL (ch))
      {
	 WAIT_STATE (ch, 12);
	 ch->mana -= mana_cost;
      }
   }
   else
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }
   if (IS_SET (page->spectype, ADV_NEXT_PAGE) &&
       !IS_SET (page->spectype, ADV_SPELL_FIRST))
   {
      if (strlen (page->chpoweroff) < 2
	  || !str_cmp (page->chpoweroff, "(null)"))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page->spectype, ADV_PARAMETER))
      {
	 if (!str_cmp (page->chpoweron, "(null)"))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 else
	    strcpy (next_par, page->chpoweron);
      }
      else
	 strcpy (next_par, arg);
      if (page->specpower < page->value[0])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if ((page_next = get_page (book, page->specpower)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page_next->quest, QUEST_MASTER_RUNE))
      {
	 if (IS_SET (page_next->spectype, ADV_DAMAGE))
	    adv_spell_damage (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_AFFECT))
	    adv_spell_affect (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_ACTION))
	    adv_spell_action (ch, book, page_next, next_par);
	 else
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   return;
}

void adv_spell_damage (CHAR_DATA * ch, OBJ_DATA * book, OBJ_DATA * page, char *argument)
{
   char arg[MAX_STRING_LENGTH];
   char buf[MAX_STRING_LENGTH];
   OBJ_DATA *page_next;
   ROOM_INDEX_DATA *old_room = ch->in_room;
   char next_par[MAX_INPUT_LENGTH];
   int mana_cost = page->points;
   int min = page->value[1];
   int max = page->value[2];
   int dam;
   int level;
   bool area_affect = FALSE;
   bool uber_affect = FALSE;
   bool victim_target = FALSE;
   bool global_target = FALSE;
   bool next_page = FALSE;
   bool parameter = FALSE;
   bool not_caster = FALSE;
   bool no_players = FALSE;
   bool cast_message = FALSE;
   bool reversed = FALSE;
   bool only_players = FALSE;	// New by Serenity
   bool only_group = FALSE;	// New by Serenity
   bool only_kingdom = FALSE;	// New by Serenity
   bool no_group = FALSE;	// New by Serenity
   bool no_kingdom = FALSE;	// New by Serenity

   int tot_damage = 0;		// New by Serenity
   int hit_targets = 0;		// New by Serenity
   int dead_targets = 0;	// New by Serenity

  bool AreaMod = FALSE;

  argument = one_argument( argument, arg );

  if ( ch->mana < mana_cost )
  {
    send_to_char( "You have insufficient mana to chant this spell.\n\r", ch );
    return;
  }

  if ( ch->pcdata->powers[MAGE_CHAIN] >= 5 )
  {
    send_to_char( "The spell has failed.\n\r", ch );
    return;
  }

  if ( ( min < 1 || max < 1 ) || ( max < min ) )
  {
    send_to_char( "The spell has failed.\n\r", ch );
    return;
  }

  if ( ( strlen( page->victpoweron ) > 0 ) && str_cmp( page->victpoweron, "(null)" ) )
    if ( ( strlen( page->victpoweroff ) > 0 ) && str_cmp( page->victpoweroff, "(null)" ) )
      cast_message = TRUE;

   if (IS_SET (page->spectype, ADV_AREA_AFFECT))
      area_affect = TRUE;
   if (IS_SET (page->spectype, ADV_UBER_AFFECT))
      uber_affect = TRUE;
   if (IS_SET (page->spectype, ADV_VICTIM_TARGET))
      victim_target = TRUE;
   if (IS_SET (page->spectype, ADV_GLOBAL_TARGET))
      global_target = TRUE;
   if (IS_SET (page->spectype, ADV_NEXT_PAGE))
      next_page = TRUE;
   if (IS_SET (page->spectype, ADV_PARAMETER))
      parameter = TRUE;
   if (IS_SET (page->spectype, ADV_NOT_CASTER))
      not_caster = TRUE;
   if (IS_SET (page->spectype, ADV_NO_PLAYERS))
      no_players = TRUE;
   if (IS_SET (page->spectype, ADV_REVERSED))
      reversed = TRUE;

   if (IS_SET (page->spectype, ADV_NO_GROUP))
      no_group = TRUE;
   if (IS_SET (page->spectype, ADV_NO_KINGDOM))
      no_kingdom = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_GROUP))
      only_group = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_KINGDOM))
      only_kingdom = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_PLAYERS))
      only_players = TRUE;

  if ( !reversed && ( IS_SET( ch->in_room->room_flags, ROOM_SAFE ) ) )
  {
    send_to_char( "Something in the air prevents you from casting that spell.\n\r", ch );
    return;
  }

  if ( next_page )
    ch->pcdata->powers[MAGE_CHAIN] += 1;

  if ( victim_target )
  {
    CHAR_DATA	*victim;
 
    if (min > 500) min = 500;
    if (max > 1000) max = 1000;

    if ( !global_target && ( victim = get_char_room( ch, arg ) ) == NULL )
    {
      send_to_char( "Your victim is not here.\n\r", ch );
      return;
    }

    if ( global_target && ( victim = get_char_world( ch, arg ) ) == NULL )
    {
      send_to_char( "Through all your efforts you cannot seem to find your victim.\n\r", ch );
      return;
    }

    if ( global_target && !reversed && ch->in_room->area != victim->in_room->area && !IS_NPC( victim ) && ( IS_SET( ch->in_room->area->aflags, AFLAG_HQ ) || IS_SET( victim->in_room->area->aflags, AFLAG_HQ ) ) )
    {
      send_to_char( "You cannot seem to chant into your victims area or from the area you are in.\n\r", ch );
      return;
    }

    if ( IS_NPC( victim ) && IS_SET( ch->in_room->room_flags, ROOM_GOD ) )
    {
      send_to_char( "Some mystical force in the air prevents you from chanting your spell.\n\r", ch );
      return;
    }

    if ( is_safe( ch, victim ) && !reversed )
      return;

    /*  Should Highlanders completely block chants, makes mages pretty useless then  */
    if ( IS_CLASS( victim, CLASS_HIGHLANDER ) && IS_DEMPOWER( victim, HPOWER_USE_PRESERVATION ) )
    {
      if ( !reversed )
      {
        if ( victim->quickening[0] >= 10 && number_percent( ) > 10 )
        {
          victim->quickening[0] -= 10;
          send_to_char( "Sparkles of energy disrupt the spell before it lands.\n\r", ch   );
          send_to_char( "Sparkles of energy disrupt a spell before it lands.\n\r", victim );
          WAIT_STATE( ch, 12 );
          return;
        }

        if ( victim->quickening[0] >= 10 )
        {
          victim->quickening[0] -= 10;
          send_to_char( "Sparkles of energy drains some damage of the spell before it lands.\n\r", ch   );
          send_to_char( "Sparkles of energy drains some damage of a spell before it lands.\n\r", victim ); 
          min = min / 3;
          max = max / 2;
        }
      }
    }

    if (IS_ITEMAFF (victim, ITEMA_REFLECT))
    {
      send_to_char ("You are unable to focus your spell on them.\n\r", ch);
      char_from_room (ch);
      char_to_room (ch, old_room);
      return;
    }

    if (IS_SET (victim->extra2, AURA_NO_MAGIC))
    {
      send_to_char ("Their aura of no magic dissipates your spell!\n\r", ch);
      char_from_room (ch);
      char_to_room (ch, old_room);
      return;
    }

    if ( reversed ) level = ch->spl[BLUE_MAGIC];
    else            level = ch->spl[RED_MAGIC];

    if ( !IS_NPC( victim ) && min >  750 ) min =  750;
    if ( !IS_NPC( victim ) && max > 1500 ) max = 1500;

    /* Okay, let's first add additional damage, before checking resistances */
    min += ch->race * 15;                     max += ch->race * 15;
    min += min * ( ch->spheres[MENT] * 0.3 ); max += max * ( ch->spheres[MENT] * 0.3 );
    /* Entropy makes spell extrmely strong, so let's fix that  */
    min *= 0.70; max *= 0.70;

    if ( ( ch->in_room->vnum == victim->in_room->vnum ) && !AreaMod )
    {
      min     *= 1.20;
      max     *= 1.20;
      AreaMod  = TRUE;
    }
    else if ( ( ch->in_room->area == victim->in_room->area ) && !AreaMod )
      AreaMod  = TRUE;
    else if ( !AreaMod )
    {
      min     *= 0.60;
      max     *= 0.60;
      AreaMod  = TRUE;
    }

    dam = number_range( min, max ) + level;

    /*  Need to have a look at this code  */
    if ( ch->spectype < 1500 )
    {
      ch->spectype += dam;

      if (IS_ITEMAFF (victim, ITEMA_RESISTANCE) && dam > 1 && !reversed)
        dam = number_range (1, dam);

      if (!IS_NPC (victim) && IS_CLASS (victim, CLASS_DEMON) && victim->in_room != NULL && victim->in_room->vnum == ROOM_VNUM_HELL && !reversed)
      {
        if (dam < 5)
	  dam = 1;
	else
	  dam *= 0.2;
      }
    }

    if ( dam < min && !global_target )
      dam = min;

    /*  Let's do damage reduction calculations  */
    if ( IS_AFFECTED( victim, AFF_SANCTUARY ) && !reversed )
      dam *= 0.5;

    if ( WORN_ARTIFACT( victim, ARTI_CLOAK_OF_THE_ARCHMAGI ) && !IS_AFFECTED( victim, AFF_SANCTUARY ) )
    {
      if ( !reversed )
        dam *= 0.5;
    }

    if ( WORN_ARTIFACT( victim, ARTI_ARCHANGELS_WING ) && number_percent() > 50 )
    {
      if ( !reversed )
      {
        char buf[MAX_STRING_LENGTH];

        dam = ( dam * number_range( 1, 99 ) ) / 100;
        sprintf( buf, "The Archangel's Wings protects %s and reduces their damage to %d.\n\r", victim->name, dam );
        if ( !IS_SET( ch->more, SHORT_COMBAT ) )
          send_to_char( buf, ch );

        sprintf( buf, "The Archangel's Wings protects you and reduces the damage to %d.\n\r", dam );
        if ( !IS_SET( victim->more, SHORT_COMBAT ) )
          send_to_char( buf, victim );
      }
    }

    if ( WORN_ARTIFACT( victim, ARTI_CRYSTAL_SHIELD ) && !reversed )
    {
      if ( number_range( 0, 99 ) < number_range( 5, 10 ) )
      {
        char buf [MAX_STRING_LENGTH];
        sprintf( buf, "%s uses the Crystal Shield to deflect your hit.\n\r", victim->name );
        if ( !IS_SET( ch->more, SHORT_COMBAT ) )
          send_to_char( buf, ch );
        if ( !IS_SET( victim->more, SHORT_COMBAT ) )
          send_to_char( "You deflect their hit with the Crystal Shield.\n\r", victim );
        dam = 0;
      }
    }

    if (victim->in_room != NULL && victim->in_room != ch->in_room)
    {
      char_from_room (ch);
      char_to_room (ch, victim->in_room);
    }
    if (!reversed)
    {
      if (is_safe (ch, victim))
      {
        char_from_room (ch);
        char_to_room (ch, old_room);
        return;
      }
    }

    char_from_room (ch);
    char_to_room (ch, old_room);

    if (cast_message)
    {
      strcpy (buf, page->victpoweron);
      act2 (buf, ch, NULL, victim, TO_CHAR);
      strcpy (buf, page->victpoweroff);
      act2 (buf, ch, NULL, victim, TO_ROOM);
    }

    if ( reversed )
    {
      victim->hit += dam;

      if ( victim->hit > victim->max_hit )
        victim->hit = victim->max_hit;
    }
    else
    {
      int otimer = victim->fight_timer;
      adv_damage (ch, victim, dam);
      sprintf (buf, "Your %s strikes $N incredibly hard!#w[#r%d#w]", page->chpoweroff, dam);
      act2 (buf, ch, NULL, victim, TO_CHAR);
      sprintf (buf, "$n's %s strikes $N incredibly hard!", page->chpoweroff);
      act2 (buf, ch, NULL, victim, TO_NOTVICT);
      sprintf (buf, "$n's %s strikes you incredibly hard!#w[#r%d#w]", page->chpoweroff, dam);
      act2 (buf, ch, NULL, victim, TO_VICT);
      hurt_person (ch, victim, dam);
      if (ch->in_room != victim->in_room) victim->fight_timer = otimer;
    }

    if (!IS_IMMORTAL (ch))
    {
      WAIT_STATE (ch, 10);

      if (ch->level >= LEVEL_ARCHMAGE)
        ch->mana -= (mana_cost / 3);
      else if (ch->level == LEVEL_MAGE)
        ch->mana -= (mana_cost / 2);
      else
        ch->mana -= mana_cost;
    }
  }
   else if (area_affect && uber_affect)
   {
      CHAR_DATA *vch = ch;
      CHAR_DATA *vch_next;

      if (ch->pcdata->powers[MAGE_CHAIN] > 4)
      {
	 stc ("Spell failed.\n\r", ch);
	 return;
      }

      if (!IS_SET (ch->more, PLR_COMB_EXP))
	 SET_BIT (ch->more, PLR_COMB_EXP);

      if (reversed)
	 level = ch->spl[BLUE_MAGIC];
      else
	 level = ch->spl[RED_MAGIC];

      if (IS_SET (ch->in_room->room_flags, ROOM_SAFE) && !reversed)
      {
	 send_to_char ("You cannot fight in a safe room.\n\r", ch);
	 return;
      }
      for (vch = char_list; vch != NULL; vch = vch_next)
      {
	 vch_next = vch->next;
         if (ch->in_room == NULL)
            continue;
	 if (vch->in_room == NULL)
	    continue;
//      if ( ch->in_room- != vch->in_room )     continue;
        if (ch->in_room->area != vch->in_room->area) continue;
	 if (ch == vch && not_caster)
	    continue;
	 if (!IS_NPC (vch) && no_players)
	    continue;

	 if ((IS_NPC (vch)) && (only_players))
	    continue;		// New -- Serenity
	 if ((!is_same_group (ch, vch)) && (only_group))
	    continue;		// New -- Serenity
	 if ((is_same_group (ch, vch)) && (no_group))
	    continue;		// New -- Serenity

	 if (is_safe_silent (ch, vch))
	    continue;
         if (((dead_targets + 1) / 2) - ((ch->race + 1) / 2) > number_range(0,99)) break;
	 if (IS_ITEMAFF (vch, ITEMA_REFLECT))
	 {
	    send_to_char ("You are unable to focus your spell on them.\n\r",
			  ch);
	    continue;
	 }
	 if (IS_SET (ch->in_room->area->aflags, AFLAG_NOAREA))
	 {
	    send_to_char ("You cannot use area bombs in this area.\n\r", ch);
	    return;
	 }

         if (IS_SET (ch->in_room->area->aflags, AFLAG_NOBOMB))
         {
            send_to_char ("You cannot use area bombs in this area.\n\r", ch);
            return;   
         }


	 if (IS_SET (ch->in_room->room_flags, ROOM_NO_AREA))
	 {
	    send_to_char ("You cannot use area bombs in this area.\n\r", ch);
	    return;
	 }
	 if (vch->in_room->area == ch->in_room->area)
	 {
            int otimer = vch->fight_timer;
	    dam = number_range (min, max) + (level * 0.95);

	    tot_damage += dam;
	    hit_targets += 1;

	    sprintf (buf, "$n's %s strikes you incredibly hard! #w[#r%d#w]",
		     page->chpoweroff, dam);
	    if (!IS_NPC (vch))
	       act2 (buf, ch, NULL, vch, TO_VICT);

	    if (IS_ITEMAFF (vch, ITEMA_RESISTANCE) && dam > 1)
	       adv_damage (ch, vch, number_range (1, dam));
	    else
	    {
	       adv_damage (ch, vch, dam);
	    }
	    if ((vch->hit - dam) < 1)
	       dead_targets++;
	    hurt_person (ch, vch, dam);

	    if (vch->fighting == ch)
	       stop_fighting (vch, TRUE);
            if (ch->in_room != vch->in_room && !IS_NPC(vch)) vch->fight_timer = otimer;
	 }
      }
// report back damage
      if (hit_targets > 0)
      {
	 sprintf (buf,
		  "#cYour %s #cslams into %s #cwith awesome force! #w[#yHit/Killed %d/%d#w]#n #w[#rAvg %d#w]#n",
		  page->chpoweroff, ch->in_room->area->name, hit_targets,
		  dead_targets, tot_damage / hit_targets);
	 act2 (buf, ch, NULL, NULL, TO_CHAR);
	 sprintf (buf, "#c$n's %s #cslams into %s #cwith awesome force!#n",
		  page->chpoweroff, ch->in_room->area->name);
	 act2 (buf, ch, NULL, NULL, TO_ROOM);
      }

      if (!IS_IMMORTAL (ch) && hit_targets > 0)
      {
	 WAIT_STATE (ch, 12);
	 if (ch->level >= LEVEL_ARCHMAGE)
	    ch->mana -= (mana_cost / 3);
	 else if (ch->level == LEVEL_MAGE)
	    ch->mana -= (mana_cost / 2);
	 else
	    ch->mana -= mana_cost;
      }

   }
   else if (area_affect && !uber_affect)
   {
      CHAR_DATA *vch = ch;
//      CHAR_DATA *vch_next;

      if (!IS_SET (ch->more, PLR_COMB_EXP))
	 SET_BIT (ch->more, PLR_COMB_EXP);

      if (reversed)
	 level = ch->spl[BLUE_MAGIC];
      else
	 level = ch->spl[RED_MAGIC];

      if (IS_SET (ch->in_room->room_flags, ROOM_SAFE) && !reversed)
      {
	 send_to_char ("You cannot fight in a safe room.\n\r", ch);
	 return;
      }

      vch = ch->in_room->people;
      for (; vch != NULL; vch = vch->next_in_room)
      {
	 if (vch->in_room == NULL)
	    continue;
	 if (ch->in_room != vch->in_room)
	    continue;
	 if (ch == vch && not_caster)
	    continue;

	 if ((IS_NPC (vch)) && (only_players))
	    continue;		// New -- Serenity
	 if ((!is_same_group (ch, vch)) && (only_group))
	    continue;		// New -- Serenity
	 if ((is_same_group (ch, vch)) && (no_group))
	    continue;		// New -- Serenity

	 if (!IS_NPC (vch) && no_players)
	    continue;

	 if (!reversed)
	 {
	    if (is_safe_silent (ch, vch))
	       continue;
	 }

         if (((dead_targets + 1) / 2) > number_range(0,99)) break;

	 if (IS_ITEMAFF (vch, ITEMA_REFLECT))
	 {
	    send_to_char ("You are unable to focus your spell on them.\n\r",
			  ch);
	    continue;
	 }
	 if (IS_SET (ch->in_room->area->aflags, AFLAG_NOAREA))
	 {
	    send_to_char ("You cannot use area bombs in this area.\n\r", ch);
	    return;
	 }

         if (IS_SET (ch->in_room->area->aflags, AFLAG_NOBOMB))
         {
            send_to_char ("You cannot use area bombs in this area.\n\r", ch);
            return;   
         }

	 if (IS_SET (ch->in_room->room_flags, ROOM_NO_AREA))
	 {
	    send_to_char ("You cannot use area bombs in this area.\n\r", ch);
	    return;
	 }
	 if (vch->in_room == ch->in_room)
	 {
	    dam = number_range (min, max) + (level * 1.15);
	    tot_damage += dam;
	    hit_targets++;

	    if (!reversed)
	    {
               int otimer = vch->fight_timer;
	       sprintf (buf,
			"$n's %s strikes you incredibly hard! #w[#r%d#w]",
			page->chpoweroff, dam);
	       act2 (buf, ch, NULL, vch, TO_VICT);

	       if (IS_ITEMAFF (vch, ITEMA_RESISTANCE) && dam > 1)
	       {
		  adv_damage (ch, vch, dam = number_range (1, dam));
		  hurt_person (ch, vch, dam);
	       }
	       else
	       {
		  adv_damage (ch, vch, dam);
		  hurt_person (ch, vch, dam);
	       }
               if (ch->in_room != vch->in_room && !IS_NPC(vch)) vch->fight_timer = otimer;
	    }
	    else
	    {
	       vch->hit = UMIN (vch->hit + dam, vch->max_hit);
	    }
	 }
      }

// report back damage
      if (hit_targets > 0)
      {
	 sprintf (buf,
		  "#cYour %s #cslams into %s #cwith impressive force! #w[#rAvg %d#w]#n",
		  page->chpoweroff, ch->in_room->name,
		  tot_damage / hit_targets);
	 act2 (buf, ch, NULL, NULL, TO_CHAR);
	 sprintf (buf, "#c$n's %s #cfills %s #cwith impressive force!#n",
		  page->chpoweroff, ch->in_room->name);
	 act2 (buf, ch, NULL, NULL, TO_ROOM);
      }

      if (!IS_IMMORTAL (ch) && hit_targets > 0)
      {
	 WAIT_STATE (ch, 24);
	 if (ch->level >= LEVEL_ARCHMAGE)
	    ch->mana -= (mana_cost / 3);
	 else if (ch->level == LEVEL_MAGE)
	    ch->mana -= (mana_cost / 2);
	 else
	    ch->mana -= mana_cost;
      }
   }
   else
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }

   if (IS_SET (page->spectype, ADV_NEXT_PAGE))	//  && IS_SET (page->spectype, ADV_SPELL_FIRST))
   {
      if ((strlen (page->chpoweroff) < 2)
	  || !str_cmp (page->chpoweroff, "(null)"))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page->spectype, ADV_PARAMETER))
      {
	 if (!str_cmp (page->chpoweron, "(null)"))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 else
	    strcpy (next_par, page->chpoweron);
      }
      else
	 strcpy (next_par, arg);

      if (page->specpower < page->value[0])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }

      if ((page_next = get_page (book, page->specpower)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }

      if (IS_SET (page_next->quest, QUEST_MASTER_RUNE))
      {
	 if (IS_SET (page_next->spectype, ADV_FAILED)
	     || !IS_SET (page_next->spectype, ADV_FINISHED)
	     || page_next->points < 1)
	    send_to_char ("The spell failed.\n\r", ch);
	 else if (IS_SET (page_next->spectype, ADV_DAMAGE))
	    adv_spell_damage (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_AFFECT))
	    adv_spell_affect (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_ACTION))
	    adv_spell_action (ch, book, page_next, next_par);
	 else
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }

   return;
}

void adv_spell_affect (CHAR_DATA * ch, OBJ_DATA * book, OBJ_DATA * page,
		       char *argument)
{
   char arg[MAX_STRING_LENGTH];
   char c_m[MAX_INPUT_LENGTH];
   char c_1[MAX_INPUT_LENGTH];
   char c_2[MAX_INPUT_LENGTH];
   OBJ_DATA *page_next;
   OBJ_DATA *obj = NULL;
   CHAR_DATA *victim = ch;
   char next_par[MAX_INPUT_LENGTH];
   int mana_cost = page->points;
   int apply_bit = page->value[1];
   int bonuses = page->value[2];
   int affect_bit = page->value[3];
   int sn;
   int level = page->level;
   bool any_affects = FALSE;
   bool area_affect = FALSE;
   bool uber_affect = FALSE;
   bool victim_target = FALSE;
   bool object_target = FALSE;
   bool global_target = FALSE;
   bool next_page = FALSE;
   bool parameter = FALSE;
   bool not_caster = FALSE;
   bool no_players = FALSE;
   bool cast_message = FALSE;
   bool message_one = FALSE;
   bool message_two = FALSE;
   bool is_reversed = FALSE;
   bool only_players = FALSE;	// New by Serenity
   bool only_group = FALSE;	// New by Serenity
   bool only_kingdom = FALSE;	// New by Serenity
   bool no_group = FALSE;	// New by Serenity
   bool no_kingdom = FALSE;	// New by Serenity

   if (ch->mana < mana_cost)
   {
      send_to_char ("You have insufficient mana to chant this spell.\n\r",
		    ch);
      return;
   }
//Matts Testing Some more

        if (ch->pcdata->powers[MAGE_CHAIN] >= 5)
    	{
		send_to_char("The spell failed.\n\r",ch);
		return;
	}

   if (IS_SET (page->spectype, ADV_NEXT_PAGE)
       && IS_SET (page->spectype, ADV_SPELL_FIRST))
   {
      if (strlen (page->chpoweroff) < 2
	  || !str_cmp (page->chpoweroff, "(null)"))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }

      if ((IS_SET (ch->flag2, AFF2_INARENA)
	   && !IS_SET (victim->flag2, AFF2_INARENA))
	  || (IS_SET (victim->flag2, AFF2_INARENA)
	      && !IS_SET (ch->flag2, AFF2_INARENA)))
      {
	 send_to_char ("You cannot interfere with arena battles\n\r", ch);
	 return;
      }

      if (IS_SET (page->spectype, ADV_PARAMETER))
      {
	 if (!str_cmp (page->chpoweron, "(null)"))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 else
	    strcpy (next_par, page->chpoweron);
      }
      else
	 strcpy (next_par, argument);
      if (page->specpower < page->value[0])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if ((page_next = get_page (book, page->specpower)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page_next->quest, QUEST_MASTER_RUNE))
      {
	 if (IS_SET (page_next->spectype, ADV_DAMAGE))
	    adv_spell_damage (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_AFFECT))
	    adv_spell_affect (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_ACTION))
	    adv_spell_action (ch, book, page_next, next_par);
	 else
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }

   one_argument (argument, arg);

   if (strlen (page->chpoweroff) > 0 && str_cmp (page->chpoweroff, "(null)"))
   {
      strcpy (c_m, page->chpoweroff);
      cast_message = TRUE;
   }
   if (strlen (page->victpoweron) > 0
       && str_cmp (page->victpoweron, "(null)"))
   {
      strcpy (c_1, page->victpoweron);
      message_one = TRUE;
   }
   if (strlen (page->victpoweroff) > 0
       && str_cmp (page->victpoweroff, "(null)"))
   {
      strcpy (c_2, page->victpoweroff);
      message_two = TRUE;
   }

   if (IS_SET (page->spectype, ADV_AREA_AFFECT))
      area_affect = TRUE;
   if (IS_SET (page->spectype, ADV_UBER_AFFECT))
      uber_affect = TRUE;
   if (IS_SET (page->spectype, ADV_VICTIM_TARGET))
      victim_target = TRUE;
   if (IS_SET (page->spectype, ADV_OBJECT_TARGET))
      object_target = TRUE;
   if (IS_SET (page->spectype, ADV_GLOBAL_TARGET))
      global_target = TRUE;
   if (IS_SET (page->spectype, ADV_NEXT_PAGE))
      next_page = TRUE;
   if (IS_SET (page->spectype, ADV_PARAMETER))
      parameter = TRUE;
   if (IS_SET (page->spectype, ADV_NOT_CASTER))
      not_caster = TRUE;
   if (IS_SET (page->spectype, ADV_NO_PLAYERS))
      no_players = TRUE;
   if (IS_SET (page->spectype, ADV_REVERSED))
   {
      is_reversed = TRUE;
      bonuses = 0 - bonuses;
   }

   if (IS_SET (page->spectype, ADV_NO_GROUP))
      no_group = TRUE;
   if (IS_SET (page->spectype, ADV_NO_KINGDOM))
      no_kingdom = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_GROUP))
      only_group = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_KINGDOM))
      only_kingdom = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_PLAYERS))
      only_players = TRUE;

   if (next_page)
      ch->pcdata->powers[MAGE_CHAIN] += 1;

   if (victim_target && !area_affect && !global_target && !object_target)
   {
      if ((victim = get_char_room (ch, arg)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim->in_room == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim ) && ( get_hours( victim ) > 9 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim );
        return;
    }
*/
      if (IS_CLASS (victim, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 0)
	    {
	       victim->quickening[0] -= 0;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		    victim);
	       return;
	    }
	 }
      }

   }
   else if (victim_target && area_affect && !uber_affect && !global_target
	    && !object_target)
   {
      if ((victim = get_char_world_noabbr (ch, arg)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim->in_room == NULL
	  || victim->in_room->area != ch->in_room->area)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_CLASS (victim, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 0)
	    {
	       victim->quickening[0] -= 0;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		    victim);
	       return;
	    }
	 }
      }
   }
   else if (victim_target && global_target && !object_target)
   {
      if ((victim = get_char_world (ch, arg)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim->in_room == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_CLASS (victim, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 0)
	    {
	       victim->quickening[0] -= 0;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		    victim);
	       return;
	    }
	 }
      }
   }
   else if (object_target && !area_affect && !global_target && !victim_target)
   {
      if ((obj = get_obj_carry (ch, arg)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (object_target && area_affect && !uber_affect && !global_target
	    && !victim_target)
   {
      if ((obj = get_obj_here (ch, arg)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (object_target && global_target && !victim_target)
   {
      if ((obj = get_obj_world (ch, arg)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (obj->in_room == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (obj->item_type == ITEM_QUEST || obj->item_type == ITEM_WGATE
	  || obj->item_type == ITEM_PIECE
          || obj->item_type == ITEM_NEWTOKEN
	  || IS_SET (obj->in_room->area->aflags, AFLAG_HQ)
	  || IS_SET (obj->in_room->area->aflags, AFLAG_ARENA)
	  || IS_SET (obj->in_room->room_flags, ROOM_CCHAMBER))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (area_affect && uber_affect)
   {
      CHAR_DATA *vch = ch;
      CHAR_DATA *vch_next;
      int main_affect = affect_bit;
      int main_apply = apply_bit;
      if (ch->pcdata->powers[MAGE_CHAIN] > 4)
      {
	 stc ("Spell failed.\n\r", ch);
	 return;
      }

      if (is_reversed)
	 level = ch->spl[BLUE_MAGIC];
      else
	 level = ch->spl[RED_MAGIC];

      if (page->toughness < PURPLE_MAGIC || page->toughness > YELLOW_MAGIC)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (page->toughness == PURPLE_MAGIC)
      {
	 if ((sn = skill_lookup ("purple sorcery")) < 0)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else if (page->toughness == RED_MAGIC)
      {
	 if ((sn = skill_lookup ("red sorcery")) < 0)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else if (page->toughness == BLUE_MAGIC)
      {
	 if ((sn = skill_lookup ("blue sorcery")) < 0)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else if (page->toughness == GREEN_MAGIC)
      {
	 if ((sn = skill_lookup ("green sorcery")) < 0)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else if (page->toughness == YELLOW_MAGIC)
      {
	 if ((sn = skill_lookup ("yellow sorcery")) < 0)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }


      for (vch = char_list; vch != NULL; vch = vch_next)
      {
	 vch_next = vch->next;
	 if (vch->in_room == NULL)
	    continue;
	 if (ch == vch && not_caster)
	    continue;
	 if (!IS_NPC (vch) && no_players)
	    continue;

	 if ((IS_NPC (vch)) && (only_players))
	    continue;		// New -- Serenity
	 if ((!is_same_group (ch, vch)) && (only_group))
	    continue;		// New -- Serenity
	 if ((is_same_group (ch, vch)) && (no_group))
	    continue;		// New -- Serenity

	 if (is_safe_silent (ch, vch))
	    continue;
	 if (is_affected (vch, sn))
	    continue;		// already affected
	 affect_bit = main_affect;
	 apply_bit = main_apply;

/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( vch ) && ( get_hours( vch ) > 6 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", vch );
        continue;
    }
*/	
	 if (IS_ITEMAFF (vch, ITEMA_REFLECT))
	 {
	    send_to_char ("You are unable to focus your spell on them.\n\r",
			  ch);
	    continue;
	 }
	 if (IS_CLASS (vch, CLASS_HIGHLANDER))
	 {
	    if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	    {
	       if (victim->quickening[0] >= 0)
	       {
		  victim->quickening[0] -= 0;
		  stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
		  stc ("Sparkles of energy disrupt a spell before it lands.\n\r", victim);
                  if (!IS_IMMORTAL (ch))
                     WAIT_STATE (ch, 12);
		  return;
	       }
	    }
	 }

	 if (vch->in_room->area == ch->in_room->area)
	 {
	    if (IS_SET (vch->extra2, AURA_NO_MAGIC) && vch != ch)
	    {
	       stc ("Their Anti-Magic shield dissipates your magic!\n\r", ch);
	       return;
	    }

	    if (apply_bit == 0)
	    {
	       if (IS_SET (affect_bit, AFF_ETHEREAL))
		  REMOVE_BIT (affect_bit, AFF_ETHEREAL);
	       if (IS_SET (affect_bit, AFF_SHADOWPLANE))
		  REMOVE_BIT (affect_bit, AFF_SHADOWPLANE);

	       enhance_stat (sn, level, ch, vch, APPLY_NONE, bonuses,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_STR))
	    {
               enhance_stat (sn, level, ch, vch, APPLY_STR, bonuses * 0.01,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_DEX))
	    {
               enhance_stat (sn, level, ch, vch, APPLY_DEX, bonuses * 0.01,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_INT))
	    {
               enhance_stat (sn, level, ch, vch, APPLY_INT, bonuses * 0.01,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_WIS))
	    {
               enhance_stat (sn, level, ch, vch, APPLY_WIS, bonuses * 0.01,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_CON))
	    {
               enhance_stat (sn, level, ch, vch, APPLY_CON, bonuses * 0.01,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    // new -- Serenity
	    if (IS_SET (apply_bit, ADV_WEAK))
	    {
	       enhance_stat (sn, level, ch, vch, APPLY_STR,
			     0 - (bonuses * 0.05), affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_FRAIL))
	    {
	       enhance_stat (sn, level, ch, vch, APPLY_CON,
			     0 - (bonuses * 0.05), affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_CLUMSY))
	    {
	       enhance_stat (sn, level, ch, vch, APPLY_DEX,
			     0 - (bonuses * 0.05), affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_AMNESIA))
	    {
	       enhance_stat (sn, level, ch, vch, APPLY_WIS,
			     0 - (bonuses * 0.05), affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    // End New
	    if (IS_SET (apply_bit, ADV_MANA))
	    {
               if (vch->max_mana > 1 && vch->max_mana <= (bonuses * -2.5))
                  enhance_stat (sn, level, ch, vch, APPLY_MANA, (1 - vch->max_mana),
			     affect_bit);
               else if (vch->max_mana > 1)
                  enhance_stat (sn, level, ch, vch, APPLY_MANA, bonuses * 2.5,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_HIT))
	    {
               if (vch->max_hit > 1 && vch->max_hit <= (bonuses * -2.5))
                  enhance_stat (sn, level, ch, vch, APPLY_HIT, (1 - vch->max_hit),
			     affect_bit);
               else if (vch->max_hit > 1)
                  enhance_stat (sn, level, ch, vch, APPLY_HIT, bonuses * 2.5,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_MOVE))
	    {
               if (vch->max_move > 1 && vch->max_move <= (bonuses * -2.5))
                  enhance_stat (sn, level, ch, vch, APPLY_MOVE, (1 - vch->max_move),
			     affect_bit);
               else if (vch->max_move > 1)
                  enhance_stat (sn, level, ch, vch, APPLY_MOVE, bonuses * 2.5,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_AC))
	    {
	       enhance_stat (sn, level, ch, vch, APPLY_AC,
                             0 - (bonuses / 2), affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_HITROLL))
	    {
	       enhance_stat (sn, level, ch, vch, APPLY_HITROLL, bonuses * 0.5,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_DAMROLL))
	    {
	       enhance_stat (sn, level, ch, vch, APPLY_DAMROLL, bonuses * 0.5,
			     affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (IS_SET (apply_bit, ADV_SAVING_SPELL))
	    {
	       enhance_stat (sn, level, ch, vch, APPLY_SAVING_SPELL,
			     0 - (bonuses * 0.1), affect_bit);
	       affect_bit = 0;
	       any_affects = TRUE;
	    }
	    if (!any_affects)
	    {
	       send_to_char ("The spell failed.\n\r", ch);
	       return;
	    }

	    if (message_one)
	       act2 (c_1, ch, NULL, vch, TO_VICT);
	    if (message_two)
	       act2 (c_2, ch, NULL, vch, TO_NOTVICT);

	    if (IS_SET (page->spectype, ADV_NEXT_PAGE)
		&& !IS_SET (page->spectype, ADV_SPELL_FIRST))
	    {
	       if ((strlen (page->chpoweroff) < 2)
		   || !str_cmp (page->chpoweroff, "(null)"))
	       {
		  send_to_char ("The spell failed.\n\r", ch);
		  return;
	       }
	       if (IS_SET (page->spectype, ADV_PARAMETER))
	       {
		  if (!str_cmp (page->chpoweron, "(null)"))
		  {
		     send_to_char ("The spell failed.\n\r", ch);
		     return;
		  }
		  else
		     strcpy (next_par, page->chpoweron);
	       }
	       else
		  strcpy (next_par, argument);

	       if (page->specpower < page->value[0])
	       {
		  send_to_char ("The spell failed.\n\r", ch);
		  return;
	       }

	       if ((page_next = get_page (book, page->specpower)) == NULL)
	       {
		  send_to_char ("The spell failed.\n\r", ch);
		  return;
	       }
	       if (IS_SET (page_next->quest, QUEST_MASTER_RUNE))
	       {
		  if (IS_SET (page_next->spectype, ADV_DAMAGE))
		     adv_spell_damage (ch, book, page_next, next_par);
		  else if (IS_SET (page_next->spectype, ADV_AFFECT))
		     adv_spell_affect (ch, book, page_next, next_par);
		  else if (IS_SET (page_next->spectype, ADV_ACTION))
		     adv_spell_action (ch, book, page_next, next_par);
		  else
		  {
		     send_to_char ("The spell failed.\n\r", ch);
		     return;
		  }
	       }
	       else
	       {
		  send_to_char ("The spell failed.\n\r", ch);
		  return;
	       }
	       return;
	    }
	 }
      }
      if (cast_message)
	 act2 (c_m, ch, NULL, vch, TO_CHAR);
      if (!IS_IMMORTAL (ch))
      {
	 WAIT_STATE (ch, 12);
	 if (ch->level >= LEVEL_ARCHMAGE)
	    ch->mana -= (mana_cost / 3);
	 else if (ch->level == LEVEL_MAGE)
	    ch->mana -= (mana_cost / 2);
	 else
	    ch->mana -= mana_cost;
      }
      return;
   }
/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim ) && ( get_hours( victim ) > 9 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim );
        return;
    }
*/
/*
    if ( (is_reversed) && victim != ch && !IS_CLASS(victim, CLASS_MAGE) &&
	( IS_SET(apply_bit, ADV_HIT) || IS_SET(apply_bit, ADV_MOVE)
       || IS_SET(apply_bit, ADV_MANA) ) )
    {
       stc("Bah.  Don't use training spells on other people.  Damn you.\n\r",ch);
       return;
    }

*/
   if (IS_SET (victim->extra2, AURA_NO_MAGIC) && victim != ch)
   {
      stc ("Their Anti-Magic shield dissipates your magic!\n\r", ch);
      return;
   }
   if (IS_CLASS (victim, CLASS_HIGHLANDER))
   {
      if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
      {
	 if (victim->quickening[0] >= 0)
	 {
	    victim->quickening[0] -= 0;
	    stc ("Sparkles of energy disrupt the spell before it lands.\n\r",
		 ch);
	    stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		 victim);
	    return;
	 }
      }
   }
   if (page->toughness < PURPLE_MAGIC || page->toughness > YELLOW_MAGIC)
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }
   if (page->toughness == PURPLE_MAGIC)
   {
      if ((sn = skill_lookup ("purple sorcery")) < 0)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (page->toughness == RED_MAGIC)
   {
      if ((sn = skill_lookup ("red sorcery")) < 0)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (page->toughness == BLUE_MAGIC)
   {
      if ((sn = skill_lookup ("blue sorcery")) < 0)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (page->toughness == GREEN_MAGIC)
   {
      if ((sn = skill_lookup ("green sorcery")) < 0)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (page->toughness == YELLOW_MAGIC)
   {
      if ((sn = skill_lookup ("yellow sorcery")) < 0)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }

   if (!victim_target && victim != ch)
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }
   if (not_caster && ch == victim)
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }
   else if (no_players && !IS_NPC (victim))
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }

   if (is_affected (victim, sn))
   {
      send_to_char
	 ("They are already affected by a spell of that colour.\n\r", ch);
      return;
   }

   if (IS_CLASS (victim, CLASS_HIGHLANDER))
   {
      if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
      {
	 if (victim->quickening[0] >= 0)
	 {
	    victim->quickening[0] -= 0;
	    stc ("Sparkles of energy disrupt the spell before it lands.\n\r",
		 ch);
	    stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		 victim);
            if (!IS_IMMORTAL (ch))
               WAIT_STATE (ch, 12);
	    return;
	 }
      }
   }

   if (apply_bit == 0)
   {
      enhance_stat (sn, level, ch, victim, APPLY_NONE, bonuses, affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_STR))
   {
      enhance_stat (sn, level, ch, victim, APPLY_STR, bonuses * 0.025,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_DEX))
   {
      enhance_stat (sn, level, ch, victim, APPLY_DEX, bonuses * 0.025,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_INT))
   {
      enhance_stat (sn, level, ch, victim, APPLY_INT, bonuses * 0.025,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_WIS))
   {
      enhance_stat (sn, level, ch, victim, APPLY_WIS, bonuses * 0.025,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_CON))
   {
      enhance_stat (sn, level, ch, victim, APPLY_CON, bonuses * 0.025,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   // new -- Serenity
   if (IS_SET (apply_bit, ADV_WEAK))
   {
      enhance_stat (sn, level, ch, victim, APPLY_STR, 0 - (bonuses * 0.05),
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_FRAIL))
   {
      enhance_stat (sn, level, ch, victim, APPLY_CON, 0 - (bonuses * 0.05),
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_CLUMSY))
   {
      enhance_stat (sn, level, ch, victim, APPLY_DEX, 0 - (bonuses * 0.05),
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_AMNESIA))
   {
      enhance_stat (sn, level, ch, victim, APPLY_WIS, 0 - (bonuses * 0.05),
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   // End New
   if (IS_SET (apply_bit, ADV_MANA))
   {
      if (victim->max_mana > 1 && victim->max_mana <= (bonuses * -5))
         enhance_stat (sn, level, ch, victim, APPLY_MANA, (1 - victim->max_mana),
                    affect_bit);
      else if (victim->max_mana > 1)
         enhance_stat (sn, level, ch, victim, APPLY_MANA, bonuses * 5,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_HIT))
   {
      if (victim->max_hit > 1 && victim->max_hit <= (bonuses * -5))
         enhance_stat (sn, level, ch, victim, APPLY_HIT, (1 - victim->max_hit),
                    affect_bit);
      else if (victim->max_hit > 1)
         enhance_stat (sn, level, ch, victim, APPLY_HIT, bonuses * 5,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_MOVE))
   {
      if (victim->max_move > 1 && victim->max_move <= (bonuses * -5))
         enhance_stat (sn, level, ch, victim, APPLY_MOVE, (1 - victim->max_move),
                    affect_bit);
      else if (victim->max_move > 1)
         enhance_stat (sn, level, ch, victim, APPLY_MOVE, bonuses * 5,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_AC))
   {
      enhance_stat (sn, level, ch, victim, APPLY_AC, 0 - bonuses,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_HITROLL))
   {
      enhance_stat (sn, level, ch, victim, APPLY_HITROLL, bonuses * 0.5,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_DAMROLL))
   {
      enhance_stat (sn, level, ch, victim, APPLY_DAMROLL, bonuses * 0.5,
		    affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (IS_SET (apply_bit, ADV_SAVING_SPELL))
   {
      enhance_stat (sn, level, ch, victim, APPLY_SAVING_SPELL,
		    0 - (bonuses * 0.2), affect_bit);
      affect_bit = 0;
      any_affects = TRUE;
   }
   if (!any_affects)
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }

   if (cast_message)
      act2 (c_m, ch, NULL, victim, TO_CHAR);
   if (message_one)
      act2 (c_1, ch, NULL, victim, TO_VICT);
   if (message_two)
      act2 (c_2, ch, NULL, victim, TO_NOTVICT);
   if (!IS_IMMORTAL (ch))
   {
      WAIT_STATE (ch, 12);
      if (ch->level >= LEVEL_ARCHMAGE)
	 ch->mana -= (mana_cost / 3);
      else if (ch->level == LEVEL_MAGE)
	 ch->mana -= (mana_cost / 2);
      else
	 ch->mana -= mana_cost;
   }

   if (IS_SET (page->spectype, ADV_NEXT_PAGE)
       && !IS_SET (page->spectype, ADV_SPELL_FIRST))
   {
      if (strlen (page->chpoweroff) < 2
	  || !str_cmp (page->chpoweroff, "(null)"))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page->spectype, ADV_PARAMETER))
      {
	 if (!str_cmp (page->chpoweron, "(null)"))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 else
	    strcpy (next_par, page->chpoweron);
      }
      else
	 strcpy (next_par, argument);
      if (page->specpower < page->value[0])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if ((page_next = get_page (book, page->specpower)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page_next->quest, QUEST_MASTER_RUNE))
      {
	 if (IS_SET (page_next->spectype, ADV_DAMAGE))
	    adv_spell_damage (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_AFFECT))
	    adv_spell_affect (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_ACTION))
	    adv_spell_action (ch, book, page_next, next_par);
	 else
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   return;
}

void adv_spell_action (CHAR_DATA * ch, OBJ_DATA * book, OBJ_DATA * page,
		       char *argument)
{
   char arg1[MAX_STRING_LENGTH];
   char arg2[MAX_STRING_LENGTH];
   char c_m[MAX_INPUT_LENGTH];
   char c_1[MAX_INPUT_LENGTH];
   char c_2[MAX_INPUT_LENGTH];
   OBJ_DATA *page_next;
   OBJ_DATA *obj = NULL;
   OBJ_DATA *obj2 = NULL;
   CHAR_DATA *victim = NULL;
   CHAR_DATA *victim2 = NULL;
   ROOM_INDEX_DATA *old_room = ch->in_room;
   char next_par[MAX_INPUT_LENGTH];
   int mana_cost = page->points;
   int action_bit = page->value[1];
   int action_type = page->value[2];
   bool area_affect = FALSE;
   bool victim_target = FALSE;
   bool object_target = FALSE;
   bool second_victim = FALSE;
   bool second_object = FALSE;
   bool global_target = FALSE;
   bool next_page = FALSE;
   bool parameter = FALSE;
   bool not_caster = FALSE;
   bool no_players = FALSE;
   bool cast_message = FALSE;
   bool message_one = FALSE;
   bool message_two = FALSE;
   int paracount=0;
   bool is_reversed = FALSE;
   bool only_players = FALSE;	// New by Serenity
   bool only_group = FALSE;	// New by Serenity
   bool only_kingdom = FALSE;	// New by Serenity
   bool no_group = FALSE;	// New by Serenity
   bool no_kingdom = FALSE;	// New by Serenity

   if (ch->mana < mana_cost)
   {
      send_to_char ("You have insufficient mana to chant this spell.\n\r",
		    ch);
      return;
   }
   if (ch->pcdata->powers[MAGE_CHAIN] >= 75)
   {
      send_to_char ("The spell failed.\n\r", ch);
      return;
   }
   if (IS_SET (page->spectype, ADV_NEXT_PAGE)
       && IS_SET (page->spectype, ADV_SPELL_FIRST))
   {
      if (strlen (page->chpoweroff) < 2
	  || !str_cmp (page->chpoweroff, "(null)"))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page->spectype, ADV_PARAMETER))
      {
	 paracount++;
	 if (!str_cmp (page->chpoweron, "(null)"))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 else if (paracount > 25)
	 {
	    stc ("The Spell Failed\n\r", ch);
	    return;
	 }
	 else
	    strcpy (next_par, page->chpoweron);
      }
      else
	 strcpy (next_par, argument);
      if (page->specpower < page->value[0])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if ((page_next = get_page (book, page->specpower)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page_next->quest, QUEST_MASTER_RUNE))
      {
	 if (IS_SET (page_next->spectype, ADV_DAMAGE))
	    adv_spell_damage (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_AFFECT))
	    adv_spell_affect (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_ACTION))
	    adv_spell_action (ch, book, page_next, next_par);
	 else
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }

   argument = one_argument (argument, arg1);
   argument = one_argument (argument, arg2);

   if (strlen (page->chpoweroff) > 0 && str_cmp (page->chpoweroff, "(null)"))
   {
      strcpy (c_m, page->chpoweroff);
      cast_message = TRUE;
   }
   if (strlen (page->victpoweron) > 0
       && str_cmp (page->victpoweron, "(null)"))
   {
      strcpy (c_1, page->victpoweron);
      message_one = TRUE;
   }
   if (strlen (page->victpoweroff) > 0
       && str_cmp (page->victpoweroff, "(null)"))
   {
      strcpy (c_2, page->victpoweroff);
      message_two = TRUE;
   }

   if (IS_SET (page->spectype, ADV_AREA_AFFECT))
      area_affect = TRUE;
   if (IS_SET (page->spectype, ADV_VICTIM_TARGET))
      victim_target = TRUE;
   if (IS_SET (page->spectype, ADV_OBJECT_TARGET))
      object_target = TRUE;
   if (IS_SET (page->spectype, ADV_GLOBAL_TARGET))
      global_target = TRUE;
   if (IS_SET (page->spectype, ADV_NEXT_PAGE))
      next_page = TRUE;
   if (IS_SET (page->spectype, ADV_PARAMETER))
      parameter = TRUE;
   if (IS_SET (page->spectype, ADV_NOT_CASTER))
      not_caster = TRUE;
   if (IS_SET (page->spectype, ADV_NO_PLAYERS))
      no_players = TRUE;
   if (IS_SET (page->spectype, ADV_SECOND_VICTIM))
      second_victim = TRUE;
   if (IS_SET (page->spectype, ADV_SECOND_OBJECT))
      second_object = TRUE;
   if (IS_SET (page->spectype, ADV_REVERSED))
      is_reversed = TRUE;
   if (IS_SET (page->spectype, ADV_NO_GROUP))
      no_group = TRUE;
   if (IS_SET (page->spectype, ADV_NO_KINGDOM))
      no_kingdom = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_GROUP))
      only_group = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_KINGDOM))
      only_kingdom = TRUE;
   if (IS_SET (page->spectype, ADV_ONLY_PLAYERS))
      only_players = TRUE;
   if (next_page)
      ch->pcdata->powers[MAGE_CHAIN] += 1;

   if (victim_target && !area_affect && !global_target && !object_target)
   {
      if ((victim = get_char_room (ch, arg1)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim->in_room == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (!IS_NPC (victim) && !IS_IMMUNE (victim, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }

      if (IS_SET (victim->in_room->area->aflags, AFLAG_ARENA))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_NPC (victim) && IS_SET (victim->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (victim->in_room->room_flags, ROOM_CCHAMBER))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == ch)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim ) && ( get_hours( victim ) > 9 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim );
        return;
    }
*/
      if (IS_CLASS (victim, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 5)
	    {
	       victim->quickening[0] -= 5;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		    victim);
	       return;
	    }
	 }
      }

   }
   else if (victim_target && area_affect && !global_target && !object_target)
   {
      if ((victim = get_char_world (ch, arg1)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim->in_room == NULL
	  || victim->in_room->area != ch->in_room->area)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (!IS_NPC (victim) && !IS_IMMUNE (victim, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (victim->in_room->room_flags, ROOM_CCHAMBER))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_NPC (victim) && IS_SET (victim->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == ch)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim ) && ( get_hours( victim ) > 9 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim );
        return;
    }
*/
      if (IS_CLASS (victim, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 5)
	    {
	       victim->quickening[0] -= 5;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		    victim);
	       return;
	    }
	 }
      }
   }
   else if (victim_target && global_target && !object_target)
   {
      if ((victim = get_char_world (ch, arg1)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim->in_room == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (!IS_NPC (victim) && !IS_IMMUNE (victim, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (victim->in_room->room_flags, ROOM_CCHAMBER))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_NPC (victim) && IS_SET (victim->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == ch)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim ) && ( get_hours( victim ) > 9 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim );
        return;
    }
*/
      if (IS_CLASS (victim, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 5)
	    {
	       victim->quickening[0] -= 5;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",
		    victim);
	       return;
	    }
	 }
      }
   }
   else if (object_target && !area_affect && !global_target && !victim_target)
   {
      if ((obj = get_obj_carry (ch, arg1)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (object_target && area_affect && !global_target && !victim_target)
   {
      if ((obj = get_obj_here (ch, arg1)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (object_target && global_target && !victim_target)
   {
      if ((obj = get_obj_world (ch, arg1)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (obj->in_room == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (obj->item_type == ITEM_QUEST || obj->item_type == ITEM_PIECE || obj->item_type == ITEM_NEWTOKEN)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
//Mac        
   }

   if (arg2[0] == '\0' && (second_victim || second_object))
   {
      send_to_char ("Please specify a target.\n\r", ch);
      return;
   }
   else if (second_victim && victim_target && !area_affect && !global_target
	    && !object_target)
   {
      if ((victim2 = get_char_room (ch, arg2)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim2->in_room == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == NULL || IS_NPC (victim) || IS_IMMUNE (victim, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (!IS_NPC (victim2) && !IS_IMMUNE (victim2, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (victim2->in_room->room_flags, ROOM_CCHAMBER))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_NPC (victim2)
	  && IS_SET (victim2->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == victim2)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim2 ) && ( get_hours( victim2 ) > 6 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim2 );
        return;
    }
*/
      if (IS_CLASS (victim2, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim2, HPOWER_USE_PRESERVATION))
	 {
	    if (victim2->quickening[0] >= 5)
	    {
	       victim2->quickening[0] -= 5;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",		    victim2);
	       return;
	    }
	 }
      }
   }
   else if (second_victim && victim_target && area_affect && !global_target
	    && !object_target)
   {
      if ((victim2 = get_char_world (ch, arg2)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim2->in_room == NULL
	  || victim2->in_room->area != ch->in_room->area)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == NULL || IS_NPC (victim) || IS_IMMUNE (victim, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (!IS_NPC (victim2) && !IS_IMMUNE (victim2, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (victim2->in_room->room_flags, ROOM_CCHAMBER))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_NPC (victim2)
	  && IS_SET (victim2->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == victim2)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim2 ) && ( get_hours( victim2 ) > 6 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim2 );
        return;
    }
*/
      if (IS_CLASS (victim2, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim2, HPOWER_USE_PRESERVATION))
	 {
	    if (victim2->quickening[0] >= 5)
	    {
	       victim2->quickening[0] -= 5;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",		    victim2);
	       return;
	    }
	 }
      }
   }
   else if (second_victim && victim_target && global_target && !object_target)
   {
      if ((victim2 = get_char_world (ch, arg2)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim2->in_room == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == NULL || IS_NPC (victim) || IS_IMMUNE (victim, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (!IS_NPC (victim2) && !IS_IMMUNE (victim2, IMM_SUMMON))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (victim2->in_room->room_flags, ROOM_CCHAMBER))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_NPC (victim2)
	  && IS_SET (victim2->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("The spell failed.\n\r", ch);
	 return;
      }
      if (victim == victim2)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
/*
    if ( IS_IMMORTAL( ch ) && ( !IS_IMMORTAL( victim2 ) && ( get_hours( victim2 ) > 6 ) ) )
    {
        stc( "You are an Immortal and they are neither an Immortal nor a Newbie.\n\rNo.\n\r", ch );
        stc( "An Immortal tried to chant on you.\n\rThey failed.\n\r", victim2 );
        return;
    }
*/
      if (IS_CLASS (victim2, CLASS_HIGHLANDER))
      {
	 if (IS_DEMPOWER (victim2, HPOWER_USE_PRESERVATION))
	 {
	    if (victim2->quickening[0] >= 5)
	    {
	       victim2->quickening[0] -= 5;
	       stc ("Sparkles of energy disrupt the spell before it lands.\n\r", ch);
	       stc ("Sparkles of energy disrupt a spell before it lands.\n\r",		    victim2);
	       return;
	    }
	 }
      }
   }
   else if (second_object && object_target && !area_affect && !global_target
	    && !victim_target)
   {
      if ((obj2 = get_obj_carry (ch, arg2)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (second_object && object_target && area_affect && !global_target
	    && !victim_target)
   {
      if ((obj2 = get_obj_here (ch, arg2)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   else if (second_object && object_target && global_target && !victim_target)
   {
      if ((obj2 = get_obj_world (ch, arg2)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }

   if (victim != NULL)
   {
      if (victim->level > ch->spl[PURPLE_MAGIC])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }

   if (victim2 != NULL)
   {
      if (victim2->level > ch->spl[PURPLE_MAGIC])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }

   switch (action_bit)
   {
   default:
      send_to_char ("The spell failed.\n\r", ch);
      return;
   case ACTION_MOVE:
      if (IS_SET (ch->flag2, AFF2_INARENA))
      {
	 stc ("You failed.\n\r", ch);
	 return;
      }
      if (IS_SET (ch->in_room->room_flags, ROOM_GOD))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (ch->position == POS_FIGHTING)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (object_target || second_object)
      {
	 if (obj)
	 {
	    if (obj->item_type == ITEM_PIECE || obj->item_type == ITEM_STOKEN
		|| obj->item_type == ITEM_QUEST
                || obj->item_type == ITEM_AQUEST
                || obj->item_type == ITEM_NEWTOKEN
		|| IS_SET (obj->in_room->area->aflags, AFLAG_HQ)
		|| IS_SET (obj->in_room->room_flags, ROOM_CCHAMBER))
	    {
	       stc ("Unable to target that item.\n\r", ch);
	       return;
	    }
	 }
	 if (obj2)
	 {
            if (obj2->carried_by != NULL
                || obj2->item_type == ITEM_PIECE
		|| obj2->item_type == ITEM_STOKEN
                || obj2->item_type == ITEM_QUEST
                || obj2->item_type == ITEM_AQUEST
                || obj2->item_type == ITEM_NEWTOKEN
		|| IS_SET (obj2->in_room->area->aflags, AFLAG_HQ)
                || IS_SET (obj2->in_room->room_flags, ROOM_CCHAMBER))
	    {
	       stc ("Unable to target that item.\n\r", ch);
	       return;
	    }
	 }
      }
      if (!victim_target && !second_victim && !object_target
	  && !second_object)
      {
	 if (cast_message)
	    act2 (c_m, ch, NULL, NULL, TO_CHAR);
	 if (message_one)
	    act2 (c_1, ch, NULL, NULL, TO_ROOM);
	 char_from_room (ch);
	 char_to_room (ch, old_room);
	 if (message_two)
	    act2 (c_2, ch, NULL, NULL, TO_ROOM);
      }
      else if (arg1[0] == '\0')
      {
	 send_to_char ("Please specify a target.\n\r", ch);
	 return;
      }
      else if (victim_target && !second_victim && !object_target
	       && !second_object)
      {
	 if (victim == NULL || victim->in_room == NULL
	     || victim->in_room == ch->in_room)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (is_reversed)
	 {
	    if (victim->position == POS_FIGHTING)
	    {
	       send_to_char ("The spell failed.\n\r", ch);
	       return;
	    }
	    if (cast_message)
	       act2 (c_m, victim, NULL, NULL, TO_CHAR);
	    if (message_one)
	       act2 (c_1, victim, NULL, NULL, TO_ROOM);
	    char_from_room (victim);
	    char_to_room (victim, ch->in_room);

	    if (message_two)
	       act2 (c_2, victim, NULL, NULL, TO_ROOM);
	    do_look (victim, "");
	 }
	 else
	 {
	    if (ch->position == POS_FIGHTING)
	    {
	       send_to_char ("The spell failed.\n\r", ch);
	       return;
	    }
	    if (cast_message)
	       act2 (c_m, ch, NULL, NULL, TO_CHAR);
	    if (message_one)
	       act2 (c_1, ch, NULL, NULL, TO_ROOM);
	    char_from_room (ch);
	    char_to_room (ch, victim->in_room);
	    if (message_two)
	       act2 (c_2, ch, NULL, NULL, TO_ROOM);
	    do_look (ch, "");
	 }
      }
      else if (!victim_target && !second_victim && object_target
	       && !second_object)
      {
	 if (obj == NULL || obj->in_room == NULL
	     || obj->in_room == ch->in_room)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (IS_SET (obj->in_room->room_flags, ROOM_GOD))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (cast_message)
	    act2 (c_m, ch, obj, NULL, TO_CHAR);
	 if (message_one)
	    act2 (c_1, ch, obj, NULL, TO_ROOM);
	 if (is_reversed)
	 {
	    obj_from_room (obj);
	    obj_to_room (obj, ch->in_room);
	 }
	 else
	 {
	    char_from_room (ch);
	    char_to_room (ch, obj->in_room);
	    do_look (ch, "");
	 }
	 if (message_two)
	    act2 (c_2, ch, obj, NULL, TO_ROOM);
      }
      else if (victim_target && second_victim && !object_target
	       && !second_object)
      {
	 if (victim == NULL || victim->in_room == NULL)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (victim2 == NULL || victim2->in_room == NULL
	     || victim2->in_room == victim->in_room)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (IS_SET (victim->in_room->room_flags, ROOM_GOD)
	     || IS_SET (victim2->in_room->room_flags, ROOM_GOD))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (is_reversed)
	 {
	    if (victim2->position == POS_FIGHTING)
	    {
	       send_to_char ("The spell failed.\n\r", ch);
	       return;
	    }
	    if (cast_message)
	       act2 (c_m, victim2, NULL, victim, TO_CHAR);
	    if (message_one)
	       act2 (c_1, victim2, NULL, victim, TO_ROOM);
	    char_from_room (victim2);
	    char_to_room (victim2, victim->in_room);
	    if (message_two)
	       act2 (c_2, victim2, NULL, victim, TO_ROOM);
	    do_look (victim2, "");
	 }
	 else
	 {
	    if (victim->position == POS_FIGHTING)
	    {
	       send_to_char ("The spell failed.\n\r", ch);
	       return;
	    }
	    if (cast_message)
	       act2 (c_m, victim, NULL, victim2, TO_CHAR);
	    if (message_one)
	       act2 (c_1, victim, NULL, victim2, TO_ROOM);
	    char_from_room (victim);
	    char_to_room (victim, victim2->in_room);
	    if (message_two)
	       act2 (c_2, victim, NULL, victim2, TO_ROOM);
	    do_look (victim, "");
	 }
      }
      else if (victim_target && !second_victim && !object_target
	       && second_object)
      {
	 if (victim == NULL || victim->in_room == NULL)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (obj2 == NULL || obj2->in_room == NULL
             || obj2->carried_by != NULL
	     || obj2->in_room == victim->in_room)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (IS_SET (obj2->in_room->room_flags, ROOM_GOD)
	     || IS_SET (victim->in_room->room_flags, ROOM_GOD))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (cast_message)
	    act2 (c_m, victim, NULL, NULL, TO_CHAR);
	 if (message_one)
	    act2 (c_1, victim, obj2, NULL, TO_ROOM);
	 if (is_reversed)
	 {
	    obj_from_room (obj2);
	    obj_to_room (obj2, victim->in_room);
	 }
	 else
	 {
	    if (victim->position == POS_FIGHTING)
	    {
	       send_to_char ("The spell failed.\n\r", ch);
	       return;
	    }
	    char_from_room (victim);
	    char_to_room (victim, obj2->in_room);
	    do_look (victim, "");
	 }
	 if (message_two)
	    act2 (c_2, victim, obj2, NULL, TO_ROOM);
      }
      else if (!victim_target && !second_victim && object_target
	       && second_object)
      {
	 if (obj == NULL || obj->in_room == NULL)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (obj2 == NULL || obj2->in_room == NULL
             || obj2->carried_by != NULL
	     || obj2->in_room == obj->in_room)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (IS_SET (obj->in_room->room_flags, ROOM_GOD)
	     || IS_SET (obj2->in_room->room_flags, ROOM_GOD))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (cast_message)
	    act2 (c_m, ch, obj, NULL, TO_CHAR);
	 if (is_reversed)
	 {
	    if (message_one)
	       act2 (c_1, ch, obj2, NULL, TO_ROOM);
	    obj_from_room (obj2);
	    obj_to_room (obj2, obj->in_room);
	    char_from_room (ch);
	    char_to_room (ch, obj->in_room);
	    if (message_two)
	       act2 (c_2, ch, obj2, NULL, TO_ROOM);
	    char_from_room (ch);
	    char_to_room (ch, old_room);
	 }
	 else
	 {
	    if (message_one)
	       act2 (c_1, ch, obj, NULL, TO_ROOM);
	    obj_from_room (obj);
	    obj_to_room (obj, obj2->in_room);
	    char_from_room (ch);
	    char_to_room (ch, obj2->in_room);
	    if (message_two)
	       act2 (c_2, ch, obj, NULL, TO_ROOM);
	    char_from_room (ch);
	    char_to_room (ch, old_room);
	 }
      }
      else if (!victim_target && second_victim && object_target
	       && !second_object)
      {
	 if (victim2 == NULL || victim2->in_room == NULL)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (obj == NULL || obj->in_room == NULL
	     || obj->in_room == victim2->in_room)
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (IS_SET (obj->in_room->room_flags, ROOM_GOD)
	     || IS_SET (victim2->in_room->room_flags, ROOM_GOD))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 if (cast_message)
	    act2 (c_m, victim2, NULL, NULL, TO_CHAR);
	 if (message_one)
	    act2 (c_1, victim, obj2, NULL, TO_ROOM);
	 if (is_reversed)
	 {
	    if (victim2->position == POS_FIGHTING)
	    {
	       send_to_char ("The spell failed.\n\r", ch);
	       return;
	    }
	    char_from_room (victim2);
	    char_to_room (victim2, obj->in_room);
	    do_look (victim2, "");
	 }
	 else
	 {
	    obj_from_room (obj);
	    obj_to_room (obj, victim2->in_room);
	 }
	 if (message_two)
	    act2 (c_2, victim2, obj, NULL, TO_ROOM);
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      break;
   case ACTION_MOB:
      if (action_type < 1)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
//      if (IS_NPC (ch) || ch->pcdata->followers > 4)
//      {
//       send_to_char ("The spell failed.\n\r", ch);
//       return;
//      }
	if ( action_type > 100 )
	{
		send_to_char( "OH...Shit!\n\rThe magic rebounded!\n\r", ch );
		act( "$n is covered in a wave of rebounding magic.", ch, NULL, NULL, TO_ROOM );
		ch->hit = ch->hit - ( ch->max_hit / 10 );
		if ( ch->hit < -10 )
			ch->hit = -10;
		if ( ch->hit < 0 )
		{
			send_to_char( "You black out!\n\r", ch );
			act( "$n blacks out from the magic wave.", ch, NULL, NULL, TO_ROOM );
			ch->position= POS_MORTAL;
		}
		return;
	}
      if ((victim = create_mobile (get_mob_index (action_type))) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (cast_message)
	 act2 (c_m, ch, NULL, victim, TO_CHAR);
      if (message_one)
	 act2 (c_1, ch, NULL, victim, TO_ROOM);
      char_to_room (victim, ch->in_room);
      SET_BIT (victim->act, ACT_NOEXP);
      {
	 char short_rename_buf[5000];
	 sprintf (short_rename_buf, "a shadow of %s", victim->short_descr);
	 free_string (victim->short_descr);
	 victim->short_descr = str_dup (short_rename_buf);
      }
      victim->level =
	 number_range (ch->spl[PURPLE_MAGIC] / 2, ch->spl[PURPLE_MAGIC]);
//      if (victim->level > ch->spl[PURPLE_MAGIC])
//      {
//       send_to_char ("The spell failed.\n\r", ch);
//       extract_char (victim, TRUE, FALSE);
//       return;
//      }
      break;
   case ACTION_OBJECT:
      if (action_type < 1)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if ((obj = create_object (get_obj_index (action_type), 0)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (cast_message)
	 act2 (c_m, ch, obj, NULL, TO_CHAR);
      if (message_one)
	 act2 (c_1, ch, obj, NULL, TO_ROOM);

      {
	 char short_rename_buf[5000];
	 sprintf (short_rename_buf, "a shadow of %s", obj->short_descr);
	 free_string (obj->short_descr);
	 obj->short_descr = str_dup (short_rename_buf);
      }
      free_string (obj->questmaker);
      obj->questmaker = str_dup (ch->name);
      obj_to_room (obj, ch->in_room);

      if (IS_SET (obj->quest, QUEST_ARTIFACT)
	  || IS_SET (obj->spectype, SITEM_DEMONIC)
	  || IS_SET (obj->extra_flags, ITEM_VANISH)
	  || IS_SET (obj->quest, QUEST_RELIC)
//next 2 lines check for arti creation
	  || (obj->pIndexData->vnum >= 29500
	      && obj->pIndexData->vnum <= 29521)
          || (obj->pIndexData->vnum >= 33600
              && obj->pIndexData->vnum <= 33699)
          || (obj->pIndexData->vnum >= 25 && obj->pIndexData->vnum <= 47))
      {
	 act ("$p explodes, hurling you to the ground!", ch, obj, NULL,
	      TO_CHAR);
	 act ("$p explodes, hurling $n to the ground!", ch, obj, NULL,
	      TO_ROOM);
	 extract_obj (obj);
	 ch->position = POS_STUNNED;
	 update_pos (ch);
	 return;
//      if ( IS_SET( obj->quest, QUEST_ARTIFACT ) )
//              REMOVE_BIT( obj->quest, QUEST_ARTIFACT );
//      if ( IS_SET( obj->spectype, SITEM_DEMONIC ) )
//              REMOVE_BIT( obj->spectype, SITEM_DEMONIC );
//      if ( IS_SET( obj->extra_flags, ITEM_VANISH ) )
//              REMOVE_BIT( obj->extra_flags, ITEM_VANISH );
//      if ( IS_SET( obj->quest, QUEST_RELIC ) )
//              REMOVE_BIT( obj->quest, QUEST_RELIC );
      }

      break;

   }
   if (!IS_IMMORTAL (ch))
   {
      WAIT_STATE (ch, 12);
      if (ch->level >= LEVEL_ARCHMAGE)
	 ch->mana -= (mana_cost / 3);
      else if (ch->level == LEVEL_MAGE)
	 ch->mana -= (mana_cost / 2);
      else
	 ch->mana -= mana_cost;
   }

   if (IS_SET (page->spectype, ADV_NEXT_PAGE)
       && !IS_SET (page->spectype, ADV_SPELL_FIRST))
   {
      if (strlen (page->chpoweroff) < 2
	  || !str_cmp (page->chpoweroff, "(null)"))
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page->spectype, ADV_PARAMETER))
      {
	 if (!str_cmp (page->chpoweron, "(null)"))
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
	 else
	    strcpy (next_par, page->chpoweron);
      }
      else
	 strcpy (next_par, argument);
      if (page->specpower < page->value[0])
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if ((page_next = get_page (book, page->specpower)) == NULL)
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
      if (IS_SET (page_next->quest, QUEST_MASTER_RUNE))
      {
	 if (IS_SET (page_next->spectype, ADV_DAMAGE))
	    adv_spell_damage (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_AFFECT))
	    adv_spell_affect (ch, book, page_next, next_par);
	 else if (IS_SET (page_next->spectype, ADV_ACTION))
	    adv_spell_action (ch, book, page_next, next_par);
	 else
	 {
	    send_to_char ("The spell failed.\n\r", ch);
	    return;
	 }
      }
      else
      {
	 send_to_char ("The spell failed.\n\r", ch);
	 return;
      }
   }
   return;
}
void do_color (CHAR_DATA * ch, char *argument)
{
   char buf[MAX_STRING_LENGTH];
   char arg[MAX_INPUT_LENGTH];

   char clan[MAX_INPUT_LENGTH];
   char type[MAX_INPUT_LENGTH];
   char color[5];
   CHAR_DATA *gch;
   one_argument (argument, arg);
   
   if (IS_NPC (ch))
      return;
   if (!IS_CLASS (ch, CLASS_MAGE))
   {
      do_rand_typo (ch);
      return;
   }

   sprintf (buf, "The Magi:\n\r");
   stc (buf, ch);
   send_to_char
      ("#c[      #pName      #c] [    #yLevel   #c] [ #pClan#c            ] [  #rHits  #c] [  #bMana  #c] [  #gMove  #c] [    #wExp     #c]#n\n\r",
       ch);
   for (gch = char_list; gch != NULL; gch = gch->next)
   {
      if (IS_NPC (gch))
	 continue;
      if (!IS_CLASS (gch, CLASS_MAGE))
	 continue;
      if (IS_IMMORTAL (gch) && !can_see (ch, gch))
	 continue;
            if (gch->clannum > 0)
            {
             if (!str_cmp(gch->name, nclans_table[gch->clannum].leader))
                    sprintf( type, "Oracle");
             else if (!str_cmp(gch->name, nclans_table[gch->clannum].prince))
                    sprintf(type, "Paragon");
             else   if (get_trust (gch) == LEVEL_APPRENTICE)
	            sprintf (type, "Disciple");
             else if (get_trust (gch) == LEVEL_MAGE)
	            sprintf (type, "Adept");
            
           }
      else
      {
      if (get_trust (gch) == LEVEL_APPRENTICE)
	 sprintf (type, "Disciple");
      else if (get_trust (gch) == LEVEL_MAGE)
	 sprintf (type, "Adept");
      else if (get_trust (gch) == LEVEL_ARCHMAGE)
	 sprintf (type, "Oracle");
      else
	 sprintf (type, "Unknown");
      }
      if (gch->clannum > 0)
          sprintf(clan, "%s", nclans_table[gch->clannum].name);
      else
          sprintf(clan, "None");

      if (gch->pcdata->powers[MPOWER_RUNE0] == PURPLE_MAGIC)
	 sprintf (color, "#P");
      else if (gch->pcdata->powers[MPOWER_RUNE0] == RED_MAGIC)
	 sprintf (color, "#r");
      else if (gch->pcdata->powers[MPOWER_RUNE0] == BLUE_MAGIC)
	 sprintf (color, "#b");
      else if (gch->pcdata->powers[MPOWER_RUNE0] == GREEN_MAGIC)
	 sprintf (color, "#g");
      else if (gch->pcdata->powers[MPOWER_RUNE0] == YELLOW_MAGIC)
	 sprintf (color, "#y");
      else
	 sprintf (color, "#n");

      sprintf (buf,
               "#c[%s%-16s#c] [#y%-12s#c] [#p%-17s#c] [#r%-8d#c] [#b%-8d#c] [#g%-8d#c] [#w%-12lli#c]#n\n\r",
	       color, capitalize (gch->name), type,clan, gch->hit, gch->mana,
	       gch->move, gch->exp);
      send_to_char (buf, ch);
   }
   return;
}

void do_promote (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg[MAX_INPUT_LENGTH];

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!IS_CLASS (ch, CLASS_MAGE))
   {
      send_to_char ("Huh?\n\r", ch);
      return;
   }

   if (ch->level < (LEVEL_ARCHMAGE))
   {
      send_to_char ("Only Archmages Can Promote Apprentices!\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      send_to_char ("Promote whom?\n\r", ch);
      return;
   }

   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      send_to_char ("They aren't here.\n\r", ch);
      return;
   }

   if (IS_NPC (victim))
   {
      send_to_char ("You can't Promote MOBS DUMBASS!\n\r", ch);
      return;
   }

   if (IS_IMMORTAL (victim))
   {
      send_to_char ("But they are Better than you already!\n\r", ch);
      return;
   }

   if (ch == victim)
   {
      send_to_char ("You cannot promote yourself.\n\r", ch);
      return;
   }

   if (!IS_CLASS (victim, CLASS_MAGE))
   {
      send_to_char ("But they aren't even an Apprentice!!\n\r", ch);
      return;
   }

   if (victim->level > 4)
   {
      send_to_char ("They cannot be promoted!\n\r", ch);
      return;
   }

   if (victim->level < LEVEL_AVATAR && !IS_IMMORTAL (victim))
   {
      send_to_char ("You can only Promote Apprentices!\n\r", ch);
      return;
   }

   if (!IS_IMMUNE (victim, IMM_VAMPIRE))
   {
      send_to_char ("You cannot promote an unwilling person.\n\r", ch);
      return;
   }

   if (ch->exp < 100000)
   {
      send_to_char
	 ("You cannot afford the 100000 exp required to teach them.\n\r", ch);
      return;
   }

   if (victim->exp < 500000)
   {
      send_to_char
	 ("They cannot afford the 500000 exp required to learn from you.\n\r",
	  ch);
      return;
   }

   ch->exp -= 100000;
   victim->exp -= 500000;

   act ("You endow $N with the power of the mastery rune!", ch, NULL, victim,
	TO_CHAR);
   act ("$n endows $N with the power of the mastery rune!", ch, NULL, victim,
	TO_NOTVICT);
   act ("$n endows the power of the mastery rune upon you!", ch, NULL, victim,
	TO_VICT);
   victim->level = LEVEL_MAGE;
   victim->trust = victim->level;
   send_to_char ("You are now a full Mage!\n\r", victim);
   save_char_obj (ch);
   save_char_obj (victim);
   return;
}