//In act_move.c, at the top, add these:

//Trap functions
bool is_trapped args((OBJ_DATA *obj));
int get_trap_type args((OBJ_DATA *obj));
void remove_trap args((OBJ_DATA *obj));
void spring_trap args((CHAR_DATA *victim, OBJ_DATA *obj));
bool save_vs_trap args((CHAR_DATA *ch, OBJ_DATA *obj));

//Then under these lines:
REMOVE_BIT (obj->value[1], CONT_CLOSED);
act ("You open $p.", ch, obj, NULL, TO_CHAR);
act ("$n opens $p.", ch, obj, NULL, TO_ROOM);

//Add these lines:
		if (is_trapped(obj))
		{
				if (!save_vs_trap(ch, obj))
				{
					spring_trap(ch, obj);
					remove_trap(obj);	
					return;
				}
				else
				{
					SEND ("You got lucky... the trap failed to spring.\n\r", ch);
					remove_trap(obj);	
					return;
				}
		}

__________________________________________________________________________________________

//Now in Merc.h add these:

#define ITEM_FIRE_TRAP		(aa)
#define ITEM_GAS_TRAP		(bb)
#define ITEM_POISON_TRAP	(cc)
#define ITEM_DART_TRAP		(dd)

//Add them under these lines:
#define ITEM_BURN_PROOF    (Y)
#define ITEM_NOUNCURSE     (Z)
__________________________________________________________________________________________

//In tables.c underneath these lines:
    {"burnproof", ITEM_BURN_PROOF, TRUE},
    {"nouncurse", ITEM_NOUNCURSE, TRUE},

//Add these lines:
	{"fire_trap", ITEM_FIRE_TRAP, TRUE},
    {"poison_trap", ITEM_POISON_TRAP, TRUE},
    {"gas_trap", ITEM_GAS_TRAP, TRUE},
    {"dart_trap", ITEM_DART_TRAP, TRUE},

__________________________________________________________________________________________

//Then make a new file called traps.c, and add all of the following to it:


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

void raw_kill args ((CHAR_DATA * victim));

typedef enum {FIRE_TRAP, POISON_TRAP, GAS_TRAP, DART_TRAP} trap_types;

int get_trap_type(OBJ_DATA *obj)
{
	int type = 0;
	
	if (IS_SET(obj->extra_flags, ITEM_FIRE_TRAP))
		type = FIRE_TRAP;
	if (IS_SET(obj->extra_flags, ITEM_POISON_TRAP))
		type = POISON_TRAP;
	if (IS_SET(obj->extra_flags, ITEM_GAS_TRAP))
		type = GAS_TRAP;
	if (IS_SET(obj->extra_flags, ITEM_DART_TRAP))
		type = DART_TRAP;
	
	return type;
}


void spring_trap(CHAR_DATA *victim, OBJ_DATA *obj)
{
	int trap_type = 0;
	int dam = 0;
	char buf[MAX_STRING_LENGTH];
	AFFECT_DATA af;
	
	trap_type = get_trap_type(obj);

	switch (trap_type)
    {
        default:
			SEND ("You got lucky... the trap failed to spring.\n\r", victim);
            return;
		case FIRE_TRAP:
			dam = dice(6,8) + 5;
			act ("A gout of flames shoots forth, searing $n!", victim, NULL, NULL, TO_ROOM);
			sprintf( buf, "A gout of flames shoots forth, searing you! {r[{x%d{r]{x\n\r", dam );			
			SEND(buf, victim);
			victim->hit -= dam;
			if (victim->hit <= 0)
				raw_kill(victim);
			return;
		case POISON_TRAP:
			dam = dice(4,8) + 5;
			act ("A poison dart springs forth, striking $n!", victim, NULL, NULL, TO_ROOM);			
			sprintf( buf, "A poison dart springs forth, striking you! {r[{x%d{r]{x\n\r", dam );			
			SEND(buf, victim);
			af.where = TO_AFFECTS;
			af.type = gsn_poison;
			af.level = number_range(25,40);
			af.duration = number_range(25,40);	
			af.location = APPLY_STR;
			af.modifier = -2;
			af.bitvector = AFF_POISON;
			affect_join (victim, &af);
			SEND ("You feel very sick.\n\r", victim);
			act ("$n looks very ill.", victim, NULL, NULL, TO_ROOM);
			victim->hit -= dam;
			if (victim->hit <= 0)
				raw_kill(victim);
			return;
		case GAS_TRAP:
			dam = dice(3,8) + 5;
			act ("A cloud of gas seeps out, choking $n!", victim, NULL, NULL, TO_ROOM);
			sprintf( buf, "A cloud of gas seeps out, choking you! {r[{x%d{r]{x\n\r", dam );			
			SEND(buf, victim);
			victim->hit -= dam;
			if (victim->hit <= 0)
				raw_kill(victim);
			return;
		case DART_TRAP:
			dam = dice(3,8) + 5;
			act ("A spring loaded dart leaps out, stabbing $n!", victim, NULL, NULL, TO_ROOM);
			sprintf( buf, "A spring loaded dart leaps out, stabbing you! {r[{x%d{r]{x\n\r", dam );			
			SEND(buf, victim);
			victim->hit -= dam;
			if (victim->hit <= 0)
				raw_kill(victim);
			return;
	}
	return;
}


void remove_trap(OBJ_DATA *obj)
{
	int type;
	
	type = get_trap_type(obj);
	switch (type)
	{
	default:
		return;
	case FIRE_TRAP:
		REMOVE_BIT (obj->extra_flags, ITEM_FIRE_TRAP);
	case POISON_TRAP:
		REMOVE_BIT (obj->extra_flags, ITEM_POISON_TRAP);
	case GAS_TRAP:
		REMOVE_BIT (obj->extra_flags, ITEM_GAS_TRAP);
	case DART_TRAP:
		REMOVE_BIT (obj->extra_flags, ITEM_DART_TRAP);
	}
	return;
}

bool save_vs_trap(CHAR_DATA *ch, OBJ_DATA *obj)
{
	int trap_type = 0;
	int reaction = 0, difficulty = 15;
	
	trap_type = get_trap_type(obj);
	
	switch (trap_type)	
	{	
	case FIRE_TRAP:
		difficulty += 5;
	case POISON_TRAP:
		difficulty += 3;
	case GAS_TRAP:
		difficulty += 8;
	case DART_TRAP:
		difficulty += 2;
	default:
		difficulty = 15;
	}
	
	difficulty += number_range(1,4); //add a little randomness to it.
	reaction = number_range(1,20);   //roll a reaction.
	
	
	if (trap_type == POISON_TRAP || trap_type == DART_TRAP)
	{
		if (get_curr_stat(ch, STAT_DEX) < 15)
			reaction -= ((get_curr_stat(ch, STAT_DEX) - 25) / 2); //max neg. of 12 w/ a Dex of 1.
		if (get_curr_stat(ch, STAT_DEX) > 15)
			reaction += ((get_curr_stat(ch, STAT_DEX)) / 5); //max bonus of 5 at Dex 25.
	}	
	
	if (trap_type == FIRE_TRAP) //it's a magical trap so bonus runs off of intelligence.
	{
		if (get_curr_stat(ch, STAT_INT) > 15)
			reaction += ((get_curr_stat(ch, STAT_INT)) / 5); //max bonus of 5 at Int 25.
	}
	
	if (reaction >= difficulty)
		return TRUE;
	else
		return FALSE;
}

bool is_trapped(OBJ_DATA *obj)
{
	if (IS_SET(obj->extra_flags, ITEM_FIRE_TRAP) || IS_SET(obj->extra_flags, ITEM_POISON_TRAP) || IS_SET(obj->extra_flags, ITEM_GAS_TRAP) || IS_SET(obj->extra_flags, ITEM_DART_TRAP))
		return TRUE;
	else
		return FALSE;
}