#include "sys/types.h"
#include <ctype.h>
#include "stdio.h"
#include "define.h"
#include "struct.h"
int max_language = MAX_LANGUAGE-LANG_PRIMAL;
flag_data lang_flags = { "Languages", &skill_table[LANG_PRIMAL].name,
&skill_table[LANG_PRIMAL+1].name, &max_language };
/*
* LOCAL FUNCTIONS
*/
const char* say_verb ( char_data*, char_data* );
void say_routine ( char_data*, char*, int );
void add_tell ( tell_data*&, const char*, const char*,
int = -1 );
void display ( tell_data*&, char_data*, char*,
char_data* = NULL );
void garble_string ( char*, char*, int );
void tell_message ( char_data*, char*, char_data*, int = 0 );
path_func hear_yell;
tell_data* ooc_history = NULL;
tell_data* atalk_history = NULL;
/*
* TELL CLASS AND SUPPORT ROUTINES
*/
Tell_Data :: Tell_Data( const char* pers, const char* txt,
int tongue )
{
record_new( sizeof( tell_data ), MEM_TELL );
name = alloc_string( pers, MEM_TELL );
message = alloc_string( txt, MEM_TELL );
language = tongue;
*name = toupper( *name );
next = NULL;
}
Tell_Data :: ~Tell_Data( )
{
record_delete( sizeof( tell_data ), MEM_TELL );
free_string( name, MEM_TELL );
free_string( message, MEM_TELL );
}
void display( tell_data*& list, char_data* ch, char* text,
char_data* victim )
{
char tmp [ MAX_STRING_LENGTH ];
int i;
tell_data* tell;
if( list == NULL ) {
if( &list == &ooc_history ) {
send( ch, "There have been no OOC's since the mud was started.\n\r" );
}
else if( victim == NULL || victim == ch ) {
send( ch, "You haven't heard any %s since logging in.\n\r", text );
}
else {
send( ch, "%s hasn't heard any %s since logging in.\n\r",
victim, text );
}
return;
}
sprintf( tmp, "--- " );
for( i = 0; i < int( strlen( text ) ); i++ )
tmp[i+4] = toupper( text[i] );
sprintf( &tmp[ strlen( text )+4 ], " ---" );
page_centered( ch, tmp );
for( tell = list; tell != NULL; tell = tell->next ) {
if( tell->language != -1 )
sprintf( tmp, "[%s >> %s]\n\r%s%s", tell->name,
skill_table[tell->language].name, tell->message,
tell->next == NULL ? "" : "\n\r" );
else
sprintf( tmp, "[%s]\n\r%s%s", tell->name,
tell->message, tell->next == NULL ? "" : "\n\r" );
page( ch, tmp );
}
return;
}
void add_tell( tell_data*& list, const char* pers, const char* message,
int language )
{
tell_data* tell;
tell = new tell_data( pers, message, language );
append( list, tell );
if( count( list ) > 10 ) {
tell = list;
list = tell->next;
delete tell;
}
return;
}
/*
* LANGUAGE ROUTINES
*/
void do_language( char_data *ch, char *argument )
{
int i;
if( is_confused_pet( ch ) || ch->pcdata == NULL )
return;
if( ch->pcdata->speaking < LANG_PRIMAL
|| ch->pcdata->speaking >= MAX_LANGUAGE )
ch->pcdata->speaking = LANG_PRIMAL;
if( *argument == '\0' ) {
send( ch, "You are currently speaking %s.\n\rType 'lang <lang\
name>' to switch to another language.\n\r",
skill_table[ch->pcdata->speaking].name );
return;
}
for( i = LANG_PRIMAL; i < MAX_LANGUAGE; i++ )
if( fmatches( argument, skill_table[i].name ) ) {
if( i == LANG_PRIMAL && ch->shdata->level < LEVEL_APPRENTICE ) {
send( ch, "Only immortals can speak in Primal.\n\r" );
return;
}
if( ch->shdata->skill[i] == UNLEARNT
&& !is_set( ch->affected_by, AFF_TONGUES ) ) {
send( ch, "You don't know that language.\n\r" );
return;
}
ch->pcdata->speaking = i;
send( ch, "You will now speak in %s.\n\r", skill_table[i].name );
return;
}
send( ch, "Unknown language.\n\r" );
return;
}
int get_language( char_data* ch, int i )
{
if( i < LANG_PRIMAL || i >= MAX_LANGUAGE )
return 0;
if( ch->pcdata == NULL || is_set( ch->affected_by, AFF_TONGUES ) )
return 10;
return ch->shdata->skill[i];
}
void garble_string( char* output, char* input, int skill )
{
skill = (200-10*skill)*10*skill;
for( ; *input != '\0'; input++, output++ ) {
if( number_range( 0, 10000 ) > skill ) {
if( ispunct( *input ) || isspace( *input ) )
*output = *input;
else if( ( *input > 90 ) && ( *input < 97 ) )
*output = *input-10;
else
*output = number_range( 'a', 'z' );
}
else
*output = *input;
}
*output = '\0';
return;
}
char* slang( char_data* ch, int language )
{
if( !is_set( ch->pcdata->pfile->flags, PLR_LANG_ID ) )
return empty_string;
if( get_language( ch, language ) == 0 )
return " (in an unknown tongue)";
char* tmp = static_string( );
sprintf( tmp, " (in %s)", skill_table[ language ].name );
return tmp;
}
bool munchkin( char_data* ch, char* text )
{
int length = strlen( text );
int punct = 0;
for( int i = 0; i < length; i++ )
if( text[i] == '?' || text[i] == '!' )
punct++;
if( punct > 3 && length/punct < 20 ) {
send( ch, "Excessive punctuation is sure sign that you shouldn't be heard from, please\n\rsurpress your munchkin tendencies.\n\r" );
return TRUE;
}
return FALSE;
}
/*
* CHANNEL SUPPORT ROUTINES
*/
inline bool hear_channels( player_data* pc )
{
return( pc->position != POS_EXTRACTED && ( pc->link == NULL
|| pc->link->connected == CON_PLAYING ) );
}
bool subtract_gsp( player_data* ch, const char* text, int cost )
{
if( get_trust( ch ) < LEVEL_ARCHITECT ) {
if( ch->gossip_pts < cost ) {
send( ch, "%s requires %s gossip point%s.\n\r",
text, number_word( cost ), cost == 1 ? "" : "s" );
return FALSE;
}
ch->gossip_pts -= cost;
}
return TRUE;
}
bool can_talk( char_data* ch, const char* string )
{
if( !is_set( ch->affected_by, AFF_SILENCE ) )
return TRUE;
if( string != NULL )
fsend( ch, "You attempt to %s, but oddly fail to make any noise.",
string );
return FALSE;
}
/*
* STANDARD CHANNELS ROUTINES
*/
void do_ooc( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
player_data* victim;
int max_length;
int length;
if( is_mob( ch ) )
return;
pc = player( ch );
if( *argument == '\0' ) {
display( ooc_history, ch, "OOC CHANNEL" );
return;
}
if( toggle( ch, argument, "OOC channel",
ch->pcdata->pfile->flags, PLR_OOC ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_OOC ) ) {
send( ch, "You have OOC off.\n\r" );
return;
}
if( munchkin( pc, argument ) )
return;
if( !subtract_gsp( pc, "Using OOC", 1 ) )
return;
sprintf( buf, "[OOC] %s:", ch->real_name( ) );
length = strlen( buf );
format_tell( tmp, argument );
max_length = 70-strlen( tmp );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[ length < max_length ] );
for( int i = 0; i < player_list; i++ ) {
victim = player_list[i];
if( hear_channels( victim )
&& is_set( victim->pcdata->pfile->flags, PLR_OOC )
&& !victim->Filtering( ch ) )
send_color( victim, COLOR_OOC, buf );
}
add_tell( ooc_history, ch->real_name( ), tmp );
}
void do_chant( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
int language;
int length;
int max_length;
if( is_mob( ch ) )
return;
pc = player( ch );
if( ch->pcdata->religion == REL_NONE ) {
send( ch, "Only those with a religion can chant.\n\r" );
return;
}
if( *argument == '\0' ) {
display( pc->chant, ch, "Chant" );
return;
}
if( toggle( ch, argument, "Chant",
ch->pcdata->pfile->flags, PLR_CHANT ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_CHANT ) ) {
send( ch, "You have chant turned off.\n\r" );
return;
}
language = ch->pcdata->speaking;
garble_string( buf, argument, get_language( ch, language ) );
format_tell( tmp, buf );
max_length = 70-strlen( tmp );
sprintf( buf, "You chant:%s%s", 7 < max_length ? "" : "\n\r",
&tmp[7 < max_length] );
send( ch, buf );
for( int i = 0; i < player_list; i++ ) {
pc = player_list[i];
if( hear_channels( pc )
&& pc->pcdata->religion == ch->pcdata->religion ) {
add_tell( pc->chant, ch->Seen_Name( pc ), tmp, language );
if( is_set( pc->pcdata->pfile->flags, PLR_CHANT ) ) {
sprintf( buf, "%s chants:", ch->Seen_Name( pc ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( pc, buf );
}
}
}
}
void do_chat( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* victim;
player_data* pc;
int language;
int max_length;
int length;
if( is_mob( ch ) )
return;
pc = player( ch );
if( *argument == '\0' ) {
display( pc->chat, ch, "chats" );
return;
}
if( toggle( ch, argument, "Chat channel",
ch->pcdata->pfile->flags, PLR_CHAT ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_CHAT ) ) {
send( "You have chat turned off.\n\r", ch );
return;
}
if( !subtract_gsp( pc, "Chatting", 1 ) )
return;
language = ch->pcdata->speaking;
garble_string( buf, argument, get_language( ch, language ) );
format_tell( tmp, buf );
max_length = 70-strlen( tmp );
sprintf( buf, "You chat%s:", slang( ch, language ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send_color( ch, COLOR_CHAT, buf );
for( int i = 0; i < player_list; i++ ) {
victim = player_list[i];
if( hear_channels( victim ) && are_allied( ch, victim ) ) {
add_tell( victim->chat, who_name( victim, ch ), tmp, language );
if( victim != ch && victim->link != NULL
&& is_set( victim->pcdata->pfile->flags, PLR_CHAT )
&& !victim->Filtering( ch ) ) {
sprintf( buf, "%s chats%s:", who_name( victim, ch ),
slang( victim, language ) );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send_color( victim, COLOR_CHAT, buf );
}
}
}
return;
}
void do_gossip( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
player_data* victim;
int language;
int max_length;
int length;
if( is_mob( ch ) )
return;
pc = player( ch );
if( *argument == '\0' ) {
display( pc->gossip, ch, "gossips" );
return;
}
if( toggle( ch, argument, "Gossip channel",
ch->pcdata->pfile->flags, PLR_GOSSIP ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_GOSSIP ) ) {
send( "You have gossip turned off.\n\r", ch );
return;
}
if( munchkin( pc, argument ) )
return;
if( !subtract_gsp( pc, "Using gossip", 10 ) )
return;
language = ch->pcdata->speaking;
garble_string( buf, argument, get_language( ch, language ) );
format_tell( tmp, buf );
max_length = 70-strlen( tmp );
sprintf( buf, "You gossip%s:", slang( ch, language ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send_color( ch, COLOR_GOSSIP, buf );
for( int i = 0; i < player_list; i++ ) {
victim = player_list[i];
if( hear_channels( victim ) ) {
add_tell( victim->gossip, who_name( victim, ch ), tmp, language );
if( victim != ch && victim->link != NULL
&& is_set( victim->pcdata->pfile->flags, PLR_GOSSIP )
&& !victim->Filtering( ch ) ) {
sprintf( buf, "%s gossips%s:", who_name( victim, ch ),
slang( victim, language ) );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send_color( victim, COLOR_GOSSIP, buf );
}
}
}
}
void do_atalk( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
player_data* victim;
int max_length;
int length;
if( is_mob( ch ) )
return;
pc = player( ch );
if( *argument == '\0' ) {
display( atalk_history, ch, "AUCTION CHANNEL" );
return;
}
if( toggle( ch, argument, "Auction channel",
ch->pcdata->pfile->flags, PLR_ATALK ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_ATALK ) ) {
send( ch, "You have ATALK off.\n\r" );
return;
}
if( !subtract_gsp( pc, "Using ATALK", 10 ) )
return;
sprintf( buf, "[ATALK] %s:", ch->real_name( ) );
length = strlen( buf );
format_tell( tmp, argument );
max_length = 70-strlen( tmp );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[ length < max_length ] );
for( int i = 0; i < player_list; i++ ) {
victim = player_list[i];
if( hear_channels( victim )
&& is_set( victim->pcdata->pfile->flags, PLR_ATALK )
&& !victim->Filtering( ch ) )
send_color( victim, COLOR_AUCTION, buf );
}
add_tell( atalk_history, ch->real_name( ), tmp );
}
/*
* IMMORTAL CHANNELS
*/
void do_avatar( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
wizard_data* imm = NULL;
int length;
int max_length;
if( *argument == '\0' ) {
imm = (wizard_data*) ch;
display( imm->avatar, ch, "avatar channel" );
return;
}
if( toggle( ch, argument, "Avatar channel",
ch->pcdata->pfile->flags, PLR_AVATAR ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_AVATAR ) ) {
send( "You have the avatar channel turned off.\n\r", ch );
return;
}
format_tell( tmp, argument );
max_length = 70-strlen( tmp );
sprintf( buf, "%s --", ch->real_name( ) );
*buf = toupper( *buf );
length = strlen( buf );
for( int i = 0; i < player_list; i++ ) {
pc = player_list[i];
if( hear_channels( pc ) && ( imm = wizard( pc ) ) != NULL
&& has_permission( imm, PERM_AVATAR_CHAN ) ) {
add_tell( imm->avatar, ch->real_name( ), tmp );
if( is_set( imm->pcdata->pfile->flags, PLR_AVATAR )
&& !imm->Filtering( ch ) ) {
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( imm, buf );
}
}
}
return;
}
void do_buildchan( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
wizard_data* imm = NULL;
int max_length;
int length;
if( *argument == '\0' ) {
imm = (wizard_data*) ch;
display( imm->build_chan, ch, "builder channel" );
return;
}
if( toggle( ch, argument, "Creator channel",
ch->pcdata->pfile->flags, PLR_BUILDCHAN ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_BUILDCHAN ) ) {
send( ch, "You have the creator channel turned off.\n\r" );
return;
}
format_tell( tmp, argument );
max_length = 70-strlen( tmp );
sprintf( buf, "%s:", ch->descr->name );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
for( int i = 0; i < player_list; i++ ) {
pc = player_list[i];
if( hear_channels( pc ) && ( imm = wizard( pc ) ) != NULL
&& has_permission( imm, PERM_BUILD_CHAN ) ) {
add_tell( imm->build_chan, ch->descr->name, tmp, -1 );
if( is_set( imm->pcdata->pfile->flags, PLR_BUILDCHAN ) )
send( buf, imm );
}
}
return;
}
void do_immtalk( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
wizard_data* imm = NULL;
int max_length;
int length;
if( *argument == '\0' ) {
imm = (wizard_data*) ch;
display( imm->imm_talk, ch, "imm_talk" );
return;
}
if( toggle( ch, argument, "Immortal channel",
ch->pcdata->pfile->flags, PLR_IMMCHAN ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_IMMCHAN ) ) {
send( ch, "You have the immortal channel turned off.\n\r" );
return;
}
format_tell( tmp, argument );
max_length = 70-strlen( tmp );
sprintf( buf, "[%s]", ch->descr->name );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
for( int i = 0; i < player_list; i++ ) {
pc = player_list[i];
if( hear_channels( pc ) && ( imm = wizard( pc ) ) != NULL
&& has_permission( imm, PERM_IMM_CHAN ) ) {
add_tell( imm->imm_talk, ch->descr->name, tmp );
if( is_set( imm->pcdata->pfile->flags, PLR_IMMCHAN ) )
send( buf, imm );
}
}
return;
}
void do_god( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
wizard_data* imm = NULL;
int max_length;
int length;
if( *argument == '\0' ) {
imm = (wizard_data*) ch;
display( imm->god_talk, ch, "God Channel" );
return;
}
format_tell( tmp, argument );
max_length = 70-strlen( tmp );
sprintf( buf, "{%s}", ch->descr->name );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
for( int i = 0; i < player_list; i++ ) {
pc = player_list[i];
if( hear_channels( pc ) && ( imm = wizard( pc ) ) != NULL
&& has_permission( imm, PERM_GOD_CHAN ) ) {
add_tell( imm->god_talk, ch->descr->name, tmp );
send( buf, imm );
}
}
return;
}
/*
* YELL ROUTINE
*/
void do_yell( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
char_data* rch;
player_data* pc;
int language;
int max_length;
int length;
if( is_confused_pet( ch ) )
return;
pc = player( ch );
if( *argument == '\0' ) {
if( pc != NULL )
display( pc->yell, ch, "yells" );
return;
}
if( !can_talk( ch, "yell" ) )
return;
if( ch->pcdata != NULL ) {
language = ch->pcdata->speaking;
garble_string( buf, argument, get_language( ch, language ) );
format_tell( tmp, buf );
}
else {
language = LANG_PRIMAL;
format_tell( tmp, argument );
}
max_length = 70-strlen( tmp );
if( ch->pcdata != NULL ) {
sprintf( buf, "You yell%s:", slang( ch, language ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( ch, buf );
}
if( pc != NULL )
add_tell( pc->yell, ch->descr->name, tmp, language );
for( int i = 0; i < *ch->array; i++ )
if( ( rch = character( ch->array->list[i] ) ) != NULL
&& rch != ch )
hear_yell( rch, ch, tmp );
exec_range( ch, 8, hear_yell, tmp );
return;
}
const char* yell_name( char_data* ch, char_data* victim,
int dir, int distance )
{
char* tmp;
if( distance == 0 ) {
if( ch->Seen( victim ) )
return ch->Seen_Name( victim );
else
return "someone nearby";
}
if( distance > 5 )
return "someone far away";
tmp = static_string( );
sprintf( tmp, "someone %s", dir_table[dir].where );
return tmp;
}
void hear_yell( char_data* victim, char_data* ch,
char* message, int dir, int distance )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
int length;
int max_length;
player_data* pc = player( victim );
const char* name;
int language;
if( pc == NULL || !can_hear( victim ) )
return;
name = yell_name( ch, victim, dir, distance );
max_length = 70-strlen( message );
language = ch->pcdata != NULL ? ch->pcdata->speaking : LANG_PRIMAL;
garble_string( tmp, message, get_language( victim, language ) );
add_tell( pc->yell, name, tmp, language );
sprintf( buf, "%s yells%s:", name,
slang( victim, language ) );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( victim, buf );
return;
}
/*
* SAY ROUTINES
*/
void do_say( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
char arg [ MAX_STRING_LENGTH ];
char_data* victim;
player_data* pc = player( ch );
int language;
int length;
int max_length;
if( is_confused_pet( ch ) )
return;
if( *argument == '\0' ) {
if( pc != NULL )
display( pc->say, ch, "says" );
return;
}
if( !can_talk( ch, "speak" ) )
return;
if( ch->pcdata != NULL ) {
language = ch->pcdata->speaking;
garble_string( buf, argument, get_language( ch, language ) );
format_tell( tmp, buf );
}
else {
language = LANG_PRIMAL;
format_tell( tmp, argument );
}
max_length = 70-strlen( tmp );
if( ch->pcdata != NULL ) {
if( is_set( ch->pcdata->pfile->flags, PLR_SAY_REPEAT ) ) {
sprintf( buf, "You %s%s:", say_verb( ch, ch ),
slang( ch, language ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( buf, ch );
}
else
send( ch, "Ok.\n\r" );
if( pc != NULL )
add_tell( pc->say, ch->descr->name, tmp, language );
}
for( int i = 0; i < *ch->array; i++ ) {
if( ( victim = character( ch->array->list[i] ) ) == NULL
|| ch == victim || ( pc = player( victim ) ) == NULL
|| !can_hear( victim ) )
continue;
victim->improve_skill( language );
sprintf( buf, "%s %s%s:", ch->Name( victim ),
say_verb( ch, victim ), slang( victim, language ) );
*buf = toupper( *buf );
length = strlen( buf );
garble_string( arg, tmp, get_language( victim, language ) );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&arg[length < max_length] );
send_color( victim, COLOR_SAYS, buf );
add_tell( pc->say, ch->Name( victim ), arg, language );
}
return;
}
const char* say_verb( char_data* ch, char_data* victim )
{
if( ch->shdata->race == RACE_LIZARD ) {
return( ch == victim ? "hiss" : "hisses" );
}
return( ch == victim ? "say" : "says" );
}
/*
* SHOUT ROUTINE
*/
void do_shout( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
player_data* pc;
player_data* victim;
int length;
int max_length;
if( is_mob( ch ) )
return;
pc = player( ch );
if( *argument == '\0' ) {
display( pc->shout, ch, "shouts" );
return;
}
if( is_set( ch->pcdata->pfile->flags, PLR_NO_SHOUT ) ) {
send( ch, "You have been forbidden from shouting by the gods.\n\r" );
return;
}
if( *argument == '\0' ) {
send( "Shout what?\n\r", ch );
return;
}
if( !subtract_gsp( pc, "Shouting", 500 ) )
return;
format_tell( tmp, argument );
max_length = 70-strlen( tmp );
sprintf( buf, "You shout:%s%s", 10 < max_length ? "" : "\n\r",
&tmp[10 < max_length] );
send( buf, ch );
add_tell( pc->shout, ch->descr->name, tmp, -1 );
for( int i = 0; i < player_list; i++ ) {
victim = player_list[i];
if( victim != ch && hear_channels( victim ) ) {
add_tell( victim->shout, who_name( victim, ch ),tmp, -1 );
sprintf( buf, "%s shouts:", who_name( victim, ch ) );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( victim, buf );
}
}
return;
}
/*
* TELL ROUTINES
*/
void tell_message( char_data* ch, char* msg, char_data* victim, int i )
{
char tmp [ THREE_LINES ];
sprintf( tmp, "++ " );
sprintf( tmp+3, msg, victim->descr->name, i );
strcat( tmp, " ++\n\r\n\r" );
tmp[3] = toupper( tmp[3] );
send( ch, tmp );
}
void process_tell( char_data* ch, char_data* victim, char* argument )
{
char buf [ 3*MAX_STRING_LENGTH ];
char tmp [ 3*MAX_STRING_LENGTH ];
player_data* pc;
int length;
int max_length;
if( ch->pcdata != NULL && victim->pcdata != NULL ) {
if( victim->Filtering( ch ) ) {
fsend( ch, "%s is filtering you - please leave %s in peace.",
victim->descr->name, victim->Him_Her( ) );
return;
}
if( ch->Filtering( victim ) ) {
fsend( ch, "You are filtering %s and only a chebucto would want to\
converse with someone they are filtering.", victim );
return;
}
}
if( ( pc = player( victim ) ) == NULL
&& victim->link != NULL )
pc = victim->link->player;
if( victim->pcdata != NULL ) {
if( victim->link == NULL && pc->switched == NULL )
tell_message( ch, "%s is link dead", victim );
else if( victim->timer+30 < current_time )
tell_message( ch, "%s has been idle for %d seconds",
victim, current_time-victim->timer );
else if( victim->array != ch->array && opponent( victim ) != NULL )
tell_message( ch, "%s is in battle", victim );
}
format_tell( tmp, argument );
max_length = 70-strlen( tmp );
if( ch->pcdata != NULL ) {
if( is_set( ch->pcdata->pfile->flags, PLR_SAY_REPEAT ) ) {
sprintf( buf, "You tell %s:", victim->Seen_Name( ch ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( ch, buf );
}
else
send( ch, "Ok.\n\r" );
}
if( pc == NULL )
return;
sprintf( buf, "%s tells %s:", ch->Seen_Name( victim ),
victim != pc || pc->switched == NULL
? "you" : pc->descr->name );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
if( ch->pcdata == NULL ) {
convert_to_ansi( victim, buf, tmp );
send( victim, tmp );
return;
}
if( !is_set( &victim->status, STAT_REPLY_LOCK ) )
victim->reply = ch;
if( victim == pc && pc->switched != NULL )
victim = pc->switched;
send_color( victim, COLOR_TELLS, buf );
add_tell( pc->tell, ch->Seen_Name( victim ), tmp );
}
void do_tell( char_data *ch, char *argument )
{
char arg [ MAX_STRING_LENGTH ];
char_data* victim;
player_data* pc = player( ch );
if( is_confused_pet( ch ) )
return;
if( *argument == '\0' ) {
if( pc != NULL )
display( pc->tell, ch, "tells" );
return;
}
argument = one_argument( argument, arg );
if( *arg == '\0' || *argument == '\0' ) {
send( ch, "Tell whom what?\n\r" );
return;
}
in_character = FALSE;
if( ( victim = one_character( ch, arg, "tell",
(thing_array*) &player_list ) ) == NULL )
return;
if( ch == victim ) {
send( ch, "Talking to yourself is pointless.\n\r" );
return;
}
if( ch->pcdata != NULL && victim->pcdata != NULL ) {
if( victim->Ignoring( ch ) ) {
fsend( ch, "%s has ignore set to level %d and you cannot tell to %s.",
victim->descr->name,
level_setting( &victim->pcdata->pfile->settings, SET_IGNORE ),
victim->Him_Her( ) );
return;
}
}
process_tell( ch, victim, argument );
}
void do_reply( char_data* ch, char* argument )
{
char* noone_msg = "Noone has told to you or the person who last told\
to you has quit.\n\r";
char_data* victim = ch->reply;
in_character = FALSE;
if( *argument == '\0' ) {
if( ch->reply == NULL ) {
send( ch, "Reply points to noone.\n\r" );
}
else {
send( ch, "Reply %s to %s.\n\r",
is_set( &ch->status, STAT_REPLY_LOCK ) ? "is locked" : "points",
victim->Seen_Name( ch ) );
}
return;
}
if( !strcasecmp( argument, "lock" ) ) {
if( victim == NULL ) {
send( ch, noone_msg );
}
else if( is_set( &ch->status, STAT_REPLY_LOCK ) ) {
send( ch, "Your reply is already locked to %s.\n\r",
victim->Seen_Name( ch ) );
}
else {
set_bit( &ch->status, STAT_REPLY_LOCK );
send( ch, "Reply locked to %s.\n\r", victim->Seen_Name( ch ) );
}
return;
}
if( !strcasecmp( argument, "unlock" ) ) {
if( !is_set( &ch->status, STAT_REPLY_LOCK ) ) {
send( ch, "Your reply is already unlocked.\n\r" );
}
else {
send( ch, "Reply unlocked.\n\r" );
remove_bit( &ch->status, STAT_REPLY_LOCK );
}
return;
}
if( victim == NULL ) {
send( ch, noone_msg );
return;
}
process_tell( ch, victim, argument );
}
/*
* WHISPER/TO
*/
void trigger_say( char_data* ch, char_data* mob, char* argument )
{
mprog_data* mprog;
for( mprog = mob->species->mprog; mprog != NULL; mprog = mprog->next )
if( mprog->trigger == MPROG_TRIGGER_TELL
&& ( is_name( argument, mprog->string )
|| *mprog->string == '\0' ) ) {
var_ch = ch;
var_mob = mob;
var_arg = argument;
var_room = Room( ch->array->where );
execute( mprog );
return;
}
}
void ic_tell( char_data* ch, char* argument, char* verb )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
char arg [ MAX_STRING_LENGTH ];
char_data* victim;
player_data* pc;
int language;
int length;
int max_length;
argument = one_argument( argument, arg );
if( ( victim = one_character( ch, arg, verb,
ch->array ) ) == NULL )
return;
if( *argument == '\0' ) {
send( ch, "%s what to %s?\n\r", verb, victim );
return;
}
if( ch == victim ) {
send( ch, "%sing something to yourself does nothing useful.\n\r",
verb );
return;
}
if( !IS_AWAKE( victim ) ) {
send( ch, "They are not in a state to hear you.\n\r" );
return;
}
/*
fsend_seen( ch, "%s whispers something to %s.\n\r", ch, victim );
*/
if( ch->pcdata != NULL ) {
language = ch->pcdata->speaking;
garble_string( buf, argument, get_language( ch, language ) );
format_tell( tmp, buf );
}
else {
language = LANG_PRIMAL;
format_tell( tmp, argument );
}
max_length = 70-strlen( tmp );
if( ch->pcdata != NULL ) {
if( is_set( ch->pcdata->pfile->flags, PLR_SAY_REPEAT ) ) {
sprintf( buf, "You %s to %s%s:", verb, victim->Name( ch ),
slang( ch, language ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( ch, buf );
}
else
send( ch, "Ok.\n\r" );
}
if( ( pc = player( victim ) ) == NULL ) {
trigger_say( ch, victim, argument );
return;
}
sprintf( buf, "%s %ss to you%s:", ch->Name( victim ),
verb, slang( victim, language ) );
buf[0] = toupper( buf[0] );
length = strlen( buf );
garble_string( arg, tmp, get_language( victim, language ) );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&arg[length < max_length] );
send_color( victim, COLOR_SAYS, buf );
add_tell( pc->whisper, ch->Seen_Name( pc ), arg );
}
void do_to( char_data* ch, char* argument )
{
player_data* pc;
if( is_confused_pet( ch ) )
return;
if( *argument == '\0' ) {
if( ( pc = player( ch ) ) != NULL )
display( pc->to, ch, "To" );
return;
}
ic_tell( ch, argument, "say" );
}
void do_whisper( char_data* ch, char* argument )
{
player_data* pc = player( ch );
if( is_confused_pet( ch ) )
return;
if( *argument == '\0' ) {
if( pc != NULL )
display( pc->whisper, ch, "whispers" );
return;
}
ic_tell( ch, argument, "whisper" );
}
/*
* EMOTE ROUTINE
*/
void do_emote( char_data *ch, char *argument )
{
char_data* rch;
bool space;
if( ch->pcdata != NULL
&& is_set( ch->pcdata->pfile->flags, PLR_NO_EMOTE ) ) {
send( ch, "You can't show your emotions.\n\r" );
return;
}
if( *argument == '\0' ) {
send( ch, "Emote what?\n\r" );
return;
}
space = strncmp( argument, "'s ", 3 ) && strncmp( argument, ", ", 2 );
for( int i = 0; i < *ch->array; i++ ) {
if( ( rch = character( ch->array->list[i] ) ) == NULL
|| rch->position <= POS_SLEEPING )
continue;
fsend( rch, "%s%s%s\n\r",
ch->Name( rch ), space ? " " : "", argument );
}
return;
}
/*
* GROUP TELL
*/
void do_gtell( char_data* ch, char* argument )
{
char tmp [ MAX_STRING_LENGTH ];
char buf [ MAX_STRING_LENGTH ];
char_data* leader;
player_data* pc = player( ch );
int language;
int length;
int max_length;
if( is_mob( ch ) )
return;
if( *argument == '\0' ) {
display( pc->gtell, ch, "group tells" );
return;
}
if( is_set( ch->pcdata->pfile->flags, PLR_NO_TELL ) ) {
send( ch, "You are banned from using tell.\n\r" );
return;
}
if( ( leader = group_leader( ch ) ) == NULL ) {
send( ch, "You aren't in a group.\n\r" );
return;
}
language = ch->pcdata->speaking;
garble_string( buf, argument, get_language( ch, language ) );
format_tell( tmp, buf );
max_length = 70-strlen( tmp );
sprintf( buf, "You tell your group%s:",
slang( ch, language ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send( buf, ch );
for( int i = 0; i < player_list; i++ ) {
pc = player_list[i];
if( pc->position != POS_EXTRACTED && ( pc->link == NULL
|| pc->link->connected == CON_PLAYING )
&& leader == group_leader( pc ) ) {
add_tell( pc->gtell, ch->Seen_Name( pc ), tmp, language );
if( pc != ch && pc->link != NULL ) {
sprintf( buf, "%s tells the group%s:", ch->Seen_Name( pc ),
slang( pc, language ) );
buf[0] = toupper( buf[0] );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send_color( pc, COLOR_GTELL, buf );
}
}
}
return;
}
/*
* CLAN TELL
*/
void do_ctell( char_data* ch, char* argument )
{
char buf [ MAX_STRING_LENGTH ];
char tmp [ MAX_STRING_LENGTH ];
int language;
int max_length;
int length;
player_data* pc = player( ch );
if( is_mob( ch ) )
return;
if( ch->pcdata->pfile->clan == NULL ) {
send( ch, "You aren't in a clan.\n\r" );
return;
}
if( *argument == '\0' ) {
display( pc->ctell, ch, "clan tells" );
return;
}
if( toggle( ch, argument, "Clan channel",
ch->pcdata->pfile->flags, PLR_CTELL ) )
return;
if( !is_set( ch->pcdata->pfile->flags, PLR_CTELL ) ) {
send( ch, "You have ctell turned off.\n\r" );
return;
}
language = ch->pcdata->speaking;
garble_string( buf, argument, get_language( ch, language ) );
format_tell( tmp, buf );
max_length = 70-strlen( tmp );
sprintf( buf, "You tell the clan%s:", slang( ch, language ) );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send_color( ch, COLOR_CTELL, buf );
for( int i = 0; i < player_list; i++ ) {
pc = player_list[i];
if( pc->In_Game( )
&& pc->pcdata->pfile->clan == ch->pcdata->pfile->clan ) {
add_tell( pc->ctell, ch->Seen_Name( pc ), tmp );
if( pc != ch && pc->link != NULL
&& is_set( pc->pcdata->pfile->flags, PLR_CTELL ) ) {
sprintf( buf, "%s ctells%s:", ch->Seen_Name( pc ),
slang( pc, language ) );
*buf = toupper( *buf );
length = strlen( buf );
sprintf( &buf[length], "%s%s", length < max_length ? "" : "\n\r",
&tmp[length < max_length] );
send_color( pc, COLOR_CTELL, buf );
}
}
}
return;
}
/*
* REVIEW COMMAND
*/
void do_review( char_data* ch, char* argument )
{
char arg [ MAX_INPUT_LENGTH ];
player_data* victim;
argument = one_argument( argument, arg );
if( *arg == '\0' ) {
send( ch, "For whom do you wish to review recent conversation?\n\r" );
return;
}
if( ( victim = (player_data*) one_character( ch, arg, "review",
(thing_array*) &player_list ) ) == NULL )
return;
if( ch == victim ) {
send( ch,
"There are simplier ways to review your own conversations.\n\r" );
return;
}
if( get_trust( victim ) >= get_trust( ch ) ) {
send( ch, "You are unable to review %s's conversations.\n\r", victim );
return;
}
if( *argument == '\0' ) {
send( ch, "Which conversation channel do you want to review?\n\r" );
return;
}
if( matches( argument, "say" ) ) {
display( victim->say, ch, "says", victim );
return;
}
if( matches( argument, "tell" ) ) {
display( victim->tell, ch, "tells", victim );
return;
}
send( ch, "Unknown history type - see help review.\n\r" );
return;
}