/* speech.c */
/* $Id: speech.c,v 1.21 1993/09/18 19:03:46 nils Exp $ */
/* Commands which involve speaking */
#include <ctype.h>
#include <sys/types.h>
#include "db.h"
#include "interface.h"
#include "net.h"
#include "match.h"
#include "config.h"
#include "externs.h"
/* generate name for object to be used when spoken */
/* for spoof protection player names always capitalized, object names */
/* always lower case */
char *spname(thing)
dbref thing;
{
/* ack! this is evil to do. -shkoo
static char buff[1024];
strcpy(buff,db[thing].name);
if (Typeof(thing)==TYPE_PLAYER)
buff[0]=to_upper(buff[0]);
else
buff[0]=to_lower(buff[0]);
return(buff);
*/
return db[thing].name;
}
/* this function is a kludge for regenerating messages split by '=' */
char *reconstruct_message(arg1,arg2)
char *arg1;
char *arg2;
{
static char buf[BUFFER_LEN];
if ( arg2 )
if ( *arg2 ) {
strcpy(buf, arg1?arg1:"");
strcat(buf, " = ");
strcat(buf, arg2);
return buf;
}
return arg1?arg1:"";
}
int sp_ok(player)
dbref player;
{
/* if ( ! Robot(player) && ! controls(player,db[player].location, TYPE_ADMIN))
{
notify(player,"Sorry robots may not speak in public");
return(0);
}
*/
return(1);
}
void do_say(player,arg1,arg2)
dbref player;
char *arg1;
char *arg2;
{
dbref loc;
char *message;
char buf[BUFFER_LEN],*bf;
if((loc = getloc(player)) == NOTHING) return;
if (!sp_ok(player))
return;
if(IS(loc,TYPE_ROOM,ROOM_AUDITORIUM) &&
!could_doit(player, loc, A_SLOCK)) {
did_it(player, loc, A_SFAIL, "Shh.", A_OSFAIL, NULL, A_ASFAIL);
return;
}
message = reconstruct_message(arg1, arg2);
pronoun_substitute(buf,player,message,player);
bf=buf+strlen(db[player].name)+1;
/* notify everybody */
notify(player, tprintf("You say \"%s\"",bf));
notify_in(loc,player,
tprintf("%s says \"%s\"", spname(player), bf));
}
void do_whisper(player,arg1,arg2)
dbref player;
char *arg1;
char *arg2;
{
dbref who;
char buf[BUFFER_LEN],*bf;
pronoun_substitute(buf, player, arg2, player);
bf = buf + strlen(db[player].name) + 1;
init_match(player, arg1, TYPE_PLAYER);
match_neighbor();
match_me();
if(power(player, POW_REMOTE)) {
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:
if ( *bf == ':' ) {
notify(player,
tprintf("You whisper-posed %s with \"%s %s\".",
db[who].name, spname(player), bf+1));
notify(who,
tprintf("%s whisper-poses: %s %s", spname(player), spname(player), bf+1));
/* wptr[0]=bf; */ /* Don't pass %0 */
did_it(player, who, NULL, 0, NULL, 0, A_AWHISPER);
break;
}
notify(player,
tprintf( "You whisper \"%s\" to %s.", bf, db[who].name));
notify(who,
tprintf( "%s whispers \"%s\"", spname(player), bf));
/* wptr[0]=bf; */ /* Don't pass %0 */
did_it(player, who, NULL, 0, NULL, 0, A_AWHISPER);
break;
}
}
void do_pose(player,arg1,arg2,possessive)
dbref player;
char *arg1;
char *arg2;
int possessive;
{
dbref loc;
char lastchar, *format;
char *message;
char buf[BUFFER_LEN], *bf;
if((loc = getloc(player)) == NOTHING) return;
if (!sp_ok(player))
return;
if(IS(loc,TYPE_ROOM,ROOM_AUDITORIUM) &&
!could_doit(player, loc, A_SLOCK)) {
did_it(player, loc, A_SFAIL, "Shhh.", A_OSFAIL, NULL, A_ASFAIL);
return;
}
if ( possessive ) {
/* get last character of player's name */
lastchar = to_lower(db[player].name[strlen(db[player].name)-1]);
format = (lastchar == 's') ? "%s' %s" : "%s's %s";
}
else
format = "%s %s";
message = reconstruct_message(arg1, arg2);
pronoun_substitute(buf,player,message,player);
bf=strlen(db[player].name)+buf+1;
/* notify everybody */
notify_in(loc,NOTHING,
tprintf(format, spname(player), bf));
}
void do_echo(player,arg1,arg2,type)
dbref player;
char *arg1, *arg2;
int type;
{
char *message = reconstruct_message(arg1,arg2);
char buf[1024];
if (type == 0) {
pronoun_substitute(buf, player, message, player);
message = buf+strlen(db[player].name) +1;
}
notify (player, message);
}
void do_emit(player,arg1,arg2,type)
dbref player;
char *arg1;
char *arg2;
int type;
{
dbref loc;
char *message;
char buf[BUFFER_LEN], *bf=buf;
if ((loc = getloc(player)) == NOTHING) return;
if (IS(loc, TYPE_ROOM, ROOM_AUDITORIUM) &&
!controls(player,loc,POW_SPOOF) &&
!could_doit(player, loc, A_SLOCK)) {
did_it(player, loc,A_SFAIL,"Shh.",A_OSFAIL,NULL,
A_ASFAIL);
return;
}
message = reconstruct_message(arg1,arg2);
if ( type == 0 ) {
pronoun_substitute(buf, player, message, player);
bf = buf + strlen(db[player].name) + 1;
}
if ( type == 1) {
strcpy(buf, message);
bf = buf;
}
if (power(player, POW_SPOOF)) {
notify_in(loc,NOTHING,tprintf("%s",bf));
return;
}
if (can_emit_msg(player, db[player].location, bf))
notify_in(loc,NOTHING,tprintf("%s", bf));
else
notify(player, "Permission denied.");
}
static void notify_in_zone P((dbref, char *));
void notify_in_zone (zone, msg)
dbref zone;
char *msg;
{
dbref thing;
static int depth=0;
if (depth > 10)
return;
depth++;
for (thing = 0; thing < db_top; thing++) {
if (db[thing].zone == zone) {
notify_in_zone(thing, msg);
notify_in(thing, NOTHING, msg);
}
}
depth--;
}
void do_general_emit(player,arg1,arg2, emittype)
dbref player;
char *arg1;
char *arg2;
int emittype;
{
dbref who;
char buf[BUFFER_LEN], *bf=buf;
if ( emittype != 4 ) {
pronoun_substitute(buf, player, arg2, player);
bf = buf + strlen(db[player].name) + 1;
}
if ( emittype == 4 ) {
bf = arg2;
while ( *bf && !(bf[0]=='=') ) bf++;
if (*bf)
bf++;
emittype=0;
}
init_match(player, arg1, TYPE_PLAYER);
match_absolute();
match_player();
match_neighbor();
match_possession();
match_me();
match_here();
who = noisy_match_result();
if(get_room(who) != get_room(player) && !controls(player,get_room(who),POW_REMOTE) && !controls_a_zone(player, who, POW_REMOTE)) {
notify(player,"Permission denied.");
return;
}
if (IS(db[who].location,TYPE_ROOM, ROOM_AUDITORIUM) &&
!controls(player,db[who].location,POW_SPOOF) &&
!could_doit(player, db[who].location, A_SLOCK)) {
did_it(player, db[who].location,A_SFAIL,"Shhh.",A_OSFAIL,NULL,
A_ASFAIL);
return;
}
switch( who ) {
case NOTHING:
break;
default:
if (emittype == 0) /* pemit */
if (can_emit_msg(player, db[who].location, bf) ||
controls (player, who, POW_SPOOF)) {
notify(who, bf);
/* wptr[0]=bf; */ /* Do not pass %0 */
did_it(player, who, NULL, 0, NULL, 0, A_APEMIT);
if(!(db[player].flags&QUIET))
notify(player, tprintf("%s just saw \"%s\".",
unparse_object(player, who), bf));
} else
notify(player, "Permission denied");
else if (emittype == 1) { /* room. */
if (((controls(player, who, POW_REMOTE) &&
controls(player, who, POW_SPOOF)) ||
db[player].location == who) &&
can_emit_msg(player,who,bf)) {
notify_in(who, NOTHING, bf);
if(!(db[player].flags&QUIET))
notify(player, tprintf("Everything in %s saw \"%s\".",
unparse_object(player, who), bf));
} else {
notify(player,"Permission denied.");
return;
}
} else if (emittype == 2) { /* oemit */
if (can_emit_msg(player, db[who].location, bf)) {
notify_in(db[who].location,who,bf);
} else {
notify(player,"Permission denied.");
return;
}
} else if (emittype == 3) /* zone */
if (controls(player, who, POW_REMOTE) &&
controls(player, who, POW_SPOOF) &&
controls(player, who, POW_MODIFY) &&
can_emit_msg(player, (dbref) -1, bf)) {
if (db[who].zone == NOTHING && !(db[player].flags&QUIET))
notify(player, tprintf("%s might not be a zone... but i'll do it anyways",
unparse_object(player, who)));
notify_in_zone (who, bf);
if(!(db[player].flags&QUIET))
notify(player, tprintf("Everything in zone %s saw \"%s\".",
unparse_object(player, who), bf));
} else
notify(player, "Permission denied.");
}
}
int can_emit_msg(player, loc, msg)
dbref player;
dbref loc;
char *msg;
{
char mybuf[1000];
char *s;
dbref thing, save_loc;
strcpy(mybuf, msg);
for (s = mybuf; *s && (*s != ' '); s++);
if (*s)
*s = '\0';
if ((thing = lookup_player(mybuf)) != NOTHING && !string_compare(db[thing].name, mybuf))
if (!controls(player, thing, POW_SPOOF)) return 0;
if ((s-mybuf)>2 && !strcmp(s-2,"'s")) {
*(s-2) = '\0';
if ((thing = lookup_player(mybuf)) != NOTHING && !string_compare(db[thing].name, mybuf))
if (!controls(player, thing, POW_SPOOF)) return 0;
}
/* yes, get ready, another awful kludge */
save_loc = db[player].location;
db[player].location = loc;
init_match (player, mybuf, NOTYPE);
match_perfect();
db[player].location = save_loc;
thing = match_result();
if (thing != NOTHING && !controls(player, thing, POW_SPOOF))
return 0;
return 1;
}
void do_announce(player,arg1,arg2)
dbref player;
char *arg1;
char *arg2;
{
char *message;
char buf[2000];
#ifndef SYSV_IO
struct descriptor_data *d;
#endif
if ( Guest(player) || (Typeof(player)!=TYPE_PLAYER && !power(player,POW_SPOOF))) {
notify(player, "You can't do that.");
return;
}
message = reconstruct_message(arg1, arg2);
if ( power(player, POW_ANNOUNCE) || payfor(player,ANNOUNCE_COST))
sprintf(buf, "%s announces \"%s\"", unparse_object(player,player), message);
else {
notify(player,"sorry, you don't have any credits.");
return;
}
log_io(tprintf("%s(#%d) [owner=%s(#%d)] executes: @announce %s",
db[player].name, player,
db[db[player].owner].name, db[player].owner, message));
/*
for(i = 0; i < db_top; i++)
if ( Typeof(i) == TYPE_PLAYER && ! (db[i].flags & NO_WALLS) )
notify(i, buf);
*/
#ifdef SYSV_IO
wall_it(buf);
#else
strcat(buf,"\n");
for (d = descriptor_list; d; d = d->next) {
if ( d->state != CONNECTED)
continue;
if ( db[d->player].flags & PLAYER_NO_WALLS )
continue;
queue_string(d, buf);
}
#endif
}
void do_broadcast(player,arg1,arg2)
dbref player;
char *arg1;
char *arg2;
{
char *message;
#ifndef SYSV_IO
struct descriptor_data *d;
#endif
char buf[2000];
if ( ! power(player, POW_BROADCAST) ) {
notify(player, "You don't have the authority to do that.");
return;
}
message = reconstruct_message(arg1, arg2);
#ifdef SYSV_IO
sprintf(buf, "Official broadcast from %s: \"%s\"",
db[player].name, message);
#else
sprintf(buf, "Official broadcast from %s: \"%s\"\n",
db[player].name, message);
#endif
log_important(tprintf("%s(#%d) executes: @broadcast %s",
db[player].name, player, message));
#ifdef SYSV_IO
for(i = 0; i < db_top; i++)
if ( Typeof(i) == TYPE_PLAYER )
notify(i, buf);
#else
for (d = descriptor_list; d; d = d->next) {
if ( d->state != CONNECTED )
continue;
queue_string(d, buf);
}
#endif
}
void do_gripe(player,arg1,arg2)
dbref player;
char *arg1;
char *arg2;
{
dbref loc;
char *message;
loc = db[player].location;
message = reconstruct_message(arg1, arg2);
log_gripe(tprintf("GRIPE from %s(%d) in %s(%d): %s",
db[player].name, player,
db[loc].name, loc,
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;
char *arg1;
char *arg2;
{
dbref *x;
int k;
x=lookup_players(player,arg1);
if(x[0]==0) return;
if(!payfor(player, PAGE_COST*(x[0]))) {
notify(player,"You don't have enough Credits.");
return;
}
for(k=1;k<=x[0];k++) {
if((db[x[k]].owner==x[k])
?(!(db[x[k]].flags & PLAYER_CONNECT))
:!(*atr_get(x[k],A_APAGE) || Hearer(x[k]))) {
notify(player,tprintf("%s isn't connected.",db[x[k]].name));
if(*Away(x[k])) {
notify(player,
tprintf("Away message from %s: %s", spname(x[k]),
atr_get(x[k],A_AWAY)));
}
} else if(!could_doit(player,x[k],A_LPAGE)) {
notify(player,
tprintf("%s is not accepting pages.",spname(x[k])));
if(*atr_get(x[k],A_HAVEN)) {
notify(player,tprintf("Haven message from %s: %s",
spname(x[k]),
atr_get(x[k],A_HAVEN)));
}
} else {
if(!*arg2) {
notify(x[k],
tprintf( "You sense that %s is looking for you in %s",
spname(player), db[db[player].location].name));
notify(player,
tprintf("You notified %s of your location.",spname(x[k])));
/* wptr[0]=arg2; */ /* Do not pass %0 */
did_it(player, x[k], NULL, 0, NULL, 0, A_APAGE);
} else if ( *arg2 == ':' ) {
notify(x[k],tprintf("%s page-poses: %s %s",spname(player),spname(player),arg2+1));
notify(player, tprintf("You page-posed %s with \"%s %s\".",
db[x[k]].name,spname(player),arg2+1));
if (db[x[k]].owner != x[k])
wptr[0]=arg2;
did_it(player, x[k], NULL, 0, NULL, 0, A_APAGE);
} else {
notify(x[k],tprintf("%s pages: %s",spname(player),arg2));
notify(player, tprintf("You paged %s with \"%s\".",
spname(x[k]),arg2));
if (db[x[k]].owner != x[k])
wptr[0]=arg2;
did_it(player, x[k], NULL, 0, NULL, 0, A_APAGE);
}
if (*Idle(x[k])) {
notify(player,
tprintf("Idle message from %s: %s", spname(x[k]),
atr_get(x[k],A_IDLE)));
notify(x[k],
tprintf("Your Idle message has been sent to %s.",
spname(player)));
}
}
}
}
void do_use(player,arg1)
dbref player;
char *arg1;
{
dbref thing;
thing = match_thing(player,arg1);
if (thing == NOTHING) return;
did_it(player, thing, A_USE, "You don't know how to use that.", A_OUSE, NULL, A_AUSE);
}