/**************************************************************************/ // 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 } /**************************************************************************/ /**************************************************************************/ /**************************************************************************/ /**************************************************************************/ /**************************************************************************/