exodus2/
exodus2/area/mobscr/
exodus2/area/mobvoc/
exodus2/bin/
exodus2/clans/
exodus2/gods/
exodus2/player/A/
exodus2/player/B/
exodus2/player/D/
exodus2/player/E/
exodus2/player/L/
exodus2/player/M/
exodus2/player/O/
exodus2/player/R/
exodus2/src/obj/clans/
// Object Triggers started by Adeon, largely completed by Iblis.  These are pretty complicated, so
// I largely suggested you DO NOT FUCKING TOUCH THESE and let me handle them.
// obj_trig.c

#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"

#define OTEDIT( fun )		bool fun( CHAR_DATA *ch, char *argument )

void set_trigger_flags(OBJ_TRIG_DATA *pObjTrig);
void check_trigger(CHAR_DATA *ch, OBJ_TRIG_DATA *ot, long trig_type,
				   OBJ_DATA *obj, CHAR_DATA *victim, int special, char *arg);
void activate_trigger(OBJ_TRIG *ot, OBJ_DATA *obj, CHAR_DATA *ch, CHAR_DATA *victim);
void activate_trigger_statement(int statement_on, OBJ_TRIG *ot, OBJ_DATA *obj, CHAR_DATA *ch, CHAR_DATA *victim);
void interp_action(char *action, OBJ_TRIG_DATA *ot, OBJ_DATA *obj,
				   CHAR_DATA *ch, CHAR_DATA *victim);
char *translate_var(char *action, OBJ_DATA *obj, CHAR_DATA *ch,
					CHAR_DATA *victim);


void disguise_fakie(OBJ_TRIG_DATA *ot, OBJ_DATA *obj);
void revert_fakie(OBJ_TRIG_DATA *ot);

bool contains_text(char *string, char *text);

void free_obj_trig(OBJ_TRIG_DATA *ot);
char *obj_trig_bit_name (int obj_trig_flags);
OBJ_TRIG_DATA *new_obj_trig(void);
extern OBJ_TRIG *ot_list;
//extern OBJ_TRIG_DATA *obj_trig_list;
extern OBJ_TRIG *giant_ot_list;
extern OBJ_TRIG *on_tick_ot_list;
extern CHAR_DATA *GLOBAL_ot_ch;
extern OBJ_DATA *GLOBAL_ot_obj;
void free_ot(OBJ_TRIG *ot);
void ot_set_bits(OBJ_TRIG_DATA* ot, char *argument);
inline void variable_substitution_new (CHAR_DATA *ch, CHAR_DATA *victim, CHAR_DATA *wearer, CHAR_DATA *extra, char *string);
bool obj_trig_in_progress = FALSE;
void check_gravity_char args((CHAR_DATA *ch));
	
	



//sets trigger flags based on the contents of the trigger string
void set_trigger_flags(OBJ_TRIG_DATA *pObjTrig)
{
	char arg1[MAX_STRING_LENGTH];
	char *targ;
	char *trigger;

	pObjTrig->trig_flags = 0; //reset them

	trigger = str_dup(pObjTrig->trigger);

	targ = one_argument(trigger, arg1);

/*	if(!str_cmp(arg1, "$when_worn"))
          SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_EXTRA_FLAGS);
	if(!str_cmp(arg1, "$when_carries"))
          SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_EXTRA_FLAGS);
	if(!str_cmp(arg1, "$when_on_ground"))
          SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_EXTRA_FLAGS);
	if(!str_cmp(arg1, "$when_worn_or_carries"))
          SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_EXTRA_FLAGS);
	if(!str_cmp(arg1, "$when_any"))
          SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_EXTRA_FLAGS);
	if (IS_SET(pObjTrig->trig_flags, OBJ_TRIG_EXTRA_FLAGS))
	  one_argument(targ, arg1);*/
	if(!str_cmp(arg1, "$entersroom"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_ENTER_ROOM);
	  ot_set_bits(pObjTrig, "worn carried on_ground");
	}
	if(!str_cmp(arg1, "$getsobj"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_GET);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$wearsobj"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_WEAR);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$char_hp_pct"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_HP_PCT);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$vict_hp_pct"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_VICT_HP_PCT);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$mana_pct"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_MANA_PCT);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$move_pct"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_MOVE_PCT);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$chance_on_hit"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHANCE_ON_HIT);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$chance_on_round"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHANCE_ON_ROUND);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$whenremoved"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_REMOVE);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$whendropped"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_DROP);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$whenput"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_PUT);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$obj_given_char"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_OBJ_GIVEN_CHAR);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$whenopened"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_OPEN);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$whenclosed"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CLOSE);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$whenactivated") ||
	   !str_cmp(arg1, "$whenentered") ||
	   !str_cmp(arg1, "$whenexited") ||
	   !str_cmp(arg1, "$whencrawled") ||
	   !str_cmp(arg1, "$whenclimbed") ||
	   !str_cmp(arg1, "$whendescended") ||
	   !str_cmp(arg1, "$whenscaled") ||
	   !str_cmp(arg1, "$whenjumped") ||
	   !str_cmp(arg1, "$whentugged") ||
	   !str_cmp(arg1, "$whenrung") ||
	   !str_cmp(arg1, "$whenshoved") ||
	   !str_cmp(arg1, "$whensmashed") ||
	   !str_cmp(arg1, "$whenpressed") ||
	   !str_cmp(arg1, "$whenpulled") ||
	   !str_cmp(arg1, "$whenboarded") ||
	   !str_cmp(arg1, "$whendug")
	   )
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_ACTION_WORD);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$char_enters_room"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_TO_ROOM);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$char_says") ||
	   !str_cmp(arg1, "$char_yells") ||
	   !str_cmp(arg1, "$char_shouts"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_VOCALIZE);
	  ot_set_bits(pObjTrig, "worn carried on_ground");
	}
	if(!str_cmp(arg1, "$char_attacks"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_ATTACKS);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$char_is_attacked"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_IS_ATTACKED);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$whenquaffed"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_QUAFFED);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$wheneaten"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_EATEN);
	  ot_set_bits(pObjTrig, NULL);
	}
	if(!str_cmp(arg1, "$char_flees"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_FLEES);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$vict_flees"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_VICT_FLEES);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$char_sleeps") ||
	   !str_cmp(arg1, "$char_sits") ||
	   !str_cmp(arg1, "$char_rests"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_POS_CHANGE);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$char_recalls"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_RECALLS);
	  ot_set_bits(pObjTrig, "worn carried");
	}
	if(!str_cmp(arg1, "$char_uses_skill"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_USES_SKILL);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$char_uses_spell"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_USES_SPELL);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$char_invokes"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_CHAR_INVOKES);
	  ot_set_bits(pObjTrig, "worn");
	}
	if(!str_cmp(arg1, "$on_tick"))
	{
	  SET_BIT(pObjTrig->trig_flags, OBJ_TRIG_ON_TICK);
	  ot_set_bits(pObjTrig, "worn carried on_ground");
	}
}


void trip_triggers(CHAR_DATA *ch, long trig_type, OBJ_DATA *obj,
		                                   CHAR_DATA *victim, int special)
{
	trip_triggers_arg(ch, trig_type, obj, victim, special,(char *) NULL);
} 

//check_trigger: makes sure all conditions for the various trigger types
// are true, and also sets neccesary variables to pass to activate_triggers
bool should_be_tripped(CHAR_DATA *ch, long trig_type, OBJ_TRIG_DATA *otd, int special, char *arg, CHAR_DATA *victim)
{
  
  char word[MAX_STRING_LENGTH];
  char *dupe;
  int value1;
  
  if(IS_NPC(ch) && !IS_SET(otd->extra_flags,OT_EXTRA_ON_NPC))
	  return FALSE;
  if(!IS_NPC(ch) && !IS_SET(otd->extra_flags,OT_EXTRA_ON_PC))
	  return FALSE;
  
  if(trig_type == OBJ_TRIG_CHAR_POS_CHANGE)
    {
      if(ch->fighting) //don't want position changes due to
	return FALSE;      //aggression to affect this trigger type
      
      if(get_position(ch) == POS_SITTING &&
	 !str_cmp(otd->trigger, "$char_sits"))
	return TRUE;
      else return FALSE;
      
      if(ch->position == POS_RESTING &&
	 !str_cmp(otd->trigger, "$char_rests"))
	return TRUE;
      else return FALSE;
      if(get_position(ch) == POS_SLEEPING &&
	 !str_cmp(otd->trigger, "$char_sleeps"))
	return TRUE;
      else return FALSE;
    }
  else if(trig_type == OBJ_TRIG_ACTION_WORD)
    {
				//$whenactivated looks for any action
      if(!str_cmp(otd->trigger, "$whenactivated"))
	return TRUE;
      
      switch(special)
	{
	case OT_SPEC_ENTER:
	  if(!str_cmp(otd->trigger, "$whenentered"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_EXIT:
	  if(!str_cmp(otd->trigger, "$whenexited"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_CRAWL:
	  if(!str_cmp(otd->trigger, "$whencrawled"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_CLIMB:
	  if(!str_cmp(otd->trigger, "$whenclimbed"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_DESCEND:
	  if(!str_cmp(otd->trigger, "$whendescended"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_SCALE:
	  if(!str_cmp(otd->trigger, "$whenscaled"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_JUMP:
	  if(!str_cmp(otd->trigger, "$whenjumped"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_TUG:
	  if(!str_cmp(otd->trigger, "$whentugged"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_RING:
	  if(!str_cmp(otd->trigger, "$whenrung"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_SHOVE:
	  if(!str_cmp(otd->trigger, "$whenshoved"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_SMASH:
	  if(!str_cmp(otd->trigger, "$whensmashed"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_PRESS:
	  if(!str_cmp(otd->trigger, "$whenpressed"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_PULL:
	  if(!str_cmp(otd->trigger, "$whenpulled"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_BOARD:
	  if(!str_cmp(otd->trigger, "$whenboarded"))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_SPEC_DIG:
          if(!str_cmp(otd->trigger, "$whendug"))
            return TRUE;
          else return FALSE;
         break;
	}
      
    }
  
  else if(trig_type == OBJ_TRIG_CHAR_VOCALIZE)
    {
      //first strip the trigger type
      dupe = one_argument(otd->trigger, word);
      //now we need to match the type of vocalization
      switch(special)
	{
	case OT_VOC_SAY:
	  if(str_cmp(word, "$char_says"))
	    return FALSE;
	  break;
	case OT_VOC_SHOUT:
	  if(str_cmp(word, "$char_shouts"))
	    return FALSE;
	  break;
	case OT_VOC_YELL:
	  if(str_cmp(word, "$char_yells"))
	    return FALSE;
	  break;
	default:
	  bug("check_triggers: bad voc type!", 0);
	  return FALSE;
	}
      
      if(contains_text(arg, dupe))
	return TRUE;
      else return FALSE;
      
    }
  else if(trig_type == OBJ_TRIG_CHAR_HP_PCT ||
	  trig_type == OBJ_TRIG_VICT_HP_PCT ||
	  trig_type == OBJ_TRIG_MANA_PCT ||
	  trig_type == OBJ_TRIG_MOVE_PCT)
    {
      dupe = one_argument(otd->trigger, word);
      word[0] = '\0';
      dupe = one_argument(dupe, word);
      
      // < hp/mana/move amount
      value1 = atoi(word);
      
      if(atoi(arg) < value1)// && value2 >= roll)
	return TRUE;
      else return FALSE;
    }
  else if (trig_type == OBJ_TRIG_OBJ_GIVEN_CHAR)
  {
	  dupe = one_argument(otd->trigger, word);
	  word[0] = '\0';
	  dupe = one_argument(dupe,word);
	  if (word[0] != '\0')
	  {
  	    if (!IS_NPC(ch))
	      return FALSE;
	    if (ch->pIndexData->vnum == atoi(word))
	      return TRUE;
	    else return FALSE;
	  }
	  return TRUE;
  }

  else if(trig_type == OBJ_TRIG_CHAR_USES_SPELL)
    {
      //first strip the trigger type
      dupe = one_argument(otd->trigger, word);
      switch(special)
	{
	case OT_TYPE_SPELL:
	  if (str_cmp(word, "$char_uses_spell"))
	    return FALSE;
	  if ((!strcmp(dupe,"spell")) 
	      || (is_number(arg) && atoi(arg) == skill_lookup(dupe)))
	    return TRUE;
	  else return FALSE;
		 break;
	  
	case OT_TYPE_SONG:
	  if (str_cmp(word, "$char_uses_spell"))
	    return FALSE;
	  if ((!strcmp(dupe,"song"))
	      || (is_number(arg) && atoi(arg) == skill_lookup(dupe)))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_TYPE_PRAYER:
	  if (str_cmp(word, "$char_uses_spell"))
	    return FALSE;
	  if ((!strcmp(dupe,"prayer"))
	      || (is_number(arg) && atoi(arg) == skill_lookup(dupe)))
	    return TRUE;
	  else return FALSE;
	  break;
	case OT_TYPE_CHANT:
	  if (str_cmp(word, "$char_uses_spell"))
	    return FALSE;
	  if ((!strcmp(dupe,"chant"))
	      || (is_number(arg) && atoi(arg) == skill_lookup(dupe)))
	    return TRUE;
	  else return FALSE;
	  break;
	default: bug("check_triggers: bad voc type!", 0);
	  return FALSE;
	}
    }
  
  else if(trig_type == OBJ_TRIG_CHAR_INVOKES)
    {
      int bs = -1;
      dupe = one_argument(otd->trigger, word);
      if(!str_cmp(dupe, "shocking"))
	{
	  bs = BLADE_SPELL_SHOCKING;
	}
      else if(!str_cmp(dupe, "frost"))
	{
	  bs = BLADE_SPELL_FROST;
	}
      else if(!str_cmp(dupe, "flaming"))
	{
	  bs = BLADE_SPELL_FLAMING;
	}
      else if(!str_cmp(dupe, "chaotic"))
	{
	  bs = BLADE_SPELL_CHAOTIC;
	}
      else if(!str_cmp(dupe, "venomous"))
	{
	  bs = BLADE_SPELL_VENEMOUS;
	}
      else if(!str_cmp(dupe, "vampiric"))
	{
	  bs = BLADE_SPELL_VAMPIRIC;
	}
      else if(!str_cmp(dupe, "apathy"))
	{
	  bs = BLADE_SPELL_APATHY;
	}
      else if(!str_cmp(dupe, "lightning"))
	{
	  bs = BURST_LIGHTNING+100;
	}
      else if(!str_cmp(dupe, "ice"))
	{
	  bs = BURST_ICE+100;
	}
      else if(!str_cmp(dupe, "fire"))
	{
	  bs = BURST_FIRE+100;
	}
      else if(!str_cmp(dupe, "unholy"))
	{
	  bs = BURST_UNHOLY+100;
	}
      else if(!str_cmp(dupe, "hellscape"))
	{
	  bs = BURST_HELLSCAPE+100;
	}
      if ((!strcmp(dupe,"invocation"))
	  || (is_number(arg) && atoi(arg) == bs))
	return TRUE;
      else return FALSE;
    }
  
  
  else if(trig_type == OBJ_TRIG_CHAR_USES_SKILL)			
    {
      
      dupe = one_argument(otd->trigger, word);
      if ((!strcmp(dupe,"skill"))
	  || (is_number(arg) && atoi(arg) == skill_lookup(dupe)))
	return TRUE;
      else return FALSE;
    }
  
  
  else if(trig_type == OBJ_TRIG_CHAR_TO_ROOM)
    {
      dupe = one_argument(otd->trigger, word);
      if (!str_cmp(dupe,arg))
	return TRUE;
      else return FALSE;
      
    }
  return TRUE;
}

void trip_triggers_arg(CHAR_DATA *ch, long trig_type, OBJ_DATA *obj, CHAR_DATA *victim, int special, char *arg)
     
{
  int i=0;
  CHAR_DATA* tch;
  if (IS_NPC(ch) && (victim == NULL || IS_NPC(victim)) && special != OT_SPEC_PULL)
    return;
  if (obj)
    {
      for (i=0;i<MAX_OBJ_TRIGS;i++)
      {
	if(obj->objtrig[i] && IS_SET(obj->objtrig[i]->pIndexData->trig_flags, trig_type))
  	  if (should_be_tripped(ch,trig_type,obj->objtrig[i]->pIndexData,special,arg,victim))
	    activate_trigger(obj->objtrig[i], obj, ch, victim);
      }
    }
  
  if (ch == NULL || ch->in_room == NULL)
	  return;
  for(obj = ch->in_room->contents; obj != NULL; obj = obj->next_content)
    {
      for (i=0;i<MAX_OBJ_TRIGS;i++)
	{
	  if(obj->objtrig[i] 
	     && IS_SET(obj->objtrig[i]->pIndexData->trig_flags, trig_type)
	     && IS_SET(obj->objtrig[i]->pIndexData->extra_flags, OT_EXTRA_WHEN_ON_GROUND))
	    if (should_be_tripped(ch,trig_type,obj->objtrig[i]->pIndexData,special,arg,victim))
	      activate_trigger(obj->objtrig[i], obj, ch, victim);
	  
	}
    }
  for(tch = ch->in_room->people; tch != NULL; tch = tch->next_in_room)
    {
      for (obj = tch->carrying; obj != NULL; obj = obj->next_content)
	{
	  for (i=0;i<MAX_OBJ_TRIGS;i++)
	    {
	      if(obj->objtrig[i] && IS_SET(obj->objtrig[i]->pIndexData->trig_flags, trig_type))
		{
		//  if(get_eq_char(tch, obj->wear_loc) == obj && obj->wear_loc != WEAR_NONE)
		if (obj->carried_by == tch && obj->wear_loc != WEAR_NONE)
		    {
		      if(IS_SET(obj->objtrig[i]->pIndexData->extra_flags, OT_EXTRA_WHEN_WORN))
		      {
		        if (should_be_tripped(ch,trig_type,obj->objtrig[i]->pIndexData,special,arg,victim))
			  activate_trigger(obj->objtrig[i], obj, ch, tch);
		      }
		      else if(IS_SET(obj->objtrig[i]->pIndexData->extra_flags, OT_EXTRA_WHEN_TRIGGERER_WORN)
		          && tch == ch)
		      {
		        if (should_be_tripped(ch,trig_type,obj->objtrig[i]->pIndexData,special,arg,victim))
 		          activate_trigger(obj->objtrig[i], obj, ch, victim);
		      }
		    }
		  else if(IS_SET(obj->objtrig[i]->pIndexData->extra_flags, OT_EXTRA_WHEN_CARRIED))
		  {
 		    if (should_be_tripped(ch,trig_type,obj->objtrig[i]->pIndexData,special,arg,victim))
		      activate_trigger(obj->objtrig[i], obj, ch, tch);
		  }
		  else if(IS_SET(obj->objtrig[i]->pIndexData->extra_flags, OT_EXTRA_WHEN_TRIGGERER_CARRIED)
		      && tch == ch)
		  {
		    if (should_be_tripped(ch,trig_type,obj->objtrig[i]->pIndexData,special,arg,victim))
 		      activate_trigger(obj->objtrig[i], obj, ch, victim);
		  }
		}
	    }
	}
    }
  if (trig_type == OBJ_TRIG_ENTER_ROOM)
   check_gravity_char(ch);
}





void trip_triggers_special(CHAR_DATA *ch, long trig_type, OBJ_DATA *obj, 
		CHAR_DATA *victim, int special, OBJ_TRIG* ot)
{
  CHAR_DATA *tch;
  ROOM_INDEX_DATA *inroom = NULL;
  if(trig_type == OBJ_TRIG_ON_TICK)
  {
    if (ot->obj_on && ot->obj_on->in_room)
      inroom = ot->obj_on->in_room;
    else if (ot->obj_on->carried_by && ot->obj_on->carried_by->in_room)
      inroom = ot->obj_on->carried_by->in_room;
    if (inroom)
    {
    
      for (tch = inroom->people; tch != NULL; tch = tch->next_in_room)
      {
        if ((!IS_NPC(tch) && IS_SET(ot->pIndexData->extra_flags,OT_EXTRA_ON_PC))
	   || (IS_NPC(tch) && IS_SET(ot->pIndexData->extra_flags,OT_EXTRA_ON_NPC)))
        {
	  if (ot->obj_on->carried_by)
	  {
 	    if ((ot->obj_on->carried_by == tch && ot->obj_on->wear_loc != WEAR_NONE))
	    {
 	      if (IS_SET(ot->pIndexData->extra_flags, OT_EXTRA_WHEN_WORN))
                activate_trigger(ot, ot->obj_on, ot->obj_on->carried_by, tch);
	    }	    
	    else if (IS_SET(ot->pIndexData->extra_flags, OT_EXTRA_WHEN_CARRIED))
 	      activate_trigger(ot, ot->obj_on, ot->obj_on->carried_by, tch);
	  }
	  else if (IS_SET(ot->pIndexData->extra_flags, OT_EXTRA_WHEN_ON_GROUND))
	    activate_trigger(ot, ot->obj_on, tch, tch);
	  break;
	}
      }
    }
  }
}

void activate_trigger(OBJ_TRIG *ot, OBJ_DATA *obj, CHAR_DATA *ch, CHAR_DATA *victim)
{
	OBJ_TRIG_DATA *otd=ot->pIndexData;
	if ((number_percent() > otd->overall_chance && otd->overall_chance != 100) || ot->seconds_left > 0 || ot->statement_on != 0)
  	  return;
	if (otd->delay[0] > 0)
	{
	  ot->statement_on = 0;
	  ot->seconds_left = otd->delay[0];
	  ot->next = ot_list;
	  ot_list = ot;
	  ot->ch = ch;
	  ot->victim = victim;
	}
	else activate_trigger_statement(0,ot,obj,ch,victim);
	return;
}

void activate_trigger_statement(int statement_on, OBJ_TRIG *ot, OBJ_DATA *obj, CHAR_DATA *ch, CHAR_DATA *victim)
{
	int i=0, pos=0;
        OBJ_TRIG_DATA *otd=ot->pIndexData;
	OBJ_TRIG *otp = NULL;
	disguise_fakie(otd, obj);
	pos = ch->position;
	if(otd->action[statement_on] != NULL && number_percent() < otd->chance[statement_on]+1)
	  interp_action(otd->action[statement_on], otd, obj, ch, victim);
        for (i = statement_on+1;i<16;i++)
        {
	  if (otd->delay[i] > 0)
	  {
	    if (ot->statement_on == 0)
	    {
	      ot->next = ot_list;
	      ot_list = ot;
	    }
	    ot->statement_on = i;
	    ot->seconds_left = otd->delay[i];
	    ot->ch = ch;
	    ot->victim = victim;
	    if (ch->fighting == NULL)
	    {
	      if (pos == POS_MOUNTED && ch->mount == NULL)
 	        ch->position = ch->position; //do nothing
	      else if (pos != POS_FIGHTING)
   	        ch->position = pos;
	      else ch->position = POS_STANDING;
	      
	    }
	     
	    break;
	  }
          if(otd->action[i] != NULL && number_percent() < otd->chance[i]+1)
            interp_action(otd->action[i], otd, obj, ch, victim);
          if (ch->fighting == NULL)
	  {
  	    if (pos == POS_MOUNTED && ch->mount == NULL)
	      ch->position = ch->position; //do nothing
	    else if (pos != POS_FIGHTING)
  	      ch->position = pos;
	    else ch->position = POS_STANDING;
	  }
        }
	if (i >= 16 && ot_list != NULL)
	  {
	    if (ot_list == ot)
              ot_list = ot->next;
	    else if (ot_list->next == ot)
	      ot_list->next = ot->next;
	    else
	    {
	      for (otp = ot_list;otp->next != NULL;otp = otp->next)
	        {
	          if (otp->next == ot)
	            {
	              otp->next = ot->next;
	              break;
	            }
	         }
	    }
	    ot->statement_on = 0;
	  }
        revert_fakie(otd);
}

void interp_action(char *action, OBJ_TRIG_DATA *ot, OBJ_DATA *obj,
				   CHAR_DATA *ch, CHAR_DATA *victim)
{
	char *raw_action;
	char buf[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH];
	if ((obj->carried_by == NULL || obj->carried_by->in_room == NULL) && obj->in_room == NULL)
  	  return;
        if (obj_trig_in_progress)  	//A pitiful attempt at function isolation/synchronization
         return;
        else obj_trig_in_progress = TRUE;
	GLOBAL_ot_ch = ch;
	GLOBAL_ot_obj = obj;
	raw_action = NULL;
	strcpy(buf2,action);
	raw_action = buf2;
	variable_substitution_new(ch,ch->fighting,obj->carried_by,victim,raw_action);
	if(obj->carried_by == NULL) 
	{
  	  if (obj->in_room)
	    char_to_room(ot->fakie, obj->in_room);
	}
	else
	{
	  if (obj->carried_by->in_room)
	    char_to_room(ot->fakie, obj->carried_by->in_room);
	}
        sprintf(buf, "%s", raw_action);
        interpret(ot->fakie, buf);
	char_from_room(ot->fakie);
	GLOBAL_ot_ch = NULL;
	GLOBAL_ot_obj = NULL;
	obj_trig_in_progress = FALSE;
}



char *translate_var(char *action, OBJ_DATA *obj, CHAR_DATA *ch,
					CHAR_DATA *victim)
{
	char *raw_action;
	raw_action = str_dup(action);
	variable_substitution(ch,raw_action);
	return raw_action;
}

void disguise_fakie(OBJ_TRIG_DATA *ot, OBJ_DATA *obj)
{
	free_string(ot->fakie->short_descr);
	ot->fakie->short_descr = str_dup(obj->short_descr);
	ot->fakie->level = obj->level;
	ot->fakie->trust = 100;
	SET_BIT (ot->fakie->comm, COMM_TRUE_TRUST);
	return;
}

void revert_fakie(OBJ_TRIG_DATA *ot)
{
	return;
	free_string(ot->fakie->short_descr);
	ot->fakie->short_descr = str_dup("The Fakie");
	return;
}

// find a obj trigger with desired vnum
OBJ_TRIG_DATA *get_obj_trig(int vnum)
{
	OBJ_TRIG_DATA *pObjTrig;
	AREA_DATA *pArea;
	if ( (pArea = get_vnum_area (vnum)) == NULL)
	{
	  //send_to_char("That vnum is not assigned an area.\n\r",ch);
	  return FALSE;
	}
	
	for (pObjTrig = pArea->ot_first; pObjTrig != NULL; pObjTrig = pObjTrig->next)
	{
          if (pObjTrig->vnum == vnum)
	    return pObjTrig;
        } 

	return NULL;
}

bool contains_text(char *string, char *text)
{
	char strword[MAX_STRING_LENGTH];
	char textword[MAX_STRING_LENGTH];
	
	text = one_argument(text, textword);

	do
	{
		string = one_argument(string, strword);

		if(!str_cmp(strword, textword))
		{
			// if it successfully evaluates every word in text then it
			//    does indeed contain the text.
			if(text[0] == '\0')
				return TRUE;
			text = one_argument(text, textword);
		}
			
	} while(string[0] != '\0');

	return FALSE;
}


// OLC Obj Trig Editor functions
OTEDIT (otedit_create)
{
  //     MOB_INDEX_DATA *pMob;
      AREA_DATA *pArea;
      OBJ_TRIG_DATA *pObjTrig, *ot;
      int value;
      bool inserted = FALSE;
      //int iHash;
      //int i=0;
      value = atoi (argument);

      /* OLC 1.1b */
      if (argument[0] == '\0' || value <= 0 || value >= INT_MAX)
	{
	  char output[MAX_STRING_LENGTH];
	  sprintf (output, "Syntax:  create [0 < vnum < %d]\n\r", INT_MAX);
	  send_to_char (output, ch);
	  return FALSE;
	}
      pArea = get_vnum_area (value);
      if (!pArea)
	{
	  send_to_char ("That vnum is not assigned an area.\n\r", ch);
	  return FALSE;
	}
      if (!is_builder (ch, pArea))
	{
	  send_to_char ("Vnum in an area you cannot build in.\n\r", ch);
	  return FALSE;
	}

	if(get_obj_trig(value))
	{
		send_to_char("Object Trigger vnum already in use, choose another.\n\r", ch);
		return FALSE;
	}

	pObjTrig = new_obj_trig();
	pObjTrig->vnum = value;

	pObjTrig->fakie = create_mobile(get_mob_index(MOB_VNUM_FAKIE));
	
	if (pArea->ot_first == NULL)
	{
	  pObjTrig->next = pArea->ot_first;
	   pArea->ot_first = pObjTrig;
	}
	else if (pArea->ot_first->next == NULL)
	{
		if (pObjTrig->vnum <  pArea->ot_first->vnum)
		{
			pObjTrig->next =  pArea->ot_first;
			pArea->ot_first = pObjTrig;
		}
		else
		{
			pObjTrig->next = pArea->ot_first->next;
			pArea->ot_first->next = pObjTrig;
		}
	}
	else
	{
		if (pObjTrig->vnum < pArea->ot_first->vnum)
                {
                        pObjTrig->next = pArea->ot_first;
                        pArea->ot_first = pObjTrig;
                }
		else
		{
		  for (ot = pArea->ot_first;ot->next != NULL;ot = ot->next)
		  {
			  if (pObjTrig->vnum < ot->next->vnum)
			  {
				  pObjTrig->next = ot->next;
				  ot->next = pObjTrig;
				  inserted = TRUE;
				  break;
			  }
		  }
			  if (!inserted)
			  {
				  ot->next = pObjTrig;
				  pObjTrig->next = NULL;
			  }
			  


		}
	}
	

	//Iblis 11/07/03 - Ok his hash implementation was NOT finished (IE saving/loading
	//only load from the list, which only contains the MOST RECENT trigger), so I'm like
	//fuck it, comment out hash shit for now
/*	iHash = value % MAX_KEY_HASH;
	pObjTrig->next = obj_trig_hash[iHash];
	obj_trig_hash[iHash] = pObjTrig;*/
	ch->desc->pEdit = (void *) pObjTrig;

	send_to_char("Object Trigger Created.\n\r", ch);
	return TRUE;
}

OTEDIT (otedit_show)
{
	OBJ_TRIG_DATA *pObjTrig;
	char buf[MAX_STRING_LENGTH];
	char buf2[MAX_STRING_LENGTH];
	bool found = FALSE;

	int i;

	buf2[0] = '\0';

	EDIT_OBJ_TRIG(ch, pObjTrig);
	
	sprintf(buf, "Name: [%s]\n\r", pObjTrig->name);
	send_to_char(buf, ch);
	sprintf(buf, "Vnum: [%d]\n\r", pObjTrig->vnum);
	send_to_char(buf, ch);
	sprintf(buf, "Chance of trigger being tripped: [%d percent]\n\r", pObjTrig->overall_chance);
	send_to_char(buf,ch);
	sprintf(buf, "Trigger Flags: [%s]\n\r", obj_trig_bit_name(pObjTrig->trig_flags));
	send_to_char(buf, ch);
	sprintf(buf, "Trigger String: [%s]\n\r", pObjTrig->trigger);
	send_to_char(buf, ch);
	if (pObjTrig->extra_flags != 0)
  	  sprintf(buf, "Extra Flags: [%s]\n\r\n\r",flag_string (ot_extra_flags, pObjTrig->extra_flags));
	else sprintf(buf, "Extra Flags: [object_only]\n\r\n\r");
	
	send_to_char(buf,ch);
	send_to_char("Action Strings:\n\r", ch);
	send_to_char("No | Chnc | Dly | Action String\n\r",ch);
	for (i = 0;i<16;i++)
	{
	  if(pObjTrig->action[i] != NULL)
	  {
	    sprintf(buf, "%d) %d %d - %s\n\r", i, pObjTrig->chance[i], pObjTrig->delay[i], pObjTrig->action[i]);
	    send_to_char(buf, ch);
	    found = TRUE;
	  }
	}
	
	if(!found)
		send_to_char("*** No Actions Defined\n\r", ch);
	

	return FALSE;
}

OTEDIT (otedit_chance)
{
	OBJ_TRIG_DATA *pObjTrig;
	int value;

	EDIT_OBJ_TRIG(ch, pObjTrig);
	
	if(argument == '\0' || !is_number(argument))
	{
		send_to_char("Syntax: chance %\n\r", ch);
		return FALSE;
	}

	value = atoi(argument);
	if (value < 0 || value > 100)
	{
	  send_to_char("Syntax: chance % (a % is between 0 and 100 genius)\n\r", ch);
	  return FALSE;
	}
	pObjTrig->overall_chance = value;
	send_to_char("Chance successfully set.\n\r", ch);

	return TRUE;
}


OTEDIT (otedit_name)
{
	OBJ_TRIG_DATA *pObjTrig;

	EDIT_OBJ_TRIG(ch, pObjTrig);

	if(argument[0] == '\0')
	{
		send_to_char("Syntax: name <name of trigger>\n\r", ch);
		return FALSE;
	}

	free_string(pObjTrig->name);
	pObjTrig->name = str_dup(argument);

	send_to_char("Trigger name set.\n\r", ch);
	return TRUE;
}

OTEDIT (otedit_trigger)
{
	OBJ_TRIG_DATA *pObjTrig;
	bool on_tick=FALSE;

	EDIT_OBJ_TRIG(ch, pObjTrig);

	if(argument[0] == '\0')
	{
		send_to_char("Syntax: trigger <trigger script string>\n\r", ch);
		return FALSE;
	}

	free_string(pObjTrig->trigger);
	pObjTrig->trigger = str_dup(argument);
        if (IS_SET(pObjTrig->trig_flags,OBJ_TRIG_ON_TICK))
	  on_tick = TRUE;
	set_trigger_flags(pObjTrig);
	if (IS_SET(pObjTrig->trig_flags,OBJ_TRIG_ON_TICK))
	  {
	    if (!on_tick)
	      {
		      
		OBJ_TRIG* otp;
		for (otp = giant_ot_list;otp != NULL;otp = otp->next_ot)
		{
			if (otp->pIndexData == pObjTrig)
			{
			  otp->next_on_tick = on_tick_ot_list;
		          on_tick_ot_list = otp;
			}
		}
	      }
	  }
	else if (on_tick)
	{
  	  OBJ_TRIG *otp,*ot;
	  for (ot = giant_ot_list;ot != NULL;ot = ot->next_ot)
	  {
	    if (ot->pIndexData == pObjTrig)
	    {
	      if (on_tick_ot_list == ot)
	      {
		on_tick_ot_list = ot->next_on_tick;
		ot->next_on_tick = NULL;
	      }
	      else if (on_tick_ot_list && on_tick_ot_list->next_on_tick == ot)
	      {
		on_tick_ot_list->next_on_tick = ot->next_on_tick;
		ot->next_on_tick = NULL;
	      }
	      else
		{
		bool found = FALSE;
		  for (otp = on_tick_ot_list;otp->next_on_tick != NULL;otp = otp->next_on_tick)
		    {
		      if (otp->next_on_tick == ot)
			{
			  otp->next_on_tick = ot->next_on_tick;
			  ot->next_on_tick = NULL;
			  found = TRUE;
			  break;
			}
		  }
		  if (!found)
		    {
		    bug("object trigger to be freed NOT FOUND on on_tick_ot_list.",0);
		    return TRUE;
		    }
		}
	    }
	  }
	}
	    
	    
	send_to_char("Trigger script string set.\n\r", ch);
	return TRUE;
}

OTEDIT (otedit_addaction)
{
	OBJ_TRIG_DATA *pObjTrig;
	bool found = FALSE;
	char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
	short argnum, argnum2, i;

	EDIT_OBJ_TRIG(ch, pObjTrig);

	if(argument[0] == '\0')
	{
		send_to_char("Syntax: addaction %ofhitting delay <action script string>\n\r", ch);
		return FALSE;
	}

	argument = one_argument(argument,arg);
	argument = one_argument(argument,arg2);
	if (!is_number(arg) || argument[0] == '\0')
        {
	        send_to_char("Syntax: addaction %ofhitting delay <action script string>\n\r", ch);
	        return FALSE;
	}
	argnum = atoi(arg);
	if (argnum < 0 || argnum > 100)
	{
		send_to_char("The chance of hitting must be between 0 and 100.\n\r",ch);
		return FALSE;
	}
	argnum2 = atoi(arg2);
	if (argnum2 < 0 || argnum2 > 999)
	{
	        send_to_char("The seconds delay must be between 0 and 999.\n\r",ch);
		return FALSE;
	}
	for (i=0;i<16;i++)
	{
	  if(pObjTrig->action[i] == NULL)
          {
            pObjTrig->action[i] = str_dup(argument);
            pObjTrig->chance[i] = argnum;
	    pObjTrig->delay[i] = argnum2;
            found = TRUE;
	    break;
          }

	}

	if(!found)
	{
		send_to_char("Maximum number of actions already defined.\n\r", ch);
		return FALSE;
	}

	send_to_char("Action added successfully.\n\r", ch);
	return TRUE;
}

OTEDIT (otedit_remaction)
{
	OBJ_TRIG_DATA *pObjTrig;
	int value, i;
	bool found = FALSE;

	EDIT_OBJ_TRIG(ch, pObjTrig);

	if(argument[0] == '\0' || !is_number(argument))
	{
		send_to_char("Syntax: remaction <action string #>\n\r", ch);
		return FALSE;
	}

	value = atoi(argument);


	for (i=value;i<16;i++)
	{
		if (pObjTrig->action[i] != NULL)
		  found = TRUE;
		if (i==value)
		  free_string(pObjTrig->action[i]);
		if (i == 15)
		{
		  pObjTrig->action[i] = NULL;
		  pObjTrig->chance[i] = 0;
		  pObjTrig->delay[i] = 0;
		}
		else
		{
		  pObjTrig->action[i] = pObjTrig->action[i+1];
		  pObjTrig->chance[i] = pObjTrig->chance[i+1];
		  pObjTrig->delay[i] = pObjTrig->delay[i+1];
		}
	}
	

	if(!found)
	{
		send_to_char("That is not a valid action string number.\n\r", ch);
		return FALSE;
	}

	send_to_char("Action removed successfully.\n\r", ch);
	return TRUE;
}

void do_otlist(CHAR_DATA* ch, char* argument)
{
  OBJ_TRIG_DATA* pObjTrig;
  char buf[MAX_STRING_LENGTH], tcbuf[MAX_STRING_LENGTH*20];
  strcpy (tcbuf, "Obj Trigger Listing:\n\r");
  for (pObjTrig = ch->in_room->area->ot_first; pObjTrig != NULL; pObjTrig = pObjTrig->next)
  {
    sprintf(buf,"[%d] - %s\n\r",pObjTrig->vnum, pObjTrig->name);
    strcat(tcbuf,buf);
  }
  page_to_char (tcbuf, ch);
}

OTEDIT (otedit_purge)
{
  OBJ_TRIG_DATA *pObjTrig, *ot;
  int value;
  bool inserted = FALSE;
  AREA_DATA *pArea;

  value = atoi (argument);

  if(argument[0] == '\0' || value <= 0 || value >= INT_MAX)
    {
      char buf[MAX_STRING_LENGTH];

      sprintf(buf, "Syntax: purge <vnum 1 - %d>\n\r", INT_MAX);
      send_to_char(buf, ch);
      return FALSE;
    }

  if(!get_obj_trig(value))
    {
      send_to_char("Object Trigger does not currently exist.\n\r", ch);
      return FALSE;
    }

  if (ch->desc->pEdit == (void *) get_obj_trig(value))
    edit_done (ch);

  if ((pArea = get_vnum_area(value)) == NULL)
  {  
    send_to_char ("That vnum is not assigned an area.\n\r", ch);
    return FALSE;
  }



  if (pArea->ot_first == NULL)
    {
      send_to_char("Object Trigger does not currently exist.\n\r", ch);
      return FALSE;
    }
  else if (pArea->ot_first->next == NULL)
    {
      if (value == pArea->ot_first->vnum)
	{
		OBJ_TRIG *ot2, *ot2_next;
		pObjTrig = pArea->ot_first;
		for (ot2 = giant_ot_list;ot2 != NULL;ot2 = ot2_next)
		{
  		  ot2_next = ot2->next_ot;
		  if (ot2->pIndexData == pObjTrig)
 		    free_ot(ot2);
		}
		free_obj_trig(pObjTrig);
		pArea->ot_first = NULL;
		inserted = TRUE;
	}
      else
	{
	  send_to_char("Object Trigger does not currently exist.\n\r", ch);
	  return FALSE;
	}
    }
  else
    {
      if (value == pArea->ot_first->vnum)
	{
  	  OBJ_TRIG *ot2, *ot2_next;
	  pObjTrig = pArea->ot_first;
	  for (ot2 = giant_ot_list;ot2 != NULL;ot2 = ot2_next)
	  {
	    ot2_next = ot2->next_ot;
	    if (ot2->pIndexData == pObjTrig)
	      free_ot(ot2);
	  }
	  pArea->ot_first = pArea->ot_first->next;
	  free_obj_trig(pObjTrig);
	  inserted = TRUE;
	}
      else
	{
	  for (ot = pArea->ot_first;ot->next != NULL;ot = ot->next)
	    {
	      if (value == ot->next->vnum)
		{
		  OBJ_TRIG *ot2, *ot2_next;
		  pObjTrig = ot->next;
		  for (ot2 = giant_ot_list;ot2 != NULL;ot2 = ot2_next)
		  {
		    ot2_next = ot2->next_ot;
		    if (ot2->pIndexData == pObjTrig)
		      free_ot(ot2);
		  }
		    
		  ot->next = ot->next->next;
		  free_obj_trig(pObjTrig);
		  inserted = TRUE;
		  break;
		}
	    }
	  if (!inserted)
	    {
	      send_to_char("Object Trigger does not currently exist.\n\r", ch);
              return FALSE;
	    }
	  
	  
	  
	}
    }
  
  
  //Iblis 11/07/03 - Ok his hash implementation was NOT finished (IE saving/loading
  //only load from the list, which only contains the MOST RECENT trigger), so I'm like
  //fuck it, comment out hash shit for now
  /*      iHash = value % MAX_KEY_HASH;
        pObjTrig->next = obj_trig_hash[iHash];
        obj_trig_hash[iHash] = pObjTrig;*/
//  ch->desc->pEdit = (void *) pObjTrig;

  send_to_char("Object Trigger Successfully Purged.\n\r", ch);
  send_to_char("MAKE SURE YOU REMOVED OR HAVE REMOVED all objects with this vnum as their object trigger.\n\r",ch);
  return TRUE;
}


// OLC Obj Trig Editor functions
OTEDIT (otedit_extra)
 {
   
   OBJ_TRIG_DATA *pObjTrig;
   int value;

   EDIT_OBJ_TRIG(ch, pObjTrig);

   if(argument[0] == '\0')
     {
       send_to_char("Syntax: extra EXTRAFLAG\n\r", ch);
       send_to_char("   where EXTRAFLAG = \n\r",ch);
       send_to_char("worn carried on_ground triggerer_worn triggerer_carried\n\r",ch);
       send_to_char("on_npc on_pc\n\r",ch);
       return FALSE;
     }

   if ((value = flag_value (ot_extra_flags, argument)) != NO_FLAG)
     {
       TOGGLE_BIT (pObjTrig->extra_flags, value);
       send_to_char ("Extra flag toggled.\n\r", ch);
       return TRUE;
     }
     send_to_char("Syntax: extra EXTRAFLAG\n\r", ch);
     send_to_char("   where EXTRAFLAG = \n\r",ch);
     send_to_char("worn carried on_ground triggerer_worn triggerer_carried\n\r",ch);
     send_to_char("on_pc on_npc\n\r",ch);
     return FALSE;
 }
   
	   

void ot_set_bits(OBJ_TRIG_DATA* ot, char *argument)
{
  int value = 0;
  if (argument != NULL)
    value = flag_value (ot_extra_flags, argument);
  REMOVE_BIT(ot->extra_flags,OT_EXTRA_WHEN_WORN);
  REMOVE_BIT(ot->extra_flags,OT_EXTRA_WHEN_CARRIED);
  REMOVE_BIT(ot->extra_flags,OT_EXTRA_WHEN_ON_GROUND);
  REMOVE_BIT(ot->extra_flags,OT_EXTRA_WHEN_TRIGGERER_CARRIED);
  REMOVE_BIT(ot->extra_flags,OT_EXTRA_WHEN_TRIGGERER_WORN);
  REMOVE_BIT(ot->extra_flags,OT_EXTRA_ON_NPC);
  SET_BIT(ot->extra_flags,OT_EXTRA_ON_PC);
  TOGGLE_BIT (ot->extra_flags, value);
}
	

void do_otlistall(CHAR_DATA* ch, char* argument)
{
  OBJ_TRIG_DATA* pObjTrig;
  char buf[MAX_STRING_LENGTH], tcbuf[MAX_STRING_LENGTH*20];
  int i=0;
  //  AREA_DATA *pArea;
  strcpy (tcbuf, "Obj Trigger Listing:\n\r");
  //Iblis 9/13/04 - Can't find the MAx vnum, so set it to 65,000.  So sue me.
  for (i = 0; i < 65000; ++i)
    {
      //      for (pObjTrig = pArea->ot_first; pObjTrig != NULL; pObjTrig = pObjTrig->next)
	pObjTrig = get_obj_trig(i);
      if (pObjTrig == NULL)
	continue;
	  sprintf(buf,"[%d] - %s\n\r",pObjTrig->vnum, pObjTrig->name);
	  strcat(tcbuf,buf);
	  //	}
    }
  page_to_char (tcbuf, ch);
}