/* This software is Copyright 1989, 1990, 1992, 1993 by various individuals. Please see the accompanying file COPYRIGHT for details. */ #include #include "db.h" #include "defs.h" #include "prims.h" #include "ctype.h" #include "match.h" #include "money.h" #include "config.h" #include "params.h" #include "externs.h" #include "property.h" #include "interface.h" /* Commands which involve speaking */ int blank(const char *s); void do_say(dbref player, const char *message) { dbref loc; char buf[BUFFER_LEN]; if((loc = getloc(player)) == NOTHING) return; /* notify everybody */ sprintf(buf, "You say, \"%s\"", message); notify(player, buf); sprintf(buf, "%s says, \"%s\"", NAME(player), message); notify_except(player, loc, player, buf); } void do_whisper(dbref player, const char *arg1, const char *arg2) { dbref who; char buf[BUFFER_LEN]; struct match_data md; init_match(player, arg1, TYPE_PLAYER, &md); match_neighbor(&md); match_me(&md); if(Royalty(player)) { match_absolute(&md); match_player(&md); } switch(who = match_result(&md)) { case NOTHING: notify(player, "Whisper to whom?"); break; case AMBIGUOUS: notify(player, "I don't know who you mean!"); break; default: sprintf(buf, "%s whispers, \"%s\"", NAME(player), arg2); if (!notify_listener(player, who, buf)) { sprintf(buf, "%s is not connected.", NAME(who)); notify(player, buf); break; } sprintf(buf, "You whisper, \"%s\" to %s.", arg2, NAME(who)); notify(player, buf); break; } } void do_pose(dbref player, const char *message) { dbref loc; char buf[BUFFER_LEN]; if((loc = getloc(player)) == NOTHING) return; /* notify everybody */ sprintf(buf, "%s %s", NAME(player), message); notify_except(player, loc, NOTHING, buf); } void do_wall(dbref player, const char *message) { dbref i; char buf[BUFFER_LEN]; if(Royalty(player)) { log_status("WALL from %s(%d): %s", NAME(player), player, message); sprintf(buf, "%s shouts, \"%s\"", NAME(player), message); for(i = 0; i < db_top; i++) { if(Typeof(i) == TYPE_PLAYER) notify(i, buf); } } else { notify(player, "But what do you want to do with the wall?"); } } void do_gripe(dbref player, const char *message) { dbref loc; loc = DBFETCH(player)->location; log_gripe("GRIPE from %s(%d) in %s(%d): %s\n", NAME(player), player, NAME(loc), 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(dbref player, const char *arg1, const char *arg2) { dbref target; char buf[BUFFER_LEN]; if (! payfor(player,LOOKUP_COST,"page")) { notify(player,OUT_ERR); /*defined in money.h */ return; } target = lookup_player(arg1); if (target == NOTHING) { notify(player,"I don't recognize that name."); return; } if (FLAGS(target) & HAVEN) { notify(player,"That player does not wish to be disturbed."); return; } if (blank(arg2)) { sprintf(buf,"You sense that %s is looking for you in %s.", NAME(player),NAME(DBFETCH(player)->location)); } else { sprintf(buf,"%s pages from %s: \"%s\"",NAME(player), NAME(DBFETCH(player)->location),arg2); } if (notify_listener(player,target,buf)) { notify(player, "Your message has been sent."); } else { sprintf(buf,"%s is not connected.",NAME(target)); notify(player,buf); } } static void do_daemon_listener(dbref player, dbref source, dbref program, const char *msg) { dbref newdaemon; struct frame *fr; char *pv; struct propref *pr; int delay; if (Typeof(program) != TYPE_PROGRAM) return; player = OWNER(player); if ( DBFETCH(player)->sp.player.daemons >= ( ((FLAGS(player) & WIZARD) || (FLAGS(program) & WIZARD)) ? MAX_WIZ_DAEMONS : MAX_DAEMONS ) ) return; if (! can_link_to(OWNER(source),TYPE_EXIT,program)) return; if (DBFETCH(program)->sp.program.start == 0) { /* try to compile program */ DBSTORE(program,sp.program.first,read_program(program)); do_compile(player,program,NOTHING); free_prog_text(DBFETCH(program)->sp.program.first); } /* if program couldn't compile, just skip it. */ if (DBFETCH(program)->sp.program.start == 0) return; delay = 1; pr = lookup_property(source,"_delay",0); if (pr) { if ((propref_get_attr(pr) & PATTR_TYPE) == PTYPE_STRING) { pv = propref_get_string(pr); if (pv) delay = atoi(pv); free(pv); } propref_done(pr); } if (delay < 1) delay = 1; fr = new_frame(); fr->systop = 0; fr->pc = DBFETCH(program)->sp.program.start; fr->writeonly = 1; fr->reading = 0; init_variables( fr, makeinst(PROG_OBJECT,player), makeinst(PROG_OBJECT,DBFETCH(player)->location), makeinst(PROG_OBJECT,source), makeinst(PROG_STRING,dup_string(NAME(source))) ); fr->caller = (struct dbref_list *)malloc(sizeof(struct dbref_list)); fr->caller->next = NULL; fr->caller->object = player; fr->trigger = source; fr->startcaller = player; fr->prog = program; push(fr->argument.st,&fr->argument.top,PROG_STRING,dup_string(msg)); newdaemon = new_daemon(player,program,delay); FLAGS(newdaemon) |= HEAR; fr->daemon = newdaemon; DBSTORE(newdaemon,sp.daemon.run,fr); add_proglock(program,newdaemon,PROGLOCK_READ); } void listener_sweep(dbref player, dbref first, const char *msg) { int count; if ((Typeof(player) == TYPE_DAEMON) && (FLAGS(player) & HEAR)) return; DOLIST(first,first) { if (FLAGS(first) & HEAR) { for (count=0;countsp.exit.ndest;count++) { do_daemon_listener(player,first,DBFETCH(first)->sp.exit.dest[count],msg); } } } } int notify_listener(dbref player, dbref listener, const char *msg) { int rv; if (listener == NOTHING) return(1); rv = 1; switch (Typeof(listener)) { case TYPE_PLAYER: rv = notify(listener,msg); listener_sweep(player,DBFETCH(listener)->sp.player.actions,msg); break; case TYPE_THING: listener_sweep(player,DBFETCH(listener)->sp.thing.actions,msg); break; } return(rv); } void notify_except(dbref player, dbref location, dbref exception, const char *msg) { dbref first; /* notify all objects/players in the room */ first = DBFETCH(location)->contents; DOLIST (first, first) { if (first != exception) notify_listener (player, first, msg); } /* do all listen exits here */ listener_sweep(player, DBFETCH(location)->sp.room.exits, msg); /* do all listen exits on me */ if (Typeof(player) == TYPE_PLAYER) listener_sweep(player, DBFETCH(player)->sp.player.actions, msg); /* do all listen exits on parents of here */ first = DBFETCH(location)->location; while (first != NOTHING) { listener_sweep(player, DBFETCH(first)->sp.room.exits, msg); first = DBFETCH(first)->location; } } int blank(const char *s) { while (*s && Cisspace(*s)) s++; return !(*s); }