//Traps- Paarshad 
//
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <limits.h>
#include "merc.h"
#include "interp.h"
#include "obj_trig.h"
#include "olc.h"
#include "recycle.h"
#include "tables.h"
#include "clans/new_clans.h"

#define MAX_NUM_TRAPS 5

extern bool crit_strike_possible;
// Trap type, Spectator message, Victim message, Num Dice, Dice Size, Dice modified (ie +23 damage), Dam Type 

const struct trap_info_type trapinfo [] = {
 {TRAP_O_PLAIN, 0,
 "A trap goes off.``\n\r",
 "A trap goes off causing you immense pain.``\n\r",
  16,7,10, "slice" //AVG 84
 },
 {TRAP_O_BLADE, 0,
 "`bIn the blink of an eye tiny razor blades fly past you leaving tiny cuts all over $n.``\n\r",
 "`bRazor blades explode towards you, cutting you badly.``\n\r",
  16,7,10, "slice" //AVG 84
 },
 {TRAP_O_NEEDLE, TFLAG_POISON ,
 "From a concealed box, a needle shoots out embedding itself in $n's skin.\n\r",
 "A needle stabs into your skin, causing you to feel ill.\n\r",
  8,7,5, "pierce" // AVG 42
 },
 {TRAP_O_BEE, TFLAG_BEE ,
 "A jar of bees shatters as they swarm around.\n\r",
 "A jar of bees shatters as the begin stinging you.\n\r",
 12,9,15, "bite" //AVG 90
 },
 {TRAP_O_EXPLODING, TFLAG_AREA, 
 "Flames encircle the room burning everything.\n\r",
 "Flames rush towards you searing your flesh.\n\r",
 8,7,10, "flame" // AVG 76
 },
 {TRAP_P_PLAIN, 0,
 "A trap goes off.``\n\r",
 "A trap goes off causing you immense pain.``\n\r",
  16,7,10, "slice" //AVG 84
 },
 {TRAP_P_ROCK, TFLAG_KNOCK, 
 "As $n walks forward, an onslaught of rocks falls on $m.\n\r",
 "A grinding sound is soon accompanied by rocks falling on your head.\n\r",
 16,9,9, "crush" // AVG 98
 },
 {TRAP_P_DART, TFLAG_DISORIENT, 
 "A dart shoots from a corner sticking into $n's neck.\n\r",
 "A dart flies into your neck, causing the world to spin.\n\r",
 10,5,10, "pierce" //AVG 50
 },
 {TRAP_P_EXPLODING, TFLAG_AREA,
 "Flames encircle the room burning everything.\n\r",
 "Flames rush towards you searing your flesh.\n\r",
 18,9,10, "flame" // AVG 110
 },
 {TRAP_P_SPIKES, 0,
 "A pair of masterfully aligned spikes leap from the doorway, impaling %n.\n\r",
 "The taste of blood enters your mouth as two spikes impale you.\n\r",
 20,7,16, "stab" // AVG 112
 },
 {TRAP_P_ALARM,0,"","",0,0,0,"bash"},
 {TRAP_R_PLAIN, 0,
 "A trap goes off.``\n\r",
 "A trap goes off causing you immense pain.``\n\r",
  16,7,10, "slice" //AVG 84
 },
 {TRAP_R_SPIKEPIT, 0,
 "`bThe ground gives way under $n.``\n\r",
 "`bThe ground gives way under your feet and you fall into a bed of spikes.``\n\r",
 20,11,13, "stab" // AVG 146
 },
 {TRAP_R_LOG, 0,
 "`bA huge log slices through the air, hitting $n square in the chest knocking $m back.``\n\r",
 "`bPains grips your entire body as a large log smacks you square in the chest.``\n\r",
 16,13,11, "smash" // AVG  134
 },
 {TRAP_R_LANDMINE, TFLAG_AREA,
 "`bShrapnel flies through the room, barely missing you.``\n\r",
 "`bA subtle click, a second before, warned of the maelstrom of shrapnel flying through you..``\n\r",
 18,9,17, "flame" // AVG 124
 },
 {TRAP_R_SPIKESNARE, TFLAG_SNARE, 
 "`bA thin coil of barbed wire wraps around $n's leg lifting $m into the air.``\n\r",
 "`bThe world turns upside as the flesh on your leg is torn upwards over your head.``\n\r",
 6,5,10, "stab" //AVG 36
 },
 {TRAP_R_ALARM,0,"","",0,0,0,"bash"},
 {-1,0,NULL,NULL,0,0,0,NULL}
};

int trap_info_lookup(int traptype)
{
  int flag;
  for (flag = 0; trapinfo[flag].type != -1; flag++)
  	if (trapinfo[flag].type == traptype)
		return flag;
  return NO_FLAG;
}
char * get_spec_mess(OBJ_DATA *obj)
{
char *smess;
EXTRA_DESCR_DATA *ed;

	 // Get Spectator message or put one in from the trap type
	for (ed = obj->extra_descr; ed; ed = ed->next)
	{
		if (is_name ("specmessage", ed->keyword) )
		break;
	}
	smess = ed->description;
	if (smess == NULL)
	{
		smess = strdup("(smess) HRM Paarshad should really put something here.\n\r");
	}
return smess;	
}
char * get_vict_mess(OBJ_DATA *obj)
{
char *vmess;
EXTRA_DESCR_DATA *ed;

	 // Get Spectator message or put one in from the trap type
	for (ed = obj->extra_descr; ed; ed = ed->next)
	{
		if (is_name ("victmessage", ed->keyword) )
		break;
	}
	vmess = ed->description;
	if (vmess == NULL)
	{
		vmess = strdup("(vmess) HRM Paarshad should really put something here.\n\r");
	}
return vmess;	
}
void spring_trap (CHAR_DATA *victim, OBJ_DATA *obj);

void trap_check(CHAR_DATA *victim,char *type, ROOM_INDEX_DATA *room, OBJ_DATA *obj)
{
OBJ_DATA *thing,*next_thing;
	if (IS_IMMORTAL(victim))
		return;
	if(room != NULL && !strcmp(type,"room"))
	{
	
		for (thing = room->contents; thing != NULL; thing = next_thing)  // BTW WIZI means its set
		{
			next_thing = thing->next_content;
			if ( (thing->item_type == ITEM_ROOM_TRAP) 
			     && IS_SET(thing->extra_flags[1],ITEM_WIZI) 
			     && ((number_percent () > (get_skill (victim, gsn_avoid_traps))*0.75 + victim->mod_stat[STAT_DEX] - thing->value[5])
			     || IS_SET(thing->value[12],TFLAG_UNAVOID) ))
			{		
				spring_trap(victim,thing);
				return;
			}
		}
	}
	if(room != NULL && 
	(
	 !strcmp(type,"door")||!strcmp(type,"north")||!strcmp(type,"east")
	 ||!strcmp(type,"south")||!strcmp(type,"west")||!strcmp(type,"up")
	 ||!strcmp(type,"down")))
	{

		for (thing = room->contents; thing != NULL; thing = next_thing)  // BTW WIZI means its set
		{
			
			next_thing = thing->next_content;
			if ( (  (thing->item_type == ITEM_PORTAL_TRAP))
			     && ( (thing->value[9] == flag_value (dir_flags, type)))
			     && IS_SET(thing->extra_flags[1],ITEM_WIZI)
			     && ((number_percent () > (get_skill (victim, gsn_avoid_traps))*0.75 + victim->mod_stat[STAT_DEX] - thing->value[5])
			     || IS_SET(thing->value[12],TFLAG_UNAVOID) ))
			{		
				spring_trap(victim,thing);
				return;
			}
		}
	
	}
	if(room != NULL && 
	(
	 !strcmp(type,"enter")||!strcmp(type,"exit")
	 ||!strcmp(type,"climb")||!strcmp(type,"crawl")
	 ||!strcmp(type,"descend")||!strcmp(type,"scale")||!strcmp(type,"jump")
	 ||!strcmp(type,"tug")))
	{
	
		for (thing = room->contents; thing != NULL; thing = next_thing)  // BTW WIZI means its set
		{
			
			next_thing = thing->next_content;
			if ( (  (thing->item_type == ITEM_PORTAL_TRAP))
			     && ( (thing->value[7] == flag_value (pact_flags, type)))
			     && IS_SET(thing->extra_flags[1],ITEM_WIZI)
			     && ((number_percent () > (get_skill (victim, gsn_avoid_traps))*0.75 + victim->mod_stat[STAT_DEX] - thing->value[5])
			     || IS_SET(thing->value[12],TFLAG_UNAVOID) ))
			{		
				spring_trap(victim,thing);
				return;
			}
		}
	}
	if (obj != NULL && !strcmp(type,"object"))
	{
		for (thing = obj->contains; thing != NULL; thing= next_thing)
		{
			next_thing = thing->next_content;
			if ( (thing->item_type == ITEM_OBJ_TRAP)  
			     && IS_SET(thing->extra_flags[1],ITEM_WIZI) 
			     && ((number_percent () > (get_skill (victim, gsn_avoid_traps))*0.75 + victim->mod_stat[STAT_DEX] - (thing->value[5]/2))
			     || IS_SET(thing->value[12],TFLAG_UNAVOID) ))
			{
				spring_trap(victim,thing);
				return;
			}
		}
	}
	 
return;
}
void trap_damage (CHAR_DATA *victim, OBJ_DATA *obj)
{
CHAR_DATA *ch = victim;
AFFECT_DATA af;
int dam;
	if (IS_SET(obj->value[12],TFLAG_SNARE))
	{

		af.where = TO_AFFECTS;
		af.type = gsn_entangle;
		af.level = obj->level;
		af.duration = 10;
		af.modifier = 0;
		af.location = 0;
		af.bitvector = 0;
		af.permaff = FALSE;
		af.composition = FALSE;
		af.comp_name = str_dup ("");
		affect_join (victim, &af);
	}
	if (IS_SET(obj->value[12],TFLAG_POISON))
	{
	  if (saves_spell (obj->level, victim, DAM_POISON))
	    {
	      act ("$n turns slightly green, but it passes.", victim, NULL, NULL,
	           TO_ROOM);
	      send_to_char ("You feel momentarily ill, but it passes.\n\r", victim);
	    }
	  else
	  {
	  af.where = TO_AFFECTS;
	  af.type = gsn_poison;
	  af.level = obj->level;
	  af.duration = obj->level;
	  af.location = APPLY_STR;
	  af.modifier = -2;
	  af.bitvector = AFF_POISON;
	  af.permaff = FALSE;
	  af.composition = FALSE;
	  if (obj->set_by != NULL)
		  af.comp_name = str_dup (obj->set_by->name);
	  else
		  af.comp_name = str_dup ("");
	  affect_join (victim, &af);
	  send_to_char ("You feel very sick.\n\r", victim);
	  act ("$n looks very ill.", victim, NULL, NULL, TO_ROOM);
	 }
	}
	if (IS_SET(obj->value[12],TFLAG_DISORIENT))
	{
	  af.where = TO_AFFECTS;
	  af.type = gsn_disorientation;
	  af.level = obj->level;
	  af.duration = 5;
	  af.location = APPLY_HITROLL;
	  af.modifier = -4;
	  af.permaff = FALSE;
	  af.bitvector = 0;
	  af.composition = FALSE;
	  af.comp_name = str_dup ("");
	  send_to_char ("The world starts spinning around you.\n\r", victim);
	  affect_join (victim, &af);
	}
	if (IS_SET(obj->value[12],TFLAG_BEE))
	{
		if (number_range (1, 100 + get_curr_stat (victim, STAT_CON) * 2) == 50 && victim->level < 92)	
		   insta_kill (victim, victim, 0, 0, 0, 0, 1);
	}
	 if (obj->value[6])
	 {
	 CHAR_DATA *mob;
	 MOB_INDEX_DATA * pMobIndex;
		pMobIndex = get_mob_index(obj->value[6]);
			
		if (pMobIndex != NULL)
		{
  	 		mob = create_mobile(pMobIndex);
			char_to_room(mob,victim->in_room);
			multi_hit (mob, victim, TYPE_UNDEFINED);
		}
	 }
	if (obj->set_by == NULL)
            ch = victim;
	else
	    ch = obj->set_by;
        

	crit_strike_possible = FALSE;
	if (IS_SET(obj->value[12],TFLAG_EXCELLENT))
	{
	  dam = (dice(obj->value[1],obj->value[2])+obj->value[3])*1.5;
	}
	else
	  dam = (dice(obj->value[1],obj->value[2])+obj->value[3]);
	dam = adjust_damage(dam);
	damage (ch, victim, dam , 0 ,attack_table[obj->value[8]].damage , FALSE);
	crit_strike_possible = TRUE;
	if (IS_SET(obj->value[12],TFLAG_KNOCK))
	{
	      victim->pcdata->knock_time = 24;
	      stop_fighting (victim, TRUE);
	      victim->position = POS_SLEEPING;
	}
	WAIT_STATE(ch,16);
}







void spring_trap (CHAR_DATA *victim, OBJ_DATA *obj)
{
CHAR_DATA *mob;
char *smess, *vmess;


	 if ( victim == NULL || IS_IMMORTAL(victim) || (obj->item_type != ITEM_ROOM_TRAP  && obj->item_type != ITEM_OBJ_TRAP && obj->item_type != ITEM_PORTAL_TRAP ) || IS_NPC(victim) || (!((victim->pcdata->loner || victim->clan != CLAN_BOGUS)) &&(obj->set_by != NULL)) )
		return;
	 if (obj->set_by != NULL && obj->set_by == victim)
		return;

	 if (obj->value[0] == TRAP_R_SPELL || obj->value[0] == TRAP_O_SPELL|| obj->value[0] == TRAP_P_SPELL)
	 {
	 	if (skill_table[obj->value[1]].spell_fun == NULL)
			return;
	 	mob = create_mobile(get_mob_index(MOB_VNUM_FAKIE));
	 	SET_BIT (mob->act, PLR_HOLYLIGHT);
		SET_BIT(mob->act2, ACT_TRAPMOB);
		if (obj->set_by != NULL)
			mob->name = strdup(obj->set_by->name);
		mob->short_descr = strdup(obj->short_descr);	 
		mob->level = obj->value[2];
	 	char_to_room(mob,victim->in_room);	
	crit_strike_possible = FALSE;
		(*skill_table[obj->value[1]].spell_fun) (obj->value[1], obj->value[2], mob, victim, skill_table[obj->value[1]].target);
	crit_strike_possible = TRUE;
		extract_char(mob,TRUE);	
	 }
	 else
	 {
		smess = get_spec_mess(obj);
		vmess = get_vict_mess(obj);
		// AREA AFFECT TYPES
		if ( IS_SET(obj->value[12], TFLAG_AREA))  
		{
		CHAR_DATA *vch;
	    CHAR_DATA *vch_next;

		      for (vch = victim->in_room->people; vch != NULL; vch = vch_next)
		        {
		            vch_next = vch->next_in_room;
			  		if ( !IS_NPC(vch) && (vch->pcdata->loner || vch->clan != CLAN_BOGUS || obj->set_by == NULL)) 
			  		{
						act (vmess, vch, obj, NULL, TO_CHAR);
						trap_damage(vch,obj);
			  		}
			  		else
						act (smess, vch, obj, NULL, TO_CHAR);
				  
				}
		}else //NON AREA AFFECT
		{
		   act (vmess, victim, obj, NULL, TO_CHAR);
  		   act (smess, victim, obj, NULL, TO_ROOM);
		   trap_damage(victim,obj);
		}
	 }
	 if (obj->item_type == ITEM_ROOM_TRAP || obj->item_type == ITEM_PORTAL_TRAP)
		 obj_from_room (obj);
	 else if (obj->item_type == ITEM_OBJ_TRAP)
		obj_from_obj(obj);
         extract_obj(obj);
	 
return;
}



void do_disarmtrap (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  bool found = FALSE;
  OBJ_DATA *obj=NULL,* container=NULL;
  argument = one_argument (argument, arg);
  argument = one_argument (argument, arg2);
   if ( arg[0] == '\0' || (strcmp(arg,"room") && strcmp(arg,"object") && strcmp(arg,"portal") )
        || ( ( !strcmp(arg,"object") || !strcmp(arg,"portal")) && arg2[0] == '\0') )  
  {
	  send_to_char ("Syntax: disarmtrap room\n\r",ch);
	  send_to_char ("        disarmtrap object [itemname]\n\r",ch);
	  return;
  }
if (!strcmp(arg,"room"))
    for (obj = ch->in_room->contents; obj != NULL; obj = obj->next_content)
    {
      if ( (obj->item_type == ITEM_ROOM_TRAP || obj->item_type == ITEM_PORTAL_TRAP) && IS_SET(obj->extra_flags[1],ITEM_WIZI))
    	break;
    }
else if (!strcmp(arg,"object"))
{
        if ((container = get_obj_carry (ch, arg2)) != NULL)
          found = TRUE;
        if (!found)
        {
                if ((container = get_obj_here (ch, arg2)) != NULL)
                        found = TRUE;
                if (!found)
                {
                        send_to_char ("You do not see that here.\n\r", ch);
                        return;
                }
        }

    for (obj = container->contains; obj != NULL; obj = obj->next_content)
    {
      if ( obj->item_type == ITEM_OBJ_TRAP && IS_SET(obj->extra_flags[1],ITEM_WIZI))
    	break;
    }
}
 if (obj == NULL)
    {
      send_to_char ("You did not find a trap.\n\r", ch);
      return;
    }
if (ch->move < ch->move*0.1)
   {
	   send_to_char ("You do not have enough energy for that.\n\r",ch);
	   return;
   }

if (obj->item_type == ITEM_OBJ_TRAP || obj->item_type == ITEM_ROOM_TRAP || obj->item_type ==
 ITEM_PORTAL_TRAP )
  {
		ch->move -= ch->max_move*.1;
                if (number_percent () < (get_skill (ch, gsn_disarm_traps)*.75+ (get_curr_stat (ch, STAT_DEX)- (obj->value[5]/2))) )
                {
                        REMOVE_BIT(obj->extra_flags[1],ITEM_WIZI);  // Trap is not active 
                        act ("$n disarms $p.", ch, obj, NULL, TO_ROOM);
                        act ("You disarm $p.", ch, obj, NULL, TO_CHAR);
                        if (obj->set_by == NULL)
			{
			         if (obj->item_type == ITEM_ROOM_TRAP)
			                 obj_from_room (obj);
			         else if (obj->item_type == ITEM_OBJ_TRAP)
			                obj_from_obj(obj);

				extract_obj(obj);
			} else  
			{
  				  if (obj->set_by != NULL)
				  {
				        if (obj == obj->set_by->trap_list)
				        {
				                obj->set_by->trap_list = obj->next_trap;
				        }
				        else
				        {
				        OBJ_DATA *prev;
			                for (prev = obj->set_by->trap_list; prev != NULL; prev = prev->next_trap)
			                {
		                        if (prev->next_trap == obj)
		                        {
		                                prev->next_trap = obj->next_trap;
		                                break;
		                        }
			          }
			          if (prev == NULL)
	        	          {
		                        bug ("do_disarmtrap: trap not found.", 0);
	                  	        return;
			          }
		        }
		}

			}

                        WAIT_STATE(ch,16);
                }else
                {
                        send_to_char("You fail and the trap fires!\n\r",ch);
			act (get_vict_mess(obj), ch, obj, NULL, TO_CHAR);
	                act (get_spec_mess(obj), ch, obj, NULL, TO_ROOM);
                       	trap_damage(ch,obj);
                        if (obj->item_type == ITEM_ROOM_TRAP)
 		                obj_from_room (obj);
		        else if (obj->item_type == ITEM_OBJ_TRAP)
                		obj_from_obj(obj);

			extract_obj(obj);
                }


  }

 
  return;
}
void do_install (CHAR_DATA * ch, char *argument)
{
  char arg[MAX_INPUT_LENGTH];
  char arg2[MAX_INPUT_LENGTH];
  char arg3[MAX_INPUT_LENGTH];
  int count=0;
  OBJ_DATA *obj,*list, *container=NULL;
  bool found;
  argument = one_argument (argument, arg);
  argument = one_argument (argument, arg2);
  argument = one_argument (argument, arg3);

  found = FALSE;
  if (!ch->pcdata->loner)
  {
	send_to_char ("The god of peace prevents you from setting traps.\n\r",ch);
	return;
  }
  if ( arg2[0] == '\0' || (strcmp(arg,"room") && strcmp(arg,"object") && strcmp(arg,"portal") )
	|| ( ( !strcmp(arg,"object") || !strcmp(arg,"portal")) && arg3[0] == '\0') )
    {
      send_to_char ("Syntax: Install room [trapname]\n\r", ch);
      send_to_char ("        Install [portal/object] [trapname] [direction/exitname/itemname]\n\r",ch);
      return;
    }
  
  if ((obj = get_obj_carry (ch, arg2)) == NULL)
    {
      send_to_char ("You do not have that trap.\n\r", ch);
      return;
    }
  if (!strcmp(arg,"object") &&  obj->item_type != ITEM_OBJ_TRAP  )
  {
	send_to_char("That is not an object trap.\n\r",ch);
	return;
  }
  if (!strcmp(arg,"room") &&  obj->item_type != ITEM_ROOM_TRAP )
  {
	send_to_char("That is not a room trap.\n\r",ch);
	return;
  }
  if (!strcmp(arg,"portal"))
  {
	if (obj->item_type != ITEM_PORTAL_TRAP )
	{
		send_to_char("That is not a portal trap.\n\r",ch);
		return;
	}
 	else if( !strcmp(arg3,"door")||strcmp(arg3,"north")||!strcmp(arg3,"east")
         ||!strcmp(arg3,"south")||!strcmp(arg3,"west")||!strcmp(arg3,"up")
         ||!strcmp(arg3,"down"))
		obj->value[9] = flag_value (dir_flags, arg3); 
	else if(!strcmp(arg3,"enter")||!strcmp(arg3,"exit")
            ||!strcmp(arg3,"climb")||!strcmp(arg3,"crawl")
            ||!strcmp(arg3,"descend")||!strcmp(arg3,"scale")||!strcmp(arg3,"jump")
            ||!strcmp(arg3,"tug")) 
	  	obj->value[7] = flag_value(pact_flags,arg3);
	else
	{
		send_to_char("Available exitnames are enter, exit, climb, crawl, descend, scale, jump, and tug.\n\r",ch);
		return;
	}

  }
   
  if (!strcmp(arg,"object"))
{
	if ((container = get_obj_carry (ch, arg3)) != NULL)
          found = TRUE;
  	if (!found)
	{
      		if ((container = get_obj_here (ch, arg3)) != NULL)
        		found = TRUE;
      		if (!found)
        	{
          		send_to_char ("You do not see that here.\n\r", ch);
          		return;
        	}
    	}
  if (container->item_type != ITEM_CONTAINER
      && container->item_type != ITEM_PACK
      && container->item_type != ITEM_PLAYER_DONATION
      && container->item_type != ITEM_NEWCLANS_DBOX
      && container->item_type != ITEM_CLAN_DONATION
      && container->item_type != ITEM_QUIVER)
        {
	send_to_char("You can only trap containers.\n\r",ch);
	return;
  	}
  if ((container->item_type == ITEM_CLAN_DONATION) ||
      (container->item_type == ITEM_NEWCLANS_DBOX))
    {
      if (container->value[0] != -1)
        if (get_obj_number (container) >= container->value[0])
          {
            send_to_char ("Sorry, the clan donation box is full.\n\r", ch);
            return;
          }
    }
  if (container->item_type == ITEM_PLAYER_DONATION)
    {
      if (container->value[0] != -1)
        if (get_obj_number (container) >= container->value[0])
          {
            send_to_char ("Sorry, that box is full.\n\r", ch);
            return;
          }
    }
      if (container->item_type != ITEM_CLAN_DONATION
          && container->item_type != ITEM_NEWCLANS_DBOX
          && container->item_type != ITEM_PLAYER_DONATION
          && container->item_type != ITEM_QUIVER)
        {
          if (get_obj_weight (obj) +
              get_true_weight (container) > (container->value[0] *
                                             10) || get_obj_weight (obj)
              > (container->value[3] * 10))
            {
              send_to_char ("It won't fit.\n\r", ch);
              return;
            }
        }
       if (container->pIndexData->vnum == OBJ_VNUM_PENTAGRAM
           && container->plr_owner && str_cmp(container->plr_owner,ch->name))
       {
          send_to_char("Only the necromancer who drew that pentagram can put objects in it.\n\r", ch);
          return;
       }

  
}
for (list = ch->trap_list;list != NULL;list = list->next_trap)
	count++;

if (count >= MAX_NUM_TRAPS)
{
	send_to_char ("You have reached the limit of traps you may install at once.\n\r",ch);
	return;
}

if (obj->item_type == ITEM_OBJ_TRAP || obj->item_type == ITEM_ROOM_TRAP || obj->item_type == ITEM_PORTAL_TRAP ) 	
  {
	if (IS_SET(obj->extra_flags[1],ITEM_WIZI)) 
	{
		send_to_char("This trap is already set, why are you holding it?\n\r",ch);
	}else
	{
		if (number_percent () < (get_skill (ch, gsn_create_traps)*.75+ (get_curr_stat (ch, STAT_DEX)- (obj->value[5]/2))) )
		{
			
			act ("$n installs $p.", ch, obj, NULL, TO_ROOM);
			act ("You install $p.", ch, obj, NULL, TO_CHAR);
			found = TRUE;
			obj->value[5] = get_curr_stat (ch,STAT_DEX);
			if (number_percent() < 5)
				SET_BIT(obj->value[12],TFLAG_NODISARM);
			
			if (number_percent() < 30)
			{
				SET_BIT(obj->value[12],TFLAG_EXCELLENT);
				obj->value[5] = UMIN(obj->value[5]+3,25);
			}
			if (!strcmp(arg,"room") || !strcmp(arg,"portal"))
			{
				obj_from_char (obj);
				obj_to_room (obj, ch->in_room);
			}
			else if (!strcmp(arg,"object"))
			{
      				obj_from_char (obj);
				obj_to_obj (obj, container);
			}
			SET_BIT(obj->extra_flags[1],ITEM_WIZI);  // Trap is installed
			obj->set_by = ch;
			WAIT_STATE(ch,16);
			if (ch->trap_list==NULL)
			{
				ch->trap_list = obj;
				obj->next_trap = NULL;
			}else
			{
				obj->next_trap = ch->trap_list;
				ch->trap_list = obj;
			}
		}else
		{
			send_to_char("The trap backfires!\n\r",ch);
			act (get_vict_mess(obj), ch, obj, NULL, TO_CHAR);
	                act (get_spec_mess(obj), ch, obj, NULL, TO_ROOM);
			trap_damage(ch,obj);
		}
		
				
	}
} else send_to_char("That is not a trap.\n\r",ch);
    
  return;
}

bool detect_room_trap (CHAR_DATA *ch, ROOM_INDEX_DATA * room)
{
OBJ_DATA *obj;
if (get_skill (ch,gsn_detect_traps) < 1)
	return FALSE;
for (obj = room->contents; obj != NULL; obj = obj->next_content)
    {
      if ( (( obj->item_type == ITEM_ROOM_TRAP 
           || obj->item_type == ITEM_PORTAL_TRAP )) 
	&& IS_SET(obj->extra_flags[1],ITEM_WIZI)
	&& (number_percent () < (get_skill (ch, gsn_detect_traps)*.75+ (get_curr_stat (ch, STAT_INT))) )
	&& !IS_SET(obj->value[12],TFLAG_NODETECT))
		return TRUE;
        	
    }

   return FALSE;	
}

bool detect_obj_trap (CHAR_DATA *ch,OBJ_DATA *obj)
{
OBJ_DATA *thing;
	if (obj != NULL )
	{
		for (thing = obj->contains; thing != NULL; thing= thing->next_content)
		{
			if ( (thing->item_type == ITEM_OBJ_TRAP)  
			     && IS_SET(thing->extra_flags[1],ITEM_WIZI) 
			     && number_percent () < (get_skill (ch, gsn_detect_traps))*0.75 + ch->mod_stat[STAT_INT] )
				return TRUE;
		}
	}
	return FALSE;
}