Mud20/accounts/
Mud20/accounts/c/
Mud20/accounts/f/
Mud20/accounts/k/
Mud20/accounts/s/
Mud20/accounts/t/
Mud20/area_current/
Mud20/area_current/newareas/
Mud20/bin/
Mud20/clans/
Mud20/gods/
Mud20/old-sources/
Mud20/player/
Mud20/player/a/del/
Mud20/player/b/
Mud20/player/b/bak/
Mud20/player/b/del/
Mud20/player/f/
Mud20/player/f/bak/
Mud20/player/f/del/
Mud20/player/k/
Mud20/player/k/bak/
Mud20/player/k/del/
Mud20/player/k/dmp/
Mud20/player/m/
Mud20/player/m/bak/
Mud20/player/o/
Mud20/player/o/bak/
Mud20/player/p/
Mud20/player/s/
Mud20/player/s/bak/
Mud20/player/s/del/
Mud20/player/t/
Mud20/player/t/del/
Mud20/player/v/
Mud20/public_html/
Mud20/races/
Mud20/skilltables/
__MACOSX/Mud20/accounts/
__MACOSX/Mud20/accounts/c/
__MACOSX/Mud20/accounts/f/
__MACOSX/Mud20/accounts/k/
__MACOSX/Mud20/accounts/s/
__MACOSX/Mud20/area_current/
__MACOSX/Mud20/area_current/core_areas/
__MACOSX/Mud20/area_current/helps/
__MACOSX/Mud20/area_current/newareas/
__MACOSX/Mud20/backups/
__MACOSX/Mud20/bin/
__MACOSX/Mud20/clans/
__MACOSX/Mud20/gods/
__MACOSX/Mud20/log/
__MACOSX/Mud20/old-sources/
__MACOSX/Mud20/player/
__MACOSX/Mud20/player/a/del/
__MACOSX/Mud20/player/b/
__MACOSX/Mud20/player/b/bak/
__MACOSX/Mud20/player/f/
__MACOSX/Mud20/player/f/bak/
__MACOSX/Mud20/player/f/del/
__MACOSX/Mud20/player/k/
__MACOSX/Mud20/player/k/bak/
__MACOSX/Mud20/player/k/del/
__MACOSX/Mud20/player/k/dmp/
__MACOSX/Mud20/player/m/
__MACOSX/Mud20/player/m/bak/
__MACOSX/Mud20/player/o/
__MACOSX/Mud20/player/o/bak/
__MACOSX/Mud20/player/p/
__MACOSX/Mud20/player/s/
__MACOSX/Mud20/player/s/bak/
__MACOSX/Mud20/player/t/del/
__MACOSX/Mud20/player/v/
__MACOSX/Mud20/public_html/
__MACOSX/Mud20/races/
__MACOSX/Mud20/skilltables/
/***************************************************************************
 * Mud20 1.0 by Todd H. Johnson (Kregor) a derivative of the Open Gaming   *
 * License by Wizards of the Coast. All comments referring to D20, OGL,    *
 * and SRD refer to the System Reference Document for the Open Gaming      *
 * system. Any inclusion of these derivatives must include credit to the   *
 * Mud20 system, the full and complete Open Gaming LIcense, and credit to  *
 * the respective authors. See ../doc/srd.txt for more information.        *
 *                                                                         *
 * Emud  2.2 by Igor van den Hoven, Michiel Lange, and Martin Bethlehem.   *
 *                                                                         *
 * MrMud 1.4 by David Bills, Dug Michael and Martin Gallwey                *
 *                                                                         *
 * Merc  2.1 Diku Mud improvments copyright (C) 1992, 1993 by Michael      *
 * Chastain, Michael Quan, and Mitchell Tse.                               *
 *                                                                         *
 * Original Diku Mud copyright (C) 1990 1991 by Sebastian Hammer,          *
 * Michael Seifert, Hans Henrik St{rfeld, Tom Madsen, and Katje Nyboe.     *
 ***************************************************************************/

/***************************************************************************
 * mob_prog.c: mob prog functions and checks														   *
 ***************************************************************************/

#include "mud.h"

/*
	Global function prototypes
*/

OBJ_DATA *get_obj_carry_vnum args( ( CHAR_DATA *ch, int vnum) );

/*
	Local function prototypes
*/

bool		is_quest				args( ( unsigned char *pt ) );
char		mprog_cmd_translate_buf[MAX_INPUT_LENGTH];

char		*mprog_cmd_translate( char *, CHAR_DATA *, CHAR_DATA *, OBJ_DATA *, void *, CHAR_DATA *);
NPC_TOKEN	*execute_mob_prog	args( ( NPC_TOKEN *token, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, CHAR_DATA *rndm, char level) );
bool		mprog_seval		args( ( char* lhs, char* opr, char* rhs ) );
bool		mprog_veval		args( ( int lhs, char* opr, int rhs ) );
char		mprog_do_ifchck	args( ( char* ifchck, CHAR_DATA* mob, CHAR_DATA* actor, OBJ_DATA* obj,  void* vo, CHAR_DATA* rndm ) );
void		mprog_translate	args( ( char ch, char* t, CHAR_DATA* mob, CHAR_DATA* actor, OBJ_DATA* obj, void* vo, CHAR_DATA* rndm ) );
void		mprog_driver		args( ( MPROG_DATA *mprog, CHAR_DATA* mob, CHAR_DATA* actor, OBJ_DATA* obj, void* vo ) );
lg_int	mprog_case_val		args( ( CHAR_DATA *mob, char *case_val ) );

/*
	function code and brief comments.
*/

bool			world_index[2000];

OBJ_DATA	*	mp_obj		= NULL;
CHAR_DATA	*	mp_char		= NULL;

int			lhsvl		= 0;
int			rhsvl		= 0;

sh_int		valid_exit	= 0;

CHAR_DATA *	pfind_mob		= NULL;
sh_int		pfind_dir		= 0;


/*
 * Functions for Grimace's 32-bit quest engine
 */
void set_quest_bits( unsigned char **pointer, unsigned int offset, unsigned int bits, unsigned int value )
{
	unsigned int cnt;
	unsigned int bytec, byteb, bitval, cbitval;
	unsigned char *pt;

	push_call("set_quest_bits(%p,%p,%p,%p)",pointer,offset,bits,value);

	if (offset + bits >= 8 * MAX_QUEST_BYTES || bits > 32)
	{
		log_printf("set_quest_bits: invalid bit range: %u %u %u", offset, bits, value);
		dump_stack();
		pop_call();
		return;
	}

	pt = (*pointer);

	if (pt == NULL)
	{
		if (value == 0)
		{
			pop_call();
			return;
		}
		ALLOCMEM(pt, bool, MAX_QUEST_BYTES);
		*pointer = pt;
	}

	for (cnt = 0 ; cnt < bits ; cnt++, offset++)
	{
		bytec   = offset / 8;
		byteb   = 1 << (offset % 8);
		cbitval = (*(pt + bytec)) & byteb;
		bitval  = value % 2;

		value /= 2;

		if (bitval == 0)
		{
			if (cbitval != 0)
			{
				*(pt+bytec) -= byteb;
			}
		}
		else
		{
			if (cbitval == 0)
			{
				*(pt+bytec) += byteb;
			}
		}
	}

	if (!is_quest(pt))
	{
		FREEMEM( pt );
		*pointer = NULL;
	}
	pop_call();
	return;
}

int get_quest_bits(unsigned char *pt, unsigned int offset, unsigned int bits)
{
	unsigned int cnt, value, refer;
	unsigned int bytec, byteb, cbitval;

	push_call("get_quest_bits(%p,%p,%p)",pt,offset,bits);

	if (pt == NULL)
	{
		pop_call();
		return 0;
	}

	if (offset + bits >= 8 * MAX_QUEST_BYTES || bits > 32)
	{
		log_printf("get_quest_bits: invalid bit range: %u %u", offset, bits);
		dump_stack();
		pop_call();
		return 0;
	}

	refer  = 1;
	value  = 0;

	for (cnt = 0 ; cnt < bits ; cnt++, offset++)
	{
		bytec   = offset / 8;
		byteb   = 1 << (offset % 8);
		cbitval = (*(pt+bytec)) & byteb;
		if (cbitval > 0)
		{
			value += refer;
		}
		refer *= 2;
	}
	pop_call();
	return(value);
}


lg_int mprog_name_to_type ( char *name )
{
	push_call("mprog_name_to_type(%p)",name);

	switch (*name)
	{
		case 'a':
			if (!strcmp(name, "act_prog"			)) { pop_call(); return ACT_PROG;		}
			if (!strcmp(name, "all_greet_prog")) { pop_call(); return GREET_PROG;	}
			if (!strcmp(name, "arrival_prog"	)) { pop_call(); return ARRIVAL_PROG;	}
			break;
		case 'b':
			if (!strcmp(name, "bribe_prog"		)) { pop_call(); return BRIBE_PROG;	}
			if (!strcmp(name, "buy_prog"			)) { pop_call(); return BUY_PROG;	}
			break;
		case 'c':
			if (!strcmp(name, "cast_prog"			)) { pop_call(); return CAST_PROG;	}
			break;
		case 'd':
			if (!strcmp(name, "damage_prog"		)) { pop_call(); return DAMAGE_PROG;	}
			if (!strcmp(name, "day_prog"			)) { pop_call(); return DAY_PROG;	}
			if (!strcmp(name, "death_prog"		)) { pop_call(); return DEATH_PROG;	}
			if (!strcmp(name, "delay_prog"		)) { pop_call(); return DELAY_PROG;	}
			if (!strcmp(name, "desc_prog"			)) { pop_call(); return DESC_PROG;		}
			if (!strcmp(name, "drop_prog"			)) { pop_call(); return DROP_PROG;		}
			if (!strcmp(name, "do_greet_prog" )) { pop_call(); return DO_GREET_PROG;	}
			break;
		case 'e':
			if (!strcmp(name, "entry_prog"		)) { pop_call(); return ENTRY_PROG;	}
			if (!strcmp(name, "exa_prog"			)) { pop_call(); return DESC_PROG;		}
			if (!strcmp(name, "exit_prog"			)) { pop_call(); return EXIT_PROG;		}
			break;
		case 'f':
			if (!strcmp(name, "fight_prog"		)) { pop_call(); return FIGHT_PROG;	}
			break;
		case 'g':
			if (!strcmp(name, "get_prog"			)) { pop_call(); return GET_PROG;	}
			if (!strcmp(name, "greet_prog"		)) { pop_call(); return GREET_PROG;	}
			if (!strcmp(name, "group_greet_prog"	)) { pop_call(); return GROUP_GREET_PROG;}
			if (!strcmp(name, "give_prog"			)) { pop_call(); return GIVE_PROG;		}
			break;
		case 'h':
			if (!strcmp(name, "hit_prog"			)) { pop_call(); return HIT_PROG;	}
			if (!strcmp(name, "hitprcnt_prog"	)) { pop_call(); return HITPRCNT_PROG;	}
			break;
		case 'i':
			if (!strcmp(name, "injure_prog"		)) { pop_call(); return HIT_PROG;	}
			if (!strcmp(name, "intercept_prog")) { pop_call(); return INTERCEPT_PROG;	}
			break;
		case 'k':
			if (!strcmp(name, "kill_prog"			)) { pop_call(); return KILL_PROG;		}
			break;
		case 'l':
			if (!strcmp(name, "leave_prog"		)) { pop_call(); return EXIT_PROG;		}
			break;
		case 'm':
			if (!strcmp(name, "month_prog"		)) {	pop_call(); return MONTH_PROG;	}
			break;
		case 'r':
			if (!strcmp(name, "rand_prog"			)) {	pop_call(); return RAND_PROG;	}
			if (!strcmp(name, "range_prog"		)) { pop_call(); return RANGE_PROG;	}		
			if (!strcmp(name, "repop_prog"		)) { pop_call(); return REPOP_PROG;	}
			if (!strcmp(name, "remove_prog"		)) { pop_call(); return REMOVE_PROG;	}
			break;
		case 's':
			if (!strcmp(name, "sayto_prog"		)) { pop_call(); return SAYTO_PROG;	}
			if (!strcmp(name, "sac_prog"			)) { pop_call(); return SAC_PROG;	}
			if (!strcmp(name, "social_prog"		)) { pop_call(); return SOCIAL_PROG;	}
			if (!strcmp(name, "speech_prog"		)) { pop_call(); return SPEECH_PROG;	}
			break;
		case 't':
			if (!strcmp(name, "time_prog"			)) { pop_call(); return TIME_PROG;		}
			if (!strcmp(name, "trigger_prog"	)) { pop_call(); return TRIGGER_PROG;	}
			if (!strcmp(name, "trap_prog"			)) { pop_call(); return TRAP_PROG;	}
			break;
		case 'u':
			if (!strcmp(name, "use_prog"			)) { pop_call(); return USE_PROG;		}
			break;
		case 'w':
			if (!strcmp(name, "wear_prog"			)) { pop_call(); return WEAR_PROG;		}
			break;
	}
	pop_call();
	return ERROR_PROG;
}

char *mprog_type_to_name( lg_int type )
{
	switch ( type )
	{
		case ACT_PROG:				return "act_prog";
		case ARRIVAL_PROG:		return "arrival_prog";
		case BRIBE_PROG:			return "bribe_prog";
		case BUY_PROG:				return "buy_prog";
		case CAST_PROG:				return "cast_prog";
		case DAMAGE_PROG:			return "damage_prog";
		case DAY_PROG:				return "day_prog";
		case DEATH_PROG:			return "death_prog";
		case DELAY_PROG:			return "delay_prog";
		case DESC_PROG:				return "desc_prog";
		case DO_GREET_PROG:		return "do_greet_prog";
		case DROP_PROG:				return "drop_prog";
		case ENTRY_PROG:			return "entry_prog";
		case EXIT_PROG:				return "exit_prog";
		case FIGHT_PROG:			return "fight_prog";
		case GET_PROG:				return "get_prog";
		case GIVE_PROG:				return "give_prog";
		case GREET_PROG:			return "greet_prog";
		case GROUP_GREET_PROG:	return "group_greet_prog";
		case HIT_PROG:				return "hit_prog";
		case HITPRCNT_PROG:		return "hitprcnt_prog";
		case INTERCEPT_PROG:	return "intercept_prog";
		case KILL_PROG:				return "kill_prog";
		case MONTH_PROG:			return "month_prog";
		case RAND_PROG:				return "rand_prog";
		case RANGE_PROG:			return "range_prog";
		case REMOVE_PROG:			return "remove_prog";
		case REPOP_PROG:			return "repop_prog";
		case SAC_PROG:				return "sac_prog";
		case SAYTO_PROG:			return "sayto_prog";
		case SOCIAL_PROG:			return "social_prog";
		case SPEECH_PROG:			return "speech_prog";
		case TIME_PROG:				return "time_prog";
		case TRAP_PROG:				return "trap_prog";
		case TRIGGER_PROG:		return "trigger_prog";
		case USE_PROG:				return "use_prog";
		case WEAR_PROG:				return "wear_prog";
		default:							return "ERROR_PROG";
	}
}


/* 
 * aggressive routine
 * adapted from aggro check by John A. Booth <john@ulantris.csci.unt.edu>
 * save processor cycles and make aggro more predictable by taking it
 * out of violence_update and into the same locations as greet_prog.
 */
bool check_aggro( CHAR_DATA *ch )
{
	CHAR_DATA *victim;
	CHAR_DATA *fch, *fch_next;
	bool check = FALSE;

	push_call("check_aggro()");
	
	for (fch = ch->in_room->first_person; fch != NULL; fch = fch_next)
	{
		fch_next	= fch->next_in_room;
	
		if (!IS_ACT(fch, ACT_AGGRESSIVE) || IS_AFFECTED(fch, AFF2_CALMED))
		{
			continue;
		}
		if (!MP_VALID_MOB(fch))
		{
			continue;
		}
		if (!IS_AWAKE(fch) || in_combat(fch) || fch->hit < get_max_hit(fch)/2)
		{
			continue;
		}
		if (IS_ACT(fch, ACT_WIMPY))
		{
			continue;
		}
		if (!can_see(fch, ch) || number_bits(1) == 0)
		{
			continue;
		}
		if (ch->master)
		{
			if (in_same_room(ch, ch->master))
			{
				victim = ch->master;
			}
			else
			{
				continue;
			}
		}
		else
		{
			victim = ch;
		}
		fight(fch, victim);
		check = TRUE;
	}
	pop_call();
	return check;
}

/*
	These two functions do the basic evaluation of ifcheck operators.
*/
bool mprog_seval( char *lhs, char *opr, char *rhs )
{
	push_call("mprog_seval(%p,%p,%p)",lhs,opr,rhs);

	switch (opr[0])
	{
		case '=':
			pop_call();
			return !strcasecmp(lhs, rhs);

		case '!':
			switch (opr[1])
			{
				case '=':
					pop_call();
					return strcasecmp(lhs, rhs);
				case '/':
					pop_call();
					return str_infix(rhs, lhs);
			}
			break;

		case '/':
			pop_call();
			return !str_infix(rhs, lhs);
	}

	log_printf("mprog_seval: invalid operator, dumping stack:\n\r");
	dump_stack();

	pop_call();
	return FALSE;
}

bool mprog_veval( int lhs, char *opr, int rhs )
{
	push_call("mprog_veval(%p,%p,%p)",lhs,opr,rhs);

	switch (opr[0])
	{
		case '=':
			pop_call();
			return ( lhs == rhs );

		case '!':
			pop_call();
			return ( lhs != rhs );

		case '>':
			switch (opr[1])
			{
				case '\0':
					pop_call();
					return ( lhs > rhs );

				case '=':
					pop_call();
					return ( lhs >= rhs );
			}
			break;
		case '<':
			switch (opr[1])
			{
				case '\0':
					pop_call();
					return ( lhs < rhs );

				case '=':
					pop_call();
					return ( lhs <= rhs );
			}
			break;

		case '&':
			pop_call();
			return ( lhs & rhs );

		case '|':
			pop_call();
			return ( lhs | rhs );
	}
	log_printf("mprog_veval: invalid operator, dumping stack\n\r");
	dump_stack();

	pop_call();
	return FALSE;
}


lg_int	mprog_case_val( CHAR_DATA *mob, char *case_val )
{
	int cnt;

	push_call("mprog_case_val(%p,%p",mob,case_val);

	if (isalpha(case_val[0]))
	{
		for (cnt = mud->bitvector_ref[toupper(case_val[0]) - 'A'] ; *bitvector_table[cnt].name != '\0' ; cnt++)
		{
			if (!strcasecmp(bitvector_table[cnt].name, case_val))
			{
				pop_call();
				return bitvector_table[cnt].value;
			}
		}
	}
	else if (isdigit(case_val[0]))
	{
		pop_call();
		return atoll(case_val);
	}
	log_build_printf(mob->pIndexData->vnum, "bad case value: '%s'", case_val);

	pop_call();
	return -1;
}


bool valid_mp_exit( EXIT_DATA *pExit )
{
	if (room_index[pExit->to_room] == NULL)
	{
		return FALSE;
	}

	if (IS_SET(pfind_mob->act, ACT_NOWANDER) && pfind_mob->reset && room_index[pExit->to_room]->sector_type != room_index[pfind_mob->reset->arg3]->sector_type)
	{
		return FALSE;
	}

	if (IS_SET(pfind_mob->act, ACT_STAY_AREA) && room_index[pExit->to_room]->area->low_r_vnum != mob_index[pfind_mob->pIndexData->vnum]->area->low_r_vnum)
	{
		return FALSE;
	}
	
	if (room_index[pExit->to_room]->area != pfind_mob->in_room->area)
	{
		return FALSE;
	}

	if (IS_SET(pExit->exit_info, EX_CLOSED))
	{
		if (!IS_AFFECTED(pfind_mob, AFF_GASEOUS)
		&&  !rspec_req(pfind_mob, RSPEC_INCORPOREAL))
		{
			return FALSE;
		}

		if (IS_SET(pExit->exit_info, EX_PASSPROOF))
		{
			return FALSE;
		}
	}

	if (IS_SET(room_index[pExit->to_room]->room_flags, ROOM_BLOCK))
	{
		return FALSE;
	}
	return TRUE;
}


/*
	Fast short distance node weighted algorithm, can be used to backtrack the
	entire shortest path - Scandum
*/

void mprog_findpath(ROOM_INDEX_DATA *room, bool cnt)
{
	bool door;

	world_index[room->vnum - room->area->low_r_vnum] = cnt;

	if (cnt < lhsvl)
	{
		if (room->vnum == rhsvl)
		{
			lhsvl      = cnt;
			valid_exit = pfind_dir;
		}
		else
		{
			cnt++;

			for (door = 0 ; door < 6 ; door++)
			{
				if (room->exit[door] && valid_mp_exit(room->exit[door]))
				{
					if (world_index[room->exit[door]->to_room - room->area->low_r_vnum] > cnt)
					{
						mprog_findpath(room_index[room->exit[door]->to_room], cnt);
					}
				}
			}
		}
	}
}

char *parse_mprog_var( char *cmnd, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, CHAR_DATA *rndm )
{
	static char results[ MAX_STRING_LENGTH * 2 ];
	int cnt;
	CHAR_DATA *chkchar = NULL;
	OBJ_DATA *chkobj = NULL;
	
	results[0] = '\0';
	for( cnt = 0; cmnd[cnt] != '\0'; cnt++ ) //Parse through every letter looking for a variable
	{
		chkchar = NULL;
		chkobj = NULL;

		if( cmnd[cnt] == '\0' ) //Reached the end, return.
			return results;

		if( cmnd[cnt] != '$' ) //Isn't a variable put it back.
			add_letter( results, cmnd[cnt] );
		else
		{
			switch( cmnd[cnt + 1] )
			{
					default:
						add_letter( results, cmnd[cnt] ); //Next letter is not a $ it should just take care of itself
						break;

					case 'i':
						chkchar = mob;
						break;

					case 'n':
						chkchar = actor;
						break;

					case 't':
						chkchar = mp_char;
						break;

					case 'r':
						chkchar = rndm;
						break;

					case 'o':
						chkobj = obj;
						break;

					case 'p':
						chkobj = mp_obj;
						break;
			}
		}
		if( chkchar || chkobj ) //Obviously, something was valid.
		{
			cnt += 2; //skip identifier, go for the meat
			if( cmnd[cnt] != '.' || cmnd[cnt] == '\0' || cmnd[cnt+1] == '\0' || cmnd[cnt+1] == ' ' ) //Not a period, just a normal variable, put it back.
			{
				add_letter( results, cmnd[cnt-2]); 
				add_letter( results, cmnd[cnt-1]); 
				add_letter( results, cmnd[cnt]); 
				if( cmnd[cnt] == '\0' )
						return results;
				continue;
			}
			else	//This is an expanded variable, pick out the word, and figure out what they want.
			{
				char word[MAX_INPUT_LENGTH];;
				word[0] = '\0';
				cnt++;

				while ( ( isalpha( cmnd[cnt] ) || isdigit( cmnd[cnt] ) ) && cmnd[cnt] != '\0' )	
				{
					add_letter( word, cmnd[cnt] );
					cnt++;
				}

				if( chkchar != NULL ) //Character checks, add any you want. 
				{
					if( !strcasecmp( word, "name" ) )
						strcat( results, get_name(chkchar) );
					else if( !strcasecmp( word, "sex" ) )
						strcat( results, sex_types[chkchar->sex] );
					else if( !strcasecmp( word, "adj" ) )
						strcat( results, adjective(chkchar) );
					else if( !strcasecmp( word, "class" ) )
						strcat( results, class_types[chkchar->class] );
					else if( !strcasecmp( word, "race") )
						strcat( results, race_table[get_race(chkchar)].race_name );
					else if( !strcasecmp( word, "god") )
						strcat( results, get_god_name(chkchar->god) );
					else if( !strcasecmp( word, "level") )
						strcat( results, format( "%d", chkchar->level ) );
				}

				if( chkobj != NULL ) //Object checks, just add if checks for what you want.
				{
					if( !strcasecmp( word, "type") )
						strcat( results, o_types[chkobj->item_type] );
				}

				if( cmnd[cnt] == '\0') //No word found, return the string.
					return results;
				else //Put it back.
					add_letter( results, cmnd[cnt]);
			}
		}
	}
	return results;
}

/*
	This function performs the evaluation of the if checks.
*/

char mprog_do_ifchck( char *ifchck, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, CHAR_DATA *rndm)
{
	char buf[ MAX_INPUT_LENGTH ];
	char arg[ MAX_INPUT_LENGTH ];
	char opr[ MAX_INPUT_LENGTH ];
	char val[ MAX_INPUT_LENGTH ];
	char val1[ MAX_INPUT_LENGTH ];
	char val2[ MAX_INPUT_LENGTH ];
	char *argument;
	

	CHAR_DATA *ifchk_char  = NULL;
	CHAR_DATA *ifchk_char2 = NULL;
	OBJ_DATA  *ifchk_obj   = NULL;
	OBJ_DATA  *ifchk_obj2  = NULL;

	char		*bufpt = buf;
	char		*argpt = arg;
	char		*oprpt = opr;
	char		*valpt = val;
	char		*point = ifchck;

	int		cnt;
	bool		retval;

	push_call("mprog_do_ifchck(%p,%p,%p,%p,%p,%p)",ifchck,mob,actor,obj,vo,rndm);

	retval = -1;

	if (*point == '\0')
	{
		log_build_printf(mob->pIndexData->vnum, "null ifchck");
		pop_call();
		return -1;
	}

	/*
		store the if check name in 'buf'
	*/

	while (*point != '(')
	{
		if (*point == ' ')
		{
			point++;
		}
		else
		{
			*bufpt++ = *point++;
		}
	}

	*bufpt = '\0';
	point++;

	/*
		store whatever is between the ( ) in 'arg'
	*/

	while (*point != ')')
	{
		*argpt++ = *point++;
	}

	*argpt = '\0';
	point++;

	/*
		store the operator in 'opr'
	*/

	if (*point == '\0')
	{
		*opr = '\0';
		*val = '\0';
	}
	else
	{
		point++;

		while (*point != ' ')
		{
			*oprpt++ = *point++;
		}
		*oprpt = '\0';
		point++;

		/*
			store the value in 'val'
		*/

		while (*point != '\0')
		{
			*valpt++ = *point++;
		}
		*valpt = '\0';
	}

	/*
		Capture the value in argument for more fun with command line
	*/
	
	argument = STRALLOC(val);
	argument = one_argument(argument, val1);
	argument = one_argument(argument, val2);

	/*
		Translate the value if needed
	*/
	if (isalpha(val[0]))
	{
		for (cnt = mud->bitvector_ref[toupper(val[0]) - 'A'] ; *bitvector_table[cnt].name != '\0' ; cnt++)
		{
			if (toupper(val[0]) == bitvector_table[cnt].name[0])
			{
				if (!strcasecmp(bitvector_table[cnt].name, val))
				{
					sprintf(val, "%lld", bitvector_table[cnt].value);
					break;
				}
			}
			else
			{
				break;
			}
		}
	}
	else
	{
		if (val[0] == '$')
		{
			switch (val[1])
			{
				case 'i':
					ifchk_char2 = mob;
					break;
				case 'n':
					ifchk_char2 = actor;
					break;
				case 't':
					ifchk_char2 = mp_char;
					break;
				case 'r':
					ifchk_char2 = rndm;
					break;
				case 'o':
					ifchk_obj2  = obj;
					break;
				case 'c':
					ifchk_obj2  = mp_obj;
					break;
				default:
					strcpy(val, mprog_cmd_translate(val, mob, actor, obj, vo, rndm));
					break;
			}
		}
	}

	if (arg[0] == '$')
	{
		switch (arg[1])
		{
			case 'i':
				ifchk_char = mob;
				break;
			case 'n':
				ifchk_char = actor;
				break;
			case 't':
				ifchk_char = mp_char;
				break;
			case 'r':
				ifchk_char = rndm;
				break;
			case 'o':
				ifchk_obj  = obj;
				break;
			case 'c':
				ifchk_obj  = mp_obj;
				break;
			case 'x':
				sprintf(arg, "%d", lhsvl);
				break;
			case 'X':
				sprintf(arg, "%s", mob->npcdata->remember);
				break;
		}
	}

	switch (buf[0])
	{
		case 'a':
			if (!strcmp(buf, "actorhasobjnum"))
			{
				if (actor == NULL)
				{
					log_build_printf(mob->pIndexData->vnum, "No actor defined for 'actorhasobjnum'");
					pop_call();
					return FALSE;
				}
				retval = ((mp_obj = get_obj_carry_vnum(actor, atol(arg))) != NULL);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "actortypewear" ) )
			{
				if (actor == NULL)
				{
					log_build_printf(mob->pIndexData->vnum, "No actor defined for 'actorwearsobjnum'");
					pop_call();
					return FALSE;
				}
				retval = ((mp_obj = get_obj_wear_type(actor, atol(arg))) != NULL);
				lhsvl  = mp_obj ? mp_obj->pIndexData->vnum : -1;
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "actorwearsobjnum" ) )
			{
				if (actor == NULL)
				{
					log_build_printf(mob->pIndexData->vnum, "No actor defined for 'actorwearsobjnum'");
					pop_call();
					return FALSE;
				}
				retval = ((mp_obj = get_obj_wear_vnum(actor, atol(arg))) != NULL);
				lhsvl  = mp_obj ? mp_obj->wear_loc : WEAR_NONE;
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "align"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->alignment;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "areaquest"))
			{
				int firstBit, len;
				AREA_DATA *area;
				char name[MAX_INPUT_LENGTH];

				if (sscanf(arg, "%d, %d, %s", &firstBit, &len, name) != 3)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <areaquest (%s)>", arg);
					pop_call();
					return FALSE;
				}

				switch (name[1])
				{
					case 'i':
						area = mob->pIndexData->area;
						break;

					case 'o':
						if (obj)
						{
							area = obj->pIndexData->area;
						}
						else
						{
							pop_call();
							return -1;
						}
						break;

					case 'c':
						if (mp_obj)
						{
							area = mp_obj->pIndexData->area;
						}
						else
						{
							pop_call();
							return -1;
						}
						break;

					default:
						log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <areaquest (%s)>", arg);
						pop_call();
						return FALSE;
				}

				lhsvl  = get_quest_bits( area->area_quest, firstBit, len);
				rhsvl  = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);

				pop_call();
				return retval;
			}
			break;

		case 'b':
			if (!strcmp(buf, "bluff_check"))
			{
				if (ifchk_char)
				{
					lhsvl = bluff_roll(ifchk_char);
					if (ifchk_char2)
					{
						rhsvl = bluff_check(ifchk_char, ifchk_char2, lhsvl, 0);
					}
					else if (is_number(val))
					{
						rhsvl = bluff_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if bluff_check: value must be a number (DC) or an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'c':
			if ( !strcmp( buf, "cansee" ) )
			{
				if (ifchk_char)
				{
					retval = can_see(mob, ifchk_char);
				}
				else if (ifchk_obj)
				{
					retval = can_see_obj(mob, ifchk_obj);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "charinroom"))
			{
				if (ifchk_char && ifchk_char->in_room)
				{
					mp_char = get_char_room(ifchk_char, val);
					retval = mprog_seval(get_name(get_char_room(ifchk_char, val)), opr, val);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "cancarry"))
			{
				if (ifchk_char)
				{
					retval = (ifchk_char->carry_number < can_carry_n(ifchk_char) && get_carry_w(ifchk_char) < can_carry_w(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "cha_check"))
			{
				if (ifchk_char)
				{
					if (ifchk_char2)
					{
						lhsvl  = cha_roll(ifchk_char);
						rhsvl  = cha_roll(ifchk_char2);
					}
					else if (is_number(val))
					{
						lhsvl  = cha_roll(ifchk_char);
						rhsvl  = atol(val);
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if cha_check: value must be a number (DC) or an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "class"))
			{
				if (ifchk_char)
				{
					if ((rhsvl = lookup_class(val1)) == -1)
						rhsvl  = atol(val);
					if ((lhsvl = ifchk_char->mclass[rhsvl]) == 0)
						lhsvl = ifchk_char->class;
					else
						lhsvl = rhsvl;
					retval = ifchk_char->mclass[rhsvl];
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "climb_check"))
			{
				if (ifchk_char)
				{
					lhsvl = climb_roll(ifchk_char);
					if (is_number(val))
					{
						rhsvl = climb_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if climb_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "con_check"))
			{
				if (ifchk_char)
				{
					if (ifchk_char2)
					{
						lhsvl  = con_roll(ifchk_char);
						rhsvl  = con_roll(ifchk_char2);
					}
					else if (is_number(val))
					{
						lhsvl  = con_roll(ifchk_char);
						rhsvl  = atol(val);
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if con_check: value must be a number (DC) or an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "concentration_check"))
			{
				if (ifchk_char)
				{
					lhsvl = concentration_roll(ifchk_char);
					if (is_number(val))
					{
						rhsvl = concentration_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if concentration_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "curr_str"))
			{
				if (ifchk_char)
				{
					lhsvl  = get_curr_str(ifchk_char);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "curr_dex"))
			{
				if (ifchk_char)
				{
					lhsvl  = get_curr_dex(ifchk_char);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "curr_con"))
			{
				if (ifchk_char)
				{
					lhsvl  = get_curr_con(ifchk_char);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "curr_int"))
			{
				if (ifchk_char)
				{
					lhsvl  = get_curr_int(ifchk_char);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "curr_wis"))
			{
				if (ifchk_char)
				{
					lhsvl  = get_curr_wis(ifchk_char);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "curr_cha"))
			{
				if (ifchk_char)
				{
					lhsvl  = get_curr_cha(ifchk_char);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'd':
			if (!strcmp(buf, "day"))
			{
				lhsvl  = mud->time_info->day;
				rhsvl  = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "decipher_script_check"))
			{
				if (ifchk_char)
				{
					if (!learned(ifchk_char, gsn_decipher_script))
					{
						pop_call();
						return FALSE;
					}
					else if (is_number(val))
					{
						lhsvl = decipher_script_roll(ifchk_char);
						rhsvl = decipher_script_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if decipher_script_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "deity"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->god;
					if ((rhsvl = lookup_god(val1)) == -1)
						rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "dex_check"))
			{
				if (ifchk_char)
				{
					if (ifchk_char2)
					{
						lhsvl  = dex_roll(ifchk_char);
						rhsvl  = dex_roll(ifchk_char2);
					}
					else if (is_number(val))
					{
						lhsvl  = dex_roll(ifchk_char);
						rhsvl  = atol(val);
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if dex_check: value must be a number (DC) or an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "delayed"))
			{
				if (ifchk_char)
				{
					if (!IS_NPC(ifchk_char))
					{
						lhsvl = ifchk_char->wait;
					}
					else
					{
						lhsvl = ifchk_char->wait / 2 + ifchk_char->timer;
					}
					retval = (lhsvl > 0);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "diplomacy_check"))
			{
				if (ifchk_char)
				{
					lhsvl = diplomacy_roll(ifchk_char);
					if (is_number(val))
					{
						rhsvl = diplomacy_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if diplomacy_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "disable_device_check"))
			{
				if (ifchk_char)
				{
					if (!learned(ifchk_char, gsn_disable_device))
					{
						pop_call();
						return FALSE;
					}
					else if (is_number(val))
					{
						lhsvl = disable_device_roll(ifchk_char);
						rhsvl = disable_device_check(ifchk_char, NULL, lhsvl, atol(val)) >= 0;
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if disable_device_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "disguise_check"))
			{
				if (ifchk_char)
				{
					if (!IS_NPC(ifchk_char))
					{
						lhsvl = disguise_roll(ifchk_char);
						if (ifchk_char2)
						{
							rhsvl = disguise_check(ifchk_char, ifchk_char2, lhsvl, 0) >= 0;
						}
						else if (is_number(val))
						{
							rhsvl = disguise_check(ifchk_char, NULL, lhsvl, atol(val)) >= 0;
						}
						else
						{
							log_build_printf(mob->pIndexData->vnum, "if disguise_check: value must be a number (DC) or an opposing $target.");
							pop_call();
							return FALSE;
						}
					}
					else if (is_number(val))
					{
						lhsvl = atol(val);
						rhsvl = disguise_check(ifchk_char, actor, lhsvl, 0) >= 0;
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if disguise_check: value for NPC check must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'e':
			if (!strcmp(buf, "escape_artist_check"))
			{
				if (ifchk_char)
				{
					lhsvl = escape_artist_roll(ifchk_char);
					if (is_number(val))
					{
						rhsvl = escape_artist_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if escape_artist_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "ethos"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->ethos;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "existsroom"))
			{
				OBJ_DATA  *robj;
				CHAR_DATA *rch;

				if (arg[0] == '$')
				{
					switch (arg[1])
					{
						case 'n':
						case 'r':
						case 't':
							if (ifchk_char)
							{
								pop_call();
								return (mob->in_room == ifchk_char->in_room);
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'o':
						case 'c':
							if (ifchk_obj && ifchk_obj->in_room)
							{
								pop_call();
								return (mob->in_room == ifchk_obj->in_room);
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <existsroom (%s)>", arg);
							break;
					}
				}

				if (!strcmp(arg, "mob"))
				{
					for (mp_char = NULL, cnt = 0, rch = mob->in_room->first_person ; rch ; rch = rch->next_in_room)
					{
						if (IS_NPC(rch) && mob != rch)
						{
							if (number_range(0, cnt) == 0)
							{
								mp_char = rch;
							}
							cnt++;
						}
					}
					pop_call();
					return (mp_char != NULL);
				}

				if (!strcmp(arg, "plr"))
				{
					for (mp_char = NULL, cnt = 0, rch = mob->in_room->first_person ; rch ; rch = rch->next_in_room)
					{
						if (!IS_NPC(rch) && mob != rch)
						{
							if (number_range(0, cnt) == 0)
							{
								mp_char = rch;
							}
							cnt++;
						}
					}
					pop_call();
					return (mp_char != NULL);
				}

				if (!strcmp(arg, "obj"))
				{
					for (mp_obj = NULL, cnt = 0, robj = mob->in_room->first_content ; robj ; robj = robj->next_content)
					{
						if (number_range(0, cnt) == 0)
						{
							mp_obj = robj;
						}
						cnt++;
					}
					pop_call();
					return (mp_obj != NULL);
				}

				if ((mp_char = get_char_room_even_blinded(mob, arg)) != NULL)
				{
					pop_call();
					return TRUE;
				}

				if ((mp_obj = get_obj_list_even_blinded(mob, arg, mob->in_room->first_content)) != NULL)
				{
					pop_call();
					return TRUE;
				}

				pop_call();
				return FALSE;
			}

			if (!strcmp(buf, "existsarea"))
			{
				if (arg[0] == '$')
				{
					switch (arg[1])
					{
						case 'n':
						case 'r':
						case 't':
							if (ifchk_char)
							{
								pop_call();
								return (mob->in_room->area == ifchk_char->in_room->area);
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'o':
						case 'c':
							if (ifchk_obj)
							{
								pop_call();
								return (ifchk_obj->in_room && mob->in_room->area == ifchk_obj->in_room->area);
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <existsarea (%s)>", arg);
							break;
					}
				}

				if ((mp_char = get_char_area_even_blinded(mob, arg)) != NULL)
				{
					pop_call();
					return TRUE;
				}

				if ((mp_obj = get_obj_area_even_blinded(mob, arg)) != NULL)
				{
					pop_call();
					return TRUE;
				}

				pop_call();
				return FALSE;
			}
			break;

		case 'f':
			if (!strcmp(buf, "findpath"))
			{
				ROOM_INDEX_DATA *room;
				int area_size;

				if (sscanf(arg, "%d, %d", &rhsvl, &lhsvl) != 2)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <findpath (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (lhsvl < 1 || lhsvl > 100)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad Path length: <findpath (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if ((room = get_room_index(rhsvl)) == NULL)
				{
					log_build_printf(mob->pIndexData->vnum, "Room not found: <findpath (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (room == mob->in_room)
				{
					log_build_printf(mob->pIndexData->vnum, "Already there: <findpath (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (room->area != mob->in_room->area)
				{
					log_build_printf(mob->pIndexData->vnum, "Destination not in mob's area <findpath (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if ((area_size = room->area->hi_r_vnum - room->area->low_r_vnum) >= 2000)
				{
					log_build_printf(mob->pIndexData->vnum, "Area too big <findpath (%s)>", arg);
					pop_call();
					return FALSE;
				}

				pfind_mob  = mob;
				valid_exit = -1;

				memset(world_index, 128, area_size);
				world_index[mob->in_room->vnum - room->area->low_r_vnum] = 0;

				for (pfind_dir = 0 ; pfind_dir < 6 ; pfind_dir++)
				{
					if (mob->in_room->exit[pfind_dir] && valid_mp_exit(mob->in_room->exit[pfind_dir]))
					{
						mprog_findpath(room_index[mob->in_room->exit[pfind_dir]->to_room], 1);
					}
				}

				pop_call();
				return (valid_exit != -1);
			}

			if (!strcmp(buf, "first_aid_check"))
			{
				if (ifchk_char)
				{
					lhsvl = first_aid_roll(ifchk_char);
					if (is_number(val))
					{
						rhsvl = first_aid_check(ifchk_char, NULL, lhsvl, atol(val)) >= 0;
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if first_aid_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'g':
			if (!strcmp(buf, "god"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->god;
					if ((rhsvl = lookup_god(val1)) == -1)
						rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "gold"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->gold;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				else if (ifchk_obj)
				{
					lhsvl  = ifchk_obj->cost;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

			/* does someone in the group have this qbit */
			if (!strcmp(buf, "groupquest"))
			{
				int firstBit,len;
				CHAR_DATA *victim;
				PLAYER_GAME *fpl;
				char name[MAX_INPUT_LENGTH];

				if (sscanf(arg, "%d, %d, %s", &firstBit, &len, name) != 3)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <groupquest (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (name[0] == '$')
				{
					switch (name[1])
					{
						case 'i':
							victim = mob;
							break;
						case 'n':
							if (actor)
							{
								victim = actor;
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "null target in ifcheck %s", arg);
								pop_call();
								return -1;
							}
							break;
						case 't':
							if (mp_char)
							{
								victim = mp_char;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'r':
							if ( rndm )
							{
								victim = rndm;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <groupguest (%s)>", arg );
							pop_call();
							return -1;
					}
				}
				else
				{
					victim = NULL;
				}

				if ((victim == NULL) && (victim = get_char_room_even_blinded(mob,name)) == NULL)
				{
					pop_call();
					return FALSE;
				}

				for (retval = FALSE, fpl = mud->f_player ; fpl ; fpl = fpl->next)
				{
					if (IS_NPC(fpl->ch))
						continue;

					if (fpl->ch != victim && !is_same_group(fpl->ch, victim))
						continue;

					lhsvl = get_quest_bits(victim->pcdata->quest[mob->pIndexData->area->low_r_vnum/100], firstBit, len);

					rhsvl = atol(val);

					if (mprog_veval(lhsvl,opr,rhsvl) == TRUE)
						retval = TRUE;
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "groupquestr"))
			{
				int firstBit,len, vnum;
				CHAR_DATA *victim;
				PLAYER_GAME *fpl;
				char name[MAX_INPUT_LENGTH];

				if (sscanf(arg, "%d, %d, %d, %s", &vnum, &firstBit, &len, name) != 4)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <groupguestr (%s)", arg);
					pop_call();
					return FALSE;
				}

				if (name[0] == '$')
				{
					switch (name[1])
					{
						case 'i':
							victim = mob;
							break;
						case 'n':
							if (actor)
							{
								victim = actor;
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "null target in ifcheck %s", arg);
								pop_call();
								return -1;
							}
							break;
						case 't':
							if (mp_char)
							{
								victim = mp_char;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'r':
							if (rndm)
							{
								victim = rndm;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'o':
							if (obj)
							{
								victim = NULL;
								one_argument_nolower(obj->name, name);
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <groupguestr (%s)>", arg);
								pop_call();
								return -1;
							}
							break;
						case 'c':
							if (mp_obj)
							{
								victim = NULL;
								one_argument_nolower(mp_obj->name, name);
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <groupguestr (%s)>", arg);
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <groupguestr (%s)>", arg);
							pop_call();
							return -1;
					}
				}
				else
				{
					victim = NULL;
				}

				if (vnum < 0 || vnum >= MAX_VNUM || room_index[vnum] == NULL)
				{
					pop_call();
					return(FALSE);
				}

				if ((victim == NULL) && (victim = get_char_room_even_blinded(mob,name)) == NULL)
				{
					pop_call();
					return FALSE;
				}

				for (retval = FALSE, fpl = mud->f_player ; fpl ; fpl = fpl->next)
				{
					if (IS_NPC(fpl->ch))
						continue;

					if (fpl->ch != victim && !is_same_group(fpl->ch, victim))
						continue;

					lhsvl = get_quest_bits(victim->pcdata->quest[room_index[vnum]->area->low_r_vnum/100], firstBit, len);

					rhsvl = atol(val);

					if (mprog_veval(lhsvl,opr,rhsvl) == TRUE)
						retval = TRUE;
				}
				pop_call();
				return retval;
			}
			break;

			/* number of PCs in a group */
			if (!strcasecmp(buf, "group_size") || !strcasecmp(buf, "group"))
			{
				PLAYER_GAME *fpl;

				if (ifchk_char)
				{
					for (lhsvl = 0, fpl = mud->f_player ; fpl ; fpl = fpl->next)
					{
						if (IS_NPC(fpl->ch))
							continue;
						if (fpl->ch == ifchk_char)
						{
							lhsvl++;
							continue;
						}
						else if (!is_same_group(ifchk_char, fpl->ch))
						{
							lhsvl++;
						}
					}
				}
				rhsvl  = atol(val);
				retval = mprog_veval(lhsvl, opr, rhsvl);
				pop_call();
				return retval;
			}

			/* total of PC levels in a group */
			if (!strcmp(buf, "group_levels"))
			{
				PLAYER_GAME *fpl;

				if (ifchk_char)
				{
					for (lhsvl = 0, fpl = mud->f_player ; fpl ; fpl = fpl->next)
					{
						if (IS_NPC(fpl->ch))
							continue;
						if (fpl->ch == ifchk_char)
						{
							lhsvl += fpl->ch->level;
							continue;
						}
						else if (!is_same_group(ifchk_char, fpl->ch))
						{
							lhsvl += fpl->ch->level;
						}
					}
				}
				rhsvl  = atol(val);
				retval = mprog_veval(lhsvl, opr, rhsvl);
				pop_call();
				return retval;
			}

		case 'h':
			if (!strcmp(buf, "handle_animal_check"))
			{
				if (ifchk_char)
				{
					lhsvl = handle_animal_roll(ifchk_char);
					if (is_number(val))
					{
						rhsvl = handle_animal_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if handle_animal_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "hasadj"))
			{
				if (ifchk_char && !IS_NPC(ifchk_char))
				{
					retval = is_string(ifchk_char->pcdata->adjective);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "hascompanion"))
			{
				if (ifchk_char && !IS_NPC(ifchk_char))
				{
					mp_char = get_companion(ifchk_char);
					retval  = (mp_char != NULL);
				}
				pop_call();
				return retval;
			}
			
			if (!strcmp(buf, "hasdesc"))
			{
				if (ifchk_char && !IS_NPC(ifchk_char))
				{
					retval = is_string(ifchk_char->description);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "hashorse"))
			{
				if (ifchk_char && !IS_NPC(ifchk_char))
				{
					mp_char = get_warhorse(ifchk_char);
					retval  = (mp_char != NULL);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "hasfamiliar"))
			{
				if (ifchk_char && !IS_NPC(ifchk_char))
				{
					mp_char = get_familiar(ifchk_char);
					retval  = (mp_char != NULL);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "hasobj"))
			{
				if (ifchk_char)
				{
					rhsvl  = ((mp_obj = get_obj_list_even_blinded(ifchk_char, arg, ifchk_char->first_carrying)) != NULL);
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "hasobjnum"))
			{
				if (ifchk_char)
				{
					rhsvl  = ((mp_obj = get_obj_carry_vnum(ifchk_char, atol(val))) != NULL);
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "haspet"))
			{
				if (ifchk_char && !IS_NPC(ifchk_char))
				{
					retval = get_pets(ifchk_char);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "hide_check"))
			{
				if (ifchk_char)
				{
					lhsvl = hide_roll(ifchk_char);
					
					if (!IS_AFFECTED(ifchk_char, AFF_HIDE))
					{
						pop_call();
						return FALSE;
					}
					if (ifchk_char2)
					{
						rhsvl = hide_check(ifchk_char, ifchk_char2, lhsvl, 0);
					}
					else if (is_number(val))
					{
						rhsvl = hide_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if hide_check: value must be a number (DC) or an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "hitprcnt"))
			{
				if (ifchk_char)
				{
					lhsvl  = 100 * ifchk_char->hit / UMAX(1, get_max_hit(ifchk_char));
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'i':
			if (!strcmp(buf, "int_check"))
			{
				if (ifchk_char)
				{
					if (ifchk_char2)
					{
						lhsvl  = int_roll(ifchk_char);
						rhsvl  = int_roll(ifchk_char2);
					}
					else if (is_number(val))
					{
						lhsvl  = int_roll(ifchk_char);
						rhsvl  = atol(val);
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if int_check: value must be a number (DC) or an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isaffected"))
			{
				if (ifchk_char)
				{
					retval = is_affected(ifchk_char, skill_lookup(val1));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "ischaotic"))
			{
				if (ifchk_char)
				{
					retval = (IS_CHAOTIC(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "iscompanion"))
			{
				if (ifchk_char)
				{
					if (IS_ACT(ifchk_char, ACT_COMPANION))
					{
						mp_char = ifchk_char->master;
						retval  = (mp_char != NULL);
					}
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "iscriminal"))
			{
				if (ifchk_char)
				{
					retval = (get_record(ifchk_char, mob->pIndexData->area, -1) != NULL);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isday"))
			{
				if (mud->time_info->hour >= 5 && mud->time_info->hour <=19)
				{
					pop_call();
					return TRUE;
				}
				else
				{
					pop_call();
					return FALSE;
				}
			}

			if (!strcmp(buf, "isdevoted"))
			{
				if (ifchk_char)
				{
					lhsvl = which_god(ifchk_char);
					retval = (lhsvl != 0);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isevil"))
			{
				if (ifchk_char)
				{
					retval = (IS_EVIL(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isfamiliar"))
			{
				if (ifchk_char)
				{
					if (IS_ACT(ifchk_char, ACT_FAMILIAR))
					{
						mp_char = ifchk_char->master;
						retval  = (mp_char != NULL);
					}
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isfight"))
			{
				if (ifchk_char)
				{
					mp_char = who_fighting(ifchk_char);
					retval  = (mp_char != NULL);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isfollow"))
			{
				if (ifchk_char)
				{
					mp_char = ifchk_char->master;
					retval  = (mp_char != NULL);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isgood"))
			{
				if (ifchk_char)
				{
					retval = (IS_GOOD(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "ishorse"))
			{
				if (ifchk_char)
				{
					if (IS_ACT(ifchk_char, ACT_WARHORSE))
					{
						mp_char = ifchk_char->master;
						retval  = (mp_char != NULL);
					}
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isimmort"))
			{
				if (ifchk_char)
				{
					retval = (IS_IMMORTAL(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "iskiller"))
			{
				if (ifchk_char)
				{
					retval = (IS_PLR(ifchk_char, PLR_KILLER));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "islawful"))
			{
				if (ifchk_char)
				{
					retval = (IS_LAWFUL(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "ismounted"))
			{
				if (ifchk_char)
				{
					mp_char = ifchk_char->mounting;
					retval  = (mp_char != NULL);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isneutral"))
			{
				if (ifchk_char)
				{
					retval = (IS_NEUTRAL(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isnight"))
			{
				if (mud->time_info->hour >= 5 && mud->time_info->hour <= 19)
				{
					pop_call();
					return FALSE;
				}
				else
				{
					pop_call();
					return TRUE;
				}
			}

			if (!strcmp(buf, "isnpc"))
			{
				if (ifchk_char)
				{
					retval = (IS_NPC(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "ispc"))
			{
				if (ifchk_char)
				{
					retval = (!IS_NPC(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "ispet"))
			{
				if (ifchk_char)
				{
					if (IS_ACT(ifchk_char, ACT_PET))
					{
						mp_char = ifchk_char->master;
						retval  = (mp_char != NULL);
					}
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "ispolymorph"))
			{
				if (ifchk_char)
				{
					lhsvl = ifchk_char->race;
					retval = (is_polymorph(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isthief"))
			{
				if (ifchk_char)
				{
					retval = (IS_PLR(ifchk_char, PLR_THIEF));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isunconcerned"))
			{
				if (ifchk_char)
				{
					retval = (IS_UNCONCERNED(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "isundead"))
			{
				if (ifchk_char)
				{
					retval = (IS_UNDEAD(ifchk_char));
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "inarea"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->in_room->area->low_r_vnum;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "inroom"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->in_room->vnum;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "intimidate_check"))
			{
				if (ifchk_char)
				{
					lhsvl = intimidate_roll(ifchk_char);
					
					if (ifchk_char2)
					{
						rhsvl = intimidate_check(ifchk_char, ifchk_char2, lhsvl, 0) >= 0;
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if intimidate_check: value must be an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'j':
			if (!strcmp(buf, "jump_check"))
			{
				if (ifchk_char)
				{
					lhsvl = jump_roll(ifchk_char);
					
					if (is_number(val))
					{
						rhsvl = jump_check(ifchk_char, NULL, lhsvl, atol(val)) >= 0;
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if jump_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'k':
			if (!strcmp(buf, "know_arcana_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_arcana_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_arcana_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "know_dungeoneering_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_dungeoneering_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_dungeoneering_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "know_geography_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_geography_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_geography_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "know_history_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_history_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_history_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "know_local_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_local_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_local_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "know_nature_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_nature_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_nature_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "know_nobility_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_nobility_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_nobility_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "know_religion_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_religion_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_religion_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "know_planes_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = know_planes_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if know_planes_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;
		
		case 'l':
			if (!strcmp(buf, "level"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->level;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				else if (ifchk_obj)
				{
					lhsvl  = ifchk_obj->level;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "level_check"))
			{
				if (ifchk_char)
				{
					lhsvl  = dice(1, 20) + ifchk_char->level;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'm':
			if (!strcmp(buf, "mclass"))
			{
				CHAR_DATA *victim;
				char name[MAX_INPUT_LENGTH];
				char mclass[MAX_INPUT_LENGTH];
				int cls;
				char *argument = (char *) arg;

				argument = grab_token(argument, mclass, ',');
				argument = one_argument(argument, name);
				
				if (mclass[0] == '\0' || name[0] == '\0')
				{
					log_build_printf(mob->pIndexData->vnum, "if mclass: <missing token (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (name[0] == '$')
				{
					switch (name[1])
					{
						case 'i':
							victim = mob;
							break;
						case 'n':
							if (actor)
							{
								victim = actor;
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "if mclass: <NULL target (%s)>", name);
								pop_call();
								return -1;
							}
							break;
						case 't':
							if (mp_char)
							{
								victim = mp_char;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'r':
							if ( rndm )
							{
								victim = rndm;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "if mclass: <bad name (%s)>", name );
							pop_call();
							return -1;
					}
				}
				else
				{
					victim = NULL;
				}

				if ((victim == NULL) && (victim = get_char_room_even_blinded(mob,name)) == NULL)
				{
					pop_call();
					return FALSE;
				}

				if (victim == NULL)
				{
					pop_call();
					return( FALSE );
				}

				if ((cls = lookup_class(mclass)) == -1)
				{
					log_build_printf(mob->pIndexData->vnum, "if mclass: <bad class (%s)>", mclass );
					pop_call();
					return FALSE;
				}
				
				lhsvl = victim->mclass[cls];
				if (ifchk_char2)
					rhsvl = ifchk_char2->mclass[cls];
				else
					rhsvl = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "month"))
			{
				lhsvl  = mud->time_info->month;
				rhsvl  = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "mount_check"))
			{
				if (ifchk_char)
				{
					lhsvl = mount_roll(ifchk_char);
					
					if (is_number(val))
					{
						rhsvl = mount_check(ifchk_char, ifchk_char->mounting, lhsvl, rhsvl);
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if mount_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'n':
			if (!strcmp(buf, "numberrange"))
			{
				int lo_range, hi_range;

				if (sscanf(arg, "%d,%d", &lo_range, &hi_range) != 2)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <numberrange (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (lo_range < 0)
				{
					log_build_printf(mob->pIndexData->vnum, "Negative range <numberrange (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (lo_range >= hi_range)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad range: <numberrange (%s)>", arg);
					pop_call();
					return FALSE;
				}
				lhsvl = number_range(lo_range, hi_range);
				rhsvl = atol(val);
				retval = mprog_veval(lhsvl, opr, rhsvl);

				pop_call();
				return retval;
			}

			if (!strcmp(buf, "number"))
			{
				switch (arg[1])  /* arg should be "$*" so just get the letter */
				{
					case 'i':
					case 'n':
					case 't':
					case 'r':
						if (ifchk_char)
						{
							if (IS_NPC(ifchk_char))
							{
								lhsvl  = ifchk_char->pIndexData->vnum;
								rhsvl  = atol(val);
								retval = mprog_veval(lhsvl, opr, rhsvl);
							}
						}
						break;
					case 'o':
					case 'c':
						if (ifchk_obj)
						{
							lhsvl  = ifchk_obj->pIndexData->vnum;
							rhsvl  = atol(val);
							retval = mprog_veval(lhsvl, opr, rhsvl);
						}
						break;
					default:
						lhsvl  = atoll(arg);
						rhsvl  = atoll(val);
						retval = mprog_veval(lhsvl, opr, rhsvl);
						break;
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "name"))
			{
				retval = mprog_seval(mprog_cmd_translate(arg, mob, actor, obj, vo, rndm), opr, val);

				pop_call();
				return retval;
			}
			break;

		case 'o':
			if (!strcmp(buf, "objquest"))
			{
				int firstBit,len;
				OBJ_DATA *item;
				char name[MAX_INPUT_LENGTH];

				if (sscanf(arg, "%d, %d, %s", &firstBit, &len, name) != 3)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <objquest (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (name[0] == '$')
				{
					switch (name[1])
					{
						case 'o':
							if (obj)
							{
								item = obj;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'c':
							if (mp_obj)
							{
								item = mp_obj;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <objquest (%s)>", arg);
							pop_call();
							return -1;
					}
				}
				else
				{
					item = NULL;
				}
				if ((item == NULL) && (item = get_obj_carry_even_blinded(mob,name)) == NULL)
				{
					pop_call();
					return FALSE;
				}
				lhsvl = get_quest_bits( item->obj_quest, firstBit, len);
				rhsvl = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "objtype"))
			{
				if (ifchk_obj)
				{
					lhsvl  = ifchk_obj->item_type;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "objval0"))
			{
				switch ( arg[1] )  /* arg should be "$*" so just get the letter */
				{
					case 'o':
						if ( obj )
						{
							lhsvl = obj->value[0];
							rhsvl = atol( val );
							retval = mprog_veval( lhsvl, opr, rhsvl );
							pop_call();
							return retval;
						}
						else
						{
							pop_call();
							return -1;
						}
					case 'c':
						if ( mp_obj )
						{
							lhsvl = mp_obj->value[0];
							rhsvl = atol( val );
							retval = mprog_veval( lhsvl, opr, rhsvl );
							pop_call();
							return retval;
						}
						else
						{
							pop_call();
							return -1;
						}
					default:
						log_build_printf(mob->pIndexData->vnum, "Bad argument to 'objval0'");
						pop_call();
						return -1;
				}
			}

			if (strstr(buf, "objval"))
			{
				cnt = buf[6] - '0';

				if (cnt >= 0 && cnt <= 7)
				{
					if (ifchk_obj)
					{
						lhsvl  = ifchk_obj->value[cnt];
						rhsvl  = atol(val);
						retval = mprog_veval(lhsvl, opr, rhsvl);
					}
				}
				pop_call();
				return retval;
			}

			if (strstr(buf, "ownsmark"))
			{
				if (ifchk_char && !IS_NPC(ifchk_char))
				{
					rhsvl = ifchk_char->pcdata->pvnum;
					if (mp_obj)
					{
						lhsvl  = mp_obj->owned_by;
					}
					else if (ifchk_obj)
					{
						lhsvl  = ifchk_obj->owned_by;
					}
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			break;

		case 'p':
			if (!strcmp(buf, "pcsinarea"))
			{
				lhsvl = atol(mprog_cmd_translate(arg, mob, actor, obj, vo, rndm));

				if (get_room_index(lhsvl) == NULL)
				{
					lhsvl = mob->pIndexData->area->nplayer;
				}
				else
				{
					lhsvl = room_index[lhsvl]->area->nplayer;
				}
				rhsvl = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "pcsinroom"))
			{
				lhsvl = atol(mprog_cmd_translate(arg, mob, actor, obj, vo, rndm));

				if (get_room_index(lhsvl) == NULL)
				{
					lhsvl = mob->in_room->nplayer;
				}
				else
				{
					lhsvl = room_index[lhsvl]->nplayer;
				}
				rhsvl  = atol(val);
				retval = mprog_veval(lhsvl, opr, rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "perception_check"))
			{
				if (ifchk_char)
				{
					lhsvl = perception_roll(ifchk_char, 0);
					
					if (is_number(val))
					{
						rhsvl = perception_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if perception_check: value must be a number (DC).");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "perm_str"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->perm_str;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "perm_int"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->perm_int;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "perm_wis"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->perm_wis;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "perm_dex"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->perm_dex;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "perm_con"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->perm_con;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "perm_cha"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->perm_cha;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "pick_lock_check"))
			{
				if (ifchk_char)
				{
					lhsvl = pick_lock_roll(ifchk_char);
					
					if (!learned(ifchk_char, gsn_pick_lock))
					{
						pop_call();
						return FALSE;
					}
					if (is_number(val))
					{
						rhsvl = pick_lock_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if pick_lock_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "position"))
			{
				if (ifchk_char)
				{
					lhsvl  = ifchk_char->position;
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'q':

			if (!strcmp(buf, "quest"))
			{
				int firstBit,len;
				CHAR_DATA *victim;
				char name[MAX_INPUT_LENGTH];

				if (sscanf(arg, "%d, %d, %s", &firstBit, &len, name) != 3)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <quest (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (name[0] == '$')
				{
					switch (name[1])
					{
						case 'i':
							victim = mob;
							break;
						case 'n':
							if (actor)
							{
								victim = actor;
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "null target in ifcheck %s", arg);
								pop_call();
								return -1;
							}
							break;
						case 't':
							if (mp_char)
							{
								victim = mp_char;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'r':
							if ( rndm )
							{
								victim = rndm;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <quest (%s)>", arg );
							pop_call();
							return -1;
					}
				}
				else
				{
					victim = NULL;
				}

				if ((victim == NULL) && (victim = get_char_room_even_blinded(mob,name)) == NULL)
				{
					pop_call();
					return FALSE;
				}

				if (victim == NULL)
				{
					pop_call();
					return( FALSE );
				}

				if (IS_NPC(victim))
				{
					lhsvl = get_quest_bits(victim->npcdata->mob_quest,firstBit, len);
				}
				else
				{
					lhsvl = get_quest_bits(victim->pcdata->quest[mob->pIndexData->area->low_r_vnum/100], firstBit, len);
				}
				rhsvl = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "questr"))
			{
				int firstBit,len, vnum;
				CHAR_DATA *victim;
				char name[MAX_INPUT_LENGTH];

				if (sscanf(arg, "%d, %d, %d, %s", &vnum, &firstBit, &len, name) != 4)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <questr (%s)", arg);
					pop_call();
					return FALSE;
				}

				if (name[0] == '$')
				{
					switch (name[1])
					{
						case 'i':
							victim = mob;
							break;
						case 'n':
							if (actor)
							{
								victim = actor;
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "null target in ifcheck %s", arg);
								pop_call();
								return -1;
							}
							break;
						case 't':
							if (mp_char)
							{
								victim = mp_char;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'r':
							if (rndm)
							{
								victim = rndm;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'o':
							if (obj)
							{
								victim = NULL;
								one_argument_nolower(obj->name, name);
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <questr (%s)>", arg);
								pop_call();
								return -1;
							}
							break;
						case 'c':
							if (mp_obj)
							{
								victim = NULL;
								one_argument_nolower(mp_obj->name, name);
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <questr (%s)>", arg);
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <questr (%s)>", arg);
							pop_call();
							return -1;
					}
				}
				else
				{
					victim = NULL;
				}

				if (vnum < 0 || vnum >= MAX_VNUM || room_index[vnum] == NULL)
				{
					pop_call();
					return(FALSE);
				}

				if ((victim == NULL) && (victim = get_char_room_even_blinded(mob,name)) == NULL)
				{
					pop_call();
					return FALSE;
				}

				if (victim == NULL)
				{
					pop_call();
					return( FALSE );
				}

				if (IS_NPC(victim))
				{
					lhsvl = get_quest_bits(victim->npcdata->mob_quest,firstBit, len);
				}
				else
				{
					lhsvl = get_quest_bits(victim->pcdata->quest[room_index[vnum]->area->low_r_vnum/100], firstBit, len);
				}
				rhsvl = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}
			break;

		case 'r':

			if (!strcmp(buf, "rand"))
			{
				lhsvl  = number_percent();
				retval = (lhsvl <= atol(arg));
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "race"))
			{
				if (ifchk_char)
				{
					lhsvl  = get_race(ifchk_char);
					rhsvl  = lookup_race(val1);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "reputation"))
			{
				if (ifchk_char)
				{
					lhsvl  = get_reputation(ifchk_char);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "roomsector"))
			{
				lhsvl = atol(arg);

				if (ifchk_char)
				{
					lhsvl = ifchk_char->in_room->sector_type;
				}
				else if (get_room_index(lhsvl) == NULL)
				{
					lhsvl = mob->in_room->sector_type;
				}
				else
				{
					lhsvl = room_index[lhsvl]->sector_type;
				}
				rhsvl  = atol(val);
				retval = mprog_veval(lhsvl, opr, rhsvl);
				pop_call();
				return retval;
			}
			break;

		case 's':
			if (!strcmp(buf, "search_check"))
			{
				if (ifchk_char)
				{
					lhsvl = search_roll(ifchk_char);
					
					if (is_number(val))
					{
						rhsvl = search_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if search_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "sense_motive_check"))
			{
				if (ifchk_char)
				{
					lhsvl = sense_motive_roll(ifchk_char);
					
					if (ifchk_char2)
					{
						rhsvl = sense_motive_check(ifchk_char, ifchk_char2, lhsvl, bluff_roll(ifchk_char2));
					}
					else if (is_number(val))
					{
						rhsvl = sense_motive_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if sense_motive_check: value must be a number (DC) or a $target char.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "sex"))
			{
				if (ifchk_char)
				{
					lhsvl  = URANGE(0, ifchk_char->sex, 2);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "shotfrom"))
			{
				switch(arg[1])
				{
					case 'i':
						retval = mprog_seval(dir_name[valid_exit], opr, val);
						break;
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "sleight_of_hand_check"))
			{
				if (ifchk_char)
				{
					lhsvl = sleight_of_hand_roll(ifchk_char);
					
					if (ifchk_char2)
					{
						rhsvl = sleight_of_hand_check(ifchk_char, ifchk_char2, lhsvl, 0);
					}
					else if (is_number(val))
					{
						rhsvl = sleight_of_hand_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if sleight_of_hand_check: value must be a number (DC) or a $target char.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "skilllevel"))
			{
				CHAR_DATA *victim;
				char name[MAX_INPUT_LENGTH];
				char skill[MAX_INPUT_LENGTH];
				int sn;
				char *argument = (char *) arg;

				argument = grab_token(argument, skill, ',');
				argument = one_argument(argument, name);
				
				if (skill[0] == '\0' || name[0] == '\0')
				{
					log_build_printf(mob->pIndexData->vnum, "if skilllevel: <missing token (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if ((sn = skill_lookup(skill)) == -1)
				{
					log_build_printf(mob->pIndexData->vnum, "if skilllevel: <bad skill (%s)>", skill );
					pop_call();
					return FALSE;
				}
				
				if (name[0] == '$')
				{
					switch (name[1])
					{
						case 'i':
							victim = mob;
							break;
						case 'n':
							if (actor)
							{
								victim = actor;
							}
							else
							{
								log_build_printf(mob->pIndexData->vnum, "if skilllevel: <NULL target (%s)>", name);
								pop_call();
								return -1;
							}
							break;
						case 't':
							if (mp_char)
							{
								victim = mp_char;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						case 'r':
							if ( rndm )
							{
								victim = rndm;
							}
							else
							{
								pop_call();
								return -1;
							}
							break;
						default:
							log_build_printf(mob->pIndexData->vnum, "if skilllevel: <bad name (%s)>", name );
							pop_call();
							return -1;
					}
				}
				else
				{
					victim = NULL;
				}

				if ((victim == NULL) && (victim = get_char_room_even_blinded(mob,name)) == NULL)
				{
					pop_call();
					return FALSE;
				}

				if (victim == NULL)
				{
					pop_call();
					return( FALSE );
				}

				lhsvl = learned(victim, sn);
				if (ifchk_char2)
					rhsvl = learned(ifchk_char2, sn);
				else
					rhsvl = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "sneak_check"))
			{
				if (ifchk_char)
				{
					lhsvl = sneak_roll(ifchk_char);
					
					if (ifchk_char2)
					{
						rhsvl = sneak_check(ifchk_char, ifchk_char2, lhsvl, 0);
					}
					else if (is_number(val))
					{
						rhsvl = sneak_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if sneak_check: value must be a number (DC) or a $target char.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "spellcraft_check"))
			{
				if (ifchk_char)
				{
					lhsvl = spellcraft_roll(ifchk_char);
					
					if (is_number(val))
					{
						rhsvl = spellcraft_check(ifchk_char, NULL, -1, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if spellcraft_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "str_check"))
			{
				if (ifchk_char)
				{
					if (ifchk_char2)
					{
						lhsvl  = str_roll(ifchk_char);
						rhsvl  = str_roll(ifchk_char2);
					}
					else if (is_number(val))
					{
						lhsvl  = str_roll(ifchk_char);
						rhsvl  = atol(val);
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if str_check: value must be a number (DC) or an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "streetwise_check"))
			{
				if (ifchk_char)
				{
					lhsvl = streetwise_roll(ifchk_char);
					if (is_number(val))
					{
						rhsvl = streetwise_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if streetwise_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1,opr,rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "survival_check"))
			{
				if (ifchk_char)
				{
					lhsvl = survival_roll(ifchk_char);
					
					if (is_number(val))
					{
						rhsvl = survival_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if survival_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "swim_check"))
			{
				if (ifchk_char)
				{
					if (is_number(val))
					{
						rhsvl = swim_check(ifchk_char, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if swim_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 't':

			if (!strcmp(buf, "time"))
			{
				lhsvl  = mud->time_info->hour;
				rhsvl  = atol(val);
				retval = mprog_veval(lhsvl,opr,rhsvl);
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "tumble_check"))
			{
				if (ifchk_char)
				{
					lhsvl = tumble_roll(ifchk_char);
					
					if (is_number(val))
					{
						rhsvl = tumble_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if tumble_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'u':
			if (!strcmp(buf, "use_magic_check"))
			{
				if (ifchk_char)
				{
					lhsvl = use_magic_roll(ifchk_char);
					
					if (is_number(val))
					{
						rhsvl = use_magic_check(ifchk_char, NULL, lhsvl, atol(val));
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if use_magic_check: value must be a number (DC)");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;

		case 'v':
			if (!strcmp( buf, "validexit"))
			{
				sh_int door;

				if (mob->in_room == NULL)
				{
					pop_call();
					return FALSE;
				}

				pfind_mob = mob;

				if (arg[0] == '\0')
				{
					for (lhsvl = cnt = door = 0 ; door < 6 ; door++)
					{
						if (get_exit(mob->in_room->vnum, door) && valid_mp_exit(mob->in_room->exit[door]))
						{
							if (number_range(0, cnt) == 0)
							{
								valid_exit = door;
								lhsvl      = mob->in_room->exit[door]->to_room;
							}
							cnt++;
						}
					}
					pop_call();
					return cnt;
				}
				door = direction_door(arg);

				if (door < 0 || door > 5)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: <validexit (%s)>", arg);
					pop_call();
					return FALSE;
				}

				if (mob->in_room->exit[door] && valid_mp_exit(mob->in_room->exit[door]))
				{
					valid_exit = door;
					lhsvl      = mob->in_room->exit[door]->to_room;
					pop_call();
					return TRUE;
				}
				pop_call();
				return FALSE;
			}
			break;

		case 'w':

			if (!strcmp(buf, "wearsobjnum"))
			{
				if (ifchk_char)
				{
					rhsvl  = ((mp_obj = get_obj_wear_vnum(ifchk_char, atol(val))) != NULL);
					retval = mprog_veval(1, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "weapontypewield" ) )
			{
				if (ifchk_char)
				{
					if ((mp_obj = get_wield(ifchk_char, FALSE)) != NULL)
					{
						lhsvl = mp_obj->value[0];
						rhsvl  = atol(val);
						retval = mprog_veval(lhsvl, opr, rhsvl);
						if (retval)
						{
							pop_call();
							return TRUE;
						}
					}
					if ((mp_obj = get_wield(ifchk_char, TRUE)) != NULL)
					{
						lhsvl = mp_obj->value[0];
						rhsvl  = atol(val);
						retval = mprog_veval(lhsvl, opr, rhsvl);
						if (retval)
						{
							pop_call();
							return TRUE;
						}
					}
				}
				pop_call();
				return FALSE;
			}

			if (!strcmp(buf, "whichgod"))
			{
				if (ifchk_char)
				{
					lhsvl  = which_god(ifchk_char);
					rhsvl  = atol(val);
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}

			if (!strcmp(buf, "wis_check"))
			{
				if (ifchk_char)
				{
					if (ifchk_char2)
					{
						lhsvl  = wis_roll(ifchk_char);
						rhsvl  = wis_roll(ifchk_char2);
					}
					else if (is_number(val))
					{
						lhsvl  = wis_roll(ifchk_char);
						rhsvl  = atol(val);
					}
					else
					{
						log_build_printf(mob->pIndexData->vnum, "if wis_check: value must be a number (DC) or an opposing $target.");
						pop_call();
						return FALSE;
					}
					retval = mprog_veval(lhsvl, opr, rhsvl);
				}
				pop_call();
				return retval;
			}
			break;
	}
	log_build_printf(mob->pIndexData->vnum, "Unknown ifcheck <%s>", buf);

	pop_call();
	return FALSE;
}


/*
	This routine handles the variables for command expansion.
	If you want to add any go right ahead, it should be fairly
	clear how it is done and they are quite easy to do, so you
	can be as creative as you want. The only catch is to check
	that your variables exist before you use them.
*/

char arg_save[MAX_INPUT_LENGTH];

void mprog_translate( char ch, char *t, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, CHAR_DATA *rndm )
{
	static char *he_she		[] = { "it",  "he",  "she" };
	static char *him_her	[] = { "it",  "him", "her" };
	static char *his_her	[] = { "its", "his", "her" };

	push_call("mprog_translate(%p,%p,%p,%p,%p,%p,%p)",ch,t,mob,actor,obj,vo,rndm);

	*t = '\0';

	switch ( ch )
	{
		case 'a':
			sprintf(t, "%d", mob->pIndexData->area->low_r_vnum);
			break;

		case 'A':
			strcpy(t, mob->pIndexData->area->name);
			break;

		case 'd':
			sprintf(t, "%d", valid_exit);
			break;
		case 'D':
			if (valid_exit < 0 || valid_exit > 5)
			{
				log_build_printf(mob->pIndexData->vnum, "bad exit direction in mprog");
			}
			else
			{
				strcpy(t, dir_name[valid_exit]);
			}
			break;

		case 'i':
			one_argument_nolower(mob->name, t);
			break;
		case 'I':
			strcpy( t, mob->short_descr );
			break;

		case 'n':
			if (!actor || !actor->name)
			{
				log_build_printf(mob->pIndexData->vnum, "null target in mprog");
				if (!rndm || !rndm->name)
				{
					break;
				}
				else
				{
					actor = rndm;
				}
			}
			one_argument_nolower(actor->name, t);
			break;

		/* The only case $N should be in is a case where we want PERS
		   to trigger in act anyway, this should work - Kregor */
		case 'N':
			if (!actor)
			{
				log_build_printf(mob->pIndexData->vnum, "null $N target in mprog");
				if (!rndm)
				{
					break;
				}
				else
				{
					actor = rndm;
				}
			}
			strcpy(t, "$N");
			break;

// 		case 'N':
// 			if (!actor)
// 			{
// 				if (!rndm)
// 				{
// 					break;
// 				}
// 				else
// 				{
// 					actor = rndm;
// 				}
// 			}
// 			strcpy(t, get_name(actor));
// 			break;
// 
		case 't':
			if (mp_char)
			{
				one_argument_nolower(mp_char->name, t);
			}
			break;
			/* again, this should work because the only time its used is an echo - Kregor */
		case 'T':
			if (mp_char)
			{
				strcpy(t, "$N");
			}
			break;

		case 'r':
			if (rndm && rndm->name)
			{
				one_argument_nolower(rndm->name, t );
			}
			break;
		case 'R':
			if (rndm)
			{
//				strcpy( t, get_name(rndm));
				strcpy(t, "$N");
			}
			break;

		case 'e':
			if (actor)
			{
				strcpy( t, he_she[ URANGE(0, actor->sex, 2) ] );
			}
			break;
		case 'm':
			if (actor)
			{
				strcpy( t, him_her[ URANGE(0, actor->sex, 2) ] );
			}
			break;
		case 's':
			if (actor)
			{
				strcpy( t, his_her[ URANGE(0, actor->sex, 2) ] );
			}
			break;

 		case 'E':
			if (mp_char)
			{
				strcpy( t, he_she[ URANGE(0, mp_char->sex, 2) ] );
			}
			break;
		case 'M':
			if (mp_char)
			{
				strcpy( t, him_her[ URANGE(0, mp_char->sex, 2) ] );
			}
			break;
 		case 'S':
 			if (mp_char)
 			{
				strcpy( t, his_her[ URANGE(0, mp_char->sex, 2) ] );
			}
			break;

		case 'j':
			strcpy( t, he_she[ URANGE(0, mob->sex, 2) ] );
			break;
		case 'k':
			strcpy( t, him_her[ URANGE(0, mob->sex, 2) ] );
			break;
		case 'l':
			strcpy( t, his_her[ URANGE(0, mob->sex, 2) ] );
			break;

		case 'J':
			if (rndm)
			{
				strcpy( t, he_she[ URANGE(0, rndm->sex, 2) ] );
			}
			break;
		case 'K':
			if (rndm)
			{
				strcpy( t, him_her[ URANGE(0, rndm->sex, 2) ] );
			}
			break;
		case 'L':
			if (rndm)
			{
				strcpy( t, his_her[ URANGE(0, rndm->sex, 2) ] );
			}
			break;

		case 'o':
			if (supermob_obj && supermob_obj->name)
			{
				one_argument_nolower(supermob_obj->name, t);
			}
			else if (obj && obj->name)
			{
				one_argument_nolower(obj->name, t);
			}
			else
			{
				strcpy( t, "<null>" );
			}
			break;
		case 'O':
			if (supermob_obj && supermob_obj->short_descr)
			{
				strcpy( t, OBJD(supermob_obj, NULL) );
			}
			if (obj && obj->short_descr)
			{
				strcpy( t, OBJD(obj, NULL) );
			}
			else
			{
				strcpy( t, "<null>" );
			}
			break;

		case 'c':
			if (mp_obj && mp_obj->name)
			{
				one_argument_nolower(mp_obj->name, t);
			}
			else
			{
				strcpy( t, "<null>" );
			}
			break;
		case 'C':
			if (mp_obj && mp_obj->short_descr)
			{
				strcpy( t, mp_obj->short_descr );
			}
			else
			{
				strcpy( t, "<null>" );
			}
			break;

		case 'x':
			sprintf(t, "%d", lhsvl);
			break;

		case 'X':
			sprintf(t, "%s", mob->npcdata->remember);
			break;

		case '$':
			strcpy(t, "$");
			break;

		case '/':
			strcpy(t, "\n\r");
			break;

		case '0':
			strcpy(t, arg_save);
			break;

		case '1':
		case '2':
		case '3':
		case '4':
		case '5':
		case '6':
		case '7':
		case '8':
		case '9':
			{
				int cnt, n;
				char *tmp;

				tmp = arg_save;
				n   = (int) ch - (int) '0';

				for (cnt = 0 ; cnt < n ; cnt++)
				{
					tmp = one_argument_nolower(tmp, t);
				}
				one_argument_nolower(t, t);
				break;
			}
		default:
			log_build_printf(mob->pIndexData->vnum, "Bad $var");
			break;
	}
	pop_call();
	return;
}

/*
	This procedure simply copies the cmnd to a buffer while expanding
	any variables by calling the translate procedure.  The observant
	code scrutinizer will notice that this is taken from act( )
*/

char *mprog_cmd_translate( char *cmnd, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, CHAR_DATA *rndm )
{
	char tmp[ MAX_INPUT_LENGTH ];
	char *str;
	char *i;
	char *point;
	point	= mprog_cmd_translate_buf;
	str		= parse_mprog_var(cmnd, mob, actor, obj, vo, rndm);

	push_call("mprog_cmd_translate(%p,%p,%p,%p,%p,%p)",cmnd,mob,actor,obj,vo,rndm);

	while ( *str != '\0' )
	{
		if ( *str != '$' )
		{
			*point++ = *str++;
			continue;
		}
		str++;
		mprog_translate( *str, tmp, mob, actor, obj, vo, rndm );
		i = tmp;
		++str;
		while ( ( *point = *i ) != '\0' )
		{
			++point, ++i;
		}
	}
	*point = '\0';
	pop_call();
	return( mprog_cmd_translate_buf );
}

/*
	The main focus of the MOBprograms.  This routine is called
	whenever a trigger is successful.  It is responsible for parsing
	the command list and figuring out what to do. However, like all
	complex procedures, everything is farmed out to the other guys.
*/

void mprog_driver ( MPROG_DATA *mprog, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo)
{
	CHAR_DATA	*rndm = NULL;
	CHAR_DATA	*vch  = NULL;
	OBJ_DATA *true_supermob_obj;
	NPC_TOKEN *tok;
	int cnt = 0;
	lg_int mp_start, mp_end;
	bool rprog_oprog = ( mob == supermob );

	push_call_format("mprog_driver(%u)",mob->pIndexData->vnum);

	if( rprog_oprog )
	{
		supermob_room = mob->in_room;
		true_supermob_obj = supermob_obj;
	}
	else
	{
		true_supermob_obj = NULL;
		supermob_room = NULL;
	}

	mp_start = get_game_usec();

	/*
		Only execute progs containing $r with a player in the room
	*/

	if (IS_SET(mprog->flags, MPTRIGGER_RAND_PLR))
	{
		if (mob->in_room->area->nplayer > 0)
		{
			for (vch = mob->in_room->first_person ; vch ; vch = vch->next_in_room)
			{
				if (!IS_NPC(vch) && can_see(mob, vch))
				{
					if (number_range(0, cnt) == 0)
					{
						rndm = vch;
					}
					cnt++;
				}
			}
		}
		if (rndm == NULL)
		{
			pop_call();
			return;
		}
	}

	tok = mprog->first_token;

	if (++mob->npcdata->mob_prog_nest > MAX_MPROG_NEST)
	{
		--mob->npcdata->mob_prog_nest;
		log_build_printf(mob->pIndexData->vnum, "mob_prog_nest exceeded maximum");
		build_dump_stack(mob->pIndexData->vnum);
		pop_call();
		return;
	}

	while (tok)
	{
		tok = execute_mob_prog(tok, mob, actor, obj, rndm, tok->level);

		cnt = TRUE;

		while (cnt && tok)
		{
			switch (tok->type)
			{
				case MPTOKEN_ELSE:
				case MPTOKEN_ENDIF:
				case MPTOKEN_CASE:
				case MPTOKEN_DEFAULT:
				case MPTOKEN_ENDSWITCH:
					tok = tok->next;
					break;
				default:
					cnt = FALSE;
					break;
			}
		}
	}

	mob->npcdata->mob_prog_nest--;

	mp_end = get_game_usec();

	if (mp_end - mp_start > 100000)
	{
		log_build_printf(mob->pIndexData->vnum, "mprog driver: %lld usec to execute mob prog", mp_end - mp_start);
		build_dump_stack(mob->pIndexData->vnum);
	}

	if (IS_SET(mud->flags, MUD_SKIPOUTPUT))
	{
		REMOVE_BIT(mud->flags, MUD_SKIPOUTPUT);
	}
	
	if (mob->npcdata->prog_char != NULL)
	{
		STRFREE(mob->npcdata->prog_cmd);
		mob->npcdata->prog_char = NULL;
	}

	pop_call();
	return;
}

NPC_TOKEN *execute_mob_prog( NPC_TOKEN *token, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, CHAR_DATA *rndm, char level)
{
	char		if_val;
	lg_int	mp_switch_val;
	char		mp_switch_buf[MAX_INPUT_LENGTH];

	push_call("execute_mob_prog(%p,%p,%p)",token,mob,actor,obj,rndm,level);

	while (token != NULL)
	{
		if (mob == NULL || mob->name == NULL)
		{
			log_printf("NULL mob in execute_mob_prog, dumping stack:");
			dump_stack();
			pop_call(); 
			return NULL;
		}

		if (actor && !IS_NPC(actor) && IS_SET(actor->act, PLR_WIZTIME))
		{
			ch_printf_color(actor, "{078}lvl: {178}%2d {078}type: {178}%2d {078}string: {138}%s\n\r", level, token->type, token->string);
		}

		switch( token->type )
		{
			case MPTOKEN_SOCIAL:
				check_social_fast(mob, token->value, mprog_cmd_translate(token->string, mob, actor, obj, NULL, rndm));
				break;

			case MPTOKEN_COMMAND:
				(*cmd_table[token->value].do_fun) (mob, mprog_cmd_translate(token->string, mob, actor, obj, NULL, rndm));
				break;

			case MPTOKEN_IF:
			case MPTOKEN_OR:
			case MPTOKEN_IFNOT:
			case MPTOKEN_ORNOT:
				if_val = mprog_do_ifchck(token->string, mob, actor, obj, NULL, rndm);

				if (if_val == -1)
				{
					log_build_printf(mob->pIndexData->vnum, "Bad ifcheck: %s", token->string);
				}

				switch (token->type)
				{
					case MPTOKEN_IFNOT:
					case MPTOKEN_ORNOT:
						if_val = !if_val;
						break;
				}

				if (if_val)
				{
					token = token->next;
					while (token != NULL && (token->type == MPTOKEN_OR || token->type == MPTOKEN_ORNOT))
					{
						token = token->next;
					}
					if (token != NULL)
					{
						switch (token->type)
						{
							case MPTOKEN_ELSE:
							case MPTOKEN_ENDIF:
								break;
							default:
								token = execute_mob_prog(token, mob, actor, obj, rndm, level + 1);
								break;
						}
						if (token != NULL && token->type == MPTOKEN_ELSE)
						{
							token = token->next;
							while (token != NULL && token->level > level)
							{
								token = token->next;
							}
						}
					}
					break;
				}
				if (!if_val && token->next != NULL && (token->next->type != MPTOKEN_OR && token->next->type != MPTOKEN_ORNOT))
				{
					token = token->next;
					while (token != NULL && token->level > level)
					{
						token = token->next;
					}
					if (token != NULL)
					{
						if (token->type == MPTOKEN_ELSE)
						{
							token = token->next;
							if (token != NULL && token->type != MPTOKEN_ELSE && token->type != MPTOKEN_ENDIF)
							{
								token = execute_mob_prog(token, mob, actor, obj, rndm, level + 1);
							}
						}
					}
				}
				break;

			case MPTOKEN_ELSE:
			case MPTOKEN_ENDIF:
			case MPTOKEN_CASE:
			case MPTOKEN_DEFAULT:
			case MPTOKEN_ENDSWITCH:
				pop_call();
				return token;
				break;

			case MPTOKEN_BREAK:
				pop_call();
				return NULL;
				break;

			case MPTOKEN_SWITCH:
				sprintf(mp_switch_buf, "%s = #case", token->string);
				mprog_do_ifchck(mp_switch_buf, mob, actor, obj, NULL, rndm);
				mp_switch_val = lhsvl;

				token = token->next;

				while (token != NULL && token->level > level)
				{
					if (token->type == MPTOKEN_CASE)
					{
						if (mp_switch_val == mprog_case_val(mob, token->string))
						{
							token = token->next;
							while (token != NULL && token->level < level + 2)
							{
								token = token->next;
							}
							if (token != NULL)
							{
								token = execute_mob_prog(token, mob, actor, obj, rndm, token->level);
							}
							while (token != NULL && token->level > level)
							{
								token = token->next;
							}
							break;
						}
					}
					else if (token->type == MPTOKEN_DEFAULT)
					{
						token = token->next;
						while (token != NULL && token->level < level + 2)
						{
							token = token->next;
						}
						if (token != NULL)
						{
							token = execute_mob_prog(token, mob, actor, obj, rndm, level + 2);
						}
						while (token != NULL && token->level > level)
						{
							token = token->next;
						}
						break;
					}

					if (token)
					{
						token = token->next;

						while (token && token->level > level + 1)
						{
							token = token->next;
						}
					}
				}
				break;
		}
		if (token)
		{
			token = token->next;
		}
		else
		{
			break;
		}
	}
	pop_call();
	return token;
}


/*
	Global function code and brief comments.
*/

/*
	The next two routines are the basic trigger types. Either trigger
	on a certain percent, or trigger on a keyword or word phrase.
	To see how this works, look at the various trigger routines..
*/

bool mprog_wordlist_check( char *arg, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, lg_int type )
{
	MPROG_DATA	*mprg;
	bool found = FALSE;

	push_call("mprog_wordlist_check(%p,%p,%p,%p,%p,%p)",arg,mob,actor,obj,vo,type);

	for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
	{
		if (IS_SET(mprg->type, type) && mob->in_room == actor->in_room)
		{
			strcpy(arg_save, arg);

			replace_str("", "!", arg);
			replace_str("", ".", arg);
			replace_str("", "?", arg);
			replace_str("", ",", arg);
			
			if (type == INTERCEPT_PROG && actor->desc)
				SET_BIT(CH(actor->desc)->pcdata->interp, INTERP_MPROG);

			if (mprg->arglist[0] == '\0')
			{
				mprog_driver(mprg, mob, actor, obj, vo);
				found = TRUE;
			}
			else if (mprg->arglist[0] == 'p' && mprg->arglist[1] == ' ')
			{
				if (!str_infix(&mprg->arglist[2], arg))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else if (mprg->arglist[0] == 'k' && mprg->arglist[1] == ' ')
			{
				if (is_multi_name_list(arg, &mprg->arglist[2]))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else if (type == SPEECH_PROG || type == SAYTO_PROG )
			{
				if (is_name_list(arg, mprg->arglist) || !str_infix(mprg->arglist, arg))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else
			{
				if (is_name_list(arg, mprg->arglist))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			if (type == INTERCEPT_PROG && actor->desc)
				REMOVE_BIT(CH(actor->desc)->pcdata->interp, INTERP_MPROG);
			if (mob->npcdata->prog_char && found)
			{
				mob->npcdata->prog_char = NULL;
				STRFREE(mob->npcdata->prog_cmd);
			}
		}
	}
	pop_call();
	return found;
}


bool mprog_percent_check( CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, lg_int type)
{
	MPROG_DATA * mprg;
	bool check = FALSE;

	push_call("mprog_percent_check(%p,%p,%p,%p,%p)",mob,actor,obj,vo,type);

	for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
	{
		if (IS_SET(mprg->type, type) && number_percent() <= atol(mprg->arglist))
		{
			check = TRUE;
			mprog_driver(mprg, mob, actor, obj, vo);
			if (type != GREET_PROG && type != DO_GREET_PROG && type != GROUP_GREET_PROG)
			{
				break;
			}
		}
	}
	pop_call();
	return check;
}

/*
	The triggers
*/

bool mprog_time_check( CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, lg_int type)
{
	MPROG_DATA * mprg;
	bool check = FALSE;

	push_call("mprog_time_check(%p,%p,%p,%p,%p)",mob,actor,obj,vo,type);

	for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
	{
		if (mprg->type != type)
		{
			continue;
		}

		if (type == TIME_PROG)
		{
			if (atol(mprg->arglist) == 24 || mud->time_info->hour == atol(mprg->arglist))
			{
				check = TRUE;
				mprog_driver(mprg, mob, actor, obj, vo);
			}
		}
		else if (type == DAY_PROG)
		{
			if (atol(mprg->arglist) == 30 || mud->time_info->day == atol(mprg->arglist))
			{
				check = TRUE;
				mprog_driver(mprg, mob, actor, obj, vo);
			}
		}
		else if (type == MONTH_PROG)
		{
			if (atol(mprg->arglist) == 12 || mud->time_info->month == atol(mprg->arglist))
			{
				check = TRUE;
				mprog_driver(mprg, mob, actor, obj, vo);
			}
		}
	}
	pop_call();
	return check;
}


bool mprog_act_trigger( char *buf, CHAR_DATA *mob, CHAR_DATA *ch, OBJ_DATA *obj, void *vo)
{
	push_call("mprog_act_trigger(%p,%p,%p,%p,%p)",buf,mob,ch,obj,vo);

	if (IS_SET(mob->pIndexData->progtypes, ACT_PROG))
	{
		if (mprog_wordlist_check(buf, mob, ch, obj, vo, ACT_PROG))
		{
			pop_call();
			return TRUE;
		}
	}
	pop_call();
	return FALSE;
}


bool mprog_social_trigger( char *social, CHAR_DATA *mob, CHAR_DATA *ch )
{
	MPROG_DATA *mprg;

	push_call("mprog_social_trigger(%p,%p,%p)",social,mob,ch);

	if (!MP_VALID_MOB(mob) || !IS_AWAKE(mob))
	{
		pop_call();
		return TRUE;
	}

	if (IS_SET(mob->pIndexData->progtypes, SOCIAL_PROG))
	{
		for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
		{
			if (IS_SET(mprg->type, SOCIAL_PROG) && !strcasecmp(social, mprg->arglist))
			{
				mprog_driver( mprg, mob, ch, NULL, NULL );

				pop_call();
				return TRUE;
			}
		}
	}
	pop_call();
	return FALSE;
}

bool mprog_trigger_trigger( char *txt, CHAR_DATA *mob, CHAR_DATA *ch )
{
	push_call("mprog_trigger_trigger(%p,%p,%p)",txt,mob,ch);
	
	if (IS_SET(mob->pIndexData->progtypes, TRIGGER_PROG))
	{
		if (mprog_wordlist_check(txt, mob, ch, NULL, NULL, TRIGGER_PROG))
		{
			pop_call();
			return TRUE;
		}
	}
	pop_call();
	return FALSE;
}


bool mprog_hit_trigger( CHAR_DATA *mob, CHAR_DATA *actor )
{
	push_call("mprog_hit_trigger(%p,%p)",mob,actor);
	
	if (MP_VALID_MOB(mob) && IS_SET(mob->pIndexData->progtypes, HIT_PROG))
	{
		if (mprog_percent_check( mob, actor, NULL, NULL, HIT_PROG ))
		{
			pop_call();
			return TRUE;
		}
	}
	pop_call();
	return FALSE;
}


bool mprog_bribe_trigger( CHAR_DATA *mob, CHAR_DATA *actor, int amount )
{
	MPROG_DATA *mprg;
	bool check = FALSE;

	push_call("mprog_bribe_trigger(%p,%p,%p)",mob,actor,amount);

	if (!MP_VALID_MOB(mob) || IS_NPC(actor) || !IS_NPC(mob) || mob->position <= POS_SLEEPING)
	{
		pop_call();
		return FALSE;
	}

	if (IS_SET(mob->pIndexData->progtypes, BRIBE_PROG))
	{
		for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
		{
			if (IS_SET(mprg->type, BRIBE_PROG) && amount >= atol(mprg->arglist))
			{
				mprog_driver( mprg, mob, actor, NULL, NULL );
				check = TRUE;
				break;
			}
		}
	}
	if (!check && !IS_PET(mob, actor))
	{
		if (!IS_ACT(mob, ACT_SCAVENGER))
		{
			act( "$N seems a bit puzzled by your generosity, and hands back the coins.", actor, NULL, mob, TO_CHAR);
			act( "$N seems a bit puzzled by $n's generosity, and hands back the coins.", actor, NULL, mob, TO_ROOM);
			gold_transaction(actor, amount);
		}
		else
		{
			act( "$N seems quite pleased by your generosity.", actor, NULL, mob, TO_CHAR);
			act( "$N seems quite pleased by $n's generosity.", actor, NULL, mob, TO_ROOM);
		}
	}
	pop_call();
	return check;
}

bool mprog_death_trigger( CHAR_DATA *killer, CHAR_DATA *mob )
{
	bool check = FALSE;

	push_call("mprog_death_trigger(%p)",mob);

	if (!MP_VALID_MOB(mob))
	{
		pop_call();
		return FALSE;
	}

	if (killer != NULL && killer != mob)
	{
		if (IS_SET(mob->pIndexData->progtypes, DEATH_PROG))
		{
			mob->position = POS_STANDING;
			SET_BIT(mob->act, ACT_WILL_DIE); /* avoids death prog triggering twice - Scandum */

			if (mprog_percent_check( mob, killer, NULL, NULL, DEATH_PROG ))
				check = TRUE;

			mob->position = POS_DEAD;
			REMOVE_BIT(mob->act, ACT_WILL_DIE);
		}
	}
	death_cry( mob );
	pop_call();
	return check;
}

bool mprog_kill_trigger( CHAR_DATA *mob, CHAR_DATA *victim )
{
	push_call("mprog_kill_trigger(%p,%p)",mob,victim);

	if (!MP_VALID_MOB(mob) || victim == NULL || victim == mob)
	{
		pop_call();
		return FALSE;
	}

	if (!IS_NPC(victim) && IS_SET(mob->pIndexData->progtypes, KILL_PROG))
	{
		if (mprog_percent_check( mob, victim, NULL, NULL, KILL_PROG ))
		{
			pop_call();
			return FALSE;
		}
	}
	pop_call();
	return TRUE;
}

bool mprog_entry_trigger( CHAR_DATA *mob )
{
	push_call("mprog_entry_trigger(%p)",mob);

	if (MP_VALID_MOB(mob) && IS_SET(mob->pIndexData->progtypes, ENTRY_PROG))
	{
		if (mprog_percent_check( mob, NULL, NULL, NULL, ENTRY_PROG ))
		{
			pop_call();
			return TRUE;
		}
	}
	pop_call();
	return FALSE;
}

bool mprog_arrival_trigger( CHAR_DATA *mob )
{
	MPROG_DATA * mprg;
	bool check = FALSE;

	push_call("mprog_arrival_trigger(%p)",mob);

	if (mob->in_room)
	{
		if (MP_VALID_MOB(mob) && IS_SET(mob->pIndexData->progtypes, ARRIVAL_PROG) && mob->walkto == mob->in_room->vnum)
		{
			for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
			{
				if (!IS_SET(mprg->type, ARRIVAL_PROG))
				{
					continue;
				}
				if (mob->in_room->vnum == atol(mprg->arglist))
				{
					mprog_driver(mprg, mob, NULL, NULL, NULL);
					check = TRUE;
				}
			}
		}
	}

	pop_call();
	return check;
}

bool mprog_buy_trigger( CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj )
{
	MPROG_DATA * mprg;
	bool check = FALSE;

	push_call("mprog_buy_trigger(%p)",mob);

	if (actor == NULL || obj == NULL)
	{
		pop_call();
		return FALSE;
	}
	if (MP_VALID_MOB(mob) && IS_SET(mob->pIndexData->progtypes, BUY_PROG))
	{
		for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
		{
			if (!IS_SET(mprg->type, BUY_PROG))
			{
				continue;
			}
			if (obj->pIndexData->vnum == atol(mprg->arglist))
			{
				mprog_driver(mprg, mob, actor, obj, NULL);
				check = TRUE;
			}
		}
	}
	pop_call();
	return check;
}

bool mprog_fight_trigger( CHAR_DATA *mob, CHAR_DATA *ch )
{
	push_call("mprog_fight_trigger(%p,%p)",mob,ch);

	if (MP_VALID_MOB(mob) && IS_SET(mob->pIndexData->progtypes, FIGHT_PROG))
	{
		if (mprog_percent_check( mob, ch, NULL, NULL, FIGHT_PROG ))
		pop_call();
		return TRUE;
	}
	pop_call();
	return FALSE;
}

bool mprog_trap_trigger( CHAR_DATA *mob, CHAR_DATA *ch )
{
	push_call("mprog_fight_trigger(%p,%p)",mob,ch);

	if (MP_VALID_MOB(mob) && IS_SET(mob->pIndexData->progtypes, TRAP_PROG))
	{
		if (mprog_percent_check( mob, ch, NULL, NULL, TRAP_PROG ))
		pop_call();
		return TRUE;
	}
	pop_call();
	return FALSE;
}

bool mprog_give_trigger( CHAR_DATA *mob, CHAR_DATA *ch, OBJ_DATA *obj )
{
	MPROG_DATA	*mprg;
	bool check = FALSE;

	push_call("mprog_give_trigger(%p,%p,%p)",mob,ch,obj);

	if (!MP_VALID_MOB(mob) || mob->position <= POS_SLEEPING)
	{
		pop_call();
		return FALSE;
	}

	if (IS_SET(mob->pIndexData->progtypes, GIVE_PROG))
	{
		for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
		{
			if (IS_SET(mprg->type, GIVE_PROG) && is_name(mprg->arglist, obj->name))
			{
				mprog_driver( mprg, mob, ch, obj, NULL );
				check = TRUE;
				break;
			}
		}
	}
	if (!check && !IS_PET(mob, ch))
	{
		if (!IS_ACT(mob, ACT_SCAVENGER))
		{
			act( "$N seems a bit puzzled by your gesture, and hands back $p.", ch, obj, mob, TO_CHAR);
			act( "$N seems a bit puzzled by $n's gesture, and hands back $p.", ch, obj, mob, TO_ROOM);
			obj_from_char(obj);
			obj_to_char(obj, ch);
		}
		else
		{
			act( "$N seems quite pleased by your generosity.", ch, NULL, mob, TO_CHAR);
			act( "$N seems quite pleased by $n's generosity.", ch, NULL, mob, TO_ROOM);
		}
	}
	pop_call();
	return check;
}

bool mprog_do_greet_trigger( CHAR_DATA *ch, CHAR_DATA *mob )
{
	push_call("mprog_do_greet_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		if (!MP_VALID_MOB(mob) || ch == mob || in_combat(mob) || !IS_AWAKE(mob) || mob->in_room != ch->in_room)
		{
			pop_call();
			return FALSE;
		}
		else if (can_see(mob, ch))
		{
			if (IS_SET(mob->pIndexData->progtypes, DO_GREET_PROG))
			{
				if (mprog_percent_check(mob, ch, NULL, NULL, DO_GREET_PROG))
				{
					pop_call();
					return TRUE;
				}
			}
			if (mob->pIndexData->pShop)
			{
				act("You greet $N.", ch, NULL, mob, TO_CHAR);
				act("$n greets $N, who shows $m $S wares.", ch, NULL, mob, TO_ROOM);
				do_list(ch, "");
				pop_call();
				return FALSE;
			}
		}
		else
		{
			act("$M cannot see you to greet you.", ch, NULL, mob, TO_CHAR);
			pop_call();
			return FALSE;
		}
	}
	act("You greet $N, who pays you no mind.", ch, NULL, mob, TO_CHAR);
	act("$n greets $N, who pays $m no mind.", ch, NULL, mob, TO_ROOM);
	pop_call();
	return FALSE;
}

/*
 * Added check_aggro routine after prog checks,
 * thus mob aggro only triggers if progs do not
 * check applies to all aggro in room, so mobs
 * don't spoil other mobs dialogs - Kregor
 */
bool mprog_greet_trigger( CHAR_DATA *ch )
{
	CHAR_DATA *vmob;
	bool check = FALSE;

	push_call("mprog_greet_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		for (vmob = ch->in_room->first_person ; vmob ; vmob = vmob->next_in_room)
		{
			if (!MP_VALID_MOB(vmob) || ch == vmob || in_combat(vmob) || !IS_AWAKE(vmob) || vmob->in_room != ch->in_room)
			{
				continue;
			}
			if (can_see(vmob, ch) && IS_SET(vmob->pIndexData->progtypes, GREET_PROG))
			{
				if (mprog_percent_check(vmob, ch, NULL, NULL, GREET_PROG))
					check = TRUE;
			}
			else if (can_see(vmob, ch) && IS_SET(vmob->pIndexData->progtypes, GROUP_GREET_PROG))
			{
				if (mud->mp_group_greeted == NULL)
				{
					mud->mp_group_greeter = vmob;
					mud->mp_group_greeted = ch;
					check = TRUE;
				}
				else if (is_same_group(ch, mud->mp_group_greeted))
				{
					mud->mp_group_greeter = vmob;
					mud->mp_group_greeted = ch;
					check = TRUE;
				}
			}
		}
	}
	if (!check)
	{
		check = check_aggro(ch);
	}
	pop_call();
	return check;
}

bool mprog_hitprcnt_trigger( CHAR_DATA *mob, CHAR_DATA *ch)
{
	MPROG_DATA *mprg;

	push_call("mprog_hitprcnt_trigger(%p,%p)",mob,ch);

	if (MP_VALID_MOB(mob) && IS_SET(mob->pIndexData->progtypes, HITPRCNT_PROG))
	{
		for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
		{
			if (IS_SET(mprg->type, HITPRCNT_PROG) && 100 * mob->hit / UMAX(1, get_max_hit(mob)) <= atol(mprg->arglist))
			{
				mprog_driver( mprg, mob, ch, NULL, NULL );
				pop_call();
				return TRUE;
			}
		}
	}
	pop_call();
	return FALSE;

}

bool mprog_repop_trigger( CHAR_DATA *mob )
{
	push_call("mprog_repop_trigger(%p)",mob);

	if (IS_SET(mob->pIndexData->progtypes, REPOP_PROG))
	{
		if (mprog_percent_check(mob, NULL, NULL, NULL, REPOP_PROG))
		{
			pop_call();
			return TRUE;
		}
	}
	pop_call();
	return FALSE;
}

bool mprog_delay_trigger(CHAR_DATA *mob, bool index)
{
	MPROG_DATA *mprg;

	push_call("mprog_delay_trigger(%p,%p)",mob,index);

	if (mob->position == POS_SLEEPING)
	{
		pop_call();
		return FALSE;
	}

	if (IS_SET(mob->pIndexData->progtypes, DELAY_PROG))
	{
		for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
		{
			if (IS_SET(mprg->type, DELAY_PROG) && index == atol(mprg->arglist))
			{
				mob->npcdata->delay_index = 0;
				mprog_driver( mprg, mob, NULL, NULL, NULL );
				pop_call();
				return TRUE;
			}
		}
	}
	pop_call();
	return FALSE;
}

bool mprog_speech_trigger( char *txt, CHAR_DATA *mob )
{
	CHAR_DATA *vmob;

	push_call("mprog_speech_trigger(%p,%p)",txt,mob);

	for (vmob = mob->in_room->first_person ; vmob ; vmob = vmob->next_in_room)
	{
		if (MP_VALID_MOB(vmob) && vmob != mob && IS_SET(vmob->pIndexData->progtypes, SPEECH_PROG) && IS_AWAKE(vmob))
		{
			if (mprog_wordlist_check( txt, vmob, mob, NULL, NULL, SPEECH_PROG ))
			{
				pop_call();
				return TRUE;
			}
		}
	}
	pop_call();
	return FALSE;
}

/*
 * prog triggers whether speech is directed to mob, or spoken indirectly,
 * but NOT if the speech is targeted to another character - Kregor
 */
bool mprog_speech_direct_trigger( char *txt, CHAR_DATA *mob, CHAR_DATA *vmob )
{
	push_call("mprog_speech_direct_trigger(%p,%p)",txt,mob);

	if (MP_VALID_MOB(vmob) && vmob != mob && IS_SET(vmob->pIndexData->progtypes, SPEECH_PROG) && IS_AWAKE(vmob))
	{
		if (mprog_wordlist_check( txt, vmob, mob, NULL, NULL, SPEECH_PROG ))
		{
			pop_call();
			return TRUE;
		}
	}
	pop_call();
	return FALSE;
}

/*
 * prog triggers only if mob is the target of sayto - Kregor
 */
bool mprog_sayto_trigger( char *txt, CHAR_DATA *mob, CHAR_DATA *vmob )
{
	push_call("mprog_sayto_trigger(%p,%p)",txt,mob);

	if (MP_VALID_MOB(vmob) && vmob != mob && IS_SET(vmob->pIndexData->progtypes, SAYTO_PROG) && IS_AWAKE(vmob))
	{
		if (mprog_wordlist_check( txt, vmob, mob, NULL, NULL, SAYTO_PROG ))
		{
			pop_call();
			return TRUE;
		}
	}
	pop_call();
	return FALSE;
}

bool mprog_desc_trigger(CHAR_DATA *mob, CHAR_DATA *ch, char *txt)
{
	MPROG_DATA *mprg;

	push_call("mprog_desc_trigger(%p,%p,%p)",mob,ch,txt);

	if (MP_VALID_MOB(mob) && IS_SET(mob->pIndexData->progtypes, DESC_PROG))
	{
		for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
		{
			if (IS_SET(mprg->type, DESC_PROG))
			{
				if (is_name(txt, mprg->arglist) || !strcmp(txt, mprg->arglist))
				{
					mprog_driver(mprg, mob, ch, NULL, NULL);

					pop_call();
					return TRUE;
				}
			}
		}
	}
	pop_call();
	return FALSE;
}

bool mprog_range_trigger( CHAR_DATA *mob, CHAR_DATA *ch, bool shot_from )
{
	MPROG_DATA *mprg;

	push_call("mprog_range_trigger(%p,%p)",mob,ch);

	valid_exit = shot_from;

	if (IS_SET(mob->pIndexData->progtypes, RANGE_PROG))
	{
		for (mprg = mob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
		{
			if (IS_SET(mprg->type, RANGE_PROG))
			{
				mprog_driver( mprg, mob, ch, NULL, NULL );
				pop_call();
				return TRUE;
			}
		}
	}
	pop_call();
	return FALSE;
}

bool mprog_exit_trigger(CHAR_DATA *ch, int door)
{
	CHAR_DATA *vmob;
	MPROG_DATA *mprg;

	push_call("mprog_exit_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		for (vmob = ch->in_room->first_person ; vmob ; vmob = vmob->next_in_room)
		{
			if (!MP_VALID_MOB(vmob) || in_combat(vmob) || !IS_AWAKE(vmob) || vmob->in_room != ch->in_room)
			{
				continue;
			}
			if (!IS_SET(vmob->pIndexData->progtypes, EXIT_PROG) || !can_see(vmob, ch))
			{
				continue;
			}
			for (mprg = vmob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
			{
				if (IS_SET(mprg->type, EXIT_PROG) && (*mprg->arglist == 0 || direction_door(mprg->arglist) == door))
				{
					mprog_driver( mprg, vmob, ch, NULL, NULL );
					pop_call();
					return TRUE;
				}
			}
		}
	}
	pop_call();
	return FALSE;
}

/*
 * Intercepts command input from ch, checks trigger,
 * caches the command in case it needs to be passed - Kregor
 */
bool mprog_intercept_trigger( char *txt, CHAR_DATA *mob, CHAR_DATA *ch, char *argument )
{
	char buf[MAX_INPUT_LENGTH];

	push_call("mprog_intercept_trigger(%p,%p,%p)",txt,mob,ch);
	
	if (!MP_VALID_MOB(mob))
	{
		pop_call();
		return FALSE;
	}
	
	if (IS_SET(mob->pIndexData->progtypes, INTERCEPT_PROG))
	{
		if (argument[0] != '\0')
			sprintf(buf, "%s %s", txt, argument);
		else
			sprintf(buf, "%s", txt);
		mob->npcdata->prog_char = ch;
		RESTRING(mob->npcdata->prog_cmd, buf);
		if (IS_PLR(ch, PLR_WIZTIME))
			ch_printf_color(ch, "{058}DEBUG: recording '%s' as your intercepted command.\n\r", buf);
	
		if (mprog_wordlist_check(txt, mob, ch, NULL, NULL, INTERCEPT_PROG))
		{
			pop_call();
			return TRUE;
		}
		//clear it out if it doesn't trigger
		mob->npcdata->prog_char = NULL;
		STRFREE(mob->npcdata->prog_cmd);
	}
	pop_call();
	return FALSE;
}

bool mprog_cast_trigger( CHAR_DATA *ch, CHAR_DATA *victim, int sn )
{
	CHAR_DATA *vmob;
	MPROG_DATA *mprg;

	push_call("mprog_cast_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		for (vmob = ch->in_room->first_person ; vmob ; vmob = vmob->next_in_room)
		{
			if (!MP_VALID_MOB(vmob) || in_combat(vmob) || !IS_AWAKE(vmob) || vmob->in_room != ch->in_room)
			{
				continue;
			}
			if (!IS_SET(vmob->pIndexData->progtypes, CAST_PROG) || !can_see(vmob, ch))
			{
				continue;
			}
			for (mprg = vmob->pIndexData->first_prog ; mprg ; mprg = mprg->next)
			{
				if (IS_SET(mprg->type, CAST_PROG) && ((*mprg->arglist == 0 && vmob == victim) || skill_lookup(mprg->arglist) == sn))
				{
					mprog_driver( mprg, vmob, ch, NULL, NULL );
					pop_call();
					return TRUE;
				}
			}
		}
	}
	pop_call();
	return FALSE;
}


/*
 * Added obj and room progs based on mud20 available mob progs
 * using supermob from SmaugFUSS 1.7... thanks SmaugFUSS and Smaug teams - Kregor
 */

void set_supermob( OBJ_DATA * obj )
{
	ROOM_INDEX_DATA *room;
	OBJ_DATA *in_obj;
	CHAR_DATA *mob;
	char buf[200];
	
	push_call("set_supermob(%p)",obj);

	if(!supermob)
	{
		if ((supermob = create_mobile(get_mob_index(3))) == NULL)
		{
			bug("set_supermob(%s): Cannot invoke SuperMob... ABORTING!", obj->name);
			dump_stack();
			exit(-1);
		}
	}

	mob = supermob;	/* debugging */

	if(!obj)
	{
		pop_call();
		return;
	}

	supermob_obj = obj;

	for(in_obj = obj ; in_obj->in_obj ; in_obj = in_obj->in_obj)
		;

	if(in_obj->carried_by)
	{
		room = in_obj->carried_by->in_room;
	}
	else
	{
		room = obj->in_room;
	}

	if(!room)
	{
		pop_call();
		return;
	}

	if(supermob->short_descr)
		STRFREE(supermob->short_descr);

	supermob->short_descr = STRALLOC(obj->short_descr);

	/*
	 * Added by Jenny to allow bug messages to show the vnum
	 * of the object, and not just supermob's vnum 
	 */
	snprintf(buf, 200, "Object #%d", obj->pIndexData->vnum);
	STRFREE(supermob->description);
	supermob->description = STRALLOC(buf);

	if(room != NULL)
	{
		char_from_room(supermob);
		char_to_room(supermob, room->vnum, FALSE);
		wiz_printf_room(supermob, "SuperMob was here! working with %s\n\r", obj->name);
	}
	pop_call();
	return;
}

void release_supermob()
{
	supermob_obj = NULL;
	char_from_room(supermob);
	char_to_room(supermob, 3, FALSE);
}

bool oprog_wordlist_check( char *arg, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, lg_int type )
{
	MPROG_DATA	*mprg;
	bool found = FALSE;

	push_call("oprog_wordlist_check(%p,%p,%p,%p,%p,%p)",arg,mob,actor,obj,vo,type);

	for (mprg = obj->pIndexData->first_prog ; mprg ; mprg = mprg->next)
	{
		if (IS_SET(mprg->type, type) && mob->in_room == actor->in_room)
		{
			strcpy(arg_save, arg);

			replace_str("", "!", arg);
			replace_str("", ".", arg);
			replace_str("", "?", arg);
			replace_str("", ",", arg);
			
			if (type == INTERCEPT_PROG && actor->desc)
				SET_BIT(CH(actor->desc)->pcdata->interp, INTERP_MPROG);

			if (mprg->arglist[0] == '\0')
			{
				mprog_driver(mprg, mob, actor, obj, vo);
				found = TRUE;
			}
			else if (mprg->arglist[0] == 'p' && mprg->arglist[1] == ' ')
			{
				if (!str_infix(&mprg->arglist[2], arg))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else if (mprg->arglist[0] == 'k' && mprg->arglist[1] == ' ')
			{
				if (is_multi_name_list(arg, &mprg->arglist[2]))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else if (type == SPEECH_PROG)
			{
				if (is_name_list(arg, mprg->arglist) || !str_infix(mprg->arglist, arg))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else
			{
				if (is_name_list(arg, mprg->arglist))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			if (type == INTERCEPT_PROG && actor->desc)
				REMOVE_BIT(CH(actor->desc)->pcdata->interp, INTERP_MPROG);
			if (mob->npcdata->prog_char && found)
			{
				mob->npcdata->prog_char = NULL;
				STRFREE(mob->npcdata->prog_cmd);
			}
		}
	}
	pop_call();
	return found;
}


bool oprog_percent_check( CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, lg_int type)
{
	MPROG_DATA * mprg;
	bool check = FALSE;

	push_call("oprog_percent_check(%p,%p,%p,%p,%p)",mob,actor,obj,vo,type);

	if (!obj)
	{
		bug("oprog_percent_check: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	for (mprg = obj->pIndexData->first_prog ; mprg ; mprg = mprg->next)
	{
		if (IS_SET(mprg->type, type) && number_percent() <= atol(mprg->arglist))
		{
			check = TRUE;
			mprog_driver(mprg, mob, actor, obj, vo);
			if (type != GREET_PROG && type != DO_GREET_PROG && type != GROUP_GREET_PROG)
			{
				break;
			}
		}
	}
	pop_call();
	return check;
}

/*
	The triggers
*/

bool oprog_time_check( CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, lg_int type)
{
	MPROG_DATA * mprg;
	bool check = FALSE;

	push_call("oprog_time_check(%p,%p,%p,%p,%p)",mob,actor,obj,vo,type);

	if (!obj)
	{
		bug("oprog_time_check: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	for (mprg = obj->pIndexData->first_prog ; mprg ; mprg = mprg->next)
	{
		if (mprg->type != type)
		{
			continue;
		}

		if (type == TIME_PROG)
		{
			if (atol(mprg->arglist) == 24 || mud->time_info->hour == atol(mprg->arglist))
			{
				set_supermob(obj);
				mprog_driver(mprg, supermob, actor, obj, vo);
				check = TRUE;
				release_supermob();
			}
		}
		else if (type == DAY_PROG)
		{
			if (atol(mprg->arglist) == 30 || mud->time_info->day == atol(mprg->arglist))
			{
				set_supermob(obj);
				mprog_driver(mprg, supermob, actor, obj, vo);
				check = TRUE;
				release_supermob();
			}
		}
		else if (type == MONTH_PROG)
		{
			if (atol(mprg->arglist) == 12 || mud->time_info->month == atol(mprg->arglist))
			{
				set_supermob(obj);
				mprog_driver(mprg, supermob, actor, obj, vo);
				check = TRUE;
				release_supermob();
			}
		}
	}
	pop_call();
	return FALSE;
}


bool oprog_act_trigger( char *buf, CHAR_DATA *mob, CHAR_DATA *ch, OBJ_DATA *obj, void *vo)
{
	OBJ_DATA *vobj;
	bool check = FALSE;

	push_call("oprog_act_trigger(%p,%p,%p,%p,%p)",buf,mob,ch,obj,vo);

	for (vobj = ch->first_carrying ; vobj ; vobj = vobj->next_content)
	{
		if (IS_SET(vobj->pIndexData->progtypes, ACT_PROG))
		{
			set_supermob(vobj);
			if (oprog_wordlist_check(buf, supermob, ch, vobj, vo, ACT_PROG))
				check = TRUE;
			release_supermob();
			break;
		}
	}
	if (!check)
	{
		for (vobj = ch->in_room->first_content ; vobj ; vobj = vobj->next_content)
		{
			if (IS_SET(vobj->pIndexData->progtypes, ACT_PROG))
			{
				set_supermob(vobj);
				if (oprog_wordlist_check(buf, supermob, ch, vobj, vo, ACT_PROG))
					check = TRUE;
				release_supermob();
				break;
			}
		}
	}
	pop_call();
	return check;
}


bool oprog_trigger_trigger( char *txt, OBJ_DATA *obj, CHAR_DATA *ch )
{
	bool check = FALSE;

	push_call("oprog_trigger_trigger(%p,%p,%p)",txt,obj,ch);
	
	if (!obj)
	{
		bug("oprog_trigger_check: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, TRIGGER_PROG))
	{
		set_supermob(obj);
		if (oprog_wordlist_check(txt, supermob, ch, obj, NULL, TRIGGER_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}


bool oprog_fight_trigger( OBJ_DATA *obj, CHAR_DATA *ch )
{
	bool check = FALSE;

	push_call("oprog_fight_trigger(%p,%p)",obj,ch);

	if (!obj)
	{
		bug("oprog_fight_check: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, FIGHT_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check( supermob, ch, obj, NULL, FIGHT_PROG ))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_greet_trigger( CHAR_DATA *ch )
{
	bool check = FALSE;
	OBJ_DATA *obj;

	push_call("oprog_greet_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		for (obj = ch->in_room->first_content ; obj ; obj = obj->next_content)
		{
			if (obj->carried_by)
			{
				continue;
			}
			if (IS_SET(obj->pIndexData->progtypes, GREET_PROG))
			{
				set_supermob(obj);
				if (oprog_percent_check(supermob, ch, obj, NULL, GREET_PROG))
					check = TRUE;
				release_supermob();
			}
			else if (IS_SET(obj->pIndexData->progtypes, GROUP_GREET_PROG))
			{
				if (mud->mp_group_greeted == NULL)
				{
					mud->mp_group_greeter = supermob;
					mud->mp_group_greet_obj = obj;
					mud->mp_group_greeted = ch;
					check = TRUE;
				}
				else if (is_same_group(ch, mud->mp_group_greeted))
				{
					mud->mp_group_greeter = supermob;
					mud->mp_group_greet_obj = obj;
					mud->mp_group_greeted = ch;
					check = TRUE;
				}
			}
		}
	}
	pop_call();
	return check;
}

bool oprog_repop_trigger( OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_repop_trigger(%p)",obj);

	if (IS_SET(obj->pIndexData->progtypes, REPOP_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, NULL, obj, NULL, REPOP_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_speech_trigger( char *txt, CHAR_DATA *ch )
{
	OBJ_DATA *obj;
	bool check = FALSE;

	push_call("oprog_speech_trigger(%p,%p)",txt,ch);

	for (obj = ch->first_carrying ; obj ; obj = obj->next_content)
	{
		if (IS_SET(obj->pIndexData->progtypes, SPEECH_PROG))
		{
			set_supermob(obj);
			if (oprog_wordlist_check( txt, supermob, ch, obj, NULL, SPEECH_PROG ))
				check = TRUE;
			release_supermob();
			break;
		}
	}
	if (!check)
	{
		for (obj = ch->in_room->first_content ; obj ; obj = obj->next_content)
		{
			if (IS_SET(obj->pIndexData->progtypes, SPEECH_PROG))
			{
				set_supermob(obj);
				if (oprog_wordlist_check( txt, supermob, ch, obj, NULL, SPEECH_PROG ))
					check = TRUE;
				release_supermob();
				break;
			}
		}
	}
	pop_call();
	return check;
}

bool oprog_examine_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_examine_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_examine_check: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, DESC_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, DESC_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_wear_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_wear_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_wear_trigger: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, WEAR_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, WEAR_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_remove_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_remove_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_remove_trigger: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, REMOVE_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, REMOVE_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_use_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_use_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_use_trigger: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (!IS_NPC(ch) && IS_SET(obj->pIndexData->progtypes, USE_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, USE_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_trap_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_use_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_use_trigger: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (!IS_NPC(ch) && IS_SET(obj->pIndexData->progtypes, TRAP_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, TRAP_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_sac_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_sac_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_sac_trigger: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, SAC_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, SAC_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_get_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_get_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_get_trigger: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, GET_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, GET_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_drop_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_drop_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_drop_trigger: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, DROP_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, DROP_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_give_trigger( CHAR_DATA *ch, OBJ_DATA *obj )
{
	bool check = FALSE;

	push_call("oprog_give_trigger(%p,%p)",ch,obj);

	if (!obj)
	{
		bug("oprog_give_trigger: no OBJ in prog", 0);
		pop_call();
		return FALSE;
	}
	if (IS_SET(obj->pIndexData->progtypes, GIVE_PROG))
	{
		set_supermob(obj);
		if (oprog_percent_check(supermob, ch, obj, NULL, GIVE_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool oprog_hit_trigger( CHAR_DATA *ch )
{
	bool check = FALSE;
	OBJ_DATA *obj;

	push_call("oprog_hit_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		for (obj = ch->in_room->first_content ; obj ; obj = obj->next_content)
		{
			if (!IS_WORN(obj))
			{
				continue;
			}
			if (IS_SET(obj->pIndexData->progtypes, HIT_PROG))
			{
				set_supermob(obj);
				if (oprog_percent_check(supermob, ch, obj, NULL, HIT_PROG))
					check = TRUE;
				release_supermob();
			}
		}
	}
	pop_call();
	return check;
}

bool oprog_damage_trigger( CHAR_DATA *ch )
{
	OBJ_DATA *obj;
	bool check = FALSE;

	push_call("oprog_damage_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		for (obj = ch->first_carrying ; obj ; obj = obj->next_content)
		{
			if (!IS_WORN(obj))
			{
				continue;
			}
			if (IS_SET(obj->pIndexData->progtypes, DAMAGE_PROG))
			{
				set_supermob(obj);
				if (oprog_percent_check(supermob, ch, obj, NULL, DAMAGE_PROG))
					check = TRUE;
				release_supermob();
			}
		}
	}
	pop_call();
	return check;
}

bool oprog_intercept_trigger( char *txt, CHAR_DATA *ch, char *argument )
{
	char buf[MAX_INPUT_LENGTH];
	OBJ_DATA *obj;

	push_call("oprog_intercept_trigger(%p,%p,%p)",txt,ch,argument);
	
	for (obj = ch->first_carrying ; obj ; obj = obj->next_content)
	{
		if (IS_SET(obj->pIndexData->progtypes, INTERCEPT_PROG))
		{
			set_supermob(obj);
			if (argument[0] != '\0')
				sprintf(buf, "%s %s", txt, argument);
			else
				sprintf(buf, "%s", txt);
			supermob->npcdata->prog_char = ch;
			RESTRING(supermob->npcdata->prog_cmd, buf);
			if (IS_PLR(ch, PLR_WIZTIME))
				ch_printf_color(ch, "{058}DEBUG: recording '%s' as your intercepted command.\n\r", buf);
	
			if (oprog_wordlist_check(txt, supermob, ch, obj, NULL, INTERCEPT_PROG))
			{
				release_supermob();
				pop_call();
				return TRUE;
			}
			release_supermob();
		}
	}

	for (obj = ch->in_room->first_content ; obj ; obj = obj->next_content)
	{
		if (IS_SET(obj->pIndexData->progtypes, INTERCEPT_PROG))
		{
			set_supermob(obj);
			if (argument[0] != '\0')
				sprintf(buf, "%s %s", txt, argument);
			else
				sprintf(buf, "%s", txt);
			supermob->npcdata->prog_char = ch;
			RESTRING(supermob->npcdata->prog_cmd, buf);
			if (IS_PLR(ch, PLR_WIZTIME))
				ch_printf_color(ch, "{058}DEBUG: recording '%s' as your intercepted command.\n\r", buf);
	
			if (oprog_wordlist_check(txt, supermob, ch, obj, NULL, INTERCEPT_PROG))
			{
				release_supermob();
				pop_call();
				return TRUE;
			}
			release_supermob();
		}
	}
	pop_call();
	return FALSE;
}

bool oprog_cast_trigger( CHAR_DATA *ch, OBJ_DATA *obj, int sn )
{
	MPROG_DATA *mprg;
	OBJ_DATA *vobj;
	bool check = FALSE;

	push_call("mprog_cast_trigger(%p)",ch);

	for (vobj = ch->first_carrying ; vobj ; vobj = vobj->next_content)
	{
		if (IS_SET(vobj->pIndexData->progtypes, CAST_PROG) && ((*mprg->arglist == 0 && vobj == obj) || skill_lookup(mprg->arglist) == sn))
		{
			set_supermob(vobj);
			mprog_driver( mprg, supermob, ch, vobj, NULL );
			check = TRUE;
			release_supermob();
			break;
		}
	}
	if (!check)
	{
		for (vobj = ch->in_room->first_content ; vobj ; vobj = vobj->next_content)
		{
			if (IS_SET(vobj->pIndexData->progtypes, CAST_PROG) && ((*mprg->arglist == 0 && vobj == obj) || skill_lookup(mprg->arglist) == sn))
			{
				set_supermob(vobj);
				mprog_driver( mprg, supermob, ch, vobj, NULL );
				check = TRUE;
				release_supermob();
				break;
			}
		}
	}
	pop_call();
	return check;
}

/*
 *  room_prog support starts here
 *
 */

void rset_supermob( ROOM_INDEX_DATA * room )
{
	char buf[200];
	
	push_call("rset_supermob(%p)",room);

	if(room != NULL)
	{
		STRFREE( supermob->short_descr );
		supermob->short_descr = STRALLOC( room->name );
		STRFREE( supermob->name );
		supermob->name = STRALLOC( get_dynamic_room_title(room) );

		/*
		 * Added by Jenny to allow bug messages to show the vnum
		 * of the room, and not just supermob's vnum 
		 */
		snprintf( buf, 200, "Room #%d", room->vnum );
		STRFREE( supermob->description );
		supermob->description = STRALLOC( buf );

		char_from_room( supermob );
		char_to_room( supermob, room->vnum, TRUE );
	}
	pop_call();
	return;
}


bool rprog_wordlist_check( char *arg, CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, lg_int type )
{
	MPROG_DATA	*mprg;
	bool found = FALSE;

	push_call("rprog_wordlist_check(%p,%p,%p,%p,%p,%p)",arg,mob,actor,obj,vo,type);

	if (mob->in_room == NULL)
	{
		pop_call();
		return FALSE;
	}

	for (mprg = mob->in_room->first_prog ; mprg ; mprg = mprg->next)
	{
		if (IS_SET(mprg->type, type) && mob->in_room == actor->in_room)
		{
			strcpy(arg_save, arg);

			replace_str("", "!", arg);
			replace_str("", ".", arg);
			replace_str("", "?", arg);
			replace_str("", ",", arg);
			
			if (type == INTERCEPT_PROG && actor->desc)
				SET_BIT(CH(actor->desc)->pcdata->interp, INTERP_MPROG);

			if (mprg->arglist[0] == '\0')
			{
				mprog_driver(mprg, mob, actor, obj, vo);
				found = TRUE;
			}
			else if (mprg->arglist[0] == 'p' && mprg->arglist[1] == ' ')
			{
				if (!str_infix(&mprg->arglist[2], arg))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else if (mprg->arglist[0] == 'k' && mprg->arglist[1] == ' ')
			{
				if (is_multi_name_list(arg, &mprg->arglist[2]))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else if (type == SPEECH_PROG)
			{
				if (is_name_list(arg, mprg->arglist) || !str_infix(mprg->arglist, arg))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			else
			{
				if (is_name_list(arg, mprg->arglist))
				{
					mprog_driver(mprg, mob, actor, obj, vo);
					found = TRUE;
				}
			}
			if (type == INTERCEPT_PROG && actor->desc)
				REMOVE_BIT(CH(actor->desc)->pcdata->interp, INTERP_MPROG);
			if (mob->npcdata->prog_char && found)
			{
				mob->npcdata->prog_char = NULL;
				STRFREE(mob->npcdata->prog_cmd);
			}
		}
	}
	pop_call();
	return found;
}


bool rprog_percent_check( CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *obj, void *vo, lg_int type)
{
	MPROG_DATA * mprg;
	bool check = FALSE;

	push_call("rprog_percent_check(%p,%p,%p,%p,%p)",mob,actor,obj,vo,type);

	if (mob->in_room == NULL)
	{
		pop_call();
		return FALSE;
	}

	for (mprg = mob->in_room->first_prog ; mprg ; mprg = mprg->next)
	{
		if (IS_SET(mprg->type, type) && number_percent() <= atol(mprg->arglist))
		{
			mprog_driver(mprg, mob, actor, obj, vo);
			check = TRUE;
			if (type != GREET_PROG && type != DO_GREET_PROG && type != GROUP_GREET_PROG)
			{
				break;
			}
		}
	}
	pop_call();
	return check;
}

/*
	The triggers
*/

bool rprog_time_check( CHAR_DATA *mob, CHAR_DATA *actor, OBJ_DATA *object, void *vo, lg_int type )
{
	ROOM_INDEX_DATA *pRoomIndex;
	MPROG_DATA * mprg;
	bool check = FALSE;

	push_call("rprog_time_check()");

	if ((pRoomIndex = actor->in_room) == NULL)
	{
		pop_call();
		return FALSE;
	}
		
	if (!IS_SET(pRoomIndex->progtypes, TIME_PROG)
	&& !IS_SET(pRoomIndex->progtypes, DAY_PROG)
	&& !IS_SET(pRoomIndex->progtypes, MONTH_PROG))
	{
		pop_call();
		return FALSE;
	}

	for (mprg = pRoomIndex->first_prog ; mprg ; mprg = mprg->next)
	{
		if (mprg->type != type)
			continue;

		if (type == TIME_PROG)
		{
			if (atol(mprg->arglist) == 24 || mud->time_info->hour == atol(mprg->arglist))
			{
				rset_supermob(pRoomIndex);
				mprog_driver(mprg, supermob, actor, NULL, NULL);
				check = TRUE;
				release_supermob();
			}
		}
		else if (type == DAY_PROG)
		{
			if (atol(mprg->arglist) == 30 || mud->time_info->day == atol(mprg->arglist))
			{
				rset_supermob(pRoomIndex);
				mprog_driver(mprg, supermob, actor, NULL, NULL);
				check = TRUE;
				release_supermob();
			}
		}
		else if (type == MONTH_PROG)
		{
			if (atol(mprg->arglist) == 12 || mud->time_info->month == atol(mprg->arglist))
			{
				rset_supermob(pRoomIndex);
				mprog_driver(mprg, supermob, actor, NULL, NULL);
				check = TRUE;
				release_supermob();
			}
		}
	}
	pop_call();
	return check;
}


bool rprog_act_trigger( char *buf, CHAR_DATA *mob, CHAR_DATA *ch, OBJ_DATA *obj, void *vo)
{
	bool check = TRUE;

	push_call("rprog_act_trigger(%p,%p,%p,%p,%p)",buf,mob,ch,obj,vo);

	if (ch->in_room == NULL)
	{
		pop_call();
		return FALSE;
	}

	if (IS_SET(ch->in_room->progtypes, ACT_PROG))
	{
		rset_supermob(ch->in_room);
		if (rprog_wordlist_check(buf, supermob, ch, obj, vo, ACT_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}


bool rprog_greet_trigger( CHAR_DATA *ch )
{
	bool check = TRUE;

	push_call("rprog_greet_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		if (IS_SET(ch->in_room->progtypes, GREET_PROG))
		{
			rset_supermob(ch->in_room);
			if (rprog_percent_check(supermob, ch, NULL, NULL, GREET_PROG))
				check = TRUE;
			release_supermob();
		}
		else if (IS_SET(ch->in_room->progtypes, GROUP_GREET_PROG))
		{
			if (mud->mp_group_greeted == NULL)
			{
				mud->mp_group_greeter = supermob;
				mud->mp_group_greeted = ch;
				check = TRUE;
			}
			else if (is_same_group(ch, mud->mp_group_greeted))
			{
				mud->mp_group_greeter = supermob;
				mud->mp_group_greeted = ch;
				check = TRUE;
			}
		}
	}
	pop_call();
	return check;
}

bool rprog_speech_trigger( char *txt, CHAR_DATA *ch )
{
	bool check = TRUE;

	push_call("rprog_speech_trigger(%p,%p)",txt,ch);

	if (ch->in_room == NULL)
	{
		pop_call();
		return FALSE;
	}

	if (IS_SET(ch->in_room->progtypes, SPEECH_PROG))
	{
		rset_supermob(ch->in_room);
		if (rprog_wordlist_check(txt, supermob, ch, NULL, NULL, SPEECH_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool rprog_examine_trigger( CHAR_DATA *ch )
{
	bool check = TRUE;

	push_call("rprog_examine_trigger(%p)",ch);

	if (ch->in_room == NULL)
	{
		pop_call();
		return FALSE;
	}

	if (IS_SET(ch->in_room->progtypes, DESC_PROG))
	{
		rset_supermob(ch->in_room);
		if (rprog_percent_check(supermob, ch, NULL, NULL, DESC_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool rprog_fight_trigger( CHAR_DATA *ch )
{
	bool check = TRUE;

	push_call("rprog_fight_trigger(%p)",ch);

	if (ch->in_room == NULL || IS_NPC(ch))
	{
		pop_call();
		return FALSE;
	}

	if (IS_SET(ch->in_room->progtypes, FIGHT_PROG))
	{
		rset_supermob(ch->in_room);
		if (rprog_percent_check(supermob, ch, NULL, NULL, FIGHT_PROG))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool rprog_death_trigger( CHAR_DATA *killer, CHAR_DATA *mob )
{
	bool check = TRUE;

	push_call("rprog_death_trigger(%p)",mob);

	if (!IS_NPC(mob) || mob->in_room == NULL)
	{
		pop_call();
		return FALSE;
	}

	if (killer != NULL && killer != mob)
	{
		if (IS_SET(mob->in_room->progtypes, DEATH_PROG))
		{
			rset_supermob(killer->in_room);
			if (rprog_percent_check( supermob, killer, NULL, NULL, DEATH_PROG ))
				check = TRUE;
			release_supermob();
		}
	}
	pop_call();
	return check;
}

bool rprog_kill_trigger( CHAR_DATA *mob, CHAR_DATA *victim )
{
	bool check = TRUE;

	push_call("rprog_kill_trigger(%p,%p)",mob,victim);

	if (!IS_NPC(mob) || mob->in_room == NULL || victim == mob)
	{
		pop_call();
		return FALSE;
	}

	if (!IS_NPC(victim) && IS_SET(mob->in_room->progtypes, KILL_PROG))
	{
		rset_supermob(victim->in_room);
		if (rprog_percent_check( supermob, victim, NULL, NULL, KILL_PROG ))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool rprog_entry_trigger( CHAR_DATA *mob )
{
	bool check = TRUE;

	push_call("rprog_entry_trigger(%p)",mob);

	if (mob->in_room == NULL)
	{
		pop_call();
		return FALSE;
	}
	if (IS_SET(mob->in_room->progtypes, ENTRY_PROG))
	{
		rset_supermob(mob->in_room);
		if (rprog_percent_check( supermob, mob, NULL, NULL, ENTRY_PROG ))
			check = TRUE;
		release_supermob();
	}
	pop_call();
	return check;
}

bool rprog_exit_trigger(CHAR_DATA *ch, int door)
{
	MPROG_DATA *mprg;

	push_call("rprog_exit_trigger(%p)",ch);

	if (!IS_NPC(ch))
	{
		if (ch->in_room == NULL || !IS_SET(ch->in_room->progtypes, EXIT_PROG))
		{
			pop_call();
			return FALSE;
		}
		
		for (mprg = ch->in_room->first_prog ; mprg ; mprg = mprg->next)
		{
			if (IS_SET(mprg->type, EXIT_PROG) && (*mprg->arglist == 0 || direction_door(mprg->arglist) == door))
			{
				rset_supermob(ch->in_room);
				mprog_driver( mprg, supermob, ch, NULL, NULL );
				release_supermob();
				pop_call();
				return TRUE;
			}
		}
	}
	pop_call();
	return FALSE;
}

bool rprog_intercept_trigger( char *txt, CHAR_DATA *ch, char *argument )
{
	char buf[MAX_INPUT_LENGTH];

	push_call("rprog_intercept_trigger(%p,%p,%p)",txt,ch,argument);
	
	if (IS_SET(ch->in_room->progtypes, INTERCEPT_PROG))
	{
		rset_supermob(ch->in_room);
		if (argument[0] != '\0')
			sprintf(buf, "%s %s", txt, argument);
		else
			sprintf(buf, "%s", txt);
		supermob->npcdata->prog_char = ch;
		RESTRING(supermob->npcdata->prog_cmd, buf);
		if (IS_PLR(ch, PLR_WIZTIME))
			ch_printf_color(ch, "{058}DEBUG: recording '%s' as your intercepted command.\n\r", buf);

		if (rprog_wordlist_check(txt, supermob, ch, NULL, NULL, INTERCEPT_PROG))
		{
			release_supermob();
			pop_call();
			return TRUE;
		}
		release_supermob();
	}
	pop_call();
	return FALSE;
}

bool rprog_cast_trigger( CHAR_DATA *ch, int sn )
{
	MPROG_DATA *mprg;

	push_call("mprog_cast_trigger(%p)",ch);

	if (!ch->in_room)
	{
		pop_call();
		return FALSE;
	}
	if (IS_SET(ch->in_room->progtypes, CAST_PROG) && (*mprg->arglist == 0 || skill_lookup(mprg->arglist) == sn))
	{
		rset_supermob(ch->in_room);
		mprog_driver( mprg, supermob, ch, NULL, NULL );
		release_supermob();
		pop_call();
		return TRUE;
	}
	pop_call();
	return FALSE;
}