[comp.sources.games] v11i014: tinymud2 - user-extendible multi-user adventure

billr@saab.CNA.TEK.COM (Bill Randle) (07/30/90)

Submitted-by: James Aspnes <asp@cs.cmu.edu>
Posting-number: Volume 11, Issue 14
Archive-name: tinymud2/Part10
Supersedes: tinymud: Volume 8, Issue 80-83



#! /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 <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 10 (of 10)."
# Contents:  boolexp.c copyright.h decompress.c do_gripes externs.h
#   help.c help.txt interface.h match.h restart-day restart-night
#   rob.c sanity-check.c small.db.README stringutil.c unparse.c
#   utils.c
# Wrapped by billr@saab on Fri Jul 27 15:27:51 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'boolexp.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'boolexp.c'\"
else
echo shar: Extracting \"'boolexp.c'\" \(3952 characters\)
sed "s/^X//" >'boolexp.c' <<'END_OF_FILE'
X#include "copyright.h"
X
X#include <ctype.h>
X
X#include "db.h"
X#include "match.h"
X#include "externs.h"
X#include "config.h"
X#include "interface.h"
X
Xint eval_boolexp(dbref player, struct boolexp *b)
X{
X    if(b == TRUE_BOOLEXP) {
X	return 1;
X    } else {
X	switch(b->type) {
X	  case BOOLEXP_AND:
X	    return (eval_boolexp(player, b->sub1)
X		    && eval_boolexp(player, b->sub2));
X	  case BOOLEXP_OR:
X	    return (eval_boolexp(player, b->sub1)
X		    || eval_boolexp(player, b->sub2));
X	  case BOOLEXP_NOT:
X	    return !eval_boolexp(player, b->sub1);
X	  case BOOLEXP_CONST:
X	    return (b->thing == player
X		    || member(b->thing, db[player].contents));
X	  default:
X	    abort();		/* bad type */
X	    return 0;
X	}
X    }
X}
X
X/* If the parser returns TRUE_BOOLEXP, you lose */
X/* TRUE_BOOLEXP cannot be typed in by the user; use @unlock instead */
Xstatic const char *parsebuf;
Xstatic dbref parse_player;
X
Xstatic void skip_whitespace(void)
X{
X    while(*parsebuf && isspace(*parsebuf)) parsebuf++;
X}
X
Xstatic struct boolexp *parse_boolexp_E(void); /* defined below */
X
X/* F -> (E); F -> !F; F -> object identifier */
Xstatic struct boolexp *parse_boolexp_F(void)
X{
X    struct boolexp *b;
X    char *p;
X    char buf[BUFFER_LEN];
X    char msg[BUFFER_LEN];
X
X    skip_whitespace();
X    switch(*parsebuf) {
X      case '(':
X	parsebuf++;
X	b = parse_boolexp_E();
X	skip_whitespace();
X	if(b == TRUE_BOOLEXP || *parsebuf++ != ')') {
X	    free_boolexp(b);
X	    return TRUE_BOOLEXP;
X	} else {
X	    return b;
X	}
X	/* break; */
X      case NOT_TOKEN:
X	parsebuf++;
X	b = (struct boolexp *) malloc(sizeof(struct boolexp));
X	b->type = BOOLEXP_NOT;
X	b->sub1 = parse_boolexp_F();
X	if(b->sub1 == TRUE_BOOLEXP) {
X	    free((void *) b);
X	    return TRUE_BOOLEXP;
X	} else {
X	    return b;
X	}
X	/* break */
X      default:
X	/* must have hit an object ref */
X	/* load the name into our buffer */
X	p = buf;
X	while(*parsebuf
X	      && *parsebuf != AND_TOKEN
X	      && *parsebuf != OR_TOKEN
X	      && *parsebuf != ')') {
X	    *p++ = *parsebuf++;
X	}
X	/* strip trailing whitespace */
X	*p-- = '\0';
X	while(isspace(*p)) *p-- = '\0';
X
X	b = (struct boolexp *) malloc(sizeof(struct boolexp));
X	b->type = BOOLEXP_CONST;
X
X	/* do the match */
X	init_match(parse_player, buf, TYPE_THING);
X	match_neighbor();
X	match_possession();
X	match_me();
X	match_absolute();
X	match_player();
X	b->thing = match_result();
X
X	if(b->thing == NOTHING) {
X	    sprintf(msg, "I don't see %s here.", buf);
X	    notify(parse_player, msg);
X	    free((void *) b);
X	    return TRUE_BOOLEXP;
X	} else if(b->thing == AMBIGUOUS) {
X	    sprintf(msg, "I don't know which %s you mean!", buf);
X	    notify(parse_player, msg);
X	    free((void *) b);
X	    return TRUE_BOOLEXP;
X	} else {
X	    return b;
X	}
X	/* break */
X    }
X}
X
X/* T -> F; T -> F & T */
Xstatic struct boolexp *parse_boolexp_T(void)
X{
X    struct boolexp *b;
X    struct boolexp *b2;
X
X    if((b = parse_boolexp_F()) == TRUE_BOOLEXP) {
X	return b;
X    } else {
X	skip_whitespace();
X	if(*parsebuf == AND_TOKEN) {
X	    parsebuf++;
X
X	    b2 = (struct boolexp *) malloc(sizeof(struct boolexp));
X	    b2->type = BOOLEXP_AND;
X	    b2->sub1 = b;
X	    if((b2->sub2 = parse_boolexp_T()) == TRUE_BOOLEXP) {
X		free_boolexp(b2);
X		return TRUE_BOOLEXP;
X	    } else {
X		return b2;
X	    }
X	} else {
X	    return b;
X	}
X    }
X}
X
X/* E -> T; E -> T | E */
Xstatic struct boolexp *parse_boolexp_E(void)
X{
X    struct boolexp *b;
X    struct boolexp *b2;
X
X    if((b = parse_boolexp_T()) == TRUE_BOOLEXP) {
X	return b;
X    } else {
X	skip_whitespace();
X	if(*parsebuf == OR_TOKEN) {
X	    parsebuf++;
X
X	    b2 = (struct boolexp *) malloc(sizeof(struct boolexp));
X	    b2->type = BOOLEXP_OR;
X	    b2->sub1 = b;
X	    if((b2->sub2 = parse_boolexp_E()) == TRUE_BOOLEXP) {
X		free_boolexp(b2);
X		return TRUE_BOOLEXP;
X	    } else {
X		return b2;
X	    }
X	} else {
X	    return b;
X	}
X    }
X}
X
Xstruct boolexp *parse_boolexp(dbref player, const char *buf)
X{
X    parsebuf = buf;
X    parse_player = player;
X    return parse_boolexp_E();
X}
END_OF_FILE
if test 3952 -ne `wc -c <'boolexp.c'`; then
    echo shar: \"'boolexp.c'\" unpacked with wrong size!
fi
# end of 'boolexp.c'
fi
if test -f 'copyright.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'copyright.h'\"
else
echo shar: Extracting \"'copyright.h'\" \(1424 characters\)
sed "s/^X//" >'copyright.h' <<'END_OF_FILE'
X/* -*-C-*-
X
XCopyright (c) 1989, 1990 by David Applegate, James Aspnes, Timothy Freeman,
X		        and Bennet Yee.
X
XThis material was developed by the above-mentioned authors.
XPermission to copy this software, to redistribute it, and to use it
Xfor any purpose is granted, subject to the following restrictions and
Xunderstandings.
X
X1. Any copy made of this software must include this copyright notice
Xin full.
X
X2. Users of this software agree to make their best efforts (a) to
Xreturn to the above-mentioned authors any improvements or extensions
Xthat they make, so that these may be included in future releases; and
X(b) to inform the authors of noteworthy uses of this software.
X
X3. All materials developed as a consequence of the use of this
Xsoftware shall duly acknowledge such use, in accordance with the usual
Xstandards of acknowledging credit in academic research.
X
X4. The authors have made no warrantee or representation that the
Xoperation of this software will be error-free, and the authors are
Xunder no obligation to provide any services, by way of maintenance,
Xupdate, or otherwise.
X
X5. In conjunction with products arising from the use of this material,
Xthere shall be no use of the names of the authors, of Carnegie-Mellon
XUniversity, nor of any adaptation thereof in any advertising,
Xpromotional, or sales literature without prior written consent from
Xthe authors and Carnegie-Mellon University in each case. */
X
END_OF_FILE
if test 1424 -ne `wc -c <'copyright.h'`; then
    echo shar: \"'copyright.h'\" unpacked with wrong size!
fi
# end of 'copyright.h'
fi
if test -f 'decompress.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'decompress.c'\"
else
echo shar: Extracting \"'decompress.c'\" \(164 characters\)
sed "s/^X//" >'decompress.c' <<'END_OF_FILE'
X#include <stdio.h>
X
Xconst char *uncompress(const char *s);
X
Xint main()
X{
X    char buf[16384];
X
X    while(gets(buf)) {
X	puts(uncompress(buf));
X    }
X    return 0;
X}
END_OF_FILE
if test 164 -ne `wc -c <'decompress.c'`; then
    echo shar: \"'decompress.c'\" unpacked with wrong size!
fi
# end of 'decompress.c'
fi
if test -f 'do_gripes' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'do_gripes'\"
else
echo shar: Extracting \"'do_gripes'\" \(711 characters\)
sed "s/^X//" >'do_gripes' <<'END_OF_FILE'
X#! /bin/sh
X#
X# This shell script should be run by CRON or ATRUN daily to extract
X# 
X#
Xcd /usr/tinymud/lib
X
XADDR=$USER
XLOGFILE=tinymud.log
XGRIPELOG=tinymud.gripes
XTMPFILE=/tmp/allgripes${$}
XNEWGRIPES=/tmp/newgripes${$}
X
X#
X# Long version of logs
X#
X#egrep 'GRIPE from|FORCE:|WIZARD:|BOBBLE:|BOOT:|SHUTDOWN:|ROBOT:' ${LOGFILE} | sort > ${TMPFILE}
X#
X# Short version of logs
X#
Xegrep 'GRIPE from|WIZARD:|SHUTDOWN:' ${LOGFILE} | sort > ${TMPFILE}
X
Xsort -o ${GRIPELOG} ${GRIPELOG}
X
Xcomm -13 ${GRIPELOG} ${TMPFILE} > ${NEWGRIPES}
X
Xif test -s ${NEWGRIPES}
Xthen
X	awk '{print $0;printf "\n"}' ${NEWGRIPES} | \
X		fmt | Mail -s "Daily TinyMUD gripes" ${ADDR}
X	cat ${NEWGRIPES} >> ${GRIPELOG}
Xfi
X
Xrm -f ${TMPFILE} ${NEWGRIPES}
END_OF_FILE
if test 711 -ne `wc -c <'do_gripes'`; then
    echo shar: \"'do_gripes'\" unpacked with wrong size!
fi
chmod +x 'do_gripes'
# end of 'do_gripes'
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'\" \(4348 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);
Xextern void writelog(const char *, ...);
X
X/* From help.c */
Xint 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, object_flag_type what, 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, const char *arg2);
Xextern void notify_except(dbref first, dbref exception, const char *msg);
Xextern void notify_except2(dbref first, dbref ex1, dbref ex2, 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);
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);
X
X/* From boolexp.c */
Xextern int eval_boolexp(dbref player, struct boolexp *b);
Xextern struct boolexp *parse_boolexp(dbref player, const char *string);
X
X/* From unparse.c */
Xextern const char *unparse_object(dbref player, dbref object);
Xextern const char *unparse_boolexp(dbref player, struct boolexp *);
X
X/* From compress.c */
X#ifdef COMPRESS
Xextern const char *compress(const char *);
Xextern const char *uncompress(const char *);
Xextern void init_compress(void);
X#endif /* COMPRESS */
END_OF_FILE
if test 4348 -ne `wc -c <'externs.h'`; then
    echo shar: \"'externs.h'\" unpacked with wrong size!
fi
# end of 'externs.h'
fi
if test -f 'help.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'help.c'\"
else
echo shar: Extracting \"'help.c'\" \(1137 characters\)
sed "s/^X//" >'help.c' <<'END_OF_FILE'
X#include "copyright.h"
X
X/* commands for giving help */
X
X#include "db.h"
X#include "config.h"
X#include "interface.h"
X#include "externs.h"
X
Xint spit_file(dbref player, const char *filename)
X{
X    FILE *f;
X    char buf[BUFFER_LEN];
X    char *p;
X
X    if((f = fopen(filename, "r")) == NULL) {
X	return (0);
X    } else {
X	while(fgets(buf, sizeof buf, f)) {
X	    for(p = buf; *p; p++) if(*p == '\n') {
X		*p = '\0';
X		break;
X	    }
X	    notify(player, buf);
X	}
X	fclose(f);
X	return (1);
X    }
X}
X
Xvoid do_help(dbref player)
X{
X    if (!spit_file(player, HELP_FILE))
X    { notify(player, "Sorry, the help file is missing right now.");
X      writelog("GRIPE automatically generated for %s(%d): no help file %s\n",
X	       db[player].name, player, HELP_FILE);      
X    }
X}
X
Xvoid do_news(dbref player)
X{ int result = 0;
X
X  result += spit_file(player, NEWS_FILE);
X  result += spit_file(player, MOTD_FILE);
X  if (Wizard(player)) result += spit_file(player, WIZARD_FILE);
X
X  if (result == 0)
X  { notify(player, "No news today."); }
X}
X
Xvoid do_motd(dbref player)
X{
X    spit_file(player, MOTD_FILE);
X    if (Wizard(player)) spit_file(player, WIZARD_FILE);
X}
END_OF_FILE
if test 1137 -ne `wc -c <'help.c'`; then
    echo shar: \"'help.c'\" unpacked with wrong size!
fi
# end of 'help.c'
fi
if test -f 'help.txt' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'help.txt'\"
else
echo shar: Extracting \"'help.txt'\" \(1009 characters\)
sed "s/^X//" >'help.txt' <<'END_OF_FILE'
XThis is TinyMUD version 1.5.4, a user-extendible, multi-user adventure game.
X
XBasic commands: 
X move/go <direction>
X get/take <thing>; drop/throw <thing>
X look; look <thing>; look <direction>
X say <message>; whisper <player> = <message>
X rob <player>; give <player> = <number of pennies>; kill <player>
X inventory
X help
X news
X @describe me = <description>
X @password <oldpassword>=<newpassword>
X page <player> --- tell player that you are looking for them (cost 1 penny)
X gripe <message> --- Complain to the management.
X home --- go home
XOther commands are available for extending the universe.  Many of
Xthese commands cost pennies, which you can obtain in a number of ways.
XFull names of exits can be used in place of a go or move command.  The
Xnames "me" and "here" are special; me means the current player, and
Xhere means the current player's location.
XMore information is available in the reference section of the Library,
Xnorth of the Temple.
XRemember, no matter how bad it gets, you can always go home.
END_OF_FILE
if test 1009 -ne `wc -c <'help.txt'`; then
    echo shar: \"'help.txt'\" unpacked with wrong size!
fi
# end of 'help.txt'
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'\" \(800 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 int 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)*8)
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 800 -ne `wc -c <'interface.h'`; then
    echo shar: \"'interface.h'\" unpacked with wrong size!
fi
# end of 'interface.h'
fi
if test -f 'match.h' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'match.h'\"
else
echo shar: Extracting \"'match.h'\" \(1359 characters\)
sed "s/^X//" >'match.h' <<'END_OF_FILE'
X#include "copyright.h"
X
X#include "db.h"
X
X/* match functions */
X/* Usage: init_match(player, name, type); match_this(); match_that(); ... */
X/* Then get value from match_result() */
X
X/* initialize matcher */
Xextern void init_match(dbref player, const char *name, int type);
Xextern void init_match_check_keys(dbref player, const char *name, int type);
X
X/* match (LOOKUP_TOKEN)player */
Xextern void match_player(void);
X
X/* match (NUMBER_TOKEN)number */
Xextern void match_absolute(void);
X
X/* match "me" */
Xextern void match_me(void);
X
X/* match "here" */
Xextern void match_here(void);
X
X/* match something player is carrying */
Xextern void match_possession(void);
X
X/* match something in the same room as player */
Xextern void match_neighbor(void);
X
X/* match an exit from player's room */
Xextern void match_exit(void);
X
X/* all of the above, except only Wizards do match_absolute and match_player */
Xextern void match_everything(void);
X
X/* return match results */
Xextern dbref match_result(void); /* returns AMBIGUOUS for multiple inexacts */
Xextern dbref last_match_result(void); /* returns last result */
X
X#define NOMATCH_MESSAGE "I don't see that here."
X#define AMBIGUOUS_MESSAGE "I don't know which one you mean!"
X
Xextern dbref noisy_match_result(void); /* wrapper for match_result */
X				/* noisily notifies player */
X				/* returns matched object or NOTHING */
END_OF_FILE
if test 1359 -ne `wc -c <'match.h'`; then
    echo shar: \"'match.h'\" unpacked with wrong size!
fi
# end of 'match.h'
fi
if test -f 'restart-day' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'restart-day'\"
else
echo shar: Extracting \"'restart-day'\" \(726 characters\)
sed "s/^X//" >'restart-day' <<'END_OF_FILE'
X#!/bin/csh -f
X
Xset WINNER = `rpick < lottery`
X
Xecho "Starting Daytime Islandia, lottery winner is $WINNER..."
X
Xcd /clients/Islandia/lib
Xif(-r islandia.db.new) then
X	set input = islandia.db.new
Xelse
X	set input = islandia.db
Xendif
X
Xcp /dev/null connect.txt
Xif(-r connect.day) cp connect.day connect.txt
Xif(-r motd.day) cp motd.day motd.txt
X
Xecho "" >> motd.txt
Xecho "		Today's Lottery Winner is $WINNER" >> motd.txt
Xecho "" >> motd.txt
X
X../bin/extract norecycle reachable players b1370 \
X	-274 -560 -809 1384 1403 1404 1406 1505 \
X	Tinker Lynx Tygling Three Janitor Mav \
X	$WINNER \
X	< $input > day.db
X
Xcp ../bin/netmud netmud.r
Xecho RESTARTED DAY VERSION AT `date` >> islandia.log
Xnetmud.r day.db day.db.new >>& islandia.log &
END_OF_FILE
if test 726 -ne `wc -c <'restart-day'`; then
    echo shar: \"'restart-day'\" unpacked with wrong size!
fi
chmod +x 'restart-day'
# end of 'restart-day'
fi
if test -f 'restart-night' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'restart-night'\"
else
echo shar: Extracting \"'restart-night'\" \(422 characters\)
sed "s/^X//" >'restart-night' <<'END_OF_FILE'
X#!/bin/csh -f
Xcd /clients/Islandia/lib
Xmv islandia.db islandia.db.old
Xif(-r islandia.db.new) then
X	mv islandia.db.new islandia.db
Xelse
X	cp islandia.db.old islandia.db
Xendif
X
Xcp ../bin/netmud.conc netmud.c
Xcp ../bin/concentrate .
Xif(-r connect.night) cp connect.night connect.txt
Xif(-r motd.night) cp motd.night motd.txt
Xecho RESTARTED AT `date` >> islandia.log
Xnice netmud.c islandia.db islandia.db.new >>& islandia.log &
END_OF_FILE
if test 422 -ne `wc -c <'restart-night'`; then
    echo shar: \"'restart-night'\" unpacked with wrong size!
fi
chmod +x 'restart-night'
# end of 'restart-night'
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'\" \(4685 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 thing;
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_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 ((db[db[victim].location].flags & HAVEN) &&
X		   !Wizard(player)) {
X	    notify(player, "Sorry, this room is safe from killing.");
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		      && !Wizard(victim)) {
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
X		/* maybe pay off the bonus */
X		if(db[victim].pennies < MAX_PENNIES) {
X		    sprintf(buf, "Your insurance policy pays %d pennies.",
X			    KILL_BONUS);
X		    notify(victim, buf);
X		    db[victim].pennies += KILL_BONUS;
X		} else {
X		    notify(victim, "Your insurance policy has been revoked.");
X		}
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 4685 -ne `wc -c <'rob.c'`; then
    echo shar: \"'rob.c'\" unpacked with wrong size!
fi
# end of 'rob.c'
fi
if test -f 'sanity-check.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'sanity-check.c'\"
else
echo shar: Extracting \"'sanity-check.c'\" \(3984 characters\)
sed "s/^X//" >'sanity-check.c' <<'END_OF_FILE'
X#include "copyright.h"
X
X#include <stdio.h>
X
X#include "db.h"
X#include "config.h"
X
X# define HAS_ENTRANCES 0x40000000
X
Xvoid check_exits(dbref i)
X{
X    dbref exit;
X    int count;
X
X    count = 10000;
X    for(exit = db[i].exits;
X	exit != NOTHING;
X	exit = db[exit].next) {
X	if(exit < 0 || exit >= db_top || Typeof(exit) != TYPE_EXIT) {
X	    printf("%d has bad exit %d\n", i, exit);
X	    break;
X	}
X
X	/* set type of exit to be really strange */
X	db[exit].flags = 4;	/* nonexistent type */
X
X	if(count-- < 0) {
X	    printf("%d has looping exits\n");
X	    break;
X	}
X    }
X}
X
Xvoid check_contents(dbref i)
X{
X    dbref thing;
X    dbref loc;
X    int count;
X
X    count = 10000;
X    for(thing = db[i].contents;
X	thing != NOTHING;
X	thing = db[thing].next) {
X	if(thing < 0 || thing >= db_top || Typeof(thing) == TYPE_ROOM) {
X	    printf("%d contains bad object %d\n", i, thing);
X	    break;
X	} else if(Typeof(thing) == TYPE_EXIT) {
X	    db[thing].flags = 4; /* nonexistent type */
X	} else if((loc = db[thing].location) != i) {
X	    printf("%d in %d but location is %d\n", thing, i, loc);
X	}
X	if(count-- < 0) {
X	    printf("%d has looping contents\n");
X	    break;
X	}
X    }
X}
X
Xvoid check_location(dbref i)
X{
X    dbref loc;
X
X    loc = db[i].location;
X    if(loc < 0 || loc >= db_top) {
X	printf("%d has bad loc %d\n", i, loc);
X    } else if(!member(i, db[loc].contents)) {
X	printf("%d not in loc %d\n", i, loc);
X    }
X}
X
Xvoid check_owner(dbref i)
X{
X    dbref owner;
X
X    owner = db[i].owner;
X    if(owner < 0 || owner >= db_top || Typeof(owner) != TYPE_PLAYER) {
X	printf("Object %s(%d) has bad owner %d\n",
X	       db[i].name, i, owner);
X    }
X}
X
Xvoid check_pennies(dbref i)
X{
X    dbref pennies;
X
X    pennies = db[i].pennies;
X
X    switch(Typeof(i)) {
X      case TYPE_ROOM:
X      case TYPE_EXIT:
X	break;
X      case TYPE_PLAYER:
X	if(pennies < 0 || pennies > MAX_PENNIES+100) {
X	    printf("Player %s(%d) has %d pennies\n", db[i].name, i, pennies);
X	}
X	break;
X      case TYPE_THING:
X	if(pennies < 0 || pennies > MAX_OBJECT_ENDOWMENT) {
X	    printf("Object %s(%d) endowed with %d pennies\n",
X		   db[i].name, i, pennies);
X	}
X	break;
X    }
X}
X
Xvoid main(int argc, char **argv)
X{
X    dbref i;
X
X    if(db_read(stdin) < 0) {
X	puts("Database load failed!");
X	exit(1);
X    } 
X
X    puts("Done loading database");
X
X    for(i = 0; i < db_top; i++) {
X	check_pennies(i);
X	check_owner(i);
X	switch(Typeof(i)) {
X	  case TYPE_PLAYER:
X	    check_contents(i);
X	    check_location(i);
X	    if(Wizard(i)) printf("Wizard: %s(%d)\n", db[i].name, i);
X	    if(Dark(i)) printf("Dark: %s(%d)\n", db[i].name, i);
X	    if(Robot(i)) printf("Robot: %s(%d)\n", db[i].name, i);
X	    if(db[i].password == NULL)
X	    { printf ("Null password: %s(%d)\n", db[i].name, i); }
X	    break;
X	  case TYPE_THING:
X	    check_location(i);
X	    break;
X	  case TYPE_ROOM:
X	    if(Robot(i)) printf("UnRobot: %s(%d)\n", db[i].name, i);
X	    check_contents(i);
X	    check_exits(i);
X	    break;
X	}
X    }
X
X    /* scan for unattached exits */
X    for(i = 0; i < db_top; i++) {
X	if(Typeof(i) == TYPE_EXIT) {
X	    printf("Unattached exit %d\n", i);
X	}
X    }
X	    
X    /* scan for unattached exits */
X    for(i = 0; i < db_top; i++) {
X	if(Typeof(i) == TYPE_EXIT) {
X	    printf("Unattached exit %d\n", i);
X	}
X    }
X	    
X    /*---- scan for unattached rooms ----*/
X    
X    /* Clear entry flags */
X    for(i = 0; i < db_top; i++) db[i].flags &= ~HAS_ENTRANCES;
X
X    /* For each exit, set its destination entry bit */    
X    for(i = 0; i < db_top; i++) {
X	if(Typeof(i) == TYPE_EXIT || Typeof(i) == 4) {
X	    if(db[i].location >= 0) db[db[i].location].flags |= HAS_ENTRANCES;
X	}
X    }
X
X    /* Now print every room with no entrances */    
X    for(i = 0; i < db_top; i++) {
X	if(Typeof(i) == TYPE_ROOM && 
X	   (db[i].flags & HAS_ENTRANCES) == 0) {
X	    if (db[i].exits == NOTHING && db[i].contents == NOTHING) {
X		printf ("Room %d has no entrances, exits, or contents\n", i);
X	    } else {
X		printf ("Room %d has no entrances\n", i);
X	    }
X	}
X    }
X	    
X    exit(0);
X}
END_OF_FILE
if test 3984 -ne `wc -c <'sanity-check.c'`; then
    echo shar: \"'sanity-check.c'\" unpacked with wrong size!
fi
# end of 'sanity-check.c'
fi
if test -f 'small.db.README' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'small.db.README'\"
else
echo shar: Extracting \"'small.db.README'\" \(1507 characters\)
sed "s/^X//" >'small.db.README' <<'END_OF_FILE'
XNotes to new administrators using small.db:
X
X1. There are four objects of type player in small.db: Wizard(#1),
XBeaker(#2), guy(#121), and Darooha(#203).  As distributed, all have
Xthe password "potrzebie."  Wizard is the administrative player; it is
Xthe only one that has its WIZARD bit set, and it owns most of the core
Xrooms.  Beaker is included for testing.  guy and Darooha own the
X"Eastward Ho" and "Bud's" adventures; if you want to leave these
Xsamples out, you can remove them using extract.  Only the Wizard and
Xthe objects owned by the Wizard are really important...
X
X2. Small.db contains no unlinked exits; thus it will be impossible for
Xanybody who is not a WIZARD to connect new rooms to the core rooms.
XWhen TinyMUD was first started up on LANCELOT.AVALON.CS.CMU.EDU, the
XTown Square was given 9 unlinked exits (7 of the 8 cardinal directions
Xplus up and down) and was set to be LINK_OK; this allowed early
Xconstruction to take place in the neighborhood of the Town Square
Xwithout the need for administrative oversight.  
X
XWhile this policy worked well during the early lifetime of the game,
Xas the database grew the immediate surroundings of the Town Square
Xbecame rather chaotic, and only a few of the directions exits from it
Xgot much use.  It might be reasonable to build a more extensive Town
XCenter before allowing haphazard construction.
X
X--Jim Aspnes
X
XYou might want instead to get a copy of TinyBASE, a more logical and
Xcomplete basis for starting a new MUD.
X
X--Michael Mauldin (Fuzzy)
END_OF_FILE
if test 1507 -ne `wc -c <'small.db.README'`; then
    echo shar: \"'small.db.README'\" unpacked with wrong size!
fi
# end of 'small.db.README'
fi
if test -f 'stringutil.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'stringutil.c'\"
else
echo shar: Extracting \"'stringutil.c'\" \(846 characters\)
sed "s/^X//" >'stringutil.c' <<'END_OF_FILE'
X#include "copyright.h"
X
X/* String utilities */
X
X#include <ctype.h>
X
X#define DOWNCASE(x) (isupper(x) ? tolower(x) : (x))
X
Xint string_compare(const char *s1, const char *s2)
X{
X    while(*s1 && *s2 && DOWNCASE(*s1) == DOWNCASE(*s2)) s1++, s2++;
X
X    return(DOWNCASE(*s1) - DOWNCASE(*s2));
X}
X
Xint string_prefix(const char *string, const char *prefix)
X{
X    while(*string && *prefix && DOWNCASE(*string) == DOWNCASE(*prefix))
X	string++, prefix++;
X    return *prefix == '\0';
X}
X
X/* accepts only nonempty matches starting at the beginning of a word */
Xconst char *string_match(const char *src, const char *sub)
X{
X    if(*sub != '\0') {
X	while(*src) {
X	    if(string_prefix(src, sub)) return src;
X	    /* else scan to beginning of next word */
X	    while(*src && isalnum(*src)) src++;
X	    while(*src && !isalnum(*src)) src++;
X	}
X    }
X
X    return 0;
X}
X
END_OF_FILE
if test 846 -ne `wc -c <'stringutil.c'`; then
    echo shar: \"'stringutil.c'\" unpacked with wrong size!
fi
# end of 'stringutil.c'
fi
if test -f 'unparse.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'unparse.c'\"
else
echo shar: Extracting \"'unparse.c'\" \(3090 characters\)
sed "s/^X//" >'unparse.c' <<'END_OF_FILE'
X#include "db.h"
X
X#include "externs.h"
X#include "config.h"
X#include "interface.h"
X
Xstatic const char *unparse_flags(dbref thing)
X{
X    static char buf[BUFFER_LEN];
X    char *p;
X    const char *type_codes = TYPE_CODES;
X
X    p = buf;
X    if(Typeof(thing) != TYPE_THING) *p++ = type_codes[Typeof(thing)];
X    if(db[thing].flags & ~TYPE_MASK) {
X	/* print flags */
X	if(db[thing].flags & WIZARD) *p++ = WIZARD_MARK;
X#ifdef ROBOT_MODE
X	if(db[thing].flags & ROBOT) *p++ = ROBOT_MARK;
X#endif ROBOT_MODE
X	if(db[thing].flags & STICKY) *p++ = STICKY_MARK;
X	if(db[thing].flags & DARK) *p++ = DARK_MARK;
X	if(db[thing].flags & LINK_OK) *p++ = LINK_MARK;
X	if(db[thing].flags & ABODE) *p++ = ABODE_MARK;
X	if(db[thing].flags & TEMPLE) *p++ = TEMPLE_MARK;
X#ifdef RESTRICTED_BUILDING
X	if(db[thing].flags & BUILDER) *p++ = BUILDER_MARK;
X#endif /* RESTRICTED_BUILDING */
X	if(db[thing].flags & HAVEN) *p++ = HAVEN_MARK;
X	if(db[thing].flags & UNWANTED) *p++ = UNWANTED_MARK;
X#ifdef GENDER
X	if(Genderof(thing) == GENDER_MALE) *p++ = MALE_MARK;
X	if(Genderof(thing) == GENDER_FEMALE) *p++ = FEMALE_MARK;
X	if(Genderof(thing) == GENDER_NEUTER) *p++ = NEUTER_MARK;
X#endif /* GENDER */
X    }
X    *p = '\0';
X    return buf;
X}
X
Xconst char *unparse_object(dbref player, dbref loc)
X{
X    static char buf[BUFFER_LEN];
X
X    switch(loc) {
X      case NOTHING:
X	return "*NOTHING*";
X      case HOME:
X	return "*HOME*";
X      default:
X	if(controls(player, loc) || can_link_to(player, NOTYPE, loc)
X	   || (db[loc].flags & UNWANTED)) {
X	    /* show everything */
X	    sprintf(buf, "%s(#%d%s)", db[loc].name, loc, unparse_flags(loc));
X	    return buf;
X	} else {
X	    /* show only the name */
X	    return db[loc].name;
X	}
X    }
X}
X
Xstatic char boolexp_buf[BUFFER_LEN];
Xstatic char *buftop;
X
Xstatic void unparse_boolexp1(dbref player,
X			     struct boolexp *b, boolexp_type outer_type)
X{
X    if(b == TRUE_BOOLEXP) {
X	strcpy(buftop, "*UNLOCKED*");
X	buftop += strlen(buftop);
X    } else {
X	switch(b->type) {
X	  case BOOLEXP_AND:
X	    if(outer_type == BOOLEXP_NOT) {
X		*buftop++ = '(';
X	    }
X	    unparse_boolexp1(player, b->sub1, b->type);
X	    *buftop++ = AND_TOKEN;
X	    unparse_boolexp1(player, b->sub2, b->type);
X	    if(outer_type == BOOLEXP_NOT) {
X		*buftop++ = ')';
X	    }
X	    break;
X	  case BOOLEXP_OR:
X	    if(outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) {
X		*buftop++ = '(';
X	    }
X	    unparse_boolexp1(player, b->sub1, b->type);
X	    *buftop++ = OR_TOKEN;
X	    unparse_boolexp1(player, b->sub2, b->type);
X	    if(outer_type == BOOLEXP_NOT || outer_type == BOOLEXP_AND) {
X		*buftop++ = ')';
X	    }
X	    break;
X	  case BOOLEXP_NOT:
X	    *buftop++ = '!';
X	    unparse_boolexp1(player, b->sub1, b->type);
X	    break;
X	  case BOOLEXP_CONST:
X	    strcpy(buftop, unparse_object(player, b->thing));
X	    buftop += strlen(buftop);
X	    break;
X	  default:
X	    abort();		/* bad type */
X	    break;
X	}
X    }
X}
X	    
Xconst char *unparse_boolexp(dbref player, struct boolexp *b)
X{
X    buftop = boolexp_buf;
X    unparse_boolexp1(player, b, BOOLEXP_CONST);	/* no outer type */
X    *buftop++ = '\0';
X
X    return boolexp_buf;
X}
X    
END_OF_FILE
if test 3090 -ne `wc -c <'unparse.c'`; then
    echo shar: \"'unparse.c'\" unpacked with wrong size!
fi
# end of 'unparse.c'
fi
if test -f 'utils.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'utils.c'\"
else
echo shar: Extracting \"'utils.c'\" \(756 characters\)
sed "s/^X//" >'utils.c' <<'END_OF_FILE'
X#include "copyright.h"
X
X#include "db.h"
X
X/* remove the first occurence of what in list headed by first */
Xdbref remove_first(dbref first, dbref what)
X{
X    dbref prev;
X
X    /* special case if it's the first one */
X    if(first == what) {
X	return db[first].next;
X    } else {
X	/* have to find it */
X	DOLIST(prev, first) {
X	    if(db[prev].next == what) {
X		db[prev].next = db[what].next;
X		return first;
X	    }
X	}
X	return first;
X    }
X}
X
Xint member(dbref thing, dbref list)
X{
X    DOLIST(list, list) {
X	if(list == thing) return 1;
X    }
X
X    return 0;
X}
X
Xdbref reverse(dbref list)
X{
X    dbref newlist;
X    dbref rest;
X
X    newlist = NOTHING;
X    while(list != NOTHING) {
X	rest = db[list].next;
X	PUSH(list, newlist);
X	list = rest;
X    }
X    return newlist;
X}
END_OF_FILE
if test 756 -ne `wc -c <'utils.c'`; then
    echo shar: \"'utils.c'\" unpacked with wrong size!
fi
# end of 'utils.c'
fi
echo shar: End of archive 10 \(of 10\).
cp /dev/null ark10isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 10 archives.
    echo ">>> now type 'sh joinspl.sh'"
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0