/* ************************************************************************
* File: act.comm.c Part of CircleMUD *
* Usage: Player-level communication commands *
* *
* All rights reserved. See license.doc for complete information. *
* *
* Copyright (C) 1993 by the Trustees of the Johns Hopkins University *
* CircleMUD is based on DikuMUD, Copyright (C) 1990, 1991. *
************************* ********************************************** */
/* Archipelago changes by Alastair J. Neil Copyright (C) 1993, 94, 95, 96 */
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include "structs.h"
#include "utils.h"
#include "comm.h"
#include "interpreter.h"
#include "handler.h"
#include "db.h"
#include "screen.h"
#include "spells.h"
/* extern variables */
extern struct room_data *world;
extern struct descriptor_data *descriptor_list;
extern struct color_list_type colors[];
extern struct char_data *character_list;
int find_track_length(sh_int src, sh_int target, int max);
bool search_info_keyword(struct char_data *target,int *index,char *keywd1,char *keywd2,int mode);
void perform_tell(struct char_data *ch, struct char_data *vict, char *arg);
ACMD(do_respond)
{
struct char_data *tch = character_list;
skip_spaces(&argument);
if (GET_LAST_TELL(ch) == NOBODY)
send_to_char("You have no-one to respond to!\r\n", ch);
else if (!*argument)
send_to_char("What is your response?\r\n", ch);
else {
/*
* Make sure the person you're replying to is still playing by searching
* for them. Note, now last tell is stored as player IDnum instead of
* a pointer, which is much better because it's safer, plus will still
* work if someone logs out and back in again.
*/
while (tch != NULL && GET_IDNUM(tch) != GET_LAST_TELL(ch))
tch = tch->next;
if (tch == NULL)
send_to_char("They are no longer playing.\r\n", ch);
else
perform_tell(ch, tch, argument);
}
}
ACMD(do_say)
{
int i;
char *len;
for (i = 0; *(argument + i) == ' '; i++)
;
if (ch->equipment[WEAR_MOUTH]){
send_to_char("you can talk with something in your mouth?\r\n", ch);
return;
}
if (!*(argument + i))
send_to_char("Yes, but WHAT do you want to say?\r\n", ch);
else {
for (len = argument +i; *(len) != '\0'; len++)
;
len--;
switch (*len){
case '?':
sprintf(buf, "$n asks '%s'", argument + i);
sprintf(buf1, "You ask '%s'\r\n", argument + i);
break;
case '!':
sprintf(buf, "$n exclaims '%s'", argument + i);
sprintf(buf1, "You exclaim '%s'\r\n", argument + i);
break;
default:
sprintf(buf, "$n says '%s'", argument + i);
sprintf(buf1, "You say '%s'\r\n", argument + i);
break;
}
act(buf, FALSE, ch, 0, 0, TO_ROOM);
if (!PRF_FLAGGED(ch, PRF_NOREPEAT)) {
send_to_char(buf1, ch);
} else
send_to_char("Ok.\r\n", ch);
}
}
ACMD(do_gsay)
{
int i;
struct char_data *k;
struct follow_type *f;
for (i = 0; *(argument + i) == ' '; i++)
;
if (!IS_AFFECTED(ch, AFF_GROUP)) {
send_to_char("But you are not the member of a group!\r\n", ch);
return;
}
if (!*(argument + i))
send_to_char("Yes, but WHAT do you want to group-say?\r\n", ch);
else {
if (ch->master)
k = ch->master;
else
k = ch;
sprintf(buf, "%s group-says '%s'\r\n", GET_NAME(ch), argument + i);
if (IS_AFFECTED(k, AFF_GROUP) && (k != ch))
send_to_char(buf, k);
for (f = k->followers; f; f = f->next)
if (IS_AFFECTED(f->follower, AFF_GROUP) && (f->follower != ch))
send_to_char(buf, f->follower);
if (!PRF_FLAGGED(ch, PRF_NOREPEAT)) {
sprintf(buf, "You group-say '%s'\r\n", argument + i);
send_to_char(buf, ch);
} else
send_to_char("Ok.\r\n", ch);
}
}
ACMD(do_tell)
{
struct char_data *vict;
half_chop(argument, buf, buf2);
if (!*buf || !*buf2)
send_to_char("Who do you wish to tell what??\r\n", ch);
else if (!(vict = get_char_vis(ch, buf)))
send_to_char("No-one by that name here..\r\n", ch);
else if (ch == vict)
send_to_char("You try to tell yourself something.\r\n", ch);
else if (IS_MOB(vict))
send_to_char("No-one by that name here..\r\n", ch);
else
perform_tell(ch, vict, buf2);
}
void perform_tell(struct char_data *ch, struct char_data *vict, char *arg)
{
if (PRF_FLAGGED(ch, PRF_NOTELL))
send_to_char("You can't tell other people while you have notell on.\r\n", ch);
else if (!IS_NPC(vict) && !vict->desc) /* linkless */
act("$E's linkless at the moment.", FALSE, ch, 0, vict, TO_CHAR);
else if (PLR_FLAGGED(vict, PLR_WRITING))
act("$E's writing a message right now, try again later.",
FALSE, ch, 0, vict, TO_CHAR);
else if (PLR_FLAGGED(vict, PLR_BUILDING))
act("$E's making part of the universe right now, try again later.",
FALSE, ch, 0, vict, TO_CHAR);
else if ((PRF_FLAGGED(vict, PRF_NOTELL)))
act("$E refuses to hear you.", FALSE, ch, 0, vict, TO_CHAR);
else if (!AWAKE(vict) && GET_MOVE(vict) > 0)
act("$E can't hear you, $E's sleeping.", FALSE, ch, 0, vict, TO_CHAR);
else if (!AWAKE(vict) && GET_MOVE(vict) < 0)
act("$E can't hear you, $E's in an exhausted slumber.", FALSE, ch, 0, vict, TO_CHAR);
else {
sprintf(buf, "%s tells you '%s'%s\r\n", GET_NAME(ch), arg,
CCNRM(vict, C_NRM));
CAP(buf);
send_to_char(CCRED(vict, C_NRM), vict);
send_to_char(buf, vict);
if (!PRF_FLAGGED(ch, PRF_NOREPEAT)) {
sprintf(buf, "%sYou tell %s '%s'%s\r\n", CCRED(ch, C_CMP),
GET_NAME(vict), arg, CCNRM(ch, C_CMP));
send_to_char(buf, ch);
} else
send_to_char("Ok.\r\n", ch);
vict->specials2.last_tell_id = GET_IDNUM(ch);
}
}
ACMD(do_whisper)
{
struct char_data *vict;
half_chop(argument, buf, buf2);
if (!*buf || !*buf2)
send_to_char("Who do you want to whisper to.. and what??\r\n", ch);
else if (!(vict = get_char_room_vis(ch, buf)))
send_to_char("No-one by that name here..\r\n", ch);
else if (vict == ch) {
act("$n whispers quietly to $mself.", FALSE, ch, 0, 0, TO_ROOM);
send_to_char("You can't seem to get your mouth close enough to your ear...\r\n", ch);
} else {
if (!(vict = get_char_room_vis(ch, buf)))
send_to_char("No-one by that name here..\r\n", ch);
else {
sprintf(buf, "$n whispers to you, '%s'", buf2);
act(buf, FALSE, ch, 0, vict, TO_VICT);
sprintf(buf, "You whisper '%s' in $N's ear.", buf2);
act(buf, FALSE, ch, 0, vict, TO_CHAR);
act("$N whispers something to $n.", FALSE, vict, 0, ch, TO_NOTVICT);
}
}
}
ACMD(do_ask)
{
struct char_data *vict;
half_chop(argument, buf, buf2);
if (ch->equipment[WEAR_MOUTH]){
send_to_char("you can talk with something in your mouth?\r\n", ch);
return;
}
if (!*buf2){
act("Ok ask sure, but ask about what?",FALSE,ch,0,0,TO_CHAR);
return;}
if (!(vict = get_char_room_vis(ch, buf)))
send_to_char("No-one by that name here..\r\n", ch);
else if (vict == ch) {
act("$n quietly asks $mself a question.", FALSE, ch, 0, 0, TO_ROOM);
send_to_char("You think about it for a while...\r\n", ch);
}
else {
if (!(vict = get_char_room_vis(ch, buf)))
send_to_char("How do you expect an answer when you aren't in the room?\r\n", ch);
else {
sprintf(buf, "$n asks you '%s'", buf2);
act(buf, FALSE, ch, 0, vict, TO_VICT);
send_to_char("Ok.\r\n", ch);
act("$n asks $N a question.", FALSE, ch, 0, vict, TO_NOTVICT);
}
}
}
#define MAX_NOTE_LENGTH 1000 /* arbitrary */
ACMD(do_write)
{
struct obj_data *paper = 0, *pen = 0;
char *papername, *penname;
papername = buf1;
penname = buf2;
argument_interpreter(argument, papername, penname);
if (!ch->desc)
return;
if (!*papername) /* nothing was delivered */ {
send_to_char("Write? With what? ON what? What are you trying to do?!?\r\n", ch);
return;
}
if (*penname) /* there were two arguments */ {
if (!(paper = get_obj_in_list_vis(ch, papername, ch->inventory))) {
sprintf(buf, "You have no %s.\r\n", papername);
send_to_char(buf, ch);
return;
}
if (!(pen = get_obj_in_list_vis(ch, penname, ch->inventory))) {
sprintf(buf, "You have no %s.\r\n", papername);
send_to_char(buf, ch);
return;
}
} else /* there was one arg.let's see what we can find */ {
if (!(paper = get_obj_in_list_vis(ch, papername, ch->inventory))) {
sprintf(buf, "There is no %s in your inventory.\r\n", papername);
send_to_char(buf, ch);
return;
}
if (paper->obj_flags.type_flag == ITEM_PEN) /* oops, a pen.. */ {
pen = paper;
paper = 0;
} else if (paper->obj_flags.type_flag != ITEM_NOTE) {
send_to_char("That thing has nothing to do with writing.\r\n", ch);
return;
}
/* one object was found. Now for the other one. */
if (!ch->equipment[HOLD]) {
sprintf(buf, "You can't write with a %s alone.\r\n", papername);
send_to_char(buf, ch);
return;
}
if (!CAN_SEE_OBJ(ch, ch->equipment[HOLD])) {
send_to_char("The stuff in your hand is invisible! Yeech!!\r\n", ch);
return;
}
if (pen)
paper = ch->equipment[HOLD];
else
pen = ch->equipment[HOLD];
}
/* ok.. now let's see what kind of stuff we've found */
if (pen->obj_flags.type_flag != ITEM_PEN) {
act("$p is no good for writing with.", FALSE, ch, pen, 0, TO_CHAR);
} else if (paper->obj_flags.type_flag != ITEM_NOTE) {
act("You can't write on $p.", FALSE, ch, paper, 0, TO_CHAR);
} else if (paper->action_description)
send_to_char("There's something written on it already.\r\n", ch);
else {
/* we can write - hooray! */
send_to_char("Ok.. go ahead and write.. end the note with a @.\r\n", ch);
act("$n begins to jot down a note.", TRUE, ch, 0, 0, TO_ROOM);
ch->desc->str = &paper->action_description;
ch->desc->max_str = MAX_NOTE_LENGTH;
act("$n finishes jottting down a note.", TRUE, ch, 0, 0, TO_ROOM);
}
}
ACMD(do_page)
{
struct descriptor_data *d;
struct char_data *vict;
if (IS_NPC(ch)) {
send_to_char("Monsters can't page.. go away.\r\n", ch);
return;
}
if (!*argument) {
send_to_char("Whom do you wish to page?\r\n", ch);
return;
}
half_chop(argument, buf, buf2);
if (!str_cmp(buf, "all")) {
if (GET_LEVEL(ch) > LEVEL_GOD) {
sprintf(buf, "\007\007*%s* %s\r\n", GET_NAME(ch), buf2);
for (d = descriptor_list; d; d = d->next)
if (!d->connected)
SEND_TO_Q(buf, d);
} else
send_to_char("You will never be godly enough to do that!\r\n", ch);
return;
}
if ((vict = get_char_vis(ch, buf))) {
sprintf(buf, "\007\007*%s* %s\r\n", GET_NAME(ch), buf2);
send_to_char(buf, vict);
if (PRF_FLAGGED(ch, PRF_NOREPEAT))
send_to_char("Ok.\r\n", ch);
else
send_to_char(buf, ch);
return;
} else
send_to_char("There is no such person in the game!\r\n", ch);
}
/**********************************************************************
* generalized communication func, originally by Fred C. Merkel (Torg) *
*********************************************************************/
ACMD(do_gen_com)
{
extern int level_can_shout;
extern int holler_move_cost;
struct descriptor_data *i;
char buf3[MAX_STRING_LENGTH];
char buf4[MAX_STRING_LENGTH];
char buf5[MAX_STRING_LENGTH];
char buf6[MAX_STRING_LENGTH];
char name[MAX_NAME_LENGTH+10];
int col, dist;
static int channels[] = {
0,
PRF_DEAF,
PRF_NOGOSS,
PRF_NOAUCT,
PRF_NOGRATZ,
PRF_NOBRAG
};
static char *com_msgs[][4] = {
{ "You cannot yell!!\r\n",
"yell",
"",
"\7" },
{ "You cannot shout!!\r\n",
"shout",
"Turn off your noshout flag first!\r\n",
"\6" },
{ "You cannot gossip!!\r\n",
"gossip",
"You aren't even on the channel!\r\n",
"\3" },
{ "You cannot auction!!\r\n",
"auction",
"You aren't even on the channel!\r\n",
"\3" },
{ "You cannot congratulate!\r\n",
"congratulate",
"You aren't even on the channel!\r\n",
"\5" },
{ "You cannot brag!\r\n",
"brag",
"You aren't even on the channel!\r\n",
"\1" }
};
/* if (!ch->desc)
return;
*/
if (ch->equipment[WEAR_MOUTH]){
send_to_char("You can talk with something in your mouth?\r\n", ch);
return;
}
if (PLR_FLAGGED(ch, PLR_NOSHOUT)) {
send_to_char(com_msgs[subcmd][0], ch);
return;
}
if (GET_LEVEL(ch) < level_can_shout) {
sprintf(buf1, "You must be at least level %d before you can %s.\r\n",
level_can_shout, com_msgs[subcmd][1]);
send_to_char(buf1, ch);
return;
}
if (subcmd == SCMD_HOLLER) {
if (GET_MOVE(ch) < holler_move_cost) {
send_to_char("You're too exhausted to yell.\r\n", ch);
return;
} else
GET_MOVE(ch) -= holler_move_cost;
}
if (PRF_FLAGGED(ch, channels[subcmd])) {
send_to_char(com_msgs[subcmd][2], ch);
return;
}
for (; *argument == ' '; argument++)
;
if (!(*argument)) {
sprintf(buf1, "Yes, %s, fine, %s we must, but WHAT???\r\n",
com_msgs[subcmd][1], com_msgs[subcmd][1]);
send_to_char(buf1, ch);
return;
}
/* strcpy(colon, com_msgs[subcmd][3]); */
col = *com_msgs[subcmd][3];
if (PRF_FLAGGED(ch, PRF_NOREPEAT))
send_to_char("Ok.\r\n", ch);
else {
if (COLOR_LEV(ch) >= C_CMP)
sprintf(buf1, "%sYou %s,%s '%s'%s\r\n", colors[col].high, com_msgs[subcmd][1],colors[col].high,
argument, KNRM);
else
sprintf(buf1, "You %s, '%s'\r\n", com_msgs[subcmd][1], argument);
send_to_char(buf1, ch);
}
strcpy(name, GET_NAME(ch));
*name = UPPER(*name);
sprintf(buf1, "%s %ss, '%s'\r\n", name, com_msgs[subcmd][1], argument);
sprintf(buf2, "Someone %ss, '%s'\r\n", com_msgs[subcmd][1], argument);
sprintf(buf3, "%s%s %ss,%s '%s'%s\r\n", colors[col].high, name,com_msgs[subcmd][1],colors[col].low , argument,
KNRM);
sprintf(buf4, "%sSomeone %ss,%s '%s'%s\r\n",colors[col].high, com_msgs[subcmd][1],colors[col].low, argument, KNRM);
for (i = descriptor_list; i; i = i->next) {
if (!i->connected && i != ch->desc &&
!PRF_FLAGGED(i->character, channels[subcmd]) &&
!PLR_FLAGGED(i->character, PLR_WRITING) &&
!PLR_FLAGGED(i->character, PLR_BUILDING)) {
if (subcmd == SCMD_SHOUT &&
(world[ch->in_room].zone != world[i->character->in_room].zone))
continue;
if (subcmd == SCMD_SHOUT) {
dist = find_track_length(ch->in_room, i->character->in_room, 10);
if (dist >= 10 || dist < 0)
continue;
else if (dist > 7 && dist < 10) {
sprintf(buf1, "You hear someone shouting in the distance.\r\n");
sprintf(buf2, "You hear someone shouting in the distance.\r\n");
sprintf(buf3, "%sYou hear someone shouting in the distance. %s\r\n", colors[col].high, KNRM);
sprintf(buf4, "%sYou hear someone shouting in the distance. %s\r\n", colors[col].high, KNRM);
}
else if ((dist >= 4) && (dist <= 7)) {
if (!strncmp(name,"A ",2) || !strncmp(name,"The ",4))
*name = LOWER(*name);
sprintf(buf1, "You hear %s %sing in the distance.\r\n", name, com_msgs[subcmd][1]);
sprintf(buf2, "You hear someone %sing in the distance.\r\n", com_msgs[subcmd][1]);
sprintf(buf3, "%sYou hear %s %sing in the distance.%s\r\n", colors[col].high, name,com_msgs[subcmd][1], KNRM);
sprintf(buf4, "%sYou hear someone %sing in the distance.%s\r\n", colors[col].high, com_msgs[subcmd][1], KNRM);
}
}
if (subcmd != SCMD_GOSSIP
&& (GET_POS(i->character) < POSITION_RESTING))
continue;
if (CAN_SEE(i->character, ch)) {
if (COLOR_LEV(i->character) >= C_NRM)
send_to_char(buf3, i->character);
else
send_to_char(buf1, i->character);
}
else {
if (COLOR_LEV(i->character) >= C_NRM)
if (GET_LEVEL(ch) > LEVEL_BUILDER)
send_to_char(buf4, i->character);
else{
sprintf(buf4, "%sSomebody %ss,%s '%s'%s\r\n",colors[col].high, com_msgs[subcmd][1],colors[col].low, argument, KNRM);
send_to_char(buf4, i->character);
}
else
if (GET_LEVEL(ch) > LEVEL_BUILDER)
send_to_char(buf2, i->character);
else{
sprintf(buf2, "Somebody %ss, '%s'\r\n", com_msgs[subcmd][1], argument);
send_to_char(buf2, i->character);
}
}
}
}
}
ACMD(do_qsay)
{
struct descriptor_data *i;
if (!PRF_FLAGGED(ch, PRF_QUEST)) {
send_to_char("You aren't even part of the quest!\r\n", ch);
return;
}
for (; *argument == ' '; argument++)
;
if (!(*argument))
send_to_char("Quest-say? Yes! Fine! Quest-say we must, but WHAT??\r\n", ch);
else {
if (PRF_FLAGGED(ch, PRF_NOREPEAT))
send_to_char("Ok.\r\n", ch);
else {
sprintf(buf1, "You quest-say, '%s'\r\n", argument);
send_to_char(buf1, ch);
}
sprintf(buf1, "$n quest-says, '%s'", argument);
for (i = descriptor_list; i; i = i->next)
if (!i->connected && i != ch->desc &&
PRF_FLAGGED(i->character, PRF_QUEST) &&
!PLR_FLAGGED(i->character, PLR_WRITING))
act(buf1, 0, ch, 0, i->character, TO_VICT);
}
}