/****************************************************************************
* ResortMUD Version 5.0 was mainly programmed by Ntanel, Garinan, Josh, *
* Badastaz, Digifuzz, Senir, Kratas, Scion, Shogar and Tagith. *
* ResortMud Version 5.0b programed By Badastaz and Garinan
* ------------------------------------------------------------------------ *
* Copyright (C) 1996 - 2001 Haslage Net Electronics: MudWorld of Lorain, *
* Ohio. ALL RIGHTS RESERVED See /doc/RMLicense.txt for more details. *
****************************************************************************/
/****************************************************************************
* ^ +----- | / ^ ^ | | +-\ *
* / \ | | / |\ /| | | | \ *
* / \ +--- |< | \ / | | | | | *
* /-----\ | | \ | v | | | | / *
* / \ | | \ | | +-----+ +-/ *
****************************************************************************
* AFKMud Copyright 1997-2002 Alsherok. Contributors: Samson, Dwip, Whir, *
* Cyberfox, Karangi, Rathian, Cam, Raine, and Tarl. *
* *
* Original SMAUG 1.4a written by Thoric (Derek Snider) with Altrag, *
* Blodkai, Haus, Narn, Scryn, Swordbearer, Tricops, Gorog, Rennard, *
* Grishnakh, Fireblade, and Nivek. *
* *
* Original MERC 2.1 code by Hatchet, Furey, and Kahn. *
* *
* Original DikuMUD code by: Hans Staerfeldt, Katja Nyboe, Tom Madsen, *
* Michael Seifert, and Sebastian Hammer. *
****************************************************************************
* Dynamic Channel System *
****************************************************************************/
#include <string.h>
#include <ctype.h>
#include <time.h>
#include "mud.h"
MUD_CHANNEL *first_channel;
MUD_CHANNEL *last_channel;
char *drunk_speech args( ( const char *argument, CHAR_DATA * ch ) );
bool check_cuss args( ( char *cuss ) );
char *const chan_types[] = {
"Global", "Zone", "Guild", "Council", "PK", "Log"
};
int get_chantypes( char *name )
{
size_t x;
for( x = 0; x < sizeof( chan_types ) / sizeof( chan_types[0] ); x++ )
if( !str_cmp( name, chan_types[x] ) )
return x;
return -1;
}
void read_channel( MUD_CHANNEL * channel, FILE * fp )
{
char *word;
bool fMatch;
for( ;; )
{
word = feof( fp ) ? "End" : fread_word( fp );
fMatch = FALSE;
switch ( UPPER( word[0] ) )
{
case '*':
fMatch = TRUE;
fread_to_eol( fp );
break;
case 'C':
KEY( "ChanName", channel->name, fread_string( fp ) );
KEY( "ChanLevel", channel->level, fread_number( fp ) );
KEY( "ChanType", channel->type, fread_number( fp ) );
KEY( "ChanHistory", channel->keephistory, fread_number( fp ) );
break;
case 'E':
if( !str_cmp( word, "End" ) )
return;
break;
}
if( !fMatch )
bug( "read_channel: no match: %s", word );
}
}
void load_mudchannels( void )
{
FILE *fp;
MUD_CHANNEL *channel;
first_channel = NULL;
last_channel = NULL;
log_string( "Loading mud channels..." );
if( ( fp = fopen( CHANNEL_FILE, "r" ) ) == NULL )
{
log_string( "No channel file found." );
return;
}
for( ;; )
{
char letter;
char *word;
letter = fread_letter( fp );
if( letter == '*' )
{
fread_to_eol( fp );
continue;
}
if( letter != '#' )
{
bug( "load_channels: # not found.", 0 );
break;
}
word = fread_word( fp );
if( !str_cmp( word, "CHANNEL" ) )
{
CREATE( channel, MUD_CHANNEL, 1 );
read_channel( channel, fp );
LINK( channel, first_channel, last_channel, next, prev );
continue;
}
else if( !str_cmp( word, "END" ) )
break;
else
{
bug( "load_channels: bad section: %s.", word );
continue;
}
}
fclose( fp );
return;
}
void save_mudchannels( void )
{
FILE *fp;
MUD_CHANNEL *channel;
if( ( fp = fopen( CHANNEL_FILE, "w" ) ) == NULL )
{
log_string( "Couldn't write to channel file." );
return;
}
for( channel = first_channel; channel; channel = channel->next )
{
if( channel->name )
{
fprintf( fp, "#CHANNEL\n" );
fprintf( fp, "ChanName %s~\n", channel->name );
fprintf( fp, "ChanLevel %d\n", channel->level );
fprintf( fp, "ChanType %d\n", channel->type );
fprintf( fp, "ChanHistory %d\n", channel->keephistory );
fprintf( fp, "End\n\n" );
}
}
fprintf( fp, "#END\n" );
fclose( fp );
}
MUD_CHANNEL *find_channel( char *name )
{
MUD_CHANNEL *channel = NULL;
for( channel = first_channel; channel; channel = channel->next )
{
if( !str_cmp( channel->name, name ) )
return channel;
}
return NULL;
}
void do_makechannel( CHAR_DATA * ch, char *argument )
{
MUD_CHANNEL *channel;
if( !argument || argument[0] == '\0' )
{
send_to_char( "&GSyntax: makechannel <name>\r\n", ch );
return;
}
if( ( channel = find_channel( argument ) ) )
{
send_to_char( "&RA channel with that name already exists.\r\n", ch );
return;
}
CREATE( channel, MUD_CHANNEL, 1 );
channel->name = STRALLOC( argument );
channel->level = LEVEL_IMMORTAL;
channel->type = CHAN_GLOBAL;
channel->keephistory = FALSE;
LINK( channel, first_channel, last_channel, next, prev );
ch_printf( ch, "New channel %s created.\r\n", argument );
save_mudchannels( );
return;
}
void do_setchannel( CHAR_DATA * ch, char *argument )
{
MUD_CHANNEL *channel;
char arg[MAX_INPUT_LENGTH], arg2[MAX_INPUT_LENGTH];
if( !argument || argument[0] == '\0' )
{
send_to_char( "Syntax: setchannel <channel> <field> <value>\r\n\r\n", ch );
send_to_char( "Field may be one of the following:\r\n", ch );
send_to_char( "name level type history\r\n", ch );
return;
}
argument = one_argument( argument, arg );
if( !( channel = find_channel( arg ) ) )
{
send_to_char( "No channel by that name exists.\r\n", ch );
return;
}
argument = one_argument( argument, arg2 );
if( !arg || arg2[0] == '\0' )
{
do_setchannel( ch, "" );
return;
}
if( !str_cmp( arg2, "name" ) )
{
ch_printf( ch, "Channel %s renamed to %s\r\n", channel->name, argument );
STRFREE( channel->name );
channel->name = STRALLOC( argument );
save_mudchannels( );
return;
}
if( !str_cmp( arg2, "level" ) )
{
int level;
if( !is_number( argument ) )
{
send_to_char( "Level must be numerical.\r\n", ch );
return;
}
level = atoi( argument );
if( level < 1 || level > MAX_LEVEL )
{
ch_printf( ch, "Invalid level. Acceptable range is 1 to %d.\r\n", MAX_LEVEL );
return;
}
channel->level = level;
ch_printf( ch, "Channel %s level changed to %d\r\n", channel->name, level );
save_mudchannels( );
return;
}
if( !str_cmp( arg2, "type" ) )
{
int type = get_chantypes( argument );
if( type == -1 )
{
send_to_char( "Invalid channel type.\r\n", ch );
return;
}
channel->type = type;
ch_printf( ch, "Channel %s type changed to %s\r\n", channel->name, argument );
save_mudchannels( );
return;
}
if( !str_cmp( arg2, "history" ) )
{
channel->keephistory = !channel->keephistory;
if( channel->keephistory )
ch_printf( ch, "Channel %s will now keep a history.\r\n", channel->name );
else
ch_printf( ch, "Channel %s will no longer keep a history.\r\n", channel->name );
save_mudchannels( );
return;
}
do_setchannel( ch, "" );
return;
}
void do_destroychannel( CHAR_DATA * ch, char *argument )
{
MUD_CHANNEL *channel;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Syntax: destroychannel <name>\r\n", ch );
return;
}
if( !( channel = find_channel( argument ) ) )
{
send_to_char( "No channel with that name exists.\r\n", ch );
return;
}
STRFREE( channel->name );
UNLINK( channel, first_channel, last_channel, next, prev );
DISPOSE( channel );
ch_printf( ch, "Channel %s destroyed.\r\n", argument );
save_mudchannels( );
return;
}
void do_showchannels( CHAR_DATA * ch, char *argument )
{
MUD_CHANNEL *channel;
send_to_char( "&WName Level Type History?&D\r\n", ch );
send_to_char( "&B-------------------------------------------&D\r\n", ch );
for( channel = first_channel; channel; channel = channel->next )
ch_printf( ch, "&Y%-18s %-4d %-10s %s\r\n", capitalize( channel->name ),
channel->level, chan_types[channel->type], channel->keephistory ? "Yes" : "No" );
return;
}
/* Stuff borrowed from I3/MUD-Net code to handle channel listening */
/* changetarg: extract a single argument (with given max length) from
* argument to arg; if arg==NULL, just skip an arg, don't copy it out
*/
const char *getarg( const char *argument, char *arg, int length )
{
int len = 0;
while( *argument && isspace( *argument ) )
argument++;
if( arg )
while( *argument && !isspace( *argument ) && len < length - 1 )
*arg++ = *argument++, len++;
else
while( *argument && !isspace( *argument ) )
argument++;
while( *argument && !isspace( *argument ) )
argument++;
while( *argument && isspace( *argument ) )
argument++;
if( arg )
*arg = 0;
return argument;
}
/* Check for a name in a list */
int hasname( const char *list, const char *name )
{
const char *p;
char arg[MAX_INPUT_LENGTH];
if( !list )
return ( 0 );
p = getarg( list, arg, MAX_INPUT_LENGTH );
while( arg[0] )
{
if( !strcasecmp( name, arg ) )
return 1;
p = getarg( p, arg, MAX_INPUT_LENGTH );
}
return 0;
}
/* Add a name to a list */
void addname( char **list, const char *name )
{
char buf[MAX_STRING_LENGTH];
if( hasname( *list, name ) )
return;
if( *list && *list[0] != '\0' )
sprintf( buf, "%s %s", *list, name );
else
strcpy( buf, name );
if( *list )
STRFREE( *list );
*list = STRALLOC( buf );
}
/* Remove a name from a list */
void removename( char **list, const char *name )
{
char buf[MAX_STRING_LENGTH];
char arg[MAX_INPUT_LENGTH];
const char *p;
buf[0] = 0;
p = getarg( *list, arg, MAX_INPUT_LENGTH );
while( arg[0] )
{
if( strcasecmp( arg, name ) )
{
if( buf[0] )
strcat( buf, " " );
strcat( buf, arg );
}
p = getarg( p, arg, MAX_INPUT_LENGTH );
}
STRFREE( *list );
*list = STRALLOC( buf );
}
void do_listen( CHAR_DATA * ch, char *argument )
{
MUD_CHANNEL *channel;
if( !argument || argument[0] == '\0' )
{
send_to_char( "Syntax: listen \r\n", ch );
send_to_char( "Syntax: listen all\r\n", ch );
send_to_char( "Syntax: listen none\r\n", ch );
send_to_char( "For a list of channels, type channels\r\n", ch );
send_to_char( "You are listenting to the following local mud channels:\r\n\r\n", ch );
ch_printf( ch, "%s\r\n", ch->pcdata->chan_listen );
return;
}
if( !str_cmp( argument, "all" ) )
{
for( channel = first_channel; channel; channel = channel->next )
{
if( ch->level >= channel->level && !hasname( ch->pcdata->chan_listen, channel->name ) )
addname( &ch->pcdata->chan_listen, channel->name );
}
send_to_char( "You are now listening to all available channels.\r\n", ch );
return;
}
if( !str_cmp( argument, "none" ) )
{
for( channel = first_channel; channel; channel = channel->next )
{
if( ch->level >= channel->level && hasname( ch->pcdata->chan_listen, channel->name ) )
removename( &ch->pcdata->chan_listen, channel->name );
}
send_to_char( "You no longer listen to any available channel.\r\n", ch );
return;
}
if( hasname( ch->pcdata->chan_listen, argument ) )
{
removename( &ch->pcdata->chan_listen, argument );
ch_printf( ch, "You no longer listen to %s\r\n", argument );
}
else
{
if( !( channel = find_channel( argument ) ) )
{
send_to_char( "No such channel.\r\n", ch );
return;
}
if( channel->level > ch->level )
{
send_to_char( "That channel is above your level.\r\n", ch );
return;
}
addname( &ch->pcdata->chan_listen, argument );
ch_printf( ch, "You now listen to %s\r\n", channel->name );
}
return;
}
/* Revised channel display by Zarius */
void do_channels( CHAR_DATA * ch, char *argument )
{
MUD_CHANNEL *channel;
int count = 0, second = 0, third = 0;
MUD_CHANNEL *offchannel;
int first = 0;
send_to_char( "&YThe following channels are available:\r\n", ch );
send_to_char( "To toggle a channel, use the &Wlisten &Ycommand.\r\n\r\n", ch );
send_to_char( "&B----------------------------------------------------------------&D\r\n", ch );
for( channel = first_channel; channel; channel = channel->next )
{
if( ch->level >= channel->level )
{
if( hasname( ch->pcdata->chan_listen, channel->name ) == 0 )
continue;
third += 1;
first += 1;
count += 1;
if( third == 1 )
ch_printf( ch, "&WYou are listening to these channels!\r\n" );
ch_printf( ch, "&C%-15.15s &D", capitalize( channel->name ) );
if( count == 4 )
{
ch_printf( ch, "\r\n" );
count = 0;
}
}
}
if( count != 0 )
ch_printf( ch, "\r\n" );
if( first != 0 )
send_to_char( "&B----------------------------------------------------------------&D\r\n", ch );
third = 0;
first = 0;
for( offchannel = first_channel; offchannel; offchannel = offchannel->next )
{
if( ch->level >= offchannel->level )
{
if( hasname( ch->pcdata->chan_listen, offchannel->name ) == 1 )
continue;
third += 1;
first += 1;
second += 1;
if( third == 1 )
ch_printf( ch, "&WYou are not listening to these channels!\r\n" );
ch_printf( ch, "&R%-15.15s &D", capitalize( offchannel->name ) );
if( second == 4 )
{
ch_printf( ch, "\r\n" );
second = 0;
}
}
}
if( second != 0 )
send_to_char( "\r\n", ch );
if( first != 0 )
send_to_char( "&B----------------------------------------------------------------&D\r\n", ch );
return;
}
void invert( char *arg1, char *arg2 )
{
int i = 0;
int len = strlen( arg1 ) - 1;
while( i <= len )
{
*( arg2 + i ) = *( arg1 + ( len - i ) );
i++;
}
*( arg2 + i ) = '\0';
}
/* Duplicate of to_channel from act_comm.c modified for dynamic channels */
void send_tochannel( CHAR_DATA * ch, MUD_CHANNEL * channel, char *argument )
{
char buf[MAX_STRING_LENGTH], buf2[MAX_STRING_LENGTH], word[MAX_INPUT_LENGTH], log_buf2[MAX_STRING_LENGTH];
char *arg, *socbuf_char = NULL, *socbuf_vict = NULL, *socbuf_other = NULL;
CHAR_DATA *victim = NULL;
CHAR_DATA *vch;
OBJ_DATA *obj; /* Burgundy Amulet */
SOCIALTYPE *social = NULL;
int position, x, msg;
short color;
char clr[MSL];
struct tm *local;
time_t t;
bool emote = FALSE;
#ifndef SCRAMBLE
int speaking = -1, lang;
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
if( IS_NPC( ch ) && channel->type == CHAN_GUILD )
{
send_to_char( "Mobs can't be in clans/guilds.\r\n", ch );
return;
}
if( !IS_PKILL( ch ) && channel->type == CHAN_PK )
{
if( !IS_IMMORTAL( ch ) )
{
send_to_char( "Peacefuls have no need to use wartalk.\r\n", ch );
return;
}
}
if( IS_SET( ch->in_room->room_flags, ROOM_SILENCE ) )
{
send_to_char( "The room absorbs your words!\r\n", ch );
return;
}
if( IS_NPC( ch ) && IS_AFFECTED( ch, AFF_CHARM ) )
{
if( ch->master )
send_to_char( "I don't think so...\r\n", ch->master );
return;
}
if( !IS_NPC( ch ) && !ch->pcdata->clan && channel->type == CHAN_GUILD )
{
ch_printf( ch, "You're not in a %s!\r\n",
!str_cmp( channel->name, "clantalk" ) ? "clan" : !str_cmp( channel->name,
"guildtalk" ) ? "guild" : "order" );
return;
}
if( !argument || argument[0] == '\0' )
{
char *name;
if( !channel->keephistory )
{
ch_printf( ch, "%s what?\r\n", capitalize( channel->name ) );
return;
}
ch_printf( ch, "The last 20 %s messages:\r\n", channel->name );
for( x = 0; x < 20; x++ )
{
if( channel->history[x][0] != NULL )
{
switch ( channel->hlevel[x] )
{
case 0:
name = channel->history[x][0];
break;
case 1:
if( IS_AFFECTED( ch, AFF_DETECT_INVIS ) || xIS_SET( ch->act, PLR_HOLYLIGHT ) )
name = channel->history[x][0];
else
name = "Someone";
break;
case 2:
if( ch->level >= channel->hinvis[x] )
name = channel->history[x][0];
else
name = "Someone";
break;
default:
name = "Someone";
}
ch_printf( ch, channel->history[x][1], name );
}
else
break;
}
return;
}
if( xIS_SET( ch->act, PLR_SILENCE ) )
{
ch_printf( ch, "You can't %s.\r\n", channel->name );
return;
}
/*
* Inverts the speech of anyone carrying the burgundy amulet
*/
for( obj = ch->first_carrying; obj; obj = obj->next_content )
{
if( obj->pIndexData->vnum == 1405 ) /* The amulet itself */
{
invert( argument, log_buf );
strcpy( argument, log_buf );
break;
}
}
/*
* OK, this is hackish - until I can figure out a better method
*/
color = -1;
if( !str_cmp( channel->name, "chat" ) )
sprintf( clr, "G" );
else if( !str_cmp( channel->name, "immtalk" ) )
sprintf( clr, "Y" );
else if( !str_cmp( channel->name, "avtalk" ) )
sprintf( clr, "O" );
else if( !str_cmp( channel->name, "ooc" ) )
sprintf( clr, "G" );
else if( !str_cmp( channel->name, "icc" ) )
sprintf( clr, "G" );
else if( !str_cmp( channel->name, "yell" ) )
sprintf( clr, "c" );
else if( !str_cmp( channel->name, "shout" ) )
sprintf( clr, "c" );
else if( !str_cmp( channel->name, "muse" ) )
sprintf( clr, "c" );
else if( !str_cmp( channel->name, "think" ) )
sprintf( clr, "c" );
else if( !str_cmp( channel->name, "auction" ) )
sprintf( clr, "G" );
else if( !str_cmp( channel->name, "wartalk" ) )
sprintf( clr, "R" );
else if( !str_cmp( channel->name, "music" ) )
sprintf( clr, "P" );
else if( !str_cmp( channel->name, "quest" ) )
sprintf( clr, "c" );
else if( !str_cmp( channel->name, "newbiechat" ) )
sprintf( clr, "c" );
else if( !str_cmp( channel->name, "guildtalk" ) )
sprintf( clr, "c" );
else if( !str_cmp( channel->name, "counciltalk" ) )
sprintf( clr, "c" );
else if( !str_cmp( channel->name, "clantalk" ) )
sprintf( clr, "R" );
else if( !str_cmp( channel->name, "ordertalk" ) )
sprintf( clr, "C" );
else if( !str_cmp( channel->name, "quote" ) )
sprintf( clr, "c" );
else
sprintf( clr, "G" );
if( color == -1 )
color = AT_GOSSIP;
set_char_color( color, ch );
arg = argument;
arg = one_argument( arg, word );
if( word[0] == '@' && ( social = find_social( word + 1 ) ) != NULL )
{
if( arg && *arg )
{
char name[MAX_INPUT_LENGTH];
one_argument( arg, name );
if( ( victim = get_char_world( ch, name ) ) )
arg = one_argument( arg, name );
if( !victim )
{
socbuf_char = social->char_no_arg;
socbuf_vict = social->others_no_arg;
socbuf_other = social->others_no_arg;
if( !socbuf_char && !socbuf_other )
social = NULL;
}
else if( victim == ch )
{
socbuf_char = social->char_auto;
socbuf_vict = social->others_auto;
socbuf_other = social->others_auto;
if( !socbuf_char && !socbuf_other )
social = NULL;
}
else if( victim != ch )
{
socbuf_char = social->char_found;
socbuf_vict = social->vict_found;
socbuf_other = social->others_found;
if( !socbuf_char && !socbuf_other && !socbuf_vict )
social = NULL;
}
else
social = NULL;
}
else
{
socbuf_char = social->char_no_arg;
socbuf_vict = social->others_no_arg;
socbuf_other = social->others_no_arg;
if( !socbuf_char && !socbuf_other )
social = NULL;
}
}
if( word[0] == ',' )
emote = TRUE;
if( social )
{
sprintf( buf, "&w[&%s%s&w] &%s%s", clr, capitalize( channel->name ), clr, socbuf_char );
act( AT_PLAIN, buf, ch, argument, victim, TO_CHAR );
}
else if( emote )
{
sprintf( log_buf, "&w[&%s%s&w] &%s%s %s\r\n", clr, capitalize( channel->name ), clr, ch->name, argument + 1 );
send_to_char( log_buf, ch );
argument = argument + 1;
}
else
{ // Profanity Filter
if( check_cuss( argument ) && !IS_IMMORTAL( ch ) && str_cmp( channel->name, "wartalk" ) )
{
msg = number_range( 0, 4 );
if( msg == 0 )
send_to_char( "Potty Mouth!\r\n", ch );
if( msg == 1 )
send_to_char( "Shame on You!\r\n", ch );
if( msg == 2 )
send_to_char( "Do you kiss your mother with that filthy mouth!?\r\n", ch );
if( msg == 3 )
send_to_char( "Git tha soap Ma, it's time fer a mouth washin'!\r\n", ch );
if( msg == 4 )
send_to_char( "Somewhere, a single tear is rolling down Garinan's cheek.\r\n", ch );
sprintf( buf, "Profanity attempt by %s on channel %s: %s", ch->name, channel->name, argument );
log_string( buf );
return;
}
ch_printf( ch, "&w[&%s%s&w] You: &%s%s\r\n", clr, capitalize( channel->name ), clr, argument );
}
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf2, "%s: %s (%s)", IS_NPC( ch ) ? ch->short_descr : ch->name, argument, channel->name );
append_to_file( LOG_FILE, buf2 );
}
/*
* Channel history. Records the last 20 messages to channels which keep historys
*/
if( channel->keephistory )
{
for( x = 0; x < 20; x++ )
{
int type;
type = 0;
if( IS_AFFECTED( ch, AFF_INVISIBLE ) )
type = 1;
if( xIS_SET( ch->act, PLR_WIZINVIS ) )
type = 2;
if( channel->history[x][0] == NULL )
{
if( IS_NPC( ch ) )
channel->history[x][0] = str_dup( ch->short_descr );
else
channel->history[x][0] = str_dup( ch->name );
t = time( NULL );
local = localtime( &t );
sprintf( log_buf2, " [%-2.2d:%-2.2d] %%s%s %s\r\n",
local->tm_hour, local->tm_min, emote ? "" : ":", argument );
channel->history[x][1] = str_dup( log_buf2 );
channel->hlevel[x] = type;
if( type == 2 )
channel->hinvis[x] = ch->pcdata->wizinvis;
else
channel->hinvis[x] = 0;
break;
}
if( x == 19 )
{
int y;
for( y = 1; y < 20; y++ )
{
int z = y - 1;
if( channel->history[z][0] != NULL )
{
DISPOSE( channel->history[z][0] );
DISPOSE( channel->history[z][1] );
channel->history[z][0] = str_dup( channel->history[y][0] );
channel->history[z][1] = str_dup( channel->history[y][1] );
channel->hlevel[z] = channel->hlevel[y];
channel->hinvis[z] = channel->hinvis[y];
}
}
if( IS_NPC( ch ) )
channel->history[x][0] = str_dup( ch->short_descr );
else
channel->history[x][0] = str_dup( ch->name );
t = time( NULL );
local = localtime( &t );
sprintf( log_buf2, " [%-2.2d:%-2.2d] %%s%s %s\r\n",
local->tm_hour, local->tm_min, emote ? "" : ":", argument );
channel->history[x][1] = str_dup( log_buf2 );
channel->hlevel[x] = type;
if( type == 2 )
channel->hinvis[x] = ch->pcdata->wizinvis;
else
channel->hinvis[x] = 0;
}
}
}
for( vch = first_char; vch; vch = vch->next )
{
/*
* Hackish solution to stop that damned "someone chat" bug - Matarael 17.3.2002
*/
if( IS_NPC( vch ) || vch == ch || !vch->desc )
continue;
if( vch->desc->connected == CON_PLAYING && hasname( vch->pcdata->chan_listen, channel->name ) )
{
char *sbuf = argument;
char lbuf[MAX_INPUT_LENGTH + 4]; /* invis level string + buf */
if( vch->level < channel->level )
continue;
/*
* Another hackish deal for now
*/
if( !str_cmp( channel->name, "newbiechat" ) && ( !IS_IMMORTAL( vch ) && vch->level < 5 ) )
continue;
if( !str_cmp( channel->name, "immtalk" ) && !IS_IMMORTAL( vch ) )
continue;
if( !str_cmp( channel->name, "avtalk" ) && vch->level < LEVEL_AVATAR )
continue;
if( IS_SET( vch->in_room->room_flags, ROOM_SILENCE ) )
continue;
if( channel->type == CHAN_ZONE && vch->in_room->area != ch->in_room->area )
continue;
if( channel->type == CHAN_PK && !IS_PKILL( vch ) && !IS_IMMORTAL( vch ) )
continue;
if( channel->type == CHAN_GUILD )
{
if( IS_NPC( vch ) )
continue;
if( vch->pcdata->clan != ch->pcdata->clan )
continue;
}
if( channel->type == CHAN_COUNCIL )
{
if( IS_NPC( vch ) )
continue;
if( vch->pcdata->council != ch->pcdata->council )
continue;
}
position = vch->position;
vch->position = POS_STANDING;
set_char_color( color, vch );
if( xIS_SET( ch->act, PLR_WIZINVIS ) && can_see( vch, ch ) && IS_IMMORTAL( vch ) )
sprintf( lbuf, "(%d) ", ( !IS_NPC( ch ) ) ? ch->pcdata->wizinvis : ch->mobinvis );
else
lbuf[0] = '\0';
#ifndef SCRAMBLE
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( vch, ch->speaking ), knows_language( ch, ch->speaking ) );
if( speakswell < 85 )
sbuf = translate( speakswell, argument, lang_names[speaking] );
}
#else
if( !knows_language( vch, ch->speaking ) && ( !IS_NPC( ch ) || ch->speaking != 0 ) )
sbuf = scramble( argument, ch->speaking );
#endif
/*
* Check to see if target is ignoring the sender
*/
if( is_ignoring( vch, ch ) )
{
/*
* If the sender is an imm then they cannot be ignored
*/
if( !IS_IMMORTAL( ch ) || vch->level > ch->level )
{
/*
* Off to oblivion!
*/
continue;
}
else
set_char_color( AT_IGNORE, vch );
}
MOBtrigger = FALSE;
/*
* Hackish solution to stop that damned "someone chat" bug - Matarael 17.3.2002
*/
if( !social && !emote )
{
sprintf( buf, "&w[&%s%s&w] $n: &%s$t", clr, capitalize( channel->name ), clr );
act( AT_PLAIN, strcat( lbuf, buf ), ch, sbuf, vch, TO_VICT );
}
if( emote )
{
sprintf( buf, "&w[&%s%s&w] &%s$n $t", clr, capitalize( channel->name ), clr );
act( AT_PLAIN, strcat( lbuf, buf ), ch, sbuf, vch, TO_VICT );
}
if( social )
{
if( vch == victim )
{
sprintf( buf, "&w[&%s%s&w] &%s%s", clr, capitalize( channel->name ), clr, socbuf_vict );
act( AT_PLAIN, buf, ch, NULL, vch, TO_VICT );
}
else if( vch != ch )
{
sprintf( buf, "&w[&%s%s&w] &%s%s", clr, capitalize( channel->name ), clr, socbuf_other );
act( AT_PLAIN, buf, ch, vch, victim, TO_THIRD );
}
}
vch->position = position;
/*
* Hackish solution to stop that damned "someone chat" bug - Matarael 17.3.2002
*/
}
}
return;
}
void to_channel( const char *argument, char *xchannel, int level )
{
MUD_CHANNEL *channel;
char buf[MAX_STRING_LENGTH];
DESCRIPTOR_DATA *d;
if( !first_descriptor || argument[0] == '\0' )
return;
if( !( channel = find_channel( xchannel ) ) )
return;
if( channel->type != CHAN_LOG )
return;
sprintf( buf, "%s: %s\r\n", capitalize( channel->name ), argument );
for( d = first_descriptor; d; d = d->next )
{
CHAR_DATA *vch;
vch = d->original ? d->original : d->character;
if( !vch )
continue;
if( d->original )
continue;
/*
* This could be coming in higher than the normal level, so check first
*/
if( vch->level < level )
continue;
if( d->connected == CON_PLAYING && vch->level >= channel->level && hasname( vch->pcdata->chan_listen, channel->name ) )
{
set_char_color( AT_LOG, vch );
send_to_char_color( buf, vch );
}
}
return;
}
bool local_channel_hook( CHAR_DATA * ch, char *command, char *argument )
{
MUD_CHANNEL *channel;
if( !( channel = find_channel( command ) ) )
return FALSE;
if( ch->level < channel->level )
return FALSE;
/*
* Logs are meant to be seen, not talked on
*/
if( channel->type == CHAN_LOG )
return FALSE;
if( !IS_NPC( ch ) && !hasname( ch->pcdata->chan_listen, command ) )
{
ch_printf( ch, "You are not listening to the %s channel.\r\n", channel->name );
return TRUE;
}
send_tochannel( ch, channel, argument );
return TRUE;
}
void do_ask( CHAR_DATA * ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
CHAR_DATA *vch;
CHAR_DATA *victim;
EXT_BV actflags;
#ifndef SCRAMBLE
int speaking = -1, lang;
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
argument = one_argument( argument, arg );
if( arg[0] == '\0' || argument[0] == '\0' )
{
send_to_char( "Ask who what?\r\n", ch );
return;
}
if( ( victim = get_char_world( ch, arg ) ) == NULL
|| ( IS_NPC( victim ) && victim->in_room != ch->in_room )
|| ( !NOT_AUTHED( ch ) && NOT_AUTHED( victim ) && !IS_IMMORTAL( ch ) ) )
{
send_to_char( "They aren't here.\r\n", ch );
return;
}
if( IS_SET( ch->in_room->room_flags, ROOM_SILENCE ) )
{
send_to_char( "You can't do that here.\r\n", ch );
return;
}
actflags = ch->act;
if( IS_NPC( ch ) )
xREMOVE_BIT( ch->act, ACT_SECRETIVE );
for( vch = ch->in_room->first_person; vch; vch = vch->next_in_room )
{
char *sbuf = argument;
if( vch == ch )
continue;
/*
* Check to see if character is ignoring speaker
*/
if( is_ignoring( vch, ch ) )
{
/*
* continue unless speaker is an immortal
*/
if( !IS_IMMORTAL( ch ) || get_trust( vch ) > get_trust( ch ) )
continue;
else
{
set_char_color( AT_IGNORE, vch );
ch_printf( vch, "You attempt to ignore %s, but are unable to do so.\r\n", ch->name );
}
}
#ifndef SCRAMBLE
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( vch, ch->speaking ), knows_language( ch, ch->speaking ) );
if( speakswell < 75 )
sbuf = translate( speakswell, argument, lang_names[speaking] );
}
#else
if( !knows_language( vch, ch->speaking ) && ( !IS_NPC( ch ) || ch->speaking != 0 ) )
sbuf = scramble( argument, ch->speaking );
#endif
sbuf = drunk_speech( sbuf, ch );
MOBtrigger = FALSE;
}
ch->act = actflags;
MOBtrigger = FALSE;
act( AT_SAY, "You ask $N '$t'", ch, drunk_speech( argument, ch ), victim, TO_CHAR );
act( AT_SAY, "$n asks you '$t'", ch, drunk_speech( argument, ch ), victim, TO_VICT );
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf, "%s: %s", IS_NPC( ch ) ? ch->short_descr : ch->name, argument );
append_to_file( LOG_FILE, buf );
}
mprog_speech_trigger( argument, ch );
return;
}
void do_say( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
CHAR_DATA *vch;
EXT_BV actflags;
char *to_vict, *to_char, *to_char_log;
int x, arglen, rn;
struct tm *lcl;
time_t cur;
/*
* Various tables for randomness -- Kratas
*/
struct
{
char *to_char;
char *to_vict;
char *to_char_log;
}
state_list[] =
{
{
"say", "says", "said"},
{
"state", "states", "stated"}
};
struct
{
char *to_char;
char *to_vict;
char *to_char_log;
}
question_list[] =
{
{
"ask", "asks", "asked"},
{
"inquire", "inquires", "inquired"}
};
struct
{
char *to_char;
char *to_vict;
char *to_char_log;
}
exclaim_list[] =
{
{
"yell", "yells", "yelled"},
{
"exclaim", "exclaims", "exclaimed"}
};
#ifndef SCRAMBLE
int speaking = -1, lang;
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
if( argument[0] == '\0' )
{
char buffer[MAX_STRING_LENGTH];
if( IS_NPC( ch ) )
{
send_to_char( "Say what?", ch );
return;
}
send_to_char_color( "&cLast things you heard said&W:&w\r\n", ch );
strcpy( buf, "" );
for( x = 0; x < 10; x++ )
{
if( ch->pcdata->say_history[x] == NULL )
break;
sprintf( buffer, " &c%s&w\r\n", ch->pcdata->say_history[x] );
strcat( buf, buffer );
}
strcat( buf, "\r\n" );
send_to_char( buf, ch );
return;
}
if( IS_SET( ch->in_room->room_flags, ROOM_SILENCE ) )
{
send_to_char( "You can't do that here.\r\n", ch );
return;
}
actflags = ch->act;
if( IS_NPC( ch ) )
xREMOVE_BIT( ch->act, ACT_SECRETIVE );
arglen = strlen( argument ) - 1;
while( argument[arglen] == ' ' || argument[arglen] == '\t' )
--arglen;
switch ( argument[arglen] )
{
case '?':
rn = rand( ) % ( sizeof( question_list ) / sizeof( question_list[0] ) );
to_vict = question_list[rn].to_vict;
to_char = question_list[rn].to_char;
to_char_log = question_list[rn].to_char_log;
break;
case '!':
rn = rand( ) % ( sizeof( exclaim_list ) / sizeof( exclaim_list[0] ) );
to_vict = exclaim_list[rn].to_vict;
to_char = exclaim_list[rn].to_char;
to_char_log = exclaim_list[rn].to_char_log;
break;
case '"':
if( argument[0] == '"' )
{
to_vict = "quotes";
to_char = "quote";
to_char_log = "quoted";
break;
}
case '.':
if( argument[arglen - 1] == '.' && argument[arglen - 2] == '.' )
{
to_vict = "trails off saying";
to_char = "trail off saying";
to_char_log = "trailed off saying";
break;
}
default:
rn = rand( ) % ( sizeof( state_list ) / sizeof( state_list[0] ) );
to_vict = state_list[rn].to_vict;
to_char = state_list[rn].to_char;
to_char_log = state_list[rn].to_char_log;
break;
}
for( vch = ch->in_room->first_person; vch; vch = vch->next_in_room )
{
char *sbuf = argument;
char tmpbuf[MAX_STRING_LENGTH];
char actbuf[MAX_STRING_LENGTH];
if( vch == ch )
continue;
/*
* Check to see if character is ignoring speaker
*/
if( is_ignoring( vch, ch ) )
{
/*
* continue unless speaker is an immortal
*/
if( !IS_IMMORTAL( ch ) || get_trust( vch ) > get_trust( ch ) )
continue;
else
{
set_char_color( AT_IGNORE, vch );
ch_printf( vch, "You attempt to ignore %s, but" " are unable to do so.\r\n", ch->name );
}
}
#ifndef SCRAMBLE
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( vch, ch->speaking ),
knows_language( ch, ch->speaking ) );
if( speakswell < 75 )
sbuf = translate( speakswell, argument, lang_names[speaking] );
}
#else
if( !knows_language( vch, ch->speaking ) && ( !IS_NPC( ch ) || ch->speaking != 0 ) )
sbuf = scramble( argument, ch->speaking );
#endif
sbuf = drunk_speech( sbuf, ch );
MOBtrigger = FALSE;
cur = time( NULL );
lcl = localtime( &cur );
sprintf( tmpbuf, "[%-2.2d:%-2.2d] %s %s '%s&c'", lcl->tm_hour, lcl->tm_min, PERS( ch, vch ), to_char_log, sbuf );
sprintf( actbuf, "$n %s '$t'", to_vict );
// act( AT_SAY, "$n says '$t'", ch, sbuf, vch, TO_VICT );
act( AT_SAY, actbuf, ch, sbuf, vch, TO_VICT );
if( !IS_NPC( vch ) )
{
for( x = 0; x < 10; x++ )
{
if( vch->pcdata->say_history[x] == '\0' )
{
vch->pcdata->say_history[x] = strdup( tmpbuf );
break;
}
if( x == 9 )
{
int i;
for( i = 1; i < 10; i++ )
{
DISPOSE( vch->pcdata->say_history[i - 1] );
vch->pcdata->say_history[i - 1] = strdup( vch->pcdata->say_history[i] );
}
DISPOSE( vch->pcdata->say_history[x] );
vch->pcdata->say_history[x] = strdup( tmpbuf );
}
}
}
}
/*
* MOBtrigger = FALSE;
* act( AT_SAY, "$n says '$T'", ch, NULL, argument, TO_ROOM );
*/
ch->act = actflags;
MOBtrigger = FALSE;
sprintf( buf, "You %s '$T'", to_char );
act( AT_SAY, buf, ch, NULL, drunk_speech( argument, ch ), TO_CHAR );
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf, "%s: %s", IS_NPC( ch ) ? ch->short_descr : ch->name, argument );
append_to_file( LOG_FILE, buf );
}
mprog_speech_trigger( argument, ch );
if( char_died( ch ) )
return;
oprog_speech_trigger( argument, ch );
if( char_died( ch ) )
return;
rprog_speech_trigger( argument, ch );
return;
}
void StoreTell( CHAR_DATA * ch, char *arg )
{
int x;
if( !IS_NPC( ch ) )
{
for( x = 0; x < 10; x++ )
{
if( ch->pcdata->tell_histories[x] == NULL )
{
ch->pcdata->tell_histories[x] = str_dup( arg );
break;
}
if( x == 9 )
{
int i;
for( i = 1; i < 10; i++ )
{
DISPOSE( ch->pcdata->tell_histories[i - 1] );
ch->pcdata->tell_histories[i - 1] = str_dup( ch->pcdata->tell_histories[i] );
}
ch->pcdata->tell_histories[x] = str_dup( arg );
}
}
}
}
void do_tell( CHAR_DATA * ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH], buf2[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
int position, x;
CHAR_DATA *switched_victim = NULL;
struct tm *lol;
time_t cor;
#ifndef SCRAMBLE
int speaking = -1, lang;
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
MOBtrigger = TRUE;
if( !IS_IMMORTAL( ch ) )
REMOVE_BIT( ch->deaf, CHANNEL_TELLS );
if( IS_SET( ch->in_room->room_flags, ROOM_SILENCE ) )
{
send_to_char( "You can't do that here.\r\n", ch );
return;
}
if( !IS_NPC( ch ) && ( xIS_SET( ch->act, PLR_SILENCE ) || xIS_SET( ch->act, PLR_NO_TELL ) ) )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
argument = one_argument( argument, arg );
if( arg[0] == '\0' || argument[0] == '\0' )
{
if( IS_NPC( ch ) )
{
send_to_char( "Tell whom what?\r\n", ch );
return;
}
send_to_char_color( "&cThe Last Tells You Have Recieved&W:&w\r\n", ch );
buf[0] = '\0';
for( x = 0; x < 10; x++ )
{
if( ch->pcdata->tell_histories[x] == NULL )
break;
sprintf( buf + strlen( buf ), "%s\r\n", ch->pcdata->tell_histories[x] );
}
strcat( buf, "\r\n" );
send_to_char( buf, ch );
return;
}
if( ( victim = get_char_world( ch, arg ) ) == NULL
|| ( IS_NPC( victim ) && victim->in_room != ch->in_room )
|| ( !NOT_AUTHED( ch ) && NOT_AUTHED( victim ) && !IS_IMMORTAL( ch ) ) )
{
send_to_char( "They aren't here.\r\n", ch );
return;
}
if( ch == victim )
{
send_to_char( "You have a nice little chat with yourself.\r\n", ch );
return;
}
if( NOT_AUTHED( ch ) && !NOT_AUTHED( victim ) && !IS_IMMORTAL( victim ) )
{
send_to_char( "They can't hear you because you are not authorized.\r\n", ch );
return;
}
if( !IS_NPC( victim ) && ( victim->switched )
&& ( get_trust( ch ) > LEVEL_AVATAR ) && !IS_AFFECTED( victim->switched, AFF_POSSESS ) )
{
send_to_char( "That player is switched.\r\n", ch );
return;
}
else if( !IS_NPC( victim ) && ( victim->switched ) && IS_AFFECTED( victim->switched, AFF_POSSESS ) )
switched_victim = victim->switched;
else if( !IS_NPC( victim ) && ( !victim->desc ) )
{
send_to_char( "That player is link-dead.\r\n", ch );
return;
}
if( !IS_NPC( victim ) && xIS_SET( victim->act, PLR_AFK ) )
{
send_to_char( "That player is away and may not have received your tell.\r\n", ch );
}
if( IS_SET( victim->deaf, CHANNEL_TELLS ) && ( !IS_IMMORTAL( ch ) || ( get_trust( ch ) <= get_trust( victim ) ) ) )
{
act( AT_PLAIN, "$E has $S tells turned off.", ch, NULL, victim, TO_CHAR );
return;
}
if( !IS_NPC( victim ) && xIS_SET( victim->act, PLR_SILENCE ) )
send_to_char( "That player is silenced. They will receive your message but can not respond.\r\n", ch );
if( ( !IS_IMMORTAL( ch ) && !IS_AWAKE( victim ) )
|| ( !IS_NPC( victim ) && IS_SET( victim->in_room->room_flags, ROOM_SILENCE ) ) )
{
act( AT_PLAIN, "$E can't hear you.", ch, 0, victim, TO_CHAR );
return;
}
if( victim->desc /* make sure desc exists first -Thoric */
&& ( victim->desc->connected == CON_EDITING
|| ( victim->desc->connected >= CON_NOTE_TO
&& victim->desc->connected <= CON_NOTE_FINISH ) ) && get_trust( ch ) < LEVEL_GOD )
{
act( AT_PLAIN, "$E is currently in a writing buffer. Please try again in a few minutes.", ch, 0, victim, TO_CHAR );
return;
}
/*
* Check to see if target of tell is ignoring the sender
*/
if( is_ignoring( victim, ch ) )
{
/*
* If the sender is an imm then they cannot be ignored
*/
if( !IS_IMMORTAL( ch ) || get_trust( victim ) > get_trust( ch ) )
{
set_char_color( AT_IGNORE, ch );
ch_printf( ch, "%s is ignoring you.\r\n", victim->name );
return;
}
else
{
set_char_color( AT_IGNORE, victim );
ch_printf( victim, "You attempt to ignore %s, but are unable to do so.\r\n", ch->name );
}
}
ch->retell = victim;
if( !IS_NPC( victim ) && IS_IMMORTAL( victim ) && victim->pcdata->tell_history &&
isalpha( IS_NPC( ch ) ? ch->short_descr[0] : ch->name[0] ) )
{
sprintf( buf, "%s told you '%s'\r\n", capitalize( IS_NPC( ch ) ? ch->short_descr : ch->name ), argument );
/*
* get lasttell index... assumes names begin with characters
*/
victim->pcdata->lt_index = tolower( IS_NPC( ch ) ? ch->short_descr[0] : ch->name[0] ) - 'a';
/*
* get rid of old messages
*/
if( victim->pcdata->tell_history[victim->pcdata->lt_index] )
STRFREE( victim->pcdata->tell_history[victim->pcdata->lt_index] );
/*
* store the new message
*/
victim->pcdata->tell_history[victim->pcdata->lt_index] = STRALLOC( buf );
}
if( switched_victim )
victim = switched_victim;
/*
* Bug fix by guppy@wavecomputers.net
*/
MOBtrigger = FALSE;
act( AT_TELL, "You tell $N '$t'", ch, argument, victim, TO_CHAR );
position = victim->position;
victim->position = POS_STANDING;
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( victim, ch->speaking ),
knows_language( ch, ch->speaking ) );
if( speakswell < 85 )
{
MOBtrigger = FALSE;
act( AT_TELL, "$n tells you '$t'", ch, translate( speakswell, argument, lang_names[speaking] ), victim, TO_VICT );
}
else
act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
}
else
act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
MOBtrigger = TRUE;
victim->position = position;
victim->reply = ch;
cor = time( NULL );
lol = localtime( &cor );
sprintf( buf2, "&R[%-2.2d:%-2.2d] %s told you &r'&R%s&r'&w", lol->tm_hour, lol->tm_min,
capitalize( IS_NPC( ch ) ? ch->short_descr : ch->name ), argument );
StoreTell( victim, buf2 );
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf, "%s: %s (tell to) %s.",
IS_NPC( ch ) ? ch->short_descr : ch->name, argument, IS_NPC( victim ) ? victim->short_descr : victim->name );
append_to_file( LOG_FILE, buf );
}
mprog_speech_trigger( argument, ch );
return;
}
void do_say_to_char( CHAR_DATA * ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
char buf[MAX_STRING_LENGTH];
CHAR_DATA *vch;
CHAR_DATA *victim;
EXT_BV actflags;
#ifndef SCRAMBLE
int speaking = -1, lang;
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
argument = one_argument( argument, arg );
if( arg[0] == '\0' || argument[0] == '\0' )
{
send_to_char( "Say what to whom?\r\n", ch );
return;
}
if( ( victim = get_char_room( ch, arg ) ) == NULL
|| ( IS_NPC( victim )
&& victim->in_room != ch->in_room ) || ( !NOT_AUTHED( ch ) && NOT_AUTHED( victim ) && !IS_IMMORTAL( ch ) ) )
{
send_to_char( "They aren't here.\r\n", ch );
return;
}
if( victim == ch )
{
send_to_char( "Do you enjoy talking to yourself?\r\n", ch );
return;
}
if( IS_SET( ch->in_room->room_flags, ROOM_SILENCE ) )
{
send_to_char( "You can't do that here.\r\n", ch );
return;
}
actflags = ch->act;
if( IS_NPC( ch ) )
xREMOVE_BIT( ch->act, ACT_SECRETIVE );
for( vch = ch->in_room->first_person; vch; vch = vch->next_in_room )
{
char *sbuf = argument;
if( vch == ch )
continue;
/*
* Check to see if character is ignoring speaker
*/
if( is_ignoring( vch, ch ) )
{
/*
* continue unless speaker is an immortal
*/
if( !IS_IMMORTAL( ch ) || get_trust( vch ) > get_trust( ch ) )
continue;
else
{
set_char_color( AT_IGNORE, vch );
ch_printf( vch, "You attempt to ignore %s, but" " are unable to do so.\r\n", ch->name );
}
}
#ifndef SCRAMBLE
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( vch, ch->speaking ),
knows_language( ch, ch->speaking ) );
if( speakswell < 75 )
sbuf = translate( speakswell, argument, lang_names[speaking] );
}
#else
if( !knows_language( vch, ch->speaking ) && ( !IS_NPC( ch ) || ch->speaking != 0 ) )
sbuf = scramble( argument, ch->speaking );
#endif
sbuf = drunk_speech( sbuf, ch );
MOBtrigger = FALSE;
}
ch->act = actflags;
MOBtrigger = FALSE;
act( AT_SAY, "You say to $N '$t'", ch, drunk_speech( argument, ch ), victim, TO_CHAR );
act( AT_SAY, "$n says to $N '$t'", ch, drunk_speech( argument, ch ), victim, TO_NOTVICT );
act( AT_SAY, "$n says to you '$t'", ch, drunk_speech( argument, ch ), victim, TO_VICT );
/*
* act( AT_SAY, "$n say$% to $O '$t'", ch, drunk_speech( argument, ch ), victim, TO_ALL );
*/
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf, "%s: %s", IS_NPC( ch ) ? ch->short_descr : ch->name, argument );
append_to_file( LOG_FILE, buf );
}
mprog_speech_trigger( argument, ch );
if( char_died( ch ) )
return;
oprog_speech_trigger( argument, ch );
if( char_died( ch ) )
return;
rprog_speech_trigger( argument, ch );
return;
}
void do_whisper( CHAR_DATA * ch, char *argument )
{
char arg[MAX_INPUT_LENGTH];
char buf[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
int position;
int speaking = -1, lang;
#ifndef SCRAMBLE
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
REMOVE_BIT( ch->deaf, CHANNEL_WHISPER );
argument = one_argument( argument, arg );
if( arg[0] == '\0' || argument[0] == '\0' )
{
send_to_char( "Whisper to whom what?\r\n", ch );
return;
}
if( ( victim = get_char_room( ch, arg ) ) == NULL )
{
send_to_char( "They aren't here.\r\n", ch );
return;
}
if( ch == victim )
{
send_to_char( "You have a nice little chat with yourself.\r\n", ch );
return;
}
if( !IS_NPC( victim ) && ( victim->switched ) && !IS_AFFECTED( victim->switched, AFF_POSSESS ) )
{
send_to_char( "That player is switched.\r\n", ch );
return;
}
else if( !IS_NPC( victim ) && ( !victim->desc ) )
{
send_to_char( "That player is link-dead.\r\n", ch );
return;
}
if( !IS_NPC( victim ) && xIS_SET( victim->act, PLR_AFK ) )
{
send_to_char( "That player is away.\r\n", ch );
return;
}
if( IS_SET( victim->deaf, CHANNEL_WHISPER ) && ( !IS_IMMORTAL( ch ) || ( get_trust( ch ) < get_trust( victim ) ) ) )
{
act( AT_PLAIN, "$E has $S whispers turned off.", ch, NULL, victim, TO_CHAR );
return;
}
if( !IS_NPC( victim ) && xIS_SET( victim->act, PLR_SILENCE ) )
send_to_char( "That player is silenced. They will receive your message but can not respond.\r\n", ch );
if( victim->desc /* make sure desc exists first -Thoric */
&& ( victim->desc->connected == CON_EDITING
|| ( victim->desc->connected >= CON_NOTE_TO
&& victim->desc->connected <= CON_NOTE_FINISH ) ) && get_trust( ch ) < LEVEL_GOD )
{
act( AT_PLAIN, "$E is currently in a writing buffer. Please try again in a few minutes.", ch, 0, victim, TO_CHAR );
return;
}
/*
* Check to see if target of tell is ignoring the sender
*/
if( is_ignoring( victim, ch ) )
{
/*
* If the sender is an imm then they cannot be ignored
*/
if( !IS_IMMORTAL( ch ) || get_trust( victim ) > get_trust( ch ) )
{
set_char_color( AT_IGNORE, ch );
ch_printf( ch, "%s is ignoring you.\r\n", victim->name );
return;
}
else
{
set_char_color( AT_IGNORE, victim );
ch_printf( victim, "You attempt to ignore %s, but are unable to do so.\r\n", ch->name );
}
}
/*
* Bug fix by guppy@wavecomputers.net
*/
MOBtrigger = FALSE;
act( AT_WHISPER, "You whisper to $N '$t'", ch, argument, victim, TO_CHAR );
position = victim->position;
victim->position = POS_STANDING;
#ifndef SCRAMBLE
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( victim, ch->speaking ),
knows_language( ch, ch->speaking ) );
if( speakswell < 85 )
{
act( AT_WHISPER, "$n whispers to you '$t'", ch,
translate( speakswell, argument, lang_names[speaking] ), victim, TO_VICT );
#else
if( !knows_language( vch, ch->speaking ) && ( !IS_NPC( ch ) || ch->speaking != 0 ) )
{
act( AT_WHISPER, "$n whispers to you '$t'", ch,
translate( speakswell, argument, lang_names[speaking] ), victim, TO_VICT );
#endif
}
else
act( AT_WHISPER, "$n whispers to you '$t'", ch, argument, victim, TO_VICT );
}
else
act( AT_WHISPER, "$n whispers to you '$t'", ch, argument, victim, TO_VICT );
if( !IS_SET( ch->in_room->room_flags, ROOM_SILENCE ) )
act( AT_WHISPER, "$n whispers something to $N.", ch, argument, victim, TO_NOTVICT );
MOBtrigger = TRUE;
victim->position = position;
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf, "%s: %s (whisper to) %s.",
IS_NPC( ch ) ? ch->short_descr : ch->name, argument, IS_NPC( victim ) ? victim->short_descr : victim->name );
append_to_file( LOG_FILE, buf );
}
mprog_speech_trigger( argument, ch );
return;
}
void do_reply( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH], buf2[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
int position;
#ifndef SCRAMBLE
int speaking = -1, lang;
MOBtrigger = TRUE;
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
if( !IS_IMMORTAL( ch ) )
REMOVE_BIT( ch->deaf, CHANNEL_TELLS );
if( IS_SET( ch->in_room->room_flags, ROOM_SILENCE ) )
{
send_to_char( "You can't do that here.\r\n", ch );
return;
}
if( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_SILENCE ) )
{
send_to_char( "Your message didn't get through.\r\n", ch );
return;
}
if( ( victim = ch->reply ) == NULL )
{
send_to_char( "They aren't here.\r\n", ch );
return;
}
if( !IS_NPC( victim ) && ( victim->switched ) && can_see( ch, victim ) && ( get_trust( ch ) > LEVEL_AVATAR ) )
{
send_to_char( "That player is switched.\r\n", ch );
return;
}
else if( !IS_NPC( victim ) && ( !victim->desc ) )
{
send_to_char( "That player is link-dead.\r\n", ch );
return;
}
if( !IS_NPC( victim ) && xIS_SET( victim->act, PLR_AFK ) )
{
send_to_char( "That player is away, so they may not recieve your message.\r\n", ch );
}
if( IS_SET( victim->deaf, CHANNEL_TELLS ) && ( !IS_IMMORTAL( ch ) || ( get_trust( ch ) <= get_trust( victim ) ) ) )
{
act( AT_PLAIN, "$E has $S tells turned off.", ch, NULL, victim, TO_CHAR );
return;
}
if( ( !IS_IMMORTAL( ch ) && !IS_AWAKE( victim ) )
|| ( !IS_NPC( victim ) && IS_SET( victim->in_room->room_flags, ROOM_SILENCE ) ) )
{
act( AT_PLAIN, "$E can't hear you.", ch, 0, victim, TO_CHAR );
return;
}
if( victim->desc /* make sure desc exists first -Thoric */
&& ( victim->desc->connected == CON_EDITING
|| ( victim->desc->connected >= CON_NOTE_TO
&& victim->desc->connected <= CON_NOTE_FINISH ) ) && get_trust( ch ) < LEVEL_GOD )
{
act( AT_PLAIN, "$E is currently in a writing buffer. Please try again in a few minutes.", ch, 0, victim, TO_CHAR );
return;
}
/*
* Check to see if the receiver is ignoring the sender
*/
if( is_ignoring( victim, ch ) )
{
/*
* If the sender is an imm they cannot be ignored
*/
if( !IS_IMMORTAL( ch ) || get_trust( victim ) > get_trust( ch ) )
{
set_char_color( AT_IGNORE, ch );
ch_printf( ch, "%s is ignoring you.\r\n", victim->name );
return;
}
else
{
set_char_color( AT_IGNORE, victim );
ch_printf( victim, "You attempt to ignore %s, but " "are unable to do so.\r\n", ch->name );
}
}
/*
* Bug fix by guppy@wavecomputers.net
*/
MOBtrigger = FALSE;
act( AT_TELL, "You tell $N '$t'", ch, argument, victim, TO_CHAR );
position = victim->position;
victim->position = POS_STANDING;
#ifndef SCRAMBLE
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( victim, ch->speaking ),
knows_language( ch, ch->speaking ) );
if( speakswell < 85 )
{
MOBtrigger = FALSE;
act( AT_TELL, "$n tells you '$t'", ch, translate( speakswell, argument, lang_names[speaking] ), victim, TO_VICT );
}
else
act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
}
else
act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
#else
if( knows_language( victim, ch->speaking ) || ( IS_NPC( ch ) && !ch->speaking ) )
act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
else
act( AT_TELL, "$n tells you '$t'", ch, scramble( argument, ch->speaking ), victim, TO_VICT );
#endif
MOBtrigger = TRUE;
mprog_speech_trigger( argument, ch );
sprintf( buf2, "&R%s told you &r'&R%s&r'&w", capitalize( IS_NPC( ch ) ? ch->short_descr : ch->name ), argument );
StoreTell( victim, buf2 );
victim->position = position;
victim->reply = ch;
ch->retell = victim;
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf, "%s: %s (reply to) %s.",
IS_NPC( ch ) ? ch->short_descr : ch->name, argument, IS_NPC( victim ) ? victim->short_descr : victim->name );
append_to_file( LOG_FILE, buf );
}
if( !IS_NPC( victim ) && IS_IMMORTAL( victim ) && victim->pcdata->tell_history &&
isalpha( IS_NPC( ch ) ? ch->short_descr[0] : ch->name[0] ) )
{
sprintf( buf, "%s told you '%s'\r\n", capitalize( IS_NPC( ch ) ? ch->short_descr : ch->name ), argument );
/*
* get lasttell index... assumes names begin with characters
*/
victim->pcdata->lt_index = tolower( IS_NPC( ch ) ? ch->short_descr[0] : ch->name[0] ) - 'a';
/*
* get rid of old messages
*/
if( victim->pcdata->tell_history[victim->pcdata->lt_index] )
STRFREE( victim->pcdata->tell_history[victim->pcdata->lt_index] );
/*
* store the new message
*/
victim->pcdata->tell_history[victim->pcdata->lt_index] = STRALLOC( buf );
}
return;
}
void do_retell( CHAR_DATA * ch, char *argument )
{
char buf[MAX_INPUT_LENGTH];
CHAR_DATA *victim;
int position;
CHAR_DATA *switched_victim = NULL;
#ifndef SCRAMBLE
int speaking = -1, lang;
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
if( !IS_IMMORTAL( ch ) )
REMOVE_BIT( ch->deaf, CHANNEL_TELLS );
if( IS_SET( ch->in_room->room_flags, ROOM_SILENCE ) )
{
send_to_char( "You can't do that here.\r\n", ch );
return;
}
if( !IS_NPC( ch ) && ( xIS_SET( ch->act, PLR_SILENCE ) || xIS_SET( ch->act, PLR_NO_TELL ) ) )
{
send_to_char( "You can't do that.\r\n", ch );
return;
}
if( argument[0] == '\0' )
{
ch_printf( ch, "What message do you wish to send?\r\n" );
return;
}
victim = ch->retell;
if( !victim )
{
send_to_char( "They aren't here.\r\n", ch );
return;
}
if( !IS_NPC( victim ) && ( victim->switched ) &&
( get_trust( ch ) > LEVEL_AVATAR ) && !IS_AFFECTED( victim->switched, AFF_POSSESS ) )
{
send_to_char( "That player is switched.\r\n", ch );
return;
}
else if( !IS_NPC( victim ) && ( victim->switched ) && IS_AFFECTED( victim->switched, AFF_POSSESS ) )
{
switched_victim = victim->switched;
}
else if( !IS_NPC( victim ) && ( !victim->desc ) )
{
send_to_char( "That player is link-dead.\r\n", ch );
return;
}
if( !IS_NPC( victim ) && xIS_SET( victim->act, PLR_AFK ) )
{
send_to_char( "That player is away.\r\n", ch );
return;
}
if( IS_SET( victim->deaf, CHANNEL_TELLS ) && ( !IS_IMMORTAL( ch ) || ( get_trust( ch ) < get_trust( victim ) ) ) )
{
act( AT_PLAIN, "$E has $S tells turned off.", ch, NULL, victim, TO_CHAR );
return;
}
if( !IS_NPC( victim ) && xIS_SET( victim->act, PLR_SILENCE ) )
send_to_char( "That player is silenced. They will receive your message, but can not respond.\r\n", ch );
if( ( !IS_IMMORTAL( ch ) && !IS_AWAKE( victim ) ) ||
( !IS_NPC( victim ) && IS_SET( victim->in_room->room_flags, ROOM_SILENCE ) ) )
{
act( AT_PLAIN, "$E can't hear you.", ch, 0, victim, TO_CHAR );
return;
}
if( victim->desc
&& ( victim->desc->connected == CON_EDITING
|| ( victim->desc->connected >= CON_NOTE_TO
&& victim->desc->connected <= CON_NOTE_FINISH ) ) && get_trust( ch ) < LEVEL_GOD )
{
act( AT_PLAIN, "$E is currently in a writing buffer. Please " "try again in a few minutes.", ch, 0, victim, TO_CHAR );
return;
}
/*
* check to see if the target is ignoring the sender
*/
if( is_ignoring( victim, ch ) )
{
/*
* if the sender is an imm then they cannot be ignored
*/
if( !IS_IMMORTAL( ch ) || get_trust( victim ) > get_trust( ch ) )
{
set_char_color( AT_IGNORE, ch );
ch_printf( ch, "%s is ignoring you.\r\n", victim->name );
return;
}
else
{
set_char_color( AT_IGNORE, victim );
ch_printf( victim, "You attempy to ignore %s, but " "are unable to do so.\r\n", ch->name );
}
}
/*
* store tell history for victim
*/
if( !IS_NPC( victim ) && IS_IMMORTAL( victim ) && victim->pcdata->tell_history &&
isalpha( IS_NPC( ch ) ? ch->short_descr[0] : ch->name[0] ) )
{
sprintf( buf, "%s told you '%s'\r\n", capitalize( IS_NPC( ch ) ? ch->short_descr : ch->name ), argument );
/*
* get lasttel index... assumes names begin with chars
*/
victim->pcdata->lt_index = tolower( IS_NPC( ch ) ? ch->short_descr[0] : ch->name[0] ) - 'a';
/*
* get rid of old messages
*/
if( victim->pcdata->tell_history[victim->pcdata->lt_index] )
STRFREE( victim->pcdata->tell_history[victim->pcdata->lt_index] );
/*
* store the new messagec
*/
victim->pcdata->tell_history[victim->pcdata->lt_index] = STRALLOC( buf );
}
if( switched_victim )
victim = switched_victim;
/*
* Bug fix by guppy@wavecomputers.net
*/
MOBtrigger = FALSE;
act( AT_TELL, "You tell $N '$t'", ch, argument, victim, TO_CHAR );
position = victim->position;
victim->position = POS_STANDING;
#ifndef SCRAMBLE
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( victim, ch->speaking ),
knows_language( ch, ch->speaking ) );
if( speakswell < 85 )
{
MOBtrigger = FALSE;
act( AT_TELL, "$n tells you '$t'", ch, translate( speakswell, argument, lang_names[speaking] ), victim, TO_VICT );
}
else
act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
}
else
act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
#else
if( knows_language( victim, ch->speaking ) || ( IS_NPC( ch ) && !ch->speaking ) )
{
act( AT_TELL, "$n tells you '$t'", ch, argument, victim, TO_VICT );
}
else
{
act( AT_TELL, "$n tells you '$t'", ch, scramble( argument, ch->speaking ), victim, TO_VICT );
}
#endif
victim->position = position;
victim->reply = ch;
MOBtrigger = TRUE;
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf, "%s: %s (retell to) %s.",
IS_NPC( ch ) ? ch->short_descr : ch->name, argument, IS_NPC( victim ) ? victim->short_descr : victim->name );
append_to_file( LOG_FILE, buf );
}
mprog_speech_trigger( argument, ch );
return;
}
void do_repeat( CHAR_DATA * ch, char *argument )
{
int tindex;
if( IS_NPC( ch ) || !IS_IMMORTAL( ch ) || !ch->pcdata->tell_history )
{
no_find( ch );
return;
}
if( argument[0] == '\0' )
{
tindex = ch->pcdata->lt_index;
}
else if( isalpha( argument[0] ) && argument[1] == '\0' )
{
tindex = tolower( argument[0] ) - 'a';
}
else
{
send_to_char( "You may only index your tell history using a single letter.\r\n", ch );
return;
}
if( ch->pcdata->tell_history[tindex] )
{
set_char_color( AT_TELL, ch );
send_to_char( ch->pcdata->tell_history[tindex], ch );
}
else
{
send_to_char( "No one like that has sent you a tell.\r\n", ch );
}
return;
}
void do_emote( CHAR_DATA * ch, char *argument )
{
char buf[MAX_STRING_LENGTH];
char *plast;
CHAR_DATA *vch;
EXT_BV actflags;
#ifndef SCRAMBLE
int speaking = -1, lang;
for( lang = 0; lang_array[lang] != LANG_UNKNOWN; lang++ )
if( ch->speaking & lang_array[lang] )
{
speaking = lang;
break;
}
#endif
if( !IS_NPC( ch ) && xIS_SET( ch->act, PLR_NO_EMOTE ) )
{
send_to_char( "You can't show your emotions.\r\n", ch );
return;
}
if( argument[0] == '\0' )
{
send_to_char( "Emote what?\r\n", ch );
return;
}
actflags = ch->act;
if( IS_NPC( ch ) )
xREMOVE_BIT( ch->act, ACT_SECRETIVE );
for( plast = argument; *plast != '\0'; plast++ )
;
strcpy( buf, argument );
if( isalpha( plast[-1] ) )
strcat( buf, "." );
for( vch = ch->in_room->first_person; vch; vch = vch->next_in_room )
{
char *sbuf = buf;
/*
* Check to see if character is ignoring emoter
*/
if( is_ignoring( vch, ch ) )
{
/*
* continue unless emoter is an immortal
*/
if( !IS_IMMORTAL( ch ) || get_trust( vch ) > get_trust( ch ) )
continue;
else
{
set_char_color( AT_IGNORE, vch );
ch_printf( vch, "You attempt to ignore %s, but" " are unable to do so.\r\n", ch->name );
}
}
#ifndef SCRAMBLE
if( speaking != -1 && ( !IS_NPC( ch ) || ch->speaking ) )
{
int speakswell = UMIN( knows_language( vch, ch->speaking ),
knows_language( ch, ch->speaking ) );
if( speakswell < 85 )
sbuf = translate( speakswell, argument, lang_names[speaking] );
}
#else
if( !knows_language( vch, ch->speaking ) && ( !IS_NPC( ch ) && ch->speaking != 0 ) )
sbuf = scramble( buf, ch->speaking );
#endif
MOBtrigger = FALSE;
act( AT_SOCIAL, "$n $t", ch, sbuf, vch, ( vch == ch ? TO_CHAR : TO_VICT ) );
}
/*
* MOBtrigger = FALSE;
* act( AT_ACTION, "$n $T", ch, NULL, buf, TO_ROOM );
* MOBtrigger = FALSE;
* act( AT_ACTION, "$n $T", ch, NULL, buf, TO_CHAR );
*/
ch->act = actflags;
if( IS_SET( ch->in_room->room_flags, ROOM_LOGSPEECH ) )
{
sprintf( buf, "%s %s (emote)", IS_NPC( ch ) ? ch->short_descr : ch->name, argument );
append_to_file( LOG_FILE, buf );
}
return;
}