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