legend/
legend/area/
legend/player/
/***************************************************************************
 *  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.                                        *
 ***************************************************************************/

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include "merc.h"

void mage_damage
args ((CHAR_DATA * ch, CHAR_DATA * victim, int dam, const char *message,
       int type));
void mage_message
args ((CHAR_DATA * ch, CHAR_DATA * victim, int dam, const char *message,
       int type));
int mage_immunity args ((CHAR_DATA * ch, int dam, const char *msg, int type));
void update_damcap args ((CHAR_DATA * ch, CHAR_DATA * victim));
void set_fighting args ((CHAR_DATA * ch, CHAR_DATA * victim));
void check_killer args ((CHAR_DATA * ch, CHAR_DATA * victim));
int check_quint args ((CHAR_DATA * ch));
void subtract_quint args ((CHAR_DATA * ch, int number));
void add_quint args ((CHAR_DATA * ch, int number));

const char *sphere_name[9] = {
   "Correspondence", "Life",
   "Prime", "Entropy",
   "Mind", "Spirit",
   "Forces", "Matter",
   "Time"
};

void do_advance (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg[MIL];

   argument = one_argument (argument, arg);
   if (IS_NPC (ch))
      return;

   if (!IS_CLASS (ch, CLASS_MAGE))
   {
      do_rand_typo (ch);
      return;
   }
   if (ch->level < LEVEL_ARCHMAGE)
   {
      stc ("Only Oracles can advance adepts.\n\r", ch);
      return;
   }
   if (arg[0] == '\0')
   {
      send_to_char ("Advance 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 (ch == victim)
   {
      stc ("Not on yourself\n\r", ch);
      return;
   }
   if (IS_NPC (victim))
   {
      stc ("Not on NPC's\n\r", ch);
      return;
   }
   if (!IS_CLASS (victim, CLASS_MAGE))
   {
      stc ("You may only Advance Mages\n\r", ch);
      return;
   }
   if (victim->level < LEVEL_MAGE)
   {
      stc ("You may only advance Adepts.\n\r", ch);
      return;
   }

   if (victim->level == LEVEL_ARCHMAGE)
   {
      stc ("They have already been advanced to Oracle\n\r", ch);
      return;
   }

   if (victim->max_mana < 30000)
   {
      stc ("They dont have the 30,000 mana requirement\n\r", ch);
      return;
   }
   if (victim->exp < 1000000)
   {
      stc ("They dont have the required 10 million experience points\n\r",
	   ch);
      return;
   }

   victim->exp -= 1000000;
   victim->level = LEVEL_ARCHMAGE;
   victim->trust = LEVEL_ARCHMAGE;
   act ("$n takes out a satchel of sand and draws an emblem of 3 ancient runes\n\r" "on the ground forming a triangle surrounding $N.\n\r", ch, NULL, victim, TO_ROOM);
   stcprintf (ch, "You have advanced %s to Oracle level\n\r", victim->name);
   act ("With a puff of smoke some ancient power is transfered from $N into $n.\n\r", ch, NULL, victim, TO_ROOM);
   stcprintf (victim, "%s has advanced you to Oracle level\n\r", ch->name);
   return;
}

void do_auranomagic (CHAR_DATA * ch, char *argument)
{
   char buf[MSL];

   if (IS_NPC (ch))
      return;

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

   if (ch->fight_timer > 0 && !IS_SET (ch->extra2, AURA_NO_MAGIC))
   {
      send_to_char ("Not until your fight timer expires.\n\r", ch);
      return;
   }

   if (IS_SET (ch->flag2, AFF2_INARENA)
       && !IS_SET (ch->extra2, AURA_NO_MAGIC))
   {
      stc ("Not while you're in the arena.\n\r", ch);
      return;
   }
   if (IS_SET (ch->war, WARRING) && !IS_SET (ch->extra2, AURA_NO_MAGIC))
   {
      stc ("Not while in a war!\n\r", ch);
      return;
   }
   if (IS_SET (ch->extra2, AURA_NO_MAGIC))
   {
      REMOVE_BIT (ch->extra2, AURA_NO_MAGIC);
      send_to_char ("Your magickal shield dissipates!.\n\r", ch);
      ch->pcdata->majesty = 180;
   }
   else
   {
      if (ch->pcdata->majesty > 0)
      {
	 if (ch->pcdata->majesty > 1)
	    sprintf (buf,
		     "You cannot raise your Magickal shield for another %d seconds.\n\r",
		     ch->pcdata->majesty);
	 else
	    sprintf (buf,
		     "You cannot raise your Magickal shield for another 1 second.\n\r");
	 send_to_char (buf, ch);
	 return;
      }
      SET_BIT (ch->extra2, AURA_NO_MAGIC);
      send_to_char ("A magical shield surrounds you.\n\r", ch);
   }

   return;
}

/* Mage Prince command */
void do_paragon (CHAR_DATA * ch, char *argument)
{

   CHAR_DATA *victim;
   char arg[MAX_STRING_LENGTH];

   argument = one_argument (argument, arg);

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

   if (ch->level < 6)
   {
      stc ("Only the oracle has the ability to make paragons!.\n\r", ch);
      return;
   }
   if (strlen (ch->clan) < 3)
   {
      stc ("You have no tradition.\n\r", ch);
      return;
   }
   if (arg[0] == '\0')
   {
      stc ("Paragon who?\n\r", ch);
      return;
   }
   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      send_to_char ("They are not here.\n\r", ch);
      return;
   }

   if (IS_NPC (victim))
   {
      send_to_char ("Not on NPCs.\n\r", ch);
      return;
   }

   if (!IS_CLASS (victim, CLASS_MAGE))
   {
      stc ("But they are not a Mage!\n\r", ch);
      return;
   }

   if (str_cmp (victim->clan, ch->clan))
   {
      send_to_char ("They are not of your Tradition\n\r", ch);
      return;
   }
   if (ch == victim)
   {
      send_to_char ("You can't do that.\n\r", ch);
      return;
   }

   if (IS_SET (victim->special, SPC_PRINCE))
   {
      REMOVE_BIT (victim->special, SPC_PRINCE);
      send_to_char ("You are no longer a Paragon.\n\r", victim);
      send_to_char ("They are no longer a Paragon.\n\r", ch);
      save_char_obj (victim);
      return;
   }
   else
   {
      SET_BIT (victim->special, SPC_PRINCE);
      send_to_char ("You are now a Paragon!\n\r", victim);
      send_to_char ("You make them a Paragon!.\n\r", ch);
      save_char_obj (victim);
      return;
   }
}

bool is_memb (CHAR_DATA * ch)
{
   int test = number_percent ();

   if (IS_SET (ch->mflags, MAGE_EMBRACED2))
   {
      stc ("You struggle to move, but the earth surrounding you won't budge.\n\r", ch);
      return TRUE;
   }

   else if (IS_SET (ch->mflags, MAGE_EMBRACED1) && test > 30)
   {
      stc ("You struggle to move, but the earth surrounding you won't budge.\n\r", ch);
      return TRUE;
   }

   else if (IS_SET (ch->mflags, MAGE_EMBRACED1) && test <= 30)
   {
      stc ("You manage to break free of the earth surrounding you.\n\r", ch);
      REMOVE_BIT (ch->mflags, MAGE_EMBRACED1);
      return FALSE;
   }

   return FALSE;
}

bool is_mage (CHAR_DATA * ch)
{
   if (!IS_CLASS (ch, CLASS_MAGE))
   {
      stc ("Huh?\n\r", ch);
      return FALSE;
   }

   return TRUE;
}

void creategate (CHAR_DATA * ch, int inroom, int toroom, bool perm)
{
   OBJ_DATA *in_gate;
   OBJ_DATA *to_gate;
   ROOM_INDEX_DATA *pIn;
   ROOM_INDEX_DATA *pTo;

   pIn = get_room_index (inroom);
   pTo = get_room_index (toroom);

   in_gate = create_object (get_obj_index (OBJ_VNUM_WGATE), 0);
   obj_to_room (in_gate, pIn);
   in_gate->value[0] = toroom;
   in_gate->value[1] = MAGE_INROOM_GATE;
   in_gate->value[3] = inroom;
   if (!perm)
      in_gate->timer = ch->spheres[MCOR] / 2;
   in_gate->item_type = ITEM_WGATE;

   to_gate = create_object (get_obj_index (OBJ_VNUM_WGATE), 0);
   obj_to_room (to_gate, pTo);
   to_gate->value[0] = inroom;
   to_gate->value[1] = MAGE_TOROOM_GATE;
   to_gate->value[3] = toroom;
   if (!perm)
      to_gate->timer = ch->spheres[MCOR] + 3;
   to_gate->item_type = ITEM_WGATE;

   return;
}

void do_spheres (CHAR_DATA * ch, char *argument)
{
   char buf[MAX_STRING_LENGTH];
   char arg1[MAX_INPUT_LENGTH];
   char arg2[MAX_INPUT_LENGTH];
   int disc, cost;

   cost = 0;

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

   if (!IS_CLASS (ch, CLASS_MAGE))
   {
      stc ("OoOoOo, look daddy! Pretty spheres!\n\r", ch);
      return;
   }

   if (arg1[0] == '\0')
   {
      stc ("#b-=[#w**#b]_[#w**#b]=-=[#w**#b]_[#w**#b]=-=[#w**#b]_[#w**#b] #wSpheres #b[#w**#b]_[#w**#b]=-=[#w**#b]_[#w**#b]=-=[#w**#b]_[#w**#b]=-#n\n\r", ch);
      stc ("#b[#w+#b]                                                                         #b[#w+#b]\n\r", ch);
      sprintf (buf,
	       "#b[#w+#b]    #cCorrespondence  #e(#w%s%s%s%s%s#e)#c       Life  #e  (#w%s%s%s%s%s#e)#c      Forces #e(#w%s%s%s%s%s#e)    #b[#w+#b]#n\n\r",
	       ch->spheres[MCOR] >= 1 ? "*" : " ",
	       ch->spheres[MCOR] >= 2 ? "*" : " ",
	       ch->spheres[MCOR] >= 3 ? "*" : " ",
	       ch->spheres[MCOR] >= 4 ? "*" : " ",
	       ch->spheres[MCOR] >= 5 ? "*" : " ",
	       ch->spheres[MLIF] >= 1 ? "*" : " ",
	       ch->spheres[MLIF] >= 2 ? "*" : " ",
	       ch->spheres[MLIF] >= 3 ? "*" : " ",
	       ch->spheres[MLIF] >= 4 ? "*" : " ",
	       ch->spheres[MLIF] >= 5 ? "*" : " ",
	       ch->spheres[MFOR] >= 1 ? "*" : " ",
	       ch->spheres[MFOR] >= 2 ? "*" : " ",
	       ch->spheres[MFOR] >= 3 ? "*" : " ",
	       ch->spheres[MFOR] >= 4 ? "*" : " ",
	       ch->spheres[MFOR] >= 5 ? "*" : " ");
      stc (buf, ch);
      sprintf (buf,
	       "#b[#w+#b]#c       Entropy      #e(#w%s%s%s%s%s#e)#c       Mind #e   (#w%s%s%s%s%s#e)#c      Spirit #e(#w%s%s%s%s%s#e)#b    [#w+#b]\n\r",
	       ch->spheres[MENT] >= 1 ? "*" : " ",
	       ch->spheres[MENT] >= 2 ? "*" : " ",
	       ch->spheres[MENT] >= 3 ? "*" : " ",
	       ch->spheres[MENT] >= 4 ? "*" : " ",
	       ch->spheres[MENT] >= 5 ? "*" : " ",
	       ch->spheres[MMIN] >= 1 ? "*" : " ",
	       ch->spheres[MMIN] >= 2 ? "*" : " ",
	       ch->spheres[MMIN] >= 3 ? "*" : " ",
	       ch->spheres[MMIN] >= 4 ? "*" : " ",
	       ch->spheres[MMIN] >= 5 ? "*" : " ",
	       ch->spheres[MSPI] >= 1 ? "*" : " ",
	       ch->spheres[MSPI] >= 2 ? "*" : " ",
	       ch->spheres[MSPI] >= 3 ? "*" : " ",
	       ch->spheres[MSPI] >= 4 ? "*" : " ",
	       ch->spheres[MSPI] >= 5 ? "*" : " ");
      stc (buf, ch);
      sprintf (buf,
	       "#b[#w+#b] #c       Prime    #e   (#w%s%s%s%s%s#e)#c       Time   #e (#w%s%s%s%s%s#e)#c      Matter #e(#w%s%s%s%s%s#e)#b    [#w+#b]#n\n\r",
	       ch->spheres[MPRI] >= 1 ? "*" : " ",
	       ch->spheres[MPRI] >= 2 ? "*" : " ",
	       ch->spheres[MPRI] >= 3 ? "*" : " ",
	       ch->spheres[MPRI] >= 4 ? "*" : " ",
	       ch->spheres[MPRI] >= 5 ? "*" : " ",
	       ch->spheres[MTIM] >= 1 ? "*" : " ",
	       ch->spheres[MTIM] >= 2 ? "*" : " ",
	       ch->spheres[MTIM] >= 3 ? "*" : " ",
	       ch->spheres[MTIM] >= 4 ? "*" : " ",
	       ch->spheres[MTIM] >= 5 ? "*" : " ",
	       ch->spheres[MMAT] >= 1 ? "*" : " ",
	       ch->spheres[MMAT] >= 2 ? "*" : " ",
	       ch->spheres[MMAT] >= 3 ? "*" : " ",
	       ch->spheres[MMAT] >= 4 ? "*" : " ",
	       ch->spheres[MMAT] >= 5 ? "*" : " ");
      stc (buf, ch);
      stc ("#b[#w+#b]                                                                         [#w+#b]\n\r", ch);

      stc ("#b-=[#w**#b]_[#w**#b]=-=[#w**#b]_[#w**#b]=-=[#w**#b]_[#w**#b]---------[#w**#b]_[#w**#b]=-=[#w**#b]_[#w**#b]=-=[#w**#b]_[#w**#b]=-#n\n\r", ch);
      return;
   }

   if (arg2[0] == '\0')
   {
      if (!str_prefix (arg1, "Life"))
      {
	 if (ch->spheres[MLIF] == 0)
	 {
	    stc ("You have no knowledge of the sphere of Life.\n\r", ch);
	    return;
	 }

	 if (ch->spheres[MLIF] >= 1)
	 {
	    divide_to_char (ch);
	    centre_text ("The Sphere of Life", ch);
	    divide_to_char (ch);
	    centre_text ("Ho Tien Chi", ch);
	 }
	 if (ch->spheres[MLIF] >= 2)
	    centre_text ("Little Good Death", ch);
	 if (ch->spheres[MLIF] >= 3)
	    centre_text ("Better Body", ch);
	 if (ch->spheres[MLIF] >= 4)
	    centre_text ("Shapechange", ch);
	 if (ch->spheres[MLIF] >= 5)
	    centre_text ("Layhands", ch);
	 divide_to_char (ch);
	 return;
      }

      if (!str_prefix (arg1, "Prime"))
      {
	 if (ch->spheres[MPRI] == 0)
	 {
	    stc ("You have no knowledge of the sphere of Prime.\n\r", ch);
	    return;
	 }

	 if (ch->spheres[MPRI] >= 1)
	 {
	    centre_text ("The Sphere of Prime", ch);
	    divide_to_char (ch);
	    centre_text ("Quintessence", ch);
	 }
	 if (ch->spheres[MPRI] >= 2)
	    centre_text ("Enchant", ch);
	 if (ch->spheres[MPRI] >= 3)
	    centre_text ("Rubbing of the Bones", ch);
	 if (ch->spheres[MPRI] >= 4)
	    centre_text ("Flames of Purification", ch);
	 if (ch->spheres[MPRI] >= 5)
	    centre_text ("Quintessence Blast", ch);
	 divide_to_char (ch);
	 return;
      }

      if (!str_prefix (arg1, "Matter"))
      {
	 if (ch->spheres[MMAT] == 0)
	 {
	    stc ("You have no knowledge of the sphere of Matter.\n\r", ch);
	    return;
	 }

	 if (ch->spheres[MMAT] >= 1)
	 {
	    divide_to_char (ch);
	    centre_text ("The Sphere of Matter", ch);
	    divide_to_char (ch);
	    centre_text ("Analyze Substance", ch);
	 }
	 if (ch->spheres[MMAT] >= 2)
	    centre_text ("Alter State", ch);
	 if (ch->spheres[MMAT] >= 3)
	    centre_text ("Alter Weight", ch);
	 if (ch->spheres[MMAT] >= 4)
	    centre_text ("Enchant Armor", ch);
	 if (ch->spheres[MMAT] >= 5)
	    centre_text ("Hover", ch);
	 divide_to_char (ch);
	 return;
      }

      if (!str_prefix (arg1, "Spirit"))
      {
	 if (ch->spheres[MSPI] == 0)
	 {
	    stc ("You have no knowledge of the Sphere of Spirit.\n\r", ch);
	    return;
	 }

	 if (ch->spheres[MSPI] >= 1)
	 {
	    divide_to_char (ch);
	    centre_text ("The Sphere of Spirit", ch);
	    divide_to_char (ch);
	    centre_text ("Call Spirit", ch);
	 }
	 if (ch->spheres[MSPI] >= 2)
	    centre_text ("Spirit Kiss", ch);
	 if (ch->spheres[MSPI] >= 3)
	    centre_text ("Awaken the Inanimate", ch);
	 if (ch->spheres[MSPI] >= 4)
	    centre_text ("Spirit Blast", ch);
	 if (ch->spheres[MSPI] >= 5)
	    centre_text ("Breach the Gauntlet", ch);
	 divide_to_char (ch);
	 return;
      }

      if (!str_prefix (arg1, "Entropy"))
      {
	 if (ch->spheres[MENT] == 0)
	 {
	    stc ("You have no knowledge of the Sphere of Entropy.\n\r", ch);
	    return;
	 }
	 else
	 {
	    divide_to_char (ch);
	    centre_text ("The Sphere of Entropy", ch);
	    divide_to_char (ch);
	    sprintf (buf,
		     "You have obtained a level %d knowledge of Entropy.",
		     ch->spheres[MENT]);
	    centre_text (buf, ch);
	    sprintf (buf, "This multiplies your damage by %f.",
		     (1 + (ch->spheres[MENT] * .1)));
	    centre_text (buf, ch);
	    sprintf (buf, "This divides your damage taken by 1.5.");
	    centre_text (buf, ch);
	    sprintf (buf, "This increases the level of your spells by %d.",
		     ch->spheres[MENT] * 5);
	    centre_text (buf, ch);
	    divide_to_char (ch);
	    return;
	 }
      }

      if (!str_prefix (arg1, "Correspondence"))
      {
	 if (ch->spheres[MCOR] == 0)
	 {
	    stc ("You have no knowledge of the sphere of Correspondence.\n\r",
		 ch);
	    return;
	 }

	 if (ch->spheres[MCOR] > 0)
	 {
	    centre_text ("The Sphere of Correspondence", ch);
	    divide_to_char (ch);
	    centre_text ("Perception", ch);
	 }

	 if (ch->spheres[MCOR] > 1)
	 {
	    centre_text ("Gateway to the Non-Living", ch);
	 }

	 if (ch->spheres[MCOR] > 2)
	 {
	    centre_text ("Gateway to the Living", ch);
	 }

	 if (ch->spheres[MCOR] > 3)
	 {
	    centre_text ("The Grasp of Elminster", ch);
	    centre_text ("The Eternal Gateway", ch);
	 }

	 if (ch->spheres[MCOR] > 4)
	 {
	    centre_text ("Polyappearance", ch);
	 }
	 divide_to_char (ch);
	 return;
      }

      else if (!str_cmp (arg1, "Mind"))
      {
	 if (ch->spheres[MMIN] == 0)
	 {
	    stc (" You have no knowledge of the Sphere of the Mind.\n\r", ch);
	    return;
	 }

	 if (ch->spheres[MMIN] > 0)
	 {
	    divide_to_char (ch);
	    centre_text ("The Sphere of Mind", ch);
	    divide_to_char (ch);
	    centre_text ("Shield", ch);
	 }

	 if (ch->spheres[MMIN] > 1)
	 {
	    centre_text ("Subliminal Impulse", ch);
	 }

	 if (ch->spheres[MMIN] > 2)
	    centre_text ("Probe Thoughts", ch);

	 if (ch->spheres[MMIN] > 3)
	    centre_text ("Possession", ch);

	 if (ch->spheres[MMIN] > 4)
	    centre_text ("Untether", ch);
	 divide_to_char (ch);
	 return;
      }

      else if (!str_prefix (arg1, "Forces"))
      {
	 if (ch->spheres[MFOR] == 0)
	 {
	    stc ("You have no knowledge of the Sphere of Forces.\n\r", ch);
	    return;
	 }

	 if (ch->spheres[MFOR] > 0)
	 {
	    centre_text ("The Sphere of Forces", ch);
	    line (ch);
	    centre_text ("Discharge Static", ch);
	 }
	 if (ch->spheres[MFOR] > 1)
	 {
	    centre_text ("Telekinesis", ch);
	 }
	 if (ch->spheres[MFOR] > 2)
	 {
	    centre_text ("Call Lightning", ch);
	    centre_text ("Control Weather", ch);
	 }
	 if (ch->spheres[MFOR] > 3)
	 {
	    centre_text ("Embracing the Earth Mother", ch);
	 }
	 if (ch->spheres[MFOR] > 4)
	 {
	    centre_text ("Tempest Shards", ch);
	    line (ch);
	 }
	 return;
      }

      else if (!str_cmp (arg1, "Time"))
      {
	 if (ch->spheres[MTIM] == 0)
	 {
	    stc ("You have no knowledge of the Sphere of Time.\n\r", ch);
	    return;
	 }
	 else
	 {
	    sprintf (buf, "You have a level %d knowledge of Time.\n\r",
		     ch->spheres[MTIM]);
	    stc (buf, ch);
	    return;
	 }
	 return;
      }

   }

   if (!str_cmp (arg2, "learn"))
   {
      if (!str_prefix (arg1, "correspondence"))
	 disc = MCOR;
      else if (!str_prefix (arg1, "life"))
	 disc = MLIF;
      else if (!str_prefix (arg1, "prime"))
	 disc = MPRI;
      else if (!str_prefix (arg1, "entropy"))
	 disc = MENT;
      else if (!str_prefix (arg1, "mind"))
	 disc = MMIN;
      else if (!str_prefix (arg1, "spirit"))
	 disc = MSPI;
      else if (!str_prefix (arg1, "forces"))
	 disc = MFOR;
      else if (!str_prefix (arg1, "matter"))
	 disc = MMAT;
      else if (!str_prefix (arg1, "time"))
	 disc = MTIM;
      else
      {
	 stc ("You must select from the following spheres:\n\r  Correspondence, Life, Prime, Entropy, Mind, Spirit, Forces, Matter, Time.\n\r", ch);
	 return;
      }
   }
   else
   {
      do_spheres (ch, "");
      return;
   }

   cost = ((ch->spheres[disc] + 1) * 10);

   if (ch->spheres[disc] >= 5)
   {
      sprintf (buf,
	       "You have already learned all levels of the %s sphere.\n\r",
	       sphere_name[disc]);
      stc (buf, ch);
      return;
   }

   if (ch->practice < cost)
   {
      sprintf (buf,
	       "You need %d primal to obtain a new level of understanding of the %s sphere.\n\r",
	       cost, sphere_name[disc]);
      stc (buf, ch);
      return;
   }

   ch->practice -= cost;
   ch->spheres[disc]++;
   sprintf (buf, "Your knowledge of the %s sphere increases.\n\r",
	    sphere_name[disc]);
   stc (buf, ch);
   return;

}

void do_drainmove (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;

   if (!IS_CLASS (ch, CLASS_MAGE))
   {
      send_to_char ("Huh?\n\r", ch);
      return;
   }
   if (ch->spheres[MLIF] < 5)
   {
      send_to_char ("You need the 5th sphere of Life for this.\n\r", ch);
      return;
   }
   if (ch->in_room->vnum == 29502)
   {
      stc ("NOT IN THIS ROOM SORRY!!\n\r", ch);
      return;
   }
   if ((victim = get_char_room (ch, argument)) == NULL)
   {
      send_to_char ("You were unable to find them.\n\r", ch);
      return;
   }
   else
   {
      ch->mana += (victim->move * 0.2);
      victim->move -= (victim->move * 0.2);

      if (ch->mana > ch->max_mana)
	 ch->mana = ch->max_mana;
      if (victim->move < 0)
	 victim->move = 0;
      send_to_char ("Your feet seem to become heavier...\n\r", victim);
      send_to_char ("You drain them and convert their power to mana.\n\r",
		    ch);
      WAIT_STATE (ch, 8);
      return;
   }
   return;
}

void do_perception (CHAR_DATA * ch, char *argument)
{
   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MCOR] < 1)
   {
      stc ("You must obtain level one Correspondence to enable your higher Perception.\n\r", ch);
      return;
   }

   if (IS_SET (ch->mflags, MAGE_PERCEPTION))
   {
      stc ("Your higher perception fades.\n\r", ch);
      REMOVE_BIT (ch->affected_by, AFF_SHADOWSIGHT);
      REMOVE_BIT (ch->act, PLR_HOLYLIGHT);
      REMOVE_BIT (ch->pcdata->stats[UNI_AFF], VAM_NIGHTSIGHT);
      REMOVE_BIT (ch->mflags, MAGE_PERCEPTION);
      return;
   }

   else
   {
      stc ("Your perception soars to new levels.\n\r", ch);
      SET_BIT (ch->affected_by, AFF_SHADOWSIGHT);
      SET_BIT (ch->act, PLR_HOLYLIGHT);
      SET_BIT (ch->pcdata->stats[UNI_AFF], VAM_NIGHTSIGHT);
      SET_BIT (ch->mflags, MAGE_PERCEPTION);
      return;
   }

   return;
}

void do_objectgate (CHAR_DATA * ch, char *argument)
{
   OBJ_DATA *obj;
   char arg1[MAX_INPUT_LENGTH];
   char arg2[MAX_INPUT_LENGTH];
   bool perm = FALSE;

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

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->fight_timer > 0)
   {
      stc ("Not with a fight timer\n\r", ch);
      return;
   }
   if (ch->spheres[MCOR] < 2)
   {
      stc ("You must obtain level two Correspondence to Open a Spacial Gate.\n\r", ch);
      return;
   }

   if (ch->spheres[MLIF] < 2 || ch->spheres[MMAT] < 2)
   {
      stc ("This sphere must be used in conjunction with either Life 2 or Matter 2, which you have not obtained.\n\r", ch);
      return;
   }

   if (arg1[0] == '\0')
   {
      stc ("What object do you want to attempt to gate to?\n\r", ch);
      return;
   }

   if ((obj = get_obj_world (ch, arg1)) == NULL)
   {
      stc ("You concentrate deeply on foreign planes, but can find no such object.\n\r", ch);
      return;
   }
   if (obj->in_room == NULL)
   {
      stc ("You cannot seem to locate the space that object is in.\n\r", ch);
      return;
   }
   if (!CAN_WEAR (obj, ITEM_TAKE) && !str_cmp (arg2, "grab"))
   {
      send_to_char ("You cant quite get your hands around it\n\r", ch);
      return;
   }

   if (obj->item_type == ITEM_PIECE)
   {
      stc ("That piece is too small to grab.\n\r", ch);
      return;
   }
   if (!str_cmp (arg2, "grab") && obj->in_obj == 0)
   {
      if (IS_SET (obj->quest, QUEST_ARTIFACT)
	  || IS_SET (obj->quest, ITEM_EQUEST)
	  || IS_SET (obj->quest, QUEST_RELIC) || obj->item_type == ITEM_QUEST
	  || obj->item_type == ITEM_WGATE || IS_SET (obj->quest, QUEST_NOGATE)
	  || obj->item_type == ITEM_STOKEN || obj->item_type == ITEM_WALL || obj->item_type == ITEM_AQUEST)
      {
	 act ("You reach through a rift in space and try to pull $p through, but a mystical force rips it from your hands.", ch, obj, NULL, TO_CHAR);
	 return;
      }

      if (obj->carried_by != NULL)
      {
	 act ("You reach through a rift in space and try to pull $p through, but someone snatches it away from you.", ch, obj, NULL, TO_CHAR);
	 return;
      }

   }
   else
   {
      if (IS_SET (obj->quest, QUEST_ARTIFACT)
	  || IS_SET (obj->quest, ITEM_EQUEST)
	  || IS_SET (obj->quest, QUEST_RELIC) || obj->item_type == ITEM_QUEST
	  || obj->item_type == ITEM_WALL || obj->item_type == ITEM_WGATE
	  || IS_SET (obj->quest, QUEST_NOGATE)
	  || obj->item_type == ITEM_STOKEN || obj->item_type == ITEM_AQUEST)
      {
	 act ("You attempt to create a rift in space to $p, but it is unlocatable.", ch, obj, NULL, TO_CHAR);
	 return;
      }

      if (obj->in_obj > 0)
      {
	 act ("You attempt to create a rift in space to $p, but it is just beyond your reach.", ch, obj, NULL, TO_CHAR);
	 return;
      }

      if (obj->carried_by != NULL)
      {
	 act ("You attempt to create a rift in space to $p, but it seems to be possessed by another.", ch, obj, NULL, TO_CHAR);
	 return;
      }

      if (IS_SET (obj->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("You failed.\n\r", ch);
	 return;
      }
      if (IS_SET (obj->in_room->area->aflags, AFLAG_ARENA))
      {
	 stc ("You failed.\n\r", ch);
	 return;
      }
      if (IS_SET (obj->in_room->room_flags, ROOM_CCHAMBER))
      {
	 stc ("You failed.\n\r", ch);
	 return;
      }
      if IS_SET
	 (obj->in_room->room_flags, ROOM_GOD)
      {
	 stc ("YOu failed!\n\r", ch);
	 return;
      }

   }

   if (!obj->in_room)
   {
      stc ("Nope\n\r", ch);
      return;
   }

   if (!str_cmp (arg2, "permanent"))
   {
      if (ch->practice < 5)
      {
	 stc ("You require five units of Primal energy to support a permanent rift.\n\r", ch);
	 return;
      }

      if (IS_SET (ch->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("You cannot make a permanent rift while in an HQ\n\r", ch);
	 return;
      }

      perm = TRUE;
      ch->practice -= 5;
   }

   creategate (ch, ch->in_room->vnum, obj->in_room->vnum, perm);

   if (!str_cmp (arg2, "grab"))
   {
      obj_from_room (obj);
      obj_to_char (obj, ch);
      act ("You reach through a rift in space and pull $p through the tear.",
	   ch, obj, NULL, TO_CHAR);
      act ("$n's hand plunges through a small tear in space and reappears holding $p.", ch, obj, NULL, TO_ROOM);
   }
   else
   {
      act ("You create a rent in the Tapestry to $p.", ch, obj, NULL,
	   TO_CHAR);
      act ("$n creates a small rent in reality.", ch, obj, NULL, TO_ROOM);
   }

   return;
}

void do_mgate (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg1[MAX_INPUT_LENGTH];
   char arg2[MAX_INPUT_LENGTH];
   bool pull = FALSE;
   bool perm = FALSE;

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

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->fight_timer > 0)
   {
      stc ("Not with a fight timer\n\r", ch);
      return;
   }
   if (ch->spheres[MCOR] < 3)
   {
      stc ("You must obtain a level three mastery of Correspondence to use Astral Gateways.\n\r", ch);
      return;
   }
   if (IS_SET (ch->in_room->room_flags, ROOM_GOD))
   {
      stc ("You failed\n\r", ch);
      return;
   }

/*
  if ( check_quint(ch) < 2 )
  {
    stc("You need two points of quintessence available to use this power.\n\r",ch);
    return;
  }
*/
   if (ch->mana < 500)
   {
      stc ("You need 500 mana spare to use this power.\n\r", ch);
      return;
   }

   if (arg1[0] == '\0')
   {
      stc ("Whom do you wish to open an Astral Gate to?\n\r", ch);
      return;
   }

   if ((victim = get_char_world (ch, arg1)) == NULL)
   {
      stc ("You scry the foreign planes, but can find no such entity.\n\r",
	   ch);
      return;
   }

   if (victim == ch)
   {
      stc ("You failed.\n\r", ch);
      return;
   }
   if (IS_SET (victim->in_room->room_flags, ROOM_GOD))
   {
      stc ("You failed\n\r", ch);
      return;
   }
   if (IS_NPC (victim) && IS_SET (victim->in_room->area->aflags, AFLAG_HQ))
   {
      stc ("You failed.\n\r", ch);
      return;
   }
   if (IS_SET (victim->in_room->room_flags, ROOM_CCHAMBER))
   {
      stc ("You failed.\n\r", ch);
      return;
   }
   if (victim->in_room->vnum == 3054)
   {
	stc("Your target is at the temple altar!\n\r", ch);
	return;
   }
   if (!str_cmp (arg2, "pull"))
   {
      if (ch->spheres[MCOR] < 4)
      {
	 stc ("You must obtain a level four mastery of Correspondence to pull another being through the Tapestry.\n\r", ch);
	 return;
      }

      if (victim->level > 100)
      {
	 stc ("Your victim is far too large to be pulled through the rent.\n\r", ch);
	 return;
      }

      else
	 pull = TRUE;
   }

   if (!str_cmp (arg2, "permanent"))
   {
      if (ch->practice < 5)
      {
	 stc ("You require Five units of Primal Energy to create an Eternal Gateway.\n\r", ch);
	 return;
      }
      if (IS_SET (ch->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("You cannot make a permanent rift while in an HQ\n\r", ch);
	 return;
      }

      if (IS_SET (victim->in_room->area->aflags, AFLAG_HQ))
      {
	 stc ("You cannot make a permanent rifts to people who are in their HQ\n\r", ch);
	 return;
      }

      perm = TRUE;
      ch->practice -= 5;
   }

   if (!IS_NPC (victim) && !IS_IMMUNE (victim, IMM_SUMMON))
   {
      act ("You attempt to open an astral gate to $N, but the rift quickly closes.", ch, NULL, victim, TO_CHAR);
      act ("$n creates a magical rift before you, which quickly disappears.",
	   ch, NULL, victim, TO_VICT);
      act ("$n attempts to open an astral gate, but fails.", ch, NULL, victim,
	   TO_ROOM);
      return;
   }

   if (IS_NPC (victim) && victim->level > 150)
   {
      act ("You attempt to open an astral gate to $N, but fail.", ch, NULL,
	   victim, TO_CHAR);
      act ("$n attempts to open an astral gate, but fails.", ch, NULL, victim,
	   TO_ROOM);
      return;
   }

   creategate (ch, ch->in_room->vnum, victim->in_room->vnum, perm);

   if (!pull)
   {
      act ("You create a small rent in the Tapestry to $N.", ch, NULL, victim,
	   TO_CHAR);
      act ("A small tear in reality pops into existance in front of you.", ch,
	   NULL, victim, TO_VICT);
      act ("$n creates a small tear in reality.", ch, NULL, victim, TO_ROOM);
      do_enter (ch, "gate");
   }

   if (pull)
   {
      act ("You create a small rent in the Tapestry and pull $N through it.",
	   ch, NULL, victim, TO_CHAR);
      act ("A small tear in reality pops into existance before you.\n\r  You are violently ripped through the tear!", ch, NULL, victim, TO_VICT);
      if (IS_SET (victim->flag2, AFF2_INARENA))
      {
	 stc ("Your victim is in the arena.  You are unable to pull them through.\n\r", ch);
	 return;
      }

      if (is_inarena (ch))
	 return;

      char_from_room (victim);
      char_to_room (victim, ch->in_room);
      do_look (victim, "");
      act ("$n creates a small tear in reality.\n\rSeconds later, $N pops out of the rent, looking confused.", ch, NULL, victim, TO_NOTVICT);
   }
   ch->mana -= 500;
   return;
}

void do_polyappear (CHAR_DATA * ch, char *argument)
{
   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MCOR] < 5)
   {
      stc ("You must become a master of the sphere of Correspondence to use Polyappearance.\n\r", ch);
      return;
   }

   if (IS_SET (ch->mflags, MAGE_POLYAPPEAR))
   {
      stc ("Your body phases and reforms as one being.\n\r", ch);
      act ("$n's many forms phase and reform as one being.", ch, NULL, NULL,
	   TO_ROOM);
      REMOVE_BIT (ch->mflags, MAGE_POLYAPPEAR);
      return;
   }

   else
   {
      stc ("Your body phases and splits into multiple figures.\n\r", ch);
      act ("$n's body phases and splits into multiple figures.", ch, NULL,
	   NULL, TO_ROOM);
      SET_BIT (ch->mflags, MAGE_POLYAPPEAR);
      return;
   }

   return;
}

void do_discharge (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   CHAR_DATA *vch = NULL;
   CHAR_DATA *vch_next = NULL;
   char arg1[MAX_INPUT_LENGTH];
   int min;
   int max;
   int damage;
   int number_hit = 0;

   argument = one_argument (argument, arg1);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;


   if (arg1[0] == '\0')
   {
      stc ("Who do you wish to strike down?\n\r", ch);
      return;
   }

   if (ch->spheres[MFOR] < 1)
   {
      stc ("You must have a level one knowledge of the Forces to discharge Static Electricity.\n\r", ch);
      return;
   }

   if (ch->mana < 5000)
   {
      stc ("You dont have enough Mana to use discharge\n\r", ch);
      return;
   }

   if (str_cmp (arg1, "all"))
   {
      if ((victim = get_char_room (ch, arg1)) == NULL)
      {
	 stc ("You were unable to locate your victim.\n\r", ch);
	 return;
      }

      if (victim->level < 3)
      {
	 stc ("They must be an avatar!\n\r", ch);
	 return;
      }
      if (is_safe (ch, victim))
	 return;
      // if (number_hit > 20) return;
      min =
	 ((ch->spl[0] + ch->spl[1] + ch->spl[2] + ch->spl[3] +
	   ch->spl[4]) * 2 * ch->spheres[MFOR] * 10);
      max =
	 ((ch->spl[0] + ch->spl[1] + ch->spl[2] + ch->spl[3] +
	   ch->spl[4]) * 2 * ch->spheres[MFOR] * 30);
      damage = number_range (min, max);
      damage *= number_range (1, ch->spheres[MFOR] * 2);
      if (weather_info.sky == SKY_LIGHTNING)
	 damage += number_range (1000, 1300);
      if (weather_info.sky == SKY_RAINING)
	 damage -= number_range (30, 35);
      number_hit++;

      if (IS_NPC (victim))
      {
	 mage_damage (ch, victim, damage, "electricity burst",
		      MAGEDAM_ELECTRIC);
      }
      else
      {
	 if (!IS_NPC (victim)
	     && IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
	 {
	    if (victim->quickening[0] >= 10)
	    {
	       victim->quickening[0] -= 10;
	       stc ("Sparkles of energy partially disrupt the electricity before it lands.\n\r", ch);
	       stc ("Sparkles of energy partially disrupt an electrical discharge.\n\r", victim);
	       ch->fight_timer = 10;
	       victim->fight_timer = 10;
	       damage *= 0.75;
	    }
	 }

	 damage *= 0.8;
	 mage_damage (ch, victim, damage, "electricity burst",
		      MAGEDAM_ELECTRIC);
      }
   }
   else
   {
      min =
	 ((ch->spl[0] + ch->spl[1] + ch->spl[2] + ch->spl[3] +
	   ch->spl[4]) * 2 * ch->spheres[MFOR] * 10);
      max =
	 ((ch->spl[0] + ch->spl[1] + ch->spl[2] + ch->spl[3] +
	   ch->spl[4]) * 2 * ch->spheres[MFOR] * 30);
      damage = number_range (min, max);
      damage *= number_range (1, ch->spheres[MFOR]);
      damage /= 3;
      if (weather_info.sky == SKY_LIGHTNING)
	 damage += number_range (1000, 1300);
      if (weather_info.sky == SKY_RAINING)
	 damage -= number_range (30, 35);
      WAIT_STATE (ch, 12);
      for (vch = ch->in_room->people; vch != NULL; vch = vch_next)
      {
	 vch_next = vch->next_in_room;
	 if (vch->level < 3)
	    continue;
	 if (is_safe (ch, vch))
	    continue;
	 if (is_same_group (ch, vch))
	    continue;
	 if (!can_see (ch, vch))
	    continue;
	 if (vch != ch)
	 {
	    if (IS_CLASS (vch, CLASS_HIGHLANDER)
		&& (IS_DEMPOWER (vch, HPOWER_USE_PRESERVATION)))
	    {
	       if (vch->quickening[0] >= 7)
	       {
		  vch->quickening[0] -= 7;
		  stc ("Sparkles of energy partially disrupt the area wide electrical arc before it lands.\n\r", ch);
		  stc ("Sparkles of energy partially disrupt an area wide electrical discharge.\n\r", vch);
		  ch->fight_timer = 10;
		  vch->fight_timer = 10;
		  damage *= 0.75;
	       }
	    }
	    mage_damage (ch, vch, damage, "electricity burst",
			 MAGEDAM_ELECTRIC);
	 }
      }
   }

   ch->mana = ch->mana - 5000;
   WAIT_STATE (ch, 12);

   return;

}

void do_telekinetics (CHAR_DATA * ch, char *argument)
{
   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MFOR] < 2)
   {
      stc ("You must obtain a level two knowledge of Forces to use Telekinesis.\n\r", ch);
      return;
   }

   if (IS_SET (ch->mflags, MAGE_TELEKINETICS))
   {
      stc ("You relax your mental energies.\n\r", ch);
      REMOVE_BIT (ch->mflags, MAGE_TELEKINETICS);
      return;
   }

   else
   {
      stc ("You focus your mental energies into your attacks.\n\r", ch);
      SET_BIT (ch->mflags, MAGE_TELEKINETICS);
      return;
   }

   return;
}

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

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MFOR] < 3)
   {
      stc ("You must obtain a level three knowledge of Forces to Call Lightning.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Whom do you wish to Call Lightning upon?\n\r", ch);
      return;
   }

   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      stc ("You were unable to locate your victim.\n\r", ch);
      return;
   }

   if (victim->level < 3)
   {
      stc ("They must be an avatar!\n\r", ch);
      return;
   }

   if (weather_info.sky != SKY_LIGHTNING)
   {
      stc ("There is no lightning in the sky to call!\n\r", ch);
      return;
   }

   WAIT_STATE (ch, 16);
   dam = number_range ((ch->spheres[MFOR] * 450), (ch->spheres[MFOR] * 600));
   if (!IS_NPC (ch))
      dam -= number_range (100, 150);

   mage_damage (ch, victim, dam, "lightning blast", MAGEDAM_ELECTRIC);
   return;
}

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

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))

      if (ch->spheres[MFOR] < 3)
      {
	 stc ("You need a level three knowledge of Forces to Control the Weather.\n\r", ch);
	 return;
      }

   if (arg[0] == '\0')
   {
      stc ("How do you want to change the weather?\n     Syntax: controlweather <rain,lightning,clear>\n\r", ch);
      return;
   }

   WAIT_STATE (ch, 16);
   if (!str_cmp (arg, "rain"))
   {
      stc ("You wave your hands over your head.\n\r", ch);
      stc ("The skies blacken and rain begins to fall.\n\r", ch);
      weather_info.sky = SKY_RAINING;
   }
   else if (!str_cmp (arg, "lightning"))
   {
      stc ("You wave your hands over your head.\n\r", ch);
      stc ("The skies blacken.\n\r", ch);
      stc ("Lightning streaks across the sky.\n\r", ch);
      weather_info.sky = SKY_LIGHTNING;
   }
   else if (!str_cmp (arg, "clear"))
   {
      stc ("You wave your hands over your head.\n\r", ch);
      stc ("The skies slowly clear up.\n\r", ch);
      weather_info.sky = SKY_CLOUDLESS;
   }
   else
   {
      stc ("Invalid option.\n   Syntax: controlweather <rain,lightning,clear>\n\r", ch);
      return;
   }

   return;
}

void do_earthembrace (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_mage (ch))
      return;

   if (ch->spheres[MFOR] < 4)
   {
      stc ("You must obtain a level four knowledge of the Forces to use Embrace of the Earth Mother.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Whom do you wish to have Gaia Embrace?\n\r", ch);
      return;
   }
   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      stc ("You were unable to locate your victim.\n\r", ch);
      return;
   }
   if (is_safe (ch, victim))
      return;
   if (ch->in_room->vnum == ROOM_VNUM_ALTAR)
   {
      stc ("The Earth cannot penetrate the aura surrounding this room!\n\r",
	   ch);
      return;
   }
   if (victim->level < 3)
   {
      stc ("They must be an avatar!\n\r", ch);
      return;
   }

   act ("You call upon the forces of the Earth to embrace $N!", ch, NULL,
	victim, TO_CHAR);
   act ("$n begins to chant mysteriously.", ch, NULL, victim, TO_ROOM);
   act ("The ground shakes and rises to embrace $N!", ch, NULL, victim,
	TO_NOTVICT);
   act ("The ground under your feet starts to surround your body.", ch, NULL,
	victim, TO_VICT);
   SET_BIT (victim->mflags, MAGE_EMBRACED2);
   WAIT_STATE (ch, 16);
   return;
}

void do_tempest (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;

   char arg[MAX_INPUT_LENGTH];
   int dam;
  int  qcost = number_range( 1, 4 );
  char buf[MAX_STRING_LENGTH];
  
   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   qcost = qcost *2;

   if (ch->spheres[MFOR] < 5)
   {
      stc ("You must master the Forces to use Tempest Blizzard.\n\r", ch);
      return;
   }

   if (check_quint (ch) < qcost)
   {
      stc ("You need four points of quintessence available to use Tempest Shards.\n\r", ch);
      return;
   }

   if (ch->mana < 500)
   {
      stc ("You need 500 mana to use this power.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Who do you wish to summon an Ice Storm upon?\n\r", ch);
      return;
   }

   if ((victim = get_char_area (ch, arg)) == NULL)
   {
      stc ("You scry the planes, but cannot find your victim.\n\r", ch);
      return;
   }

   if (victim->level < 3)
   {
      stc ("They must be an avatar!\n\r", ch);
      return;
   }

   if (ch == victim)
   {
	stc("Sado-masochist tendencies eh?\n\r", ch);
        return;
   }
   if (is_safe (ch, victim))
   {
      return;
   }

   if (IS_SET (victim->in_room->area->aflags, AFLAG_HQ))
   {
      stc ("You are unable to focus your tempest shards!\n\r", ch);
      return;
   }
   dam =
      ((number_range (200, 350) + ch->spl[BLUE_MAGIC]) * ch->spheres[MFOR]);

   if (victim->in_room->area != ch->in_room->area)
   {
      if (ch->practice < 10)
      {
	 stc ("You locate your victim, but they are too distant.\n\r", ch);
	 return;
      }
      else if (check_quint (ch) < qcost + 1)
      {
	 stc ("You need five points of quintessence available to use Tempest Shards across the gap.\n\r", ch);
	 return;
      }
      else
      {
	 stc ("You locate your victim, and spend quintessence and primal energy to bridge the gap.\n\r", ch);
	 ch->practice -= 10;
	 subtract_quint (ch, 1);
	 dam /= 2;
      }
   }

  ch->mana -= 1000;
  subtract_quint (ch, qcost );
  WAIT_STATE (ch, (skill_table[gsn_shards].beats - qcost));

  sprintf( buf, "#wYou channel #r%d #wpoints of quintessence into your mind.#n\n\r", qcost );
  send_to_char( buf, ch );
   act ("You call upon the Forces of Nature to obliterate $N.", ch, NULL, victim, TO_CHAR);
   act ("The sky turns an ominous white.\n\r...Seconds later, deadly shards of ice shoot out of the sky, piercing your skin.", ch, NULL, victim, TO_VICT);

   mage_damage (ch, victim, dam, "ice shards", MAGEDAM_ICESTORM);

   if (victim != NULL)
   {
      set_fighting (ch, victim);
      if (victim->in_room != ch->in_room)
      {
         stop_fighting (ch, TRUE);
	 stop_fighting (victim, TRUE);
      }
   }
/*
	if ( victim->in_room != ch->in_room )
	{
         if (victim->fighting != NULL)
         {
            stop_fighting (victim, TRUE);
            stop_fighting (ch, TRUE);
         }
		if ( ( victim->fighting ) && ( victim->fighting == ch ) )
			victim->fighting = NULL;
		if ( ( ch->fighting ) &&( ch->fighting == victim ) )
			ch->fighting = NULL;
		if ( ( victim->fighting ) )
			victim->fighting = NULL;
		if ( ( ch->fighting ) )
			ch->fighting = NULL;
	}

	for (vch = char_list; vch != NULL; vch = vch_next)
	{
		vch_next = vch->next;

		if (vch->level < 3)
			continue;

		if (vch->in_room == NULL)
			continue;

		if ( vch->in_room->area != victim->in_room->area )
			continue;
		act ("Shards of deadly ice chill the area.\n\r", ch, NULL, vch, TO_VICT);
	}
*/
//  WAIT_STATE( victim, 16 + qcost );

  return;
}

bool is_immune (CHAR_DATA * ch, int type)
{
   if (IS_SET (ch->imms[IMMUNITY], type))
      return TRUE;
   else
      return FALSE;
}

bool is_resistant (CHAR_DATA * ch, int type)
{
   if (IS_SET (ch->imms[RESISTANCE], type))
      return TRUE;
   else
      return FALSE;
}

bool is_vulnerable (CHAR_DATA * ch, int type)
{
   if (IS_SET (ch->imms[VULNERABLE], type))
      return TRUE;
   else
      return FALSE;
}

int mage_immunity (CHAR_DATA * ch, int dam, const char *msg, int type)
{
   if (IS_NPC (ch))
      return dam;

   if (is_immune (ch, type))
      dam = 0;

   else if (is_resistant (ch, type))
      dam *= 0.85;

   else if (is_vulnerable (ch, type))
      dam *= 4;

   return dam;
}

void mage_damage (CHAR_DATA * ch, CHAR_DATA * victim, int dam,
		  const char *message, int type)
{
   int max_dam = ch->damcap[DAM_CAP];

   if (victim->position == POS_DEAD)
      return;

   if (ch->damcap[DAM_CHANGE] == 1)
      update_damcap (ch, victim);

   if (dam > max_dam)
      dam = max_dam;

   if (victim != ch)
   {
      /*
       * Certain attacks are forbidden.
       * Most other attacks are returned.
       */
      if (is_safe (ch, victim))
	 return;
      check_killer (ch, victim);

      if (victim->position > POS_STUNNED && ch->in_room == victim->in_room)
      {
	 if (victim->fighting == NULL)
	    set_fighting (victim, ch);
	 victim->position = POS_FIGHTING;
      }

      if (victim->position > POS_STUNNED)
      {
         if (ch->fighting == NULL && ch->in_room == victim->in_room)
	    set_fighting (ch, victim);
	 /*
	  * If victim is charmed, ch might attack victim's master.
	  */
	 if (IS_NPC (ch) && IS_NPC (victim) && IS_AFFECTED (victim, AFF_CHARM)
	     && victim->master != NULL
	     && victim->master->in_room == ch->in_room
	     && number_bits (3) == 0)
	 {
	    stop_fighting (ch, FALSE);
	    multi_hit (ch, victim->master, TYPE_UNDEFINED);
	    return;
	 }
      }

      /*
       * More charm stuff.
       */
      if (victim->master == ch)
	 stop_follower (victim);

      /*
       * Damage modifiers.
       */
      if (IS_AFFECTED (ch, AFF_HIDE))
      {
	 if (!can_see (victim, ch))
	 {
	    dam *= 2;
	    send_to_char
	       ("You use your concealment to place a devastating attack to a vital location!\n\r",
		ch);
	 }
	    REMOVE_BIT (ch->affected_by, AFF_HIDE);
	 act ("$n places a devasating blow to $N's body.", ch, NULL, victim,
	      TO_ROOM);
      }


      if (IS_AFFECTED (victim, AFF_SANCTUARY) && dam > 1)
	dam *= 0.5;
      else
        dam *= 1.5;

      if (IS_AFFECTED (victim, AFF_PROTECT) && IS_EVIL (ch) && dam > 1)
	 dam -= dam * 0.25;

      if (type == MAGEDAM_FIRE && WORN_ARTIFACT (victim, ARTI_DEMONS_HEART))
         dam = 0;

      if (dam < 0)
	 dam = 0;

      // I'll eventually add resistances, immunities, vulnerabilities, etc
      // Right about here. Amen.


      mage_message (ch, victim, dam, message, type);
      hurt_person (ch, victim, dam);
      return;
   }

   else
      return;
}

void mage_message (CHAR_DATA * ch, CHAR_DATA * victim, int dam,
		   const char *message, int type)
{
   char buf1[MAX_STRING_LENGTH];
   char buf2[MAX_STRING_LENGTH];
   char buf3[MAX_STRING_LENGTH];
   char damm[MAX_STRING_LENGTH];
   char dam2[MAX_STRING_LENGTH];
   const char *chm;
   const char *victm;

   if (dam == 0)
   {
      chm = " miss";
      victm = " misses";
   }
   else if (dam <= 50)
   {
      chm = " graze";
      victm = " grazes";
   }
   else if (dam <= 100)
   {
      chm = " wound";
      victm = " wounds";
   }
   else if (dam <= 200)
   {
      chm = " mutilate";
      victm = " mutilates";
   }
   else if (dam <= 300)
   {
      chm = " massacre";
      victm = " massacres";
   }
   else if (dam <= 400)
   {
      chm = " eviscerate";
      victm = " eviscerates";
   }
   else if (dam <= 500)
   {
      chm = " annihilate";
      victm = " annihilates";
   }
   else if (dam <= 600)
   {
      chm = " obliterate";
      victm = " obliterates";
   }
   else if (dam <= 800)
   {
      chm = " dissipate";
      victm = " dissipates";
   }
   else if (dam <= 1000)
   {
      chm = " vaporize";
      victm = " vaporizes";
   }
   else
   {
      chm = " liquify";
      victm = " liquifies";
   }

   if (!IS_NPC (victim) && (victim->hit - dam) < 0)
   {
      if (type == MAGEDAM_ELECTRIC)
      {
	 act ("Your electric shock causes $N to spasm violently and vomit blood.", ch, NULL, victim, TO_CHAR);
	 act ("$n's electric shock causes $N to spasm violently and vomit blood.", ch, NULL, victim, TO_NOTVICT);
	 act ("$n's electric shock causes your body to spasm violently as you vomit blood.", ch, NULL, victim, TO_VICT);
	 make_part (victim, "blood");
      }

      else if (type == MAGEDAM_ICESTORM)
      {
	 act ("Your ice shards tear $N's flesh from $S body and leave $M mortally wounded.", ch, NULL, victim, TO_CHAR);
	 act ("$n's ice shards tear $N's flesh from $S body and leave $M mortally wounded.", ch, NULL, victim, TO_NOTVICT);
	 act ("$n's ice shards tear your flesh from your body and leave you mortally wounded.", ch, NULL, victim, TO_VICT);
	 make_part (victim, "blood");
      }

      else
      {
	 act ("Your magical energy tears $N's body asunder.", ch, NULL,
	      victim, TO_CHAR);
	 act ("$n's magical energies tear $N's body asunder.", ch, NULL,
	      victim, TO_NOTVICT);
	 act ("$n's magical energies tear your body asunder.", ch, NULL,
	      victim, TO_VICT);
	 make_part (victim, "blood");
      }
   }

   if (dam == 0 && is_immune (ch, type))
   {
      sprintf (buf1, "$N is unaffected by your %s.", message);
      sprintf (buf2, "$N is unaffected by $n's %s.", message);
      sprintf (buf3, "You are unaffected by $n's %s.", message);
   }

   if (dam == 0 && !is_immune (ch, type))
   {
      sprintf (buf1, "You miss $N with your %s.", message);
      sprintf (buf2, "$n misses $N with $s %s.", message);
      sprintf (buf3, "$n misses you with $s %s.", message);
   }

   else
   {
	 sprintf (damm, "%d", dam);
	 ADD_COLOUR (ch, damm, L_RED);
	 sprintf (dam2, ". [%s]", damm);

      sprintf (buf1, "You%s $N with your %s%s", chm, message, dam2);
      sprintf (buf2, "$n%s $N with $s %s.", victm, message);
      sprintf (buf3, "$n%s you with $s %s%s", victm, message, dam2);
   }

   act (buf1, ch, NULL, victim, TO_CHAR);
   act (buf2, ch, NULL, victim, TO_NOTVICT);
   act (buf3, ch, NULL, victim, TO_VICT);

   return;

}

void do_quintessence (CHAR_DATA * ch, char *argument)
{
   char buf[MAX_STRING_LENGTH];

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MPRI] < 1)
   {
      stc ("You cannot store Quintessence until you have learned level 1 Prime.\n\r", ch);
      return;
   }

   line2 (ch);
   centre_text ("Quintessence", ch);
   line2 (ch);
   sprintf (buf,
	    "*   You have %d points of Quintessence stored within your body.               *\n\r",
	    ch->quint[BODY]);
   stc (buf, ch);
   sprintf (buf,
	    "*   You have %d points of Quintessence stored within your Avatar.             *\n\r",
	    ch->quint[AVATAR]);
   stc (buf, ch);
   line2 (ch);
   return;
}

int check_quint (CHAR_DATA * ch)
{
   if (ch->spheres[MPRI] < 3)
      return ch->quint[AVATAR];
   else if (ch->spheres[MPRI] >= 3)
      return (ch->quint[AVATAR] + ch->quint[BODY]);
   else
      return ch->quint[AVATAR];
}

void subtract_quint (CHAR_DATA * ch, int number)
{
   ch->quint[MTOTAL] = check_quint (ch);	// Find Total Quint of Char
   ch->quint[MTOTAL] -= number;	// Subtract from Max
   if (ch->quint[MTOTAL] > 5)
   {
      ch->quint[AVATAR] = 5;
      ch->quint[MTOTAL] -= 5;
      if (ch->quint[MTOTAL] > 5)
      {
	 ch->quint[BODY] = 5;
	 ch->quint[MTOTAL] = 0;
      }
      else
      {
	 ch->quint[BODY] = ch->quint[MTOTAL];
	 ch->quint[MTOTAL] = 0;
      }
   }
   else
   {
      ch->quint[AVATAR] = ch->quint[MTOTAL];	// Move all quint to Avatar
      ch->quint[BODY] = 0;	// Drain the body
   }
   return;
}

void add_quint (CHAR_DATA * ch, int number)
{
   ch->quint[MTOTAL] = check_quint (ch);
   ch->quint[MTOTAL] += number;
   if (ch->quint[MTOTAL] > 5)
   {
      ch->quint[AVATAR] = 5;
      ch->quint[MTOTAL] -= 5;
      if (ch->quint[MTOTAL] > 5)
      {
	 ch->quint[BODY] = 5;
	 ch->quint[MTOTAL] = 0;
      }
      else
      {
	 ch->quint[BODY] = ch->quint[MTOTAL];
	 ch->quint[MTOTAL] = 0;
      }
   }
   else
   {
      ch->quint[AVATAR] = ch->quint[MTOTAL];
      ch->quint[BODY] = 0;
   }
   return;
}

void do_enchant (CHAR_DATA * ch, char *argument)
{
   OBJ_DATA *obj;
   char arg[MIL];

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MPRI] < 2)
   {
      stc ("You must obtain a level two knowledge of Prime to use Enchant Weapon.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("What object do you wish to enchant?\n\r", ch);
      return;
   }

   if ((obj = get_obj_carry (ch, arg)) == NULL)
   {
      stc ("You are not carrying that object.\n\r", ch);
      return;
   }

   if (obj->item_type != ITEM_WEAPON)
   {
      act ("$p is not a weapon.", ch, obj, NULL, TO_CHAR);
      return;
   }

   if (IS_SET (obj->quest, QUEST_MAGEENCHANT))
   {
      act ("$p is already filled with quintessence.", ch, obj, NULL, TO_CHAR);
      return;
   }

   if (check_quint (ch) < 1)
   {
      stc ("You need one point of quintessence available to use this power.\n\r", ch);
      return;
   }

   if (IS_SET (obj->quest, QUEST_ARTIFACT)
       || IS_SET (obj->quest, QUEST_RELIC))
   {
      act ("$p is too powerful for your quintessence.", ch, obj, NULL,
	   TO_CHAR);
      return;
   }

   obj->value[1] += (ch->spheres[MPRI] * 2);
   obj->value[2] += (ch->spheres[MPRI] * 2);
   SET_BIT (obj->quest, QUEST_MAGEENCHANT);
   act ("$p glows radiantly as you infuse your quintessence into it.", ch,
	obj, NULL, TO_CHAR);
   act ("$n's weapon, $p, glows brilliantly.", ch, obj, NULL, TO_ROOM);
   subtract_quint (ch, 1);
   return;
}

/* Recolor to any color you want! */
void do_recolour (CHAR_DATA * ch, char *argument)
{
   char arg1[MAX_INPUT_LENGTH];
   char buf[MAX_STRING_LENGTH];
   int col;

   argument = one_argument (argument, arg1);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->level < LEVEL_MAGE)
   {
      stc ("You must be a FULL Mage to use this power.\n\r", ch);
      return;
   }
   if (check_quint (ch) < 1)
   {
      stc ("You need one point of quintessence available change color.\n\r",
	   ch);
      return;
   }

   if (ch->exp < 100000)
   {
      stc ("It costs 100 thousand exp to change your color!\n\r", ch);
      return;
   }
   if (arg1[0] == '\0')
   {
      stc ("Recolor to what? #rRED#n, #bBLUE#n, #gGREEN#n, #yYELLOW#n, or #PPURPLE#n?\n\r", ch);
      return;
   }

   if (!str_cmp (arg1, "purple"))
      col = 0;
   else if (!str_cmp (arg1, "red"))
      col = 1;
   else if (!str_cmp (arg1, "blue"))
      col = 2;
   else if (!str_cmp (arg1, "green"))
      col = 3;
   else if (!str_cmp (arg1, "yellow"))
      col = 4;
   else
   {
      stc ("No such color!\n\r", ch);
      return;
   }

   ch->pcdata->powers[MPOWER_RUNE0] = col;
   sprintf (buf, "You now chant %s spells.\n\r", capitalize (arg1));
   stc (buf, ch);
   subtract_quint (ch, 1);
   ch->exp -= 100000;
   return;
}

void do_rubbing (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg[MIL];
   int dam;

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MPRI] < 3)
   {
      stc ("You must obtain level three Prime to use Rubbing of the Bones.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Whom do you wish to use this on?\n\r", ch);
      return;
   }

   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      stc ("You cannot find your victim here.\n\r", ch);
      return;
   }

   if (victim->level < 3)
   {
      stc ("They must be an avatar!\n\r", ch);
      return;
   }

   if (check_quint (ch) < 2)
   {
      stc ("You must have two points of quintessence to use this power.\n\r",
	   ch);
      return;
   }

   subtract_quint (ch, 2);
   dam = ch->spheres[MPRI] * 400;
   if (!IS_NPC (victim))
      dam /= number_range (1.5, 2);
   mage_damage (ch, victim, dam, "quintessence warp", MAGEDAM_QUINT);
   WAIT_STATE (ch, 16);
   act ("You are stunned by $n's blast.", ch, NULL, victim, TO_VICT);
   WAIT_STATE (victim, 8);
   return;
}

void do_purification (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg[MIL];
   int dam;

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MPRI] < 4)
   {
      stc ("You must obtain level four Prime to use Flames of Purification.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Whom do you wish to use this on?\n\r", ch);
      return;
   }

   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      stc ("You cannot find your victim here.\n\r", ch);
      return;
   }
   if (victim->level < 3)
   {
      stc ("They must be an avatar!\n\r", ch);
      return;
   }

   if (check_quint (ch) < 3)
   {
      stc ("You must have three points of quintessence to use this power.\n\r", ch);
      return;
   }

   subtract_quint (ch, 3);
   dam = ch->spheres[MPRI] * 800;
   if (!IS_NPC (victim))
      dam /= number_range (1.5, 2);
   if (!WORN_ARTIFACT (victim, ARTI_DEMONS_HEART)) mage_damage (ch, victim, dam, "flames of purification", MAGEDAM_QUINT);
   WAIT_STATE (ch, 16);
   return;
}

void do_qblast (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg[MIL];
   int dam;

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MPRI] < 5)
   {
      stc ("You must obtain level five Prime to use Quintessence Blast.\n\r",
	   ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Whom do you wish to use this on?\n\r", ch);
      return;
   }

   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      stc ("You cannot find your victim here.\n\r", ch);
      return;
   }

   if (!IS_NPC (victim) && victim->level < 3)
   {
      stc ("They must be an avatar!\n\r", ch);
      return;
   }

   if (check_quint (ch) < 2)
   {
      stc ("You must have five points of quintessence to use this power.\n\r",
	   ch);
      return;
   }

   subtract_quint (ch, 2);

   dam = (ch->spheres[MPRI] * ch->damcap[0]) * 0.85;
   if (!IS_NPC (victim))
      dam /= number_range (1.5, 2);
   mage_damage (ch, victim, dam, "quintessence blast", MAGEDAM_QUINT);
   WAIT_STATE (ch, 16);
   return;
}

void do_dimmak (CHAR_DATA * ch, char *argument)
{
   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MENT] < 1)
   {
      stc ("You must obtain level one entropy to use Dim Mak.\n\r", ch);
      return;
   }

   if (IS_SET (ch->mflags, MFLAGS_DIMMAK))
   {
      REMOVE_BIT (ch->mflags, MFLAGS_DIMMAK);
      stc ("You no longer focus your attacks on your opponent's weakness.\n\r", ch);
      return;
   }

   else
   {
      SET_BIT (ch->mflags, MFLAGS_DIMMAK);
      stc ("You now focus your attacks on your opponent's weakness.\n\r", ch);
      return;
   }

   return;
}

void do_hotienchi (CHAR_DATA * ch, char *argument)
{
   int i, test = 0;

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MLIF] < 1)
   {
      stc ("You must obtain level one Life to use Ho Tien Chi.\n\r", ch);
      return;
   }

   for (i = 0; i < 7; i++)
   {
      if (ch->loc_hp[i] > 0)
	 test++;
   }

   if (ch->hit == ch->max_hit && ch->mana == ch->max_mana
       && ch->move == ch->max_move && test == 0)
   {
      stc ("You are in perfect condition!\n\r", ch);
      return;
   }

   if (ch->loc_hp[6] > 0)
   {
      stc ("Your wounds close up and stop bleeding.\n\r", ch);
      ch->loc_hp[6] = 0;
   }

   if ((ch->loc_hp[0] + ch->loc_hp[1] + ch->loc_hp[2] + ch->loc_hp[3] +
	ch->loc_hp[4] + ch->loc_hp[5]) != 0)
   {
      stc ("Your bones mend themselves together and new limbs grow out of your body.\n\r", ch);
      ch->loc_hp[0] = 0;
      ch->loc_hp[1] = 0;
      ch->loc_hp[2] = 0;
      ch->loc_hp[3] = 0;
      ch->loc_hp[4] = 0;
      ch->loc_hp[5] = 0;
   }

   stc ("A warm feeling spreads through your body.\n\r", ch);
   ch->hit += (ch->spheres[MLIF] * 400);
   ch->mana += (ch->spheres[MLIF] * 200);
   ch->move += (ch->spheres[MLIF] * 200);
   if (ch->hit > ch->max_hit)
      ch->hit = ch->max_hit;
   if (ch->mana > ch->max_mana)
      ch->mana = ch->max_mana;
   if (ch->move > ch->max_move)
      ch->move = ch->max_move;
   update_pos (ch);
   WAIT_STATE (ch, 18);
   return;
}

void do_littledeath (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg[MIL];

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MLIF] < 2)
   {
      stc ("You must obtain level two Life to use Little Good Death.\n\r",
	   ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Whom do you wish to use this on?\n\r", ch);
      return;
   }

   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      stc ("You cannot find your victim here.\n\r", ch);
      return;
   }

   if (!IS_NPC (victim))
   {
      stc ("A human being is too complex for this spell.\n\r", ch);
      return;
   }

   if (victim->level > 100)
   {
      act ("$N's pattern is too complex to destroy.", ch, NULL, victim,
	   TO_CHAR);
      return;
   }

   WAIT_STATE (ch, 12);
   act ("You mentally grasp $N's pattern and tear $M to shreds.", ch, NULL,
	victim, TO_CHAR);
   act ("$n's eyes turn black.\n$N's body is torn to shreds before your eyes!", ch, NULL, victim, TO_ROOM);
   raw_kill (victim, ch);
   return;
}

void do_betterbody (CHAR_DATA * ch, char *argument)
{
   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MLIF] < 3)
   {
      stc ("You must obtain level three Life to use Better Body.\n\r", ch);
      return;
   }

   if (IS_SET (ch->mflags, MAGE_BETTERBODY))
   {
      stc ("Your body shrinks to its true form.\n\r", ch);
      REMOVE_BIT (ch->mflags, MAGE_BETTERBODY);

      ch->pcdata->perm_str -= 4;
      ch->pcdata->perm_con -= 2;
      ch->pcdata->perm_dex -= 3;
      //ch->hitroll -= 115;
      //ch->damroll -= 200;
      return;

   }

   else
   {
      stc ("Your body contorts and grows to supernatural size.\n\r", ch);
      SET_BIT (ch->mflags, MAGE_BETTERBODY);
      ch->pcdata->perm_str += 4;
      ch->pcdata->perm_dex += 3;
      ch->pcdata->perm_con += 2;
      return;
   }
   return;
}

void do_shapechange (CHAR_DATA * ch, char *argument)
{
   char arg[MIL];
   char buf[MSL];
   int choice = 0;

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MLIF] < 4)
   {
      stc ("You must obtain level four Life to Change Shape.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      divide_to_char (ch);
      centre_text ("Forms", ch);
      divide_to_char (ch);
      stc ("    [ 0 ]  Human\n", ch);
      stc ("    [ 1 ]  Tiger\n", ch);
      stc ("    [ 2 ]  Lion\n", ch);
      stc ("    [ 3 ]  Raven\n", ch);
      stc ("    [ 4 ]  Frog\n", ch);
      stc ("    [ 5 ]  Dog\n", ch);
      stc ("    [ 6 ]  Hawk\n", ch);
      stc ("    [ 7 ]  Mouse\n", ch);
      stc ("    [ 8 ]  Spider\n", ch);
      divide_to_char (ch);
      return;
   }

   choice = is_number (arg) ? atoi (arg) : -1;

   if (choice == 1)
   {
      sprintf (buf, "%s the ferocious tiger", ch->name);
      stc ("You transform into a ferocious tiger.\n\r", ch);
      act ("$n transforms into a tiger.", ch, NULL, NULL, TO_ROOM);
   }
   else if (choice == 2)
   {
      sprintf (buf, "%s the lion", ch->name);
      stc ("You transform into a lion.\n\r", ch);
      act ("$n transforms into a lion.", ch, NULL, NULL, TO_ROOM);
   }
   else if (choice == 3)
   {
      sprintf (buf, "%s the raven", ch->name);
      stc ("You transform into a raven.\n\r", ch);
      act ("$n transforms into a raven.", ch, NULL, NULL, TO_ROOM);
   }
   else if (choice == 4)
   {
      sprintf (buf, "%s the frog", ch->name);
      stc ("You transform into a frog.\n\r", ch);
      act ("$n transforms into a frog.", ch, NULL, NULL, TO_ROOM);
   }
   else if (choice == 5)
   {
      sprintf (buf, "%s the dog", ch->name);
      stc ("You transform into a small dog.\n\r", ch);
      act ("$n transforms into a dog.", ch, NULL, NULL, TO_ROOM);
   }
   else if (choice == 6)
   {
      sprintf (buf, "%s the hawk", ch->name);
      stc ("You transform into a hawk.\n\r", ch);
      act ("$n transforms into a hawk.", ch, NULL, NULL, TO_ROOM);
   }
   else if (choice == 7)
   {
      sprintf (buf, "%s the mouse", ch->name);
      stc ("You transform into a white mouse.\n\r", ch);
      act ("$n transforms into a white mouse.", ch, NULL, NULL, TO_ROOM);
   }
   else if (choice == 8)
   {
      sprintf (buf, "%s the spider", ch->name);
      stc ("You transform into a black spider.\n\r", ch);
      act ("$n transforms into a black spider.", ch, NULL, NULL, TO_ROOM);
   }
   else if (choice == 0)
   {
      if (IS_AFFECTED (ch, AFF_POLYMORPH))
      {
	 REMOVE_BIT (ch->affected_by, AFF_POLYMORPH);
	 REMOVE_BIT (ch->mflags, MAGE_SHAPED);
	 free_string (ch->morph);
	 ch->morph = str_dup ("");
	 stc ("You revert to your human form.\n\r", ch);
	 act ("$n reverts to $s human form.", ch, NULL, NULL, TO_ROOM);
	 return;
      }
      else
      {
	 stc ("You aren't even shapechanged!\n\r", ch);
	 return;
      }
   }
   else
   {
      stc ("That's not a choice!\n\r", ch);
      do_shapechange (ch, "");
      return;
   }

   SET_BIT (ch->affected_by, AFF_POLYMORPH);
   SET_BIT (ch->mflags, MAGE_SHAPED);
   clear_stats (ch);
   free_string (ch->morph);
   ch->morph = str_dup (buf);
   return;
}

void do_layhands (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg[MIL];
   int i, test = 0;

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MLIF] < 1)
   {
      stc ("You must obtain level one Life to use Ho Tien Chi.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Whom do you wish to use this on?\n\r", ch);
      return;
   }

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

   for (i = 0; i < 7; i++)
   {
      if (victim->loc_hp[i] > 0)
	 test++;
   }

   if (victim->hit == victim->max_hit && victim->mana == victim->max_mana
       && victim->move == victim->max_move && test == 0)
   {
      stc ("They are in perfect condition!\n\r", ch);
      return;
   }

   if (victim->loc_hp[6] > 0)
   {
      stc ("Your wounds close up and stop bleeding.\n\r", victim);
      victim->loc_hp[6] = 0;
   }

   if ((victim->loc_hp[0] + victim->loc_hp[1] + victim->loc_hp[2] +
	victim->loc_hp[3] + victim->loc_hp[4] + victim->loc_hp[5]) != 0)
   {
      stc ("Your bones mend themselves together and new limbs grow out of your body.\n\r", victim);
      victim->loc_hp[0] = 0;
      victim->loc_hp[1] = 0;
      victim->loc_hp[2] = 0;
      victim->loc_hp[3] = 0;
      victim->loc_hp[4] = 0;
      victim->loc_hp[5] = 0;
   }

   stc ("A warm feeling spreads through your body.\n\r", victim);
   victim->hit += (ch->spheres[MLIF] * 75);
   victim->mana += (ch->spheres[MLIF] * 50);
   victim->move += (ch->spheres[MLIF] * 50);
   if (victim->hit > victim->max_hit)
      victim->hit = victim->max_hit;
   if (victim->mana > victim->max_mana)
      victim->mana = victim->max_mana;
   if (victim->move > victim->max_move)
      victim->move = victim->max_move;
   WAIT_STATE (ch, 18);
   act ("You lay your hands on $N and rejuvenate $M.", ch, NULL, victim,
	TO_CHAR);
   return;
}

void do_analyze (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   OBJ_DATA *obj;
   char arg[MAX_INPUT_LENGTH];
   char buf[MAX_INPUT_LENGTH];

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MMAT] < 1)
   {
      stc ("You must obtain level one Matter to use Analyze Substance.\n\r",
	   ch);
      return;
   }

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

   if ((victim = get_char_room (ch, arg)) == NULL)
   {
      if ((obj = get_obj_carry (ch, arg)) == NULL)
      {
	 send_to_char ("Analyze what?\n\r", ch);
	 return;
      }
      act ("A look of concentration comes over $n's face as they analyze the substance of $p.", ch, obj, NULL, TO_ROOM);
      spell_identify (skill_lookup ("identify"), ch->level, ch, obj);
      return;
   }

   if (!IS_NPC (victim) && IS_IMMUNE (victim, IMM_SHIELDED))
   {
      send_to_char ("You are unable to analyze their substance.\n\r", ch);
      return;
   }

   act ("$n analyzes $N's substance.", ch, NULL, victim, TO_NOTVICT);
   act ("$n analyzes your substance.", ch, NULL, victim, TO_VICT);
   if (IS_NPC (victim))
      sprintf (buf, "%s is an NPC.\n\r", victim->short_descr);
   else
   {
      if (victim->level == 12)
	 sprintf (buf, "%s is an Implementor.\n\r", victim->name);
      else if (victim->level == 11)
	 sprintf (buf, "%s is a High Judge.\n\r", victim->name);
      else if (victim->level == 10)
	 sprintf (buf, "%s is a Judge.\n\r", victim->name);
      else if (victim->level == 9)
	 sprintf (buf, "%s is an Enforcer.\n\r", victim->name);
      else if (victim->level == 8)
	 sprintf (buf, "%s is a Quest Maker.\n\r", victim->name);
      else if (victim->level == 7)
	 sprintf (buf, "%s is a Builder.\n\r", victim->name);
      else if (victim->level >= 3)
	 sprintf (buf, "%s is an Avatar.\n\r", victim->name);
      else
	 sprintf (buf, "%s is a Mortal.\n\r", victim->name);
   }
   send_to_char (buf, ch);
   if (!IS_NPC (victim))
   {
      sprintf (buf, "Str:%d, Int:%d, Wis:%d, Dex:%d, Con:%d.\n\r",
	       get_curr_str (victim), get_curr_int (victim),
	       get_curr_wis (victim), get_curr_dex (victim),
	       get_curr_con (victim));
      send_to_char (buf, ch);
   }
   sprintf (buf, "Hp:%d/%d, Mana:%d/%d, Move:%d/%d.\n\r", victim->hit,
	    victim->max_hit, victim->mana, victim->max_mana, victim->move,
	    victim->max_move);
   send_to_char (buf, ch);
   if (!IS_NPC (victim))
      sprintf (buf, "Hitroll:%d, Damroll:%d, AC:%d.\n\r",
	       char_hitroll (victim), char_damroll (victim),
	       char_ac (victim));
   else
      sprintf (buf, "AC:%d.\n\r", char_ac (victim));
   send_to_char (buf, ch);
   if (!IS_NPC (victim))
   {
      sprintf (buf, "Status:%d, ", victim->race);
      send_to_char (buf, ch);
   }
   sprintf (buf, "Alignment:%d.\n\r", victim->alignment);
   send_to_char (buf, ch);
   if (!IS_NPC (victim) && IS_EXTRA (victim, EXTRA_PREGNANT))
      act ("$N is pregnant.", ch, NULL, victim, TO_CHAR);
   return;
}

void do_alterstate (CHAR_DATA * ch, char *argument)
{
   OBJ_DATA *obj;
   CHAR_DATA *victim;
   char arg[MIL];

  int quintcost = 2;

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MMAT] < 2)
   {
      stc ("You must obtain level two Matter to use Alter State.\n\r", ch);
      return;
   }

   if (arg[0] == '\0' && ch->fighting == NULL)
   {
      stc ("Whom do you wish to use this on?\n\r", ch);
      return;
   }

   if (ch->fighting == NULL)
   {
      if ((victim = get_char_room (ch, arg)) == NULL)
      {
	 stc ("You are unable to find them in this room.\n\r", ch);
	 return;
      }
   }
   else
      victim = ch->fighting;

   if ((obj = get_eq_char (victim, WEAR_WIELD)) == NULL)
   {
      if ((obj = get_eq_char (victim, WEAR_HOLD)) == NULL)
      {
         if ((obj = get_eq_char (victim, WEAR_DUAL)) == NULL)
         {
            stc ("They aren't using any weapons!\n\r", ch);
            return;
         }
      }
   }

   if (check_quint (ch) < 2)
   {
      stc ("You need two points of quintessence to use this power.\n\r", ch);
      return;
   }

   if (is_safe (ch, victim))
      return;

   if (!IS_NPC (victim))
   {
      if (IS_DEMPOWER (victim, HPOWER_USE_PRESERVATION))
      {
	 if (victim->quickening[0] >= 5)
	 {
	    victim->quickening[0] -= 5;
	    if (number_range (1, 100) > 50)
	    {
	       stc ("Sparkles of energy crackle around your weapons blocking their attempt to alter them.\n\r", victim);
	       stc ("Sparkles of energy crackle around their weapons blocking your alterstate.\n\r", ch);
	       ch->fight_timer = 10;
	       victim->fight_timer = 10;
	       return;
	    }
	    else
	    {
	       stc ("Sparkles of energy crackle around your weapons but fail to block their attempt to alter them.\n\r", victim);
	       stc ("Sparkles of energy crackle around their weapons but fail to block your alterstate.\n\r", ch);
	    }
	 }
      }
   }

   obj_from_char (obj);
   obj_to_char (obj, victim);
   act ("You alter the state of $N's weapon, causing $M to drop it.", ch, NULL, victim, TO_CHAR);
   act ("$n's eyes glow dark black.", ch, NULL, NULL, TO_ROOM);
   act ("$p shakes violently, causing you to drop it.", ch, obj, victim, TO_VICT);

  subtract_quint (ch, quintcost );
  WAIT_STATE (ch, 12 );
  WAIT_STATE (victim, 8);
  return;
}

void do_alterweight (CHAR_DATA * ch, char *argument)
{
   OBJ_DATA *obj;
   char arg[MIL];
   int oldweight = 0;

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MMAT] < 3)
   {
      stc ("You must obtain level three Matter to use Alter Weight.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Which object's weight do you want to lower?\n\r", ch);
      return;
   }

   if ((obj = get_obj_carry (ch, arg)) == NULL)
   {
      stc ("You are not carrying that object.\n\r", ch);
      return;
   }

   if (obj->weight <= 1)
   {
      stc ("That object is already as light as possible!\n\r", ch);
      return;
   }
   oldweight = obj->weight;
   ch->carry_weight -= (oldweight - 1);
   obj->weight = 1;
   act ("You rearrange $p's pattern, lowering it's weight.", ch, obj, NULL,
	TO_CHAR);
   act ("$n's eyes glow bright green.", ch, NULL, NULL, TO_ROOM);
   WAIT_STATE (ch, 8);
   return;
}

void do_enchantarmor (CHAR_DATA * ch, char *argument)
{
   OBJ_DATA *obj;
   AFFECT_DATA *paf;
   char arg[MIL];

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MMAT] < 4)
   {
      stc ("You must obtain level four Matter to use Enchant Armor.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Which piece of armor do you want to enchant?\n\r", ch);
      return;
   }

   if ((obj = get_obj_carry (ch, arg)) == NULL)
   {
      stc ("You are not carrying that object.\n\r", ch);
      return;
   }

   if (IS_SET (obj->quest, QUEST_MAGEENCHANT))
   {
      stc ("This object has already been enchanted.\n\r", ch);
      return;
   }

   if (obj->item_type != ITEM_ARMOR)
   {
      stc ("This item isn't a piece of armor.\n\r", ch);
      return;
   }

   if (check_quint (ch) < 3)
   {
      stc ("You need three points of quintessence to Enchant Armor.\n\r", ch);
      return;
   }

   act ("You lay your hands on $p and rearrange its pattern.", ch, obj, NULL,
	TO_CHAR);
   act ("$n's eyes glow bright blue.\n$n lays $s hands on $p.\n$p glows blue.", ch, obj, NULL, TO_ROOM);
   SET_BIT (obj->quest, QUEST_MAGEENCHANT);

   if (affect_free == NULL)
   {
      paf = alloc_perm (sizeof (*paf));
   }
   else
   {
      paf = affect_free;
      affect_free = affect_free->next;
   }

   paf->type = skill_lookup ("enchant weapon");
   paf->duration = -1;
   paf->location = APPLY_HITROLL;
   paf->modifier = 3;
   paf->bitvector = 0;
   paf->next = obj->affected;
   obj->affected = paf;

   if (affect_free == NULL)
   {
      paf = alloc_perm (sizeof (*paf));
   }
   else
   {
      paf = affect_free;
      affect_free = affect_free->next;
   }

   paf->type = skill_lookup ("enchant weapon");
   paf->duration = -1;
   paf->location = APPLY_DAMROLL;
   paf->modifier = 3;
   paf->bitvector = 0;
   paf->next = obj->affected;
   obj->affected = paf;

   WAIT_STATE (ch, 16);
   subtract_quint (ch, 3);
   return;
}

void do_hover (CHAR_DATA * ch, char *argument)
{
   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MMAT] < 5)
   {
      stc ("You must obtain level 5 matter to use Hoverwalk.\n\r", ch);
      return;
   }

   if (IS_AFFECTED (ch, AFF_FLYING))
   {
      stc ("You slowly float to the ground as your air cushion dissipates.\n\r", ch);
      act ("$n slowly floats to the ground.", ch, NULL, NULL, TO_ROOM);
      REMOVE_BIT (ch->affected_by, AFF_FLYING);
      return;
   }
   else
   {
      stc ("You restructure the pattern of the air around your body.\n\rYou slowly float into the air.\n\r", ch);
      act ("$n slowly floats into the air.", ch, NULL, NULL, TO_ROOM);
      SET_BIT (ch->affected_by, AFF_FLYING);
      return;
   }

   return;
}

void do_mshadow (CHAR_DATA * ch, char *argument)
{
   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MMIN] < 5)
   {
      stc ("You must obtain level five Mind to use Untether.\n\r", ch);
      return;
   }
   if (ch->fight_timer > 0)
   {
      stc ("Not with a fight timer!\n\r", ch);
      return;
   }
   if (IS_SET (ch->flag2, AFF2_INARENA))
   {
      stc ("Not while you're in the arena.\n\r", ch);
      return;
   }
   if (!IS_AFFECTED (ch, AFF_SHADOWPLANE))
   {
      send_to_char ("You fade into the plane of shadows.\n\r", ch);
      act ("The shadows flicker and swallow up $n.", ch, NULL, NULL, TO_ROOM);
      SET_BIT (ch->affected_by, AFF_SHADOWPLANE);
      do_look (ch, "auto");
      return;
   }

   REMOVE_BIT (ch->affected_by, AFF_SHADOWPLANE);
   send_to_char ("You fade back into the real world.\n\r", ch);
   act ("The shadows flicker and $n fades into existance.", ch, NULL, NULL,
	TO_ROOM);
   do_look (ch, "auto");
   return;
}

void do_callspirit (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   AFFECT_DATA af;
   int sn;

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MSPI] < 1)
   {
      stc ("You must obtain level one Spirit to Call Spirits.\n\r", ch);
      return;
   }

   if (ch->pcdata->followers > 5)
   {
      stc ("Nothing seems to happen.\n\r", ch);
      return;
   }

   stc ("You chant an arcane spell and conjure a spirit.\n\r", ch);
   act ("$n chants loudly in a foreign language.", ch, NULL, NULL, TO_ROOM);

   if ((sn = skill_lookup ("guardian")) < 0)
   {  
      send_to_char ("Bug - please inform an imp.\n\r", ch);   
      return;
   }
   ch->pcdata->followers++;
   victim = create_mobile (get_mob_index (MOB_VNUM_GUARDIAN));
   victim->name = str_dup ("spirit");
   victim->short_descr = str_dup ("A wicked spirit");
   victim->long_descr =
      str_dup ("A ghostly image hovers over the ground here.\n\r");
   victim->level = 1000;
   victim->hit = 25000;
   victim->max_hit = 25000;
   victim->hitroll = 50;
   victim->damroll = 50;
   victim->armor = 300;
   SET_BIT (victim->act, ACT_NOEXP);
   char_to_room (victim, ch->in_room);
   add_follower (victim, ch);
   af.type = sn;
   af.duration = 6666; 
   af.location = APPLY_NONE;
   af.modifier = 0;
   af.bitvector = AFF_CHARM;
   affect_to_char (victim, &af);
   act ("$N materializes next to $n.", ch, NULL, victim, TO_ROOM);
   return;
}

void do_spiritkiss (CHAR_DATA * ch, char *argument)
{
   int sn, level;

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MSPI] < 2)
   {
      stc ("You must obtain level two Spirit to use Spirit Kiss.\n\r", ch);
      return;
   }

   if ((sn = skill_lookup ("spirit kiss")) < 0)
      return;

   if (is_affected (ch, sn))
   {
      stc ("You are already blessed by the spirits.\n\r", ch);
      return;
   }

   if (check_quint (ch) < 1)
   {
      stc ("You need one point of quintessence to call a spirit.\n\r", ch);
      return;
   }

   level = (ch->spheres[MSPI] * 25);
   (*skill_table[sn].spell_fun) (sn, level, ch, ch);
   WAIT_STATE (ch, 12);
   subtract_quint (ch, 1);
   return;
}

void do_spiritblast (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *victim;
   char arg[MIL];
   int dam;

   argument = one_argument (argument, arg);

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MSPI] < 4)
   {
      stc ("You must obtain level 4 Spirit to use Spirit Blast.\n\r", ch);
      return;
   }

   if (arg[0] == '\0')
   {
      stc ("Whom do you want to use Spirit Blast on?\n\r", ch);
      return;
   }

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

   if (victim->level < 3)
   {
      stc ("They must be an avatar!\n\r", ch);
      return;
   }

   dam = ch->spheres[MSPI] * 200;
   mage_damage (ch, victim, dam, "spirit blast", MAGEDAM_OTHER);
   if (!IS_NPC (victim))
   {
      if (IS_CLASS (victim, CLASS_HIGHLANDER) && (number_range (1, 100 < 60)))
      {
	 int quick_drain = dice (1, 4);

	 if (victim->quickening[0] >= 0)
	    victim->quickening[0] -= quick_drain;
	 if (victim->quickening[0] < 0)
	    victim->quickening[0] = 0;

	 stc ("You grin as some of their quickening drains away.\n\r", ch);
	 act ("$n grins as some of your quickening is drained away.\n\r", ch,
	      NULL, victim, TO_VICT);
      }
   }

   victim->mana -= (dam * 6);
   victim->move -= (dam * 6);
   ch->mana += (dam * 3);
   ch->move += (dam * 3);

   if (ch->mana > (ch->max_mana))
      ch->mana = (ch->max_mana);
   if (ch->move > (ch->max_move))
      ch->move = (ch->max_move);
   if (victim->mana < 0)
      victim->mana = 0;
   if (victim->move < 0)
      victim->move = 0;
   stc ("You absorb the energy from the blast.\n\r", ch);
   stc ("You feel drained.\n\r", victim);
   WAIT_STATE (ch, 16);
   return;
}

void do_breach (CHAR_DATA * ch, char *argument)
{
   CHAR_DATA *vch;
   CHAR_DATA *vch_next;
   CHAR_DATA *mount;

   if (IS_NPC (ch))
      return;

   if (!is_mage (ch))
      return;

   if (ch->spheres[MSPI] < 5)
   {
      stc ("You must obtain level 5 Spirit to Breach the Gauntlet.\n\r", ch);
      return;
   }
   if (ch->fight_timer > 0)
   {
      stc ("Not with a fight timer!\n\r", ch);
      return;
   }
   if (check_quint (ch) < 2)
   {
      stc ("You need two points of quintessence to breach the gauntlet.\n\r",
	   ch);
      return;
   }

   for (vch = char_list; vch != NULL; vch = vch_next)
   {
      vch_next = vch->next;
      if (vch->in_room == NULL)
	 continue;
      if (!IS_NPC (vch) && vch->pcdata->chobj != NULL)
	 continue;
      if (vch->level < 3)
	 continue;
      if (IS_SET (vch->affected_by, AFF_SHADOWPLANE))
	 continue;
      if (ch == vch)
	 continue;
      if (vch->in_room == ch->in_room)
      {
	 if ((mount = ch->mount) != NULL)
	 {
	    if (mount == vch)
	       continue;
	 }

	 if (can_see (ch, vch))
	 {
	    act ("$n's eyes turn dark black.\nThe room is torn apart before your very eyes, and you fall into a black nothingness.", ch, NULL, vch, TO_VICT);
	    SET_BIT (vch->affected_by, AFF_SHADOWPLANE);
	 }
      }
   }
   SET_BIT (ch->affected_by, AFF_SHADOWPLANE);
   subtract_quint (ch, 2);
   stc ("You tear the room apart, reforming it in the spirit world.\n\r", ch);
   return;

}