/
mudd/docs/html/
mudd/world/
#include <sys/types.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include "mud.h"

bool area_spell = FALSE;
bool detect_opp_align = FALSE;


void spell_detect_align (CHAR_DATA *ch)
{
  detect_opp_align = TRUE;
  do_who (ch, "");
  detect_opp_align = FALSE;
  return;
}

void 
show_hitdam (int gsn, char *noun, int dam, CHAR_DATA * ch, CHAR_DATA * victim)
{
  dam_message (ch, victim, dam, gsn, 0);
  return;
}

void
spell_astral (CHAR_DATA *ch, void *vo)
{
  CHAR_DATA *vict;
   if ((vict = get_char_world (ch, target_name)) == NULL)
     {
       send_to_char("You can't find them.\n\r", ch);
       return;
     }

   if (FIGHTING (ch) || LEVEL (vict) > LEVEL (ch) + 20 || !IS_OPEN (vict->in_room->area) || vict->in_room->vnum < 1000 || vict == ch ||
      ch->in_room->vnum < 1000)
    {
      send_to_char ("You cannot go there.\n\r", ch);
      return;
    }

  if (IS_MOB(vict) && IS_SET(vict->in_room->area->area_flags, AREA_HOMELAND))
    {
      send_to_char("The spell failed.\n\r", ch);
      return;
    }
  if ((vict->in_room && IS_SET (vict->in_room->room_flags, ROOM_NOSUMMON)) ||
      (ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_NOSUMMON)))
    {
      send_to_char ("The spell failed.\n\r", ch);
      return;
    }
  act ("$n disappears in a flash of bright light!", ch, NULL, NULL, TO_ROOM);
  char_from_room (ch);
  char_to_room (ch, vict->in_room);
  act ("$B$3$n appears out of nowhere$R$7!", ch, NULL, NULL, TO_ROOM);
  send_to_char("You step through the void and when you rematerialize, you are elsewhere!\n\r", ch);
  do_look (ch, "auto");
  WAIT_STATE (ch, 15*PULSE_VIOLENCE);
  return;
}

void 
spell_summon (int sn, int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *vict;
  if (!target_name || target_name[0] == '\0')
    return;
  if ((vict = get_char_world (ch, target_name)) == NULL)
    {
      send_to_char ("You can't find them.\n\r", ch);
      return;
    }
  if (FIGHTING (vict) || LEVEL (vict) > LEVEL (ch) + 20 || !IS_OPEN (vict->in_room->area) ||
      vict->in_room->vnum < 1000 || vict == ch ||
      ch->in_room->vnum < 1000)
    {
      send_to_char ("You can't summon to or from here.\n\r", ch);
      return;
    }
  if (IS_MOB (vict) && !pow.can_summon_mobs)
    {
      send_to_char ("You cannot summon mobs.\n\r", ch);
      return;
    }
  if ((vict->in_room && IS_SET (vict->in_room->room_flags, ROOM_NOSUMMON)) ||
      (ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_NOSUMMON)))
    {
      send_to_char ("You cannot summon to or from this location.\n\r", ch);
      return;
    }
  if (IS_PLAYER (vict) && IS_PLAYER (ch) && (DIFF_ALIGN(ch, vict)))
    {
      send_to_char ("You cannot summon THEM!.\n\r", ch);
      return;
    }
  
  act ("$n disappears in a flash of bright light!", vict, NULL, vict, TO_ROOM);
  char_from_room (vict);
  char_to_room (vict, ch->in_room);
  act ("$n appears in a blinding flash of light!", vict, NULL, vict, TO_ROOM);
  send_to_char ("You have been summoned!!\n\r", vict);
  do_look (vict, "auto");
  return;
}
  void 
spell_portal (CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *vict;
  SINGLE_OBJECT *portal;
  if (!target_name || target_name[0] == '\0')
    return;
  if ((vict = get_char_world (ch, target_name)) == NULL)
    {
      send_to_char ("The spell failed.\n\r", ch);
      return;
    }
  if (FIGHTING (vict) || LEVEL (vict) > LEVEL (ch) + 20 || !IS_OPEN (vict->in_room->area) ||
      vict->in_room->vnum < 1000 || vict == ch ||
      ch->in_room->vnum < 1000 || vict->wait > 10)
    {
      send_to_char ("The spell failed.\n\r", ch);
      return;
    }
  if (IS_MOB (vict) && IS_SET(vict->in_room->area->area_flags, AREA_HOMELAND))
    {
      send_to_char ("The spell failed.\n\r", ch);
      return;
    }
  if ((vict->in_room && IS_SET (vict->in_room->room_flags, ROOM_NOSUMMON)) ||
      (ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_NOSUMMON)))
    {
      send_to_char ("The spell failed.\n\r", ch);
      return;
    }
  if (IS_PLAYER (vict) && IS_PLAYER (ch) && (DIFF_ALIGN(ch, vict)))
    {
      send_to_char ("The spell failed.\n\r", ch);
      return;
    }
  if (get_obj_index(25) == NULL)
    {
      send_to_char("The spell failed! Portals do not exist!\n\r", ch);
      return;
    }
  if ((portal = create_object(get_obj_index(25), 0)) == NULL)
    {
      send_to_char ("The spell failed! No portal!\n\r", ch);
      return;
    }
  act ("$n utters the final incantation, and a magical disk appears!", ch, NULL, NULL, TO_ROOM);
  act ("A magical, glowing disk appears overhead!", vict, NULL, NULL, TO_ROOM);
  send_to_char("A magical, glowing disk appears overhead!\n\r", vict);
  ((I_FURNITURE *)portal->more)->to_room_vnum = vict->in_room->vnum;
  obj_to(portal, ch->in_room);
  if ((portal = create_object(get_obj_index(25), 0)) == NULL)
    {
      send_to_char ("The spell failed! No portal!\n\r", ch);
      return;
    }
  ((I_FURNITURE *)portal->more)->to_room_vnum = ch->in_room->vnum;
  obj_to(portal, vict->in_room);
  if (number_range(1,50) == 3)
    {
      send_to_char("OUCH! You almost get dragged into the vortex created!\n\r", ch);
      ch->hit /=2;
    }
  return;
}
       
void 
spell_teleport (int sn, int level, CHAR_DATA * ch, void *vo)
{
  ROOM_DATA *rd;
  CHAR_DATA *victim = (CHAR_DATA *) vo;

  if (!victim)
    victim = ch;
  if (FIGHTING (ch))
    {
      send_to_char ("The spell failed!\n\r", ch);
      return;
    }
  while ((rd = get_room_index (number_range (1001, 99999))) == NULL || !IS_OPEN (rd->area) ||
	 rd->sector_type == SECT_WATER_NOSWIM || rd->sector_type == SECT_WATER_SWIM ||
	 IS_SET (rd->room_flags, ROOM_NOSUMMON)) ;
  
  act ("$n disappears!", victim, NULL, victim, TO_ROOM);

  char_from_room (victim);
  char_to_room (victim, rd);
  return;
}
void 
spell_word_of_recall (int sn, int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  if (IS_MOB (ch))
    return;
  if (!victim)
    victim = ch;
  if (IS_MOB (victim))
    return;
  if (ch->in_room && IS_SET (ch->in_room->room_flags, ROOM_NO_RECALL))
    {
      send_to_char ("The spell failed!\n\r", ch);
      return;
    }
  if (FIGHTING (ch))
    {
      send_to_char ("The spell failed!\n\r", ch);
      return;
    }

  if (DIFF_ALIGN(ch, victim))
    return;

  if (IS_HURT (victim, CURSE)) {
	  if (victim==ch) {
		send_to_char("A powerful curse is preventing you from recalling!\n\r", ch);
	  } else {
		send_to_char("A powerful curse prevents your spell from succeeding!\n\r",ch);
	  }
	  return;
  }
  act ("$n disappears!", victim, NULL, victim, TO_ROOM);
  char_from_room (victim);
  char_to_room (victim, get_room_index (ch->pcdata->alignment+100));
  victim->pcdata->no_quit_pk = 0; /* JRAJRA */
  victim->pcdata->no_quit = 0;
  return; 
}
    
void 
scatter_mob (CHAR_DATA * mob)
{
  int just_moved_dir = -1;
  int moved_rooms = 0;
  int move_tries = 0;
  int move_dir;

  if (!mob->in_room)
    return;

  while (move_tries < 20 && moved_rooms < 3)
    {
      move_dir = number_range (0, 5);
      while (move_dir == rev_dir[just_moved_dir])
	move_dir = number_range (0, 5);
      if (move_char (mob, move_dir))
	{
	  move_tries++;
	  moved_rooms++;
	  just_moved_dir = move_dir;
	  continue;
	}
      else
	move_tries++;
    }

  return;
}


/* Fix this!!! */
void 
spell_dispel_magic (int sn, int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  
  if (victim == NULL)
    return;
  return;
  /*
  if (IS_PLAYER (victim))
    {
      int i;
      for (i = 0; i < 4; i++)
	victim->aff[i] = victim->pcdata->nat_aff[i];
      FIXIT(victim);
    }*/
}

void
spell_necromancy (SPELL_DATA * spell, CHAR_DATA * ch)
{  
  SINGLE_OBJECT *obj;
  AFFECT_DATA  af;
  char buf[500];
  MOB_PROTOTYPE *pMob;
  CHAR_DATA *vict;
  long bonus;
  bzero (&af, sizeof (af));
  if(!target_name || target_name[0] == '\0')
    return;
  if ((obj = get_obj_list (ch, target_name, ch->in_room->contents)) == NULL)
    {
      send_to_char ("You don't see that here.\n\r", ch);
      return;
    }
  if (obj->pIndexData->item_type == ITEM_CORPSE_PC)
    {
      send_to_char ("You may only resurect mobile corpses.\n\r", ch);
      return;
    }
  else if (obj->pIndexData->item_type != ITEM_CORPSE_NPC)
    {
      send_to_char ("You may only resurect corpses.\n\r", ch);
      return;
      }
  act("$n begins summoning the nether forces...", ch, NULL, NULL, TO_ROOM);
  send_to_char("You begin summoning the nether forces...\n\r", ch);
  WAIT_STATE (ch, 15*PULSE_VIOLENCE);
  if(LEVEL(ch) < obj->pIndexData->level)
    {
      act("$n's powers were insufficent to resurect $p.", ch, obj, NULL, TO_ROOM);
      send_to_char ("You were unable to resurect the corpse.\n\r", ch);
      obj_from (obj);
      free_it (obj);
      return;
    }
  act("$n summons the $B$0darkest forces$R of the netherworlds and brings life to $p$R!", ch, obj, NULL, TO_ROOM);
  sprintf (buf, "You successfully bring %s \x1B[0;37mback from the dead!\n\r", obj->short_descr);
  send_to_char(buf, ch);

  if((pMob = get_mob_index(5)) == NULL)
    {
      send_to_char ("A god forgot to create the mob that goes along with this spell!\n\r", ch);
      return;
    }
  vict = create_mobile (pMob);
  char_to_room (vict, ch->in_room);
  bonus = ((obj->pIndexData->level - LEVEL(ch))/2) + number_range (1, get_stat(ch, WIS));
  obj_from (obj);
  free_it (obj);
  vict->hit += bonus;
  add_follower (vict, ch);
  af.type = spell->gsn;
  af.duration = number_fuzzy (100);
  af.location = 0;
  af.modifier = 0;
  af.aff[HURT] = CHARM;
  affect_to_char (vict, &af);
  return;
}

void 
spell_create_object (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
  SINGLE_OBJECT *obj;
  if ((obj = create_object (get_obj_index (spell->creates_obj), 0)) == NULL)
    {
      send_to_char ("A god has set up this spell wrong.. please contact a god.\n\r", ch);
      return;
    }
  if (IS_SET (spell->spell_bits, SPELL_OBJ_TO_ROOM))
    obj_to (obj, ch->in_room);
  else
    {
      obj_to (obj, ch);
      obj->wear_loc = -1;
    }
  return;
}

bool 
remove_sa (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  if (number_range(1,9) >
      get_curr_wis(ch)  || number_range(1,9) > get_curr_wis(victim))
    {
      send_to_char ("Your spell fails!\n\r", ch);
      return FALSE;
    }
  if (!IS_HURT(victim, spell->aff[HURT]) &&
      !IS_PROT(victim, spell->aff[PROT]) &&
      !IS_AFF(victim, spell->aff[AFF]) &&
      !IS_DET(victim, spell->aff[DET]))
    {
      send_to_char("Your spell fails!\n\r", ch);
      return FALSE;
    }
  affect_strip_bits (victim, -1, spell->gsn);
  return TRUE;
}


void 
write_stuff (SPELL_DATA * spell, CHAR_DATA * ch, CHAR_DATA * victim)
{
  if (spell->act_to_ch_1)
    act (spell->act_to_ch_1, ch, NULL, victim, TO_CHAR);
  if (spell->act_to_ch_2)
    act (spell->act_to_ch_2, ch, NULL, victim, TO_CHAR);
  if (victim && spell->act_to_vict_1)
    act (spell->act_to_vict_1, ch, NULL, victim, TO_VICT);
  if (victim && spell->act_to_vict_2)
    act (spell->act_to_vict_2, ch, NULL, victim, TO_VICT);

  if (victim && ch == victim && spell->act_to_vict_1)
    act (spell->act_to_vict_1, ch, NULL, victim, TO_CHAR);
  if (victim && ch == victim && spell->act_to_vict_2)
    act (spell->act_to_vict_2, ch, NULL, victim, TO_CHAR);

  if (spell->act_to_notvict_1)
    act (spell->act_to_notvict_1, ch, NULL, victim, TO_NOTVICT);
  if (spell->act_to_notvict_2)
    act (spell->act_to_notvict_2, ch, NULL, victim, TO_NOTVICT);
  return;
}

void
general_spell (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo)
{
  
  general_spell2 (spell, level, ch, vo, FALSE, ch->in_room);
  if (IS_PLAYER(ch) && number_range(1,14) == 3 &&
      check_skill(ch, gsn_double_cast) &&
      (spell->spell_type == TAR_CHAR_OFFENSIVE ||
       (IS_SET(spell->spell_bits, (SPELL_HEALS_DAM | SPELL_ADD_MOVE)))))
    {
      general_spell2 (spell, level, ch, vo, FALSE, ch->in_room);
    }
  return;
}


void 
general_spell2 (SPELL_DATA * spell, int level, CHAR_DATA * ch, void *vo,
		bool area, ROOM_DATA *targetroom)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  CHAR_DATA *next = NULL;
  bool once = FALSE;
  int dur = 0;
  if (spell->spell_type == TAR_OBJ_INV)
    victim = NULL;

  if (spell->creates_obj != 0)
    {
      spell_create_object (spell, level, ch, vo);
    }
    
  /* If this is an area spell...you set the victim to the first in room. */
  
  if (area_spell && victim)
    {
      victim = victim->in_room->people;
      next = victim->next_in_room;
    }
  if (!victim)
    {
      victim = ch;
      area_spell = FALSE;
    }
  /* We set once to FALSE meaning we have not cast this once, then
     if we have a victim, and either we have not done this once
     or if next is not NULL, we do it again. Then, if the spell is
     and area spell, next is set to something, otherwise next is set
     to NULL. So, if this is not an area spell, then after the 
     first time through, once is TRUE, and next is NULL so the 
     middle is false and the loop stops. */

  for (once = FALSE; victim && (!once || next != NULL) ; victim = next)
    {
      if (area_spell)
	next = victim->next_in_room;
      else 
	next = NULL;
      once = TRUE;

      if (!victim)
	victim = ch;
      if (!victim->in_room || victim->data_type == 50)
	return;
      /* This is where we check all the "special spells" 
	 spell_bits2 are used for the oddball spells that don't
	 fall into the category of offensive/defensive/affect/healing */
      if (!IS_SET(spell->spell_bits, SPELL_AREA) || (ch != victim && spell->spell_type != TAR_CHAR_OFFENSIVE) || (ch != victim && spell->spell_type == TAR_CHAR_OFFENSIVE && (!IS_MOB(ch) && DIFF_ALIGN(ch, victim))))
	{
      if (spell->spell_bits2 != 0)
	{
	      if (IS_SET (spell->spell_bits2, SPELL_CHARM_PERSON))
		spell_charm_person (spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_SCRY))
		spell_scry (spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_LOCATE_PERSON))
		spell_locate_person (spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_DISPEL_MAGIC))
		spell_dispel_magic (spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_IDENTIFY))
		spell_identify (spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_LOCATE_OBJECT))
		spell_locate_object (spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_TELEPORT))
		spell_teleport(spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_SUMMON))
		spell_summon(spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_RECALL))
		spell_word_of_recall(spell->gsn, level, ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_PORTAL))
		spell_portal(ch, vo);
	      if (IS_SET (spell->spell_bits2, SPELL_ASTRAL))
		spell_astral(ch, vo);
	  if (IS_SET(spell->spell_bits2, SPELL_DETECT_ALIGN))
	    spell_detect_align(ch);
	  if (IS_SET (spell->spell_bits2, SPELL_NECROMANCY))
	    spell_necromancy(spell, ch);	  
	}
      if (spell->spell_bits != 0)
	{
	  if (IS_SET (spell->spell_bits, SPELL_REMOVES_BIT))
	    if (!remove_sa (spell, level, ch, victim))
	      {};
	  if (IS_SET (spell->spell_bits, SPELL_MASS_DISTORTION))
	    {
	      victim->hit/=2;
	    }
	  
	  if (IS_SET (spell->spell_bits, SPELL_ADD_MOVE + SPELL_HEALS_DAM))
	    {
	      int adds = translate (spell->damage, level, ch);
	      int lvl = spell->spell_level;
	      int bonus = ((100 * get_curr_wis(ch))/((10 +lvl*2/7)));
	      affect_strip(ch, gsn_chameleon);
	      if (bonus > 120) bonus = 120;
	      if (bonus < 90) bonus /= 3;
	      if (bonus > 89) 
		{
		  bonus += lvl * is_member(ch, GUILD_HEALER)/2;
		  if (victim->in_room != ch->in_room)
		    bonus /= 2;
		  if (IS_AUGMENTED(ch, AUG_HEAD_WIS)) bonus += lvl/3+3;
		  bonus += (ch->pcdata->remort_times) * 8;
		  if (race_info[ch->pcdata->race].parts[2] > 1)
		    bonus = bonus * 3/2;
		  if (victim->in_room != ch->in_room)
		    bonus /= 2;
		}
	      adds = (((bonus)*adds)/100);
              if (IS_PLAYER(ch))
		adds = ((race_info[ch->pcdata->race].heal_percent + align_info[ch->pcdata->alignment].heal_percent)*adds)/100;
	      if (IS_SET(victim->in_room->room_flags, ROOM_LOWMAGIC))
		adds/=2;
	      if (IS_SET(victim->in_room->room_flags, ROOM_HIGHMAGIC))
		adds= (3*adds)/2;
	      if (IS_HURT (victim, VAMPIRIC))
		adds /= 7;
	      if (IS_SET(spell->spell_bits, SPELL_ADD_MOVE))
		{
		  victim->move += adds;
		  if (victim->move > victim->max_move)
		    victim->move = victim->max_move;
		  if (victim->move < 1)
		    victim->move = 1;
		}
	      if (IS_SET(spell->spell_bits, SPELL_HEALS_DAM))
		{
		  victim->hit += adds;
		  if (victim->hit > victim->max_hit)
		    victim->hit = victim->max_hit;
		  if (victim->hit < 1)
		    victim->hit = 1;
		}
	    }
	}
      write_stuff (spell, ch, victim);
      if (str_cmp (spell->duration, "N/A") && translate (spell->duration, level, ch) > 0)
	{
	  bool failed = FALSE;
	  dur = translate (spell->duration, level, ch);
	  if (spell->spell_type == TAR_CHAR_OFFENSIVE)
	    {
	      if (victim && ch != victim)
		{
		  /* Most ranged/area spells fail to work */
		  if (victim->in_room != ch->in_room && 
		      number_range (1,4) != 2)
		    failed = TRUE;
		  if (saves_spell (level, victim) && 
		      (IS_MOB(ch) ||  number_range(1,3) == 2 ||
		       str_cmp(race_info[ch->pcdata->race].name, "illithid")))
		    failed = TRUE;
		  if (failed)
		    {
		      act ("$N resisted the effects of your spell!", ch, NULL, victim, TO_CHAR);
		      act ("You resisted the effects of $n's spell!", ch, NULL, victim, TO_VICT);  
		      if (ch->in_room == victim->in_room)
			set_fighting (ch, victim);
		    }
		}
	      if (IS_AUGMENTED(victim, AUG_MENTAL_ARMOR) || IS_AFF(victim, MINDSHIELD))
		dur = UMAX(dur/2, 1);
	      
	    }
	  dur += dur * is_member(ch, GUILD_SORCERER)/10;
	  if ((ch->in_room->vnum > 999 || 
	       spell->spell_type == TAR_CHAR_OFFENSIVE) && !failed )
	    {
	      int jj;
              bool bigaffect = FALSE;
	      for (jj = 0; jj < 5; jj++)
                { 
                  if (translate (spell->modifier[jj], level, ch) != 0 &&
                      spell->location[jj] > 0)
                    bigaffect = TRUE;
                }
	      for (jj = 0; jj < 5; jj++)
		
		{
                  if (bigaffect && (translate(spell->modifier[jj], level,
					      ch) == 0 || spell->location[jj] <= 0))
		    continue;
                  if (!bigaffect && jj > 5) 
		    break;
                  {
		    AFFECT_DATA paf;
		    int durr = dur;
		    int modif = translate (spell->modifier[jj], level, ch);
		    modif += modif * is_member(ch, GUILD_SORCERER)/10;
		    bzero (&paf, sizeof (paf));
		    paf.type = spell->gsn;
		   
		    paf.duration = UMAX(0, (durr-1));
		    paf.location = spell->location[jj];
		    paf.modifier = modif;
		    paf.aff[0] = spell->aff[0];
		    paf.aff[1] = spell->aff[1];
		    paf.aff[2] = spell->aff[2];
		    paf.aff[3] = spell->aff[3];
		    if (!IS_MOB(victim))
		      {
			renew_affect ((IS_AFF(victim, REFLECT) &&
				       spell->spell_type == TAR_CHAR_OFFENSIVE) ?
				      ch : victim , &paf);
			if (IS_SET(paf.aff[0],SLEEP))
			  {
			    do_sleep (victim, "");
			    NEW_POSITION(victim, POSITION_SLEEPING);
			  }
		      }
		    else if (IS_AFF(victim, REFLECT) && spell->spell_type == TAR_CHAR_OFFENSIVE)
		      {
			renew_affect (ch, &paf);
			if (IS_SET(paf.aff[0],SLEEP))
			  {
			    do_sleep (ch, "");
			    NEW_POSITION(ch, POSITION_SLEEPING);
			  }
		      }
		  }
		}
	    }
	}
      if (spell->spell_type == TAR_CHAR_OFFENSIVE)
	{
          if (spell->damage == NULL)
	    {
	      if (IS_AFF (victim, REFLECT))
		{
		  affect_strip_bits (victim, AFF, REFLECT);
		}
	    }
	  else
	    {
	      int dam_left = 100;
	      int lvl = spell->spell_level;
	      int dam = translate (spell->damage, level, ch);
	      int mint = 17 + lvl/6;
	      int bonus = ((100 * get_curr_int(ch))/(mint));
              check_char_fight_init (ch, victim);
	      if (IS_HURT(ch, FEAR) && number_range(1,5) != 3)
		{
		  send_to_char("You are too afraid to attack them!\n\r", ch);
		  WAIT_STATE(ch, PULSE_VIOLENCE);
		  continue;
		}
	      if (IS_AUGMENTED(ch, AUG_HEAD_INT) 
		  && is_member (ch, GUILD_WIZARD) > 3
		  && number_range(1, UMIN(spell->spell_level, 60)) > 50
		  && number_range(1,UMIN(LEVEL(ch),60)) > 50)
		{
		  check_fgt(victim);
		  if (victim->fgt->ears < 9)
		    victim->fgt->ears = 10+number_range(1,2);
		  else 
		    victim->fgt->ears += number_range(1,2);
		  victim->position = POSITION_BASHED;
		}
	      if (bonus > 120) bonus = 120;
	      if (bonus < 90) bonus /= 4;
	      if (bonus > 89) 
		{
		  bonus += lvl * is_member(ch, GUILD_WIZARD)/3;
		  if (IS_AUGMENTED(ch, AUG_HEAD_INT)) bonus += (lvl/4+3);
		  if (race_info[ch->pcdata->race].parts[2] > 1)
		    bonus = bonus * 3/2;
		  if (ch->in_room != victim->in_room)
		    bonus /=2;
		}
	      bonus += (ch->pcdata->remort_times) * 8;
	      dam = ((bonus) * dam)/100;
	      if (IS_PLAYER(ch))
		{
		  dam = ((race_info[ch->pcdata->race].attack_spell_percent + align_info[ch->pcdata->alignment].attack_spell_percent)*dam)/100;
		  if (!str_cmp(race_info[ch->pcdata->race].name, "high-elf") && IS_PLAYER(victim) && DIFF_ALIGN(ch, victim))
		    dam = dam*12/10;
		}
	      if(spell->spell_bits > 0 && victim && victim->in_room)
		{
		  if (IS_SET (spell->spell_bits,SPELL_FIRE))
		    {
		      if (IS_HURT(victim, FIRE)) dam = dam*4/3;
		      if(IS_PROT(victim,FIRE)) dam = dam *4/5;
		      else
			spell_fire_breath (level, ch, (void *) victim);
		    }
		  if (IS_SET (spell->spell_bits,SPELL_ACID))
		    {
		      if (IS_HURT(victim, ACID)) dam = dam*4/3;
		      if(IS_PROT(victim,ACID)) dam = dam*4/5;
		      else
			spell_acid_breath (level, ch, (void *) victim);
		    }
		  if (IS_SET (spell->spell_bits,SPELL_ICE))
		    {
		      if (IS_HURT(victim, ICE)) dam = dam*4/3;
		      if(IS_PROT(victim, ICE)) dam = dam * 4/5;
		      else
			spell_ice_breath (level, ch, (void *) victim);
		    }
		  if (IS_SET (spell->spell_bits,SPELL_WIND))
		    {if (IS_HURT(victim, WIND)) dam = dam*4/3;
		    if(IS_PROT(victim,WIND)) dam = dam*4/5;
		    else
		      spell_wind_breath (level, ch, (void *) victim);
		    }
		  if (IS_SET (spell->spell_bits,SPELL_SHARD))
		    {
		      if (IS_HURT(victim, SHARDS)) dam = dam*4/3;
		      if(IS_PROT(victim,SHARDS)) dam = dam*4/5;
		      else
			spell_shard_breath (level, ch, (void *) victim);
		    }
		  if (IS_SET (spell->spell_bits,SPELL_SHOCK))
		    {
		      if (IS_HURT(victim, SHOCK)) dam = dam*4/3;
		      if(IS_PROT(victim,SHOCK)) dam = dam*4/5;
		      else
			spell_shock_breath (level, ch, (void *) victim);
		    }
		}
	      if (!ch || !victim)
		return;
	      if (IS_SET(victim->in_room->room_flags, ROOM_LOWMAGIC) &&
		  IS_PLAYER(ch))
		dam/=2;
	      if (IS_SET(victim->in_room->room_flags, ROOM_HIGHMAGIC))
		dam= (3*dam)/2;
	      if (victim->in_room->sector_type == SECT_ASTRAL)
		dam*=2;
	      if (IS_AFF(victim,REFLECT))
		{
		  affect_strip_bits (victim, AFF, REFLECT);
		  victim = ch;
		  dam *=2;
		}
	      if (IS_SET (spell->spell_bits, SPELL_HALVED_SAVE) && saves_spell (level, victim))
		dam_left -= number_range(30,60);
	      if (IS_AFF(victim, MINDSHIELD))
		dam_left -= number_range(0,30);
	      if (IS_AUGMENTED(victim, AUG_MENTAL_ARMOR))
		dam_left -= number_range(0,20);
	      if (dam_left < 30) dam_left = 30;
	      dam = ((dam_left * dam)/100);
	      if (victim->in_room != ch->in_room)
		{
		  dam = dam*3/4;
		  if (IS_MOB(victim) && IS_SET(victim->act, ACT_SENTINEL))
		    dam = 0;
		  WAIT_STATE(ch, 3*PULSE_VIOLENCE);
		}
	      damage (ch, victim, dam, spell->gsn);
	      if (FIGHTING(ch) != NULL)
		{
		  if (IS_SET (spell->spell_bits, SPELL_VAMPIRIC))
		    {
		      ch->hit += dam/2;
		      if (ch->hit > ch->max_hit)
			ch->hit = ch->max_hit; 
		      act("You drain the life from $N, and it infuses your body.", ch, NULL, victim, TO_CHAR);
		      act("$n drain the life from you.",ch, NULL, victim, TO_VICT);
		      act("$n drains the life from $N.", ch, NULL, victim, TO_NOTVICT);
		    }
		}
	    }
	}
	}
  if (IS_PLAYER (ch))
    {
      check_skill(ch, spell->gsn);
      if (spell->spell_lag > 0 && IS_PLAYER(ch) && ch->pcdata->no_quit < spell->spell_lag)
	ch->pcdata->no_quit = spell->spell_lag;
    }
    }
  return;
}


void 
spell_message (int sn, int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *rec;
  char buf[STD_LENGTH];
  char targname[SML_LENGTH];
  if (ch->pcdata->no_quit > 0)/* JRAJRA spell lag */
    {
      send_to_char("You cannot cast message yet!\n\r", ch);
      return;
    }
  else
    {
  if (!target_name || target_name[0] == '\0')
    {
      send_to_char ("A voice booms from the heavens:\n\r", ch);
      send_to_char ("\x1B[1;37mSyntax\x1B[0m: cast 'message' <\x1B[1;37mtarget\x1B[0m> <\x1B[1;37mmsg\x1B[0m>\n\r", ch);
      return;
    }
  target_name = one_argy (target_name, targname);
  if ((rec = get_char_world (ch, targname)) == NULL)
    {
      send_to_char ("You send a voice, but you get the feeling it could not deliver.\n\r", ch);
      return;
    }
  sprintf (buf, "\x1B[1;32mA voice from afar tells you '\x1B[0m%s\x1B[1;32m'\x1B[0m\n\r",
	   target_name);
  send_to_char (buf, rec);
  sprintf (buf, "You send a mystical voice to talk to %s.", NAME (rec));
  send_to_char (buf, ch);
 
  return;
    }
}
void 
spell_charm_person (int sn, int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  AFFECT_DATA af;
  bzero (&af, sizeof (af));
  if (victim == ch)
    {
      send_to_char ("You like yourself even better!\n\r", ch);
      return;
    }
  if (IS_MOB (victim) && (victim->pIndexData->mobtype == MOB_GHOST) || IS_AFF(victim, ETHEREAL))
    {
      act ("$N doesn't have a body to charm.", ch, NULL, victim, TO_CHAR);
      return;
    }
  if (IS_MOB (victim) && IS_SET (victim->act, ACT_UNTOUCHABLE))
    {
      send_to_char ("You failed.\n\r", ch);
      return;
    }
  if (IS_HURT (victim, CHARM)
      || IS_HURT (ch, CHARM)
      || level < LEVEL (victim) - 6
      || IS_PLAYER (victim)
      || IS_PROT (victim, CHARM)
      || saves_spell (level, victim))
    {
      act ("$N snarls at you in complete hatred!", ch, NULL, victim, TO_CHAR);
      act ("$n just tried to charm you!!", ch, NULL, victim, TO_VICT);
      return;
    }
  if (MASTER (victim) != NULL)
    stop_follower (victim);
  add_follower (victim, ch);
  af.type = sn;
  af.duration = number_fuzzy (level / 10);
  af.location = 0;
  af.modifier = 0;
  af.aff[HURT] = CHARM;
  affect_to_char (victim, &af);
  act ("You feel compelled to follow $n.", ch, NULL, victim, TO_VICT);
  if (ch != victim)
    act ("$N gazes at you as if $S life revolved around you.",
	 ch, NULL, victim, TO_CHAR);
  return;
}

void 
spell_scry (int sn, int level, CHAR_DATA * ch, void *vo)
{
  char buf[STD_LENGTH];
  if (target_name == '\0')
    {
      return;
    }
  if (ch->pcdata->online_spot->located == TRUE && ch->pcdata->online_spot->pk_since_locate < 3)
    {
      send_to_char("You must pkill before using this spell again.\n\r", ch);
      return;
    }
  if (!scry (ch, level, target_name))
    {
      sprintf (buf, "You were unable to scry %s.\n\r", target_name);
      send_to_char (buf, ch);
    }
  else
    {
      ch->pcdata->online_spot->located = TRUE;
      ch->pcdata->online_spot->pk_since_locate = 0;
    }
  return;
}

void 
spell_locate_person (int sn, int level, CHAR_DATA * ch, void *vo)
{
  char buf[STD_LENGTH];
  if (target_name == '\0')
    {
      return;
    }
  if (ch->pcdata->online_spot->located == TRUE && ch->pcdata->online_spot->pk_since_locate < 3)
    {
      send_to_char("You must pkill before using this spell again.\n\r", ch);
      return;
    }
  if (!locate_person (ch, level, target_name))
    {
      sprintf (buf, "You were unable to locate %s.\n\r", target_name);
      send_to_char (buf, ch);
    }
  else
    {
      ch->pcdata->online_spot->located = TRUE;
      ch->pcdata->online_spot->pk_since_locate = 0;
    }
  return;
}

void 
spell_identify (int sn, int level, CHAR_DATA * ch, void *vo)
{
  SINGLE_OBJECT *obj = (SINGLE_OBJECT *) vo;
  SPELL_DATA *spp;
  char buf3[500];
  char buf2[STD_LENGTH];
  char buf[STD_LENGTH];
  AFFECT_DATA *paf;
  
  send_to_char (
		 "\x1B[0m-----------------------------------------------------------------------------\n\r",
		 ch);
  sprintf (buf, "'%s\x1B[0m' is some sort of \x1B[1;34m%s\x1B[0m.\n\r",
           STRR (obj, short_descr),
	   item_type_name (obj->pIndexData->item_type));
  send_to_char (buf, ch);
  sprintf (buf, "It weighs \x1B[1;37m%d\x1B[0;37m Stones and \x1b[1;37m%d\x1b[0;37m Pebbles , and is apparently worth \x1B[1;37m%d\x1B[0;33m copper\x1B[0m.\n\r",
	   (obj->pIndexData->weight/WGT_MULT),(obj->pIndexData->weight % WGT_MULT), obj->cost);
  send_to_char (buf, ch);
  sprintf (buf, "It is affected by \x1b[0;34m[\x1B[1;34m%s\x1B[0;34m]\x1B[0m.\n\r",
	   extra_bit_name (obj->extra_flags));
  send_to_char (buf, ch);
  sprintf (buf,
	   "- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -\n\r");
  switch (obj->pIndexData->item_type)
    {
    case ITEM_SCROLL:
    case ITEM_POTION:
      {
	I_POTION *pot = (I_POTION *) obj->more;
	send_to_char (buf, ch);
        sprintf (buf, "Level \x1B[1;34m%d\x1B[0m spells of:", pot->spell_level);
	send_to_char (buf, ch);
	if (pot->spells[0] >= 0 && pot->spells[0] < SKILL_COUNT)
	  {
	    send_to_char (" '\x1B[1;37m", ch);
	    if ((spp = skill_lookup (NULL, pot->spells[0])) != NULL)
	      send_to_char (spp->spell_name, ch);
	    send_to_char ("\x1B[0m'", ch);
	  }
	if (pot->spells[1] >= 0 && pot->spells[1] < SKILL_COUNT)
	  {
	    send_to_char (" '\x1B[1;37m", ch);
	    if ((spp = skill_lookup (NULL, pot->spells[1])) != NULL)
	      send_to_char (spp->spell_name, ch);
	    send_to_char ("\x1B[0m'", ch);
	  }
	if (pot->spells[2] >= 0 && pot->spells[2] < SKILL_COUNT)
	  {
	    send_to_char (" '\x1B[1;37m", ch);
	    if ((spp = skill_lookup (NULL, pot->spells[2])) != NULL)
	      send_to_char (spp->spell_name, ch);
	    send_to_char ("\x1B[0m'", ch);
	  }
	send_to_char (".\n\r", ch);
      }
    break;
    case ITEM_WAND:
    case ITEM_STAFF:
      {
	I_WAND *wnd = (I_WAND *) obj->more;
	send_to_char (buf, ch);
	sprintf (buf, "Has \x1B[34m%d\x1B[0m of \x1B[1;34m%d\x1B[0m charges of level \x1B[1;37m%d\x1B[0m",
		 wnd->current_charges, wnd->max_charges, wnd->spell_level);
	send_to_char (buf, ch);
	if (wnd->spells[0] >= 0 && wnd->spells[0] < SKILL_COUNT)
	  {
	    send_to_char (" '\x1B[1;37m", ch);
	    if ((spp = skill_lookup (NULL, wnd->spells[0])) != NULL)
	      send_to_char (spp->spell_name, ch);
	    send_to_char ("\x1B[0m'", ch);
	  }
	send_to_char (".\n\r", ch);
	break;
      }
    case ITEM_SHIELD:
      {
	I_SHIELD *shld = (I_SHIELD *)obj->more;
	send_to_char(buf, ch);
	sprintf(buf, "This absorbs up to %d points of damage.\n\r", shld->max_power);
	send_to_char(buf, ch);
      }
    break;
    case ITEM_GEM:
      {
	I_GEM *gem = (I_GEM *) obj->more;
	int i;
	sprintf (buf2, "Mana Type(s): ");
	for (i = 0; i < 5; i++)
	  {
	    buf2[0] = 0;
	    if (IS_SET(gem->gem_type, mana_data[i].flagname))
	      {
		sprintf(buf2 + strlen(buf2), "%s%s ", mana_data[i].color, mana_data[i].how_it_appears);
	      }
	  }
	send_to_char(buf2, ch);
	sprintf (buf3, "\n\rMaximum mana: \x1B[1;37m%d\x1B[0m.", gem->max_mana);
	strcat (buf2, buf3);
	send_to_char (buf2, ch);
	send_to_char ("\n\rGems may not give you their max mana if you have low intelligence or wisdom.\n\r", ch);
	sprintf (buf2, "Max spell level for this gem: %d\n\r", gem->max_level);
	send_to_char (buf2, ch);
	if (gem->casts_spell != 0)
	  {
	    SPELL_DATA *spl;
	    if ((spl = skill_lookup(NULL, gem->casts_spell)) != NULL)
	      {
		sprintf(buf2, "This gem is empowered to cast the spell %s.\n\r", spl->spell_name);
		send_to_char(buf2, ch);
	      }
	  }
      }
    break;
    case ITEM_MISSILE:
      {
        I_MISSILE *mis = (I_MISSILE *) obj->more;
        sprintf (buf, "This weapon takes ammo of type %d and shoots %d shot%s at a time.\n\r", 
            mis->ammo_type, mis->shots_per_use, (mis->shots_per_use > 1 ? "s" : ""));
        send_to_char(buf, ch);
      }
      break;
    case ITEM_WEAPON:
      {
	I_WEAPON *weap = (I_WEAPON *) obj->more;
	sprintf (buf, "This weapon is capable of \x1B[1;34m%d\x1B[0md\x1B[1;34m%d\x1B[0m damage.\n\r",
		 weap->firstdice, weap->seconddice);
	send_to_char (buf, ch);
	if (weap->casts_spell != 0)
	  {
	    SPELL_DATA *spl;
	    if ((spl = skill_lookup(NULL, weap->casts_spell)) != NULL)
	      {
		sprintf(buf2, "This weapon is empowered to cast the spell %s.\n\r", spl->spell_name);
		send_to_char(buf2, ch);
	      }
	  }
      }
	break;
    case ITEM_AMMO:
      {
	I_AMMO *ammo = (I_AMMO *) obj->more;
	send_to_char (buf, ch);
	sprintf (buf, "This ammunition is capable of \x1B[1;34m%d\x1B[0md\x1B[1;34m%d\x1B[0m damage.\n\r",
		 ammo->firstdice, ammo->seconddice);
	send_to_char(buf, ch);

	sprintf(buf, "This ammo is of type %d.\n\r", ammo->ammo_type);
	send_to_char(buf, ch);
        if (ammo->total_shots > 1)
          {
            sprintf(buf, "This ammo has %d out of %d shots left.\n\r",
             ammo->shots_left, ammo->total_shots);
            send_to_char(buf, ch);
          }
	break;
      }


    case ITEM_ARMOR:
      {
	I_ARMOR *arm = (I_ARMOR *) obj->more;
	send_to_char (buf, ch);
	sprintf (buf, "Leg AC: %d  Body AC: %d  Head AC: %d  Arm AC: %d.\n\r", arm->protects_legs,
		 arm->protects_body, arm->protects_head, arm->protects_arms);
	send_to_char (buf, ch);
	break;
      }
    }
  for (paf = obj->pIndexData->affected; paf != NULL; paf = paf->next)
    {
      if (paf->location != APPLY_NONE && paf->modifier != 0)
	{
	  if (paf->modifier > 0)
	    sprintf (buf, "It is +\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
		     paf->modifier, affect_loc_name (paf->location));
	  else
	    sprintf (buf, "It is -\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
		     paf->modifier * -1, affect_loc_name (paf->location));
	  send_to_char (buf, ch);
	}
    }
  for (paf = obj->affected; paf != NULL; paf = paf->next)
    {
      if (paf->location != APPLY_NONE && paf->modifier != 0)
	{
	  if (paf->modifier > 0)
	    sprintf (buf, "It is +\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
		     paf->modifier, affect_loc_name (paf->location));
	  else
	    sprintf (buf, "It is -\x1B[1;36m%d\x1B[0m to \x1B[36m%s\x1B[0m.\n\r",
		     paf->modifier * -1, affect_loc_name (paf->location));
	  send_to_char (buf, ch);
	}
    }
  
  send_to_char (
		 "-----------------------------------------------------------------------------\n\r", ch);
  return;
}


void 
spell_locate_object (int sn, int level, CHAR_DATA * ch, void *vo)
{
  char buf[SML_LENGTH];
  SINGLE_OBJECT *obj;
  SINGLE_OBJECT *in_obj;
  bool found;
  int number = 0, i;
  found = FALSE;
  if (level > 100 || LEVEL (ch) > 100)
    return;
  for (i = 0; i < 2; i++)
    {
      for (obj = object_list[i]; obj != NULL && number <= LEVEL (ch);
	   obj = obj->next)
	{
	  if (!can_see_obj (ch, obj) || !is_name (target_name, obj->pIndexData->name))
	    continue;
	  found = TRUE;
	  number++;
	  for (in_obj = obj; in_obj->in_obj != NULL; in_obj = in_obj->in_obj)
	    ;
	  if (in_obj->carried_by != NULL)
	    {
	      sprintf (buf, "%s carried by %s.\n\r",
		       STRR (obj, short_descr), PERS (in_obj->carried_by, ch));
	    }
	  else
	    {
	      sprintf (buf, "%s in %s.\n\r",
		       STRR (obj, short_descr), in_obj->in_room == NULL
		       ? "somewhere" : in_obj->in_room->name);
	    }
	  buf[0] = UPPER (buf[0]);
	  send_to_char (buf, ch);
	}
    }
  if (!found)
    send_to_char ("Nothing like that in hell, heaven or earth.\n\r", ch);
  return;
}

void 
spell_acid_breath (int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  SINGLE_OBJECT *obj_lose;
  SINGLE_OBJECT *obj_next;
  I_ARMOR *arm;
  I_WEAPON *wep;
  if (ch->in_room->vnum < 1000  || number_percent () > level)
    return;
  for (obj_lose = victim->carrying; obj_lose != NULL; obj_lose = obj_next)
    {
      obj_next = obj_lose->next_content;
      if (number_range (1, 4) != 3)
	continue;
      switch (obj_lose->pIndexData->item_type)
	{
	case ITEM_ARMOR:
	  {
	    arm = (I_ARMOR *)obj_lose->more;
	    if (arm->condition_now > 0)
	      {
		act ("$p is covered with acid!", victim, obj_lose, NULL, TO_CHAR);  
		arm->condition_now-= 4;
		if (arm->condition_now <= 0)
		  {
		    obj_from(obj_lose);
		    free_it(obj_lose);
		    break;
		  }
		if(number_range(1,50) == 2)
		  {
		    act ("$p is splashed with acid and loses some of its resilience!", victim, obj_lose, NULL, TO_CHAR);
		    arm->max_condition-= 3;
		    if (arm->max_condition < 1)
		      arm->max_condition = 1;
		    if (arm->protects_legs > 1)
		      arm->protects_legs -= number_bits(1);
		    if (arm->protects_body > 1)
		      arm->protects_body -= number_bits(1);
		    if (arm->protects_head > 1)
		      arm->protects_head -= number_bits(1);
		    if (arm->protects_arms > 1)
		      arm->protects_arms -= number_bits(1);
		  }
	      }
	  }
	break;
	case ITEM_WEAPON:
	  wep = (I_WEAPON *)obj_lose->more;
	  if (wep->damage_p > 0)
	    {
	      act("$p is splashed with acid!", ch, obj_lose, NULL, TO_CHAR);
	      wep->damage_p-=5;
	      if (wep->damage_p <= 0)
		{
		  obj_from(obj_lose);
		  free_it(obj_lose);
		  break;
		}
	      if(number_range(1,50) == 3)
		{
		  if (wep->firstdice > 1)
		    wep->firstdice -= number_bits(1);
		  if (wep->seconddice > 1)
		    wep->seconddice -= number_bits(1);
		  act("The acid damages $p permanently!", victim, obj_lose, NULL, TO_CHAR);
		  if (wep->strength > 5)
		      wep->strength -= 3;
		}
	    }
	  break;
	case ITEM_CONTAINER:
	  act ("$p fumes and dissolves!",victim, obj_lose, NULL, TO_CHAR);
	  obj_from (obj_lose);
	  free_it (obj_lose);
	  break;
	}
    }
return;
}

void 
spell_fire_breath (int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  SINGLE_OBJECT *obj_lose;
  SINGLE_OBJECT *obj_next;
  if (ch->in_room->vnum < 1000 || IS_PROT (victim, FIRE) || number_percent () < level)
    return;
  for (obj_lose = victim->carrying; obj_lose != NULL; obj_lose = obj_next)
    {
      char *msg;
      obj_next = obj_lose->next_content;
      if (number_range (1,4) != 3)
	continue;
      switch (obj_lose->pIndexData->item_type)
	{
	default:
	  continue;
	case ITEM_CONTAINER:
	  {
	    I_CONTAINER * cnt = (I_CONTAINER *) obj_lose->more;
	    if (!IS_SET(cnt->flags, CONT_INDESTRUCTABLE))
	      msg = "$p ignites and burns!";
	    else
	      continue;
	  }
	break;
	case ITEM_POTION:
	  msg = "$p bubbles and boils!";
	  break;
	case ITEM_SCROLL:
	  msg = "$p crackles and burns!";
	  break;
	case ITEM_STAFF:
	  msg = "$p smokes and chars!";
	  break;
	case ITEM_WAND:
	  msg = "$p sparks and sputters!";
	  break;
        case ITEM_AMMO:
          msg =  "$p blackens and burns!";
          break;	  
 	case ITEM_FOOD:
	  msg = "$p blackens and crisps!";
	  break;
	case ITEM_PILL:
	  msg = "$p melts and drips!";
	  break;
	}
      act (msg, victim, obj_lose, NULL, TO_CHAR);
      obj_from (obj_lose);
      free_it (obj_lose);
    }
  return;
}

void 
spell_ice_breath (int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  SINGLE_OBJECT *obj_lose;
  SINGLE_OBJECT *obj_next;
  I_ARMOR *arm;
  I_WEAPON *wep;
  if (ch->in_room->vnum < 1000 || IS_PROT (victim, ICE) || number_percent () < level)
    return;
  for (obj_lose = victim->carrying; obj_lose != NULL;
       obj_lose = obj_next)
    {
      obj_next = obj_lose->next_content;
      if (number_range (1, 5) != 3)
	continue;
      switch (obj_lose->pIndexData->item_type)
	{
	default:
	  continue;
	case ITEM_POTION:
	  {
	    act ("$p turns to ice and explodes!", victim, obj_lose, NULL, TO_CHAR);
	    obj_from (obj_lose);
	    free_it (obj_lose);
	  }
	break;
	case ITEM_DRINK_CON:
	  {
	    act ("$p turns to ice and explodes!", victim, obj_lose, NULL, TO_CHAR);
	    obj_from (obj_lose);
	    free_it (obj_lose);
	  }
	break;
	case ITEM_ARMOR:
	  arm = (I_ARMOR *)obj_lose->more;
	  if (arm->condition_now > 0)
	    {
	      act ("$p freezes and cracks!", victim, obj_lose, NULL, TO_CHAR);  
	      arm->condition_now-= 4;
	      if (arm->condition_now <= 0)
		{
		  obj_from(obj_lose);
		  free_it(obj_lose);
		  break;
		}
	      if(number_range(1,50) == 2)
		{
		  act ("$p is frozen and permanently damaged!", victim, obj_lose, NULL, TO_CHAR);
		  arm->max_condition-= 3;
		  if (arm->max_condition < 2)
		    arm->max_condition = 2;
		  if (arm->protects_legs > 2)
		    arm->protects_legs -= number_bits(1);
		  if (arm->protects_body > 2)
		    arm->protects_body -= number_bits(1);
		  if (arm->protects_head > 2)
		    arm->protects_head -= number_bits(1);
		  if (arm->protects_arms > 2)
		    arm->protects_arms -= number_bits(1);
		}
	    }
	  break;
	case ITEM_WEAPON:
	  wep = (I_WEAPON *)obj_lose->more;
	  if (wep->damage_p > 0)
	    {
	      act("$p is frozen!", ch, obj_lose, NULL, TO_CHAR);
	      wep->damage_p-=5;
	      if (wep->damage_p <= 0)
		{
		  obj_from(obj_lose);
		  free_it(obj_lose);
		  break;
		}
	      if(number_range(1,50) == 3)
		{
		  if (wep->firstdice > 1)
		    wep->firstdice -= number_bits(1);
		  if (wep->seconddice > 1)
		    wep->seconddice -= number_bits(1);
		  act("The ice damages $p permanently!", victim, obj_lose, NULL, TO_CHAR);
		  if (wep->strength > 5)
		    {
		      wep->strength -= 3;
		    }
		}
	    }
	  break;
	}
    }
  return; 
}
void 
spell_shard_breath (int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  SINGLE_OBJECT *obj_lose;
  SINGLE_OBJECT *obj_next;
  I_ARMOR *arm;
  I_WEAPON *wep;
   if (ch->in_room->vnum < 1000 || IS_PROT (victim, SHARDS) || number_percent () < level)
    return;
   for (obj_lose = victim->carrying; obj_lose != NULL;
	obj_lose = obj_next)
     {
       obj_next = obj_lose->next_content;
       if(number_range(1,4) != 3) continue;
       switch (obj_lose->pIndexData->item_type)
	 {
	 default:
	   continue;
	 case ITEM_POTION:
	   {
	     act ("$p is hit with a shard and explodes!", victim,obj_lose, NULL, TO_CHAR);
	     obj_from (obj_lose);
	     free_it (obj_lose);
	   }
	 break;
	 case ITEM_DRINK_CON:
	   {
	     act ("$p gets zinged and rips open!", victim, obj_lose,NULL, TO_CHAR);
	     obj_from (obj_lose);
	     free_it (obj_lose);
	   }
	 break;
	 case ITEM_ARMOR:
	   arm = (I_ARMOR *)obj_lose->more;
	   if (arm->condition_now > 0)
	     {
	       act ("$p gets pelted with shards!", victim, obj_lose, NULL, TO_CHAR);  
	       arm->condition_now-= 4;
	       if (arm->condition_now <= 0)
		 {
		   obj_from(obj_lose);
		   free_it(obj_lose);
		   break;
		 }
	       if(number_range(1,50) == 2)
		 {
		   act ("$p absorbs a solid blow from a flying sliver!", victim, obj_lose, NULL, TO_CHAR);
		   arm->max_condition-= 3;
		   if (arm->max_condition < 2)
		     arm->max_condition = 2;
		   if (arm->protects_legs > 1)
		     arm->protects_legs -= number_bits(1);
		   if (arm->protects_body > 1)
		     arm->protects_body -= number_bits(1);
		   if (arm->protects_head > 1)
		     arm->protects_head -= number_bits(1);
		   if (arm->protects_arms > 1)
		     arm->protects_arms -= number_bits(1);
		 }
	     }
	   break;
	 case ITEM_WEAPON:
	   wep = (I_WEAPON *)obj_lose->more;
	   if (wep->damage_p > 0)
	     {
	       act("$p gets zinged!", ch, obj_lose, NULL, TO_CHAR);
	       wep->damage_p-=5;
	       if (wep->damage_p <= 0)
		 {
		   obj_from(obj_lose);
		   free_it(obj_lose);
		   break;
		 }
	       if(number_range(1,50) == 3)
		 {
		   if (wep->firstdice > 1)
		     wep->firstdice -= number_bits(1);
		   if (wep->seconddice > 1)
		     wep->seconddice -= number_bits(1);
		   act("The shards damage $p permanently!", victim, obj_lose, NULL, TO_CHAR);
		   if (wep->strength > 5)
		     {
		       wep->strength -= 3;
		     }
		 }
	     }
	   break;
	 }
     }
   return; 
}

void 
spell_shock_breath (int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
  SINGLE_OBJECT *obj;
  SINGLE_OBJECT *obj_next;
  if (ch->in_room->vnum < 1000 || IS_PROT (victim, SHOCK) || number_percent () < level)
    return;
  for (obj = victim->carrying; obj != NULL; obj = obj_next)
    {
      obj_next = obj->next_content;
      if (number_range (1, 4) != 3) continue;
      switch (obj ->pIndexData->item_type)
	{
	default:
	  continue;
	case ITEM_SCROLL:
	case ITEM_PILL:
	case ITEM_POTION:
	  { 
	    act ("$p glows with power, then fades!", victim, obj, NULL, TO_CHAR);	
	    if ((((I_POTION *) obj->more)->spell_level > 10)  && (number_range(1,50) != 3))
	      ((I_POTION *) obj->more)->spell_level -= number_range(5,10);
	    else
	      ((I_POTION *) obj->more)->spell_level += number_range(5,10);
	  }
	break;
	case ITEM_STAFF:
	case ITEM_WAND:
	  {
	    act ("$p sparks with energy, then falls silent!",  victim, obj, NULL, TO_CHAR);
	    if ((((I_WAND *) obj->more)->current_charges > 0)  && (number_range(1,50) != 3))
	      ((I_WAND *) obj->more)->current_charges--;
	    else
	      ((I_WAND *) obj->more)->current_charges++;
	    if ((((I_WAND *) obj->more)->spell_level > 10)  && (number_range(1,50) != 3))
	      ((I_WAND *) obj->more)->spell_level -= number_range(5,10);
	    else
	      ((I_WAND *) obj->more)->spell_level += number_range(5,10);
	  }
	break;
	case ITEM_GEM:
	  {
	    if(number_range(1,3) == 3)
	      {
		if (number_range(1,20) == 3) 
		  {
		    ((I_GEM *) obj->more)->gem_type =number_range(1,31);
		    act ("$p seems to change color before your eyes...",  victim, obj, NULL, TO_CHAR);
		  }
		if ((((I_GEM *) obj->more)->max_mana > 15)  &&(number_range(1,10) == 3)) 
		  {
		    if(number_range(1,20) != 4)
		      {
			act ("$p flares brightly and then fades...",  victim, obj, NULL, TO_CHAR);
			((I_GEM *) obj->more)->max_mana -= number_range(1,15);
		      }
		    else
		      {
			act ("$p flares brightly and glows with power",  victim, obj, NULL, TO_CHAR);
			((I_GEM *) obj->more)->max_mana += number_range(1,15);
		      }
		  }
		if ((((I_GEM *) obj->more)->max_level > 10)  &&(number_range(1,10) == 3)) 
		  {
		    if(number_range(1,20) != 4)
		      {
			act ("$p glows brightly and then fades...",  victim, obj, NULL, TO_CHAR);
			((I_GEM *) obj->more)->max_level -= number_range(1,10);
		      }
		    else
		      {
			act ("$p glows brightly and hums with power",  victim, obj, NULL, TO_CHAR);
			((I_GEM *) obj->more)->max_level += number_range(1,10);
		      }
		  }
	      }
	  }
	break;
	}
    }
  return;
}



void 
spell_wind_breath (int level, CHAR_DATA * ch, void *vo)
{
  CHAR_DATA *victim = (CHAR_DATA *) vo;
   if (((ch->in_room->vnum >= BATTLEGROUND_START_VNUM) && (ch->in_room->vnum <= BATTLEGROUND_END_VNUM)) || IS_PROT (victim, WIND))
  return;
  if (number_percent () < level && !saves_spell (level, victim))
    {
      if ((number_range (1,50) == 5) && IS_AFF(victim,
INVIS))
	{
	  affect_strip_bits (victim, AFF, INVIS);
	  send_to_char("Everyone can SEE you now!\n\r", victim);
	}
      if ((number_range (1,50) == 5) && IS_AFF(victim, FLYING))
	{
	  affect_strip_bits (victim, AFF, FLYING);
	  send_to_char("You fall back down to the ground!\n\r", victim);
	}
      if (number_range (1,50) == 5 && IS_AFF(victim, HIDE))
	{
	  affect_strip_bits (victim, AFF, HIDE);
	  send_to_char("The burst of air uncovers your hiding place!\n\r", victim);
	}
      if ((number_range (1,50) == 5) && IS_AFF(victim, SNEAK))
	{
	  affect_strip_bits (victim, AFF, SNEAK);
	  send_to_char("The wind makes you stumble and crash!\n\r", victim);
	}
      if ((number_range (1,50) == 5) && IS_DET(victim, DARK))
	{
	  affect_strip_bits (victim, DET, DARK);
	  send_to_char("The dust swirls in your eyes, ruining your night vision!\n\r", victim);
	}
      if ((number_range (1,50) == 5) && IS_DET(victim,INVIS))
	{
	  affect_strip_bits (victim, DET, INVIS);
	  send_to_char("The massive storm obscures your sensitive vision!\n\r", victim);
	}
      if ((number_range (1,50) == 5) && IS_DET(victim,HIDE))
	{
	  affect_strip_bits (victim, DET, HIDE);
	  send_to_char("The wind makes it impossible to detect movements in the woods!\n\r", victim);
	}
    }
  /*  JRAJRAJRA */
  return;
}


void
do_trapset (CHAR_DATA *ch, char *argy)
{
  
SINGLE_OBJECT *obj;
SINGLE_OBJECT *cont;
int door; 
char arg1[SML_LENGTH];
  DEFINE_COMMAND ("trapset", do_trapset, POSITION_STANDING, 0, LOG_NORMAL, "Creates a trap in the room!")
    WAIT_STATE (ch, 35);
  
  if (!ch || !ch->in_room) return;
  if ((obj = get_item_held(ch, ITEM_TRAP)) == NULL)
    {
      send_to_char("You must be holding a trap in order to set it!\n\r", ch);
      return;
    }
  if (ch->position != POSITION_STANDING)
    {
      send_to_char("You must be standing to set a trap!\n\r", ch);
      return;
    }
  argy = one_argy(argy, arg1);
  if ((door = get_direction_number(arg1)) < DIR_MAX)
    {
      EXIT_DATA *pexit;
      if ((pexit = ch->in_room->exit[door]) == NULL || 
	  !pexit->to_room ||
	  !pexit->d_info ||
	  IS_SET (pexit->d_info->exit_info, EX_ISWALL))
	{
	  send_to_char("What are you doing? There is no exit there.\n\r",ch); 
	  return;
	}
      if (pexit->d_info && pexit->d_info->trap)
	{
	  send_to_char ("That exit already has a trap!\n\r", ch);
	  set_off_trap(ch, NULL, door);
	  obj_from(obj);
	  free_it(obj);
	  return;
	}
      if (!IS_SET(((I_TRAP *)obj->more)->location, TRAP_FOR_DOOR))
	{
	  send_to_char("This is the wrong kind of trap to use on an exit!\n\rYou ruin it trying to set it.", ch);
	  obj_from(obj);
	  free_it(obj);
	  return;
	}
      if(number_range(1,12) == 3 || !check_skill(ch, gsn_trapset))
	{
	  send_to_char("You failed to set the trap.\n\r", ch);
	  obj_from(obj);
	  free_it(obj);
	  return;
	}
      if (!pexit->d_info)
	pexit->d_info = new_door();
      pexit->d_info->trap = ((I_TRAP *)obj->more)->type;
      obj_from(obj);
      free_it(obj);
      send_to_char("Ok, the door is now trapped.\n\r", ch);
      return;
    }      
  if (arg1[0] == '\0' || argy == "" || !str_cmp(argy, "room"))
    {
      if (ch->in_room->trap > 0)
	{
	  send_to_char("There was already a trap here!\n\r", ch);
	  set_off_trap(ch, NULL, MAX_DIR);
	  obj_from  (obj);
	  free_it (obj);
	  return;
	}
      if (!IS_SET(((I_TRAP *)obj->more)->location, TRAP_FOR_ROOM))
	{
	  send_to_char("This is the wrong kind of trap to use on a room!\n\rYou ruin it trying to set it.", ch);
	  obj_from(obj);
	  free_it(obj);
	  return;
	}
      if(number_range(1,12) == 3 || !check_skill(ch, gsn_trapset))
	{
	  send_to_char("You failed to set the trap.\n\r", ch);
	  obj_from(obj);
	  free_it(obj);
	  return;
	}
      ch->in_room->trap = ((I_TRAP *)obj->more)->type; 
      obj_from (obj);
      free_it (obj);
      send_to_char("Ok trap set.\n\r", ch);
      return;
    }
  if ((cont = get_obj_here (ch, arg1, SEARCH_ROOM_FIRST)) != NULL &&
      cont->pIndexData->item_type == ITEM_CONTAINER)
    {
      if (((I_CONTAINER *)cont->more)->trap_type > 0)
	{
	  send_to_char("There was already a trap on the item!\n\r", ch);
	  set_off_trap(ch, cont, 0);
	  obj_from  (obj);
	  free_it (obj);
	  return;
	}
      if (!IS_SET(((I_TRAP *)obj->more)->location, TRAP_FOR_OBJECT))
	{
	  send_to_char("This is the wrong kind of trap to use on an object!\n\rYou ruin it trying to set it.", ch);
	  obj_from(obj);
	  free_it(obj);
	  return;
	}
      if(number_range(1,12) == 3 || !check_skill(ch, gsn_trapset))
	{
	  send_to_char("You failed to set the trap.\n\r", ch);
	  obj_from(obj);
	  free_it(obj);
	  return;
	}
      ((I_CONTAINER *)cont->more)->trap_type = ((I_TRAP *)obj->more)->type; 
      obj_from (obj);
      free_it (obj);
      send_to_char("Ok trap set.\n\r", ch);
      return;
    }
  send_to_char ("Trap what? See help trapset for more information.\n\r", ch);
  return;
}


void
do_detrap (CHAR_DATA *ch, char* argy)
{
  char arg1[SML_LENGTH];
  int door;
  EXIT_DATA *pexit;
  SINGLE_OBJECT *obj;
  DEFINE_COMMAND("detrap", do_detrap, POSITION_STANDING, 0, LOG_NORMAL, "Removes a trap from the room.")
    
      if (IS_MOB(ch))
      return; 
    WAIT_STATE(ch, 5*PULSE_VIOLENCE);
    argy = one_argy(argy, arg1);
 
  if(arg1[0] == '\0' || arg1 == "")
    {
      send_to_char("Detrap what?\n\r", ch);
      return;
    }
  if ((door = get_direction_number (arg1)) != DIR_MAX)
    {
      if ((pexit = ch->in_room->exit[door]) == NULL)
	{
	  send_to_char("There is no exit in that direction to detrap!\n\r", ch);
	  return;
	}
      if (!pexit->d_info || !pexit->d_info->trap)
	{
	  send_to_char("That exit is not trapped!\n\r", ch);
	  return;
	}
      else 
	{
	  if (check_skill(ch, gsn_detrap))
	    {
	      send_to_char("Ok, trap removed successfully.\n\r", ch);
	      pexit->d_info->trap = 0;
	      return;
	    }
	  else
	    { 
	      send_to_char ("Oops.\n\r", ch);
	      set_off_trap (ch, NULL, door);
	      return;
	    }
	}
    }
  if(!str_cmp(arg1, "room"))
    {
      if(ch->in_room->trap == 0)
	{
	  send_to_char("There is no trap here to remove!\n\r", ch);
	  return;
	}
      if(check_skill(ch, gsn_detrap))
	{
	  ch->in_room->trap = 0;
	  send_to_char("Ok, the room has been detrapped.\n\r", ch);
	  return;
	} 
      else 
	{
	  send_to_char ("Oops.\n\r", ch);
	  set_off_trap (ch, NULL, MAX_DIR);
	  return;
	  
	}
    }
  if ((obj = get_obj_here (ch, arg1, SEARCH_INV_FIRST)) != NULL)
    {
      if (obj->pIndexData->item_type != ITEM_CONTAINER)
	{
	  send_to_char ("That's not a container.\n\r", ch);
	  return;
	}
      else
	{
	  I_CONTAINER *con = (I_CONTAINER *) obj->more;
	  if (con->trap_type == 0)
	    {
	      send_to_char("This container is not trapped.\n\r", ch);
	      return;
	    }
	  else
	    {
	      if (check_skill(ch, gsn_detrap))
		{
		  con->trap_type = 0;
		  send_to_char("Ok, trap removed successfully.\n\r", ch);
		  return;
		}
	      else
		{
		  set_off_trap (ch, obj, 0);
		  return;
		} 
	    }
	}
    }
  else
    {
      send_to_char("Exactly what do you think is trapped in this room?\n\r", ch);
      return;
    }
return;
}

void 
set_off_trap (CHAR_DATA *ch, SINGLE_OBJECT *cont, int direction)
{
  CHAR_DATA *vict, *victn;
  int aff;
  char ch_msg[SML_LENGTH];
  char other_msg[SML_LENGTH];
  char trap_name[STD_LENGTH];
  char ch_death_message[SML_LENGTH];
  char other_death_message[SML_LENGTH];
  char damage_name[SML_LENGTH];
  char ch_buf[SML_LENGTH];
  char other_buf[SML_LENGTH];
  bool armor_stops = FALSE;
  bool area_trap = FALSE;
  bool destroy_target = FALSE;
  int type = 0;
  int damage = 0;
  int i;
  char *t;
  bool once = FALSE;

  ch_msg[0] = '\0';
  other_msg[0] = '\0';
  ch_buf[0] = '\0';
  other_buf[0] = '\0';

  if (!ch->in_room) 
    return;

  sprintf(damage_name, "trap");
  sprintf(ch_death_message, "$t killed you!\n\r");
  sprintf (other_death_message, "$t killed $n!");
  sprintf (trap_name, "a trap");
  if (cont == NULL)
    {
      if (direction < MAX_DIR && direction >= 0)
	{
	  if (ch->in_room->exit[direction] && 
	      ch->in_room->exit[direction]->d_info)
	    {
	      type = ch->in_room->exit[direction]->d_info->trap;
	      ch->in_room->exit[direction]->d_info->trap = 0;
	      if (ch->in_room->exit[direction]->d_info->keyword)
                sprintf(trap_name, "the %s",ch->in_room->exit[direction]->d_info->keyword);
	      else
                sprintf(trap_name, "the door");
	    }
	  switch (type)
	    {
	    case 1:
	      area_trap = TRUE; 
              sprintf(ch_msg, "As you open %s, you hear a weird hissing sound. Before you know it, the air is filled with $2n$B$2o$B$0xio$B$2u$R$2s$R fumes!", trap_name);
              sprintf(other_msg, "As $n opens %s, you hear a weird hissing sound. Before you know it, the air is filled with $2n$B$2o$B$0xio$B$2u$R$2s$R fumes!", trap_name);
              damage = number_range(100,300);
	      aff = POISON;
	      sprintf (damage_name, "noxious fumes");
	      break;
	    case 2:
	      armor_stops = TRUE;
              sprintf(ch_msg, "As you open %s, you hear a weird clicking noise. Before you know it, a spiked trap catches your hand! Pain shoots up your arm making you scream in agony!", trap_name);
              sprintf(other_msg, "As $n opens %s, you hear a weird clicking noise. Before you know it, a spiked trap catches $n's hand making $s scream in agony!", trap_name);
              damage = number_range(100,250);
	      aff = FUMBLE;
	      sprintf (damage_name, "spiked trap");
	      break;
	    case 3:
	      area_trap = TRUE; 
	      armor_stops = TRUE;
              sprintf(ch_msg, "As you open %s, hear some strange noises. Before you have time to do anything, you see hundreds of tiny sharp metal shards exploding in the air, penetrating every part of your body.", trap_name);
              sprintf(other_msg, "As $n opens %s, you notice a perplex look on $s face. Before you have time to do anything, you see hundreds of tiny sharp metal shards exploding in the air, penetrating every part of your body.", trap_name);
              damage = number_range(300,400);
	      aff = WOUND;
	      sprintf(damage_name, "shards");
	      break;
	    case 4:
	      area_trap = TRUE; 
	      armor_stops = TRUE; 
	      destroy_target = TRUE;
              sprintf(ch_msg, "As you open %s, you start smelling the odor of $B$0black$R$7 powder. Before you know it, you triggered a trap making %s explode. The heat of the explosion and the fragments flying in the air causes you tremendous pain!", trap_name, trap_name);
              sprintf(other_msg, "As $n opens %s, you start smelling the ordor of $B$0black$R$7 powder. Before you know it, $n triggered a trap making %s explode . The heat of the explosion and the fragments flying in the air causes you tremendous pain!", trap_name, trap_name);
              damage = number_range(400,500);
	      aff = WOUND | LETHARGY;
	      sprintf (damage_name, "explosion");
	      break;
	    case 5:
	      area_trap = TRUE;
              sprintf(ch_msg, "As you open %s, you hear a weird hissing sound. Before you know it, the air is filled by an $B$2a$R$2cidi$Bc$R fog, burning your skin and your lungs!", trap_name);
              sprintf(other_msg, "As $n opens %s, you hear a weird hissing sound. Before you know it, the air is filled by an $B$2a$R$2cidi$Bc$R fog, burning your skin and your lungs!", trap_name);
	      sprintf (damage_name, "acid fog");
              damage = number_range(400, 700);
	      aff = POISON;
	      break;
	    case 6:
	      area_trap = TRUE;
	      armor_stops = TRUE; 
              sprintf(ch_msg, "As you open %s, you hear some strange noises. You suddently feel a breath of burning $B$3sand$R filling the air. You cough and gag for air while groping at your eyes!", trap_name);
              sprintf(other_msg, "As $n opens %s, you notice a perplex look on $s face. Before you have time to do anything, you feel a breath of burning $B$3sand$R filling the air. You cough and gag for air while groping at your eyes!", trap_name);
              damage = number_range(100, 120);
	      aff = BLIND;
	      sprintf (damage_name, "burning sand");
	      break;
	    case 7:
	      area_trap = TRUE;
              sprintf(ch_msg, "As you open %s, you hear some strange noises. Before you have time to do anything, a cloud of a $B$3yellowish$R gas starts filling up the air. You try to run but sense it is impossible to move any limb of your body!", trap_name);
              sprintf(other_msg, "As $n opens %s, you notice a perplex look on $s face. Before you have time to do anything, a cloud of a $B$3yellowish$R gas starts filling up the air. You try to run but sense it is impossible to move any limb of your body!", trap_name);
              damage = number_range(60, 70);
	      aff = PARALYZE;
	      sprintf (damage_name, "paralyzing gas");
	      break;
	      return;
	    }
	}
      else if (direction == MAX_DIR)
	{
	  if (ch->in_room)
	    {
	      type = ch->in_room->trap;
	      ch->in_room->trap = 0;
	    }
	  sprintf (trap_name, "a trap");
	  switch (type)
	    {
	    case 1:
	      area_trap = TRUE; 
	      sprintf(ch_msg, "As you walk in, you hear a weird hissing sound. Before you know it, the air is filled with $2n$B$2o$B$0xio$B$2u$R$2s$R fumes!");
	      sprintf(other_msg, "As $n walks in, you hear a weird hissing sound. Before you know it, the air is filled with $2n$B$2o$B$0xio$B$2u$R$2s$R fumes!");
	      damage = number_range(100,300);
	      aff = POISON;
	      sprintf (damage_name, "noxious fumes");
	      break;
	    case 2:
	      armor_stops = TRUE;
	      sprintf(ch_msg, "As you walk in, you hear a weird clicking noise. Before you know it, a spiked trap catches your foot! Pain shoots up your leg making you scream in agony!");
	      sprintf(other_msg, "As $n walks in, you hear a weird clicking noise. Before you know it, a spiked trap catches $n's foot making $s scream in agony!");
	      damage = number_range(100,250);
	      aff = FUMBLE;
	      sprintf (damage_name, "spiked trap");
	      break;
	    case 3:
	      area_trap = TRUE; 
	      armor_stops = TRUE;
	      sprintf(ch_msg, "As you walk in, you notice a small $Bwhite$R pouch lying on the ground. Before you know it, the pouch explodes into a hundreds of tiny sharp metal shards, penetrating every part of your body.");
	      sprintf(other_msg, "As $n walks in, you notice a perplex look on $s face. Before you have time to do anything, you see hundreds of tiny sharp metal shards exploding in the air, penetrating every part of your body.");
	      damage = number_range(300,400);
	      aff = WOUND;
	      sprintf(damage_name, "shards");
	      break;
	    case 4:
	      area_trap = TRUE; 
	      armor_stops = TRUE; 
	      sprintf(ch_msg, "As you walk in, you start smelling the odor of $B$0black$R$7 powder. Before you know it, you triggered a trap making a small pouch explode. The heat of the explosion and the fragments flying in the air causes you tremendous pain!");
	      sprintf(other_msg, "As $n walks in, you start smelling the ordor of $B$0black$R$7 powder. Before you know it, $n triggered a trap making a small pouch explode. The heat of the explosion and the fragments flying in the air causes you tremendous pain!");
	      damage = number_range(400,500);
	      aff = WOUND | LETHARGY;
	      sprintf (damage_name, "explosion");
	      break;
	    case 5:
	      area_trap = TRUE;
	      sprintf(ch_msg, "As you walk in, you hear a weird hissing sound. Before you know it, the air is filled by an $B$2a$R$2cidi$Bc$R fog, burning your skin and your lungs!");
	      sprintf(other_msg, "As $n walks in, you hear a weird hissing sound. Before you know it, the air is filled by an $B$2a$R$2cidi$Bc$R fog, burning your skin and your lungs!");
	      sprintf (damage_name, "acid fog");
	      damage = number_range(400, 700);
	      aff = POISON;
	      break;
	    case 6:
	      area_trap = TRUE;
	      armor_stops = TRUE; 
	      sprintf(ch_msg, "As you walk in, you notice a $3brown$R pouch lying on the ground. Before you know it the pouch explodes. You suddently feel a breath of burning $B$3sand$R filling the air. You cough and gag for air while groping at your eyes!");
	      sprintf(other_msg, "As $n walks in, you notice a perplex look on $s face. Before you have time to do anything, you feel a breath of burning $B$3sand$R filling the air. You cough and gag for air while groping at your eyes!");
	      damage = number_range(100, 120);
	      aff = BLIND;
	      sprintf (damage_name, "burning sand");
	      break;
	    case 7:
	      area_trap = TRUE;
	      sprintf(ch_msg, "As you walk in, you notice a $B$0black$R canister lying on the ground. Before you know it, the canister opens and a $B$3yellowish$R gas starts filling up the air. You try to run but sense it is impossible to move any limb of your body!");
	      sprintf(other_msg, "As $n walks in, you notice a perplex look on $s face. Before you have time to do anything, a cloud of a $B$3yellowish$R gas starts filling up the air. You try to run but sense it is impossible to move any limb of your body!");
	      damage = number_range(60, 70);
	      aff = PARALYZE;
	      sprintf (damage_name, "paralyzing gas");
	      break;
	    case 8:
	      armor_stops = TRUE;
	      sprintf(ch_msg, "As you walk in, you hear a faint mechanical noise. Suddenly a large blade pops out of the ground and slices you across the abdomen, leaving a deep cut.");
	      sprintf(other_msg, "As $n walk in, you hear a faint mechanical noise. Suddenly a large blade pops out of the ground and slices $n across the abdomen, leaving a deep cut.");
	      damage = number_range(2,300);
	      aff = BURNING;
	      sprintf (damage_name, "sharp blade");
	      break;
	      return;
	    }
	}
      if (type == 0)
        return;
    }
  else
    {
      type = ((I_CONTAINER *)cont->more)->trap_type;
      sprintf(trap_name, "%s", OOSTR (cont, short_descr));
      switch (type)
	{
	case 1:
          area_trap = TRUE; 
          sprintf(ch_msg, "As you open %s, you hear a weird hissing sound. Before you know it, the air is filled with $2n$B$2o$B$0xio$B$2u$R$2s$R fumes!", trap_name);
          sprintf(other_msg, "As $n opens %s, you hear a weird hissing sound. Before you know it, the air is filled with $2n$B$2o$B$0xio$B$2u$R$2s$R fumes!", trap_name);
          damage = number_range(100,300);
	  aff = POISON;
	  sprintf (damage_name, "noxious fumes");
          break;
	case 2:
	  armor_stops = TRUE;
          sprintf(ch_msg, "As you open %s, you hear a weird clicking noise. Before you know it, a spiked trap catches your fingers and pain shoots up your hands making you scream in agony!", trap_name);
          sprintf(other_msg, "As $n opens %s, you hear a weird clicking noise. Before you know it, a spiked trap catches $n's fingers making $s scream in agony!", trap_name);
          damage = number_range(100,250);
	  aff = FUMBLE;
	  sprintf (damage_name, "spiked trap");
	  break;
	case 3:
	  area_trap = TRUE; 
	  armor_stops = TRUE;
          sprintf(ch_msg, "As you open %s, you notice a small $Bwhite$R pouch lying in the bottom. Before you know it, the pouch explodes into a hundreds of tiny sharp metal shards, penetrating every part of your body.", trap_name);
          sprintf(other_msg, "As $n opens %s, you notice a perplexed look on $s face. Before you have time to do anything, you see hundreds of tiny sharp metal shards exploding in the air, penetrating every part of your body.", trap_name);
          damage = number_range(300,400);
	  aff = WOUND;
	  sprintf(damage_name, "shards");
	  break;
	case 4:
	  area_trap = TRUE; 
	  armor_stops = TRUE; 
          destroy_target = TRUE;
          sprintf(ch_msg, "As you open %s, you start smelling the odor of $B$0black$R$7 powder. Before you know it, you triggered a trap making the container explode. The heat of the explosion and the fragments flying in the air causes you tremendous pain!", trap_name);
          sprintf(other_msg, "As $n opens %s, you start smelling the odor of $B$0black$R$7 powder. Before you know it, $n triggered a trap making the container explode. The heat of the explosion and the fragments flying in the air causes you tremendous pain!", trap_name);
          damage = number_range(400,500);
	  aff = WOUND | LETHARGY;
	  sprintf (damage_name, "explosion");
	  break;
	case 5:
	  area_trap = TRUE;
          sprintf(ch_msg, "As you open %s, you hear a weird hissing sound. Before you know it, the air is filled by an $B$2a$R$2cidi$Bc$R fog, burning your skin and your lungs!", trap_name);
          sprintf(other_msg, "As $n opens %s, you hear a weird hissing sound. Before you know it, the air is filled by an $B$2a$R$2cidi$Bc$R fog, burning your skin and your lungs!", trap_name);
	  sprintf (damage_name, "acid fog");
          damage = number_range(400, 700);
	  aff = POISON;
	  break;
	case 6:
	  area_trap = TRUE;
	  armor_stops = TRUE; 
          sprintf(ch_msg, "As you open %s, you notice a $3brown$R pouch lying in the bottom. Before you know it the pouch explodes. You suddently feel a breath of burning $B$3sand$R filling the air. You cough and gag for air while groping at your eyes!", trap_name);
          sprintf(other_msg, "As $n opens %s, you notice a perplex look on $s face. Before you have time to do anything, you feel a breath of burning $B$3sand$R filling the air. You cough and gag for air while groping at your eyes!", trap_name);
          damage = number_range(100, 120);
	  aff = BLIND;
	  sprintf (damage_name, "burning sand");
	  break;
	case 7:
	  area_trap = TRUE;
          sprintf(ch_msg, "As you open %s, you notice a $B$0black$R canister in the bottom. Before you know it, the canister opens and a $B$3yellowish$R gas starts filling up the air. You try to run but sense it is impossible to move any limb of your body!", trap_name);
          sprintf(other_msg, "As $n opens %s, you notice a perplex look on $s face. Before you have time to do anything, a cloud of a $B$3yellowish$R gas starts filling up the air. You try to run but sense it is impossible to move any limb of your body!", trap_name);
          damage = number_range(60, 70);
	  aff = PARALYZE;
	  sprintf (damage_name, "paralyzing gas");
	  break;
	  return;
	}
    }     
  if (ch_msg[0] != '\0')   
    act(ch_msg, ch, NULL, NULL, TO_CHAR);
  if (other_msg[0] != '\0') 
    act(other_msg, ch, NULL, NULL, TO_ROOM);
  
  if (area_trap)
    vict = ch->in_room->people;
  else
    vict = ch;
  for (i = 0; i < 20; i++)
    {
      if (damage >= dmsg.generic_range[i][0] &&
	  damage < dmsg.generic_range[i][1])
	{
	  strcpy(ch_buf, dmsg.gen_m2[i]);
	  strcpy(other_buf, dmsg.gen_m1[i]);
	  sprintf (ch_buf, damage_name);
	  sprintf (other_buf, damage_name);
	  break;
	}
    }
  for (i = 0; i < 2; i++)
    {
      for (t = (i == 0 ? ch_buf : other_buf); *t; t++)
	{
	  if (*t == '$')
	    {
	      t++;
	      switch (*t)
		{
		case 'n':
		  *t = 't';
		  break;
		case 'N':
		  *t = 'n';
		  break;
		case 'S':
		  *t = 's';
		  break;
		case 'M':
		  *t = 'm';
		  break;
		case 'E':
		  *t = 'e';
		  break;
		}
	    }
	}
    }
  for (; (vict && (!once || area_trap)); vict = victn)
    {
      victn = vict->next_in_room;
      once = TRUE;
      damage -= (armor_stops ? (vict->armor/10 + 
                (IS_PLAYER(vict) ? vict->pcdata->armor[3] : 0)) : 0);    
      if (damage < 2) damage = 2;
      vict->hit -= damage;
      act (ch_buf, vict, trap_name, NULL, TO_CHAR);            
      act (other_buf, vict, trap_name, NULL, TO_ROOM);            
      if (vict->hit < 0)
	{
	  if (IS_PLAYER(vict) && LEVEL(vict) > IMM_LEVEL)
	    MAXHIT(vict);
	  else
	    {
	      act (ch_death_message, vict, trap_name, NULL, TO_CHAR);
	      act (other_death_message, vict, trap_name, NULL, TO_ROOM);
	      raw_kill(vict, FALSE);
	    }
	}
      else
	{
	  AFFECT_DATA paf;
	  bzero(&paf, sizeof(paf));
	  paf.type = gsn_trapset;
	  paf.aff[HURT] = aff;
	  paf.location = 0;
	  paf.modifier = 0;
	  paf.aff[1] = 0;
	  paf.aff[2] = 0;
	  paf.aff[3] = 0;
	  paf.duration = 5 + number_range(1,4);
	  renew_affect(vict, &paf);
	  WAIT_STATE(vict, 2*PULSE_VIOLENCE);
	}
    }
  if (destroy_target && cont && cont->pIndexData->item_type == ITEM_CONTAINER)
    {
      obj_from(cont);
      free_it(cont);
    }
  else if (cont && cont->pIndexData->item_type == ITEM_CONTAINER)
    ((I_CONTAINER *)cont->more)->trap_type = 0;
  return;
}