/**************************************************************************/
// act_comm.cpp - primarily code relating to player communications
/***************************************************************************
* The Dawn of Time v1.69r (c)1997-2004 Michael Garratt *
* >> A number of people have contributed to the Dawn codebase, with the *
* majority of code written by Michael Garratt - www.dawnoftime.org *
* >> To use this source code, you must fully comply with all the licenses *
* in licenses.txt... In particular, you may not remove this copyright *
* notice. *
***************************************************************************
* >> Original Diku Mud copyright (c)1990, 1991 by Sebastian Hammer, *
* Michael Seifert, Hans Henrik St{rfeldt, Tom Madsen, & Katja Nyboe. *
* >> Merc Diku Mud improvements copyright (C) 1992, 1993 by Michael *
* Chastain, Michael Quan, and Mitchell Tse. *
* >> ROM 2.4 is copyright 1993-1995 Russ Taylor and has been brought to *
* you by the ROM consortium: Russ Taylor(rtaylor@pacinfo.com), *
* Gabrielle Taylor(gtaylor@pacinfo.com) & Brian Moore(rom@rom.efn.org) *
* >> Oblivion 1.2 is copyright 1996 Wes Wagner *
**************************************************************************/
#include "include.h" // dawn standard includes
#include "intro.h"
#include "channels.h"
#include "msp.h"
#include "pload.h"
// command procedures needed
DECLARE_DO_FUN(do_quit );
DECLARE_DO_FUN(do_amote );
DECLARE_DO_FUN(do_pmote );
DECLARE_DO_FUN(do_smote );
DECLARE_DO_FUN(do_flee );
void saymote( language_data *language, char_data *ch, char *argument, int sayflags);
void laston_player_deleting(char_data * ch);
void quit_char(char_data *ch, char *argument, bool character_deleting );
char_data* find_innkeeper(char_data* ch);
/**************************************************************************/
void do_delet( char_data *ch, char *)
{
ch->println( "You must type the full command to delete yourself." );
}
/**************************************************************************/
void do_delete( char_data *ch, char *argument)
{
char strsave[MIL];
#ifndef WIN32
char buf[MSL];
#endif
bool remove_pfile = false;
if (IS_NPC(ch))
return;
// Check if they're being ordered to do this
if ( IS_SET( ch->dyn, DYN_IS_BEING_ORDERED ))
{
if ( ch->master )
ch->master->println( "Not going to happen." );
return;
}
if (ch->in_room->vnum==ROOM_VNUM_JAIL)
{
ch->println( "Deleting in this room is not an option, if you really want to be deleted,\r\n"
"send a note to admin asking so, and then logoff." );
return;
}
if (ch->pcdata->confirm_delete)
{
if (argument[0] != '\0')
{
ch->println( "Delete status removed." );
ch->pcdata->confirm_delete = false;
return;
}
else
{
sprintf( strsave, pfilename( ch->name, get_pfiletype(ch)) );
wiznet("$N turns $Mself into line noise.",ch,NULL,0,0,0);
if (ch->level < 5)
remove_pfile = true;
laston_player_deleting(ch); // remove character from laston list
intro_player_delete(ch); // remove them from the intro database
quit_char(ch, "", true); // let character delete
// on dedicated pkill muds, players just use the delete
// command to logout when they have no quit timers...
// so their pfile is not deleted.
if(!GAMESETTING5(GAMESET5_DEDICATED_PKILL_STYLE_MUD))
{
#ifdef WIN32
unlink(strsave); // delete player file
#else
if (remove_pfile)
{
unlink(strsave); // delete player file
}
else // move them to the delete directory
{
sprintf(buf,"mv %s %s &", strsave, DELETE_DIR);
system(buf);
}
#endif
}
return;
}
}
if (argument[0] != '\0')
{
ch->println( "Just type delete. No argument." );
return;
}
ch->println( "Type delete again to confirm this command." );
ch->println( "WARNING: this command is irreversible." );
ch->println( "Typing delete with an argument will undo delete status." );
ch->pcdata->confirm_delete = true;
wiznet("$N is contemplating deletion.",ch,NULL,0,0,get_trust(ch));
}
/**************************************************************************/
// RT code to display channel status
void do_channels( char_data *ch, char *)
{
char buf[MSL];
/* lists all channels and their status */
ch->println( " channel status" );
ch->println( "---------------------" );
ch->printlnf( "`s%-15s%s", "Newbie", HAS_CONFIG(ch, CONFIG_NONEWBIE)?"OFF":"ON");
ch->printlnf( "`c%-15s%s", "OOC", HAS_CHANNELOFF(ch, CHANNEL_OOC)?"OFF":"ON");
ch->printlnf( "`g%-15s%s", "Q/A", HAS_CHANNELOFF(ch, CHANNEL_QA)?"OFF":"ON");
if (IS_IMMORTAL(ch))
{
ch->printlnf( "`G%-15s%s", "Immtalk", HAS_CHANNELOFF(ch, CHANNEL_IMMTALK)?"OFF":"ON");
}
ch->printlnf( "`g%-15s%s`x", "Quiet mode", HAS_CHANNELOFF(ch, CHANNEL_QUIET)?"ON":"OFF");
if (IS_SET(ch->comm,COMM_AFK))
ch->println( "You are AFK." );
if (IS_SET(ch->comm,COMM_SNOOP_PROOF))
ch->println( "You are immune to snooping." );
if (ch->lines != PAGELEN)
{
if (ch->lines){
ch->printlnf( "You display %d lines of scroll.", ch->lines+2 );
}else{
ch->println( "Scroll buffering is off." );
}
}
if (!IS_NULLSTR(ch->prompt))
{
sprintf(buf,"Your current prompt is: %s",ch->prompt);
ch->printlnbw(buf);
}
if (!IS_NULLSTR(ch->olcprompt))
{
sprintf(buf,"Your current olc prompt is: %s",ch->olcprompt);
ch->printlnbw(buf);
}
if (IS_SET(ch->comm,COMM_NOSHOUT))
ch->println( "You cannot yell." );
if (IS_SET(ch->comm,COMM_NOTELL))
ch->println( "You cannot use tell." );
if (IS_SET(ch->comm,COMM_NOCHANNELS))
ch->println( "You cannot use channels." );
if (IS_SET(ch->comm,COMM_NOEMOTE))
ch->println( "You cannot show emotions." );
}
/**************************************************************************/
// quiet blocks out all communication
void do_quiet ( char_data *ch, char *)
{
if (HAS_CHANNELOFF(ch, CHANNEL_QUIET))
{
ch->println( "Quiet mode removed." );
REMOVE_CHANNELOFF(ch, CHANNEL_QUIET);
}
else
{
ch->println( "From now on, you will only hear says and emotes." );
SET_CHANNELOFF(ch, CHANNEL_QUIET);
}
}
// prototype
#if defined(unix)
const char echo_off_str [] = { '\0', '\0', '\0' };
const char echo_on_str [] = { '\0' };
const char go_ahead_str [] = { '\0' };
/*const char echo_off_str [] = { IAC, WILL, TELOPT_ECHO, '\0' };
const char echo_on_str [] = { IAC, WONT, TELOPT_ECHO, '\0' };
const char go_ahead_str [] = { IAC, GA, '\0' };
*/
#endif
/**************************************************************************/
void do_nspeak( char_data *ch, char *argument)
{
// Check if they're being ordered to do this
if ( IS_SET( ch->dyn, DYN_IS_BEING_ORDERED ))
{
if ( ch->master )
ch->master->println( "Not going to happen." );
return;
}
if(IS_NPC(ch) || ch->pcdata->diplomacy==0)
{
ch->println( "You must be a noble to speak." );
return;
}
if (IS_NULLSTR(argument))
{
ch->println( "What do you wish to proclaim?" );
return;
}
ch->printlnf( "`YYou Noble Speak: '%s'`x", argument);
broadcast(ch,"`Y<noble:> '%s`Y'`x\r\n", argument);
}
/**************************************************************************/
// by Kalahn - Sept 98
void do_ntalk( char_data *ch, char *argument )
{
char_data *nch, *victim;
// unswitched mobs can't ooc
if (IS_UNSWITCHED_MOB(ch))
{
ch->println( "Players or switched players only." );
return;
}
// Check if they're being ordered to do this
if ( IS_SET( ch->dyn, DYN_IS_BEING_ORDERED ))
{
if ( ch->master )
ch->master->println( "Not going to happen." );
return;
}
if (IS_NULLSTR(argument) )
{
ch->println( "What do you wish to ntalk?" );
return;
}
if (IS_SET(TRUE_CH(ch)->comm,COMM_NOCHANNELS))
{
ch->println( "The gods have revoked your channel priviliges." );
return;
}
ch->printlnf( "`=NYou ntalk: `=n%s`x", argument);
// log all ntalk to a single file
// Let's see what they say when we're not there :)
{
char logbuf[MSL];
sprintf(logbuf,"%s`x", argument);
append_datetime_ch_to_file( ch, NTALK_LOGFILE, logbuf);
}
for ( nch = player_list; nch; nch = nch->next_player )
{
if (TRUE_CH(ch)==nch){
continue;
}
victim=nch;
// ntalk going thru switch
if (victim->controlling && victim->controlling->desc)
{
victim=victim->controlling;
}
if (IS_NOBLE(nch)){
if (!IS_NOBLE(ch))
{
victim->printlnf( "`=N<%s [not a noble] noble talks>: `=n'%s`=n'`x",
TRUE_CH(ch)->name, argument);
}else{
if (IS_IMMORTAL(nch)){
victim->printlnf( "`=N<%s noble talks>: `=n'%s`=n'`x",
TRUE_CH(ch)->name, argument);
}else{
victim->printlnf( "`=N<noble talk>: `=n'%s`=n'`x", argument);
}
}
}
}
}
/**************************************************************************/
void do_afk ( char_data *ch, char *argument)
{
// unswitched mobs can't be afk
if (IS_UNSWITCHED_MOB(ch)){
ch->println("players only sorry");
return;
}
// Check if they're being ordered to do this
if ( IS_SET( ch->dyn, DYN_IS_BEING_ORDERED )){
if ( ch->master )
ch->master->println( "Not going to happen." );
return;
}
if(!IS_NULLSTR(argument)){
// this makes it so you can change your afk message without turning afk off
REMOVE_BIT(TRUE_CH(ch)->comm,COMM_AFK);
}
if (IS_SET(TRUE_CH(ch)->comm,COMM_AFK)) {
act("$n has returned from being AFK.",ch,NULL,NULL,TO_ROOM);
ch->println( "AFK mode removed. Type 'replay' to see tells." );
REMOVE_BIT(TRUE_CH(ch)->comm,COMM_AFK);
}else{
if(IS_NULLSTR(argument)){
replace_string(TRUE_CH(ch)->pcdata->afk_message, "");
}else{
// idiot checks
if(c_str_len(argument)==-1){
ch->println("You can't have newline colour codes in your afk message");
return;
}
if(c_str_len(argument)>50){
ch->println("Your afk message can't be more than 50 visible characters.");
return;
}
// set their afk away message
replace_string(TRUE_CH(ch)->pcdata->afk_message, argument);
}
if(IS_NULLSTR(argument)){
act("$n just went AFK.",ch,NULL,NULL,TO_ROOM);
ch->println( "You are now in AFK mode.");
}else{
act("$n just went AFK ($t).",ch,argument,NULL,TO_ROOM);
ch->printlnf( "You are now in AFK mode (%s).", argument );
}
SET_BIT(TRUE_CH(ch)->comm,COMM_AFK);
}
}
/**************************************************************************/
void do_requestooc (char_data *ch, char *argument)
{
char_data *victim;
if (!IS_IMMORTAL(ch) && !IS_OOC(ch))
{
ch->println( "You must be in the chat rooms to use requestooc." );
return;
}
if (argument[0]=='\0')
{
ch->println( "Request for whom to go to ooc chat rooms." );
return;
}
if ((victim=get_whovis_player_world(ch, argument))==NULL)
{
ch->println( "They are not playing." );
return;
}
ch->printlnf( "`=OSending ooc chat request to %s.`x", victim->name);
victim->wraplnf("`=O%s has requested that you go to the ooc chat "
"rooms to talk to them.`x", ch->name);
victim->println("`=OYou can get there by typing `=Cgoooc`x." );
}
/**************************************************************************/
void do_pray( char_data *ch, char *argument )
{
char buf[MSL];
if(IS_NULLSTR(argument)){
ch->println( "Pray What?" );
return;
}
ch->printlnf( "`MYou pray to any who would listen: '%s'`x", argument);
// put it on the prayers wiznet channel
if (!IS_SET(ch->comm, COMM_NOPRAY)){
sprintf(buf,"`m%s prays '%s`m' [room %d](%s)`x\r\n",
ch->name, argument, ch->in_room?ch->in_room->vnum:0,
position_table[ch->position].name);
wiznet(buf,NULL,NULL,WIZ_PRAYERS_DREAMS,0,AVATAR);
};
for(char_data *c=player_list; c; c = c->next_player){
if( c != ch && ch->in_room==get_room_index(c->temple))
{
if(!IS_NPC(ch)){
ch->pcdata->did_ic=true;
}
act_new("`M$n prays '$t'`x",ch, argument,c,TO_VICT,POS_DEAD);
}
}
}
/**************************************************************************/
void do_sayto( char_data *ch, char *argument )
{
char arg[MSL], buf[MSL];
char_data *victim;
argument = one_argument(argument,arg);
if (IS_NULLSTR(arg))
{
ch->println( "Sayto whom what?" );
ch->println( "note: you can actually use normal say and put a > symbol \r\n"
"followed by a players name as an abbreviation of say to...\r\n"
"eg `=C '>kal hello `x or `=C say >kalahn hello`x" );
return;
}
victim = get_char_room( ch, arg);
if (!victim)
{
ch->printlnf( "You can't find '%s' to 'sayto'", arg );
return;
}
if (victim==ch)
{
ch->println( "You can't direct sayto at yourself." );
return;
}
sprintf(buf,">%s %s", arg, argument);
saymote( ch->language, ch, buf, 0);
}
/**************************************************************************/
void do_say( char_data *ch, char *argument )
{
int sayflags=0;
if(HAS_CONFIG2(ch,CONFIG2_NOAUTOSAYMOTE)){
SET_BIT(sayflags, SAYFLAG_NO_SAYMOTE);
}
if(HAS_CONFIG2(ch,CONFIG2_AUTOSAYCOLOURCODES)){
SET_BIT(sayflags, SAYFLAG_CONVERT_COLOUR);
}
saymote( ch->language, ch, argument, sayflags);
}
/**************************************************************************/
void do_saymote( char_data *ch, char *argument )
{
saymote( ch->language, ch, argument, 0);
}
/**************************************************************************/
void do_rsay( char_data *ch, char *argument )
{
// Check if they're being ordered to do this
if ( IS_SET( ch->dyn, DYN_IS_BEING_ORDERED ))
{
if ( ch->master )
ch->master->println( "Not going to happen." );
return;
}
if(!IS_NPC(ch)){
if(ch->pcdata->security<1){
ch->println("rsay is for mobprogs only, it is a say seen only to the person who is remembered.");
}else{
ch->println("rsay is for use in mobprogs only, it is short for 'remembered say'.`1"
"A mob must first 'mob remember $n', then 'rsay whatever text' will only be heard by $q.");
return;
}
return;
}
saymote( ch->language, ch, argument, A);
}
/**************************************************************************/
// Kal July99
void do_saycolour(char_data *ch, char *argument)
{
char arg[MSL];
char newcol;
argument = first_arg(argument,arg, false); // first_arg keeps case
if (IS_NULLSTR(arg))
{
ch->println( "`xUse saycolour to set your default colour when talking.");
ch->println( "syntax: saycolour <single color code character>");
ch->println( "e.g. `=Csaycol G`x would make all the words you spoke to be `Ggreen`x");
return;
}
if(str_len(arg)>1)
{
ch->println( "saycolour: You can't have more than a single character for a colour code!");
return;
}
newcol=arg[0];
{// check it is a valid code
char buf[MSL];
sprintf(buf, "`%c", newcol);
if (c_str_len(buf)!=0){
ch->println( "saycolour: You can't have a colour code that is a control code!");
return;
}else{
ch->printlnf("say colour code set to '%c'", newcol);
ch->saycolour=newcol;
}
}
}
/**************************************************************************/
// Kal July99
void do_motecolour(char_data *ch, char *argument)
{
char arg[MSL];
char newcol;
argument = first_arg(argument,arg, false); // first_arg keeps case
if (IS_NULLSTR(arg))
{
ch->println( "`xUse motecolour to set your default colour of motes in saymotes." );
ch->println( "syntax: motecolour <single color code character>" );
ch->println( "e.g. `=Cmotecol G`x would make all the motes in your saymotes to be `Ggreen`x" );
return;
}
if(str_len(arg)>1)
{
ch->println( "motecolour: You can't have more than a single character for a colour code!");
return;
}
newcol=arg[0];
{// check it is a valid code
char buf[MSL];
sprintf(buf, "`%c", newcol);
if (c_str_len(buf)!=0){
ch->println( "motecolour: You can't have a colour code that is a control code!");
return;
}else{
ch->printlnf( "mote colour code set to '%c'", newcol);
ch->motecolour=newcol;
}
}
}
/**************************************************************************/
// Kalahn August 97
void do_whisper( char_data *ch, char *argument )
{
char_data *victim, *overhear;
char target[MIL];
char message[MSL];
// dont allow messages that could be defrauding
if(check_defrauding_argument(ch, argument)){
return;
}
// wiznet whispers NO MOBS
if( !IS_UNSWITCHED_MOB(ch )) {
wiznet(FORMATF("whisper %s: \"%s\"", ch->name, argument),
ch ,NULL,WIZ_WHISPERS,0,get_trust(ch));
}
argument = one_argument( argument, target);
if( IS_NULLSTR(target)){
ch->println( "Whisper to whom?" );
return;
}
if(!str_cmp(target,"all")){
ch->println( "If you are going to tell everyone just use say." );
return;
}
// find the person in the room to whisper them
victim = get_char_room( ch, target);
if(!victim){
ch->printlnf( "You can't find '%s' to whisper to", target);
return;
}
if (victim == ch){
ch->println( "If you start whispering to yourself, people will think you're strange." );
return;
}
if(!IS_AWAKE(victim)){
ch->printlnf( "You had better wake '%s' first.", PERS(victim, ch));
return;
}
argument = ltrim_string(argument);
if(IS_NULLSTR(argument)){
ch->printlnf( "What do you want to whisper to %s?", PERS(victim, ch));
return;
}
// record the whisper as ic or ooc, or maybe both
if(!IS_NPC(ch)){
ch->pcdata->did_ic=true;
if(room_is_private(ch->in_room)){
ch->pcdata->did_ooc=true;
}
}
// go thru all in the room - whispering
// to target, and those who over hear
for ( overhear=ch->in_room->people; overhear; overhear = overhear->next_in_room )
{
if ( overhear == ch || !IS_AWAKE(overhear)){
continue;
}
translate_language(ch->language, true, ch, overhear, argument, message);
// direct it to whoever is necessary
if(overhear == victim){
RECORD_TO_REPLAYROOM=true;
if ( !is_affected( victim, gsn_deafness ) || IS_OOC(victim)) {
act("`x$n whispers to you '$t`x'", ch, message, victim, TO_VICT);
}
act("`xYou whisper '$t`x' to $N`x.", ch, argument, victim,TO_CHAR);
RECORD_TO_REPLAYROOM=false;
continue;
}
if (IS_AWAKE(overhear) && IS_TRUSTED(overhear, INVIS_LEVEL(ch)))
{
// the higher the chance value, the more likely 'overhear' will hear
int chance = 45 - ch->perm_stats[STAT_IN]/3; // approx range 45 -> 75
chance -= ch->modifiers[STAT_IN]/3; // can take it up to > 100
chance += overhear->modifiers[STAT_QU]/4;
chance += overhear->modifiers[STAT_IN]/3;
// awareness helps you overhear
chance += get_skill(overhear,gsn_awareness)/5;
chance-= number_range(1,100);
if (( chance > 0
|| IS_IMMORTAL(overhear)
|| is_affected(overhear, gsn_augment_hearing ))) // overheard
{
if ( IS_OOC(overhear) || !is_affected( overhear, gsn_deafness) ) {
overhear->printlnf("`sYou overhear %s whispering '%s`x' to %s`x.",
PERS(ch, overhear), message, PERS(victim, overhear));
overhear->record_replayroom_event(
FORMATF("`sYou overhear %s whispering '%s`x' to %s`x.",
PERS(ch, overhear), message, PERS(victim, overhear))
);
}
} else if (chance+45 > 0){ // notice but not hear
overhear->printlnf("`xYou notice %s whispering to %s`x.",
PERS(ch, overhear), PERS(victim, overhear));
overhear->record_replayroom_event(
FORMATF("`xYou notice %s whispering to %s`x.",
PERS(ch, overhear), PERS(victim, overhear))
);
}
}
}
return;
}
/**************************************************************************/
// return true if for any reason if the sender can't send a tell
// - this function sends a message to the sender stating the reason
bool tell_cant_send_tell(char_data *ch)
{
// unswitched mobs can't send tells
if (IS_UNSWITCHED_MOB(ch))
{
ch->println( "Uncontrolled mobs can't tell." );
return true;
}
// Check if they're being ordered to do this
if ( IS_SET( ch->dyn, DYN_IS_BEING_ORDERED ))
{
if ( ch->master ){
ch->master->println( "Not going to happen." );
}
ch->println( "You can't be ordered to send tells." );
return true;
}
if(IS_SET(TRUE_CH(ch)->comm, COMM_NOTELL) ){
ch->println( "You arent allowed to send tells currently." );
return true;
}
return false;
}
/**************************************************************************/
void deliver_tell(char_data *ch, char * fmt, ...)
{
assert(!IS_NPC(ch));
char_data *target=ch->controlling?ch->controlling:ch;
char buf[MSL];
va_list args;
va_start (args, fmt);
vsnprintf (buf, MSL, fmt, args);
va_end (args);
char recordbuf[MSL];
sprintf(recordbuf, "%s> %s",
shorttime(NULL),
buf);
replace_string( // record it in their replay buffer
ch->pcdata->replaytell_text[ch->pcdata->next_replaytell],
recordbuf);
++ch->pcdata->next_replaytell%=MAX_REPLAYTELL;
if(HAS_CONFIG(ch, CONFIG_AUTOWRAPTELLS)){
target->wrapln(buf); // send to the character
}else{
target->print(buf); // send to the character
}
}
/**************************************************************************/
enum sendtext_type {ST_TELL, ST_RETELL, ST_REPLY};
/**************************************************************************/
// - Kalahn, Jan 00
void tell_sendtext(char_data *from, char_data *to, char *text, sendtext_type type)
{
assertp(from);
assertp(to);
// get the characters they are connected to
// - so messages can be transperant to switch etc
char_data *sender=from->controlling?from->controlling:from;
if(IS_NPC(from) || IS_NPC(to)){ // TRUE_CH() must be used in the calling function
sender->println("Tells can't be exchanged with non playing characters.");
return;
}
if(channel_colour_disabled(to,CHANNEL_TELLS)){
text=strip_colour(text);
}
// support restricting tells between players
if(GAMESETTING2(GAMESET2_TELL_RESTRICTIONS))
{
if( !(IS_IMMORTAL(from) || IS_IMMORTAL(to)
||(IS_NEWBIE_SUPPORT(from) && !IS_LETGAINED(to))
||(IS_NEWBIE_SUPPORT(to) && !IS_LETGAINED(from))))
{
if (IS_NEWBIE_SUPPORT(from)){
sender->println( "Tells may only be exchanged with an immortal or new players.");
}else if (!IS_LETGAINED(from)){
sender->println( "`xTells may only be exchanged with an immortal or newbie support players\r\n"
"(ie has +++ in who).\r\n"
"If you want to talk to another player about Out of Character (OOC) way\r\n"
"you can use goto the ooc rooms using the `=Cgoooc`x command, and then request\r\n"
"using the `=Crequestooc`x command that the person you are wanting to talk meets\r\n"
"meets you in the ooc rooms.");
}else{
sender->println( "Tells may only be exchanged with an immortal." );
}
return;
}
}
// get the name of the person the message is being sent to from
// the senders perspective
char to_name[MIL];
char to_capname[MIL];
int to_gender;
bool to_unknown;
if(type==ST_REPLY && IS_SET(from->dyn,DYN_UNKNOWN_REPLY_NAME)){
to_unknown=true;
strcpy(to_name,"someone"); // the default name
to_gender=SEX_NEUTRAL;
}else{
to_unknown=false;
strcpy(to_name, mxp_create_tag(from, FORMATF("ch-uid_name %d", to->uid), capitalize(to->name)));
to_gender=URANGE(0, to->pcdata->true_sex, 2);
}
strcpy(to_capname,capitalize(to_name));
// leave imms in peace and quiet from mortal tells :)
if( HAS_CHANNELOFF(to, CHANNEL_QUIET) && !IS_IMMORTAL(from)) {
sender->printlnf( "%s is not receiving tells.", to_name);
return;
}
// check for nothing to say - including empty colour codes
if ( IS_NULLSTR(text) || c_str_len(text)==0) {
sender->printlnf( "%s %s what?",
(type==ST_TELL)?"Tell": ((type==ST_RETELL)?"Retell":"Reply to"), to_name);
return;
}
// If the sender knows the name of the person they are talking to or they can't
// see the person they are talking to on the wholist, they can be informed
// of the linkdead status of the person they are speaking with
if ( !(to->controlling?to->controlling:to)->desc
&& (!to_unknown || !can_see_who(from,to)))
{
sender->wraplnf("%s seems to have misplaced %s link... "
"the tell will be recorded in %s replay which they will "
"automatically see if they reconnect.",
to_capname, his_her[to_gender], his_her[to_gender]);
}
// keep a track of what newbie support is doing
if ( (IS_NEWBIE_SUPPORT(from) && !IS_LETGAINED(to))
||(IS_NEWBIE_SUPPORT(to) && !IS_LETGAINED(from)) )
{
char tbuf[MSL];
char nbuf[MSL];
sprintf (tbuf,"Tell %s %s", to->name, text);
append_newbie_support_log(from, tbuf);
if ( !IS_IMMORTAL( from ) && !IS_IMMORTAL( to )) {
sprintf (nbuf, "`W%s newbietells %s '%s'",
from->name, to->name, text);
wiznet(nbuf,from,NULL,WIZ_NEWBIETELL,0,LEVEL_IMMORTAL);
}
}
// get the name of the person sending the message
// from the receivers perspective
char from_name[MIL];
bool from_unknown=true;;
int from_gender;
switch(type){
case ST_TELL: // 'new conversation' sender known if can be seen on the wholist
if(can_see_who(to, from) || IS_SET(from->dyn, DYN_USING_KTELL) ){
from_unknown=false;
REMOVE_BIT(from->dyn, DYN_HAS_ANONYMOUS_RETELL);
}else{
SET_BIT(from->dyn, DYN_HAS_ANONYMOUS_RETELL);
}
break;
case ST_REPLY: // For the sender to be replying, the receiver has to have
// sent the sender a tell earlier, therefore the receiver could see them
// then, so this conversation isn't anonymous
from_unknown=false;
break;
case ST_RETELL: // determined on the anonymous status of original tell
if(!IS_SET(from->dyn, DYN_HAS_ANONYMOUS_RETELL)){
from_unknown=false;
}
break;
}
if(from_unknown){
strcpy(from_name,"Someone"); // name unknown to the receiver
from_gender=SEX_NEUTRAL;
}else{
strcpy(from_name, mxp_create_tag(to, FORMATF("ch-uid_name %d", from->uid), capitalize(from->name)));
from_gender=URANGE(0, from->pcdata->true_sex, 2);
}
// send the messages
deliver_tell( from, "%sYou %s%s %s '%s%s'`x\r\n",
(type==ST_REPLY?"`=M":"`=m"),
(from_unknown?"anonymously ":""),
(to_unknown && type==ST_REPLY)|| !can_see_who(from, to)? mxp_create_tag(from, "tl_rp", "tell"):
mxp_create_tag(from, (FORMATF("%s %s", from->retell==to?"tl-nm_rp_tlnm":"tl-nm_rt_tlnm", to->name)), "tell"),
to_name,
text,
(type==ST_REPLY?"`=M":"`=m"));
deliver_tell(to, "%s%s %s you %s'%s%s'`x\r\n", // tells you
(to->retell!=from || from_unknown?"`=M":"`=m"),
from_name,
(from_unknown || !can_see_who(to, from))?mxp_create_tag(to, "tl_rp", "tells"):
mxp_create_tag(to, (FORMATF("%s %s", to->retell==from?"tl-nm_rt_tlnm":"tl-nm_rp_tlnm", from->name)), "tells"),
(to_unknown?"(someone) ":""),
text,
(to->retell!=from?"`=M":"`=m"));
// reply locks onto all anonymous tells
// if the tell isn't anonymous then to those who you arent retelling you
// also when the receiver doesn't have any current reply
if(from_unknown || to->retell!=from || !to->reply){
if(!to_unknown){
to->reply=from;
}
if(from_unknown){
SET_BIT(to->dyn,DYN_UNKNOWN_REPLY_NAME);
}else{
REMOVE_BIT(to->dyn,DYN_UNKNOWN_REPLY_NAME);
}
}
if(type==ST_TELL){
from->retell=to;
}
// inform the sender of receiver afk status on the message they just sent
// (assuming it wont give away the identity of an imm that is a 'someone')
if (IS_SET(to->comm,COMM_AFK) && (!to_unknown || !can_see_who(from,to)))
{
from->wraplnf(
"%s is currently AFK and therefore might not have seen your message. Your "
"message has been displayed to their screen and recorded in %s tell replay buffer.",
to_capname,
his_her[to_gender]);
}
}
/**************************************************************************/
void do_tell( char_data *ch, char *argument )
{
char arg[MIL];
char_data *victim;
if(tell_cant_send_tell(ch)){
return;
};
if( HAS_CHANNELOFF(ch, CHANNEL_QUIET) ) {
ch->println( "You must turn off quiet mode before sending a tell." );
return;
}
// find out who the tell is going to
argument = one_argument( argument, arg );
if ( arg[0] == '\0' || argument[0] == '\0' )
{
ch->println( "Tell whom what?" );
return;
}
// remove a , from the name field if required
if (arg[str_len(arg)-1]==',')
arg[str_len(arg)-1]=0;
if ( ( victim = get_whovis_player_world( ch, arg ) ) == NULL)
{
ch->printlnf( "'%s' couldn't be found to send a tell to.", arg);
return;
}
if(TRUE_CH(ch)==victim){
ch->println( "Try talking to someone other than yourself." );
return;
}
tell_sendtext(TRUE_CH(ch), victim, argument, ST_TELL);
}
/**************************************************************************/
void do_atell( char_data *ch, char *argument )
{
if(IS_NULLSTR(argument)){
ch->println( "atell <who> what you want to say - anonymous tell" );
return;
}
int whovis = IS_SET(TRUE_CH(ch)->comm, COMM_WHOVIS);
REMOVE_BIT(TRUE_CH(ch)->comm, COMM_WHOVIS);
do_tell(ch, argument);
if (whovis)
{
SET_BIT(TRUE_CH(ch)->comm, COMM_WHOVIS);
}
}
/**************************************************************************/
void do_ktell( char_data *ch, char *argument )
{
if(IS_NULLSTR(argument)){
ch->println( "ktell <who> what you want to say - known tell" );
return;
}
SET_BIT(TRUE_CH(ch)->dyn, DYN_USING_KTELL);
do_tell(ch, argument);
REMOVE_BIT(TRUE_CH(ch)->dyn, DYN_USING_KTELL);
}
/**************************************************************************/
void do_retell( char_data *ch, char *argument )
{
if(tell_cant_send_tell(ch)){
return;
};
if (!TRUE_CH(ch)->retell)
{
ch->println( "They aren't here." );
ch->println( "(you have to send someone a tell before using retell.)" );
return;
}
tell_sendtext(TRUE_CH(ch), TRUE_CH(ch)->retell, argument, ST_RETELL);
}
/**************************************************************************/
void do_reply( char_data *ch, char *argument )
{
if(tell_cant_send_tell(ch)){
return;
};
if ( TRUE_CH(ch)->reply == NULL )
{
ch->println( "They aren't here." );
return;
}
tell_sendtext(TRUE_CH(ch), TRUE_CH(ch)->reply, argument, ST_REPLY);
}
/**************************************************************************/
struct sectyellinfo
{
short sectindex;
float yellreduction; // amount of yell remaining after the sound
// travelled thru the room
};
// return the id of the next yell
time_t get_yell_id(void)
{
static int lastyellid=0;
lastyellid++;
return lastyellid;
}
sectyellinfo sectyelltable[]={
{SECT_INSIDE ,(float)0.90}, // reduction amounts on the high side
{SECT_CITY ,(float)0.85}, // to make the yell command actually useable
{SECT_FIELD ,(float)0.75},
{SECT_FOREST ,(float)0.70},
{SECT_HILLS ,(float)0.70},
{SECT_MOUNTAIN ,(float)0.65},
{SECT_WATER_SWIM ,(float)0.55},
{SECT_WATER_NOSWIM ,(float)0.45},
{SECT_SWAMP ,(float)0.45},
{SECT_AIR ,(float)0.65},
{SECT_DESERT ,(float)0.65},
{SECT_CAVE ,(float)0.80},
{SECT_UNDERWATER ,(float)0.35},
{SECT_SNOW ,(float)0.80},
{SECT_ICE ,(float)0.80},
{SECT_TRAIL ,(float)0.75},
{SECT_LAVA ,(float)0.40},
};
/**************************************************************************/
float get_yellreduction(short sector)
{
if(sector<0 || sector>=SECT_MAX){
bugf("get_yellreduction(): Out of range sector value %d!!!", sector);
return (float)0.50; // use low value
}
if(sectyelltable[sector].sectindex==sector){
return sectyelltable[sector].yellreduction;
}else{ // gotta go look for it
bugf("get_yellreduction(): Table out of order for index %d, sectyelltable[sector].sectindex=%d!!",
sector, sectyelltable[sector].sectindex);
return (float)0.65; // use low value
}
}
/**************************************************************************/
void recurse_yell(ROOM_INDEX_DATA *to_room, float amplitude,
int direction, time_t yellindex)
{
if(!to_room){
bug("recurse_yell(): to_room==NULL!");
return;
}
// reduce the amplitude of the yell to travel this room
amplitude*=get_yellreduction(to_room->sector_type);
// yell has died out
if(amplitude<5.0){
return;
}
// if the room we are currently in already has a yell that is greater
// or equal to our current amplitude, leave this path
if(to_room->yellindex==yellindex && to_room->yell_amplitude>=amplitude){
return;
}
// add our yell here
to_room->yellindex=yellindex;
to_room->yell_amplitude=amplitude;
to_room->yell_enteredindir=direction;
// broadcast the yell in all directions
int dir;
for (dir=0;dir<MAX_DIR;dir++)
{
if(!to_room->exit[dir] || !to_room->exit[dir]->u1.to_room)
continue;
if(IS_SET(to_room->exit[dir]->exit_info,EX_CLOSED)){
amplitude*=(float)0.55; // lose 45% going thru doors
}
if(dir!=direction){
amplitude*=(float)0.70; // lose 30% changing direction
}
// yells dont bleed between OOC and IC
if((to_room->exit[dir]->u1.to_room->room_flags&ROOM_OOC)
!=(to_room->room_flags&ROOM_OOC)){
continue;
}
if( !to_room->exit[dir]->u1.to_room->exit[rev_dir[dir]]
|| to_room->exit[dir]->u1.to_room->exit[rev_dir[dir]]->u1.to_room!=to_room){
// exits missed matched, wipe directional component
recurse_yell(to_room->exit[dir]->u1.to_room, amplitude, -1, yellindex);
}else{
// send to the next room
recurse_yell(to_room->exit[dir]->u1.to_room, amplitude, dir, yellindex);
}
}
}
/**************************************************************************/
char *get_yellreversedir(short dir, int amplitude)
{
static char buf[MIL];
if(dir==-1){
if(amplitude>50){
sprintf(buf,"from somewhere in the near surroundings");
}else if (amplitude>40){
sprintf(buf,"from somewhere not far from here");
}else if (amplitude>30){
sprintf(buf,"from somewhere in the near distance");
}else if (amplitude>20){
sprintf(buf,"from somewhere in the distance");
}else if (amplitude>10){
sprintf(buf,"from somewhere in the far distance");
}else if (amplitude>4){
sprintf(buf,"from somewhere in the far far distance");
}else{
sprintf(buf,"faintly");
}
}else{
if(amplitude>50){
sprintf(buf,"from somewhere in the near surroundings to the %s",
dir_name[rev_dir[dir]]);
}else if (amplitude>40){
sprintf(buf,"from somewhere not far from here to the %s",
dir_name[rev_dir[dir]]);
}else if (amplitude>30){
sprintf(buf,"from somewhere in the near distant %s",
dir_name[rev_dir[dir]]);
}else if (amplitude>20){
sprintf(buf,"from somewhere in the distant %s",
dir_name[rev_dir[dir]]);
}else if (amplitude>10){
sprintf(buf,"from somewhere in the far distance %s",
dir_name[rev_dir[dir]]);
}else if (amplitude>5){
sprintf(buf,"from somewhere in the far far distant %s",
dir_name[rev_dir[dir]]);
}else if (amplitude>2){
sprintf(buf,"faintly from the %s", dir_name[rev_dir[dir]]);
}else{
sprintf(buf,"faintly");
}
}
return buf;
}
/**************************************************************************/
bool ftp_reconnect(char *name);
/**************************************************************************/
void do_testyell(char_data *ch, char *)
{
ch->println("===Yell test info");
ch->printlnf( "Room vnum = %d",ch->in_room->vnum);
ch->printlnf( "Yellindex = %d",(int)ch->in_room->yellindex);
ch->printlnf( "Yell_enteredindir = %d",ch->in_room->yell_enteredindir);
ch->printlnf( "Yell_amplitude = %f",ch->in_room->yell_amplitude);
if(ch->desc){
ch->println("===Colour memory test dump");
ch->printlnf("current = %c", ch->desc->colour_memory.current);
ch->printlnf("saved index = %d", ch->desc->colour_memory.saved_index);
for(int i=0; i<MAX_SAVED_COLOUR_ARRAY; i++){
ch->printlnf("%d] saved =%c", i, ch->desc->colour_memory.saved[i]);
}
}
// manual room count
{
int rcount=0;
int i;
ROOM_INDEX_DATA *pRoomIndex;
for(i=0; i<MAX_KEY_HASH; i++){
for ( pRoomIndex = room_index_hash[i];
pRoomIndex != NULL;
pRoomIndex = pRoomIndex->next )
{
rcount++;
}
}
ch->printlnf("manual room count=%d", rcount);
}
if(HAS_MSP(ch)){
ch->println("Testing MSP by sending quaff sound using msp_to_room()...");
msp_to_room(MSPT_ACTION, MSP_SOUND_QUAFF,
0,
ch,
false,
true);
ch->println("Test finished.");
}else{
ch->println("Currently your msp setting is disabled, so no msp test sound is sent to you.");
}
ch->println("Telling your dawnftp client to reconnect (if you have one).");
ftp_reconnect(ch->name);
}
/**************************************************************************/
// Kal - July 99
void do_yell(char_data *ch, char *argument )
{
char buf2[MSL];
static int rpmon=0;
char buf[MSL];
time_t yellid= get_yell_id();
float start_amp=race_table[ch->race]->high_size*(float)1.1;
if ( IS_SET(ch->comm, COMM_NOSHOUT) )
{
ch->println( "You can't yell." );
return;
}
if ( argument[0] == '\0' )
{
ch->println( "Yell what?" );
return;
}
if(IS_SET(ch->in_room->room_flags, ROOM_NOSPEAK)
&& !HAS_CONFIG(ch, CONFIG_HOLYSPEECH)) {
ch->println( "You feel the air escape your lungs, and yet... no sound." );
return;
}
// wiznet RPMONITOR
if (!IS_NPC(ch) && !IS_OOC(ch))
{
rpmon++;
if (rpmon>=5)
{
sprintf (buf2, "Wiznet rpmonitor: %s yells '%s'`x", ch->name, argument);
wiznet(buf2,ch,NULL,WIZ_RPMONITOR,0,get_trust(ch));
rpmon=0;
}
}
if(!IS_NPC(ch)){
ch->pcdata->did_ic=true;
}
// fromroom , amplitude, no direction
recurse_yell(ch->in_room, start_amp, -1, yellid);
// now transmit to all connections what they heard
{
ROOM_INDEX_DATA *this_room;
connection_data *d;
for ( d = connection_list; d; d = d->next )
{
if ( d->connected_state == CON_PLAYING
&& d->character && d->character->in_room
&& IS_AWAKE(d->character))
{
this_room=d->character->in_room;
if(this_room->yellindex==yellid){
// they heard it
translate_language(ch->language, true, ch, d->character, argument, buf);
if(this_room== ch->in_room)
{
act("$n yells '$t'`x",ch,buf,d->character,TO_VICT);
}
else
{
if(IS_IMMORTAL(CH(d)))
{
d->character->printlnf( "You hear a %s voice(%s) yell %s '%s', %f",
(ch->sex==2?"female":"male"),
ch->name,
get_yellreversedir(this_room->yell_enteredindir,
(int)this_room->yell_amplitude),
buf, this_room->yell_amplitude);
}
else
{
if(IS_OOC(ch))
{
d->character->printlnf( "You hear a %s voice(%s) yell %s '%s'",
(ch->sex==2?"female":"male"), ch->name,
get_yellreversedir(this_room->yell_enteredindir,
(int)this_room->yell_amplitude), buf);
}
else
{
d->character->printlnf( "You hear a %s voice yell %s '%s'",
(ch->sex==2?"female":"male"),
get_yellreversedir(this_room->yell_enteredindir,
(int)this_room->yell_amplitude), buf);
}
}
}
}
}
}
}
act("You yell '$t'`x",ch,argument,NULL,TO_CHAR);
}
/**************************************************************************/
void do_emote( char_data *ch, char *argument )
{
char buf2[MSL];
static int rpmon=0;
if ( !IS_NPC(ch) && IS_SET(ch->comm, COMM_NOEMOTE) )
{
ch->println( "You can't show your emotions." );
return;
}
if ( argument[0] == '\0' )
{
ch->println( "Emote what?" );
return;
}
// Integrated emote code
{
int starcount = count_char(argument, '*');
int atcount = count_char(argument, '@');
if(starcount>0)
{
if( atcount>0){
do_amote(ch,argument);
}else{
do_smote(ch,argument);
}
return;
}
if( atcount>0){
do_pmote(ch,argument);
return;
}
}
if(!IS_OOC(ch))
{
// dont allow messages that could be defrauding
if(check_defrauding_argument(ch, argument)){
return;
}
}
// allow players to put a # at the start of an emote and
// it wont be counted towards rps, but can alias emotes to give
// there character unique like socials
bool rps_candiate=true;
if(*argument=='#'){
rps_candiate=false;
argument++;
};
// wiznet RPMONITOR
if (!IS_NPC(ch))
{
if (!IS_OOC(ch))
{
rpmon++;
if (rpmon>=15)
{
sprintf (buf2, "Wiznet rpmonitor: %s emotes '%s`x'", ch->name, argument);
wiznet(buf2,ch,NULL,WIZ_RPMONITOR,0,get_trust(ch));
rpmon=0;
}
if(rps_candiate){
ch->pcdata->did_ic=true;
}
}
if(room_is_private(ch->in_room) && rps_candiate){
ch->pcdata->did_ooc=true;
ch->pcdata->did_ic=false;
}
// anti autorps abuse system
if(IS_IC(ch) && rps_candiate)
{
++ch->pcdata->emote_index%=RPS_AUDIT_SIZE;
free_string(ch->pcdata->emotecheck[ch->pcdata->emote_index]);
ch->pcdata->emotecheck[ch->pcdata->emote_index]=str_dup(argument);
ch->pcdata->emotetimes[ch->pcdata->emote_index]=current_time;
}
}
MOBtrigger = false;
RECORD_TO_REPLAYROOM=true;
act( "$n $T`x", ch, NULL, argument, TO_ROOM );
act( "$n $T`x", ch, NULL, argument, TO_CHAR );
RECORD_TO_REPLAYROOM=false;
MOBtrigger = true;
return;
}
/**************************************************************************/
// written by Kalahn
void do_amote( char_data *ch, char *argument )
{
char *letter;
char act_text[MIL];
char vict_text[MIL];
char ch_arg[MIL];
char_data *victim;
if ( !IS_NPC(ch) && IS_SET(ch->comm, COMM_NOEMOTE) )
{
ch->println( "You can't show your emotions." );
return;
}
argument = one_argument( argument, ch_arg );
if ( ch_arg[0] == '\0' || argument[0] == '\0')
{
ch->println( "Syntax: amote <at> <text>." );
ch->println( "<at> is the target who the amote is direct at." );
ch->println( "The text must include * for your name and a @ where you want the targets name." );
ch->println( "eg amote guard Jumping from out of the shadows, * grabs @ by the neck." );
return;
}
if (( victim = get_char_room( ch, ch_arg ) ) == NULL )
{
ch->printlnf( "You can't seem to find the player '%s'.", ch_arg);
return;
}
if (victim == ch)
{
ch->println( "You can't direct amotes at yourself... use smote.");
return;
}
if ( argument[0] == '\0' )
{
ch->printlnf( "Amote what towards %s.", PERS(victim, ch));
return;
}
if ( (count_char(argument,'@') != 1) || (count_char(argument,'*') != 1) )
{
ch->println( "Syntax: amote <target> <text>." );
ch->println( " The text must include a single * for your name and a single @ where you want the targets name." );
ch->println( " * must appear before @." );
ch->println( " eg amote guard Jumping from out of the shadows, * grabs @ by the neck." );
return;
}
if (strstr(argument,"@") < strstr(argument,"*"))
{
ch->println( "AMOTE: * must appear before the @." );
return;
}
// dont allow messages that could be defrauding
if(check_defrauding_argument(ch, argument)){
return;
}
// allow players to put a # at the start of an emote and
// it wont be counted towards rps, but can alias emotes to give
// there character unique like socials
bool rps_candiate=true;
if(*argument=='#'){
rps_candiate=false;
argument++;
};
act_text[0]= '\0';
vict_text[0]= '\0';
letter = argument;
for (; *letter != '\0'; letter++)
{
if (*letter == '@')
{
if ( *(letter+1) == '\'' && *(letter+2) == 's')
{
strcat(act_text, "`#`x$N's`&");
strcat(vict_text, "your");
letter += 2;
}
else if ( *(letter+1) == 'r' || *(letter+1) == 's')
{
strcat(act_text, "`#`x$N's`&");
strcat(vict_text, "your");
letter++;
}
else
{
strcat(act_text, "`#`x$N`&");
strcat(vict_text, "you");
}
}
else if (*letter == '*')
{
strcat(act_text, "`#`W$n`&");
strcat(vict_text, "`#`W$n`&");
}
else
{
strncat(act_text, letter,1);
strncat(vict_text, letter,1);
}
}
MOBtrigger = false;
act( act_text, ch, NULL, victim, TO_NOTVICT );
act( act_text, ch, NULL, victim, TO_CHAR );
act( vict_text, ch, NULL, victim, TO_VICT );
MOBtrigger = true;
if(!IS_NPC(ch) && rps_candiate){
ch->pcdata->did_ic=true;
if(room_is_private(ch->in_room)){
ch->pcdata->did_ooc=true;
ch->pcdata->did_ic=false;
}
}
}
/**************************************************************************/
// modified by Kalahn to use @ in place of name and use act
void do_pmote( char_data *ch, char *argument )
{
char *letter;
char act_text[MIL];
char vict_text[MIL];
char ch_arg[MIL];
char_data *victim;
if ( !IS_NPC(ch) && IS_SET(ch->comm, COMM_NOEMOTE) )
{
ch->println( "You can't show your emotions." );
return;
}
argument = one_argument( argument, ch_arg );
if ( ch_arg[0] == '\0' || argument[0] == '\0')
{
ch->println( "Syntax: pmote <target> <text>." );
ch->println( "The text must include a single @ where you want the targets name." );
ch->println( "eg pmote guard smiles at @." );
return;
}
if (( victim = get_char_room( ch, ch_arg ) ) == NULL )
{
ch->printlnf( "You can't seem to find the player '%s'.", ch_arg);
return;
}
if (victim == ch)
{
ch->println( "You can't direct pmotes at yourself... use emote." );
return;
}
if ( argument[0] == '\0' )
{
ch->printlnf( "Pmote what towards %s.", PERS(victim, ch));
return;
}
if (count_char(argument,'@') != 1)
{
ch->println( "Syntax: pmote <target> <text>." );
ch->println( "The text must include a single @ where you want the targets name." );
ch->println( "eg pmote guard smiles at @." );
return;
}
// dont allow messages that could be defrauding
if(check_defrauding_argument(ch, argument)){
return;
}
// allow players to put a # at the start of an emote and
// it wont be counted towards rps, but can alias emotes to give
// there character unique like socials
bool rps_candiate=true;
if(*argument=='#'){
rps_candiate=false;
argument++;
};
strcpy (act_text, "$n ");
strcpy (vict_text, "$n ");
letter = argument;
for (; *letter != '\0'; letter++)
{
if (*letter == '@')
{
if ( *(letter+1) == '\'' && *(letter+2) == 's')
{
strcat(act_text, "`#`x$N's`&");
strcat(vict_text, "your");
letter += 2;
}
else if ( *(letter+1) == 'r' || *(letter+1) == 's')
{
strcat(act_text, "`#`x$N's`&");
strcat(vict_text, "your");
letter++;
}
else
{
strcat(act_text, "`#`x$N`&");
strcat(vict_text, "you");
}
}
else
{
strncat(act_text, letter,1);
strncat(vict_text, letter,1);
}
}
MOBtrigger = false;
act( act_text, ch, NULL, victim, TO_NOTVICT );
act( act_text, ch, NULL, victim, TO_CHAR );
act( vict_text, ch, NULL, victim, TO_VICT );
MOBtrigger = true;
if(!IS_NPC(ch) && rps_candiate){
ch->pcdata->did_ic=true;
if(room_is_private(ch->in_room)){
ch->pcdata->did_ooc=true;
ch->pcdata->did_ic=false;
}
}
}
/**************************************************************************/
// modified by Kalahn to use * in place of name and use act
void do_smote(char_data *ch, char *argument )
{
char *letter;
char act_text[MSL];
if ( !IS_NPC(ch) && IS_SET(ch->comm, COMM_NOEMOTE) && !IS_AWAKE(ch))
{
ch->println( "You can't show your emotions." );
return;
}
if ( argument[0] == '\0' )
{
ch->println( "Smote what?" );
return;
}
if (count_char(argument,'*') != 1)
{
ch->println( "You must include a single * where you want your name to appear in a smote." );
return;
}
// dont allow messages that could be defrauding
if(check_defrauding_argument(ch, argument)){
return;
}
// allow players to put a # at the start of an emote and
// it wont be counted towards rps, but can alias emotes to give
// there character unique like socials
bool rps_candiate=true;
if(*argument=='#'){
rps_candiate=false;
argument++;
};
act_text[0]='\0';
letter = argument;
for (; *letter != '\0'; letter++)
{
if (*letter == '*'){
strcat(act_text, "`#`W$n`&");
}else{
strncat(act_text, letter,1);
}
}
MOBtrigger = false;
act(act_text, ch, NULL, NULL, TO_ROOM );
act(act_text, ch, NULL, NULL, TO_CHAR );
MOBtrigger = true;
return;
}
/**************************************************************************/
void do_bug( char_data *ch, char *argument )
{
char buf[MSL];
if(IS_NULLSTR(argument)){
ch->println("This command is used for reporting bug in any of code in the game.");
ch->println("You must type something as a parameter.");
return;
}
sprintf(buf,"do_bug: %s reported the bug '%s' [room %d]\r\n", ch->name, argument, ch->in_room->vnum);
wiznet(buf,NULL,NULL,WIZ_BUGS,0,AVATAR); // put it on the bug wiznet channel
append_logentry_to_file( ch, BUG_FILE, argument );
ch->println( "Bug logged. (bug automatically records the room you are in by the way)" );
return;
}
/**************************************************************************/
void do_typo( char_data *ch, char *argument )
{
char buf[MSL];
if(IS_NULLSTR(argument)){
ch->println( "This command is used for reporting typos in any of the text anywhere in the game." );
ch->println( "You must type something as a parameter, there is also the 'type' social." );
return;
}
sprintf(buf,"do_typo: %s reported the typo '%s' [room %d]\r\n", ch->name, argument, ch->in_room->vnum);
wiznet(buf,NULL,NULL,WIZ_BUGS,0,AVATAR); // put it on the bug wiznet channel
append_logentry_to_file( ch, TYPO_FILE, argument );
ch->println( "Typo logged. (typo automatically records the room you are in by the way)" );
return;
}
/**************************************************************************/
void do_qui( char_data *ch, char *)
{
ch->println( "If you want to QUIT, you have to spell it out." );
return;
}
/**************************************************************************/
void mp_logout_trigger( char_data *ch);
/**************************************************************************/
void quit_char(char_data *ch, char *argument, bool character_deleting )
{
connection_data *d,*c_next;
int id;
// Check if they're being ordered to do this
if ( IS_SET( ch->dyn, DYN_IS_BEING_ORDERED ))
{
if ( ch->master )
ch->master->println( "Not going to happen." );
return;
}
if(IS_SET(ch->dyn,DYN_USING_ATLEVEL)){
ch->println( "You can't quit while using at level!" );
return;
}
if ( IS_SWITCHED(ch) )
{
if (IS_IMMORTAL(ch)){
ch->println( "You are currently controlling a mob... type `=Creturn`x first!" );
}else{
ch->println( "You are not in your mortal body, type `=Creturn`x to get back to it then try quitting.!" );
}
return;
}
if ( IS_NPC(ch) )
return;
// ploaded players can't quit
if(ch->pload && ch->pload->dont_save){
if(ch->pload->loaded_by){
ch->pload->loaded_by->printlnf( "quit_char(): character %s can't 'quit' cause it was ploaded.", ch->name);
}
logf( "quit_char(): character %s can't 'quit' cause it was ploaded.", ch->name);
return;
}
mp_logout_trigger( ch);
if ( !character_deleting && !IS_LINKDEAD(ch) && ch->pnote && str_cmp("confirm", argument)) {
switch(ch->pnote->type) {
default:
break;
case NOTE_NOTE:
ch->println( "`YYou have a Note in progress.`x\r\n" );
break;
case NOTE_IDEA:
ch->println( "`YYou have an Idea in progress.`x\r\n" );
break;
case NOTE_PENALTY:
ch->println( "`YYou have a Penalty note in progress.`x\r\n" );
break;
case NOTE_NEWS:
ch->println( "`YYou have a News in progress.`x\r\n" );
break;
case NOTE_CHANGES:
ch->println( "`YYou have a Change in progress.`x\r\n" );
break;
case NOTE_ANOTE:
ch->println( "`YYou have an Anote in progress.`x\r\n" );
break;
case NOTE_INOTE:
ch->println( "`YYou have an Inote in progress.`x\r\n" );
break;
}
ch->println( "You may either post it, clear it, or type `=Cquit confirm`x to quit now." );
return;
}
if (!( character_deleting
|| ( IS_IMMORTAL(ch) && !str_cmp("confirm", argument))
)
) // if they are deleting they can quit or if they are an imm typing 'quit confirm'
{
if ( ch->position == POS_FIGHTING )
{
ch->println( "No way! You are fighting." );
return;
}
#ifndef unix
if (moot->moot_type<0){
moot->moot_type =0;
}
#endif
if(ch->pcdata->diplomacy && moot->moot_type){
ch->println( "You can not quit while a moot is in progress." );
return;
}
if(moot->moot_victim==ch){
ch->println( "You can not quit while a moot is called against you." );
return;
}
if(!GAMESETTING5(GAMESET5_DEDICATED_PKILL_STYLE_MUD)){
if(ch->pknorecall>0){
if (IS_IMMORTAL(ch)){
ch->println( "You have a PK norecall timer (been in a pk fight)" );
ch->println( "If you wish to quit you must type `#`=Cquit confirm`&" );
}else{
ch->println( "You may not leave this world so soon after conflict." );
}
return;
}
}
if(ch->pknoquit>0){
if (IS_IMMORTAL(ch)){
ch->println( "You have a PK noquit timer (been in a pk fight)" );
ch->println( "If you wish to quit you must type `#`=Cquit confirm`&" );
}else{
ch->println( "You may not leave this world so soon after PK interactions." );
ch->println( "(you have a pknoquit timer)" );
}
return;
}
if ( ch->position < POS_STUNNED )
{
ch->println( "You're not DEAD yet." );
return;
}
}
ch->println( "Alas, all good things must come to an end." );
act( "$n fades from the realm.", ch, NULL, NULL, TO_ROOM );
// send the info broadcast about the person leaving
info_broadcast(ch, "%s has left the realm.", ch->name);
if(GAMESETTING5(GAMESET5_DEDICATED_PKILL_STYLE_MUD))
{
if(!IS_IMMORTAL(ch)){
pkill_broadcast("%s fades from the realm of death! [Pk=%d.Pd=%d]\r\n",
ch->name,
TRUE_CH(ch)->pcdata->p9999kills,
TRUE_CH(ch)->pcdata->p9999defeats);
}
}
if (ch->desc){
logf( "%s has quit. (connected_socket = %d), (left in room=%d, lasticroom=%d)",
ch->name, ch->desc->connected_socket,
ch->in_room?ch->in_room->vnum:0,
ch->last_ic_room?ch->last_ic_room->vnum:0);
}else{
logf( "%s has quit. (descriptor = linkless) (left in room=%d, lasticroom=%d)",
ch->name,
ch->in_room?ch->in_room->vnum:0,
ch->last_ic_room?ch->last_ic_room->vnum:0);
}
sprintf( log_buf, "%s has left the game. (left level %d, remort %d), room=%d, lasticroom=%d",
ch->name, ch->level, ch->remort,
ch->in_room?ch->in_room->vnum:0,
ch->last_ic_room?ch->last_ic_room->vnum:0);
wiznet(log_buf,ch,NULL,WIZ_LOGINS,0, UMIN(get_trust(ch), MAX_LEVEL));
// record their exit into the game into their plog if they have one
if (!IS_NPC(ch) && IS_SET(ch->act, PLR_LOG)){
append_playerlog( ch, log_buf);
}
if (ch->desc){
if (IS_IRC(ch)){
sprintf( log_buf, "was %s@%s (IRC).", ch->name, ch->desc->remote_hostname);
}else{
sprintf( log_buf, "was %s@%s", ch->name, ch->desc->remote_hostname);
}
wiznet(log_buf,NULL,NULL,WIZ_SITES,0,UMIN(get_trust(ch),MAX_LEVEL));
}
// After extract_char the ch is no longer valid!
save_char_obj( ch );
id = ch->id;
d = ch->desc;
extract_char( ch, true );
if ( d){
connection_close( d );
}else{
log_string("do_quit: linkless player quiting");
}
// toast evil cheating bastards
for (d = connection_list; d != NULL; d = c_next)
{
char_data *tch;
c_next = d->next;
tch = d->original ? d->original : d->character;
if (tch && tch->id == id)
{
extract_char(tch,true);
connection_close(d);
}
}
return;
}
/**************************************************************************/
void do_quit( char_data *ch, char *argument )
{
quit_char(ch, argument, false);
}
/**************************************************************************/
void do_save( char_data *ch, char *)
{
if ( IS_NPC(ch) )
return;
save_char_obj( ch );
ch->printlnf( "Saving, remember that %s has automatic saving.", MUD_NAME );
#ifdef unix
WAIT_STATE(ch,1 * PULSE_VIOLENCE);
#endif
return;
}
/**************************************************************************/
// RT changed to allow unlimited following and follow the NOFOLLOW rules
void do_follow( char_data *ch, char *argument )
{
char arg[MIL];
char_data *victim;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
ch->println( "Follow whom?" );
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
ch->println( "They aren't here." );
return;
}
if ( IS_AFFECTED(ch, AFF_CHARM) && ch->master != NULL )
{
act( "But you'd rather follow $N!", ch, NULL, ch->master, TO_CHAR );
return;
}
if ( victim == ch )
{
if ( ch->master == NULL )
{
ch->println( "You already follow yourself." );
return;
}
stop_follower(ch);
return;
}
if (!IS_NPC(victim) && IS_SET(victim->act,PLR_NOFOLLOW) && !IS_IMMORTAL(ch))
{
act("$N doesn't seem to want any followers.\r\n",
ch,NULL,victim, TO_CHAR);
return;
}
REMOVE_BIT(ch->act,PLR_NOFOLLOW);
if ( ch->master != NULL )
stop_follower( ch );
add_follower( ch, victim );
return;
}
/**************************************************************************/
void add_follower( char_data *ch, char_data *master )
{
if ( ch->master != NULL )
{
bug("Add_follower: non-null master.");
return;
}
ch->master = master;
ch->leader = NULL;
if ( can_see( master, ch ))
{
if ( !IS_SET(ch->dyn,DYN_SILENTLY))
{
act( "$n now follows you.", ch, NULL, master, TO_VICT );
}
}
act( "You now follow $N.", ch, NULL, master, TO_CHAR );
return;
}
/**************************************************************************/
void stop_follower( char_data *ch )
{
if ( ch->master == NULL )
{
bug("Stop_follower: null master.");
return;
}
if ( IS_AFFECTED(ch, AFF_CHARM) )
{
REMOVE_BIT( ch->affected_by, AFF_CHARM );
affect_strip( ch, gsn_charm_person );
// remove loophole where players would tell a mob to attack then
// do nofollow leaving the mob to fight to the death
if(IS_NPC(ch)){
if(ch->fighting && IS_NPC(ch->fighting)){
do_flee(ch,"");
do_flee(ch,"");
do_flee(ch,"");
// if they dont suceed in fleeing they become worthless
if(ch->fighting){
ch->no_xp=true;
ch->hitroll=-30;
ch->damroll=-30;
ch->hit=1;
ch->max_hit=1;
}
}
}
}
if ( ch->in_room && can_see( ch->master, ch ))
{
if ( IS_SET( ch->dyn, DYN_SILENTLY ))
{
act( "$n stops following you.", ch, NULL, ch->master, TO_VICT );
act( "You stop following $N.", ch, NULL, ch->master, TO_CHAR );
}
}
if (ch->master->pet == ch)
ch->master->pet = NULL;
ch->master = NULL;
ch->leader = NULL;
return;
}
/**************************************************************************/
bool is_character_loaded_into_room(char_data *ch, ROOM_INDEX_DATA *room);
/**************************************************************************/
// nukes charmed monsters and pets
void nuke_pets( char_data *ch)
{
char_data *pet;
if ((pet = ch->pet) != NULL)
{
// if they arent in the game yet (haven't logged in, and this
// isn't a reconnect) set pet->room to NULL
if((ch->desc && ch->desc->connected_state!=CON_PLAYING) || !ch->desc){
if(!is_character_loaded_into_room(ch->pet,ch->pet->in_room)){
ch->pet->in_room=NULL;
};
}
stop_follower(pet);
if (pet->in_room != NULL)
act("$N slowly fades away.",ch,NULL,pet,TO_NOTVICT);
extract_char(pet,true);
}
ch->pet = NULL;
return;
}
/**************************************************************************/
void die_follower( char_data *ch )
{
char_data *fch;
if ( ch->master != NULL )
{
if (ch->master->pet == ch)
ch->master->pet = NULL;
stop_follower( ch );
}
ch->leader = NULL;
for ( fch = char_list; fch != NULL; fch = fch->next )
{
if(ch->pet==fch){ // pets arent affected by nofollow
continue;
}
if ( fch->master == ch )
stop_follower( fch );
if ( fch->leader == ch )
fch->leader = fch;
}
return;
}
/**************************************************************************/
void do_order( char_data *ch, char *argument )
{
char buf[MSL];
char arg[MIL], arg2[MIL], arg3[MIL];
char_data *victim;
char_data *recipient;
char_data *och;
char_data *och_next;
bool found;
bool fAll;
argument = one_argument( argument, arg );
argument = one_argument(argument,arg2);
if ( IS_NULLSTR(arg) || IS_NULLSTR(arg2))
{
ch->println( "Order whom to do what?" );
return;
}
if ( IS_AFFECTED( ch, AFF_CHARM ) )
{
ch->println( "You feel like taking, not giving, orders." );
return;
}
if ( !str_cmp( arg, "all" ) )
{
fAll = true;
victim = NULL;
}
else
{
fAll = false;
// allow order pet
if(ch->pet && !str_cmp(arg ,"pet")){
victim=ch->pet;
if(ch->in_room!=victim->in_room){
ch->println( "Your pet isn't here." );
return;
}
}else{
if (( victim = get_char_room( ch, arg )) == NULL )
{
ch->println( "They aren't here." );
return;
}
}
if ( victim == ch )
{
ch->println( "Aye aye, right away!" );
return;
}
if (!IS_AFFECTED(victim, AFF_CHARM) || victim->master != ch
|| (IS_IMMORTAL(victim) && victim->trust >= ch->trust))
{
ch->println( "Do it yourself!" );
return;
}
}
strcat(arg2, " ");
strcat(arg2, argument);
found = false;
for ( och = ch->in_room->people; och != NULL; och = och_next )
{
och_next = och->next_in_room;
if ( IS_AFFECTED(och, AFF_CHARM)
&& och->master == ch
&& ( fAll || och == victim ) )
{
if ( !str_prefix("master", arg2))
{
argument = one_argument(argument, arg3);
if (!IS_SET(och->act, ACT_PET))
{
ch->println( "That is not your pet." );
return;
}
if ( IS_NULLSTR(arg3))
{
ch->println( "Who would you like to give your pet to?" );
return;
}
if ( ( recipient = get_char_room( ch, arg3 ) ) == NULL )
{
ch->println( "There is nobody like that here to take the pet." );
return;
}
if (IS_NPC(recipient))
{
ch->println( "You may only give pets to other players." );
return;
}
if (recipient->level < och->level)
{
act( "It appears as though your pet would be the master of $N.",
ch, NULL, recipient, TO_CHAR);
return;
}
if (recipient->pet){
act( "It appears as though $N already has a pet.",
ch, NULL, recipient, TO_CHAR);
return;
}
stop_follower(och);
ch->pet = NULL;
SET_BIT(och->act, ACT_PET);
SET_BIT(och->affected_by, AFF_CHARM);
add_follower( och, recipient);
och->leader = recipient;
recipient->pet = och;
act("$n is now $N's pet.", och, NULL, recipient, TO_ROOM);
act("You are now $N's pet.", och, NULL, recipient, TO_CHAR);
return;
}
else
{
// PC being ordered to do this - 3% chance of breaking the charm
if ( !IS_NPC(och) && number_range(1,33)==1 && !IS_IMMORTAL(ch))
{
sprintf( buf, "$n orders you to '%s', you manage to come to your senses and break the charm!", arg2 );
affect_parentspellfunc_strip( och, gsn_charm_person);
act( buf, ch, NULL, och, TO_VICT );
ch->printlnf( "%s doesn't appear to have heard you!", PERS(och, ch));
continue;
}
found = true;
// Toggle the Ordered Bit
SET_BIT( och->dyn, DYN_IS_BEING_ORDERED );
sprintf( buf, "$n orders you to '%s'.", arg2 );
act( buf, ch, NULL, och, TO_VICT );
interpret( och, arg2 );
// Remove the Ordered Bit
REMOVE_BIT( och->dyn, DYN_IS_BEING_ORDERED );
}
}
}
if ( found )
{
WAIT_STATE(ch,PULSE_VIOLENCE);
ch->println( "Ok." );
}
else
ch->println( "You have no followers here." );
return;
}
/**************************************************************************/
void do_group( char_data *ch, char *argument )
{
char arg[MIL];
char_data *victim;
one_argument( argument, arg );
if ( arg[0] == '\0' )
{
char_data *gch;
char_data *leader;
leader = (ch->leader != NULL) ? ch->leader : ch;
ch->printlnf( "%s's group:", icapitalize( PERS( leader, ch )));
for ( gch = char_list; gch; gch = gch->next )
{
if ( is_same_group( gch, ch ) )
{
// has hacks to prevent div by 0
ch->printlnf( "[ %3d%% hp - %3d%% mana - %3d%% mv ] %s",
(int) gch->hit*100/(gch->max_hit==0?1:gch->max_hit),
(int) gch->mana*100/(gch->max_mana==0?1:gch->max_mana),
(int) gch->move*100/(gch->max_move==0?1:gch->max_move),
capitalize( PERS(gch, ch) ));
}
}
return;
}
if ( ( victim = get_char_room( ch, arg ) ) == NULL )
{
ch->println( "They aren't here." );
return;
}
if ( ch->master != NULL || ( ch->leader != NULL && ch->leader != ch ) )
{
ch->println( "But you are following someone else!" );
return;
}
if ( victim->master != ch && ch != victim )
{
act( "$N isn't following you.", ch, NULL, victim, TO_CHAR );
return;
}
if (IS_AFFECTED(victim,AFF_CHARM))
{
ch->println( "You can't remove charmed mobs from your group." );
return;
}
if (IS_AFFECTED(ch,AFF_CHARM))
{
act("You like your master too much to leave $m!",ch,NULL,victim,TO_VICT);
return;
}
if(GAMESETTING(GAMESET_RESTRICTED_GROUPING)){
if (victim->level - ch->level > 8)
{
ch->println( "They are too high of a level for your group." );
return;
}
if (victim->level - ch->level < -8)
{
ch->println( "They are too low of a level for your group." );
return;
}
}
if ( IS_NPC( victim ))
{
ch->println( "You can't use this command to group mobs. ");
return;
}
if ( is_same_group( victim, ch ) && ch != victim )
{
victim->leader = NULL;
act( "$n removes you from $s group.", ch, NULL, victim, TO_VICT );
act( "You remove $N from your group.", ch, NULL, victim, TO_CHAR );
return;
}
victim->leader = ch;
act( "You join $n's group.", ch, NULL, victim, TO_VICT );
act( "$N joins your group.", ch, NULL, victim, TO_CHAR );
return;
}
/**************************************************************************/
void do_report(char_data *ch, char *)
{
// has hacks to prevent div by 0
do_say(ch,
FORMATF( "I have %3d%% hp, %3d%% mana and %3d%% movement.",
(int) ch->hit*100/(ch->max_hit==0?1:ch->max_hit),
(int) ch->mana*100/(ch->max_mana==0?1:ch->max_mana),
(int) ch->move*100/(ch->max_move==0?1:ch->max_move)));
}
/**************************************************************************/
void do_split( char_data *ch, char *argument )
{
char buf[MSL];
char arg1[MIL],arg2[MIL];
char_data *gch;
int members;
int amount_gold = 0, amount_silver = 0;
int share_gold, share_silver;
int extra_gold, extra_silver;
argument = one_argument( argument, arg1 );
one_argument( argument, arg2 );
if ( arg1[0] == '\0' )
{
ch->println( "Split how much?" );
return;
}
amount_silver = atoi( arg1 );
if (arg2[0] != '\0')
amount_gold = atoi(arg2);
if ( amount_gold < 0 || amount_silver < 0)
{
ch->println( "Your group wouldn't like that." );
return;
}
if ( amount_gold == 0 && amount_silver == 0 )
{
ch->println( "You hand out zero coins, but no one notices." );
return;
}
if ( ch->gold < amount_gold || ch->silver < amount_silver)
{
ch->println( "You don't have that much to split." );
return;
}
members = 0;
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( is_same_group( gch, ch ) && !IS_AFFECTED(gch,AFF_CHARM))
members++;
}
if ( members < 2 )
{
ch->println( "Just keep it all." );
return;
}
share_silver = amount_silver / members;
extra_silver = amount_silver % members;
share_gold = amount_gold / members;
extra_gold = amount_gold % members;
if ( share_gold == 0 && share_silver == 0 )
{
ch->println( "Don't even bother, cheapskate." );
return;
}
ch->silver -= amount_silver;
ch->silver += share_silver + extra_silver;
ch->gold -= amount_gold;
ch->gold += share_gold + extra_gold;
if (share_silver > 0)
{
ch->printlnf( "You split %d silver coins. Your share is %d silver.",
amount_silver,share_silver + extra_silver);
}
if ( share_gold > 0)
{
ch->printlnf( "You split %d gold coins. Your share is %d gold.",
amount_gold,share_gold + extra_gold);
}
if (share_gold == 0)
{
sprintf(buf,"$n splits %d silver coins. Your share is %d silver.",
amount_silver,share_silver);
}
else if (share_silver == 0)
{
sprintf(buf,"$n splits %d gold coins. Your share is %d gold.",
amount_gold,share_gold);
}
else
{
sprintf(buf,
"$n splits %d silver and %d gold coins, giving you %d silver and %d gold.\r\n",
amount_silver,amount_gold,share_silver,share_gold);
}
for ( gch = ch->in_room->people; gch != NULL; gch = gch->next_in_room )
{
if ( gch != ch && is_same_group(gch,ch) && !IS_AFFECTED(gch,AFF_CHARM))
{
act( buf, ch, NULL, gch, TO_VICT );
gch->gold += share_gold;
gch->silver += share_silver;
}
}
return;
}
/**************************************************************************/
void do_gtell( char_data *ch, char *argument )
{
char buf[MSL];
char_data *gch;
if ( argument[0] == '\0' )
{
ch->println( "Tell your group what?" );
return;
}
if ( IS_SET( ch->comm, COMM_NOTELL ) )
{
ch->println( "Your message didn't get through!" );
return;
}
// Note use of gch->printlnf so gtell works on sleepers.
sprintf( buf, "%s tells the group '%s'", ch->name, argument );
for ( gch = char_list; gch != NULL; gch = gch->next )
{
if ( is_same_group( gch, ch ) )
gch->printlnf( "%s", buf );
}
return;
}
/**************************************************************************/
void do_resetroom(char_data *ch, char *)
{
reset_room( ch->in_room, true );
ch->printlnf( "Room '%s' [%d] reset.",
ch->in_room->name, ch->in_room->vnum);
return;
}
/**************************************************************************/
void do_resetarea(char_data *ch, char *)
{
reset_area( ch->in_room->area);
reset_room( ch->in_room, true );
ch->printlnf( "Area '%s' [%d-%d] reset.",
ch->in_room->area->name, ch->in_room->area->min_vnum,
ch->in_room->area->max_vnum);
return;
}
/**************************************************************************/
void do_crashloop (char_data *ch, char * argument)
{
if (IS_NPC(ch))
{
do_huh(ch,"");
return;
}
if (str_cmp("confirm", argument))
{
ch->println( "`xType `=Ccrashloop confirm`x if you want to put the mud into" );
ch->println( "`xan endless loop to test the signal handling!" );
return;
}
for (;;); // loop endlessly ( Now that's some awesome code :) -- Ker )
}
/**************************************************************************/
/*
* It is very important that this be an equivalence relation:
* (1) A ~ A
* (2) if A ~ B then B ~ A
* (3) if A ~ B and B ~ C, then A ~ C
*/
bool is_same_group( char_data *ach, char_data *bch )
{
if ( ach == NULL || bch == NULL)
return false;
if ( ach->leader != NULL ) ach = ach->leader;
if ( bch->leader != NULL ) bch = bch->leader;
return ach == bch;
}
/**************************************************************************/
void do_ntell( char_data *ch, char *argument )
{
char arg[MIL], buf[MSL];
char_data *nch, *victim, *nvictim;
// unswitched mobs can't send ntells
if (IS_UNSWITCHED_MOB(ch))
{
return;
}
if (!IS_NOBLE(ch)){
do_huh(ch,"");
return;
}
// Check if they're being ordered to do this
if ( IS_SET( ch->dyn, DYN_IS_BEING_ORDERED ))
{
if ( ch->master )
ch->master->println( "Not going to happen." );
return;
}
argument = one_argument( argument, arg );
if ( arg[0] == '\0' || argument[0] == '\0' )
{
ch->println( "Noble tell whom what?" );
return;
}
if ( ( victim = get_whovis_player_world( ch, arg ) ) == NULL
|| IS_NPC(victim) )
{
ch->println( "They aren't here." );
return;
}
// Put in these lines from do_tell in because it made some sense. <shrug>
if (victim->controlling && victim->controlling->desc)
{
victim=victim->controlling;
}
if(ch==victim)
{
ch->println( "No point in sending an ntell to yourself." );
return;
};
// Also from do_tell, looked good to put.
if ( victim->desc == NULL)
{
act("$N seems to have misplaced $S link...try again later.", ch,NULL,victim,TO_CHAR);
sprintf(buf,"A noble ntells you '%s'\r\n`x", argument);
buf[0] = UPPER(buf[0]);
add_buf(victim->pcdata->buffer,buf);
return;
}
if (IS_SET(victim->comm,COMM_AFK))
{
if (IS_NPC(victim))
{
act("$E is AFK, and not receiving tells.",ch,NULL,victim,TO_CHAR);
return;
}
act("$E is AFK, but your tell will go through when $E returns.", ch,NULL,victim,TO_CHAR);
sprintf(buf,"A noble ntells you '%s'\r\n", argument );
buf[0] = UPPER(buf[0]);
add_buf(victim->pcdata->buffer,buf);
victim->printlnf( "A noble just tried to ntell you '%s' (you are marked as afk)`x", argument);
return;
}
if(!IS_NPC(ch))
ch->pcdata->did_ooc=true;
// Send the tell to the player.
victim->printlnf("`M%s ntells you '%s`M'"
"(you can use nreply to talk back if you need to)`x\r\n",
IS_IMMORTAL(victim)?PERS(ch,victim):"A noble", argument );
// Start the broadcast of the ntell to all nobles.
for ( nch = player_list; nch; nch = nch->next_player )
{
if (TRUE_CH(ch)==nch)
{
ch->printlnf( "`MYou ntell %s '%s`M'", victim->name, argument);
continue;
}
// dont see both the noble broadcast and the personal message
if( nch==victim)
{
continue;
};
nvictim=nch;
// ntalk going thru switch
if (nvictim->controlling && nvictim->controlling->desc)
nvictim=nvictim->controlling;
if (IS_NOBLE(nch))
{
if (IS_IMMORTAL(nch))
{
nvictim->printlnf( "`M<%s ntells %s>: '%s`M'`x",
TRUE_CH(ch)->name, victim->name, argument);
}else{
nvictim->printlnf( "`M<A noble ntells %s>: '%s`M'`x", victim->name, argument);
}
}
}
return;
}
/**************************************************************************/
void do_nreply( char_data *ch, char *argument )
{
char_data *nch, *victim;
// unswitched mobs can't send nreplies
if (IS_UNSWITCHED_MOB(ch))
{
return;
}
if ( IS_NULLSTR(argument) )
{
ch->println( "Nreply what?" );
return;
}
//Start the broadcast of the nreply to all nobles.
for ( nch = player_list; nch; nch = nch->next_player )
{
if (TRUE_CH(ch)==nch)
{
ch->printlnf( "`MYou nreply '%s`M'", argument);
continue;
}
victim=nch;
// ntalk going thru switch
if (victim->controlling && victim->controlling->desc)
victim=victim->controlling;
if (IS_NOBLE(nch))
{
victim->printlnf( "`M<%s nreplies> '%s`M'`x",
TRUE_CH(ch)->name, argument);
}
}
return;
}
/**************************************************************************/
void do_declineooc(char_data *ch, char *argument)
{
char_data *victim;
char arg[MIL];
int minutes = 0;
argument = one_argument( argument, arg );
if ( IS_NULLSTR( arg ))
{
ch->println( "Who do you want to decline?" );
return;
}
if ( !IS_NULLSTR( argument ))
{
minutes = atoi( argument );
}
if (( victim = get_whovis_player_world( ch, arg )) == NULL )
{
ch->println( "They are not playing." );
return;
}
ch->printlnf( "`cSending ooc chat decline to %s.`x", victim->name);
if ( minutes > 0 )
{
ch->printlnf( "`c You have specified that you will be available in %d minute(s).`x", minutes );
}
victim->printlnf( "`c%s has declined an ooc chat with you.", ch->name );
if ( minutes > 0 )
{
victim->printlnf( "`c %s has specified that they will be available in approximately %d minute(s).`x",
ch->name, minutes );
victim->println( "`c Please respect their wishes and be patient.`x" );
}
}
/**************************************************************************/
extern bool hotreboot_in_progress;
/**************************************************************************/
// turn mccp on/off
void do_mccp( char_data *ch, char *argument )
{
connection_data *d=TRUE_CH(ch)->desc;
#ifndef MCCP_ENABLED
ch->wrapln("Mud Client Compression Protocol (MCCP) support has not "
"been enabled for this compile of the mud therefore unavailable.");
ch->wraplnf("There have been a total of %d uncompressed bytes sent to your connection",
d?d->bytes_sent:0);
return;
#else
if (!d) {
ch->println("You don't have an descriptor!?!");
return;
}
if(IS_NULLSTR(argument)){
unsigned int bs=d->bytes_sent;
unsigned int bsbc=d->bytes_sent_before_compression;
unsigned int bsac=d->bytes_sent_after_compression;
ch->titlebar("MUD CLIENT COMPRESSION PROTOCOL SYNTAX");
ch->println(" Syntax: `=Cmccp on2`x - to force mccp on (v2 startup).");
ch->println(" Syntax: `=Cmccp on1`x - to force mccp on (v1 startup).");
ch->println(" Syntax: `=Cmccp off`x - to force mccp off.");
ch->titlebar("MCCP CONNECTION STATISTICS");
if(d->out_compress){
ch->printlnf(" `WYour connection is currently connected with mccp%d.`x",
d->mccp_version);
}else{
ch->println(" Your connection is currently not making use of mccp.");
}
ch->printlnf(" Total bytes sent to your connection: %d", bs);
if(d->out_compress){
ch->printlnf(" Bytes sent to your connection after compression: %7d", bsac);
ch->printlnf(" Bytes sent to your connection before compression:%7d", bsbc);
if(bsbc){
ch->printlnf(" Compression ratio: %0.2f%%`x", (float)bsac*100/ (float)bsbc );
}
}
ch->titlebar("");
return;
}
if(hotreboot_in_progress){
ch->println("You can't change your mccp status while a hotreboot is in progress");
return;
}
if(!str_cmp("on2", argument)){
if(d->out_compress){
ch->println("Your connection is already compressed.");
}else{
ch->println("Manually starting mccp2 compression.");
d->mccp_version=2;
d->begin_compression();
}
return;
}
if(!str_cmp("on1", argument)){
if(d->out_compress){
ch->println("Your connection is already compressed.");
}else{
ch->println("Manually starting mccp1 compression.");
d->mccp_version=1;
d->begin_compression();
}
return;
}
if(!str_cmp("off", argument)){
if(d->out_compress){
ch->printlnf("Stopping mccp%d compression.", d->mccp_version);
d->end_compression();
}else{
ch->println("You don't currently have a compressed connection to turn off.");
}
return;
}
ch->printlnf("Unrecognised command '%s'", argument);
do_mccp(ch,"");
#endif // MCCP_ENABLED
}
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/
/**************************************************************************/