billr@saab.CNA.TEK.COM (Bill Randle) (07/14/90)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 91
Archive-name: nethack3p9/Part46
Supersedes: NetHack3: Volume 7, Issue 56-93
#! /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 46 (of 56)."
# Contents: Install.vms include/config.h include/monsym.h
# src/fountain.c src/mkmaze.c src/unixmain.c
# Wrapped by billr@saab on Wed Jul 11 17:12:03 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Install.vms' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'Install.vms'\"
else
echo shar: Extracting \"'Install.vms'\" \(10809 characters\)
sed "s/^X//" >'Install.vms' <<'END_OF_FILE'
X
X Instructions for Installing NetHack 3.0
X on a VMS system
X =======================================
X
X (Credit for an enhanced VMS NetHack 3.0 goes to the VMS team of
X Joshua Delahunty and Pat Rankin who built on the work of David
X Gentzel.)
X
X1. Building NetHack requires a C compiler (either VAX C or GNU C) and
X VMS version 4.6 or later (but see note #9). It has been tested on 5.3;
X as of this writing, 5.4 has not yet been released. For MicroVMS 4.6
X or 4.7, an extra edit is required in file vmsconf.h (see step #3).
X The new build procedure (vmsbuild.com) should not need to be
X modified; it now accepts an option for selecting VAXC vs GNUC, and it
X can detect different versions of VAXC to use appropriate CC command
X qualifiers. Versions of VAXC earlier than v2.3 will produce many
X warning messages (over 100 per source file; close to 10,000 total!),
X but NetHack has been verified to compile, link, and execute correctly
X when built with VAXC v2.2 using vmsbuild.com.
X
X2. Make sure all the NetHack files are in the appropriate directory
X structure. You should have a main directory with subdirectories
X [.vms], [.src], [.include], [.auxil], and [.others]; you may also
X have [.amiga] and [.mac], but they are not needed to build NetHack
X on VMS. If you do not follow this structure, the supplied procedures
X and instructions in this file will not function properly. The .c
X files in [.src] are files which are used by all versions of NetHack,
X regardless of machine (there are a few UNIX-specific files, but we can
X ignore them). The build & install command procedures (.com), the
X VMS-specific .c files, and one VMS-specific .h file belong in [.vms].
X All the .h files (except lev_lex.h) belong in [.include]. Other
X assorted files belong in [.auxil]. The only files in [.others] used
X by the VMS version of NetHack are random.c and possibly termcap.
X (The directory structure is also described in the file called Files.)
X
X3. Go to the [.include] subdirectory and edit vmsconf.h according to
X the comments. You may also want to edit config.h, but that's only
X necessary if you want or need to disable some of the game options.
X The distributed copy of config.h will work successfully on VMS;
X vmsconf.h has conditional code to deal with the UNIX-specific items.
X
X4. Go to the [.src] directory and look at the top of topten.c. You may
X want to change the definitions of PERSMAX and PERS_IS_UID here to get
X different behavior from the high score list.
X
X5. If you have lex or flex and yacc or bison, you may edit the procedure
X [.vms]spec_lev.com and execute it to process a couple of source files
X for NetHack's special level compiler. This step is optional; the
X distribution contains pre-processed versions of these files that can
X be used as is.
X $ @[.VMS]SPEC_LEV !{OPTIONAL}
X If you perform this step, do so prior to executing vmsbuild.com.
X
X6. To build NETHACK.EXE and a couple of its auxiliary programs, execute
X the following two DCL commands:
X $ SET DEFAULT [.SRC] !assuming you're currently in 'main'
X $ @[-.VMS]VMSBUILD !defaults to VAXC unless symbol 'CC' exists
X or $ @[-.VMS]VMSBUILD "GNUC"
X then go get a cup of coffee or take a nap. Using VAXC v3.1, the
X build procedure takes about 45-60 minutes on an unloaded VAXstation
X 3100-38 with local disk; it will take *much* longer on slower systems
X such as uVAX-II and 11/7xx. After completion, you should now have
X created the game executable, NETHACK.EXE, with a size of roughly 1300
X blocks (larger if the VAXCRTL object-library option of vmsbuild is used).
X
X7. Go back to the main directory. Edit [.vms]install.com to indicate
X where you want everything to be installed. Use the command
X $ @[.VMS]INSTALL
X to build some data files using the two auxiliary programs, and to
X create the target directory and copy all necessary files there.
X After it completes, the files [.src]*.obj, [.src]nethack.olb and
X [.src]*.exe can be deleted if you wish to recover their disk space.
X
XNotes:
X
X1. VMS NetHack uses the termcap routines borrowed from GNU Emacs. These
X have been supplied for those who do not already have GNU Emacs, but
X they are not properly a part of the NetHack distribution. Since
X these files (vmstermcap.c and vmstparam.c) bear the usual GNU license,
X any executable made with these files is also under the GNU license,
X which among other things means you must be prepared to distribute all
X the source that went into the executable if you distribute the
X executable. See the GNU license in the files for further details.
X
X2. termcap is a text file containing descriptions of terminal capabilities
X and the escape sequences that software must use to take advantage of
X them. If you do not already have a termcap file in use on your
X system there is a small one in file [.OTHERS]TERMCAP. It contains
X definitions for common Digital terminals, also suitable for most
X clones and emulators. NetHack uses the translation of the logical
X name TERMCAP to find the termcap file, so you need to use the DCL
X command DEFINE or ASSIGN to set it up. It uses the logical name
X NETHACK_TERM to get the name of the terminal (such as "vt100"). If
X that logical name is not defined, it tries EMACS_TERM. If that also
X is not defined, it uses the value generated by the C Run-Time library,
X which is normally of the form "vt100-80" or "vt200-132".
X
X3. There is code which attempts to make NetHack secure in case it is
X installed with privileges (to allow the playground to be protected against
X world write). THIS HAS NOT BEEN TESTED. Install NetHack with privileges
X at your own risk. If you do so, however, we would love to hear of your
X experiences, good or bad. The default setup uses world-writeable files,
X which is NOT secure and not advisable in any environment where there
X are untrustworthy users. If you allow users to run NetHack from
X captive accounts (VMS 5.1 or earlier) or from restricted accounts
X (5.2 and later), you must either make sure that they do not have TMPMBX
X privilege or else disable NetHack's ability to spawn an interactive
X subprocess. To disable subprocesses, disable the "!" (shell) command
X by commenting out the definition of SHELL in vmsconf.h prior to
X building the program. This necessity will be removed in a future
X release, where NetHack will check for captive accounts correctly.
X
X4. VMS NetHack uses SMG$READ_KEYSTROKE to read characters from the
X keyboard. This means that arrow keys work, but also means that using
X escape to abort commands doesn't. If you want to abort a command use
X two escapes or ^Z. Just about any non-arrow function key should also
X work as an abort. Note that under UNIX ^Z is the suspend command; a
X future release may re-utilize ^Z in some similar capacity on VMS.
X
X5. NetHack does not run in PASTHRU or PASSALL mode. This is to allow ^C
X interrupts. An unpleasant (albeit minor) side-effect of this is that
X some wizard commands don't work (^G, ^O, ^X). Another side-effect is
X that ^Y and ^C echo "<interrupt>" and "<cancel>" respectively. This
X will be fixed in a future release.
X
X6. To install an update of this version of NetHack after changing something
X you will have to go through almost the entire build process (unless you
X know for certain exactly what needs to be rebuilt). If you added,
X deleted, or reordered monsters or objects or changed the format of saved
X level files, you should also remove any saved games and bones levels.
X (Trying to use such files often produces amusing but useless confusions
X on the game's part.) If you just want to re-link the program, you
X can invoke vmsbuild.com with a parameter value of "LINK", as in
X $ @[-.vms]vmsbuild "LINK"
X If you need to link with the GNUC library, then you must have a DCL
X symbol 'CC' whose value begins with "G" (or "g"). This is necessary
X because the mechanism for specifying GNUC vs VAXC is not accessible
X when you specify "LINK" as the procedure parameter.
X
X7. In version 3.0 patchlevel 7, the format of the record (score) file
X was changed. If you want to use an old record file from an earlier
X version, manually edit it so that the killer (last item on each line)
X is preceded by "killed by", "killed by a", or "killed by an". If the
X death was by petrification, use "petrified by" instead. Do not
X change "starvation", "quit", "escaped", or "ascended". Record files
X retained from patchlevel 7 to patchlevel 8 do not need any fixups.
X
X8. NetHack optionally maintains a logfile which receives one line appended
X to it whenever a game ends. This can be disabled entirely by adding
X an "#undef LOGFILE" directive to vmsconf.h prior to building the
X program, or it can be disabled later by removing the file "LOGFILE."
X from the playground directory. If not disabled prior to compilation,
X the logfile can be reinitialized by simply creating an empty LOGFILE
X in the playground, but make sure that it's protected properly or new
X entries will not be appended.
X
X9. Support for VMS versions earlier than V4.6 is now included. The need
X for this support is detected automatically by vmsbuild.com, and also
X automatically used when needed, but it has not received as thorough a
X testing as the rest of NetHack. The reason that special support is
X needed is that the C Run-Time Library (VAXCRTL) underwent a major
X revision for VMS V4.6. Several routines which NetHack utilizes were
X not available prior to that upgrade.
X
X10. The new release of vmsbuild.com collects most of the object files
X (xxx.OBJ) into an object library (NETHACK.OLB) as it compiles the
X source files. This should prevent the EXQUOTA problem that some
X sites have reported when linking nethack.exe, by limiting the number
X of files which the linker accesses at one time. Note that if you
X compile any source files manually, you'll need to replace those
X modules in the object library prior to linking the program:
X $ cc/include=[-.include] [-.vms]vmstty !for example
X $ libr/obj nethack vmstty !replace VMSTTY
X $ @[-.vms]vmsbuild LINK !re-link NETHACK.EXE
X If you forget to replace the library entry, your newly compiled code
X will not be included in the new executable image.
X
X11. If necessary, send problem reports via email to
X "nethack-bugs@linc.cis.upenn.edu" (Internet address 130.91.6.8).
X
X27-MAY-1990
END_OF_FILE
if test 10809 -ne `wc -c <'Install.vms'`; then
echo shar: \"'Install.vms'\" unpacked with wrong size!
fi
# end of 'Install.vms'
fi
if test -f 'include/config.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'include/config.h'\"
else
echo shar: Extracting \"'include/config.h'\" \(10686 characters\)
sed "s/^X//" >'include/config.h' <<'END_OF_FILE'
X/* SCCS Id: @(#)config.h 3.0 89/06/23
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#ifndef CONFIG_H /* make sure the compiler does not see the typedefs twice */
X#define CONFIG_H
X
X
X/*
X * Section 1: OS selection.
X * Select the version of the OS you are using.
X * For "UNIX" select either SYSV or BSD in unixconf.h.
X * A "VMS" option is not needed since the VMS C-compiler
X * provides it (no need to change sec#1, vmsconf.h handles it).
X */
X
X#define UNIX /* delete if no fork(), exec() available */
X
X#ifdef __MSDOS__ /* Turbo C auto-defines __MSDOS__, MSC defines MSDOS */
X#define MSDOS /* define for MS-DOS (in case compiler doesn't) */
X#else
X/* #define MSDOS /* define for MS-DOS and most other micros */
X /* DO NOT define for AMIGA - MSDOS will be
X * automatically defined at the right place. */
X# ifdef AZTEC_C /* Manx auto-defines this */
X# ifdef MCH_AMIGA /* Manx auto-defines this for AMIGA */
X# ifndef AMIGA
X#define AMIGA /* define for Commodore-Amiga */
X# endif /* (Lattice auto-defines AMIGA) */
X/* #define AZTEC_36 /* define for version 3.6 of manx */
X#define AZTEC_50 /* define for version 5.0 of manx */
X# endif
X# endif
X#ifdef LATTICE
X# define NEARDATA __near /* put some data close */
X# define NO_SCAN_BRACK /* scanf doesn't handle [] (this define available
X * for any system with this problem) */
X#else
X# define NEARDATA
X#endif
X/* #define TOS /* define for Atari 1040ST */
X
X/* #define STUPID /* avoid some complicated expressions if
X your C compiler chokes on them */
X/* #define STUPID_CPP /* use many small functions instead of macros to
X avoid overloading limited preprocessors */
X/* #define TERMINFO /* uses terminfo rather than termcap */
X /* should be defined for HPUX and most, but not all,
X SYSV */
X /* in particular, it should NOT be defined for the
X * UNIXPC unless you remove the use of the shared
X * library in the makefile */
X/* #define MINIMAL_TERM /* if a terminal handles highlighting or tabs poorly,
X try this define, used in pager.c and termcap.c */
X/* #define MACOS /* define for Apple Macintosh */
X#endif
X
X#ifdef AMIGA
X#define NEED_VARARGS
X# ifdef AZTEC_36
X# define KR1ED /* Aztec 3.6 needs extra help for defined() */
X# endif
X# ifdef AZTEC_50
X# define USE_OLDARGS /* Aztec 5.0 prototypes aren't quite right */
X# endif
X#endif
X
X#ifdef MACOS
X#define THINKC4 /* for the Think C 4.0 compiler */
X/* #define LSC /* for the Lightspeed C 3.01p4 compiler */
X/* #define AZTEC /* for the Manx Aztec C 3.6c compiler */
X#define SMALLDATA /* for Mac compilers with 32K global data limit */
X#define CUSTOM_IO /* uncomment only while compiling Nethack */
X/* #define MAKEDEFS_C /* uncomment only while compiling makedefs */
X# ifndef MAKEDEFS_C
X# ifndef NEED_VARARGS
X#define NEED_VARARGS /* if you're using precompiled headers */
X# endif
X# endif
X# ifdef LSC
X#define KR1ED /* for compilers which can't handle defined() */
X# endif
X# ifdef AZTEC
X#define KR1ED /* Lightspeed C & Aztec can't handle defined() yet */
X# endif
X#endif /* MACOS */
X
X#ifdef VMS /* really old compilers need special handling, detected here */
X# ifdef VAXC /* must use CC/DEFINE=ANCIENT_VAXC for vaxc v2.2 or older */
X# ifdef ANCIENT_VAXC /* vaxc v2.2 and earlier [lots of warnings to come] */
X# define KR1ED /* simulate defined() */
X# define USE_VARARGS
X# else /* vaxc v2.3,2.4,or 3.x */
X# if defined(PROTOTYPING_ON) /* this breaks 2.2 (*forces* use of ANCIENT)*/
X# define __STDC__ 0 /* vaxc is not yet ANSI compliant, but close enough */
X# define signed /* well, almost close enough */
X#include <stddef.h>
X# endif
X# define USE_STDARG
X# endif
X# endif /*VAXC*/
X# ifdef VERYOLD_VMS /* v4.5 or earlier */
X# define USE_OLDARGS /* <varargs.h> is there, vprintf & vsprintf aren't */
X# ifdef USE_VARARGS
X# undef USE_VARARGS
X# endif
X# ifdef USE_STDARG
X# undef USE_STDARG
X# endif
X# endif
X#endif /*VMS*/
X
X
X#ifdef KR1ED /* For compilers which cannot handle defined() */
X#define defined(x) (-x-1 != -1)
X/* Because:
X * #define FOO => FOO={} => defined( ) => (-1 != - - 1) => 1
X * #define FOO 1 or on command-line -DFOO
X * => defined(1) => (-1 != - 1 - 1) => 1
X * if FOO isn't defined, FOO=0. But some compilers default to 0 instead of 1
X * for -DFOO, oh well.
X * => defined(0) => (-1 != - 0 - 1) => 0
X *
X * But:
X * defined("") => (-1 != - "" - 1)
X * [which is an unavoidable catastrophe.]
X */
X#endif
X
X
X
X/*
X * Section 2: Some global parameters and filenames.
X * Commenting out WIZARD, LOGFILE, or NEWS removes that feature
X * from the game; otherwise set the appropriate wizard name.
X * LOGFILE and NEWS refer to files in the playground.
X */
X
X#ifndef WIZARD /* allow for compile-time or Makefile changes */
X# ifndef KR1ED
X#define WIZARD "izchak" /* the person allowed to use the -D option */
X# else
X#define WIZARD
X#define WIZARD_NAME "izchak"
X# endif
X#endif
X
X#define LOGFILE "logfile" /* larger file for debugging purposes */
X#define NEWS "news" /* the file containing the latest hack news */
X
X/*
X * If COMPRESS is defined, it should contain the full path name of your
X * 'compress' program. Defining ZEROCOMP causes NetHack to do simpler
X * zero-run compression internally. Both COMPRESS and ZEROCOMP create
X * smaller bones/level/save files, but require additional code and time.
X */
X
X#ifndef MACOS
X#define COMPRESS "/usr/local/compress" /* path name for 'compress' */
X# ifndef COMPRESS
X#define ZEROCOMP /* Use only if COMPRESS is not used -- Olaf Seibert */
X# endif
X#endif
X
X#ifndef MACOS
X#define CHDIR /* delete if no chdir() available */
X#endif
X
X#ifdef CHDIR
X/*
X * If you define HACKDIR, then this will be the default playground;
X * otherwise it will be the current directory.
X */
X#define HACKDIR "/usr/games/lib/nethackdir" /* nethack directory */
X
X/*
X * Some system administrators are stupid enough to make Hack suid root
X * or suid daemon, where daemon has other powers besides that of reading or
X * writing Hack files. In such cases one should be careful with chdir's
X * since the user might create files in a directory of his choice.
X * Of course SECURE is meaningful only if HACKDIR is defined.
X */
X/* #define SECURE /* do setuid(getuid()) after chdir() */
X
X/*
X * If it is desirable to limit the number of people that can play Hack
X * simultaneously, define HACKDIR, SECURE and MAX_NR_OF_PLAYERS.
X * #define MAX_NR_OF_PLAYERS 6
X */
X#endif /* CHDIR /**/
X
X
X
X/*
X * Section 3: Definitions that may vary with system type.
X * For example, both schar and uchar should be short ints on
X * the AT&T 3B2/3B5/etc. family.
X */
X
X/*
X * Uncomment the following line if your compiler doesn't understand the
X * 'void' type (and thus would give all sorts of compile errors without
X * this definition).
X */
X/* #define void int /* define if no "void" data type. */
X
X#include "tradstdc.h"
X
X/*
X * type schar: small signed integers (8 bits suffice) (eg. TOS)
X *
X * typedef char schar;
X *
X * will do when you have signed characters; otherwise use
X *
X * typedef short int schar;
X */
X#ifdef AZTEC
X#define schar char
X#else
Xtypedef signed char schar;
X#endif
X
X/*
X * type uchar: small unsigned integers (8 bits suffice - but 7 bits do not)
X *
X * typedef unsigned char uchar;
X *
X * will be satisfactory if you have an "unsigned char" type;
X * otherwise use
X *
X * typedef unsigned short int uchar;
X */
Xtypedef unsigned char uchar;
X
X/*
X * Various structures have the option of using bitfields to save space.
X * If your C compiler handles bitfields well (e.g., it can initialize structs
X * containing bitfields), you can define BITFIELDS. Otherwise, the game will
X * allocate a separate character for each bitfield. (The bitfields used never
X * have more than 7 bits, and most are only 1 bit.)
X */
X#define BITFIELDS /* Good bitfield handling */
X
X
X
X/*
X * Section 4: THE FUN STUFF!!!
X *
X * Conditional compilation of special options are controlled here.
X * If you define the following flags, you will add not only to the
X * complexity of the game but also to the size of the load module.
X */
X
X/* game features */
X#define POLYSELF /* Polymorph self code by Ken Arromdee */
X#define THEOLOGY /* Smarter gods - The Unknown Hacker */
X#define SOUNDS /* Add more life to the dungeon */
X#define KICK /* Allow kicking things besides doors -Izchak Miller */
X/* dungeon features */
X#define THRONES /* Thrones and Courts by M. Stephenson */
X#define FOUNTAINS /* Fountain code by SRT (+ GAN + EB) */
X#define SINKS /* Kitchen sinks - Janet Walz */
X#define ALTARS /* Sacrifice sites - Jean-Christophe Collet */
X/* dungeon levels */
X#define WALLIFIED_MAZE /* Fancy mazes - Jean-Christophe Collet */
X#define REINCARNATION /* Rogue-like levels */
X#define STRONGHOLD /* Challenging special levels - Jean-Christophe Collet*/
X/* monsters & objects */
X#define ORACLE /* Include another source of information */
X#define MEDUSA /* Mirrors and the Medusa by Richard P. Hughey */
X#define KOPS /* Keystone Kops by Scott R. Turner */
X#define ARMY /* Soldiers, barracks by Steve Creps */
X#define WORM /* Long worms */
X#define GOLEMS /* Golems, by KAA */
X#define INFERNO /* Demons & Demonlords */
X#ifdef INFERNO
X#define SEDUCE /* Succubi/incubi additions, by KAA, suggested by IM */
X#endif
X#define TOLKIEN /* More varieties of objects and monsters */
X#define PROBING /* Wand of probing code by Gil Neiger */
X#define WALKIES /* Leash code by M. Stephenson */
X#define SHIRT /* Hawaiian shirt code by Steve Linhart */
X#define MUSIC /* Musical instruments - Jean-Christophe Collet */
X#define TUTTI_FRUTTI /* Fruits as in Rogue, but which work... -KAA */
X#define SPELLS /* Spell casting by M. Stephenson */
X#define NAMED_ITEMS /* Special named items handling */
X/* difficulty */
X#define ELBERETH /* Allow for disabling the E word - Mike 3point */
X#define EXPLORE_MODE /* Allow non-scoring play with additional powers */
X#define HARD /* Enhanced wizard code by M. Stephenson */
X/* I/O */
X#define REDO /* support for redoing last command - DGK */
X#define COM_COMPL /* Command line completion by John S. Bien */
X#ifndef AMIGA
X#define CLIPPING /* allow smaller screens -- ERS */
X#endif
X
X#ifdef REDO
X#define DOAGAIN '\001' /* The "redo" key used in tty.c and cmd.c */
X#endif
X
X#define EXP_ON_BOTL /* Show experience on bottom line */
X/* #define SCORE_ON_BOTL /* added by Gary Erickson (erickson@ucivax) */
X
X
X
X#include "global.h" /* Define everything else according to choices above */
X
X#endif /* CONFIG_H /**/
END_OF_FILE
if test 10686 -ne `wc -c <'include/config.h'`; then
echo shar: \"'include/config.h'\" unpacked with wrong size!
fi
# end of 'include/config.h'
fi
if test -f 'include/monsym.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'include/monsym.h'\"
else
echo shar: Extracting \"'include/monsym.h'\" \(1983 characters\)
sed "s/^X//" >'include/monsym.h' <<'END_OF_FILE'
X/* SCCS Id: @(#)monsym.h 3.0 89/11/08
X/* Monster symbols and creation information rev 1.0 */
X/* NetHack may be freely redistributed. See license for details. */
X
X#ifndef MONSYM_H
X#define MONSYM_H
X
X#define S_ANT 'a'
X#define S_BLOB 'b'
X#define S_COCKATRICE 'c'
X#define S_DOG 'd'
X#define S_EYE 'e'
X#define S_FELINE 'f'
X#define S_GREMLIN 'g'
X#define S_HUMANOID 'h'
X#define S_IMP 'i'
X#define S_JELLY 'j'
X#define S_KOBOLD 'k'
X#define S_LEPRECHAUN 'l'
X#define S_MIMIC 'm'
X#define S_NYMPH 'n'
X#define S_ORC 'o'
X#define S_PIERCER 'p'
X#define S_QUADRUPED 'q'
X#define S_RODENT 'r'
X#define S_SPIDER 's'
X#define S_TRAPPER 't'
X#define S_UNICORN 'u'
X#define S_VORTEX 'v'
X#define S_WORM 'w'
X#define S_XAN 'x'
X#define S_YLIGHT 'y'
X#define S_ZRUTY 'z'
X#define S_APE 'A'
X#define S_BAT 'B'
X#define S_CENTAUR 'C'
X#define S_DRAGON 'D'
X#define S_ELEMENTAL 'E'
X#define S_FUNGUS 'F'
X#define S_GNOME 'G'
X#define S_GIANT 'H'
X#define S_STALKER 'I'
X#define S_JABBERWOCK 'J'
X#define S_KOP 'K'
X#define S_LICH 'L'
X#define S_MUMMY 'M'
X#define S_NAGA 'N'
X#define S_OGRE 'O'
X#define S_PUDDING 'P'
X#define S_QUANTMECH 'Q'
X#define S_RUSTMONST 'R'
X#define S_SNAKE 'S'
X#define S_TROLL 'T'
X#define S_UMBER 'U'
X#define S_VAMPIRE 'V'
X#define S_WRAITH 'W'
X#define S_XORN 'X'
X#define S_YETI 'Y'
X#define S_ZOMBIE 'Z'
X#define S_HUMAN '@'
X#define S_GHOST ' '
X#define S_GOLEM '\''
X#define S_DEMON '&'
X#define S_EEL ';'
X#define S_LIZARD ':'
X
X#define S_WORM_TAIL '~'
X#define S_MIMIC_DEF ']'
X
X#define G_UNIQ 0x800 /* generated only once */
X#define G_HELL 0x400 /* generated only in "hell" */
X#define G_NOGEN 0x200 /* generated only specially */
X#define G_NOCORPSE 0x100 /* no corpse left ever */
X#define G_SGROUP 0x080 /* appear in small groups normally */
X#define G_LGROUP 0x040 /* appear in large groups normally */
X#define G_GENO 0x020 /* can be genocided */
X#define G_GENOD 0x010 /* have been genocided */
X#define G_FREQ 0x007 /* creation frequency mask */
X
X#endif /* MONSYM_H /* */
END_OF_FILE
if test 1983 -ne `wc -c <'include/monsym.h'`; then
echo shar: \"'include/monsym.h'\" unpacked with wrong size!
fi
# end of 'include/monsym.h'
fi
if test -f 'src/fountain.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/fountain.c'\"
else
echo shar: Extracting \"'src/fountain.c'\" \(10647 characters\)
sed "s/^X//" >'src/fountain.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)fountain.c 3.0 88/12/22
X/* Code for drinking from fountains. */
X/* Scott R. Turner, srt@ucla, 10/27/86 */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
X#ifdef FOUNTAINS
Xstatic void NDECL(dowatersnakes);
Xstatic void NDECL(dowaterdemon);
Xstatic void NDECL(dowaternymph);
Xstatic void FDECL(dogushforth,(int));
Xstatic void NDECL(dofindgem);
X
Xstatic
Xvoid
Xdowatersnakes() /* Fountain of snakes! */ {
X register int num = rnd(6);
X if (!(mons[PM_WATER_MOCCASIN].geno & G_GENOD)) {
X if (!Blind)
X pline("An endless stream of %s pours forth!",
X Hallucination ? makeplural(rndmonnam())
X : "snakes");
X else
X You("hear something hissing!");
X while(num-- > 0) (void) makemon(&mons[PM_WATER_MOCCASIN],u.ux,u.uy);
X } else
X pline("The fountain bubbles furiously for a moment, then calms.");
X}
X
Xstatic
Xvoid
Xdowaterdemon() /* Water demon */ {
Xregister struct monst *mtmp;
X
X if((mtmp = makemon(&mons[PM_WATER_DEMON],u.ux,u.uy))) {
X if (!Blind)
X You("have unleashed %s!", defmonnam(mtmp));
X else
X You("feel the presence of evil.");
X
X /* Give those on low levels a (slightly) better chance of survival */
X if ( rnd(100) > (80 + dlevel)) {
X pline("Grateful for %s release, %s grants you a wish!",
X Blind ? "its" : "his", Blind ? "it" : "he" );
X makewish();
X mongone(mtmp);
X }
X }
X}
X
Xstatic
Xvoid
Xdowaternymph() /* Water Nymph */ {
X register struct monst *mtmp;
X if((mtmp = makemon(&mons[PM_WATER_NYMPH],u.ux,u.uy))) {
X if (!Blind)
X You("have attracted %s!", defmonnam(mtmp));
X else
X You("hear a seductive voice.");
X mtmp->msleep = 0;
X } else
X if (!Blind)
X pline("A large bubble rises to the surface and pops.");
X else
X You("hear a loud pop.");
X}
X
X
Xstatic
Xvoid
Xdogushforth(drinking) /* Gushing forth in this room */
Xint drinking;
X{
Xregister int num = rnd(10);
Xregister xchar mx,my;
Xregister int tryct = 0;
Xregister int uroom = inroom(u.ux, u.uy);
Xregister struct mkroom *croom = &rooms[uroom];
Xregister int madepool = 0;
X
X if(croom->hx < 0 || has_upstairs(croom) ||
X has_dnstairs(croom)) {
X if (drinking) Your("thirst is quenched.");
X else pline("Water sprays all over you.");
X return;
X }
X while(num--) {
X do {
X if(++tryct > 200) {
X if(madepool)
X pline("Water gushes forth from the overflowing fountain!");
X else if (drinking) Your("thirst is quenched.");
X else pline("Water sprays all over you.");
X return;
X }
X mx = somex(croom);
X my = somey(croom);
X } while(nexttodoor(mx,my) || !((mx+my)%2) ||
X (mx == u.ux && my == u.uy) ||
X (IS_POOL(levl[mx][my].typ)));
X
X /* Put a pool at mx, my */
X
X levl[mx][my].typ = POOL;
X levl[mx][my].doormask = 0;
X mnewsym(mx,my);
X if (cansee(mx, my))
X prl(mx, my);
X madepool = 1;
X }
X
X pline("Water gushes forth from the overflowing fountain!");
X}
X
Xstatic
Xvoid
Xdofindgem() /* Find a gem in the sparkling waters. */ {
X
X if (!Blind) You("spot a gem in the sparkling waters!");
X (void) mksobj_at(rnd_class(DILITHIUM_CRYSTAL, LUCKSTONE-1), u.ux, u.uy);
X levl[u.ux][u.uy].looted = T_LOOTED;
X}
X
Xvoid
Xdryup(){
X if (!rn2(3) && IS_FOUNTAIN(levl[u.ux][u.uy].typ)) {
X if (!Blind) pline("The fountain dries up!");
X levl[u.ux][u.uy].typ = ROOM;
X levl[u.ux][u.uy].looted = 0;
X if(Invisible) newsym(u.ux, u.uy);
X fountsound--;
X }
X}
X
Xvoid
Xdrinkfountain() {
X
X /* What happens when you drink from a fountain? */
X register int fate = rnd(30);
X
X if(Levitation) {
X You("are floating high above the fountain.");
X return;
X }
X else if (fate < 10) {
X pline("The cool draught refreshes you.");
X u.uhunger += rnd(10); /* don't choke on water */
X } else {
X switch (fate) {
X
X case 19: /* Self-knowledge */
X
X You("feel self-knowledgeable...");
X more();
X enlightenment();
X pline("The feeling subsides.");
X break;
X
X case 20: /* Foul water */
X
X pline("The water is foul! You gag and vomit.");
X morehungry(rnd(20)+10);
X vomit();
X break;
X
X case 21: /* Poisonous */
X
X pline("The water is contaminated!");
X if (Poison_resistance) {
X#ifdef TUTTI_FRUTTI
X pline("Perhaps it is runoff from the nearby %s farm.", pl_fruit);
X#else
X pline("Perhaps it is runoff from the nearby orange farm.");
X#endif
X losehp(rnd(4),"unrefrigerated sip of juice",
X KILLED_BY_AN);
X break;
X }
X losestr(rn1(4,3));
X losehp(rnd(10),"contaminated water", KILLED_BY);
X break;
X
X case 22: /* Fountain of snakes! */
X
X dowatersnakes();
X break;
X
X case 23: /* Water demon */
X dowaterdemon();
X break;
X
X case 24: /* Curse an item... */ {
X register struct obj *obj;
X
X pline("This water's no good!");
X morehungry(rnd(20)+10);
X for(obj = invent; obj ; obj = obj->nobj)
X if (!rn2(5)) curse(obj);
X break;
X }
X
X case 25: /* See invisible */
X
X You("see an image of someone stalking you.");
X pline("But it disappears.");
X HSee_invisible |= INTRINSIC;
X break;
X
X case 26: /* See Monsters */
X
X (void) monster_detect((struct obj *)0);
X break;
X
X case 27: /* Find a gem in the sparkling waters. */
X
X if (!levl[u.ux][u.uy].looted) {
X dofindgem();
X break;
X }
X
X case 28: /* Water Nymph */
X
X dowaternymph();
X break;
X
X case 29: /* Scare */ {
X register struct monst *mtmp;
X
X pline("This water gives you bad breath!");
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X mtmp->mflee = 1;
X }
X break;
X
X case 30: /* Gushing forth in this room */
X
X dogushforth(TRUE);
X break;
X
X default:
X
X pline("This tepid water is tasteless.");
X break;
X }
X }
X dryup();
X}
X
Xvoid
Xdipfountain(obj)
Xregister struct obj *obj;
X{
X if (Levitation) {
X You("are floating high above the fountain.");
X return;
X }
X
X if (obj->otyp == LONG_SWORD && u.ulevel >= 5 && !rn2(6)
X#ifdef NAMED_ITEMS
X && !is_artifact(obj) && !exist_artifact(obj, "Excalibur")
X#else
X && !strcmp(ONAME(obj), "Excalibur")
X#endif
X ) {
X /* The lady of the lake acts! - Eric Backus */
X /* Be *REAL* nice */
X pline("A murky hand from the depths reaches up to bless the sword.");
X pline("As the hand retreats, the fountain disappears!");
X
X#ifndef NAMED_ITEMS
X if(obj->spe < 5) obj->spe = 5;
X#else
X /* otherwise +rnd(10) / +5 "Super"sword */
X obj = oname(obj, "Excalibur", 1);
X#endif
X bless(obj);
X obj->rustfree = 1;
X levl[u.ux][u.uy].typ = ROOM;
X levl[u.ux][u.uy].looted = 0;
X if(Invisible) newsym(u.ux, u.uy);
X fountsound--;
X return;
X } else (void) get_wet(obj);
X
X switch (rnd(30)) {
X case 16: /* Curse the item */
X curse(obj);
X break;
X case 17:
X case 18:
X case 19:
X case 20: /* Uncurse the item */
X if(obj->cursed) {
X if (!Blind)
X pline("The water glows for a moment.");
X obj->cursed = 0;
X } else {
X pline("A feeling of loss comes over you.");
X }
X break;
X case 21: /* Water Demon */
X dowaterdemon();
X break;
X case 22: /* Water Nymph */
X dowaternymph();
X break;
X case 23: /* an Endless Stream of Snakes */
X dowatersnakes();
X break;
X case 24: /* Find a gem */
X dofindgem();
X break;
X case 25: /* Water gushes forth */
X dogushforth(FALSE);
X break;
X case 26: /* Strange feeling */
X pline("A strange tingling runs up your %s.",
X body_part(ARM));
X break;
X case 27: /* Strange feeling */
X You("feel a sudden chill.");
X break;
X case 28: /* Strange feeling */
X pline("An urge to take a bath overwhelms you.");
X if (u.ugold > 10) {
X u.ugold -= somegold() / 10;
X You("lost some of your gold in the fountain!");
X levl[u.ux][u.uy].looted = 0;
X }
X break;
X case 29: /* You see coins */
X
X /* We make fountains have more coins the closer you are to the
X * surface. After all, there will have been more people going
X * by. Just like a shopping mall! Chris Woodbury */
X
X mkgold((long)(rnd((MAXLEVEL-dlevel)*2)+5), u.ux, u.uy);
X if (!Blind)
X pline("Far below you, you see coins glistening in the water.");
X break;
X }
X dryup();
X return;
X}
X#endif
X
X#ifdef SINKS
Xvoid
Xdrinksink()
X{
X if (Levitation) {
X You("are floating high above the sink.");
X return;
X }
X switch(rn2(20)) {
X static struct obj NEARDATA *otmp;
X case 0: You("take a sip of very cold water.");
X break;
X case 1: You("take a sip of very warm water.");
X break;
X case 2: You("take a sip of scalding hot water.");
X if (Fire_resistance)
X pline("It seems quite tasty.");
X else losehp(rnd(6), "sipping boiling water", KILLED_BY);
X break;
X case 3: if (mons[PM_SEWER_RAT].geno & G_GENOD)
X pline("The sink seems quite dirty.");
X else {
X static struct monst NEARDATA *mtmp;
X
X mtmp = makemon(&mons[PM_SEWER_RAT], u.ux, u.uy);
X pline("Eek! There's %s in the sink!",
X Blind ? "something squirmy" :
X defmonnam(mtmp));
X }
X break;
X case 4: do {
X otmp = mkobj(POTION_SYM,FALSE);
X } while(otmp->otyp == POT_WATER);
X otmp->cursed = otmp->blessed = 0;
X if (Blind)
X pline("The sink emits some odd liquid.");
X else
X pline("The sink emits a stream of %s water.",
X Hallucination ? hcolor() :
X objects[otmp->otyp].oc_descr);
X otmp->dknown = !(Blind || Hallucination);
X otmp->quan++; /* Avoid panic upon useup() */
X otmp->corpsenm = 1; /* kludge for docall() */
X (void) dopotion(otmp);
X obfree(otmp, (struct obj *)0);
X break;
X case 5: if (!levl[u.ux][u.uy].looted) {
X You("find a ring in the sink!");
X (void) mkobj_at(RING_SYM, u.ux, u.uy, TRUE);
X levl[u.ux][u.uy].looted = T_LOOTED;
X } else pline("Some dirty water backs up in the drain.");
X break;
X case 6: pline("The pipes break! Water spurts out!");
X sinksound--;
X levl[u.ux][u.uy].doormask = 0;
X#ifdef FOUNTAINS
X levl[u.ux][u.uy].typ = FOUNTAIN;
X fountsound++;
X#else
X levl[u.ux][u.uy].typ = ROOM;
X#endif
X if (Invisible) newsym(u.ux,u.uy);
X break;
X case 7: pline("The water moves as though of its own will!");
X if (!makemon(&mons[PM_WATER_ELEMENTAL], u.ux, u.uy))
X pline("But it quiets down.");
X break;
X case 8: pline("Yuk, this water tastes awful.");
X more_experienced(1,0);
X newexplevel();
X break;
X case 9: pline("Gaggg... this tastes like sewage! You vomit.");
X morehungry(rnd(30-ACURR(A_CON))+10);
X vomit();
X break;
X#ifdef POLYSELF
X case 10: pline("This water contains toxic wastes!");
X You("undergo a freakish metamorphosis!");
X polyself();
X break;
X#endif
X /* more odd messages --JJB */
X case 11: You("hear clanking from the pipes....");
X break;
X case 12: You("hear snatches of song from among the sewers...");
X break;
X case 19: if (Hallucination) {
X pline("A murky hand reaches up out of the drain... --oops--");
X break;
X }
X default: You("take a sip of %s water.",
X rn2(3) ? (rn2(2) ? "cold" : "warm") : "hot");
X }
X}
X#endif /* SINKS /**/
END_OF_FILE
if test 10647 -ne `wc -c <'src/fountain.c'`; then
echo shar: \"'src/fountain.c'\" unpacked with wrong size!
fi
# end of 'src/fountain.c'
fi
if test -f 'src/mkmaze.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/mkmaze.c'\"
else
echo shar: Extracting \"'src/mkmaze.c'\" \(10520 characters\)
sed "s/^X//" >'src/mkmaze.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)mkmaze.c 3.0 88/10/25
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
Xextern int x_maze_max, y_maze_max;
X
X#if defined(WALLIFIED_MAZE) || defined(STRONGHOLD)
Xstatic int FDECL(iswall,(int,int));
Xstatic boolean FDECL(okay,(int,int,int));
Xstatic void FDECL(maze0xy,(coord *));
X
Xstatic int
Xiswall(x,y)
Xint x,y;
X{
X# ifndef WALLIFIED_MAZE
X if (x<0 || y<0 || x>COLNO-1 || y>ROWNO-1)
X# else
X if (x<0 || y<0 || x>COLNO || y>ROWNO)
X# endif
X return 0;
X return (IS_WALL(levl[x][y].typ) || IS_DOOR(levl[x][y].typ)
X || levl[x][y].typ == SDOOR);
X}
X
Xvoid
Xwallification(x1, y1, x2, y2, see)
Xint x1, y1, x2, y2;
Xboolean see;
X{
X uchar type;
X short x,y;
X register struct rm *room;
X
X if (x1 < 0) x1 = 0;
X if (x2 < x1) x2 = x1;
X if (x2 > COLNO-1) x2 = COLNO-1;
X if (x1 > x2) x1 = x2;
X if (y1 < 0) y1 = 0;
X if (y2 < y1) y2 = y1;
X if (y2 > COLNO-1) y2 = ROWNO-1;
X if (y1 > y2) y1 = y2;
X for(x = x1; x <= x2; x++)
X for(y = y1; y <= y2; y++) {
X room = &levl[x][y];
X type = room->typ;
X if (iswall(x,y)) {
X if (IS_DOOR(type))
X continue;
X else
X if (iswall(x,y-1))
X if (iswall(x,y+1))
X if (iswall(x-1,y))
X if (iswall(x+1,y))
X room->typ = CROSSWALL;
X else
X room->typ = TLWALL;
X else
X if (iswall(x+1,y))
X room->typ = TRWALL;
X else
X room->typ = VWALL;
X else
X if (iswall(x-1,y))
X if (iswall(x+1,y))
X room->typ = TUWALL;
X else
X room->typ = BRCORNER;
X else
X if (iswall(x+1,y))
X room->typ = BLCORNER;
X else
X room->typ = VWALL;
X else
X if (iswall(x,y+1))
X if (iswall(x-1,y))
X if (iswall(x+1,y))
X room->typ = TDWALL;
X else
X room->typ = TRCORNER;
X else
X if (iswall(x+1,y))
X room->typ = TLCORNER;
X else
X room->typ = VWALL;
X else
X room->typ = HWALL;
X if (type == SDOOR) room->typ = type;
X }
X room->scrsym = news0(x,y);
X if (see) room->seen = 0;
X }
X}
X#endif /* WALLIFIED_MAZE /**/
X
Xstatic boolean
Xokay(x,y,dir)
Xint x,y;
Xregister int dir;
X{
X move(&x,&y,dir);
X move(&x,&y,dir);
X if(x<3 || y<3 || x>x_maze_max || y>y_maze_max || levl[x][y].typ != 0)
X return(FALSE);
X return(TRUE);
X}
X
Xstatic void
Xmaze0xy(cc) /* find random starting point for maze generation */
X coord *cc;
X{
X cc->x = 3 + 2*rn2((x_maze_max>>1) - 1);
X cc->y = 3 + 2*rn2((y_maze_max>>1) - 1);
X return;
X}
X
X/* NCR towers define "tower". Blecccch. */
X#ifdef tower
X# undef tower
X#endif
X
Xstatic const uchar NEARDATA tower[] = {
X MOAT, MOAT, MOAT, MOAT, MOAT, MOAT, MOAT,
X MOAT, MOAT, TLCORNER, HWALL, TRCORNER, MOAT, MOAT,
X MOAT, TLCORNER, BRCORNER, ROOM, BLCORNER, TRCORNER, MOAT,
X MOAT, VWALL, ROOM, ROOM, ROOM, VWALL, MOAT,
X MOAT, BLCORNER, TRCORNER, ROOM, TLCORNER, BRCORNER, MOAT,
X MOAT, MOAT, BLCORNER, HWALL, BRCORNER, MOAT, MOAT,
X MOAT, MOAT, MOAT, MOAT, MOAT, MOAT, MOAT,
X};
X
Xvoid
Xmakemaz()
X{
X int x,y;
X register int zx,zy;
X coord mm;
X int i;
X
X is_maze_lev = TRUE;
X#ifdef STRONGHOLD
X xdnladder = ydnladder = xupladder = yupladder = 0;
X if (dlevel == stronghold_level) {
X if (load_special("castle")) {
X xupstair = yupstair = 3;
X levl[xupstair][yupstair].scrsym = UP_SYM;
X levl[xupstair][yupstair].typ = STAIRS;
X return;
X }
X impossible("Cannot build the STRONGHOLD!");
X }
X if (dlevel == tower_level) {
X if (load_special("tower1")) {
X xupstair = yupstair = 3;
X levl[xupstair][yupstair].scrsym = UP_SYM;
X levl[xupstair][yupstair].typ = STAIRS;
X return;
X }
X impossible("Cannot build the TOWER!");
X }
X if (dlevel == tower_level+1) {
X if (load_special("tower2")) {
X xupstair = yupstair = 3;
X levl[xupstair][yupstair].scrsym = UP_SYM;
X levl[xupstair][yupstair].typ = STAIRS;
X return;
X }
X impossible("Cannot build the TOWER!");
X }
X if (dlevel == tower_level+2) {
X if (load_special("tower3")) {
X xupstair = yupstair = 3;
X levl[xupstair][yupstair].scrsym = UP_SYM;
X levl[xupstair][yupstair].typ = STAIRS;
X return;
X }
X impossible("Cannot build the TOWER!");
X }
X# ifdef ENDGAME
X if (dlevel == ENDLEVEL) { /* EndGame level */
X if (load_special("endgame")) {
X pline("Well done, mortal!");
X pline("But now thou must face the final Test...");
X pline("Prove thyself worthy or perish!");
X u.ux = x_maze_max - 1;
X u.uy = y_maze_max - 1;
X xupstair = yupstair = 0;
X return;
X }
X impossible("Cannot build the EndGame Level!");
X done(ESCAPED);
X }
X# endif
X#endif
X#ifndef WALLIFIED_MAZE
X for(x = 2; x < x_maze_max; x++)
X for(y = 2; y < y_maze_max; y++)
X levl[x][y].typ = STONE;
X#else
X for(x = 2; x <= x_maze_max; x++)
X for(y = 2; y <= y_maze_max; y++)
X levl[x][y].typ = ((x % 2) && (y % 2)) ? STONE : HWALL;
X#endif
X
X /* make decoy wizard levels */
X if((dlevel == wiz_level) ||
X#ifdef STRONGHOLD
X (!rn2(3) && (dlevel > stronghold_level+1))) {
X#else
X (!rn2(3) && (dlevel > medusa_level+1))) {
X#endif
X
X register struct monst *mtmp;
X
X zx = x_maze_max / 2;
X zy = y_maze_max / 2;
X if (!(zx % 2)) zx++;
X if (!(zy % 2)) zy++;
X for(y = zy-3, i=0; y <= zy+3; y++)
X for(x = zx-3; x <= zx+3; x++)
X levl[x][y].typ = tower[i++];
X walkfrom(zx+4, zy);
X if(mtmp = makemon(&mons[PM_HELL_HOUND], zx+1, zy))
X mtmp->msleep = 1;
X (void) makemon(&mons[PM_KRAKEN], zx+2, zy+2);
X if (mtmp = makemon(&mons[PM_VAMPIRE_LORD], zx-1, zy))
X mtmp->msleep = 1;
X if (dlevel == wiz_level) {
X
X (void) mksobj_at(AMULET_OF_YENDOR, zx, zy);
X flags.made_amulet = 1;
X if(mtmp = makemon(&mons[PM_WIZARD_OF_YENDOR], zx, zy))
X mtmp->msleep = 1;
X } else {
X struct obj *ot;
X /* make a cheap plastic imitation */
X if (ot = mksobj_at(AMULET_OF_YENDOR, zx, zy))
X ot-> spe = -1;
X (void) makemon(&mons[dprince()], zx, zy);
X }
X /* they should wake up when we intrude */
X (void) maketrap(zx-1, zy, SQBRD);
X (void) maketrap(zx+1, zy, SQBRD);
X (void) maketrap(zx, zy-1, SQBRD);
X (void) maketrap(zx, zy+1, SQBRD);
X } else {
X maze0xy(&mm);
X zx = mm.x;
X zy = mm.y;
X walkfrom(zx,zy);
X#ifndef STRONGHOLD /* it's in the castle */
X# ifdef HARD /* only one wand of wishing created */
X if(!rn2(10) || (dlevel == medusa_level + 1))
X# endif
X (void) mksobj_at(WAN_WISHING, zx, zy);
X#endif
X (void) mksobj_at(BOULDER, zx, zy); /* put a boulder on top of it */
X }
X
X#ifdef WALLIFIED_MAZE
X wallification(2, 2, x_maze_max, y_maze_max, TRUE);
X#else
X for(x = 2; x < x_maze_max; x++)
X for(y = 2; y < y_maze_max; y++)
X levl[x][y].scrsym = news0(x,y);
X#endif
X mazexy(&mm);
X levl[(xupstair = mm.x)][(yupstair = mm.y)].scrsym = UP_SYM;
X levl[xupstair][yupstair].typ = STAIRS;
X xdnstair = ydnstair = 0;
X#ifdef STRONGHOLD
X if (dlevel < stronghold_level) {
X mazexy(&mm);
X levl[(xdnstair = mm.x)][(ydnstair = mm.y)].scrsym = DN_SYM;
X levl[xdnstair][ydnstair].typ = STAIRS;
X }
X#endif
X for(x = rn1(8,11); x; x--) {
X mazexy(&mm);
X (void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y, TRUE);
X }
X for(x = rn1(10,2); x; x--) {
X mazexy(&mm);
X (void) mksobj_at(BOULDER, mm.x, mm.y);
X }
X mazexy(&mm);
X (void) makemon(&mons[PM_MINOTAUR], mm.x, mm.y);
X for(x = rn1(5,7); x; x--) {
X mazexy(&mm);
X (void) makemon((struct permonst *) 0, mm.x, mm.y);
X }
X for(x = rn1(6,7); x; x--) {
X mazexy(&mm);
X mkgold(0L,mm.x,mm.y);
X }
X for(x = rn1(6,7); x; x--)
X mktrap(0,1,(struct mkroom *) 0);
X}
X
X#ifdef MSDOS
X/* Make the mazewalk iterative by faking a stack. This is needed to
X * ensure the mazewalk is successful in the limited stack space of
X * the program. This iterative version uses the mimumum amount of stack
X * that is totally safe.
X */
Xvoid
Xwalkfrom(x,y)
Xint x,y;
X{
X#define CELLS (ROWNO * COLNO) / 4 /* a maze cell is 4 squares */
X char mazex[CELLS + 1], mazey[CELLS + 1]; /* char's are OK */
X int q, a, dir, pos;
X int dirs[4];
X
X pos = 1;
X mazex[pos] = (char) x;
X mazey[pos] = (char) y;
X while (pos) {
X x = (int) mazex[pos];
X y = (int) mazey[pos];
X#ifndef WALLIFIED_MAZE
X levl[x][y].typ = CORR;
X#else
X levl[x][y].typ = ROOM;
X#endif
X q = 0;
X for (a = 0; a < 4; a++)
X if(okay(x, y, a)) dirs[q++]= a;
X if (!q)
X pos--;
X else {
X dir = dirs[rn2(q)];
X move(&x, &y, dir);
X#ifndef WALLIFIED_MAZE
X levl[x][y].typ = CORR;
X#else
X levl[x][y].typ = ROOM;
X#endif
X move(&x, &y, dir);
X pos++;
X if (pos > CELLS)
X panic("Overflow in walkfrom");
X mazex[pos] = (char) x;
X mazey[pos] = (char) y;
X }
X }
X}
X#else
X
Xvoid
Xwalkfrom(x,y) int x,y; {
Xregister int q,a,dir;
Xint dirs[4];
X#ifndef WALLIFIED_MAZE
X levl[x][y].typ = CORR;
X#else
X levl[x][y].typ = ROOM;
X#endif
X while(1) {
X q = 0;
X for(a = 0; a < 4; a++)
X if(okay(x,y,a)) dirs[q++]= a;
X if(!q) return;
X dir = dirs[rn2(q)];
X move(&x,&y,dir);
X#ifndef WALLIFIED_MAZE
X levl[x][y].typ = CORR;
X#else
X levl[x][y].typ = ROOM;
X#endif
X move(&x,&y,dir);
X walkfrom(x,y);
X }
X}
X#endif /* MSDOS */
X
Xvoid
Xmove(x,y,dir)
Xregister int *x, *y;
Xregister int dir;
X{
X switch(dir){
X case 0: --(*y); break;
X case 1: (*x)++; break;
X case 2: (*y)++; break;
X case 3: --(*x); break;
X }
X}
X
Xvoid
Xmazexy(cc) /* find random point in generated corridors,
X so we don't create items in moats, bunkers, or walls */
X coord *cc;
X{
X int cpt=0;
X
X do {
X cc->x = 3 + 2*rn2((x_maze_max>>1) - 1);
X cc->y = 3 + 2*rn2((y_maze_max>>1) - 1);
X cpt++;
X#ifndef WALLIFIED_MAZE
X } while (cpt < 100 && levl[cc->x][cc->y].typ != CORR);
X#else
X } while (cpt < 100 && levl[cc->x][cc->y].typ != ROOM);
X#endif
X if (cpt >= 100) panic("mazexy: can't find a place!");
X return;
X}
X
Xvoid
Xbound_digging()
X/* put a non-diggable boundary around the initial portion of a level map.
X * assumes that no level will initially put things beyond the isok() range.
X */
X{
X register int x,y;
X register boolean found;
X int xmin,xmax,ymin,ymax;
X
X found = FALSE;
X for(xmin=1; !found; xmin++)
X for(y=0; y<=ROWNO-1; y++)
X if(levl[xmin][y].typ != STONE) found = TRUE;
X xmin -= 2;
X
X found = FALSE;
X for(xmax=COLNO-2; !found; xmax--)
X for(y=0; y<=ROWNO-1; y++)
X if(levl[xmax][y].typ != STONE) found = TRUE;
X xmax += 2;
X
X found = FALSE;
X for(ymin=1; !found; ymin++)
X for(x=xmin; x<=xmax; x++)
X if(levl[x][ymin].typ != STONE) found = TRUE;
X ymin -= 2;
X
X found = FALSE;
X for(ymax=ROWNO-2; !found; ymax--)
X for(x=xmin; x<=xmax; x++)
X if(levl[x][ymax].typ != STONE) found = TRUE;
X ymax += 2;
X
X for(x=xmin; x<=xmax; x++) {
X levl[x][ymin].diggable = W_NONDIGGABLE;
X levl[x][ymax].diggable = W_NONDIGGABLE;
X }
X
X for(y=ymin; y<=ymax; y++) {
X levl[xmin][y].diggable = W_NONDIGGABLE;
X levl[xmax][y].diggable = W_NONDIGGABLE;
X }
X}
END_OF_FILE
if test 10520 -ne `wc -c <'src/mkmaze.c'`; then
echo shar: \"'src/mkmaze.c'\" unpacked with wrong size!
fi
# end of 'src/mkmaze.c'
fi
if test -f 'src/unixmain.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/unixmain.c'\"
else
echo shar: Extracting \"'src/unixmain.c'\" \(10617 characters\)
sed "s/^X//" >'src/unixmain.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)unixmain.c 3.0 89/01/13
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X/* main.c - Unix NetHack */
X
X#include "hack.h"
X
X#include <signal.h>
X#include <pwd.h>
X#ifndef O_RDONLY
X#include <fcntl.h>
X#endif
X
Xchar SAVEF[PL_NSIZ + 11] = "save/"; /* save/99999player */
X
Xconst char *hname = 0; /* name of the game (argv[0] of call) */
Xchar obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */
Xint hackpid = 0; /* current pid */
Xint locknum = 0; /* max num of players */
X#ifdef DEF_PAGER
Xchar *catmore = 0; /* default pager */
X#endif
X
Xextern struct passwd *getpwnam(), *getpwuid();
X#ifdef CHDIR
Xstatic void chdirx();
X#endif /* CHDIR */
Xstatic void whoami();
X
Xint
Xmain(argc,argv)
Xint argc;
Xchar *argv[];
X{
X extern int x_maze_max, y_maze_max;
X register int fd;
X#ifdef CHDIR
X register char *dir;
X#endif
X#ifdef COMPRESS
X char cmd[80], old[80];
X#endif
X
X hname = argv[0];
X hackpid = getpid();
X (void) umask(0);
X
X /*
X * Remember tty modes, to be restored on exit.
X *
X * gettty() must be called before startup()
X * due to ordering of LI/CO settings
X * startup() must be called before initoptions()
X * due to ordering of graphics settings
X */
X gettty();
X setbuf(stdout,obuf);
X startup();
X initoptions();
X whoami();
X
X#ifdef CHDIR /* otherwise no chdir() */
X /*
X * See if we must change directory to the playground.
X * (Perhaps hack runs suid and playground is inaccessible
X * for the player.)
X * The environment variable HACKDIR is overridden by a
X * -d command line option (must be the first option given)
X */
X dir = getenv("HACKDIR");
X#endif
X if(argc > 1) {
X#ifdef CHDIR
X if (!strncmp(argv[1], "-d", 2) && argv[1][2] != 'e') {
X /* avoid matching "-dec" for DECgraphics; since the man page
X * says -d directory, hope nobody's using -desomething_else
X */
X argc--;
X argv++;
X dir = argv[0]+2;
X if(*dir == '=' || *dir == ':') dir++;
X if(!*dir && argc > 1) {
X argc--;
X argv++;
X dir = argv[0];
X }
X if(!*dir)
X error("Flag -d must be followed by a directory name.");
X } else
X#endif /* CHDIR /**/
X
X /*
X * Now we know the directory containing 'record' and
X * may do a prscore().
X */
X if (!strncmp(argv[1], "-s", 2)) {
X#ifdef CHDIR
X chdirx(dir,0);
X#endif
X prscore(argc, argv);
X if(isatty(1)) getret();
X settty(NULL);
X exit(0);
X }
X }
X
X /*
X * It seems you really want to play.
X */
X setrandom();
X cls();
X u.uhp = 1; /* prevent RIP on early quits */
X u.ux = FAR; /* prevent nscr() */
X (void) signal(SIGHUP, (SIG_RET_TYPE) hangup);
X#ifdef SIGXCPU
X (void) signal(SIGXCPU, (SIG_RET_TYPE) hangup);
X#endif
X
X /*
X * Find the creation date of this game,
X * so as to avoid restoring outdated savefiles.
X */
X gethdate(hname);
X
X /*
X * We cannot do chdir earlier, otherwise gethdate will fail.
X */
X#ifdef CHDIR
X chdirx(dir,1);
X#endif
X
X /*
X * Process options.
X */
X while(argc > 1 && argv[1][0] == '-'){
X argv++;
X argc--;
X switch(argv[0][1]){
X#if defined(WIZARD) || defined(EXPLORE_MODE)
X# ifndef EXPLORE_MODE
X case 'X':
X# endif
X case 'D':
X# ifdef WIZARD
X {
X char *user;
X int uid;
X struct passwd *pw = (struct passwd *)0;
X
X uid = getuid();
X user = getlogin();
X if (user) {
X pw = getpwnam(user);
X if (pw && (pw->pw_uid != uid)) pw = 0;
X }
X if (pw == 0) {
X user = getenv("USER");
X if (user) {
X pw = getpwnam(user);
X if (pw && (pw->pw_uid != uid)) pw = 0;
X }
X if (pw == 0) {
X pw = getpwuid(uid);
X }
X }
X if (pw && !strcmp(pw->pw_name,WIZARD)) {
X wizard = TRUE;
X break;
X }
X }
X /* otherwise fall thru to discover */
X# endif
X# ifdef EXPLORE_MODE
X case 'X':
X discover = TRUE;
X# endif
X break;
X#endif
X#ifdef NEWS
X case 'n':
X flags.nonews = TRUE;
X break;
X#endif
X case 'u':
X if(argv[0][2])
X (void) strncpy(plname, argv[0]+2, sizeof(plname)-1);
X else if(argc > 1) {
X argc--;
X argv++;
X (void) strncpy(plname, argv[0], sizeof(plname)-1);
X } else
X Printf("Player name expected after -u\n");
X break;
X case 'i':
X if(!strcmp(argv[0]+1, "ibm")) assign_ibm_graphics();
X break;
X case 'd':
X if(!strcmp(argv[0]+1, "dec")) assign_dec_graphics();
X break;
X default:
X /* allow -T for Tourist, etc. */
X (void) strncpy(pl_character, argv[0]+1,
X sizeof(pl_character)-1);
X
X /* Printf("Unknown option: %s\n", *argv); */
X }
X }
X
X if(argc > 1)
X locknum = atoi(argv[1]);
X#ifdef MAX_NR_OF_PLAYERS
X if(!locknum || locknum > MAX_NR_OF_PLAYERS)
X locknum = MAX_NR_OF_PLAYERS;
X#endif
X#ifdef DEF_PAGER
X if(!(catmore = getenv("HACKPAGER")) && !(catmore = getenv("PAGER")))
X catmore = DEF_PAGER;
X#endif
X#ifdef MAIL
X getmailstatus();
X#endif
X#ifdef WIZARD
X if (wizard)
X Strcpy(plname, "wizard");
X else
X#endif
X if(!*plname || !strncmp(plname, "player", 4)
X || !strncmp(plname, "games", 4))
X askname();
X plnamesuffix(); /* strip suffix from name; calls askname() */
X /* again if suffix was whole name */
X /* accepts any suffix */
X#ifdef WIZARD
X if(!wizard) {
X#endif
X /*
X * check for multiple games under the same name
X * (if !locknum) or check max nr of players (otherwise)
X */
X (void) signal(SIGQUIT,SIG_IGN);
X (void) signal(SIGINT,SIG_IGN);
X if(!locknum)
X Sprintf(lock, "%d%s", getuid(), plname);
X getlock(); /* sets lock if locknum != 0 */
X#ifdef WIZARD
X } else
X Sprintf(lock, "%d%s", getuid(), plname);
X#endif /* WIZARD /**/
X setftty();
X
X /*
X * Initialisation of the boundaries of the mazes
X * Both boundaries have to be even.
X */
X
X x_maze_max = COLNO-1;
X if (x_maze_max % 2)
X x_maze_max--;
X y_maze_max = ROWNO-1;
X if (y_maze_max % 2)
X y_maze_max--;
X
X /* initialize static monster strength array */
X init_monstr();
X
X Sprintf(SAVEF, "save/%d%s", getuid(), plname);
X regularize(SAVEF+5); /* avoid . or / in name */
X#ifdef COMPRESS
X Strcpy(old,SAVEF);
X Strcat(SAVEF,".Z");
X if((fd = open(SAVEF,O_RDONLY)) >= 0) {
X (void) close(fd);
X Strcpy(cmd, COMPRESS);
X Strcat(cmd, " -d "); /* uncompress */
X# ifdef COMPRESS_OPTIONS
X Strcat(cmd, COMPRESS_OPTIONS);
X Strcat(cmd, " ");
X# endif
X Strcat(cmd,SAVEF);
X (void) system(cmd);
X }
X Strcpy(SAVEF,old);
X#endif
X if((fd = open(SAVEF,O_RDONLY)) >= 0 &&
X /* if not up-to-date, quietly unlink file via false condition */
X (uptodate(fd) || unlink(SAVEF) == 666)) {
X#ifdef WIZARD
X /* Since wizard is actually flags.debug, restoring might
X * overwrite it.
X */
X boolean remember_wiz_mode = wizard;
X#endif
X (void) chmod(SAVEF,0); /* disallow parallel restores */
X (void) signal(SIGINT, (SIG_RET_TYPE) done1);
X pline("Restoring save file...");
X (void) fflush(stdout);
X if(!dorecover(fd))
X goto not_recovered;
X#ifdef WIZARD
X if(!wizard && remember_wiz_mode) wizard = TRUE;
X#endif
X pline("Hello %s, welcome to NetHack!", plname);
X /* get shopkeeper set properly if restore is in shop */
X (void) inshop();
X#ifdef EXPLORE_MODE
X if (discover)
X You("are in non-scoring discovery mode.");
X#endif
X#if defined(EXPLORE_MODE) || defined(WIZARD)
X if (discover || wizard) {
X pline("Do you want to keep the save file? ");
X if(yn() == 'n')
X (void) unlink(SAVEF);
X else {
X (void) chmod(SAVEF,FCMASK); /* back to readable */
X# ifdef COMPRESS
X Strcpy(cmd, COMPRESS);
X Strcat(cmd, " ");
X# ifdef COMPRESS_OPTIONS
X Strcat(cmd, COMPRESS_OPTIONS);
X Strcat(cmd, " ");
X# endif
X Strcat(cmd,SAVEF);
X (void) system(cmd);
X# endif
X }
X }
X#endif
X flags.move = 0;
X } else {
Xnot_recovered:
X newgame();
X /* give welcome message before pickup messages */
X pline("Hello %s, welcome to NetHack!", plname);
X#ifdef EXPLORE_MODE
X if (discover)
X You("are in non-scoring discovery mode.");
X#endif
X flags.move = 0;
X set_wear();
X pickup(1);
X read_engr_at(u.ux,u.uy);
X }
X
X flags.moonphase = phase_of_the_moon();
X if(flags.moonphase == FULL_MOON) {
X You("are lucky! Full moon tonight.");
X if(!u.uluck) change_luck(1);
X } else if(flags.moonphase == NEW_MOON) {
X pline("Be careful! New moon tonight.");
X }
X
X initrack();
X
X moveloop();
X return(0);
X}
X
Xvoid
Xglo(foo)
Xregister int foo;
X{
X /* construct the string xlock.n */
X register char *tf;
X
X tf = lock;
X while(*tf && *tf != '.') tf++;
X Sprintf(tf, ".%d", foo);
X}
X
X/*
X * plname is filled either by an option (-u Player or -uPlayer) or
X * explicitly (by being the wizard) or by askname.
X * It may still contain a suffix denoting pl_character.
X */
Xvoid
Xaskname() {
X register int c, ct;
X
X Printf("\nWho are you? ");
X (void) fflush(stdout);
X ct = 0;
X while((c = Getchar()) != '\n') {
X if(c == EOF) error("End of input\n");
X /* some people get confused when their erase char is not ^H */
X if(c == '\010') {
X if(ct) ct--;
X continue;
X }
X if(c != '-')
X if(c < 'A' || (c > 'Z' && c < 'a') || c > 'z') c = '_';
X if(ct < sizeof(plname)-1)
X plname[ct++] = c;
X }
X plname[ct] = 0;
X if(ct == 0) askname();
X}
X
X#ifdef CHDIR
Xstatic void
Xchdirx(dir, wr)
Xchar *dir;
Xboolean wr;
X{
X
X# ifdef SECURE
X if(dir /* User specified directory? */
X# ifdef HACKDIR
X && strcmp(dir, HACKDIR) /* and not the default? */
X# endif
X ) {
X (void) setgid(getgid());
X (void) setuid(getuid()); /* Ron Wessels */
X }
X# endif
X
X# ifdef HACKDIR
X if(dir == NULL)
X dir = HACKDIR;
X# endif
X
X if(dir && chdir(dir) < 0) {
X perror(dir);
X error("Cannot chdir to %s.", dir);
X }
X
X /* warn the player if we can't write the record file */
X /* perhaps we should also test whether . is writable */
X /* unfortunately the access systemcall is worthless */
X if(wr) {
X register int fd;
X
X if(dir == NULL)
X dir = ".";
X if((fd = open(RECORD, O_RDWR)) < 0) {
X if((fd = open(RECORD, O_CREAT|O_RDWR, FCMASK)) < 0) {
X Printf("Warning: cannot write %s/%s", dir, RECORD);
X getret();
X } else
X (void) close(fd);
X } else
X (void) close(fd);
X }
X}
X#endif /* CHDIR /**/
X
Xstatic void
Xwhoami() {
X /*
X * Who am i? Algorithm: 1. Use name as specified in NETHACKOPTIONS
X * 2. Use $USER or $LOGNAME (if 1. fails)
X * 3. Use getlogin() (if 2. fails)
X * The resulting name is overridden by command line options.
X * If everything fails, or if the resulting name is some generic
X * account like "games", "play", "player", "hack" then eventually
X * we'll ask him.
X * Note that we trust the user here; it is possible to play under
X * somebody else's name.
X */
X register char *s;
X
X if(!*plname && (s = getenv("USER")))
X (void) strncpy(plname, s, sizeof(plname)-1);
X if(!*plname && (s = getenv("LOGNAME")))
X (void) strncpy(plname, s, sizeof(plname)-1);
X if(!*plname && (s = getlogin()))
X (void) strncpy(plname, s, sizeof(plname)-1);
X}
END_OF_FILE
if test 10617 -ne `wc -c <'src/unixmain.c'`; then
echo shar: \"'src/unixmain.c'\" unpacked with wrong size!
fi
# end of 'src/unixmain.c'
fi
echo shar: End of archive 46 \(of 56\).
cp /dev/null ark46isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 56 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
echo Building monst.c from monst.c1 and monst.c2
cat src/monst.c1 src/monst.c2 > src/monst.c
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0