/* speech.c */
#include "copyright.h"
/* Commands which involve speaking */
#include <ctype.h>
#include <string.h>
#include "config.h"
#include "externs.h"
#include "db.h"
#include "interface.h"
#include "match.h"
char *spname(thing)
dbref thing;
{
static char buff[BUFFER_LEN];
#ifdef FULL_INVIS
if(!Dark(thing)) {
strcpy(buff, db[thing].name);
} else {
if(Typeof(thing) != TYPE_PLAYER) {
strcpy(buff, "Something");
} else {
strcpy(buff, "Someone");
}
}
#else
strcpy(buff, db[thing].name);
#endif
return (buff);
}
/* this function is a kludge for regenerating messages split by '=' */
const char *reconstruct_message(arg1, arg2)
const char *arg1;
const char *arg2;
{
static char buf[BUFFER_LEN];
if (arg2 && *arg2) {
strcpy(buf, arg1);
strcat(buf, " = ");
strcat(buf, arg2);
return buf;
} else {
return arg1;
}
}
void do_say(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref loc;
const char *message;
char tbuf1[BUFFER_LEN];
if ((loc = getloc(player)) == NOTHING)
return;
message = reconstruct_message(arg1, arg2);
strcpy(tbuf1, pronoun_substitute(player, message, player));
/* notify everybody */
notify(player, tprintf("You say \"%s\"", tbuf1));
notify_except(db[loc].contents, player,
tprintf("%s says \"%s\"", spname(player), tbuf1));
}
void do_oemit(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref who;
dbref loc;
char tbuf1[BUFFER_LEN];
void oemit_notify_except();
init_match(player, arg1, TYPE_PLAYER);
if ((loc = getloc(player)) == NOTHING)
return;
match_neighbor();
match_me();
switch (who = match_result()) {
case NOTHING:
case AMBIGUOUS:
who = player;
default:
strcpy(tbuf1, pronoun_substitute(player, arg2, player));
notify(player, tprintf("%s", tbuf1));
oemit_notify_except(db[loc].contents, player, who, tbuf1);
}
}
void do_whisper(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref who;
int key;
const char *gap;
init_match(player, arg1, TYPE_PLAYER);
match_neighbor();
match_possession();
match_container();
match_me();
if (Wizard(player)) {
match_absolute();
match_player();
}
switch (who = match_result()) {
case NOTHING:
notify(player, "Whisper to whom?");
break;
case AMBIGUOUS:
notify(player, "I don't know who you mean!");
break;
default:
gap = " ";
switch (*arg2) {
case SEMI_POSE_TOKEN:
gap = "";
case POSE_TOKEN:
key = 1;
arg2 = arg2 + 1;
break;
default:
key = 2;
break;
}
switch (key) {
case 1:
notify(player, tprintf("%s senses, \"%s%s%s\"", db[who].name,
db[player].name, gap, arg2));
notify(who, tprintf("You sense: %s%s%s", db[player].name, gap, arg2));
break;
case 2:
notify(player,
tprintf("You whisper, \"%s\" to %s.", arg2, db[who].name));
notify(who,
tprintf("%s whispers, \"%s\"", db[player].name, arg2));
break;
}
break;
}
}
void do_pemit(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref who;
char tbuf1[BUFFER_LEN];
init_match(player, arg1, NOTYPE);
match_neighbor();
match_possession();
match_container();
match_me();
match_here();
match_player();
match_absolute();
switch (who = match_result()) {
case NOTHING:
notify(player, "I don't see that player here.");
break;
case AMBIGUOUS:
notify(player, "I don't know who you mean!");
break;
default:
if (Typeof(who) != TYPE_PLAYER && Typeof(who) != TYPE_THING) {
notify(player, "Only players and things can hear @pemits.");
break;
}
if (Haven(who) && (player != who)) {
notify(player,tprintf("I'm sorry, but %s wishes to be left alone now.",
db[who].name));
return;
}
strcpy(tbuf1, pronoun_substitute(player, arg2, player));
notify(player,
tprintf("You pemit \"%s\" to %s.", tbuf1, db[who].name));
if (Nospoof(who)) {
notify(who,
tprintf("[%s->%s] %s", db[player].name, db[who].name, tbuf1));
} else {
notify(who,
tprintf("%s", tbuf1));
}
break;
}
}
void do_pose(player, arg1, arg2, space)
dbref player;
const char *arg1, *arg2;
int space;
{
dbref loc;
const char *message;
char tbuf1[BUFFER_LEN];
if ((loc = getloc(player)) == NOTHING)
return;
message = reconstruct_message(arg1, arg2);
strcpy(tbuf1, pronoun_substitute(player, message, player));
/* notify everybody */
if(!space)
notify_except(db[loc].contents, NOTHING,
tprintf("%s %s", spname(player), tbuf1));
else
notify_except(db[loc].contents, NOTHING,
tprintf("%s%s", spname(player), tbuf1));
}
void do_wall(player, arg1, arg2, key)
dbref player;
const char *arg1;
const char *arg2;
int key;
{
const char *gap;
const char *message;
if (!Wizard(player)) {
notify(player, "Having delusions of grandeur today, are we?");
return;
}
message = reconstruct_message(arg1, arg2);
gap = " ";
switch (*arg1) {
case SAY_TOKEN:
key = 1;
message = message + 1;
break;
case SEMI_POSE_TOKEN:
gap = "";
case POSE_TOKEN:
key = 2;
message = message + 1;
break;
}
switch (key) {
case 2:
fprintf(stderr, "WALL from %d: %s%s%s\n", player, db[player].name,
gap, message);
raw_broadcast(0, "Announcement: %s%s%s", db[player].name, gap, message);
break;
case 3:
fprintf(stderr, "WALL from %s(%d): %s\n", db[player].name, player,
message);
raw_broadcast(0, "Announcement [%s]: %s", db[player].name, message);
break;
default:
fprintf(stderr, "WALL from %s(%d): %s\n", db[player].name, player,
message);
raw_broadcast(0, "Announcement: %s shouts, \"%s\"", db[player].name,
message);
break;
}
}
void do_wizwall(player, arg1, arg2, privs, key)
dbref player;
const char *arg1;
const char *arg2;
int privs;
int key;
{
/* privs is 0 for wizard wizwall, 1 for royalty-wizard wizwall */
const char *gap;
const char *message;
if (!Wizard(player)
#ifdef ROYALTY_FLAG
&& !Royalty(player)
#endif
) {
notify(player, "What makes you think someone wants to listen to you?");
return;
}
if (!privs && !Wizard(player)) {
notify(player, "Posing as a wizard could be hazardous to your health.");
return;
}
message = reconstruct_message(arg1, arg2);
gap = " ";
switch(*arg1) {
case SAY_TOKEN:
key = 1;
message = message + 1;
break;
case SEMI_POSE_TOKEN:
gap = "";
case POSE_TOKEN:
key = 2;
message = message + 1;
break;
}
if (!privs) {
switch(key) {
case 2:
raw_broadcast(WIZARD, "Broadcast: %s%s%s", db[player].name, gap,
message);
break;
case 3:
raw_broadcast(WIZARD, "Broadcast [%s]: %s", db[player].name, message);
break;
default:
raw_broadcast(WIZARD, "Broadcast: %s says, \"%s\"", db[player].name,
message);
}
}
#ifdef ROYALTY_FLAG
else {
switch (key) {
case 2:
raw_broadcast(WIZARD, "Admin: %s%s%s", db[player].name, gap, message);
raw_broadcast(ROYALTY, "Admin: %s%s%s", db[player].name, gap, message);
break;
case 3:
raw_broadcast(WIZARD, "Admin [%s]: %s", db[player].name, message);
raw_broadcast(ROYALTY, "Admin [%s]: %s", db[player].name, message);
break;
default:
raw_broadcast(WIZARD, "Admin: %s says, \"%s\"", db[player].name,
message);
raw_broadcast(ROYALTY, "Admin: %s says, \"%s\"", db[player].name,
message);
}
}
#endif
}
void do_gripe(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref loc;
const char *message;
loc = db[player].location;
message = reconstruct_message(arg1, arg2);
fprintf(stderr, "GRIPE from %s(%d) in %s(%d): %s\n",
db[player].name, player,
db[loc].name, loc,
message);
fflush(stderr);
/* try telling GOD about it */
if (!Haven(GOD)) {
notify(GOD,
tprintf("%s gripes: \"%s\"",
unparse_object(GOD, player), message));
}
notify(player, "Your complaint has been duly noted.");
}
/* doesn't really belong here, but I couldn't figure out where else */
void do_page(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref target;
const char *message, *gap;
char *spoof;
int key;
if ((!*arg1) && (!*arg2)) {
if (db[player].pageto == NOTHING) {
notify(player, "You haven't paged anyone since connecting.");
} else {
notify(player,
tprintf("You last paged %s.", db[db[player].pageto].name));
}
return;
}
if (Haven(player))
notify(player, "You are set HAVEN and cannot receive pages.");
if (index(arg1, ' ') != NULL) {
message = reconstruct_message(arg1, arg2);
target = db[player].pageto;
} else {
message = arg2;
if (!*arg1) {
target = db[player].pageto;
} else if ((target = lookup_player(arg1)) == NOTHING) {
if (!*arg2) {
target = db[player].pageto;
message = arg1;
} else {
target = short_page(arg1);
}
}
}
if (target == NOTHING) {
notify(player, "I can't find who you're trying to page.");
return;
} else if (target == AMBIGUOUS) {
notify(player, "I'm not sure who you want to page!");
return;
} else if ((!(db[target].flags & PLAYER_CONNECT)) ||
(Dark(target) && Haven(target))) {
page_return(player, target, "Away", "AWAY",
"That player is not connected.");
return;
} else if (Haven(target)) {
page_return(player, target, "Haven", "HAVEN",
"That player is not accepting any pages.");
return;
} else if (!eval_boolexp(db[player].owner, db[target].usekey,
target, 0, USELOCK)) {
page_return(player, target, "Haven", "HAVEN",
"That player is not accepting your pages.");
return;
} if (!payfor(player, PAGE_COST)) {
notify(player, tprintf("You don't have enough %s.", MONIES));
return;
}
db[player].pageto = target;
gap = " ";
switch (*message) {
case SEMI_POSE_TOKEN:
gap = "";
case POSE_TOKEN:
key = 1;
message = message + 1;
break;
case NULL:
key = 2;
break;
default:
key = 3;
break;
}
if (Typeof(player) != TYPE_PLAYER && Nospoof(target))
strcpy(spoof, tprintf("[#%d] ", player));
else
strcpy(spoof, "");
switch (key) {
case 1:
notify(target, tprintf("%sFrom afar, %s%s%s", spoof,
db[player].name, gap, message));
notify(player, tprintf("Long distance to %s: %s%s%s", db[target].name,
db[player].name, gap, message));
break;
case 2:
notify(target, tprintf("%sYou sense that %s is looking for you in %s",
spoof, db[player].name, db[db[player].location].name));
notify(player, tprintf("You have paged %s.", db[target].name));
break;
case 3:
notify(target, tprintf("%s%s pages: %s", spoof, db[player].name,
message));
notify(player, tprintf("You paged %s with '%s'.", db[target].name,
message));
break;
}
page_return(player, target, "Idle", "IDLE", NULL);
return;
}
void esnotify(player, msg, sender)
dbref player;
const char *msg;
dbref sender;
{
if (player < 0 || player >= db_top) return;
if (Nospoof(player)) {
notify(player, tprintf("[%s:] %s", spname(sender), msg));
} else {
notify(player, tprintf("%s", msg));
}
}
void notify_except(first, exception, msg)
dbref first;
dbref exception;
const char *msg;
{
if(first < 0 || first >= db_top)
return;
if (db[first].location != exception)
notify(db[first].location, msg);
DOLIST(first, first) {
if (first != exception) {
notify(first, msg);
}
}
}
void emit_notify_except(first, exception, msg)
dbref first;
dbref exception;
const char *msg;
{
if(first < 0 || first >= db_top)
return;
if (db[first].location != exception)
esnotify(db[first].location, msg, exception);
DOLIST(first, first) {
if (first != exception) {
esnotify(first, msg, exception);
}
}
}
void notify_except2(first, exc1, exc2, msg)
dbref first;
dbref exc1;
dbref exc2;
const char *msg;
{
if(first < 0 || first >= db_top)
return;
if ((db[first].location != exc1) && (db[first].location != exc2))
notify(db[first].location, msg);
DOLIST(first, first) {
if (first != exc1 && first != exc2) {
notify(first, msg);
}
}
}
void oemit_notify_except(first, exc1, exc2, msg)
dbref first;
dbref exc1;
dbref exc2;
const char *msg;
{
if(first < 0 || first >= db_top)
return;
if ((db[first].location != exc1) && (db[first].location != exc2))
esnotify(db[first].location, msg, exc1);
DOLIST(first, first) {
if (first != exc1 && first != exc2) {
esnotify(first, msg, exc1);
}
}
}
void do_emit(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref loc;
const char *message;
char tbuf1[BUFFER_LEN];
if ((loc = getloc(player)) == NOTHING)
return;
message = reconstruct_message(arg1, arg2);
strcpy(tbuf1, pronoun_substitute(player, message, player));
/* notify everybody */
notify(player, tprintf("%s", tbuf1));
emit_notify_except(db[loc].contents, player, tbuf1);
}
void do_remit(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref room;
const char *rmno;
char tbuf1[BUFFER_LEN];
init_match(player, arg1, NOTYPE);
match_here();
match_absolute();
match_neighbor();
match_me();
match_player();
match_exit();
switch (room = match_result()) {
case NOTHING:
case AMBIGUOUS:
notify(player, "I can't find that.");
break;
default:
if (Typeof(room) == TYPE_EXIT) {
notify(player, "There can't be anything in that!");
break;
}
if((Typeof(room) == TYPE_PLAYER) && Haven(room)) {
notify(player, "That person is havened. No @remitting allowed.");
break;
}
strcpy(tbuf1, pronoun_substitute(player, arg2, player));
rmno = unparse_object(player, room);
notify(player,
tprintf("You remit, \"%s\" in %s", tbuf1, rmno));
oemit_notify_except(db[room].contents, player, room, tbuf1);
}
}
void do_lemit(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
dbref room;
int rec = 0;
const char *message;
char tbuf1[BUFFER_LEN];
message = reconstruct_message(arg1, arg2);
strcpy(tbuf1, pronoun_substitute(player, message, player));
/* only players and things may use this command */
if (Typeof(player) != TYPE_PLAYER && Typeof(player) != TYPE_THING)
return;
/* prevent infinite loop if player is inside himself */
if ((room = db[player].location) == player) {
notify(player, "Invalid container object.");
return;
}
while ((Typeof(room) != TYPE_ROOM) && (rec < 15)) {
room = db[room].location;
rec++;
}
if (rec > 15) {
notify(player, "Too many containers.");
return;
} else {
notify(player, tprintf("You lemit: \"%s\"", tbuf1));
oemit_notify_except(db[room].contents, player, room, tbuf1);
}
}
void do_zemit(player, arg1, arg2)
dbref player;
const char *arg1;
const char *arg2;
{
const char *where;
dbref zone;
dbref room;
char tbuf1[BUFFER_LEN];
init_match(player, arg1, NOTYPE);
match_absolute();
switch (zone = match_result()) {
case NOTHING:
case AMBIGUOUS:
notify(player, "Invalid zone.");
return;
default:
if (!controls(player, zone)) {
notify(player, "Permission denied.");
return;
}
if (!payfor(player, FIND_COST)) {
notify(player, "Sorry, you don't have enough money to do that.");
return;
}
strcpy(tbuf1, pronoun_substitute(player, arg2, player));
where = unparse_object(player, zone);
notify(player,
tprintf("You zemit, \"%s\" in zone %s", tbuf1, where));
for (room = 0; room < db_top; room++)
if ((getzone(room) == zone) && (Typeof(room) == TYPE_ROOM))
oemit_notify_except(db[room].contents, player, room, tbuf1);
}
}