Path: uunet!wyse!mips!apple!usc!cs.utexas.edu!rice!uw-beaver!zephyr.ens.tek.com!tekred!saab!billr From: billr@saab.CNA.TEK.COM (Bill Randle) Newsgroups: comp.sources.games Subject: v08i082: tinymud - user-extendible multi-user adventure game, Part03/04 Message-ID: <5097@tekred.CNA.TEK.COM> Date: 20 Jan 90 03:15:46 GMT Sender: nobody@tekred.CNA.TEK.COM Lines: 2218 Approved: billr@saab.CNA.TEK.COM Submitted-by: DEEJ@MAINE.BITNET Posting-number: Volume 8, Issue 82 Archive-name: tinymud/Part03 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'create.c' <<'END_OF_FILE' X#include "copyright.h" X X/* Commands that create new objects */ X X#include "db.h" X#include "config.h" X#include "interface.h" X#include "externs.h" X X/* utility for open and link */ Xstatic dbref parse_linkable_room(dbref player, const char *room_name) X{ X dbref room; X X /* parse room */ X if(!string_compare(room_name, "here")) { X room = db[player].location; X } else if(!string_compare(room_name, "home")) { X return HOME; /* HOME is always linkable */ X } else { X room = parse_dbref(room_name); X } X X /* check room */ X if(room < 0 || room >= db_top X || Typeof(room) != TYPE_ROOM) { X notify(player, "That's not a room!"); X return NOTHING; X } else if(!can_link_to(player, room)) { X notify(player, "You can't link to that."); X return NOTHING; X } else { X return room; X } X} X X/* use this to create an exit */ Xvoid do_open(dbref player, const char *direction, const char *linkto) X{ X dbref loc; X dbref exit; X X#ifdef RESTRICTED_BUILDING X if(!Builder(player)) { X notify(player, "That command is restricted to authorized builders."); X return; X } X#endif /* RESTRICTED_BUILDING */ X X if((loc = getloc(player)) == NOTHING) return; X if(!*direction) { X notify(player, "Open where?"); X return; X } else if(!ok_name(direction)) { X notify(player, "That's a strange name for an exit!"); X return; X } X X if(!controls(player, loc)) { X notify(player, "Permission denied."); X } else if(!payfor(player, EXIT_COST)) { X notify(player, X "Sorry, you don't have enough pennies to open an exit."); X } else { X /* create the exit */ X exit = new_object(); X X /* initialize everything */ X db[exit].name = alloc_string(direction); X db[exit].owner = player; X db[exit].flags = TYPE_EXIT; X X /* link it in */ X PUSH(exit, db[loc].exits); X X /* and we're done */ X notify(player, "Opened."); X X /* check second arg to see if we should do a link */ X if(*linkto != '\0') { X notify(player, "Trying to link..."); X if((loc = parse_linkable_room(player, linkto)) != NOTHING) { X if(!payfor(player, LINK_COST)) { X notify(player, "You don't have enough pennies to link."); X } else { X /* it's ok, link it */ X db[exit].location = loc; X notify(player, "Linked."); X } X } X } X } X} X X/* use this to link to a room that you own */ X/* it seizes ownership of the exit */ X/* costs 1 penny */ X/* plus a penny transferred to the exit owner if they aren't you */ X/* you must own the linked-to room AND specify it by room number */ Xvoid do_link(dbref player, const char *name, const char *room_name) X{ X dbref loc; X dbref thing; X dbref room; X X if((loc = getloc(player)) == NOTHING) return; X if((room = parse_linkable_room(player, room_name)) == NOTHING) return; X X init_match(player, name, TYPE_EXIT); X match_exit(); X match_neighbor(); X match_possession(); X match_me(); X match_here(); X if(Wizard(player)) { X match_absolute(); X match_player(); X } X X if((thing = noisy_match_result()) != NOTHING) { X switch(Typeof(thing)) { X case TYPE_EXIT: X /* we're ok, check the usual stuff */ X if(db[thing].location != NOTHING) { X if(controls(player, thing)) { X if(Typeof(db[thing].location) == TYPE_PLAYER) { X notify(player, "That exit is being carried."); X } else { X notify(player, "That exit is already linked."); X } X } else { X notify(player, "Permission denied."); X } X } else { X /* handle costs */ X if(db[thing].owner == player) { X if(!payfor(player, LINK_COST)) { X notify(player, X "It costs a penny to link this exit."); X return; X } X } else { X if(!payfor(player, LINK_COST + EXIT_COST)) { X notify(player, X "It costs two pennies to link this exit."); X return; X#ifdef RESTRICTED_BUILDING X } else if(!Builder(player)) { X notify(player, X "Only authorized builders may seize exits."); X#endif /* RESTRICTED_BUILDING */ X } else { X /* pay the owner for his loss */ X db[db[thing].owner].pennies += EXIT_COST; X } X } X X /* link has been validated and paid for; do it */ X db[thing].owner = player; X db[thing].location = room; X X /* notify the player */ X notify(player, "Linked."); X } X break; X case TYPE_THING: X case TYPE_PLAYER: X if(!controls(player, thing)) { X notify(player, "Permission denied."); X } else if(room == HOME) { X notify(player, "Can't set home to home."); X } else { X /* do the link */ X db[thing].exits = room; /* home */ X notify(player, "Home set."); X } X break; X case TYPE_ROOM: X if(!controls(player, thing)) { X notify(player, "Permission denied."); X } else { X /* do the link, in location */ X db[thing].location = room; /* dropto */ X notify(player, "Dropto set."); X } X break; X default: X notify(player, "Internal error: weird object type."); X fprintf(stderr, "PANIC weird object: Typeof(%d) = %d\n", X thing, Typeof(thing)); X break; X } X } X} X X/* use this to create a room */ Xvoid do_dig(dbref player, const char *name) X{ X dbref room; X char buf[BUFFER_LEN]; X X#ifdef RESTRICTED_BUILDING X if(!Builder(player)) { X notify(player, "That command is restricted to authorized builders."); X return; X } X#endif /* RESTRICTED_BUILDING */ X X /* we don't need to know player's location! hooray! */ X if(*name == '\0') { X notify(player, "Dig what?"); X } else if(!ok_name(name)) { X notify(player, "That's a silly name for a room!"); X } else if(!payfor(player, ROOM_COST)) { X notify(player, "Sorry, you don't have enough pennies to dig a room."); X } else { X room = new_object(); X X /* Initialize everything */ X db[room].name = alloc_string(name); X db[room].owner = player; X db[room].flags = TYPE_ROOM; X X sprintf(buf, "%s created with room number %d.", name, room); X notify(player, buf); X } X} X X/* use this to create an object */ Xvoid do_create(dbref player, char *name, int cost) X{ X dbref loc; X dbref thing; X X#ifdef RESTRICTED_BUILDING X if(!Builder(player)) { X notify(player, "That command is restricted to authorized builders."); X return; X } X#endif /* RESTRICTED_BUILDING */ X X if(*name == '\0') { X notify(player, "Create what?"); X return; X } else if(!ok_name(name)) { X notify(player, "That's a silly name for a thing!"); X return; X } else if(cost < 0) { X notify(player, "You can't create an object for less than nothing!"); X return; X } else if(cost < OBJECT_COST) { X cost = OBJECT_COST; X } X X if(!payfor(player, cost)) { X notify(player, "Sorry, you don't have enough pennies."); X } else { X /* create the object */ X thing = new_object(); X X /* initialize everything */ X db[thing].name = alloc_string(name); X db[thing].location = player; X db[thing].owner = player; X db[thing].pennies = OBJECT_ENDOWMENT(cost); X db[thing].flags = TYPE_THING; X X /* endow the object */ X if(db[thing].pennies > MAX_OBJECT_ENDOWMENT) { X db[thing].pennies = MAX_OBJECT_ENDOWMENT; X } X X /* home is here (if we can link to it) or player's home */ X if((loc = db[player].location) != NOTHING X && can_link_to(player, loc)) { X db[thing].exits = loc; /* home */ X } else { X db[thing].exits = db[player].exits; /* home */ X } X X /* link it in */ X PUSH(thing, db[player].contents); X X /* and we're done */ X notify(player, "Created."); X } X} X END_OF_FILE if test 7226 -ne `wc -c <'create.c'`; then echo shar: \"'create.c'\" unpacked with wrong size! fi # end of 'create.c' fi if test -f 'db.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'db.c'\" else echo shar: Extracting \"'db.c'\" \(4473 characters\) sed "s/^X//" >'db.c' <<'END_OF_FILE' X#include "copyright.h" X X#include X X#include "db.h" X Xstruct object *db = 0; Xdbref db_top = 0; X Xextern void *malloc(unsigned long); Xextern void *realloc(void *, unsigned long); X Xconst char *alloc_string(const char *string) X{ X char *s; X X /* NULL, "" -> NULL */ X if(string == 0 || *string == '\0') return 0; X X if((s = (char *) malloc(strlen(string)+1)) == 0) { X abort(); X } X strcpy(s, string); X return s; X} X Xstatic void db_grow(dbref newtop) X{ X struct object *newdb; X X if(newtop > db_top) { X db_top = newtop; X if(db) { X if((newdb = (struct object *) X realloc((void *) db, X db_top * sizeof(struct object))) == 0) { X abort(); X } X db = newdb; X } else { X /* make the initial one */ X if((db = (struct object *) X malloc(db_top * sizeof(struct object))) == 0) { X abort(); X } X } X } X} X Xdbref new_object() X{ X dbref newobj; X struct object *o; X X newobj = db_top; X db_grow(db_top + 1); X X /* clear it out */ X o = db+newobj; X o->name = 0; X o->description = 0; X o->location = NOTHING; X o->contents = NOTHING; X o->exits = NOTHING; X o->next = NOTHING; X o->key = NOTHING; X o->fail_message = 0; X o->succ_message = 0; X o->ofail = 0; X o->osuccess = 0; X o->owner = NOTHING; X o->pennies = 0; X /* flags you must initialize yourself */ X o->password = 0; X X return newobj; X} X X#define DB_MSGLEN 512 X Xstatic void putref(FILE *f, dbref ref) X{ X fprintf(f, "%d\n", ref); X} X Xstatic void putstring(FILE *f, const char *s) X{ X if(s) { X fputs(s, f); X } X putc('\n', f); X} X Xint db_write_object(FILE *f, dbref i) X{ X struct object *o; X X o = db + i; X putstring(f, o->name); X putstring(f, o->description); X putref(f, o->location); X putref(f, o->contents); X putref(f, o->exits); X putref(f, o->next); X putref(f, o->key); X putstring(f, o->fail_message); X putstring(f, o->succ_message); X putstring(f, o->ofail); X putstring(f, o->osuccess); X putref(f, o->owner); X putref(f, o->pennies); X putref(f, o->flags); X putstring(f, o->password); X X return 0; X} X Xdbref db_write(FILE *f) X{ X dbref i; X X for(i = 0; i < db_top; i++) { X fprintf(f, "#%d\n", i); X db_write_object(f, i); X } X fputs("***END OF DUMP***\n", f); X fflush(f); X return(db_top); X} X Xdbref parse_dbref(const char *s) X{ X const char *p; X long x; X X x = atol(s); X if(x > 0) { X return x; X } else if(x == 0) { X /* check for 0 */ X for(p = s; *p; p++) { X if(*p == '0') return 0; X if(!isspace(*p)) break; X } X } X X /* else x < 0 or s != 0 */ X return NOTHING; X} X Xstatic dbref getref(FILE *f) X{ X static char buf[DB_MSGLEN]; X X fgets(buf, sizeof(buf), f); X return(atol(buf)); X} X Xstatic const char *getstring(FILE *f) X{ X static char buf[DB_MSGLEN]; X char *p; X X fgets(buf, sizeof(buf), f); X for(p = buf; *p; p++) { X if(*p == '\n') { X *p = '\0'; X break; X } X } X X if(!*buf) { X return(0); X } else { X return(alloc_string(buf)); X } X} X Xvoid db_free() X{ X dbref i; X struct object *o; X X if(db) { X for(i = 0; i < db_top; i++) { X o = &db[i]; X if(o->name) free(o->name); X if(o->description) free(o->description); X if(o->succ_message) free(o->succ_message); X if(o->fail_message) free(o->fail_message); X if(o->ofail) free(o->ofail); X if(o->osuccess) free(o->osuccess); X if(o->password) free(o->password); X } X free(db); X db = 0; X db_top = 0; X } X} X Xdbref db_read(FILE *f) X{ X dbref i; X struct object *o; X const char *end; X X db_free(); X for(i = 0;; i++) { X switch(getc(f)) { X case '#': X /* another entry, yawn */ X if(i != getref(f)) { X /* we blew it */ X return -1; X } X /* make space */ X db_grow(i+1); X X /* read it in */ X o = db+i; X o->name = getstring(f); X o->description = getstring(f); X o->location = getref(f); X o->contents = getref(f); X o->exits = getref(f); X o->next = getref(f); X o->key = getref(f); X o->fail_message = getstring(f); X o->succ_message = getstring(f); X o->ofail = getstring(f); X o->osuccess = getstring(f); X o->owner = getref(f); X o->pennies = getref(f); X o->flags = getref(f); X o->password = getstring(f); X break; X case '*': X end = getstring(f); X if(strcmp(end, "**END OF DUMP***")) { X free(end); X return -1; X } else { X free(end); X return db_top; X } X default: X return -1; X break; X } X } X} X END_OF_FILE if test 4473 -ne `wc -c <'db.c'`; then echo shar: \"'db.c'\" unpacked with wrong size! fi # end of 'db.c' fi if test -f 'db.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'db.h'\" else echo shar: Extracting \"'db.h'\" \(3790 characters\) sed "s/^X//" >'db.h' <<'END_OF_FILE' X#include "copyright.h" X X#ifndef __DB_H X#define __DB_H X#include X Xtypedef int dbref; /* offset into db */ X X#define TYPE_ROOM 0x0 X#define TYPE_THING 0x1 X#define TYPE_EXIT 0x2 X#define TYPE_PLAYER 0x3 X#define NOTYPE 0x7 /* no particular type */ X#define TYPE_MASK 0x7 /* room for expansion */ X#define ANTILOCK 0x8 /* if present, makes key cause failure */ X#define WIZARD 0x10 /* gets automatic control */ X#define LINK_OK 0x20 /* anybody can link to this room */ X#define DARK 0x40 /* contents of room are not printed */ X#define TEMPLE 0x80 /* objects dropped in this room go home */ X#define STICKY 0x100 /* this object goes home when dropped */ X X#ifdef RESTRICTED_BUILDING X#define BUILDER 0x200 /* this player can use construction commands */ X#endif /* RESTRICTED_BUILDING */ X Xtypedef int object_flag_type; X X#define Typeof(x) (db[(x)].flags & TYPE_MASK) X#define Wizard(x) ((db[(x)].flags & WIZARD) != 0) X#define Dark(x) ((db[(x)].flags & DARK) != 0) X X#ifdef RESTRICTED_BUILDING X#define Builder(x) ((db[(x)].flags & (WIZARD|BUILDER)) != 0) X#endif /* RESTRICTED_BUILDING */ X X/* special dbref's */ X#define NOTHING (-1) /* null dbref */ X#define AMBIGUOUS (-2) /* multiple possibilities, for matchers */ X#define HOME (-3) /* virtual room, represents mover's home */ X Xstruct object { X const char *name; X const char *description; X dbref location; /* pointer to container */ X /* for exits, pointer to destination */ X dbref contents; /* pointer to first item */ X dbref exits; /* pointer to first exit for rooms */ X /* pointer to home for things and players */ X dbref next; /* pointer to next in contents/exits chain */ X X /* the following are used for pickups for things, entry for exits */ X dbref key; /* if not NOTHING, must have this to do op */ X const char *fail_message; /* what you see if op fails */ X const char *succ_message; /* what you see if op succeeds */ X /* other messages get your name prepended, so if your name is "Foo", */ X /* and osuccess = "disappears in a blast of gamma radiation." */ X /* then others see "Foo disappears in a blast of gamma radiation." */ X /* (At some point I may put in Maven-style %-substitutions.) */ X const char *ofail; /* what others see if op fails */ X const char *osuccess; /* what others see if op succeeds */ X X dbref owner; /* who controls this object */ X int pennies; /* number of pennies object contains */ X object_flag_type flags; X const char *password; /* password for players */ X}; X Xextern struct object *db; Xextern dbref db_top; X Xextern const char *alloc_string(const char *s); X Xextern dbref new_object(); /* return a new object */ X Xextern int db_write_object(FILE *, dbref); /* write one object to file */ X Xextern dbref db_write(FILE *f); /* write db to file, return # of objects */ X Xextern dbref db_read(FILE *f); /* read db from file, return # of objects */ X /* Warning: destroys existing db contents! */ X Xextern void db_free(); X Xextern dbref parse_dbref(const char *); /* parse a dbref */ X X#define DOLIST(var, first) \ X for((var) = (first); (var) != NOTHING; (var) = db[(var)].next) X#define PUSH(thing, locative) \ X ((db[(thing)].next = (locative)), (locative) = (thing)) X#define getloc(thing) (db[thing].location) X X/* X Usage guidelines: X X To refer to objects use db[object_ref]. Pointers to objects may X become invalid after a call to new_object(). X X The programmer is responsible for managing storage for string X components of entries; db_read will produce malloc'd strings. The X alloc_string routine is provided for generating malloc'd strings X duplicates of other strings. Note that db_free and db_read will X attempt to free any non-NULL string that exists in db when they are X invoked. X*/ X#endif /* __DB_H */ END_OF_FILE if test 3790 -ne `wc -c <'db.h'`; then echo shar: \"'db.h'\" unpacked with wrong size! fi # end of 'db.h' fi if test -f 'externs.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'externs.h'\" else echo shar: Extracting \"'externs.h'\" \(3748 characters\) sed "s/^X//" >'externs.h' <<'END_OF_FILE' X#include "copyright.h" X X/* Prototypes for externs not defined elsewhere */ X#include "db.h" X X/* From create.c */ Xextern void do_open(dbref player, const char *direction, const char *linkto); Xextern void do_link(dbref player, const char *name, const char *room_name); Xextern void do_dig(dbref player, const char *name); Xextern void do_create(dbref player, char *name, int cost); X X/* From game.c */ Xextern void do_dump(dbref player); Xextern void do_shutdown(dbref player); X X/* From help.c */ Xextern void spit_file(dbref player, const char *filename); Xextern void do_help(dbref player); Xextern void do_news(dbref player); X X/* From look.c */ Xextern void look_room(dbref player, dbref room); Xextern void do_look_around(dbref player); Xextern void do_look_at(dbref player, const char *name); Xextern void do_examine(dbref player, const char *name); Xextern void do_inventory(dbref player); Xextern void do_find(dbref player, const char *name); X X/* From move.c */ Xextern void moveto(dbref what, dbref where); Xextern void enter_room(dbref player, dbref loc); Xextern void send_home(dbref thing); Xextern int can_move(dbref player, const char *direction); Xextern void do_move(dbref player, const char *direction); Xextern void do_get(dbref player, const char *what); Xextern void do_drop(dbref player, const char *name); X X/* From player.c */ Xextern dbref lookup_player(const char *name); Xextern void do_password(dbref player, const char *old, const char *newobj); X X/* From predicates.h */ Xextern int can_link_to(dbref who, dbref where); Xextern int could_doit(dbref player, dbref thing); Xextern int can_doit(dbref player, dbref thing, const char *default_fail_msg); Xextern int can_see(dbref player, dbref thing, int can_see_location); Xextern int controls(dbref who, dbref what); Xextern int payfor(dbref who, int cost); X X/* From rob.c */ Xextern void do_kill(dbref player, const char *what, int cost); Xextern void do_give(dbref player, char *recipient, int amount); Xextern void do_rob(dbref player, const char *what); X X/* From set.c */ Xextern void do_name(dbref player, const char *name, char *newname); Xextern void do_describe(dbref player, const char *name, const char *description); Xextern void do_fail(dbref player, const char *name, const char *message); Xextern void do_success(dbref player, const char *name, const char *message); Xextern void do_osuccess(dbref player, const char *name, const char *message); Xextern void do_ofail(dbref player, const char *name, const char *message); Xextern void do_lock(dbref player, const char *name, const char *keyname); Xextern void do_unlock(dbref player, const char *name); Xextern void do_unlink(dbref player, const char *name); Xextern void do_chown(dbref player, const char *name, const char *newobj); Xextern void do_set(dbref player, const char *name, const char *flag); X X/* From speech.c */ Xextern void do_wall(dbref player, const char *arg1, const char *arg2); Xextern void do_gripe(dbref player, const char *arg1, const char *arg2); Xextern void do_say(dbref player, const char *arg1, const char *arg2); Xextern void do_page(dbref player, const char *arg1); Xextern void notify_except(dbref first, dbref exception, const char *msg); X X/* From stringutil.c */ Xextern int string_compare(const char *s1, const char *s2); Xextern int string_prefix(const char *string, const char *prefix); Xextern const char *string_match(const char *src, const char *sub); X X/* From utils.c */ Xextern int member(dbref thing, dbref list); Xextern dbref remove_first(dbref first, dbref what); Xextern const char *getname(dbref thing); X X/* From wiz.c */ Xextern void do_teleport(dbref player, const char *arg1, const char *arg2); Xextern void do_force(dbref player, const char *what, char *command); Xextern void do_stats(dbref player, const char *name); END_OF_FILE if test 3748 -ne `wc -c <'externs.h'`; then echo shar: \"'externs.h'\" unpacked with wrong size! fi # end of 'externs.h' fi if test -f 'interface.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'interface.h'\" else echo shar: Extracting \"'interface.h'\" \(801 characters\) sed "s/^X//" >'interface.h' <<'END_OF_FILE' X#include "copyright.h" X X#include "db.h" X X/* these symbols must be defined by the interface */ Xextern void notify(dbref player, const char *msg); Xextern int shutdown_flag; /* if non-zero, interface should shut down */ Xextern void emergency_shutdown(void); X X/* the following symbols are provided by game.c */ X X/* max length of command argument to process_command */ X#define MAX_COMMAND_LEN 512 X#define BUFFER_LEN ((MAX_COMMAND_LEN)*4) Xextern void process_command(dbref player, char *command); X Xextern dbref create_player(const char *name, const char *password); Xextern dbref connect_player(const char *name, const char *password); Xextern void do_look_around(dbref player); X Xextern int init_game(const char *infile, const char *outfile); Xextern void dump_database(void); Xextern void panic(const char *); END_OF_FILE if test 801 -ne `wc -c <'interface.h'`; then echo shar: \"'interface.h'\" unpacked with wrong size! fi # end of 'interface.h' fi if test -f 'look.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'look.c'\" else echo shar: Extracting \"'look.c'\" \(7643 characters\) sed "s/^X//" >'look.c' <<'END_OF_FILE' X#include "copyright.h" X X/* commands which look at things */ X X#include "db.h" X#include "config.h" X#include "interface.h" X#include "match.h" X#include "externs.h" X Xstatic void notify_name(dbref player, dbref thing) X{ X char buf[BUFFER_LEN]; X X if(controls(player, thing)) { X /* tell him the number */ X sprintf(buf, "%s(#%d)", getname(thing), thing); X notify(player, buf); X } else { X /* just tell him the name */ X notify(player, getname(thing)); X } X} X Xstatic void look_contents(dbref player, dbref loc, const char *contents_name) X{ X dbref thing; X dbref can_see_loc; X X /* check to see if he can see the location */ X can_see_loc = (!Dark(loc) || controls(player, loc)); X X /* check to see if there is anything there */ X DOLIST(thing, db[loc].contents) { X if(can_see(player, thing, can_see_loc)) { X /* something exists! show him everything */ X notify(player, contents_name); X DOLIST(thing, db[loc].contents) { X if(can_see(player, thing, can_see_loc)) { X notify_name(player, thing); X } X } X break; /* we're done */ X } X } X} X Xstatic void look_simple(dbref player, dbref thing) X{ X if(db[thing].description) { X notify(player, db[thing].description); X } else { X notify(player, "You see nothing special."); X } X} X Xvoid look_room(dbref player, dbref loc) X{ X char buf[BUFFER_LEN]; X X /* tell him the name, and the number if he can link to it */ X if(can_link_to(player, loc)) { X sprintf(buf, "%s (#%d)", getname(loc), loc); X notify(player, buf); X } else { X notify(player, getname(loc)); X } X X /* tell him the description */ X if(db[loc].description) notify(player, db[loc].description); X X /* tell him the appropriate messages if he has the key */ X can_doit(player, loc, 0); X X /* tell him the contents */ X look_contents(player, loc, "Contents:"); X} X Xvoid do_look_around(dbref player) X{ X dbref loc; X X if((loc = getloc(player)) == NOTHING) return; X look_room(player, loc); X} X Xvoid do_look_at(dbref player, const char *name) X{ X dbref thing; X X if(*name == '\0') { X if((thing = getloc(player)) != NOTHING) { X look_room(player, thing); X } X } else { X /* look at a thing here */ X init_match(player, name, NOTYPE); X match_exit(); X match_neighbor(); X match_possession(); X if(Wizard(player)) { X match_absolute(); X match_player(); X } X match_here(); X match_me(); X X if((thing = noisy_match_result()) != NOTHING) { X switch(Typeof(thing)) { X case TYPE_ROOM: X look_room(player, thing); X break; X case TYPE_PLAYER: X look_simple(player, thing); X look_contents(player, thing, "Carrying:"); X break; X default: X look_simple(player, thing); X break; X } X } X } X} X Xstatic const char *flag_description(dbref thing) X{ X static char buf[BUFFER_LEN]; X X strcpy(buf, "Type: "); X switch(Typeof(thing)) { X case TYPE_ROOM: X strcat(buf, "Room"); X break; X case TYPE_EXIT: X strcat(buf, "Exit"); X break; X case TYPE_THING: X strcat(buf, "Thing"); X break; X case TYPE_PLAYER: X strcat(buf, "Player"); X break; X default: X strcat(buf, "***UNKNOWN TYPE***"); X break; X } X X if(db[thing].flags & ~TYPE_MASK) { X /* print flags */ X strcat(buf, " Flags:"); X if(db[thing].flags & WIZARD) strcat(buf, " WIZARD"); X if(db[thing].flags & STICKY) strcat(buf, " STICKY"); X if(db[thing].flags & DARK) strcat(buf, " DARK"); X if(db[thing].flags & LINK_OK) strcat(buf, " LINK_OK"); X if(db[thing].flags & TEMPLE) strcat(buf, " TEMPLE"); X#ifdef RESTRICTED_BUILDING X if(db[thing].flags & BUILDER) strcat(buf, " BUILDER"); X#endif /* RESTRICTED_BUILDING */ X } X X return buf; X} X Xvoid do_examine(dbref player, const char *name) X{ X dbref thing; X dbref content; X dbref exit; X char buf[BUFFER_LEN]; X X if(*name == '\0') { X if((thing = getloc(player)) == NOTHING) return; X } else { X /* look it up */ X init_match(player, name, NOTYPE); X match_exit(); X match_neighbor(); X match_possession(); X match_absolute(); X /* only Wizards can examine other players */ X if(Wizard(player)) match_player(); X match_here(); X match_me(); X X /* get result */ X if((thing = noisy_match_result()) == NOTHING) return; X } X X if(!can_link(player, thing)) { X notify(player, X "You can only examine what you own. Try using \"look.\""); X return; X } X X sprintf(buf, "%s(#%d) [%s] Key: %c%s(#%d) Pennies: %d %s", X getname(thing), thing, X getname(db[thing].owner), X db[thing].flags & ANTILOCK ? NOT_TOKEN : ' ', X getname(db[thing].key), X db[thing].key, X db[thing].pennies, X flag_description(thing)); X notify(player, buf); X if(db[thing].description) notify(player, db[thing].description); X if(db[thing].fail_message) { X sprintf(buf, "Fail: %s", db[thing].fail_message); X notify(player, buf); X } X if(db[thing].succ_message) { X sprintf(buf, "Success: %s", db[thing].succ_message); X notify(player, buf); X } X if(db[thing].ofail) { X sprintf(buf, "Ofail: %s", db[thing].ofail); X notify(player, buf); X } X if(db[thing].osuccess) { X sprintf(buf, "Osuccess: %s", db[thing].osuccess); X notify(player, buf); X } X X /* show him the contents */ X if(db[thing].contents != NOTHING) { X notify(player, "Contents:"); X DOLIST(content, db[thing].contents) { X notify_name(player, content); X } X } X X switch(Typeof(thing)) { X case TYPE_ROOM: X /* tell him about exits */ X if(db[thing].exits != NOTHING) { X notify(player, "Exits:"); X DOLIST(exit, db[thing].exits) { X notify_name (player, exit); X } X } else { X notify(player, "No exits."); X } X X /* print dropto if present */ X if(db[thing].location != NOTHING) { X sprintf(buf, "Dropped objects go to: %s(#%d)", X getname(db[thing].location), db[thing].location); X notify(player, buf); X } X break; X case TYPE_THING: X case TYPE_PLAYER: X /* print home */ X sprintf(buf, "Home: %s(#%d)", X getname(db[thing].exits), db[thing].exits); /* home */ X notify(player, buf); X /* print location if player can link to it */ X if(db[thing].location != NOTHING X && (controls(player, db[thing].location) X || can_link_to(player, db[thing].location))) { X sprintf(buf, "Location: %s(#%d)", X getname(db[thing].location), db[thing].location); X notify(player, buf); X } X break; X case TYPE_EXIT: X /* print destination */ X switch(db[thing].location) { X case NOTHING: X break; X case HOME: X notify(player, "Destination: ***HOME***"); X break; X default: X sprintf(buf, "%s: %s(#%d)", X (Typeof(db[thing].location) == TYPE_ROOM X ? "Destination" : "Carried by"), X getname(db[thing].location), db[thing].location); X notify(player, buf); X break; X } X break; X default: X /* do nothing */ X break; X } X} X Xvoid do_score(dbref player) X{ X char buf[BUFFER_LEN]; X X sprintf(buf, "You have %d %s.", X db[player].pennies, X db[player].pennies == 1 ? "penny" : "pennies"); X notify(player, buf); X} X Xvoid do_inventory(dbref player) X{ X dbref thing; X X if((thing = db[player].contents) == NOTHING) { X notify(player, "You aren't carrying anything."); X } else { X notify(player, "You are carrying:"); X DOLIST(thing, thing) { X notify_name(player, thing); X } X } X X do_score(player); X} X Xvoid do_find(dbref player, const char *name) X{ X dbref i; X char buf[BUFFER_LEN]; X X if(!payfor(player, LOOKUP_COST)) { X notify(player, "You don't have enough pennies."); X } else { X for(i = 0; i < db_top; i++) { X if(Typeof(i) != TYPE_EXIT X && controls(player, i) X && (!*name || string_match(db[i].name, name))) { X sprintf(buf, "%s(#%d)", db[i].name, i); X notify(player, buf); X } X } X notify(player, "***End of List***"); X } X} END_OF_FILE if test 7643 -ne `wc -c <'look.c'`; then echo shar: \"'look.c'\" unpacked with wrong size! fi # end of 'look.c' fi if test -f 'match.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'match.c'\" else echo shar: Extracting \"'match.c'\" \(5386 characters\) sed "s/^X//" >'match.c' <<'END_OF_FILE' X#include "copyright.h" X X/* Routines for parsing arguments */ X#include X X#include "db.h" X#include "config.h" X#include "match.h" X X#define DOWNCASE(x) (isupper(x) ? tolower(x) : (x)) X Xstatic dbref exact_match = NOTHING; /* holds result of exact match */ Xstatic int check_keys = 0; /* if non-zero, check for keys */ Xstatic dbref last_match = NOTHING; /* holds result of last match */ Xstatic int match_count; /* holds total number of inexact matches */ Xstatic dbref match_who; /* player who is being matched around */ Xstatic const char *match_name; /* name to match */ Xstatic int preferred_type = NOTYPE; /* preferred type */ X Xvoid init_match(dbref player, const char *name, int type) X{ X exact_match = last_match = NOTHING; X match_count = 0; X match_who = player; X match_name = name; X check_keys = 0; X preferred_type = type; X} X Xvoid init_match_check_keys(dbref player, const char *name, int type) X{ X init_match(player, name, type); X check_keys = 1; X} X Xstatic dbref choose_thing(dbref thing1, dbref thing2) X{ X int has1; X int has2; X X if(thing1 == NOTHING) { X return thing2; X } else if(thing2 == NOTHING) { X return thing1; X } X X if(preferred_type != NOTYPE) { X if(Typeof(thing1) == preferred_type) { X if(Typeof(thing2) != preferred_type) { X return thing1; X } X } else if(Typeof(thing2) == preferred_type) { X return thing2; X } X } X X if(check_keys) { X has1 = could_doit(match_who, thing1); X has2 = could_doit(match_who, thing2); X X if(has1 && !has2) { X return thing1; X } else if (has2 && !has1) { X return thing2; X } X /* else fall through */ X } X X return (random() % 2 ? thing1 : thing2); X} X Xvoid match_player() X{ X dbref match; X const char *p; X X if(*match_name == LOOKUP_TOKEN X && payfor(match_who, LOOKUP_COST)) { X for(p = match_name + 1; isspace(*p); p++); X if((match = lookup_player(p)) != NOTHING) { X exact_match = match; X } X } X} X X/* returns nnn if name = #nnn, else NOTHING */ Xstatic dbref absolute_name() X{ X dbref match; X X if(*match_name == NUMBER_TOKEN) { X match = parse_dbref(match_name+1); X if(match < 0 || match >= db_top) { X return NOTHING; X } else { X return match; X } X } else { X return NOTHING; X } X} X Xvoid match_absolute() X{ X dbref match; X X if((match = absolute_name()) != NOTHING) { X exact_match = match; X } X} X Xvoid match_me() X{ X if(!string_compare(match_name, "me")) { X exact_match = match_who; X } X} X Xvoid match_here() X{ X if(!string_compare(match_name, "here") X && db[match_who].location != NOTHING) { X exact_match = db[match_who].location; X } X} X Xstatic void match_list(dbref first) X{ X dbref absolute; X X absolute = absolute_name(); X if(!controls(match_who, absolute)) absolute = NOTHING; X X DOLIST(first, first) { X if(first == absolute) { X exact_match = first; X return; X } else if(!string_compare(db[first].name, match_name)) { X /* if there are multiple exact matches, randomly choose one */ X exact_match = choose_thing(exact_match, first); X } else if(string_match(db[first].name, match_name)) { X last_match = first; X match_count++; X } X } X} X Xvoid match_possession() X{ X match_list(db[match_who].contents); X} X Xvoid match_neighbor() X{ X dbref loc; X X if((loc = db[match_who].location) != NOTHING) { X match_list(db[loc].contents); X } X} X Xvoid match_exit() X{ X dbref loc; X dbref exit; X int exit_status; X dbref absolute; X const char *match; X const char *p; X X if((loc = db[match_who].location) != NOTHING) { X absolute = absolute_name(); X if(!controls(match_who, absolute)) absolute = NOTHING; X X DOLIST(exit, db[loc].exits) { X if(exit == absolute) { X exact_match = exit; X } else { X match = db[exit].name; X while(*match) { X /* check out this one */ X for(p = match_name; X (*p X && DOWNCASE(*p) == DOWNCASE(*match) X && *match != EXIT_DELIMITER); X p++, match++); X /* did we get it? */ X if(*p == '\0') { X /* make sure there's nothing afterwards */ X while(isspace(*match)) match++; X if(check_keys) { X exit_status = could_doit(match_who, exit); X } else { X exit_status = 1; X } X if(*match == '\0' || *match == EXIT_DELIMITER) { X /* we got it */ X exact_match = choose_thing(exact_match, exit); X goto next_exit; /* got this match */ X } X } X /* we didn't get it, find next match */ X while(*match && *match++ != EXIT_DELIMITER); X while(isspace(*match)) match++; X } X } X next_exit: X ; X } X } X} X Xvoid match_everything() X{ X match_exit(); X match_neighbor(); X match_possession(); X match_me(); X match_here(); X if(Wizard(match_who)) { X match_absolute(); X match_player(); X } X} X Xdbref match_result() X{ X if(exact_match != NOTHING) { X return exact_match; X } else { X switch(match_count) { X case 0: X return NOTHING; X case 1: X return last_match; X default: X return AMBIGUOUS; X } X } X} X X/* use this if you don't care about ambiguity */ Xdbref last_match_result() X{ X if(exact_match != NOTHING) { X return exact_match; X } else { X return last_match; X } X} X Xdbref noisy_match_result() X{ X dbref match; X X switch(match = match_result()) { X case NOTHING: X notify(match_who, NOMATCH_MESSAGE); X return NOTHING; X case AMBIGUOUS: X notify(match_who, AMBIGUOUS_MESSAGE); X return NOTHING; X default: X return match; X } X} X END_OF_FILE if test 5386 -ne `wc -c <'match.c'`; then echo shar: \"'match.c'\" unpacked with wrong size! fi # end of 'match.c' fi if test -f 'rob.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'rob.c'\" else echo shar: Extracting \"'rob.c'\" \(4521 characters\) sed "s/^X//" >'rob.c' <<'END_OF_FILE' X#include "copyright.h" X X/* rob and kill */ X X#include "db.h" X#include "config.h" X#include "interface.h" X#include "match.h" X#include "externs.h" X Xvoid do_rob(dbref player, const char *what) X{ X dbref loc; X dbref thing; X char buf[BUFFER_LEN]; X X if((loc = getloc(player)) == NOTHING) return; X X init_match(player, what, TYPE_PLAYER); X match_neighbor(); X match_me(); X if(Wizard(player)) { X match_absolute(); X match_player(); X } X thing = match_result(); X X switch(thing) { X case NOTHING: X notify(player, "Rob whom?"); X break; X case AMBIGUOUS: X notify(player, "I don't know who you mean!"); X break; X default: X if(Typeof(thing) != TYPE_PLAYER) { X notify(player, "Sorry, you can only rob other players."); X } else if(db[thing].pennies < 1) { X sprintf(buf, "%s is penniless.", db[thing].name); X notify(player, buf); X sprintf(buf, X "%s tried to rob you, but you have no pennies to take.", X db[player].name); X notify(thing, buf); X } else if(can_doit(player, thing, X "Your conscience tells you not to.")) { X /* steal a penny */ X db[player].pennies++; X db[thing].pennies--; X notify(player, "You stole a penny."); X sprintf(buf, "%s stole one of your pennies!", db[player].name); X notify(thing, buf); X } X break; X } X} X Xvoid do_kill(dbref player, const char *what, int cost) X{ X dbref victim; X char buf[BUFFER_LEN]; X X init_match(player, what, TYPE_PLAYER); X match_neighbor(); X match_me(); X if(Wizard(player)) { X match_player(); X match_absolute(); X } X victim = match_result(); X X switch(victim) { X case NOTHING: X notify(player, "I don't see that player here."); X break; X case AMBIGUOUS: X notify(player, "I don't know who you mean!"); X break; X default: X if(Typeof(victim) != TYPE_PLAYER) { X notify(player, "Sorry, you can only kill other players."); X } else if(Wizard(victim)) { X notify(player, "Sorry, Wizards are immortal."); X } else { X /* go for it */ X /* set cost */ X if(cost < KILL_MIN_COST) cost = KILL_MIN_COST; X X /* see if it works */ X if(!payfor(player, cost)) { X notify(player, "You don't have enough pennies."); X } else if((random() % KILL_BASE_COST) < cost) { X /* you killed him */ X sprintf(buf, "You killed %s!", db[victim].name); X notify(player, buf); X X /* notify victim */ X sprintf(buf, "%s killed you!", db[player].name); X notify(victim, buf); X sprintf(buf, "Your insurance policy pays %d pennies.", X KILL_BONUS); X notify(victim, buf); X X /* pay off the bonus */ X db[victim].pennies += KILL_BONUS; X X /* send him home */ X send_home(victim); X X /* now notify everybody else */ X sprintf(buf, "%s killed %s!", X db[player].name, db[victim].name); X notify_except(db[db[player].location].contents, player, buf); X } else { X /* notify player and victim only */ X notify(player, "Your murder attempt failed."); X sprintf(buf, "%s tried to kill you!", db[player].name); X notify(victim, buf); X } X break; X } X } X} X Xvoid do_give(dbref player, char *recipient, int amount) X{ X dbref who; X char buf[BUFFER_LEN]; X X /* do amount consistency check */ X if(amount < 0 && !Wizard(player)) { X notify(player, "Try using the \"rob\" command."); X return; X } else if(amount == 0) { X notify(player, "You must specify a positive number of pennies."); X return; X } X X /* check recipient */ X init_match(player, recipient, TYPE_PLAYER); X match_neighbor(); X match_me(); X if(Wizard(player)) { X match_player(); X match_absolute(); X } X X switch(who = match_result()) { X case NOTHING: X notify(player, "Give to whom?"); X return; X case AMBIGUOUS: X notify(player, "I don't know who you mean!"); X return; X default: X if(!Wizard(player)) { X if(Typeof(who) != TYPE_PLAYER) { X notify(player, "You can only give to other players."); X return; X } else if(db[who].pennies + amount > MAX_PENNIES) { X notify(player, "That player doesn't need that many pennies!"); X return; X } X } X break; X } X X /* try to do the give */ X if(!payfor(player, amount)) { X notify(player, "You don't have that many pennies to give!"); X } else { X /* he can do it */ X sprintf(buf, "You give %d %s to %s.", X amount, X amount == 1 ? "penny" : "pennies", X db[who].name); X notify(player, buf); X if(Typeof(who) == TYPE_PLAYER) { X sprintf(buf, "%s gives you %d %s.", X db[player].name, X amount, X amount == 1 ? "penny" : "pennies"); X notify(who, buf); X } X X db[who].pennies += amount; X } X} END_OF_FILE if test 4521 -ne `wc -c <'rob.c'`; then echo shar: \"'rob.c'\" unpacked with wrong size! fi # end of 'rob.c' fi if test -f 'set.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'set.c'\" else echo shar: Extracting \"'set.c'\" \(8181 characters\) sed "s/^X//" >'set.c' <<'END_OF_FILE' X#include "copyright.h" X X/* commands which set parameters */ X#include X#include X X#include "db.h" X#include "config.h" X#include "match.h" X#include "interface.h" X#include "externs.h" X Xstatic dbref match_controlled(dbref player, const char *name) X{ X dbref match; X X init_match(player, name, NOTYPE); X match_everything(); X X match = noisy_match_result(); X if(match != NOTHING && !controls(player, match)) { X notify(player, "Permission denied."); X return NOTHING; X } else { X return match; X } X} X Xvoid do_name(dbref player, const char *name, char *newname) X{ X dbref thing; X void free(void *); X char *password; X X if((thing = match_controlled(player, name)) != NOTHING) { X /* check for bad name */ X if(*newname == '\0') { X notify(player, "Give it what new name?"); X return; X } X X /* check for renaming a player */ X if(Typeof(thing) == TYPE_PLAYER) { X /* split off password */ X for(password = newname; isgraph(*password); password++); X X /* eat whitespace */ X if(*password) { X *password++ = '\0'; /* terminate name */ X while(*password && isspace(*password)) password++; X } X X /* check for null password */ X if(!*password) { X notify(player, X "You must specify a password to change a player name."); X notify(player, "E.g.: name player = newname password"); X return; X } else if(strcmp(password, db[thing].password)) { X notify(player, "Incorrect password."); X return; X } else if(!payfor(player, LOOKUP_COST) X || !ok_player_name(newname)) { X notify(player, "You can't give a player that name."); X return; X } X } else { X if(!ok_name(newname)) { X notify(player, "That is not a reasonable name."); X return; X } X } X X /* everything ok, change the name */ X if(db[thing].name) { X free((void *) db[thing].name); X } X db[thing].name = alloc_string(newname); X notify(player, "Name set."); X } X} X Xvoid do_describe(dbref player, const char *name, const char *description) X{ X dbref thing; X X if((thing = match_controlled(player, name)) != NOTHING) { X if(db[thing].description) { X free((void *) db[thing].description); X } X db[thing].description = alloc_string(description); X notify(player, "Description set."); X } X} X Xvoid do_fail(dbref player, const char *name, const char *message) X{ X dbref thing; X X if((thing = match_controlled(player, name)) != NOTHING) { X if(db[thing].fail_message) { X free((void *) db[thing].fail_message); X } X db[thing].fail_message = alloc_string(message); X notify(player, "Message set."); X } X} X Xvoid do_success(dbref player, const char *name, const char *message) X{ X dbref thing; X X if((thing = match_controlled(player, name)) != NOTHING) { X if(db[thing].succ_message) { X free((void *) db[thing].succ_message); X } X db[thing].succ_message = alloc_string(message); X notify(player, "Message set."); X } X} X Xvoid do_osuccess(dbref player, const char *name, const char *message) X{ X dbref thing; X X if((thing = match_controlled(player, name)) != NOTHING) { X if(db[thing].osuccess) { X free((void *) db[thing].osuccess); X } X db[thing].osuccess = alloc_string(message); X notify(player, "Message set."); X } X} X Xvoid do_ofail(dbref player, const char *name, const char *message) X{ X dbref thing; X X if((thing = match_controlled(player, name)) != NOTHING) { X if(db[thing].ofail) { X free((void *) db[thing].ofail); X } X db[thing].ofail = alloc_string(message); X notify(player, "Message set."); X } X} X Xvoid do_lock(dbref player, const char *name, const char *keyname) X{ X dbref thing; X dbref key; X int antilock; X X init_match(player, name, NOTYPE); X match_everything(); X X switch(thing = match_result()) { X case NOTHING: X notify(player, "I don't see what you want to lock!"); X return; X case AMBIGUOUS: X notify(player, "I don't know which one you want to lock!"); X return; X default: X if(!controls(player, thing)) { X notify(player, "You can't lock that!"); X return; X } X break; X } X X /* now we know it's ok to lock */ X if(antilock = (*keyname == NOT_TOKEN)) { X /* skip past ! and any following whitespace */ X for(keyname++; *keyname && isspace(*keyname); keyname++); X } X X /* match keyname */ X init_match(player, keyname, TYPE_THING); X match_neighbor(); X match_possession(); X match_me(); X match_player(); X if(Wizard(player)) match_absolute(); X X switch(key = match_result()) { X case NOTHING: X notify(player, "I can't find that key!"); X return; X case AMBIGUOUS: X notify(player, "I don't know which key you want!"); X return; X default: X if(Typeof(key) != TYPE_PLAYER X && Typeof(key) != TYPE_THING) { X notify(player, "Keys can only be players or things."); X return; X } X break; X } X X /* everything ok, do it */ X db[thing].key = key; X if(antilock) { X db[thing].flags |= ANTILOCK; X notify(player, "Anti-Locked."); X } else { X db[thing].flags &= ~ANTILOCK; X notify(player, "Locked."); X } X} X Xvoid do_unlock(dbref player, const char *name) X{ X dbref thing; X X if((thing = match_controlled(player, name)) != NOTHING) { X db[thing].key = NOTHING; X db[thing].flags &= ~ANTILOCK; X notify(player, "Unlocked."); X } X} X Xvoid do_unlink(dbref player, const char *name) X{ X dbref exit; X X init_match(player, name, TYPE_EXIT); X match_exit(); X match_here(); X if(Wizard(player)) { X match_absolute(); X } X X switch(exit = match_result()) { X case NOTHING: X notify(player, "Unlink what?"); X break; X case AMBIGUOUS: X notify(player, "I don't know which one you mean!"); X break; X default: X if(!controls(player, exit)) { X notify(player, "Permission denied."); X } else { X switch(Typeof(exit)) { X case TYPE_EXIT: X db[exit].location = NOTHING; X notify(player, "Unlinked."); X break; X case TYPE_ROOM: X db[exit].location = NOTHING; X notify(player, "Dropto removed."); X break; X default: X notify(player, "You can't unlink that!"); X break; X } X } X } X} X Xvoid do_chown(dbref player, const char *name, const char *newobj) X{ X dbref thing; X dbref owner; X X if(!Wizard(player)) { X notify(player, "Permission denied."); X } else { X init_match(player, name, NOTYPE); X match_everything(); X X if((thing = noisy_match_result()) == NOTHING) { X return; X } else if((owner = lookup_player(newobj)) == NOTHING) { X notify(player, "I couldn't find that player."); X } else if(Typeof(thing) == TYPE_PLAYER) { X notify(player, "Players always own themselves."); X } else { X db[thing].owner = owner; X notify(player, "Owner changed."); X } X } X} X Xvoid do_set(dbref player, const char *name, const char *flag) X{ X dbref thing; X const char *p; X object_flag_type f; X X /* find thing */ X if((thing = match_controlled(player, name)) == NOTHING) return; X X /* move p past NOT_TOKEN if present */ X for(p = flag; *p && (*p == NOT_TOKEN || isspace(*p)); p++); X X /* identify flag */ X if(*p == '\0') { X notify(player, "You must specify a flag to set."); X return; X } else if(string_prefix("LINK_OK", p)) { X f = LINK_OK; X } else if(string_prefix("DARK", p)) { X f = DARK; X } else if(string_prefix("STICKY", p)) { X f = STICKY; X } else if(string_prefix("WIZARD", p)) { X f = WIZARD; X } else if(string_prefix("TEMPLE", p)) { X f = TEMPLE; X#ifdef RESTRICTED_BUILDING X } else if(string_prefix("BUILDER", p)) { X f = BUILDER; X#endif /* RESTRICTED_BUILDING */ X } else { X notify(player, "I don't recognized that flag."); X return; X } X X /* check for restricted flag */ X if(!Wizard(player) X && (f == WIZARD X#ifdef RESTRICTED_BUILDING X || f == BUILDER X#endif /* RESTRICTED_BUILDING */ X || f == TEMPLE X || f == DARK && Typeof(thing) != TYPE_ROOM)) { X notify(player, "Permission denied."); X return; X } X X /* check for stupid wizard */ X if(f == WIZARD && *flag == NOT_TOKEN && thing == player) { X notify(player, "You cannot make yourself mortal."); X return; X } X X /* else everything is ok, do the set */ X if(*flag == NOT_TOKEN) { X /* reset the flag */ X db[thing].flags &= ~f; X notify(player, "Flag reset."); X } else { X /* set the flag */ X db[thing].flags |= f; X notify(player, "Flag set."); X } X} X END_OF_FILE if test 8181 -ne `wc -c <'set.c'`; then echo shar: \"'set.c'\" unpacked with wrong size! fi # end of 'set.c' fi if test -f 'wiz.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'wiz.c'\" else echo shar: Extracting \"'wiz.c'\" \(4178 characters\) sed "s/^X//" >'wiz.c' <<'END_OF_FILE' X#include "copyright.h" X X/* Wizard-only commands */ X X#include "db.h" X#include "interface.h" X#include "match.h" X#include "externs.h" X Xvoid do_teleport(dbref player, const char *arg1, const char *arg2) X{ X dbref victim; X dbref destination; X const char *to; X X if(!Wizard(player)) { X notify(player, "Only a Wizard may teleport at will."); X return; X } X X /* get victim, destination */ X if(*arg2 == '\0') { X victim = player; X to = arg1; X } else { X init_match(player, arg1, NOTYPE); X match_neighbor(); X match_possession(); X match_me(); X match_absolute(); X match_player(); X X if((victim = noisy_match_result()) == NOTHING) { X return; X } X to = arg2; X } X X /* get destination */ X init_match(player, to, TYPE_PLAYER); X match_neighbor(); X match_me(); X match_here(); X match_absolute(); X match_player(); X X switch(destination = match_result()) { X case NOTHING: X notify(player, "Send it where?"); X break; X case AMBIGUOUS: X notify(player, "I don't know which destination you mean!"); X break; X default: X /* check victim, destination types, teleport if ok */ X if(Typeof(destination) == TYPE_EXIT X || Typeof(destination) == TYPE_THING X || Typeof(victim) == TYPE_EXIT X || Typeof(victim) == TYPE_ROOM X || (Typeof(victim) == TYPE_PLAYER X && Typeof(destination) != TYPE_ROOM)) { X notify(player, "Bad destination."); X } else if(Typeof(victim) == TYPE_PLAYER) { X notify(victim, "You feel a wrenching sensation..."); X enter_room(victim, destination); X } else { X moveto(victim, destination); X } X } X} X Xvoid do_force(dbref player, const char *what, char *command) X{ X dbref victim; X X if(!Wizard(player)) { X notify(player, "Only Wizards may use this command."); X return; X } X X /* get victim */ X if((victim = lookup_player(what)) == NOTHING) { X notify(player, "That player does not exist."); X return; X } X X /* force victim to do command */ X process_command(victim, command); X} X Xvoid do_stats(dbref player, const char *name) X{ X dbref rooms; X dbref exits; X dbref things; X dbref players; X dbref unknowns; X dbref total; X dbref i; X dbref owner; X char buf[BUFFER_LEN]; X X if(!Wizard(player)) { X sprintf(buf, "The universe contains %d objects.", db_top); X notify(player, buf); X } else { X owner = lookup_player(name); X total = rooms = exits = things = players = unknowns = 0; X for(i = 0; i < db_top; i++) { X if(owner == NOTHING || owner == db[i].owner) { X total++; X switch(Typeof(i)) { X case TYPE_ROOM: X rooms++; X break; X case TYPE_EXIT: X exits++; X break; X case TYPE_THING: X things++; X break; X case TYPE_PLAYER: X players++; X break; X default: X unknowns++; X break; X } X } X } X sprintf(buf, X "%d objects = %d rooms, %d exits, %d things, %d players, %d unknowns.", X total, rooms, exits, things, players, unknowns); X notify(player, buf); X } X} X Xvoid do_toad(dbref player, const char *name) X{ X dbref victim; X char buf[BUFFER_LEN]; X X if(!Wizard(player)) { X notify(player, "Only a Wizard can turn a person into a toad."); X return; X } X X init_match(player, name, TYPE_PLAYER); X match_neighbor(); X match_absolute(); X match_player(); X if((victim = noisy_match_result()) == NOTHING) return; X X if(Typeof(victim) != TYPE_PLAYER) { X notify(player, "You can only turn players into toads!"); X } else if(Wizard(victim)) { X notify(player, "You can't turn a Wizard into a toad."); X } else if(db[victim].contents != NOTHING) { X notify(player, "What about what they are carrying?"); X } else { X /* we're ok */ X /* do it */ X if(db[victim].password) { X free(db[victim].password); X db[victim].password = 0; X } X db[victim].flags = TYPE_THING; X db[victim].owner = player; /* you get it */ X db[victim].pennies = 1; /* don't let him keep his immense wealth */ X X /* notify people */ X notify(victim, "You have been turned into a toad."); X sprintf(buf, "You turned %s into a toad!", db[victim].name); X notify(player, buf); X X /* reset name */ X sprintf(buf, "a slimy toad named %s", db[victim].name); X free(db[victim].name); X db[victim].name = alloc_string(buf); X } X} END_OF_FILE if test 4178 -ne `wc -c <'wiz.c'`; then echo shar: \"'wiz.c'\" unpacked with wrong size! fi # end of 'wiz.c' fi echo shar: End of archive 3 \(of 4\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 4 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0