/
vortex/area/
/***************************************************************************
 *  Original Diku Mud copyright (C) 1990, 1991 by Sebastian Hammer,        *
 *  Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, and Katja Nyboe.   *
 *                                                                         *
 *  Merc Diku Mud improvments copyright (C) 1992, 1993 by Michael          *
 *  Chastain, Michael Quan, and Mitchell Tse.                              *
 *                                                                         *
 *  In order to use any part of this Merc Diku Mud, you must comply with   *
 *  both the original Diku license in 'license.doc' as well the Merc       *
 *  license in 'license.txt'.  In particular, you may not remove either of *
 *  these copyright notices.                                               *
 *                                                                         *
 *  Much time and thought has gone into this software and you are          *
 *  benefitting.  We hope that you share your changes too.  What goes      *
 *  around, comes around.                                                  *
 ***************************************************************************/

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


void drowgrant( CHAR_DATA *ch, char *argument )
{
 CHAR_DATA *victim;
 char arg1[MAX_INPUT_LENGTH];
 char arg2[MAX_INPUT_LENGTH];
 int inpart = 0;
 int cost = 0;

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

 if( IS_NPC(ch) )
  return;
 if( !IS_CLASS(ch,CLASS_DROW) )
 {
  do_huh(ch,"");
  return;
 }

 if( arg1[0] == '\0' || arg2[0] == '\0' )
 {
  stc("Syntax: Grant <person> <power>\n\r",ch);
  stc("Warrior      (0)         Mage         (0)         Cleric     (0)\n\r",ch);  
  stc("Drowfire     (2,500)     Darkness     (7,500)     Drowpoison (2,500)\n\r",ch);
  stc("Speed        (7,500)     Drowshield   (5,000)     Levitation (1,000)\n\r",ch);
  stc("Scry         (10,000)    Garotte      (5,000)     Spiderarms (7,500)\n\r",ch);
  stc("Drowhate     (10,000)    Spiderform   (15,000)    Web        (5,000)\n\r",ch);
  stc("Dgarotte     (2,500)     Earthshatter (7,500)     Toughskin  (7,500)\n\r",ch);
  return;
 }

 if( (victim = get_char_world(ch,arg1)) == NULL )
 {
  stc("Nobody by that name.\n\r",ch);
  return;
 }

 if( IS_NPC(victim) )
 {
  stc("Not on NPC's.\n\r",ch);
  return;
 }

 if( !IS_CLASS(victim,CLASS_DROW) )
 { 
  stc("Only on Drow.\n\r",ch);
  return;
 }

 if( !str_cmp(arg2,"mage") || !str_cmp(arg2,"warrior") || !str_cmp(arg2,"cleric") )
 {
  if( victim->generation > 3 )
  {
   stc("They are not worthy enough of such an honor!\n\r",ch);
   return;
  }

  if( IS_SET(GET_POWERS(victim,DROW_BITS),DROW_WAR)
   || IS_SET(GET_POWERS(victim,DROW_BITS),DROW_MAG)
   || IS_SET(GET_POWERS(victim,DROW_BITS),DROW_CLE) )
  {
   stc("They already have a profession.\n\r",ch);
   return;
  }
  if( !str_cmp(arg2,"mage") )
   SET_BIT_POWERS(victim,DROW_BITS,DROW_MAG);
  else if( !str_cmp(arg2,"cleric") )
   SET_BIT_POWERS(victim,DROW_BITS,DROW_CLE);
  else if( !str_cmp(arg2,"warrior") )
   SET_BIT_POWERS(victim,DROW_BITS,DROW_WAR);
  stc("You give them a profession.\n\r",ch);
  stc("You have been given a profession.\n\r",victim);
  save_char_obj(victim);
  return;
 }

 if( !str_cmp(arg2,"drowfire") )          { inpart = DPOWER_DROWFIRE;     cost = 2500;  }
 else if( !str_cmp(arg2,"darkness") )     { inpart = DPOWER_DARKNESS;     cost = 7500;  }
 else if( !str_cmp(arg2,"spiderarms") )   { inpart = DPOWER_ARMS;         cost = 7500;  }
 else if( !str_cmp(arg2,"web") )          { inpart = DPOWER_WEB;          cost = 5000;  }
 else if( !str_cmp(arg2,"spiderform") )   { inpart = DPOWER_SPIDERFORM;   cost = 15000; }
 else if( !str_cmp(arg2,"drowhate") )     { inpart = DPOWER_DROWHATE;     cost = 10000; }
 else if( !str_cmp(arg2,"drowshield") )   { inpart = DPOWER_DROWSHIELD;   cost = 5000;  }
 else if( !str_cmp(arg2,"levitation") )   { inpart = DPOWER_LEVITATION;   cost = 1000;  }
 else if( !str_cmp(arg2,"garotte") )      { inpart = DPOWER_GAROTTE;      cost = 5000;  }
 else if( !str_cmp(arg2,"dgarotte") )     { inpart = DPOWER_DGAROTTE;     cost = 2500;  }
 else if( !str_cmp(arg2,"drowpoison") )   { inpart = DPOWER_DROWPOISON;   cost = 2500;  }
 else if( !str_cmp(arg2,"earthshatter") ) { inpart = DPOWER_EARTHSHATTER; cost = 7500;  }
 else if( !str_cmp(arg2,"speed") )        { inpart = DPOWER_SPEED;        cost = 7500;  }
 else if( !str_cmp(arg2,"toughskin") )    { inpart = DPOWER_TOUGHSKIN;    cost = 7500;  } 
 else if( !str_cmp(arg2,"scry") )         { inpart = DPOWER_SCRY;         cost = 10000; }
 else
 {
  stc("Available powers are:\n\r",ch);
  stc("Warrior      (0)         Mage         (0)         Cleric     (0)\n\r",ch);  
  stc("Drowfire     (2,500)     Darkness     (7,500)     Drowpoison (2,500)\n\r",ch);
  stc("Speed        (7,500)     Drowshield   (5,000)     Levitation (1,000)\n\r",ch);
  stc("Scry         (10,000)    Garotte      (5,000)     Spiderarms (7,500)\n\r",ch);
  stc("Drowhate     (10,000)    Spiderform   (15,000)    Web        (5,000)\n\r",ch);
  stc("Dgarotte     (2,500)     Earthshatter (7,500)     Toughskin  (7,500)\n\r",ch);
  return;
 }

 if( IS_SET(GET_POWERS(victim,DROW_BITS),inpart) )
 {
  if( victim != ch )
   stc("They already have that power.\n\r",ch);
  else
   stc("You already have that power.\n\r",ch);
  return;
 }
 if( GET_POWERS(ch,DROW_POINTS) < cost ) 
 {
  stc("You have insufficient power to grant that gift.\n\r",ch);
  return;
 }
 SET_BIT_POWERS(victim,DROW_BITS,inpart);
 GET_POWERS(ch,DROW_POINTS) -= cost;
 stc("You have been granted a gift from Lloth!\n\r",victim);
 if( victim != ch )
  stc("Ok.\n\r",ch);
 if( victim != ch )
  save_char_obj(ch);
 save_char_obj(victim);
 return; 
}

void chaosblast( CHAR_DATA *ch, char *argument )
{
 CHAR_DATA *victim;
 char arg[MAX_INPUT_LENGTH];
 int sn;
 int level;
 int spelltype;
 int cost = 100;

 argument = one_argument(argument,arg);

 if( IS_NPC(ch) )
  return;

 if( !IS_CLASS(ch,CLASS_DROW) || (!IS_SET(GET_POWERS(ch,DROW_BITS),DROW_MAG) && ch->generation > 2) )
 {
  do_huh(ch,"");
  return;
 }

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

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

 if( is_safe(ch,victim) )
 {
  stc("Not while safe.\n\r",ch);
  return;
 }

 if( ch->mana < cost )
 {
  stc("You don't have enough mana.\n\r",ch);
  return;
 }

 if( (sn = skill_lookup("chaos blast")) < 0 )
  return;
 spelltype = skill_table[sn].target;
 level = (ch->spl[spelltype] * 2);
 act("You concentrate your power on $N.",ch,NULL,victim,TO_CHAR);
 act("$n concentrates $s power on you.",ch,NULL,victim,TO_VICT);
 act("$n concentraces $s power on $N.",ch,NULL,victim,TO_NOTVICT);
 (*skill_table[sn].spell_fun)(sn,level,ch,victim);
 WAIT_STATE(ch,12);
 ch->mana -= cost;
 return;
}

void drowfire( CHAR_DATA *ch, char *argument )
{
 CHAR_DATA *victim;
 char arg[MAX_INPUT_LENGTH];
 int sn;
 int level;
 int spelltype;
 int cost = 100;

 argument = one_argument(argument,arg);

 if( IS_NPC(ch) )
  return;

 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_DROWFIRE) )
 {
  do_huh(ch,"");
  return;
 }

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

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

 if( is_safe(ch,victim) )
 {
  stc("Not while safe.\n\r",ch);
  return;
 }

 if( ch->mana < cost )
 {
  stc("You don't have enough mana.\n\r",ch);
  return;
 }

 if( (sn = skill_lookup("drowfire")) < 0 )
  return;
 spelltype = skill_table[sn].target;
 level = ch->spl[spelltype] * 0.5;
 (*skill_table[sn].spell_fun)(sn,level,ch,victim);
 WAIT_STATE(ch,12);
 ch->mana -= cost;
 return;
}

void heal( CHAR_DATA *ch, char *argument ) 
{
 int cost = 100;

 if( IS_NPC(ch) )
  return;

 if( !IS_CLASS(ch,CLASS_DROW) || (!IS_SET(GET_POWERS(ch,DROW_BITS),DROW_CLE) && ch->generation > 2)) 
 {
  do_huh(ch,"");
  return;
 }

 if( ch->mana < cost )
 {
  stc("You don't have enough mana.\n\r",ch);
  return;
 }

 ch->mana -= cost;
 ch->hit += (ch->spl[BLUE_MAGIC] * 2);
 if( ch->hit > ch->max_hit )
  ch->hit = ch->max_hit;
 stc("Lloth heals you.\n\r",ch);
 act("$n is healed by Lloth.",ch,NULL,NULL,TO_ROOM);
 WAIT_STATE(ch,12);
 return;
}

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

 if( IS_NPC(ch) )
  return;

 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_DROWHATE) )
 {
  do_huh(ch,"");
  return;
 }

 if( IS_SET(GET_POWERS(ch,DROW_BITS),DROW_HATE) )
 {
  stc("You calm your hatred.\n\r",ch);
  REM_BIT_POWERS(ch,DROW_BITS,DROW_HATE);
 }
 else
 {
  stc("You invoke your hatred for others.\n\r",ch);
  SET_BIT_POWERS(ch,DROW_BITS,DROW_HATE);
 }
 return;
}

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

 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_SPIDERFORM) )
 {
  do_huh(ch,"");
  return;
 }

 if( IS_SET(GET_POWERS(ch,DROW_BITS),DROW_SPIDERFORM) )
 {
  stc("You return to your normal form.\n\r",ch);
  REM_BIT_POWERS(ch,DROW_BITS,DROW_SPIDERFORM);  
 }
 else
 {
  stc("You mutate into a large spider.\n\r",ch);
  SET_BIT_POWERS(ch,DROW_BITS,DROW_SPIDERFORM);
 }
 return;
}

void drowshield( CHAR_DATA *ch, char *argument )
{
 if( IS_NPC(ch) )           
  return;
  
 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_DROWSHIELD) )
 {
  do_huh(ch,"");
  return;
 }
  
 if( IS_SET(GET_POWERS(ch,DROW_BITS),DROW_SHIELD) )
 {
  stc("You stop shielding your aura.\n\r",ch);
  REM_BIT_POWERS(ch,DROW_BITS,DROW_SHIELD); 
 }
 else
 {   
  stc("You shield your aura from those around you.\n\r",ch);
  SET_BIT_POWERS(ch,DROW_BITS,DROW_SHIELD); 
 }
 return;
}

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

 if( !IS_CLASS(ch,CLASS_DROW) )
 {
  do_huh(ch,"");
  return;
 }

 display_class_stats(ch);
 return;
}

void darkness(CHAR_DATA *ch, char *argument)
{
 bool blah = FALSE;

 if( IS_NPC(ch) )
  return;

 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_DARKNESS) )
 {
  do_huh(ch,"");
  return;
 }
 
 if( ch->pcdata->pulse_timer[PULSE_DARKNESS] < 1 )
 {
  stc("You lack the strength to summon darkness.\n\r",ch);
  return;
 }
 if( ch->fight_timer > 0 )
 {
  stc("You can not call upon the darkness with a fight timer active.\n\r",ch);
  return;
 }
 if( IS_SET(ch->newbits,NEW_DARKNESS) )
 {
  stc("You banish your globe of darkness.\n\r",ch);
  act("The globe of darkness around $n disappears.",ch,NULL,NULL,TO_ROOM);
  REMOVE_BIT(ch->newbits,NEW_DARKNESS);
  
  if(ch->in_room != NULL)
   if( IS_SET(ch->in_room->room_flags,ROOM_TOTAL_DARKNESS) )
    REMOVE_BIT(ch->in_room->room_flags,ROOM_TOTAL_DARKNESS);
  return;
 }
 else
 { 
  stc("You summon a globe of darkness.\n\r",ch);
  act("$n summons a globe of darkness.",ch,NULL,NULL,TO_ROOM);

  if( IS_SET(ch->extra,TIED_UP) )
  {
   REMOVE_BIT(ch->extra,TIED_UP);
   blah = TRUE;
  }

  if( IS_AFFECTED(ch,AFF_WEBBED) )
  {
   REMOVE_BIT(ch->affected_by,AFF_WEBBED);
   blah = TRUE;
  }
  SET_BIT(ch->newbits, NEW_DARKNESS);

  if( blah )
   stc("The darkness sets you free.\n\r",ch);

  if( !IS_SET(ch->in_room->room_flags, ROOM_TOTAL_DARKNESS) )
   SET_BIT(ch->in_room->room_flags, ROOM_TOTAL_DARKNESS);
  
  return;
 }
 
 return;
}
	
void earthshatter( CHAR_DATA *ch, char *argument )
{
 CHAR_DATA *vch;
 CHAR_DATA *vch_next;
 int dam;
 int level;
 int cost = 100;   

 if( IS_NPC(ch) )
  return;

 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_EARTHSHATTER) )
 {
  do_huh(ch,"");
  return;
 }

 if( ch->mana < cost )
 {
  stc("You need more mana.\n\r",ch);
  return;
 }
 
 level = ch->spl[PURPLE_MAGIC] * 2;
 ch->mana -= cost;
 stc("You summon the power of the underworld, shattering the earth!\n\r",ch);
 act("$n summons the power of the underworld, shattering the earth!",ch,NULL,NULL,TO_ROOM);

 for( vch = ch->in_room->people; vch != NULL; vch = vch_next )
 {
  vch_next = vch->next_in_room;
  if( vch == ch )
   continue;
  if( is_same_group(ch,vch) )
   continue;
  if( is_safe(ch,vch) )
  {
   stc("Not while safe.\n\r",ch);
   continue;
  }
  dam = dice(level,7);
  if( saves_spell(level,vch) )
   dam /= 2;
  damage(ch,vch,dam,skill_lookup("earthquake"));
 }
 WAIT_STATE(ch,12);
 return;
}

void garotte( CHAR_DATA *ch, char *argument )
{
 char buf[MAX_STRING_LENGTH];
 char arg[MAX_INPUT_LENGTH];
 CHAR_DATA *victim;
 OBJ_DATA *obj;
 int chance;

 one_argument(argument, arg);
 chance = number_percent();

 if( IS_NPC(ch) )
  return;

 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_GAROTTE) )
 {
  do_huh(ch,"");
  return;
 }

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

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

 if( victim == ch )
 {
  stc("That would be a bad idea.\n\r",ch);
  return;
 }

 if( is_safe(ch,victim) )
 {
  stc("Not while safe.\n\r",ch);
  return;
 }

 if( ((obj = get_eq_char(ch,WEAR_WIELD)) == NULL || obj->value[3] != 4)
  && ((obj = get_eq_char(ch,WEAR_HOLD)) == NULL || obj->value[3] != 4) )
 {
  stc("You need to wield a whip.\n\r",ch);
  return;
 }
     
 if( victim->fighting != NULL )
 {
  stc("You can't garotte a fighting person.\n\r",ch);
  return;
 }

 if( victim->hit < (victim->max_hit * 0.10) )
 {
  act("$N is too hurt for you to sneak up.",ch,NULL,victim,TO_CHAR);
  return;
 }
 check_killer(ch,victim);
 WAIT_STATE(ch,12);

 if( chance <= 5 )
 {
  ch->fight_timer += 5;
  damage(ch,victim,0,gsn_garotte);
  return;
 }

 ch->fight_timer += 5;
 one_hit(ch,victim,gsn_garotte,1);
 multi_hit(ch,victim,TYPE_UNDEFINED);
 return;
}

void dgarotte( CHAR_DATA *ch, char *argument )
{
 char buf[MAX_STRING_LENGTH];                 
 char arg[MAX_INPUT_LENGTH];
 CHAR_DATA *victim;
 OBJ_DATA *obj;
 int chance;
 
 one_argument(argument, arg);
 chance = number_percent();
  
 if( IS_NPC(ch) )
  return;
        
 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_DGAROTTE) )
 {      
  do_huh(ch,"");
  return;
 }

 if( !IS_SET(ch->newbits,NEW_DARKNESS) )
 {
  stc("You have to be surrounded in darkness.\n\r",ch);
  return;
 }

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

 if( (victim = get_char_room(ch,arg)) == NULL)
 {      
  stc("They are't here.\n\r",ch);
  return;
 }      
 
 if( victim == ch )
 {      
  stc("That would be a bad idea.\n\r",ch);
  return;
 }
 if( is_safe(ch,victim) )
 {
  stc("Not while safe.\n\r",ch);
  return;
 }
 
 if( ((obj = get_eq_char(ch,WEAR_WIELD)) == NULL || obj->value[3] != 4)
  && ((obj = get_eq_char(ch,WEAR_HOLD)) == NULL || obj->value[3] != 4) )
 {
  stc("You need to wield a whip.\n\r",ch);
  return;
 }
        
 if( victim->fighting != NULL )
 {      
  stc("You can't garotte a fighting person.\n\r",ch);
  return;
 }      
        
 if( victim->hit < (victim->max_hit * 0.20) ) 
 {      
  act("$N is too hurt for you to sneak up.",ch,NULL,victim,TO_CHAR);
  return;
 }
 if( IS_SET(ch->newbits,NEW_DARKNESS) )
 {
  stc("You banish your globe of darkness.\n\r",ch);
  act("The globe of darkness around $n disappears.",ch,NULL,NULL,TO_ROOM);
  REMOVE_BIT(ch->newbits,NEW_DARKNESS);
 
  if(ch->in_room != NULL)
   if( IS_SET(ch->in_room->room_flags,ROOM_TOTAL_DARKNESS) )
    REMOVE_BIT(ch->in_room->room_flags,ROOM_TOTAL_DARKNESS);
 }
 check_killer(ch,victim);
 WAIT_STATE(ch,24);

 if( chance <= 5 )
 {
  ch->fight_timer += 5; damage(ch,victim,0,gsn_garotte);
  return;
 }
  
 ch->fight_timer += 5;
 one_hit(ch,victim,gsn_garotte,1);
 multi_hit(ch,victim,TYPE_UNDEFINED);
 return;
}

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

 if( !IS_CLASS(ch,CLASS_DROW) || !IS_SET(GET_POWERS(ch,DROW_BITS),DPOWER_LEVITATION) )
 {
  do_huh(ch,"");
  return;
 }
 
 if( IS_SET(ch->affected_by,AFF_FLYING) )
 {
  stc("You gently float to the ground.\n\r",ch);
  REMOVE_BIT(ch->affected_by,AFF_FLYING);
 }
 else
 {
  stc("You slowly rise into the air.\n\r",ch);
  SET_BIT(ch->affected_by,AFF_FLYING);
 }
 return;
}

void strangle( CHAR_DATA * ch, char *argument )
{
 CHAR_DATA *victim;
 int dam = 0;
 int cost = 100;
  
 if( IS_NPC(ch) )  
  return;

 if( !IS_CLASS(ch,CLASS_DROW) || (!IS_SET(GET_POWERS(ch,DROW_BITS),DROW_WAR) && ch->generation > 2) )
 {
  do_huh(ch,"");
  return;
 }

 if( ch->move < cost )  
 { 
  stc("You are too tired to strangle somebody.\n\r",ch);
  return;
 }

 if( ch->fighting == NULL )
 {
  stc("You need to be fighting in order to use strangle.\n\r",ch);
  return;
 }

 else if( ch->fighting != NULL )
  victim = ch->fighting;

 if( victim == ch )
 {
  stc("Not the brightest, are you?\n\r",ch);
  return;
 }

 if( is_safe(ch,victim) )
 {
  stc("Not while safe.\n\r",ch);
  return;
 }
 
 check_killer(ch,victim);
 WAIT_STATE(ch,12);
 dam = (class_damroll(ch)/2);
 dam += number_range(ch->damroll/16,ch->damroll/8);
 ch->move -= cost;
 hurt_person(ch,victim,dam);
 update_pos(victim);

 act2("You wrap your whip around $N's neck, strangling them! [$D]",ch,NULL,victim,TO_CHAR,dam);
 act2("$n wraps $s whip around your neck, strangling you! [$D]",ch,NULL,victim,TO_VICT,dam);
 act2("$n wraps $s whip around $N's neck, strangling $M! [$D]",ch,NULL,victim,TO_NOTVICT,dam);

 return;
}