/* speech.c */ #include "os.h" #include "copyright.h" /* Commands which involve speaking */ #include "config.h" #include "externs.h" #include "db.h" #include "interface.h" #include "match.h" static void emit_notify_except (dbref first, dbref exception, const char *msg); static void oemit_notify_except (dbref first, dbref exc1, dbref exc2, const char *msg); static char *spname (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 (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 (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 (dbref player, const char *arg1, const char *arg2) { dbref who; dbref loc; char tbuf1[BUFFER_LEN]; 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 (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 (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 (dbref player, const char *arg1, const char *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 (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 (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 (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 (dbref player, const char *arg1, const char *arg2) { dbref target; const char *message, *gap; char spoof[1024]; 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 0: 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; } static void esnotify (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 (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); } } } static void emit_notify_except (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 (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); } } } static void oemit_notify_except (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 (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 (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 (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 (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); } }