/
LIB3/
LIB3/D/ADMIN/
LIB3/D/ADMIN/OBJ/
LIB3/D/ADMIN/ROOM/W/
LIB3/D/HOME/
LIB3/D/HOME/CITY/ARENA/
LIB3/D/HOME/CITY/ITEMS/
LIB3/D/HOME/CITY/POSTOFFI/
LIB3/DOC/
LIB3/GLOBAL/SPECIAL/
LIB3/GLOBAL/VIRTUAL/
LIB3/NET/
LIB3/NET/CONFIG/
LIB3/NET/DAEMON/CHARS/
LIB3/NET/GOPHER/
LIB3/NET/INHERIT/
LIB3/NET/OBJ/
LIB3/NET/SAVE/
LIB3/NET/VIRTUAL/
LIB3/OBJ/B_DAY/
LIB3/OBJ/HANDLERS/TERM_TYP/
LIB3/PLAYERS/B/
LIB3/PLAYERS/N/
LIB3/ROOM/
LIB3/SAVE/
LIB3/SAVE/BOARDS/
LIB3/SAVE/ENVIRON/
LIB3/SAVE/POST/
LIB3/STD/COMMANDS/SHADOWS/
LIB3/STD/CREATOR/
LIB3/STD/DOM/
LIB3/STD/EFFECTS/
LIB3/STD/EFFECTS/HEALING/
LIB3/STD/EFFECTS/OTHER/
LIB3/STD/EFFECTS/POISONS/
LIB3/STD/ENVIRON/
LIB3/STD/GUILDS/
LIB3/STD/LIQUIDS/
LIB3/STD/ROOM/
LIB3/STD/TRIGGER/SHADOW/
LIB3/W/
LIB3/W/BANNOR/
LIB3/W/NEWSTYLE/
#pragma save_binary
/*

   Code originaly by nimmox@igor.  Modified for discworld by Pinkfish.
   This file is also put in /players/nimmox/generic/responsive_monster.c
   See for more information on how to use it /players/nimmox/open/resp_exam.c

   If you want to use it, you don't need to read all this,
   the example will do....

   Nimmox (january 1993)
 */


mapping respond_to_with;
int     stop_responding;

int     match( string str, mixed str2 );


void    create()
{
    respond_to_with = ([ ]);
}				/* create() */


/* To toggle catch_tell, in case of sequence responding...
   See example */
void    set_stop_responding( int i )
{
    stop_responding = i;
}

int     query_stop_responding()
{
    return stop_responding;
}

void    set_respond_to_with( mapping map )
{
    respond_to_with = map;
}

mapping query_respond_to_with()
{
    return respond_to_with;
}


void    add_respond_to_with( mixed *trigger, mixed response )
{
/* Added by Newstyle, 02/12/93, because of errors */
    if( !respond_to_with )
	respond_to_with = ([ ]);
    respond_to_with[ trigger ] = response;
}				/* add_response() */


/* Check_sub_sequence checks whether the array (words) contains a subsequence
   a specified in the indices of the respond_to_with mapping */
mixed * check_sub_sequence( string *words )
{
    int     word_index;
    int     format_index;	/* what do you know....Meaningful names :-) */
    mixed * format;
    int     format_size;
    int     word_size;
    int     match_counter;
    int     cu_format_size;

    format_index = 0;
    format = m_indices( respond_to_with );
    word_size = sizeof( words );
    format_size = sizeof( format );

    while( format_index < format_size )
    {
	word_index = 0;
	match_counter = 0;
	cu_format_size = sizeof( format[ format_index ] );
	while( (word_index < word_size) && (match_counter < cu_format_size) )
	{
	    match_counter += match( words[ word_index ],
				    format[ format_index ][ match_counter ] );
	    word_index++;
	}
	if( match_counter == (cu_format_size) )
	    return respond_to_with[ format[ format_index ] ];
	format_index++;
    }
    return 0;
}				/* check_sub_sequence() */


/* match returns 1 if str matches the format.... see also the definitions in
   the example file... */
int     match( string str, mixed format )
{
    if( str == format )
	return 1;
    if( pointerp( format ) )
	return( member_array( str, format ) != -1 );
    return 0;
}				/* match() */


/* removing annoying readmarks....  Like .'s and ?'s */
string  remove_read_marks( string str )
{
    int     count;
    string  result;
    int     size;
    string  temp;

    size = strlen( str );
    count = 0;
    result = "";
    while( count < size )
    {
	temp = str[ count..count ];
	if( ((temp >= "a") && (temp <= "z")) ||
		(temp == " ") )
	    result += temp;
	else
	    result += " ";
	count++;
    }
    return result;
}				/* remove_read_marks() */


void    senddstr( string str, object per )
{
    if( environment( this_object() ) )
	if( per )
	    command( replace( str, ({ "$hname$", per->query_name(), "$hcname$",
				      per->query_cap_name() }) ) );
	else
	    command( str );
}				/* sendstr() */


/* Take care not to send to other monsters.... Infinite recursion problem... */
/* Imagine two monsters chatting with each other...... */

void    exec_response( mixed rep, object per )
{
    if( pointerp( rep ) )
	return exec_response( rep[ random( sizeof( rep ) ) ], per );
    if( stringp( rep ) )
	if( rep[ 0..0 ] == "#" )
	    call_out( rep[ 1..strlen( rep ) - 1 ], 0, per );
	else
	    call_out( "senddstr", 0, rep, per );
}				/* exec_response() */


/* respond as defined in respond_to_with mapping...See also
   the definitions in the example monster */


void    event_person_say( object per, string start, string mess, string lang )
{
    mixed * response;

/* Used to have a !interactive.  People will just have to be careful with
 * their responses, so as to not set off other monsters.
 */
    if( stop_responding || !sizeof( respond_to_with ) )
	return;
    mess = lower_case( mess );
    mess = remove_read_marks( mess );
    if( mess && strlen( mess ) )
	response = check_sub_sequence( ({ "@say" }) +explode( mess, " " ) );
    if( response )
	exec_response( response, per );
}				/* event_person_say() */



/*
   no 'at' or 'avoid' exists, whoever screwed this, should fix it!
   -Bill.

   void event_person_tell( object ob, string start, string mess, string lang )
   {
   mixed *response;
   string *bits;

   if( !interactive( per ) || stop_responding ||
   member_array( this_object(), avoid ) != -1 || !sizeof( respond_to_with ) )
   return ;
   mess = lower_case( mess );
   mess = remove_read_marks( mess );
   if( !mess )
   return ;
   if( objectp( at ) )
   response = check_sub_sequence( ({ "@tell", }) + explode( mess, " " ) );
   if( response )
   exec_response( response, per );
   }
    *//* event_person_tell() */


void    event_soul( object per, string mess, object *avoid, string verb,
		    string last, mixed at )
{
    mixed * response;
    string *bits;

    if( !interactive( per ) || stop_responding ||
	    member_array( this_object(), avoid ) != -1 ||
	    !sizeof( respond_to_with ) )
	return;
    mess = lower_case( mess );
    mess = remove_read_marks( mess );
    if( !mess )
	return;
    if( objectp( at ) )
	response = check_sub_sequence( ({ "@" + verb, "#" + last,
					  at->query_name() })+
				       explode( mess, " " ) );
    if( response )
	exec_response( response, per );
}				/* event_soul() */