/**********************************************************
*************** S U N D E R M U D *** 2 . 0 **************
**********************************************************
* The unique portions of the SunderMud code as well as *
* the integration efforts for code from other sources is *
* based primarily on the efforts of: *
* *
* Lotherius <aelfwyne@operamail.com> (Alvin W. Brinson) *
* and many others, see "help sundermud" in the mud. *
**********************************************************/
/* channels.c
* Zeran - major cleanup of the channel code resides in this file.
* Adding a channel can be done by simply adding an entry
* into channel_table and calling channel_message from
* the parent function (ie, do_gossip, do_say, do_foo etc)
*/
#include "everything.h"
/* local functions */
int channel_lookup ( char *argument );
/* Zeran - channel structure and declaration */
struct channel_type
{
char *name;
char *pre_str_speaker;
char *pre_str_receiver;
char *format_str;
bool use_language;
bool use_drunk;
bool check_nochannel;
bool check_quiet;
bool mob_trigger;
int pos;
int min_level;
int channel_id;
long chan_flag;
};
struct channel_type channel_table[] =
{
/* { "name", "pre_str_speaker", "pre_str_receiver", "format",
language, drunk, nochannel, quiet,
mob_trigger, pos, min_level, channel_id, channel_flag
},
*/
{"gossip", "{cYou gossip", "{c$n gossips", "'{C$t{c'{x",
FALSE, FALSE, TRUE, TRUE,
FALSE, POS_SLEEPING, 1, CHAN_GOSSIP, COMM_NOGOSSIP
},
{"auction", "{yYou auction", "{y$n auctions", "'{Y$t{y'{x",
FALSE, FALSE, TRUE, TRUE,
FALSE, POS_SLEEPING, 1, CHAN_AUCTION, COMM_NOAUCTION
},
{"music", "{mYou sing", "{m$n sings", "'{M$t{m'{x",
FALSE, FALSE, TRUE, TRUE,
FALSE, POS_DEAD, 1, CHAN_MUSIC, COMM_NOMUSIC
},
{"question", "{gYou question", "{g$n questions", "'{G$t{g'{x",
FALSE, FALSE, TRUE, TRUE,
FALSE, POS_DEAD, 1, CHAN_QUESTION, COMM_NOQUESTION
},
{"answer", "{gYou answer", "{g$n answers", "'{G$t{g'{x",
FALSE, FALSE, TRUE, TRUE,
FALSE, POS_DEAD, 1, CHAN_ANSWER, COMM_NOQUESTION
},
{"shout", "{xYou shout", "{x$n shouts", "'{x$t{x'{x",
FALSE, FALSE, TRUE, TRUE,
FALSE, POS_RESTING, 1, CHAN_SHOUT, COMM_DEAF
},
{"yell", "{xYou yell", "{x$n yells", "'{x$t{x'{x",
FALSE, FALSE, TRUE, TRUE,
FALSE, POS_RESTING, 1, CHAN_YELL, 0
},
{"immtalk", "{c[{Y$n{c]:", "{c[{Y$n{c]:", "{c$t{x",
FALSE, FALSE, FALSE, TRUE,
FALSE, POS_DEAD, LEVEL_HERO, CHAN_IMMTALK, 0
},
{"imptalk", "[{rI{gM{bP{x] [{Y$n{x]:",
"[{rI{gM{bP{x] [{Y$n{x]:", "{Y$t{x",
FALSE, FALSE, FALSE, FALSE,
FALSE, POS_DEAD, MAX_LEVEL, CHAN_IMPTALK, 0
},
{"say", "{gYou say", "{g$n says", "'{G$t{g'{x",
TRUE, TRUE, FALSE, FALSE,
TRUE, POS_RESTING, 1, CHAN_SAY, 0
},
{"clantalk", "{rYou tell the clan", "{r$n tells the clan",
"'{R$t{r'{x",
FALSE, FALSE, TRUE, TRUE,
FALSE, POS_SLEEPING, 1, CHAN_CLAN, COMM_NOCLANTELL
},
{"", "", "", "", FALSE, FALSE, FALSE, FALSE, FALSE, 0, 0, 0}
};
void channel_message ( CHAR_DATA * ch, char *argument, char *channel )
{
DESCRIPTOR_DATA *d;
char buf_to_speaker[MAX_STRING_LENGTH];
char buf_to_receiver[MAX_STRING_LENGTH];
char lang_name[MAX_STRING_LENGTH];
char *pre_str_speaker;
char *pre_str_receiver;
char *format_str;
char *outbuf = NULL;
char tmpbuf[MAX_STRING_LENGTH];
bool use_language;
bool use_drunk_speech;
bool do_mob_trigger;
bool check_quiet;
bool check_nochannel;
int pos;
int lang_skill = 0;
int channel_no = -1;
int channel_id;
int chan_flag;
int min_level;
tmpbuf[0] = '\0';
channel_no = channel_lookup ( channel );
if ( channel_no == -1 )
{
bugf ( "Invalid channel [%s] in channel_message", channel );
return;
}
/* Ok, get the values from the channel table that we need */
pre_str_speaker = channel_table[channel_no].pre_str_speaker;
pre_str_receiver = channel_table[channel_no].pre_str_receiver;
format_str = channel_table[channel_no].format_str;
use_language = channel_table[channel_no].use_language;
use_drunk_speech = channel_table[channel_no].use_drunk;
check_quiet = channel_table[channel_no].check_quiet;
check_nochannel = channel_table[channel_no].check_nochannel;
do_mob_trigger = channel_table[channel_no].mob_trigger;
min_level = channel_table[channel_no].min_level;
pos = channel_table[channel_no].pos;
channel_id = channel_table[channel_no].channel_id;
chan_flag = channel_table[channel_no].chan_flag;
/* Check quiet and nochannel settings */
if ( check_quiet && IS_SET ( ch->comm, COMM_QUIET ) )
{
send_to_char ( "You must turn off quiet mode first.\n\r", ch );
return;
}
if ( check_quiet && IS_SET ( ch->comm, COMM_NOCHANNELS ) )
{
send_to_char ( "The gods have revoked your channel priviliges.\n\r", ch );
return;
}
// Imms like to make ppl noshout, this isn't checked elsewhere.
if ( channel_id == CHAN_SHOUT && IS_SET ( ch->comm, COMM_NOSHOUT ) )
{
send_to_char ( "You find your voice very scratchy, and can't shout. Odd, that.\n\r", ch );
return;
}
// Hey Z why didn't you just move this here instead of also having it in 40 diff places?
if ( argument[0] == '\0' && chan_flag != 0 )
{
if ( IS_SET ( ch->comm, chan_flag ) )
{
form_to_char ( ch, "%s is now ON.\n\r",
capitalize ( channel_table[channel_no].name ) );
REMOVE_BIT ( ch->comm, chan_flag);
}
else
{
form_to_char ( ch, "%s is now OFF.\n\r",
capitalize ( channel_table[channel_no].name ) );
SET_BIT ( ch->comm, chan_flag );
}
return;
}
if ( !IS_NPC ( ch ) ) // Make sure channel is on for the speaker.
REMOVE_BIT ( ch->comm, chan_flag );
/* Build message to speaker */
if ( use_language )
{
if ( !IS_NPC ( ch ) )
SNP ( lang_name, "%s tongue", ch->speaking );
else
SNP ( lang_name, "common tongue" );
SNP ( buf_to_speaker, "%s in %s %s",
pre_str_speaker, lang_name, format_str );
}
else
SNP ( buf_to_speaker, "%s %s",
pre_str_speaker, format_str );
/* Send message to speaker */
act_new ( buf_to_speaker, ch, argument, NULL, TO_CHAR, POS_DEAD );
/* Build message to receivers */
/* Scramble for language if speaker is NOT NPC */
if ( use_language )
{
lang_skill = skill_lookup ( lang_name );
if ( !IS_NPC ( ch ) )
argument = scramble ( argument, ch->pcdata->learned[lang_skill] );
SNP ( buf_to_receiver, "%s in %s %s", pre_str_receiver,
lang_name, format_str );
}
else
SNP ( buf_to_receiver, "%s %s",
pre_str_receiver, format_str );
/* Set outbuf to point to argument */
SLCPY ( tmpbuf, argument );
/* Ok, send the messages */
for ( d = descriptor_list; d != NULL; d = d->next )
{
CHAR_DATA *victim;
if ( d->connected != CON_PLAYING || d->connected >= CON_NOTE_TO )
continue;
/* You would not believe how hard the bug that led to the above two lines */
/* was to track down. */
victim = d->original ? d->original : d->character;
/* Check for something freaky - Lotherius */
/* This was for some obscure bug I finally axxed, I think. Leaving it here in case it shows back up. */
if (!victim)
{
send_to_char (":1: We were about to crash! Aborted instead. Report to imms.\n\r", ch);
bugf ( "Null victim in channel_message found." );
return;
}
/* List of checks to skip current receiver */
if ( d->character != ch )
{
/* Check quiet */
if ( check_quiet && IS_SET ( victim->comm, COMM_QUIET ) )
continue;
/* Check minimum level */
if ( get_trust ( victim ) < min_level && victim->level < min_level )
continue;
/* Channel dependent exclusions */
switch ( channel_id )
{
case CHAN_GOSSIP:
{
if ( IS_SET ( victim->comm, COMM_NOGOSSIP ) )
continue;
break;
}
case CHAN_MUSIC:
{
if ( IS_SET ( victim->comm, COMM_NOMUSIC ) )
continue;
break;
}
case CHAN_AUCTION:
{
if ( IS_SET ( victim->comm, COMM_NOAUCTION ) )
continue;
break;
}
case CHAN_QUESTION:
{
if ( IS_SET ( victim->comm, COMM_NOQUESTION ) )
continue;
break;
}
case CHAN_ANSWER:
{
if ( IS_SET ( victim->comm, COMM_NOQUESTION ) )
continue;
break;
}
case CHAN_IMMTALK:
{
if ( IS_SET ( victim->comm, COMM_NOWIZ ) )
continue;
break;
}
case CHAN_IMPTALK:
{
break;
}
case CHAN_YELL:
{
if ( victim->in_room->area != ch->in_room->area )
continue;
break;
}
case CHAN_SHOUT:
{
if ( IS_SET ( victim->comm, COMM_DEAF ) )
continue;
break;
}
case CHAN_SAY:
{
if ( victim->in_room && ( victim->in_room != ch->in_room ) )
continue;
break;
}
case CHAN_CLAN:
{
if ( IS_SET ( victim->comm, COMM_NOCLANTELL ) )
continue;
if ( !is_same_clan(victim, ch) )
continue;
break;
}
default:
{
bugf( "Invalid channel_id [%d] in channel_message", channel_id );
return;
}
}
/* end switch */
}
/* end if */
/* Check for something freaky */
if (!victim)
{
send_to_char (":2: We were about to crash! Aborted instead. Report to imms.\n\r", ch);
continue;
}
/* Check language and drunk, then send the message */
if ( (!IS_NPC (victim) ) && (use_language) )
outbuf = scramble ( tmpbuf, victim->pcdata->learned[lang_skill] );
else
outbuf = tmpbuf;
if ( ( use_drunk_speech ) && (!IS_NPC (victim) ) )
outbuf = drunk_speech ( outbuf, ch );
act_new ( buf_to_receiver, ch, outbuf, d->character, TO_VICT, pos );
}
/* end for descriptor loop */
// Moved this elsewhere... I think... -- Lotherius
// if ( do_mob_trigger )
// mprog_speech_trigger ( argument, ch );
}
/* end channel_message */
void do_channels ( CHAR_DATA * ch, char *argument )
{
/* lists all channels and their status */
send_to_char ("Use the new \"config\" command.\n\r", ch);
return;
}
int channel_lookup ( char *argument )
{
int count = 0;
while ( channel_table[count].name[0] != '\0' )
{
if ( !str_cmp ( channel_table[count].name, argument ) )
return count;
count++;
}
return -1;
}