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