/
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
inherit "/global/play_parse_com";
inherit "/global/communicate";
 
#include "player.h"
#include "term.h"
#include "process_str.h"
 
#define SHOUT_DISTANCE 1000
 
int     earmuffs, cols, rows;
static mapping colour_map;
string  term_name = "network";
mixed  *tell_history;
static string new_line = "", cur_term;
static mixed *eemessages;
 
void    create()
{
    languages = ({ "common" });
    cur_lang = "common";
    eemessages = ({ });
    play_parse_com::create();
}
 
string  query_term_name()
{
    return term_name;
}
string  query_cur_term()
{
    return cur_term;
}
int     query_earmuffs()
{
    return earmuffs;
}
 
string  read_message( string str, string type, string lang )
{
    mixed   bing;
 
    if( member_array( lang, languages ) == -1 )
        if( (bing = (mixed)LANGUAGE_HAND->query_garble_object( lang )) )
            if( LANGUAGE_HAND->query_language_magic( lang ) )
                return( string ) bing->garble_text( str, previous_object() );
 
            else
                if( (bing = (mixed)bing->garble_text( str, previous_object() )) )
                    return "You cannot read the writing " + bing +
                        (type ? " written in " + type : "") + "\n";
                else
                    return "You could have sworn there was writing there...\n";
        else
            return "You cannot read the writing " + (type ? " written in " + type : "") + "\n";
    if( LANGUAGE_HAND->query_language_magic( lang ) )
        if( (bing = (mixed)LANGUAGE_HAND->query_garble_object( lang )) )
            return( string ) bing->magical_text( str, previous_object() );
 
        else
            return "Error : Missing or invalid langauge interpreter.\n";
    if( !type )
        return str + "\n";
    return "'" + str + "' written in " + type + "\n";
}
 
string  fix_string( string ret )
{
    string *st;
    int     i;
 
    if( !cur_term )
        if( term_name != "network" )
            cur_term = term_name;
        else
            cur_term = "dumb";
    if( !colour_map )
        colour_map = (mapping)TERM_HANDLER->set_term_type( cur_term );
    if( !stringp( ret ) || ret == "" )
        return ret;
    st = explode( ret, "%^" );
    ret = "";
    for( i = 0; i < sizeof( st ); i++ )
        if( stringp( colour_map[ st[ i ] ] ) )
            ret += colour_map[ st[ i ] ];
        else
            ret += st[ i ];
    return ret + colour_map[ "RESET" ];
}
 
int     set_term_type( string str )
{
    if( !str )
    {
        notify_fail( "Syntax: " + query_verb() + " <term_type>\n" +
                     "Where term type is one of :-\n " +
                     implode( (string *)TERM_HANDLER->query_term_types(), ", " )
                     + ".\n" );
        return 0;
    }
    if( str != term_name )
    {
        if( member_array( str, ( string * )TERM_HANDLER->query_term_types() ) == -1 )
        {
            notify_fail( "No such terminal type as " + str + ".\n" );
            return 0;
        }
        if( str != "network" )
            colour_map = (mapping)TERM_HANDLER->set_term_type( str );
        else
            this_object()->player_connected();
        term_name = str;
        cur_term = 0;
        write( "Ok, terminal type set to " + str + ".\n" );
        return 1;
    }
    else
    {
        notify_fail( "Terminal type unchanged as " + str + ".\n" );
        return 0;
    }
}
 
int     set_network_terminal_type( string name )
{
    if( term_name != "network" )
        return 0;
    if( !name )
    {
        cur_term = "dumb";
        colour_map = 0;
    }
    if( colour_map = (mapping)TERM_HANDLER->set_network_term_type( name ) )
    {
        cur_term = name;
        return 1;
    }
}
 
void    event_commands()
{
    add_action( "earmuffs", "ear*muffs" );
    add_action( "inform", "inf*orm" );
    add_action( "set_our_rows", "rows" );
    add_action( "set_our_cols", "cols" );
    add_action( "set_term_type", "term" );
    add_action( "do_new_line", "new_*line" );
    add_action( "do_tell_his", "ht*ell" );
    if( this_object()->query_property( NO_LINE_PROP ) )
        new_line = "";
    else
        new_line = "\n";
}
 
int     do_tell_his( string str )
{
    int     i;
 
    if( !pointerp( tell_history ) || !sizeof( tell_history ) )
    {
        notify_fail( "You have not been told anything.\n" );
        return 0;
    }
    write( "Your tell history is:\n" );
    for( i = 0; i < sizeof( tell_history ); i++ )
    {
        if( sizeof( tell_history[ i ] ) > 2 )
            write( "** " + ctime( tell_history[ i ][ 2 ] ) + " **\n" );
        efun::tell_object( this_object(), fix_string( sprintf( "%s%-=*s\n",
                                                               tell_history[ i ][ 0 ], cols - strlen( tell_history[ i ][ 0 ] ),
                                                               tell_history[ i ][ 1 ] ) ) );
    }
    return 1;
}
 
int     earmuffs( string str )
{
    string  s1, s2, *types, *on;
 
    types = ({ "shout" });
    if( this_object()->query_creator() )
        types += ({ "creator-tell", "multiple-soul",
                    "remote-soul", "inter-creator-tell" });
    if( this_object()->query_lord() )
        types += ({ "lord-tell" });
    if( !(on = (string *)this_object()->query_property( "earmuffs" )) )
        on = ({ });
    if( !str )
    {
        if( earmuffs )
            write( "Your earmuffs are on.\n" );
        else
            write( "Your earmuffs are off.\n" );
        if( sizeof( on ) )
            printf( "Earmuffed events : %-=*s", cols - 20,
                    implode( on, ", " ) + ".\n" );
        on = types - on;
        if( on && sizeof( on ) )
            printf( "Audible events : %-=*s", cols - 18,
                    implode( on, ", " ) + ".\n" );
        return 1;
    }
    if( sscanf( str, "%s %s", s1, s2 ) == 2 )
    {
        if( member_array( s1, types ) == -1 )
        {
            notify_fail( "You cannot earmuff " + s1 + " events.\n" );
            return 0;
        }
        switch( s2 )
        {
            case "on":
                if( member_array( s1, on ) == -1 )
                    on += ({ s1 });
                write( "Your " + s1 + " events will now be earmuffed.\n" );
                break;
            case "off":
                on = on - ({ s1 });
                write( "Your " + s1 + " events will not be earmuffed.\n" );
                break;
            default:
                if( member_array( s1, on ) == -1 )
                {
                    write( "Your " + s1 + " events will be earmuffed.\n" );
                    on += ({ s1 });
                }
                else
                {
                    write( "Your " + s1 + " events will not be earmuffed.\n" );
                    on = on - ({ s1 });
                }
                break;
        }
    }
    else
        switch( str )
        {
            case "on":
                earmuffs = 1;
                write( "Ear muffs turned on.\n" );
                break;
            case "off":
                earmuffs = 0;
                write( "Ear muffs turned off.\n" );
                break;
            case "all":
                on = types;
                break;
            case "none":
                on = ({ });
                write( "Nothing will be ear muffed any more.\n" );
                break;
            default:
                if( member_array( str, types ) == -1 )
                {
                    notify_fail( "You cannot earmuff " + str + " events.\n" );
                    return 0;
                }
                if( member_array( str, on ) == -1 )
                {
                    write( "Your " + str + " events will be earmuffed.\n" );
                    on += ({ str });
                }
                else
                {
                    write( "Your " + str + " events will not be earmuffed.\n" );
                    on = on - ({ str });
                }
                break;
        }
    this_player()->add_property( "earmuffs", on );
    return 1;
}
 
int     check_earmuffs( string type )
{
    string *on;
 
    if( !earmuffs )
        return 0;
    if( !(on = (string *)this_object()->query_property( "earmuffs" )) )
        return 0;
    if( member_array( type, on ) == -1 )
        return 0;
    return 1;
}
 
int     inform( string str )
{
    string *types, *on, s1, s2;
 
    types = ({ "logon" });
    if( this_object()->query_creator() )
        types += ({ "link-death", "message", "call", "death", "guild" });
    if( this_object()->query_lord() )
        types += ({ "force", "enter", "dest", "cheat", "xp" });
 
    if( !(on = (string *)this_object()->query_property( "inform" )) )
        on = ({ });
    if( !str )
    {
        if( this_object()->query_property( "inform repressed" ) )
            write( "Your informs are currently being repressed.\n" );
        if( sizeof( on ) )
            printf( "Informed events : %-=*s", cols - 19,
                    implode( on, ", " ) + ".\n" );
        on = types - on;
        if( on && sizeof( on ) )
            printf( "Uninformed events : %-=*s", cols - 21,
                    implode( on, ", " ) + ".\n" );
        return 1;
    }
    if( sscanf( str, "%s %s", s1, s2 ) == 2 )
    {
        if( member_array( s1, types ) == -1 )
        {
            notify_fail( "You cannot be informed of " + s1 + " events.\n" );
            return 0;
        }
        switch( s2 )
        {
            case "on":
                if( member_array( s1, on ) == -1 )
                    on += ({ s1 });
                write( "You will now be informed of " + s1 + " events.\n" );
                break;
            case "off":
                on = on - ({ s1 });
                write( "You will now not be informed of " + s1 + " events.\n" );
                break;
            default:
                if( member_array( s1, on ) == -1 )
                {
                    write( "You will now not be informed of " + s1 + " events.\n" );
                    on += ({ s1 });
                }
                else
                {
                    write( "You will now not be informed of " + s1 + " events.\n" );
                    on = on - ({ s1 });
                }
                break;
        }
    }
    else
        switch( str )
        {
            case "on":
                this_object()->remove_property( "inform repressed" );
                write( "You are now being informed.\n" );
                break;
            case "off":
                this_object()->add_property( "inform repressed", 1 );
                write( "Inform is now repressed.\n" );
                break;
            case "all":
                on = types;
                break;
            case "none":
                on = ({ });
                write( "You will not be informed of anything.\n" );
                break;
        }
    this_object()->add_property( "inform", on );
    return 1;
}
 
void    set_rows( int i )
{
    rows = i;
}
int     query_rows()
{
    return rows;
}
 
int     set_our_rows( string str )
{
    int     val;
 
    if( !str )
    {
        notify_fail( "Rows currently set to " + rows + ".\nrows <number> to set.\n" );
        return 0;
    }
    if( !sscanf( str, "%d", val ) || val <= 10 )
    {
        notify_fail( "Invalid number of rows.\n" );
        return 0;
    }
    write( "Rows set to " + val + ".\n" );
    rows = val;
    return 1;
}
 
int     query_cols()
{
    return cols;
}
void    set_cols( int i )
{
    cols = i;
}
 
int     set_our_cols( string str )
{
    int     val;
 
    if( !str )
    {
        notify_fail( "Columns currently set to " + cols + ".\ncols <number> to set.\n" );
        return 0;
    }
    if( !sscanf( str, "%d", val ) || val <= 35 )
    {
        notify_fail( "Invalid column size.\n" );
        return 0;
    }
    write( "Columns set to " + val + ".\n" );
    cols = val;
    return 1;
}
 
int     do_new_line( string str )
{
    switch( str )
    {
        case 0:
            if( new_line == "" )
                new_line = "\n";
            else
                new_line = "";
            break;
        case "off":
            new_line = "";
            break;
        case "on":
            new_line = "\n";
            break;
        default:
            notify_fail( "Syntax: new_line <on|off>\n" );
            return 0;
    }
    if( new_line == "" )
    {
        this_object()->add_property( NO_LINE_PROP, 1 );
        write( "New lines after everything switched off.\n" );
    }
    else
    {
        this_object()->remove_property( NO_LINE_PROP );
        write( "New lines after everything switched on.\n" );
    }
    return 1;
}
 
void    add_message( object ob, string mess, int mangle )
{
    if( !sizeof( eemessages ) )
    {
        call_out( "print_messages", 0 );
        eemessages = ({ mess, ({ mangle, ob }) });
        return;
    }
    if( eemessages[ sizeof( eemessages ) - 2 ] == mess
            && eemessages[ sizeof( eemessages ) - 1 ] )
        eemessages[ sizeof( eemessages ) - 1 ] += ({ ob });
    else
        eemessages += ({ mess, ({ mangle, ob }) });
}
 
void    event_inform( object ob, string mess, string type )
{
    string *on, inform_col;
 
    if( !(on = (string *)this_object()->query_property( "inform" )) )
        on = ({ });
    if( this_object()->query_property( "inform repressed" )
            || (ob->query_invis() && !this_object()->query_creator())
            || ((int)ob->query_invis() == 2 && !this_object()->query_lord())
            || !sizeof( on ) )
        return;
    if( member_array( type, on ) == -1 )
        return;
    add_message( ob, "[" + sprintf( "%-=*s", cols - 2, mess ) + "]\n", 0 );
}
 
void    event_enter( object ob, string mess, object from )
{
    if( stringp( mess ) )
        add_message( ob, mess + "\n", 1 );
}
 
void    event_exit( object ob, string mess, object to )
{
    ::event_exit( ob, mess, to );
    if( mess )
        add_message( ob, mess + "\n", 1 );
}
 
void    print_messages()
{
    mixed * bing;
    string *bits;
    int     i, j;
 
    bing = eemessages;
    eemessages = ({ });
    tell_object( this_object(), new_line );
    for( i = 0; i < sizeof( bing ); i += 2 )
    {
/* Do squidging of two wide patterns. */
        while( i + 6 < sizeof( bing ) && bing[ i ] == bing[ i + 4 ]
                && bing[ i + 2 ] == bing[ i + 6 ] && bing[ i + 1 ][ 0 ] && bing[ i + 3 ][ 0 ]
                && bing[ i + 5 ][ 0 ] && bing[ i + 7 ][ 0 ] )
        {
/* Squidge...  */
            bing[ i + 1 ] += bing[ i + 5 ][ 1..10900 ];
            bing[ i + 3 ] += bing[ i + 7 ][ 1..10000 ];
            bing = delete( bing, i + 4, 4 );
        }
/* Three wide patterns. */
        while( i + 10 < sizeof( bing ) && bing[ i ] == bing[ i + 6 ]
                && bing[ i + 2 ] == bing[ i + 8 ] && bing[ i + 4 ] == bing[ i + 10 ]
                && bing[ i + 1 ][ 0 ] && bing[ i + 3 ][ 0 ] && bing[ i + 9 ][ 0 ] && bing[ i + 11 ][ 0 ]
                && bing[ i + 5 ][ 0 ] && bing[ i + 7 ][ 0 ] )
        {
/* Squidge...  */
            bing[ i + 1 ] += bing[ i + 7 ][ 1..10900 ];
            bing[ i + 3 ] += bing[ i + 9 ][ 1..10000 ];
            bing[ i + 5 ] += bing[ i + 11 ][ 1..10000 ];
            bing = delete( bing, i + 6, 6 );
        }
        if( sizeof( bing[ i + 1 ] ) > 2 )
            tell_object( this_object(), fix_string( sprintf( "%-=*s", cols,
                                                             (bing[ i + 1 ][ 0 ] ? replace( bing[ i ], ({ "$s", "", "%", "", "$N",
                                                                                                          query_multiple_short( bing[ i + 1 ][ 1..10000 ], 1 ) }) ) :
                                                              bing[ i ]) ) ) );
        else
            if( bing[ i + 1 ][ 0 ] && bing[ i + 1 ][ 1 ] )
            {
                bits = explode( "!" + bing[ i ] + "!", "%" );
                if( sizeof( bits ) > 1 )
                {
                    for( j = 1; j < sizeof( bits ); j += 2 )
                        bits[ j ] = pluralize( bits[ j ] );
                    bing[ i ] = implode( bits, "" );
                    bing[ i ] = bing[ i ][ 1..strlen( bing[ i ] ) - 2 ];
                }
                tell_object( this_object(), fix_string( sprintf( "%-=*s", cols,
                                                                 replace( bing[ i ], ({ "$s", "s", "$N",
                                                                                        bing[ i + 1 ][ 1 ]->short() }) ) ) ) );
            }
            else
                tell_object( this_object(), fix_string( sprintf( "%-=*s", cols, bing[ i ] ) ) );
    }
}
 
void    event_say( object caller, string str, mixed avoid )
{
    if( pointerp( avoid ) )
    {
        if( member_array( this_object(), avoid ) != -1 )
            return;
    }
    else
        if( avoid == this_object() )
            return;
    if( stringp( str ) )
        add_message( caller, (string)PROCESS_STR->do_process( str ), 0 );
} /* event_say() */
 
void    event_write( object caller, string str )
{
    if( sizeof( eemessages ) )
        print_messages();
    efun::tell_object( this_object(), fix_string( str ) );
}
 
void    do_efun_write( string str )
{
    if( sizeof( eemessages ) )
        print_messages();
    if( stringp( str ) && cols )
        efun::tell_object( this_object(),
                           fix_string( sprintf( "%-=*s", cols,
                                       (string)PROCESS_STR->do_process( str ) ) ) );
}
 
void    event_soul( object ob, string str, mixed avoid )
{
    if( ob != this_object() )
    {
        if( sizeof( avoid ) > 1 && check_earmuffs( "multiple-soul" ) )
            return;
        event_say( ob, str, avoid );
    }
    else
        do_efun_write( str );
}
 
void    event_person_say( object ob, string start, string mess, string lang )
{
    if( member_array( lang, languages ) == -1 )
    {
        mixed   str;
 
        if( !(str = (mixed)LANGUAGE_HAND->query_garble_object( lang )) )
            return;
        if( !(str = (mixed)str->garble_say( start, mess )) )
            return;
        start = str[ 0 ];
        mess = str[ 1 ];
    }
    else
        if( ob == this_object() )
            return;
    add_message( ob, sprintf( "%s%-=*s\n", start, cols - strlen( start ), mess ), 0 );
}
 
void    event_person_tell( object ob, string start, string mess, string lang )
{
    mixed   str;
    int     id;
 
    if( member_array( lang, languages ) == -1 )
    {
        if( !(str = (mixed)LANGUAGE_HAND->query_garble_object( lang )) )
            return;
        if( !(str = (mixed)str->garble_say( start, mess )) )
            return;
        start = str[ 0 ];
        mess = str[ 1 ];
    }
    else
        if( !pointerp( tell_history ) )
            tell_history = ({ });
    tell_history += ({ ({ start, mess, time() }) });
    if( sizeof( tell_history ) > MAX_TELL_HIS )
        tell_history = tell_history[ 1..1000 ];
    add_message( ob, sprintf( "%s%-=*s\n", start, cols - strlen( start ), mess ), 0 );
    if( (id = query_idle( this_object() )) > TELL_WARN_TIME )
    {
        str = ({ });
        if( id / (60 * 60) )
            str += ({ (id / (60 * 60)) + " hours" });
        if( (id / 60) % 60 )
            str += ({ ((id / 60) % 60) + " minutes" });
        if( id % 60 )
            str += ({ (id % 60) + " seconds" });
        write( this_object()->query_cap_name() + " has been idle for " +
               query_multiple_short( str ) + ".\n" );
    }
}
 
void    event_whisper( object ob, string start, string mess, object *obs,
                       string lang )
{
    string  people;
    mixed   str;
 
    people = "";
    if( member_array( lang, languages ) == -1 )
    {
        if( !(str = (mixed)LANGUAGE_HAND->query_garble_object( lang )) )
            return;
        if( !(str = (mixed)str->garble_whisper( start, mess )) )
            return;
        start = str[ 0 ];
        mess = str[ 1 ];
        people = ": ";
    }
    else
        people = "";
    if( member_array( this_object(), obs ) == -1 )
        add_message( ob, start + "to " + query_multiple_short( obs ) + people + "\n", 0 );
    else
        if( sizeof( obs ) == 1 )
            add_message( ob, sprintf( "%s%-=*s\n",
                                      start + "to you " + people + ": ", cols - strlen( start ) - 10,
                                      mess ), 0 );
        else
            add_message( ob, sprintf( "%s%-=*s\n",
                                      start + "to ", cols - strlen( start ) - 10,
                                      query_multiple_short( obs + ({ "you" }) ) + people +
                                      ": " + mess ), 0 );
}
 
int     abs( int i )
{
    if( i < 0 )
        return -i;
    return i;
}
 
void    event_person_shout( object ob, string start, string mess, string lang )
{
    int *   co_ord1, *co_ord2, d, dx, dy;
    string  dir;
    mixed   str;
 
    if( ob == this_object() )
        return;
    if( check_earmuffs( "shout" ) )
        return;
    if( member_array( lang, languages ) == -1 )
    {
        if( !(str = (mixed)LANGUAGE_HAND->query_garble_object( lang )) )
            return;
        if( !(str = (mixed)str->garble_say( start, mess )) )
            return;
        start = str[ 0 ];
        mess = str[ 1 ];
    }
    if( environment( ob ) && environment() )
    {
        co_ord1 = (mixed *)environment( ob )->query_co_ord();
        co_ord2 = (mixed *)environment()->query_co_ord();
        if( !co_ord1 || !co_ord2 )
            return;
 
        dx = co_ord1[ 0 ] - co_ord2[ 0 ];
        dy = co_ord1[ 1 ] - co_ord2[ 1 ];
        d = co_ord1[ 2 ] - co_ord2[ 2 ];
        d += abs( dx ) + abs( dy );
 
        if( d > SHOUT_DISTANCE * 5 / 4 )
            return;
        if( dy || dx )
        {
            if( dy > 0 )
                dir = "south";
            else
                dir = "north";
            if( 3 * abs( dx ) > abs( dy ) )
                if( dx > 0 )
                    dir = "west";
                else
                    dir = "east";
            else
                if( 3 * abs( dy ) < abs( dx ) )
                    if( dx > 0 )
                        dir += "west";
                    else
                        dir += "east";
 
            if( d > SHOUT_DISTANCE )
                str = "In the distance to the " + dir + " " + start +
                    " something you cannot make out.";
            if( d < SHOUT_DISTANCE / 4 )
                str = "Nearby to the " + dir + " " + start + ": " + mess;
            else
                if( d > SHOUT_DISTANCE / 2 )
                    str = "In the distance to the " + dir + " " + start + ": " + mess;
                else
                    str = "To the " + dir + " " + start + ": " + mess;
        }
        else
            str = start + ": " + mess;
    }
    else
        str = start + ": " + mess;
    if( strlen( str ) > 20 )
        add_message( ob,
                     sprintf( "%-s%-=*s\n", str[ 0..19 ], cols - 20, str[ 20..10000 ] ), 0 );
    else
        add_message( ob, str + "\n", 0 );
}
 
void    event_creator_tell( object ob, string start, string mess, int forced )
{
    if( ob == this_object()
            || (check_earmuffs( "creator-tell" ) && !forced) ||
            !this_object()->query_creator() )
        return;
    efun ::tell_object( this_object(), new_line + fix_string( sprintf( "%s%-=*s\n",
                                                                       start, cols - strlen( start ), mess ) ) );
}
 
void    event_lord_tell( object ob, string start, string mess, int forced )
{
    if( ob == this_object()
            || (check_earmuffs( "lord-tell" ) && !forced) ||
            !"secure/master"->query_lord( (string)this_object()->query_name() ) )
        return;
    efun ::tell_object( this_object(), new_line +
                        fix_string( sprintf( "%s%-=*s\n",
                                             start, cols - strlen( start ), mess ) ) );
}
 
void    event_inter_creator_tell( object ob, string mname, string pname,
                                  string mess, object ig, int emote )
{
    if( !this_object()->query_creator() || check_earmuffs( "inter-creator-tell" )
            || this_object() == ig )
        return;
    efun ::tell_object( this_object(), new_line +
                        fix_string( sprintf( "%s@%s%s%-=*s\n", pname, mname, ( emote ? " " : ": " ),
                                             cols - strlen( mname ) - strlen( pname ) - 3, mess ) ) );
}
 
void    event_player_echo_to( object ob, string mess )
{
    if( this_object()->query_lord() )
        efun::tell_object( this_object(), ob->query_cap_name() + " echo to's:\n" );
    efun::tell_object( this_object(), new_line + fix_string( sprintf( "%-=*s\n",
                                                                      cols, mess ) ) );
}
 
void    event_player_emote_all( object ob, string mess )
{
    if( ob == this_object() )
        return;
    if( this_object()->query_lord() )
        add_message( ob, ob->query_cap_name() + " emote all's:\n", 0 );
    add_message( ob, sprintf( "%-=*s\n", cols, mess ), 0 );
}
 
void    event_player_echo( object ob, string mess )
{
    if( ob == this_object() )
        return;
    if( this_object()->query_lord() )
        add_message( ob, ob->query_cap_name() + " echo's:\n", 0 );
    add_message( ob, sprintf( "%-=*s\n", cols, mess ), 0 );
}