atd/area/
atd/build/
atd/clans/
atd/log/
atd/player/store/
atd/site/
atd/src/bin/
/***************************************************************************
 *  God Wars Mud originally written by Kavir Richard Woolcock.         *
 *  Changes done to the code done by Sage aka Walter Howard, this mud is   *
 *  for the public, however if you run this code it means you agree        *
 *  to the license.low, license.gw, and license.merc have fun. :)          *
***************************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <stdlib.h>
#include "merc.h"
#include "commands.h"

/*
 * Functions needed
 */
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 ) );
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 ) );
void readaura           args( ( CHAR_DATA *ch, CHAR_DATA * victim ) );
void spheres            args( ( CHAR_DATA *ch ) );

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


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;
}

/*
 * Stick the arete shit in here
 *    <char>, <sphere>, <minarete>, <minspherevalue>, <mana -1 if not needed>
 */
bool has_mana( CHAR_DATA *ch, int sp, int arete, int spv, int mana )
{
    if( IS_NPC(ch) )
        return TRUE;
    
    if( ch->spheres[MART] < arete )
    {
        stc("You do not command enough arete to harness this power.\n\r",ch);
        return TRUE;
    }

    if( ch->spheres[sp] < spv )
    {
        stc("You are not skilled enough to command this sphere.\n\r", ch );
        return TRUE;
    }

    if( mana > 0 && ch->mana < mana )
    {
        ch_printf(ch, "You need atleast %d mana to use this spell.\n\r",
		mana);
        return TRUE;
    }
    ch->mana -= mana;
    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];
   else
	in_gate->timer = -1;
  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];
  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' )
  {
      ch_printf(ch,
      "-=[**]_[**]=-=[**]_[**]=-=[**]_[**] Spheres [**]_[**]=-=[**]_[**]=-=[**]_[**]=-\n\r");
      ch_printf(ch,
      "[+]                                                                         [+]\n\r");
      ch_printf(ch,
      "[+]    Correspondence  (%s%s%s%s%s)       Life    (%s%s%s%s%s)      Forces  (%s%s%s%s%s)   [+]\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 ? "*" : " " );
      ch_printf(ch,
      "[+]       Entropy      (%s%s%s%s%s)       Mind    (%s%s%s%s%s)      Spirit  (%s%s%s%s%s)   [+]\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 ? "*" : " " );
      ch_printf(ch,
      "[+]        Prime       (%s%s%s%s%s)       Time    (%s%s%s%s%s)      Matter  (%s%s%s%s%s)   [+]\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 ? "*" : " " );
      ch_printf(ch,
      "[+]                        Arete       (%s%s%s%s%s%s%s%s%s%s)                        [+]\n\r",
                ch->spheres[MART] >= 1 ? "*" : " ", ch->spheres[MART] >= 2 ? "*" : " ",
                ch->spheres[MART] >= 3 ? "*" : " ", ch->spheres[MART] >= 4 ? "*" : " ",
                ch->spheres[MART] >= 5 ? "*" : " ", ch->spheres[MART] >= 6 ? "*" : " ",
                ch->spheres[MART] >= 7 ? "*" : " ", ch->spheres[MART] >= 8 ? "*" : " ",
                ch->spheres[MART] >= 9 ? "*" : " ", ch->spheres[MART] >= 10 ? "*" : " " );
      stc(
      "[+]                                                                         [+]\n\r",ch);
      stc("-=[**]_[**]=-=[**]_[**]=-=[**]_[**]---------[**]_[**]=-=[**]_[**]=-=[**]_[**]=-\n\r",ch);
      return;
  }

  if ( arg2[0] == '\0' )
  {
      if( !str_cmp( arg1, "help" ) )
      {
	  spheres(ch);
	  return;
      }
      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);
	centre_text("Demmok", ch );
	if( ch->spheres[MENT] > 4 )
	   centre_text("Mage shields", 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);
        centre_text("Ethereal Shields", 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 if ( !str_prefix( arg1, "arete" ) )
    {
      disc = MART;
          if ( ch->spheres[disc] >= 10 )
	  {
	    stc(
		"You have already learned all levels of the arete sphere.\n\r",ch);
	    return;
	  }
	  cost = ( ( ch->spheres[disc] + 1 ) * 2000 );

	  if ( ch->pcdata->stats[DEMON_CURRENT] < cost )
	  {
            ch_printf( ch, "You need %d cps to obtain a new level of understanding of the arete sphere.\n\r", cost );
	    return;
	  }
	  ch->pcdata->stats[DEMON_CURRENT] -= cost;
	  ch->spheres[MART]++;
	  ch_printf( ch, "Your knowledge of the arete sphere increases.\n\r");
	  return;
    }	
    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 ) * 2000 );

  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->pcdata->stats[DEMON_CURRENT] < cost )
  {
    sprintf(buf, "You need %d cps to obtain a new level of understanding of the %s sphere.\n\r", cost, sphere_name[disc] );
    stc(buf,ch);
    return;
  }

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

}

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

    if ( !is_mage(ch) )
        return;
               /*  ch, sp, arete, spv, mana */
    if ( has_mana( ch, MCOR, 1, 1, 1000 ) )
    {
        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);
        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);
        return;
    }

    return;
}

// Shield, Scry, Level II Correspondence

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 ( has_mana( ch, MCOR, 2, 2, 0 ) )
    {
        stc("You must obtain level two Correspondence to Open a Spacial Gate.\n\r",ch);
        return;
    }

    if ( has_mana( ch, MMAT, 2, 2, 1500 ) )
    {
        stc("This sphere must be used in conjunction with 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 ( !str_cmp(arg2, "grab" ) )
    {
        if ( IS_SET(obj->quest, QUEST_ARTIFACT)
             || IS_SET(obj->quest, ITEM_EQUEST)
             || IS_SET(obj->quest, QUEST_RELIC) )
        {
            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->pIndexData->vnum >= 30040)
        {
            stc("You reach through a rift in space but the quest-machine is to heavy for you.\n\r", ch );
            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) )
        {
            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 contained.\n\r" ,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 ( !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;
        }

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

    if( !obj || !obj->in_room
        || obj->in_room->vnum < 1 )
    {
        bugf("do_objectgate: obj->in_room->vnum == 0 (%s)", STR(obj,name));
        send_to_char("You cannot create a rift to that.\n\r",ch);
        return;
    }
    else
        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 ( has_mana(ch, MCOR, 3, 3, 2000 ) )
    {
        stc("You must obtain a level three mastery of Correspondence to use Astral Gateways.\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 ( ch == victim)
    {
        stc("Why you wanna mgate to your self?,\n\r", ch);
        return;
    }
    if ( !str_cmp(arg2, "pull" ) )
    {
        if ( has_mana( ch, MCOR, 4, 4, 3000 ) )
        {
            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;
        WAIT_STATE(ch,35);
    }

  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;
      }

      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 > 2000 )
    {
        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;
    }

	if( IS_SET(victim->in_room->room_flags, ROOM_NO_TELEPORT ) )
        {
            send_to_char( "You failed.\n\r", ch );
            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);
    }

    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,victim) )
            return;

        char_from_room(victim);
        char_to_room( victim, ch->in_room );
        if( IS_SET(ch->affected_by, AFF_SHADOWPLANE )
            && !IS_SET(victim->affected_by, AFF_SHADOWPLANE ) )
            SET_BIT( victim->affected_by, AFF_SHADOWPLANE );
        else if( !IS_SET(ch->affected_by, AFF_SHADOWPLANE )
                 && IS_SET(victim->affected_by, AFF_SHADOWPLANE ) )
            REMOVE_BIT( victim->affected_by, AFF_SHADOWPLANE );

        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);
    }

    return;
}

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

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MCOR, 5, 5, 3000) )
    {
        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 damage;

  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 ( has_mana( ch, MFOR, 1, 1, 1200 ) ) 
  {
    stc("You must have a level one knowledge of the Forces to discharge Static Electricity.\n\r",ch);
    return;
  }
  
  if ( is_safe_room( ch->in_room ) )
  {
	stc( "Not in a safe room.\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 ) )
    {
	stc("They are safe from your attacks.\n\r", ch);
	return;
    }

    WAIT_STATE(ch,36);
    damage = number_range(ch->spheres[MFOR] * 100,ch->spheres[MFOR] * 120);
    damage += 10000;
    if ( weather_info.sky == SKY_LIGHTNING )
      damage += number_range(100,130)*10;
    if ( weather_info.sky == SKY_RAINING )
      damage -= number_range(300,350)*10;

    mage_damage(ch, victim, damage, "electricity burst", MAGEDAM_ELECTRIC);
  }
  else
  {
      damage = number_range(ch->spheres[MFOR] * 100,ch->spheres[MFOR] * 120);
      damage += 7000;
      if ( weather_info.sky == SKY_LIGHTNING )
          damage += number_range(100,130)*5;
      if ( weather_info.sky == SKY_RAINING )
          damage -= number_range(300,350)*5;

      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 ( vch != ch )
              mage_damage( ch, vch, damage, "electricity burst", MAGEDAM_ELECTRIC );
      }
  }

  return;

}

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

  if ( !is_mage(ch) ) return;

  if ( has_mana( ch, MFOR, 2, 2, 0 ) )
  {
      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 ( has_mana( ch, MFOR, 3, 3,1500 ) )
    {
        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;
    }

    if( is_safe_room( ch->in_room ) )
    {
	stc( "Not in a safe room.\n\r", ch);
	return;
    }

    if( is_safe( ch, victim ) )
    {
	stc( "They are safe from your attacks.\n\r", ch );
	return;
    }
    WAIT_STATE(ch, 4);
    dam = number_range( (ch->spheres[MFOR]*150),(ch->spheres[MFOR]*200) );
    dam += 3000;

    mage_damage(ch, victim, dam, "lightning blast", MAGEDAM_ELECTRIC);
    mage_damage(ch, victim, dam, "lightning blast", MAGEDAM_ELECTRIC);    
    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_CLASS(ch, CLASS_MAGE) )
    {
        stc("Huh\n\r",ch);
        return;
    }
    if ( has_mana( ch, MFOR, 3, 3, 1000 ) )
    {
        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\r"
            "     Syntax: controlweather <rain,lightning,clear>\n\r",ch);
        return;
    }

    WAIT_STATE(ch, 6);
    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\r"
            "   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 ( has_mana( ch, MFOR, 4, 4, 1000 ) )
    {
        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 ( 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, 12);
    return;
}

void do_tempest( CHAR_DATA *ch, char *argument )
{
  CHAR_DATA *victim;
  CHAR_DATA *vch;
  CHAR_DATA *vch_next;
  ROOM_INDEX_DATA *chroom;
  ROOM_INDEX_DATA *victimroom;
  
  char arg[MAX_INPUT_LENGTH];
  int dam;

  argument = one_argument( argument, arg );

  if ( IS_NPC(ch) ) return;

  if ( !is_mage(ch) ) return;

  if ( has_mana(ch,MFOR,5,5,7000) )
  {
    stc("You must master the Forces to use Tempest Blizzard.\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_world( 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 ( victim->in_room->area != ch->in_room->area )
  {
    stc("You locate your victim, but they are too distant.\n\r",ch);
    return;
  }

  chroom = ch->in_room;
  victimroom = victim->in_room;
    if( is_safe_room( victimroom ) 
	|| is_safe_room( chroom ) )
    {
	stc( "Not in a safe room.\n\r", ch);
	return;
    }

  WAIT_STATE(ch, 24);
  char_from_room(ch);
  char_to_room(ch, victimroom);
  act("{yYou call upon the Forces of Nature to obliterate $N.{n",ch,NULL,victim,TO_CHAR);
  act("{WThe sky turns an ominous white.\n\r{n..."
      "{cSeconds later, deadly shards of ice shoot out of the sky, piercing your skin.",ch,NULL,victim,TO_VICT);

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

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

      if ( vch->in_room == ch->in_room )
      {
          if ( vch->level < 3 ) continue;
	   
          if ( vch != ch && !is_safe( ch, vch ) )
          {
              dam = number_range(350,450);
              if ( vch == victim )
                  dam += number_range( 50,100 );
	      dam += 4000;
              mage_damage( ch, vch, dam, "ice shards", MAGEDAM_ICESTORM );
          }

          continue;
      }

      if ( vch->in_room->area == ch->in_room->area
           && IS_OUTSIDE(vch)
	&& IS_AWAKE(vch) )
        stc( "{CShards of deadly ice fall from the sky.{x\n\r", vch );
  }
  
  char_from_room(ch);
  char_to_room(ch, chroom);
  return;
}


void update_mdamcap( CHAR_DATA *ch, CHAR_DATA *victim )
{
    int max_dam =  3000;

    if( IS_NPC(ch) )
        max_dam += ch->level * 100;
    else
    {
        max_dam += ( 400 * ch->spheres[MENT] );
        max_dam += ( 400 * ch->spheres[MPRI] );
        max_dam += get_curr_int(ch) * 50;

        if ( IS_ITEMAFF(ch, ITEMA_ARTIFACT)) max_dam += 500;
        if ( IS_ITEMAFF(victim, ITEMA_ARTIFACT)) max_dam -= 500;
    }


    if ( max_dam < 1000 )
        max_dam = 1000;
    else if ( max_dam > 20000 )
        max_dam = 20000;
    ch->damcap[DAM_CAP] = max_dam;
    ch->damcap[DAM_CHANGE] = 0;
    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, int type )
{
  if ( IS_NPC(ch) ) return dam;

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

  else if ( is_resistant( ch, type ) )
    dam /= 2;

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

  return dam;
}

void mage_damage( CHAR_DATA *ch, CHAR_DATA *victim,
                  int dam, const char *message, int type )
{
    int max_dam;


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

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


    max_dam = ch->damcap[DAM_CAP];

    if ( dam > max_dam )
        dam = max_dam;

    if ( victim != ch )
    {
        if ( is_safe( ch, victim ) )
            return;
        check_killer( ch, victim );

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

        if ( victim->position > POS_STUNNED )
        {
            if ( ch->fighting == NULL )
                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 *= 1.5;
                send_to_char("You use your concealment to get a surprise attack!\n\r",ch);
            }
            REMOVE_BIT( ch->affected_by, AFF_HIDE );
            act( "$n leaps from $s concealment.", ch, NULL, NULL, TO_ROOM);
        }

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

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

        if( IS_ITEMAFF(victim,ITEMA_RESISTANCE) )
	    dam *= 0.5;


        if ( dam < 0 )
            dam = 0;
        else
            dam = mage_immunity( victim, dam, type );
        // Take care of the new stats
    	if( !IS_NPC(victim) )
	        dam -= get_curr_wis(victim) * 10;
	else
		dam -= get_curr_wis(victim) * 2;

        if ( dam < 0 )
            dam = 0;

        mage_message( ch, victim, dam, message, type );
        hurt_person(ch,victim,dam,FALSE);
        if( IS_CLASS(ch,CLASS_MAGE) )
            update_damcap(ch,victim);
        return;
  }
  else
  {
      if( IS_CLASS(ch,CLASS_MAGE) )
          update_damcap(ch,victim);
      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 <= 500 ) {  chm = " graze";       victm = " grazes";     }
    else if ( dam <= 1000) {  chm = " wound";       victm = " wounds";     }
    else if ( dam <= 2000) {  chm = " mutilate";    victm = " mutilates";  }
    else if ( dam <= 3000) {  chm = " massacre";    victm = " massacres";  }
    else if ( dam <= 4000) {  chm = " eviscerate";  victm = " eviscerates";}
    else if ( dam <= 5000) {  chm = " annihilate";  victm = " annihilates";}
    else if ( dam <= 6000) {  chm = " obliterate";  victm = " obliterates";}
    else if ( dam <= 8000) {  chm = " dissipate";   victm = " dissipates"; }
    else if ( dam <= 10000){  chm = " vaporize";    victm = " vaporizes";  }
    else                   {  chm = " liquify";     victm = " liquifies";  }

    if ( !IS_NPC(victim) && ( victim->hit - dam ) < 0 )
    {
        if ( type == MAGEDAM_ELECTRIC )
        {
            act("{CYour electric shock causes $N to spasm violently and vomit blood.{x",ch,NULL,victim,TO_CHAR);
            act("{C$n's electric shock causes $N to spasm violently and vomit blood.{x",ch,NULL,victim,TO_NOTVICT);
            act("{C$n's electric shock causes your body to spasm violently as you vomit blood.{x",ch,NULL,victim,TO_VICT);
            make_part(victim,"blood");
        }
        else if ( type == MAGEDAM_ICESTORM )
        {
            act("{cYour ice shards tear $N's flesh from $S body and leave $M mortally wounded.{x",ch,NULL,victim,TO_CHAR);
            act("{c$n's ice shards tear $N's flesh from $S body and leave $M mortally wounded.{x",ch,NULL,victim,TO_NOTVICT);
            act("{c$n's ice shards tear your flesh from your body and leave you mortally wounded.{x",ch,NULL,victim,TO_VICT);
            make_part(victim,"blood");
        }
        else
        {
            act("{YYour magical energy tears $N's body asunder.{x",ch,NULL,victim,TO_CHAR);
            act("{Y$n's magical energies tear $N's body asunder.{x",ch,NULL,victim,TO_NOTVICT);
            act("{Y$n's magical energies tear your body asunder.{x",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
    {
        if ( ch->spheres[MFOR] > 1 )
        {
            sprintf(damm,"%d",dam);
            ADD_COLOUR(ch, damm, D_RED);
            sprintf(dam2,".[%s]",damm);
        }
        else
            sprintf(dam2,".");

        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.", victm, message);
    }

    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) || !ch->pcdata ) return;

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MPRI, 1, 1, 0 ) )
    {
        stc("You cannot store Quintessence until you have learned level 1 Prime.\n\r",ch);
        return;
    }

    argument = one_argument( argument, buf );

    if( buf[0] != '\0' && !str_prefix( buf, "buy" ) )
    {
        int body_cost = ch->quint[BODY];
	if( ch->fighting )
	{
	    stc( "You cannot buy quintessence while fighting.\n\r", ch );
	    return;
	}

        if( ch->quint[BODY] > 40 )
        {
            stc( "You can not buy anymore quintessence.\n\r",ch);
            return;
        }
        if( body_cost > PC(ch,stats[DEMON_CURRENT]) )
        {
	    ch_printf(ch,"It will cost you %d class points to raise your quin by 1.\n\r", body_cost );
            return;
        }
        PC(ch,stats[DEMON_CURRENT]) -= body_cost;
        ch->quint[BODY]++;
        ch->quint[MTOTAL]++;
        stc("You begin to draw more of the natural energy around you into your being.\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 )
{
  int max;
  if( PC(ch,stats[UNI_GEN] ) >= 3 ) max = 2;
  else if( PC(ch,stats[UNI_GEN]) >= 2 ) max = 4;
  else if( PC(ch,stats[UNI_GEN]) >= 1 ) max = 6;
  else max = 0;

  ch->quint[MTOTAL] = check_quint(ch);   // Find Total Quint of Char
  ch->quint[MTOTAL] -= number;           // Subtract from Max
  if( ch->quint[MTOTAL] >= max )   // Oonly do alterations if quin is
  {                                // higher then max
     if( ch->quint[AVATAR] >= number ) // First check avatar.
     {
	ch->quint[AVATAR] -= number;
     }
     else if( ch->quint[BODY] >= number )
     {
	ch->quint[BODY] -= number;
     }
     else
     {
	int x;
	ch->quint[AVATAR] -= number;
	x = ch->quint[AVATAR];
	if( x > 0 || ch->quint[BODY] < x )
	    return;
	ch->quint[BODY] += x;
     }
  }
	
  return;
}

int  get_maxq( CHAR_DATA *ch )
{
  int max;
  if( PC(ch,stats[UNI_GEN] ) >= 3 ) max = 2;
  else if( PC(ch,stats[UNI_GEN]) >= 2 ) max = 4;
  else if( PC(ch,stats[UNI_GEN]) >= 1 ) max = 6;
  else max = 0;
  max += ch->spheres[MPRI];
  return max;
}

void add_quint( CHAR_DATA *ch, int number )
{
  int max;
  if( PC(ch,stats[UNI_GEN] ) >= 3 ) max = 2;
  else if( PC(ch,stats[UNI_GEN]) >= 2 ) max = 4;
  else if( PC(ch,stats[UNI_GEN]) >= 1 ) max = 6;
  else max = 0;

  ch->quint[MTOTAL] = check_quint(ch);
  ch->quint[MTOTAL] += number;
 
  if ( ch->quint[MTOTAL] > max )
  {
    ch->quint[AVATAR] = max;
    ch->quint[MTOTAL] -= max;
    if ( ch->quint[MTOTAL] > max )
    {
      ch->quint[BODY] = max;
      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 ( has_mana( ch, MPRI, 2, 2, 2000 ) )
  {
      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]*4);
  obj->value[2] += (ch->spheres[MPRI]*4);
  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;
}

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 ( has_mana( ch, MPRI, 3, 3, 2000 ) )
    {
        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( is_safe_room( ch->in_room ) )
    {
	stc( "Not in a safe room.\n\r", ch);
	return;
    }

    if( is_safe( ch, victim ) )
    {
	stc( "You cannot attack them.\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] * 150;
    dam += 1000;
    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 ( has_mana( ch, MPRI, 4, 4, 0) )
  {
      stc("You must obtain level three 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;
  }

    if( is_safe_room( ch->in_room ) )
    {
	stc( "Not in a safe room.\n\r", ch);
	return;
    }
    if( is_safe( ch, victim ) )
    {
	stc( "You cannot attack them.\n\r", ch );
	return;
    }
  subtract_quint(ch, 3);
  dam = ch->spheres[MPRI] * 200;
  dam += 3000;
  mage_damage(ch,victim,dam,"flames of purification",MAGEDAM_QUINT);
  mage_damage(ch,victim,dam,"flames of purification",MAGEDAM_QUINT);  
  WAIT_STATE(ch, 8);
  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 ( has_mana( ch, MPRI, 5, 5, 2500 ) )
  {
      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 ( victim->level < 3 )
  {
      stc("They must be an avatar!\n\r",ch);
      return;
  }

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

    if( is_safe_room( ch->in_room ) )
    {
	stc( "Not in a safe room.\n\r", ch);
	return;
    }
    if( is_safe( ch, victim ) )
    {
	stc( "You cannot attack them.\n\r", ch );
	return;
    }

  subtract_quint(ch, 5);
  dam = ch->spheres[MPRI] * 1500;

  mage_damage(ch,victim,dam,"quintessence blast",MAGEDAM_QUINT);
  mage_damage(ch,victim,dam,"quintessence blast",MAGEDAM_QUINT);
  mage_damage(ch,victim,dam,"quintessence blast",MAGEDAM_QUINT);  
  if( IS_NPC(victim) )
	WAIT_STATE(ch, 4 );
  else
	WAIT_STATE(ch, 12);
  return;
}

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

  if ( !is_mage(ch) ) return;

  if ( has_mana( ch, MENT, 1, 1, 0 ) )
  {
      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 ( has_mana( ch, MLIF, 1, 1, 1000) )
  {
      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]*200);
  ch->mana += (ch->spheres[MLIF]*100);
  ch->move += (ch->spheres[MLIF]*100);
  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;
  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 ( has_mana( ch, MLIF, 2, 2, 2000 ) )
  {
    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 ( has_mana( ch, MLIF, 3, 3, 3000 ) )
  {
    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;
      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 ( has_mana( ch, MLIF, 4, 4, 4000 ) )
    {
        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 ( has_mana( ch, MLIF, 1, 1, 1000 ) )
    {
        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 )
{
    OBJ_DATA *obj;
    CHAR_DATA *vch;
    char arg[MIL];

    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' )
    {
        stc("Analyze which object?\n\r",ch);
        return;
    }

    obj = get_obj_carry( ch, arg );
    vch  = get_char_room( ch, arg );
    if ( obj == NULL && !vch)
    {
        stc("You can't analyze that.\n\r",ch);
        return;
    }

    if( vch )
    {
        act("You analyze the substance pattern of $n.",ch,NULL,vch,TO_CHAR);
        readaura( ch, vch );
        return;
    }
    else if( obj )
    {
        act("You analyze the substance pattern of $p.",ch,obj,NULL,TO_CHAR);
        (*skill_table[skill_lookup("identify")].spell_fun) (skill_lookup("identify"), 50, ch, obj );
        return;
    }
    else
    {
        stc("You can't analyze that.\n\r",ch);
        return;
    }

    return;
}

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

    argument = one_argument( argument, arg );

    if ( IS_NPC(ch) ) return;

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MMAT, 2, 2,0 ) )
    {
        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 )
        {
            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;
    }

    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, 2 );
    WAIT_STATE(ch, 4);
    return;
}

void do_alterweight( 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 ( has_mana( ch,MMAT, 3, 3, 0 ) )
    {
        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;
    }

    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];
    bool train = FALSE;
    argument = one_argument( argument, arg );

    if ( IS_NPC(ch) ) return;

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MMAT, 4, 4, 0 ) )
    {
        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;
    }

    argument = one_argument( argument, arg );

    if( arg[0] != '\0' && !str_cmp( arg, "train" ) )
        train = TRUE;

    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;
    if( train )
    {
        paf->location = APPLY_HIT;
        if( ch->spl[TAR_OBJ_INV] > 339 )
            paf->modifier = -500;
        else if( ch->spl[TAR_OBJ_INV] > 300 )
            paf->modifier = -400;
        else if( ch->spl[TAR_OBJ_INV] > 200 )
            paf->modifier = -200;
        else
            paf->modifier = -100;
    }
    else
    {
        paf->location       = APPLY_HITROLL;
        if( ch->spl[TAR_OBJ_INV] > 200 )
            paf->modifier = 5;
        else
            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;
    if( train )
    {
        paf->location = APPLY_MANA;
        if( ch->spl[TAR_OBJ_INV] > 339 )
            paf->modifier = -500;
        else if( ch->spl[TAR_OBJ_INV] > 300 )
            paf->modifier = -400;
        else if( ch->spl[TAR_OBJ_INV] > 200 )
            paf->modifier = -200;
        else
            paf->modifier = -100;
    }
    else
    {

        paf->location       = APPLY_DAMROLL;
        if( ch->spl[TAR_OBJ_INV] > 200 )
            paf->modifier = train ? -5 : 5;
        else
            paf->modifier       = train ? -3 : 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 ( has_mana( ch, MMAT, 5, 5, 0 ) )
  {
      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 ( has_mana( ch, MMIN, 5, 5, 0 ) )
  {
      stc("You must obtain level five Mind to use Untether.\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;

    if ( IS_NPC(ch) ) return;

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MSPI, 1, 1, 1000 ) )
    {
        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);

    ch->pcdata->followers++;
    victim=create_mobile( get_mob_index( MOB_VNUM_GUARDIAN ) );
    free_string( victim->name );
    victim->name = str_dup("spirit");
    free_string( victim->short_descr );
    victim->short_descr = str_dup("A wicked spirit");
    free_string( victim->long_descr );
    victim->long_descr = str_dup("A ghostly image hovers over the ground here.");
    victim->level = 200;
    victim->hit = ch->hit/2;
    victim->max_hit = 5000;
    victim->hitroll = 1550;
    victim->damroll = 1550;
    victim->armor = 300;
    SET_BIT(victim->act, ACT_NOEXP);
    char_to_room( victim, ch->in_room );
    add_follower( victim, ch );
    af.duration  = 666;
    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 ( has_mana( ch, MSPI, 2, 2, 0 ) )
  {
      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]*5);
  if ( ch->spheres[MENT] >= 1 )
      level +=ch->spl[skill_table[sn].target]*(.25+(ch->spheres[MENT]*.1));

  (*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 ( has_mana( ch, MSPI, 4, 4, 0 ) )
    {
        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;
    }

    if( is_safe_room( ch->in_room) || is_safe( ch, victim ) )
    {
	stc( "Not in a safe room!\n\r", ch );
	return;
    }

    if( IS_AFFECTED( ch, AFF_ETHEREAL ) )
    {
	stc("You cannot do this on someone ethereal.\n\r", ch );
	return;
    }

    dam = ch->spheres[MSPI] * 50;
    mage_damage(ch, victim, dam, "spirit blast", MAGEDAM_OTHER);
    dam *= 100;
    victim->mana = UMAX( 0, victim->mana-dam );	    
    victim->move = UMAX( 0, victim->move-dam );
    ch->mana = UMAX( ch->mana+dam, ch->max_mana );
    ch->move = UMAX( ch->move+dam, ch->max_move );
    stc("You absorb the energy from the blast.\n\r",ch);
    stc("You feel drained.\n\r",victim);
    WAIT_STATE(ch, 24);
    return;
}

void do_breach( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *vch;
    CHAR_DATA *vch_next;
    CHAR_DATA *mount;
    bool shadow = FALSE;

    if ( IS_NPC(ch) )
    {
        stc("Npc's may not breach.\n\r",ch);
        return;
    }

    if ( !is_mage(ch) )
    {
	stc("Only mages may use this.\n\r", ch );
	 return;
    }

    if ( has_mana( ch, MSPI, 5, 5, 0 ) )
    {
        stc("You must obtain level 5 Spirit to Breach the Gauntlet.\n\r",ch);
        return;
    }

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

    if( IS_SET(ch->affected_by, AFF_SHADOWPLANE) )
        shadow = TRUE;

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

            if (can_see(ch,vch))
            {
                if( !shadow )
                {
                    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);
                }
                else
                {
                    act("$n's eyes turn bright white\n\r"
                        "The room is torn apart before your very eyes, and reformed in front of you.",ch,NULL,vch,TO_VICT);
                    REMOVE_BIT(vch->affected_by, AFF_SHADOWPLANE);
                }
            }
    }
    if( !shadow )
        SET_BIT(ch->affected_by, AFF_SHADOWPLANE);
    else
        REMOVE_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;

}

void do_mshield( CHAR_DATA *ch, char * argument )
{
    char arg[MAX_INPUT_LENGTH];
    int type;

    if ( IS_NPC(ch) ) return;

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MENT, 3, 3, 1600 ) )
    {
        stc("You do not poses enough knowledge to cast this.\n\r", ch );
        return;
    }

    argument = one_argument( argument, arg );
    if( arg[0] == '\0' )
    {
        stc("What type of shield do you wanna raise.\n\r", ch );
        return;
    }
    
    if( !str_prefix( arg, "blades" ) )
        type = mBLADE;
    else if( !str_prefix( arg, "chaos" ) )
        type = mCHAOS;
    else if( !str_prefix( arg, "prismatic" ) )
        type = mPRIS;
    else
    {
        stc( "What type of shield do you wanna raise.\n\r", ch );
        return;
    }
    

    ch->mageshields[type][mON] = TRUE;
    ch->mageshields[type][mTIME] = (11 * PULSE_TICK );

    switch( type )
    {
    case mBLADE:
        stc("You are covered in deadly spinning {Rblades{n.\n\r", ch );
        break;
    case mCHAOS:
        stc("You are surrounded by a {echaotic{n force.\n\r", ch );
        break;
    case mPRIS:
        stc("You are surrounded by a {pPrismatic{n barrier.\n\r", ch );
        break;
    }
    return;
}


void spheres( CHAR_DATA * ch )
{
    BUFFER *buf = buffer_new( MAX_STRING_LENGTH );
    char * dark;
    char * bright;
    
    switch( PC(ch,powers[MPOWER_RUNE0]) )
    {
    default:
    case PURPLE_MAGIC:  dark = "{m"; bright = "{M"; break;
    case RED_MAGIC:     dark = "{r"; bright = "{R"; break;
    case BLUE_MAGIC:    dark = "{b"; bright = "{B"; break;
    case GREEN_MAGIC:   dark = "{g"; bright = "{G"; break;
    case YELLOW_MAGIC:  dark = "{y"; bright = "{Y"; break;
    }

    bprintf(buf,"%s*%s------------------------------------------------------------------------------%s*\n\r", bright, dark, bright );
    bprintf(buf,"%s|                                  %s({WSPHERES%s)                                   %s|\n\r", dark, bright, bright, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WPower:               %s| {WSphere   %s| {WCommand:  %s| {WWhat it does                   %s|\n\r", dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WPerception           %s| {WCorres 1 %s| {Wpercept   %s| {WGives you true sight           %s|\n\r", dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WGateway to Living    %s| {WCorres 3 %s| {Wmgate     %s| {WCreate portal to a mob/player  %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WGrasp of Elminster   %s| {WCorres 4 %s| {Wpull      %s| {W\"pull\" target through a rift   %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WEternal Gateway      %s| {WCorres 4 %s| {Wperminant %s| {Wmakes a rift perminant         %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WPolyappearance       %s| {WCorres 5 %s| {Wpolyappea %s| {WImproves combat ability        %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WDimmak               %s| {WEntrop 1 %s| {Wdimmak    %s| {WImproves combat ability        %s|\n\r",  dark, dark, dark,dark, dark );
    bprintf(buf,"%s| {WArcane Mastery       %s| {WEntrop 2 %s| {Wmshield   %s| {Wmshield chaos, pris, blade     %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WQuintessence         %s| {WPrime  1 %s| {Wquintesse %s| {WShow/Buy Quintessence          %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WEnchant              %s| {WPrime  2 %s| {Wenchant   %s| {WRaise a weapons Average damage %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WRubbing of the Bones %s| {WPrime  3 %s| {Wrubbing   %s| {WCauses damage                  %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WFlames of Purificati %s| {WPrime  4 %s| {Wpurificat %s| {WDamage spell                   %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WQuintessence Blast   %s| {WPrime  5 %s| {Wqblast    %s| {WDamage spell                   %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WHotienchi            %s| {WLife   1 %s| {Whotienchi %s| {WRepair your body and heal      %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WLittle Death         %s| {WLife   2 %s| {Wlittledea %s| {WInstant kill                   %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WBeterbody            %s| {WLife   3 %s| {Wbetterbod %s| {WIncrease your size             %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WShapechange          %s| {WLife   4 %s| {Wshapechan %s| {WChange shapes (polymorph)      %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WLayhands             %s| {WLife   5 %s| {Wlayhands  %s| {WBetter heal                    %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WAnalyze Substance    %s| {WMatter 1 %s| {Wanalyze   %s| {WId an object, or Read Aura     %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WAlter State          %s| {WMatter 2 %s| {Walterstat %s| {WOppenant drops weapon          %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WAlter Weight         %s| {WMatter 3 %s| {Walterweig %s| {WChange the weight to lighter   %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WEnchant Armor        %s| {WMatter 4 %s| {Wenchanta  %s| {WEnchant a piece of armor       %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WHover                %s| {WMatter 5 %s| {Whover     %s| {WFly over trips                 %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WCall Spirit          %s| {WSpirit 1 %s| {Wcallspiri %s| {WCall a familar to your side    %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WSpirit Kiss          %s| {WSpirit 2 %s| {Wspiritkis %s| {WDamage                         %s|\n\r",  dark, dark, dark, dark,dark );
    bprintf(buf,"%s| {WAwaken the Undead    %s| {WSpirit 3 %s| {Wawaken    %s| {WCreate a Zombie                %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WSpirit Blast         %s| {WSpirit 4 %s| {Wspiritbla %s| {WDamage                         %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WBreach the Gauntlet  %s| {WSpirit 5 %s| {Wbreach    %s| {WBring room into/outof shadows  %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WShield               %s| {WMind   1 %s| {Wshield    %s| {WShield your stats from others  %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WSubliminal Impulse   %s| {WMind   2 %s| {Wimpulse   %s| {WCommand someone else           %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WProbe thoughts       %s| {WMind   3 %s| {Wprobe     %s| {WWhatch what this person types  %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WPossesion            %s| {WMind   4 %s| {Wposs      %s| {WWatch what this person sees    %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WUntether             %s| {WMind   5 %s| {Wunteather %s| {WEnter/Exit the shadow plain    %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WManaShield           %s| {WMind   5 %s| {WManaShiel %s| {WCreate a ManaShield            %s|\n\r",dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s----------%s*%s-----------%s*%s--------------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s|                               %s({WMULTI SPHERES%s)                                %s|\n\r", dark, bright, bright, dark );
    bprintf(buf,"%s*%s----------------------%s*%s---------------%s*%s-----------%s*%s---------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s| {WConsecrate Circle    %s| {MSp 3 Mt 3     %s| {Wconsecrat %s| {WMakes current room safe   %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WFear                 %s| {MSp 4 Mi 2     %s| {WFear      %s| {WMakes vicitm flee         %s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s| {WSolidify Spirit      %s| {MMa 3 Pr 3     %s| {WN/A       %s| {WMakes spirit guardian buff%s|\n\r",  dark, dark, dark, dark, dark );
    bprintf(buf,"%s*%s----------------------%s*%s---------------%s*%s-----------%s*%s---------------------------%s*\n\r", bright, dark, bright, dark, bright, dark, bright, dark, bright, dark );
    bprintf(buf,"%s|                                                                              |\n\r", dark );
    bprintf(buf,"%s*%s------------------------------------------------------------------------------%s*\n\r", bright, dark, bright );
    page_to_char( buf->data, ch );
    buffer_free( buf );
    return;
}
              
void do_consecrate( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA * rch;
    ROOM_AFFECT_DATA raf;
    ROOM_INDEX_DATA  *pRoom;
    int rn;

    if ( IS_NPC(ch) ) return;

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MSPI, 6, 3, 0 ) 
      || has_mana( ch, MMAT, 6, 3, 0 ) )
    {
        stc("You must achive 6 arete, 3 spirit, and 3 matter to consecrate the circle.\n\r", ch );
        return;
    }
    if( is_inarena( ch, ch ) )
	return;

    if( ch->fight_timer > 0 )
    {
        stc("You can not concescrate this circle with a fight timer.\n\r",ch);
        return;
    }

    if ( !(pRoom = ch->in_room ) || IS_SET( pRoom->affected_by, ROOM_SAFE ) )
    {
        stc("You are unable to consecrate a circle here.\n\r", ch);
        return;
    }

    if( ( rn = raffect_lookup( "con_circle" ) ) < 0 )
    {
        ch_printf( ch, "Bad room_affect lookup for con_circle.  Inform immortals.\n\r" );
        return;
    }

    raf.type = rn;
    raf.level = ch->level;
    raf.duration = 10;
    raf.bitvector = ROOM_SAFE;
    raf.caster    = ch;
    raf.applies_spell = -1;
    raf.modifier  = -1;
    raf.location  = -1;
    affect_to_room( pRoom, &raf );

    for (rch = ch->in_room->people; rch != NULL; rch = rch->next_in_room)
    {
        if (rch->fighting != NULL)
            stop_fighting(rch, TRUE);
    }
    return;
}

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

    if( IS_NPC(ch) ) return;
	
    if( !is_mage(ch) ) 
    {
	stc( "Huh?\n\r", ch );
	return;
    }

    if( ( sn = skill_lookup( "manashield" )) < 1 )
    {
	stc( "Inform immortal that manshield does not exhist.\n\r", ch);
	return;
    }

    if ( is_affected( ch, sn ) )
    {
	send_to_char("Nothing happens.\n\r",ch);
	return;
    }

    af.type      = sn;
    af.duration  = 52;
    af.modifier  = 0;
    af.location  = 0;
    af.bitvector = 0;
    affect_to_char( ch, &af );

    stc( "A shimmering blue glow surrounds you.\n\r", ch );
    act( "A shimmering blue glow surrounds $n.\n\r", ch, NULL, NULL, TO_ROOM );
    return;
}
     
void do_warfear( CHAR_DATA *ch, char *argument )
{
    CHAR_DATA *victim;
    char arg[MIL];

    if ( IS_NPC(ch) ) return;

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MSPI, 6, 4, 0 ) 
      || has_mana( ch, MMIN, 6, 4, 0 ) )
    {
        stc("You must achive 6 arete, 4 spirit, and 2 mind to instill fear.\n\r", ch );
        return;
    }
    argument = one_argument( argument, arg );
    
    if( arg[0] == '\0' )
    {
        stc("Who do you wish to instill fear into.\n\r",ch);
        return;
    }
    victim = get_char_room( ch, arg );

    if( !victim )
    {
        stc("Who do you wish to instill fear into.\n\r",ch);
        return;
    }

    if( check_quint(ch) < 4 )
    {
        stc("You need atleast 3 quintessence to cast this.\n\r",ch);
        return;
    }

    WAIT_STATE(ch,12);
    if( get_curr_int(ch) < get_curr_int(victim)
        && number_percent() < 70 )
    {
        return;
    }
    subtract_quint(ch,3);
    do_flee(victim,"");
    return;
}
void do_overcome( CHAR_DATA *ch, char * argument )
{
    CHAR_DATA *victim;
    char arg[MIL];

    if ( IS_NPC(ch) ) return;

    if ( !is_mage(ch) ) return;

    if ( has_mana( ch, MSPI, 10, 3, 0 )
      || has_mana( ch, MMIN, 10, 3, 0 )
      || has_mana( ch, MLIF, 10, 3, 0 )
      || has_mana( ch, MPRI, 10, 1, 0 ) )
    {
        stc("You must achive 10 arete, 4 spirit, and 2 mind to overcome your master.\n\r", ch );
        return;
    }
    argument = one_argument( argument, arg );

    if( arg[0] == '\0' )
    {
        stc("Who do you wish to overcome.\n\r",ch);
        return;
    }
    victim = get_char_room( ch, arg );

    if( !victim )
    {
        stc("Who do you wish to overcome.\n\r",ch);
        return;
    }

    if( IS_NPC(victim) || PC(victim,rank) <= PC(ch,rank) )
    {
        ch_printf( ch, "%s is not your master.\n\r", capitalize(victim->name));
        return;
    }
    
    if( victim->position > 1 )
    {
        ch_printf( ch, "%s is not mortally wounded.\n\r",
                   capitalize(victim->name) );
        return;
    }

    PC(victim,rank)--;
    PC(ch,rank)++;
    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 );
    ch_printf( ch, "You have overcome %s.\n\r", capitalize(victim->name));
    act( "With a flick of a wrist a golden amulet is transfered from $N to $n.\n\r",
         ch, NULL, victim, TO_ROOM );
    ch_printf( victim, "%s has beaten you.\n\r", capitalize(ch->name));
    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_mage(ch) )
    {
        send_to_char("Huh?\n\r",ch);
        return;
    }

    if (GET_GEN(ch) > WRL_MASTER )
    {
	stc("Only Master Warlocks can promote a warmage.\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 a warmage!!\n\r",ch);
        return;
    }

    if ( GET_GEN(victim) < 3 )
    {
	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 warmages!\n\r", ch );
	return;
    }

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

    if( PC(ch,powers[MPOWER_RUNE0]) != PC(victim,powers[MPOWER_RUNE0]) )
    {
	ch_printf( ch, "You are not %s's rubicant.\n\r", victim->name );
	return;
    }

    PC(victim,stats[UNI_GEN])--;
    ch_printf( ch, "%s is now a warlock.\n\r", victim->name );
    ch_printf( victim, "You are now a warlock.\n\r" );
    return;
}