[comp.sources.games] v10i087: nethack3p9 - display oriented dungeons & dragons

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

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 87
Archive-name: nethack3p9/Part42
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 42 (of 56)."
# Contents:  Install.dos Install.ovl src/do_name.c src/sp_lev.c
# Wrapped by billr@saab on Wed Jul 11 17:11:56 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'Install.dos' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Install.dos'\"
else
echo shar: Extracting \"'Install.dos'\" \(13860 characters\)
sed "s/^X//" >'Install.dos' <<'END_OF_FILE'
X	Instructions for compiling and installing NetHack 3.0
X		   on an MS-DOS, TOS, or OS/2 system
X	=====================================================
X	    (or, How to make PC, ST, and OS/2 NetHack 3.0)
X		      Last revision: 22 May 1990
X
X    Credit for ST and OS/2 NetHack 3.0 goes to Eric Smith and Timo Hakulinen,
X    respectively.  Additional credit should be given to Steve Creps and
X    Mike Threepoint for PC NetHack.
X
X*** Note: if you intend to compile NetHack on an MS-DOS PC using OVERLAY, 
X    please turn to the instructions in Install.ovl.  The overlay version is
X    currently available only for MSC.
X
X1.  Make sure all the NetHack files are in the appropriate directory structure.
X    You should have a main directory with subdirectories src, include, auxil,
X    others, amiga, mac, and vms.  If you do not follow this structure, the
X    Makefile will not function properly.
X
X    All the shared and UNIX-specific .c files and the source Makefile belong
X    in src; all the PC .c files and make files belong in others; all the .h
X    files belong in include; other assorted files belong in auxil.  We will
X    not need any of the files from the amiga, mac, and vms directories.
X
X    If you downloaded or ftp'd the sources from a UNIX system, the lines
X    will probably end in UNIX-style newlines, instead of the carriage
X    return and line feed pairs used by DOS and OS/2.  Turbo C 2.0 in
X    particular dislikes these; you'll have to convert them (with a utility
X    like Rahul Dhesi's "flip").  Also, every file should end with an empty
X    line, because both Microsoft C has a habit of ignoring the last line of
X    each file. (TOS compilers generally don't have either problem).
X
X2.  Copy the .c files from the others directory to your src directory
X    based on the following decisions.  (You will probably want to include
X    all of these files.)
X
X    You will definitely need pc*.c and msdos.c.
X
X    The file termcap.uu is the fixed version of the Fred Fish termcap library.
X    You will need to run a uudecode utility on it to generate the file
X    termcap.arc.  termcap.arc contains several files of termcap routines.
X    Using them with NetHack involves very little knowledge of the UNIX concept
X    of a termcap database; mostly you need to know enough to set a TERM
X    environment variable.  You can unarc termcap.arc here in the others
X    directory, but if you are going to use it, it is probably best to unarc a
X    copy in the src directory.  That way you will not miss copying any
X    files over.  Wherever you unarc it, get rid of the included makefile
X    since a better version has been provided as Makefile.lib.
X
X    random.c is only needed if you want the high-quality random number
X    generation routines.
X
X    trampoli.c and ovlmgr.obj files are needed for the MS-DOS overlays.
X    You may ignore these.
X
X    TOS users should use others/lev_lex.c instead of src/lev_lex.c.
X    MS-DOS users should be able to use either, but the one in src
X    is smaller.  If you have flex or some other lex work-alike, use
X    that to produce lev_lex.c from lev_comp.l.
X
X    Obviously, TOS users don't need the MS-DOS overlay functions.
X    Moreover, the GCC "curses" library has termcap routines built
X    in, so if you have this you don't need termcap.arc.
X
X3.  Now look at Makefile.* in your others directory.  Consult the list below
X    and pick out the makefile most appropriate to your system.  Rename this
X    file to "Makefile" (no extension), and move it into your src directory.
X
X    DOS:
X	Microsoft C 5.0+	Makefile.msc
X	Microsoft C 4.0 	Makefile.pc
X	Turbo C 2.0		Makefile.tcc
X    OS/2:
X	Microsoft C 5.1 	Makefile.os2
X    TOS:
X	GCC 1.34		Makefile.st
X
X    The PC NetHack makefiles are set up for NDMAKE, a public domain
X    "make" utility.  Both Microsoft's and Borland's "make" leave much to
X    be desired.  It is worth the extra effort to get NDMAKE if you don't
X    already have it.  Among other things, NDMAKE automatically generates
X    link response files when the link command involves so many objects
X    that the command would become longer than DOS can handle.  If you must
X    use Microsoft's or Borland's "make", you'll need to edit the makefile
X    into a form your make can use, and add instructions to generate a link
X    response file.
X
X    Makefile.os2 can also be used with Microsoft NMAKE, which is shipped with
X    new versions of MS languages.  This "make", although slightly incompatible
X    with NDMAKE, is powerful enough to make NetHack.  Since NDMAKE only works
X    in DOS, the only way to compile NetHack in OS/2 currently is to use NMAKE.
X    However, when cross-compiling for OS/2 in DOS, NDMAKE is a better choice
X    because it requires less RAM for itself.  See Makefile.os2 for more
X    information.
X
X    The ST NetHack makefile should work with either the widely available
X    PD make, or (much better) GNU Make.
X
X    If you're using a different compiler, you will have to adapt one of
X    the makefiles to your needs.  In particular, change the CC and CFLAGS
X    macros to your C compiler's file name and the parameters to pass it.
X
X    For DOS users, if you are going to be constructing the Fred Fish termlib
X    you will need the Makefile.lib.  Copy this to your source directory too,
X    and do not change its name.
X
X    Makefile.top in the top directory and Makefile.aux(il) in the
X    auxil directory are for UNIX NetHack.  You may delete them.
X
X4.  Now go to the include subdirectory to edit a couple of the header files
X    there.
X
X    First edit config.h according to the comments to match your system and
X    desired set of features.  Mostly you need to check the WIZARD option,
X    make sure the HACKDIR is set properly, and check TERMLIB and COMPRESS.
X
X    Also edit pcconf.h for PC or OS/2 NetHack, or tosconf.h for ST NetHack.
X    pcconf.h should not need much editing.  If you are not going to include
X    random.c or termcap.uu you will need to comment out RANDOM or TERMLIB
X    respectively.  You will definitely need to comment out OVERLAY.
X
X    Commenting out the #define TERMLIB in pcconf.h/tosconf.h to disable
X    use of termcap routines (relying on the ANSI_DEFAULT feature) will make
X    your job a bit easier.  However, you can compile with both and simply
X    not set your TERM variable if you do not wish to use the termcap file
X    settings.
X
X    ST and OS/2 NetHackers can skip to the next section, since the entire game
X    will fit in less than one megabyte.
X
X PC NetHackers:
X
X    To compile under MS-DOS, you must either produce an overlaid executable or
X    make some very difficult decisions about which features to include.
X
X    The base size of a PC NetHack executable, with no extra features or
X    overlays, will be around 570 (or better) kilobytes.  Anything over 590K
X    is likely not to work.  Here's an incomplete and outdated list of the
X    approximate costs of various additional features in terms of executable
X    size, using Microsoft C:
X
X	WIZARD		    3K
X	LOGFILE
X	NEWS
X	COMPRESS	    2K
X	ZEROCOMP
X	CHDIR
X
X	POLYSELF	   31K
X	THEOLOGY	   11K
X	SOUNDS		    6K
X	KICK
X
X	THRONES 	    3K
X	FOUNTAINS	    2K
X	SINKS		    5K
X	ALTARS		    4K
X
X	WALLIFIED_MAZE	    1K
X	REINCARNATION	    7K
X	STRONGHOLD	   13K
X
X	ORACLE
X	MEDUSA
X	KOPS
X	ARMY		    1K
X	WORM
X	GOLEMS		    2K
X	INFERNO
X	SEDUCE
X	TOLKIEN
X	PROBING 	    1K
X	WALKIES 	    4K
X	SHIRT
X	MUSIC		    6K
X	TUTTI_FRUTTI
X	SPELLS		   10K
X	NAMED_ITEMS
X
X	ELBERETH	    3K
X	EXPLORE_MODE	    2K
X	HARD
X
X	REDO		    1K
X	COM_COMPL	    1K
X	CLIPPING
X
X	DGK		    7K
X	TERMLIB
X	RANDOM		    1K
X	SHELL
X	TEXTCOLOR	    1K
X
X    Using Turbo C, we eked by with just WIZARD, ZEROCOMP, BITFIELDS, ELBERETH,
X    HARD, REDO, DGK and TEXTCOLOR.
X
X5.  If you're using a compiler not in the list in step 3, you may want to look
X    through system.h, in the include directory.  This file matches the return
X    and parameter types for system calls and library routines with various
X    flavors of compilers and operating systems.  Leaving this file alone is
X    unlikely to cause problems, but if you get compile errors with any
X    functions in the standard library, it's worth checking the declarations
X    there.
X
X6.  If you want to change the high score list behavior, examine the top of
X    topten.c, in the src directory.  You may want to change the definitions of
X    PERSMAX, POINTSMIN, and ENTRYMAX.  I set POINTSMIN to 51 and ENTRYMAX to
X    50 to keep the size of the score list down.
X
X7.  Go to the src directory and edit the top of your Makefile.  Be sure the
X    directory you want the game installed in actually exists.
X
X    If you elected not to use the high-quality BSD random number routines by
X    commenting out RANDOM in pcconf.h or tosconf.h, comment out (or set equal
X    to nothing) the RANDOM macro in your Makefile.
X
X    If you elected to use Fred Fish's termcap library (bundled in as
X    termcap.arc), you will have to generate termcap.lib from those sources
X    by typing make -f makefile.lib termlib.lib.  DOS / OS/2 users must set the
X    TERMLIB option in Makefile.msc / Makefile.os2 to link in the resulting
X    termlib.lib.
X
X    If you are recompiling after patching your sources, or if you got your
X    files from somewhere other than the official distribution, "touch
X    makedefs.c" to ensure that certain files (onames.h and pm.h) are remade,
X    lest potentially troublesome timestamps fool "make".
X
X8.  Now, enter "make all", and take a long siesta; your computer will be
X    occupied for a long time.  If all goes well, you will get an executable.
X    If you tried to compile in too many features, you will probably get a
X    dysfunctional executable, and will have to start over.
X
X	Hint:  If you're short on memory, you might enter "make -n all
X	>script.bat", and then in DOS enter "script", or in TOS use the Gulam
X	command "source script.bat".  GCC users will be short on memory if
X	they only have 2 megabytes. Indeed, some files will not compile in
X	2 megabytes with the GCC 1.36; for these you'll either have to turn
X	off the -O option or use an earlier version of the GCC.
X
X9.  Make sure the support files-- data, rumors, cmdhelp, opthelp, help, hh,
X    history, license, and oracles (if ORACLES was #define'd)-- were copied
X    to the game directory.  If not, move them there from the auxil directory
X    yourself.  rumors can be created manually by entering "makedefs -r";
X    data by entering "makedefs -d".
X
X    If you compiled in the compiled levels (if STRONGHOLD was #define'd), make
X    sure castle, tower?, and possibly endgame are there, too.  They can be
X    created manually by entering "lev_comp filename.des", where filename.des
X    is the appropriate description file (found in the auxil directory).
X
X10. Go to the others directory.  Copy NetHack.cnf, or Atari.cnf for TOS, to
X    your game directory as "NetHack.cnf".  Edit it to reflect your particular
X    setup and personal preferences, following the comments.
X
X    If you compiled in the TERMLIB feature, also move the "termcap" file to
X    your game directory.  (Note:  GCC's termcap routines have built-in
X    defaults, so the termcap file is not necessary with that compiler.)
X
X    To use funky graphics charaters in TOS, uudecode "atarifnt.uue" and unarc
X    the resulting "atarifnt.arc".  This contains a program to run that makes
X    some line graphics characters available to NetHack.  To use them, uncomment
X    the appropriate line in your NetHack.cnf file, and run the program before
X    running NetHack (you can put the program in an AUTO folder if you want).
X
X    If you'll be running NetHack from a different subdirectory, you will
X    want to "set HACKDIR=\games\nethack" (or whatever directory you want to
X    use) now.  Add it to your autoexec.bat (in DOS), if you'll be playing
X    often.
X
X11. Play NetHack.  If it works, you're done!
X
X
XNotes
X-----
X
X1)  Save files and bones files from previous versions will not work with
X    NetHack 3.0.  Don't bother trying to keep them.  Record (score) files
X    from before 3.0 patchlevel 7 will almost work, but you need to make one
X    change manually to them:  At the end of each line is a word or phrase
X    specifying what killed the player.  Change the string to start with the
X    words "killed by", "killed by a", or "killed by an" (whichever is
X    appropriate).  If the death was petrification, it should read "petrified
X    by" instead of "killed by".  Don't change "starvation", "quit", "escaped",
X    or "ascended".
X
X2)  To install an update of NetHack after changing something, enter "make"
X    from the src directory.  If you add, delete, or reorder monsters or
X    objects, or you change the format of saved level files, delete any save
X    and bones files.  (Trying to use such files sometimes produces amusing
X    confusions on the game's part, but usually crashes.)
X
X3)  During linking, the Microsoft Overlay Linker will need temporary storage
X    space to make the PC and OS/2 versions.  Make sure you have
X    about a meg of free disk where ever you have defined your temporary
X    storage.  It is also a good idea to compile with as much free RAM as
X    possible.  It may otherwise get crowded with the bigger, more complex
X    source files.  (Compiler bombs with "out of heap space" or similar.)
X    If this happens, strip your configuration, zap TSR's etc.
X
X4)  On a 286 10MHz PC you will have NetHack in about 2 - 2.5 hours.
X
X5)  Both OS/2 NetHack and the overlaid PC NetHack have been developed using
X    MSC 5.1.  MSC 6.0 is on the market, but since there hasn't been enough
X    time to fully test the game compiled with MSC 6.0, the distribution version
X    supports officially only MSC 5.1.  To compile NetHack with MSC 6.0, it may
X    be necessary to make some slight modifications to respective makefiles
X    as well as some source files.  Also, when compiling OS/2 version with MSC
X    6.0, change library "doscalls" to "os2" in Makefile.os2.
END_OF_FILE
if test 13860 -ne `wc -c <'Install.dos'`; then
    echo shar: \"'Install.dos'\" unpacked with wrong size!
fi
# end of 'Install.dos'
fi
if test -f 'Install.ovl' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Install.ovl'\"
else
echo shar: Extracting \"'Install.ovl'\" \(14761 characters\)
sed "s/^X//" >'Install.ovl' <<'END_OF_FILE'
X	    Instructions for compiling and installing the Overlaid
X			NetHack 3.0 on an MS-DOS system
X	    ======================================================
X			(or, How to make PC NetHack 3.0)
X			  Last revision: June 02, 1990
X
X    (Credit for a runnable full PC NetHack 3.0 goes to the overlay team of
X     Pierre Martineau, Stephen Spackman, Norm Meluch, and Kevin Smolkowski,
X     who built on the work of Steve Creps and Mike Threepoint.)
X
X
XI.  Dispelling the Myths:
X
X    Compiling NetHack is not as easy as it sounds, nor as hard as it looks,
X    however it will behoove you to read this entire file through before
X    beginning the task.
X
X    The NetHack executable that you are about to get will be generated by an
X    overlay linker.  The beauty of this overlay linker beastie is that it will
X    create an executable that will function in much less memory than it would
X    "normally" take to run.  Do not be deceived.  The RAM requirement for the
X    overlay version is about 550k!  You can load the program in less RAM, but
X    you will begin to experience a serious amount of disk thrashing at 530k
X    or less.  Absolute minimum will probably be in the neighborhood of 380-400k.
X    You do not want to run the program like that!  The more free RAM you have
X    available for the program, the more smoothly it will run.
X
X    The magic piece to the overlay puzzle is a program called ovlmgr.asm.  This
X    is a replacement for the Microsoft (and we use the term loosely) overlay
X    manager.  This program has been enhanced since its release in November
X    1989.  It will now allow NetHack to use EMS memory if any is available,
X    therefore, RAM requirements can be reduced to the minimum with at least
X    256K of EMS.
X
X    As of patch level 7, version 3.0 has an added feature in the Makefile.  
X    This feature enables a structured break-up of the object modules so that 
X    we can link heavily used functions together without actual source code
X    movement.  This has provided a great speed improvement for this release.
X    See the file others\maintain.ovl for more information on this structuring.
X
X
XII.  How long is this going to take?
X
X    On an XT class PC it has been rumored that NetHack can be built in 8 - 10
X      hours.
X    On a 286 10MHz PC you can build NetHack in about 3 - 3.5 hours,
X    On the flip side if you have a 386 33MHz PC with a *VERRRRY* fast hard
X      disk, math coprocessor, 32 bit bus, and severe I/O caching you will have
X      NetHack in about 15 minutes!
X    
X    Hope you enjoy the game.  We have worked very hard to try to bring it back
X    to the PC.
X
X
XIII.  Tools:
X
X   The following programs are necessary to successfully compile the overlaid
X   version of NetHack:
X
X   A.	Microsoft C, version 5.1 or newer.
X
X   B.	The Microsoft Overlay Linker, version 3.6 or newer or preferably,
X	 the Microsoft Segmented Linker, version 5.01.20 or newer. The
X	 overlay linker has been known to cause problems with other
X	 programs, but not with NetHack, yet.
X	One of these linkers should be included in your MSC version.
X
X   C.	NDmake, version 4.5 or newer, (available from your local ftp site).
X	 As the overlay makefile is pretty large, you will want to use the
X	 large model of NDmake: MAKE45L.EXE, as your make program.
X	MSC 6.0 has a new make program distributed with it that might be
X	 able to handle the Makefile.ovl with a few modifications.  This has
X	 not been completely tested.  We recommend NDmake 4.5.
X
X
XIV.  Optional tools:
X
X   The following programs are not necessary, because pre-built copies of the
X   files are included in this distribution.  However, if you want to build
X   NetHack 100% from scratch, you will need them.
X
X   A.	An 80x86 assembler.
X	This is for assembling the ovlmgr.asm file into ovlmgr.obj.  If you
X	 want to assemble your own copy of the overlay manager.  The file
X	 others\ovlmgr.uu is a uuencoded version of the assembled ovlmgr.asm.
X	For details, see the file ovlmgr.doc.
X
X   B.	Yacc/Bison & Lex/Flex workalike programs for the PC.
X	The source files for the special levels compiler are built using
X	 bison and flex.  Precompiled copies of the files lev_lex.c, and
X	 lev_comp.c have been provided if you do not have these utilities.
X	Bison & flex should also be available at your local ftp site.
X
X
XV.  To compile your copy of NetHack on a MSDOS machine:
X    (or "just follow the "simple" steps outlined below.)
X
X1.  It almost goes without saying that you should make sure that your tools
X    are set up and running correctly.
X
X2.  Make sure all the NetHack files are in the appropriate directory
X    structure.  You should have a main directory with subdirectories
X    src, include, auxil, others, amiga, mac, and vms.  If you do not
X    follow this structure, the Makefile.ovl will not function properly.
X
X    All the shared and UNIX-specific .c files and the source Makefile(.src)
X    belong in src; all the PC *.c files and PC make files belong in others;
X    all the .h files belong in include; other assorted files belong in auxil.
X    Check the file "Files" in your top level directory for an exact listing
X    of what file is in which directory.
X
X    We will not need any of the files from the amiga, mac, and vms
X    directories, so you can delete them if you need the space.
X
X    If you downloaded or ftp'd the sources from a UNIX system, the lines
X    will probably end in UNIX-style newlines, instead of the carriage
X    return and line feed pairs used by DOS.  Some programs have trouble
X    with them,  you may need to convert them (with a utility like
X    Rahul Dhesi's "flip").  Also, every file should end with an empty
X    line, because both Microsoft C and MASM have a habit of ignoring the
X    last line of each file. 
X
X3.  Move/Copy files from the others directory to your src directory
X    based on the following criteria.  You will probably want to include
X    most all of these files.
X
X    You will definitely need pc*.c, msdos.c, and trampoli.c.
X
X    random.c is only needed if you want the high-quality random number
X    generation routines.
X
X    You should be able to use either others/lev_lex.c (generated by flex)
X    or src/lev_lex.c (generated by lex), but the one in src is smaller.
X    If you have flex or some other lex work-alike, you can use that to
X    produce lev_lex.c from lev_comp.l.
X
X    The file termcap.uu is the fixed version of the Fred Fish termcap library.
X    You will need to run a uudecode utility on it to generate the file
X    termcap.arc.  termcap.arc contains several files of termcap routines.
X    Using them with NetHack involves very little knowledge of the UNIX concept
X    of a termcap database; mostly you need to know enough to set a TERM
X    environment variable.  You can unarc termcap.arc here in the others
X    directory, but if you are going to use it, it is probably best to unarc a
X    copy in the src directory.  That way you will not miss copying any
X    files over.  Wherever you unarc it, get rid of the included makefile
X    since a better version has been provided as Makefile.lib.
X
X    ovlmgr.uu (MS-DOS overlay manager) is the uuencoded assembled
X    object module for the overlay manager in case you do not have an assembler.
X    You will need to run a uudecode utility on this file too, to generate
X    ovlmgr.obj.
X
X    Exesmurf.uu is the uuencoded copy of the exesmurf utility which displays
X    and modifies the contents of an executable file header.  It is similar
X    to Microsoft's exemod utility but it provides infomation on overlays
X    which EXEMOD does not.  It is used to modify the Nethack executable's
X    memory allocation.
X
X4.  Rename the file Makefile.ovl to "Makefile." (no extension), and move 
X    it into your src directory.
X
X    The PC NetHack makefiles are set up for NDMAKE, a public domain
X    "make" utility.  Both Microsoft's "make" leaves much to
X    be desired.  It is worth the extra effort to get NDMAKE if you don't
X    already have it.  Among other things, NDMAKE automatically generates
X    link response files when the link command involves so many objects
X    that the command would become longer than DOS can handle.  If you must
X    use Microsoft's or Borland's "make", you'll need to edit the makefile
X    into a form your make can use, and add instructions to generate a link
X    response file.
X
X    If you are going to be constructing the Fred Fish termlib you will need 
X    the Makefile.lib.  Copy this to your source directory too, and do not 
X    change its name.
X
X    Makefile.top in the top directory, Makefile.src in the src directory,
X    and Makefile.aux(il) in the auxil directory are for UNIX NetHack. You
X    will not need these, and you may delete them.
X
X    Makefile.pc, Makefile.msc, and Makefile.tos are for compiling non-
X    overlaid versions of NetHack, and for the atari.  You may delete these
X    too.
X
X4.  Now go to the include subdirectory to edit a couple of the header files
X    there.
X
X    First edit config.h according to the comments to match your system and
X    desired set of features.  Mostly you need to check the WIZARD option,
X    make sure the HACKDIR is set properly, and check TERMLIB and COMPRESS.
X  
X    Using Microsoft C and overlays, we've managed to enable all the special
X    features.  You may include all the neat features you want.
X
X    Also check pcconf.h, which should not need much editing (if you are
X    including termcap.uu and random.c).  If you are not including these, you
X    will need to comment out TERMLIB and/or RANDOM.  You should make doubly
X    certain that OVERLAY is defined in pcconf.h, since otherwise things will
X    compile properly but very ugly things are likely to happen wherever
X    function pointers cross overlay boundaries - the linker is a little thick
X    about that.
X
X    Commenting out the #define TERMLIB in pcconf.h to disable use of termcap
X    routines (relying on the ANSI_DEFAULT feature) will make your job a bit
X    easier.  However, you can compile with both TERMLIB and ANSI_DEFAULT
X    and simply not set your TERM variable if you do not wish to use the
X    termcap file settings.
X
X6.  If you want to change the high score list behavior, examine the top of
X    topten.c, in the src directory.  You may want to change the definitions of
X    PERSMAX, POINTSMIN, and ENTRYMAX.  I set POINTSMIN to 51 and ENTRYMAX to
X    50 to keep the size of the score list down.
X
X7.  Go to the src directory and edit the top of your Makefile.  Be sure the
X    directory you want the game installed (GAMEDIR) in actually exists.
X
X    If you elected not to use the high-quality BSD random number routines by
X    commenting out RANDOM in pcconf.h or tosconf.h, comment out (or set equal
X    to nothing) the RANDOM macro in your Makefile.
X
X    If you elected to use Fred Fish's termcap library (bundled in as
X    termcap.arc), you will have to generate termlib.lib from those sources
X    by typing "make -f makefile.lib".  You must also set the TERMLIB option
X    in Makefile.ovl to link in the resulting termlib.lib.
X
X    If you have a MASM compatible Assembler, you may want to enable the option
X    in the makefile to rebuild ovlmgr.obj, although a ready-made object file 
X    is provided for those of you without.   Before assembling ovlmgr, be sure
X    to read ovlmgr.doc as there are several options that you may or may not
X    wish to enable/disable.
X    
X    If you are recompiling after patching your sources, or if you got your
X    files from somewhere other than the official distribution, "touch
X    makedefs.c" to ensure that certain files (onames.h and pm.h) are remade,
X    lest potentially troublesome timestamps fool "make".
X
X8.  Now, enter "make45l install", and take a long siesta; your computer will
X    be occupied for a long time.  If all goes well, you will get an executable.
X
X9.  Make sure the support files -- data, rumors, cmdhelp, opthelp, help, hh,
X    history, license, and oracles (if ORACLE was #define'd) -- were copied
X    to the game directory.  If not, move them there from the auxil directory
X    yourself.  rumors can be created manually by entering "makedefs -r",
X    data by entering "makedefs -d".
X
X    If you compiled in the special levels (if STRONGHOLD was #define'd), make
X    sure castle, tower?, and possibly endgame are there, too.  They can be
X    created manually by entering "lev_comp filename.des", where filename.des
X    is the appropriate description file (found in the auxil directory).
X
X    Make sure the files NetHack.cnf and termcap also made it to your game
X    directory.  If not go to the others directory and copy NetHack.cnf and
X    termcap to your game directory.  Edit NetHack.cnf to reflect your
X    particular setup and personal preferences, by following the comments.
X
X    If you'll be running NetHack from a different subdirectory, you will
X    want to "set HACKDIR=c:\games\nethack" (or whatever drive and directory 
X    you want to use) now.  Add it to your autoexec.bat (in DOS), if you'll 
X    be playing often.
X
X11. Play NetHack.  If it works, you're done!
X
X
XNotes
X-----
X1)  First and foremost:  We have been developing with MSC 5.1 as a compiler
X    and NDmake 4.5 as a make.  NDmake is readily available on the Usenet;
X    obtaining MSC might be more of a problem.  MSC 5.0 is broken.  You *will
X    not* be able to compile the overlay version with that compiler due to
X    problems with the /Gt option allowing the CONST segment to become
X    > 64k when linking.
X    MSC 6.0 and its make utility have been used to generate an overlaid
X    NetHack.exe, however sufficient testing has not been completed at this
X    time for us to "recommend" its use.
X
X2)  Save files and bones files from previous versions will not work with
X    NetHack 3.0.  Don't bother trying to keep them.  Record (score) files
X    from before 3.0 patchlevel 7 will almost work, but you need to make one
X    change manually to them:  At the end of each line is a word or phrase
X    specifying what killed the player.  Change the string to start with the
X    words "killed by", "killed by a", or "killed by an" (whichever is
X    appropriate).  If the death was petrification, it should read "petrified
X    by" instead of "killed by".  Don't change "starvation", "quit", "escaped",
X    or "ascended".
X
X3)  To install an update of NetHack after changing something, enter "make"
X    from the src directory.  If you add, delete, or reorder monsters or
X    objects, or you change the format of saved level files, delete any save
X    and bones files.  (Trying to use such files sometimes produces amusing
X    confusions on the game's part, but usually crashes.)
X
X4)  During linking the Microsoft Overlay Linker will need temporary storage
X    space.  Make sure you have about a meg of free disk wherever you have
X    defined your temporary storage.
END_OF_FILE
if test 14761 -ne `wc -c <'Install.ovl'`; then
    echo shar: \"'Install.ovl'\" unpacked with wrong size!
fi
# end of 'Install.ovl'
fi
if test -f 'src/do_name.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/do_name.c'\"
else
echo shar: Extracting \"'src/do_name.c'\" \(13564 characters\)
sed "s/^X//" >'src/do_name.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)do_name.c	3.0	89/11/08
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X
X#ifdef NAMED_ITEMS
X# include <ctype.h>
X#endif
X
X#ifdef OVLB
X
Xstatic char *FDECL(visctrl, (CHAR_P));
Xstatic void FDECL(do_oname, (struct obj *));
X
Xstatic
Xchar *
Xvisctrl(c)
Xchar c;
X{
X#ifdef LINT	/* static char ccc[3]; */
X	char ccc[3];
X#else
X	static char ccc[3];
X#endif
X
X	if(c < 040) {
X		ccc[0] = '^';
X		ccc[1] = c + 0100;
X		ccc[2] = 0;
X	} else {
X		ccc[0] = c;
X		ccc[1] = 0;
X	}
X	return(ccc);
X}
X
Xvoid
Xgetpos(cc,force,goal)
Xcoord	*cc;
Xint force;
Xconst char *goal;
X{
X	register int cx, cy, i, c;
X	const char *sdp = flags.num_pad ? ndir : sdir;
X#ifdef MACOS
X	extern short	macflags;
X	Boolean	fUpdateFlagOn;
X	long	ticks;
X#endif
X
X	if(flags.verbose) pline("(For instructions type a ?)");
X#ifdef MACOS	
X	if ((macflags & fDoUpdate) && (macflags & fDoNonKeyEvt)) {
X		fUpdateFlagOn = true;
X	} else {
X		fUpdateFlagOn = false;
X		macflags |= (fDoUpdate | fDoNonKeyEvt);
X	}
X	macflags |= fMoveWRTMouse;
X#endif
X	cx = cc->x;
X	cy = cc->y;
X#ifdef CLIPPING
X	cliparound(cx, cy);
X	(void) win_curs(cx, cy);
X#else
X	curs(cx,cy+2);
X#endif
X	while((c = readchar()) != '.'){
X		for(i=0; i<8; i++) if(sdp[i] == c){
X			if(1 <= cx + xdir[i] && cx + xdir[i] <= COLNO)
X				cx += xdir[i];
X			if(0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO-1)
X				cy += ydir[i];
X			goto nxtc;
X		}
X		if(c == '?'){
X			pline("Use [%s] to move the cursor to %s.",
X			      flags.num_pad ? "2468" : "hjkl", goal);
X			pline("Type a . when you are at the right place.");
X		} else {
X			if (!index(quitchars, c))
X			    pline("Unknown direction: '%s' (%s).",
X				visctrl(c),
X				force ?
X				    flags.num_pad ? "use 2468 or ." :
X						    "use hjkl or ." :
X				    "aborted");
X			if(force) goto nxtc;
X#ifdef MACOS
X			macflags &= ~fMoveWRTMouse;
X			if (!fUpdateFlagOn)
X				macflags &= ~(fDoUpdate | fDoNonKeyEvt);
X#endif
X			cc->x = -1;
X			cc->y = 0;
X			return;
X		}
X	nxtc:	;
X#ifdef CLIPPING
X		cliparound(cx, cy);
X		(void) win_curs(cx, cy);
X#else
X		curs(cx,cy+2);
X#endif
X	}
X#ifdef MACOS
X	macflags &= ~fMoveWRTMouse;
X	if (!fUpdateFlagOn)
X		macflags &= ~(fDoUpdate | fDoNonKeyEvt);
X#endif
X	cc->x = cx;
X	cc->y = cy;
X	return;
X}
X
Xstruct monst *
Xchristen_monst(mtmp, name)
Xstruct monst *mtmp;
Xconst char *name;
X{
X	register int lth,i;
X	register struct monst *mtmp2;
X
X	/* dogname and catname are 63-character arrays; the generic naming
X	 * function do_mname() below also cut names off at 63 characters */
X	lth = strlen(name)+1;
X	if(lth > 63){
X		lth = 63;
X	}
X	mtmp2 = newmonst(mtmp->mxlth + lth);
X	*mtmp2 = *mtmp;
X	for(i=0; i<mtmp->mxlth; i++)
X		((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
X	mtmp2->mnamelth = lth;
X	(void)strncpy(NAME(mtmp2), name, lth);
X	NAME(mtmp2)[lth-1] = 0;
X	replmon(mtmp,mtmp2);
X	return(mtmp2);
X}
X
Xint
Xdo_mname(){
X	char buf[BUFSZ];
X	coord cc;
X	register int cx,cy;
X	register struct monst *mtmp;
X	register char *curr;
X	boolean blank;
X
X	cc.x = u.ux;
X	cc.y = u.uy;
X	getpos(&cc, 0, "the monster you want to name");
X	cx = cc.x;
X	cy = cc.y;
X	if(cx < 0) return(0);
X	if (cx == u.ux && cy == u.uy) {
X		pline("This %s creature is called %s and cannot be renamed.",
X		ACURR(A_CHA) > 14 ?
X		(flags.female ? "beautiful" : "handsome") :
X		"ugly",
X		plname);
X		return(0);
X	}
X	if (!cansee(cx,cy) || !MON_AT(cx,cy) || (mtmp = m_at(cx, cy))->mimic
X		    || (mtmp->minvis && !See_invisible) || mtmp->mundetected) {
X		pline("I see no monster there.");
X		return(0);
X	}
X	pline("What do you want to call %s? ", lmonnam(mtmp));
X	getlin(buf);
X	clrlin();
X	if(!*buf || *buf == '\033') return(0);
X
X	/* unnames monster if all spaces */
X	for (curr = buf, blank = 1; *curr; blank = (*curr++ == ' '));
X	if(blank) *buf = '\0';
X
X 	if(type_is_pname(mtmp->data)) {
X 	    pline("%s doesn't like being called names!", Monnam(mtmp));
X 	    if(!mtmp->mtame) {
X 		pline("%s gets %sangry!", Monnam(mtmp),
X 		      mtmp->mpeaceful ? "" : "very ");
X 		mtmp->mpeaceful = 0;
X		mtmp->msleep = 0;
X 	    }
X 	    return(0);
X 	}
X	(void) christen_monst(mtmp, buf);
X	return(0);
X}
X
X/*
X * This routine changes the address of obj. Be careful not to call it
X * when there might be pointers around in unknown places. For now: only
X * when obj is in the inventory.
X */
Xstatic
Xvoid
Xdo_oname(obj)
Xregister struct obj *obj;
X{
X	char buf[BUFSZ];
X	register char *curr;
X	boolean blank;
X
X	pline("What do you want to name %s? ", doname(obj));
X	getlin(buf);
X	clrlin();
X	if(!*buf || *buf == '\033')	return;
X
X	/* unnames item if all spaces */
X	for (curr = buf, blank = 1; *curr; blank = (*curr++ == ' '));
X	if(blank) *buf = '\0';
X
X#ifdef NAMED_ITEMS
X	if(is_artifact(obj))
X		pline("The artifact seems to resist the attempt.");
X	else if (restr_name(obj, buf) || exist_artifact(obj, buf)) {
X		int n = rn2(strlen(buf));
X		char c1,c2;
X
X		c1 = isupper(buf[n]) ? tolower(buf[n]) : buf[n];
X		while (c1 == (c2 = 'a' + rn2('z'-'a')));
X		if (isupper(buf[n]))
X			/* islower(c2) guaranteed by generation */
X			buf[n] = toupper(c2);
X		else buf[n] = c2;
X		pline("While engraving your hand slips.");
X		more();
X		You("engrave: \"%s\".",buf);
X		(void)oname(obj, buf, 1);
X	}
X	else
X#endif
X		(void)oname(obj, buf, 1);
X}
X
Xstruct obj *
Xoname(obj, buf, ininv)
Xregister struct obj *obj;
Xconst char	*buf;
Xregister int ininv;
X{
X	register struct obj *otmp, *otmp2, *contents;
X	register int	lth;
X
X	lth = *buf ? strlen(buf)+1 : 0;
X	if(lth > 63){
X		lth = 63;
X	}
X	/* if already properly named */
X	if(lth == obj->onamelth && (!lth || !strcmp(ONAME(obj),buf)))
X		return obj;
X#ifdef NAMED_ITEMS
X	/* If named artifact exists in the game, do not create another.
X	 * Also trying to create an artifact shouldn't de-artifact
X	 * it (e.g. Excalibur from prayer). In this case the object
X	 * will retain its current name. */
X	if (is_artifact(obj) || exist_artifact(obj, buf))
X		return obj;
X	else
X		artifact_exists(obj, buf, TRUE);
X#endif
X	otmp2 = newobj(lth);
X	*otmp2 = *obj;
X	otmp2->onamelth = lth;
X#ifdef __GNUC__
X	/* Without the following line, the program gives anything an empty
X	 * name when I try to #name it.  Probably a compiler bug, but at the
X	 * point where I discovered this, there's no time to check to make
X	 * sure.
X	 */
X	if (buf) (void)donull();
X#endif
X	if(lth) {
X		(void)strncpy(ONAME(otmp2), buf, lth);
X		ONAME(otmp2)[lth-1] = 0;
X	}
X	if (obj->owornmask) {
X		/* Note: dying by burning in Hell causes problems if you
X		 * try doing this when owornmask isn't set.
X		 */
X		setworn((struct obj *)0, obj->owornmask);
X		setworn(otmp2, otmp2->owornmask);
X	}
X
X	if (ininv) {
X		/* do freeinv(obj); etc. by hand in order to preserve
X		   the position of this object in the inventory */
X		if(obj == invent) invent = otmp2;
X		else for(otmp = invent; ; otmp = otmp->nobj){
X			if(!otmp)
X				panic("oname: cannot find obj.");
X			if(otmp->nobj == obj){
X				otmp->nobj = otmp2;
X				break;
X			}
X		}
X	}
X	if (Is_container(obj)) {
X		for(contents=fcobj; contents; contents=contents->nobj)
X			if(contents->cobj==obj) contents->cobj = otmp2;
X	}
X	/* obfree(obj, otmp2);	/* now unnecessary: no pointers on bill */
X	free((genericptr_t) obj);	/* let us hope nobody else saved a pointer */
X	return otmp2;
X}
X
Xstatic const char NEARDATA callable[] = {
X	SCROLL_SYM, POTION_SYM, WAND_SYM, RING_SYM, AMULET_SYM, GEM_SYM,
X#ifdef SPELLS
X	SPBOOK_SYM,
X#endif
X	ARMOR_SYM, TOOL_SYM, 0 };
X
Xint
Xddocall()
X{
X	register struct obj *obj;
X#ifdef REDO
X	char	ch;
X
X	if (!in_doagain)
X#endif
X		pline("Name an individual object? ");
X	switch(
X#ifdef REDO
X		ch = 
X#endif
X		ynq()) {
X	case 'q':
X		break;
X	case 'y':
X#ifdef REDO
X		savech(ch);
X#endif
X		obj = getobj("#", "name");
X		if(obj) do_oname(obj);
X		break;
X	default:
X#ifdef REDO
X		savech(ch);
X#endif
X		obj = getobj(callable, "call");
X		if(obj) docall(obj);
X	}
X	return 0;
X}
X
Xvoid
Xdocall(obj)
Xregister struct obj *obj;
X{
X	char buf[BUFSZ];
X	struct obj otemp;
X	register char **str1;
X	register char *str;
X	boolean blank;
X
X	otemp = *obj;
X	otemp.quan = 1;
X	otemp.onamelth = 0;
X	if (otemp.corpsenm) { /* kludge, meaning it's sink water */
X		pline("Call a stream of %s fluid: ",
X				objects[otemp.otyp].oc_descr);
X	} else
X		pline("Call %s: ", an(xname(&otemp)));
X	getlin(buf);
X	clrlin();
X	if(!*buf || *buf == '\033')
X		return;
X
X	/* clear old name */
X	str1 = &(objects[obj->otyp].oc_uname);
X	if(*str1) free((genericptr_t)*str1);
X
X	/* uncalls item if all spaces */
X	for (str = buf, blank = 1; *str; blank = (*str++ == ' '));
X	if(blank) *buf = '\0';
X	if (!*buf) {
X		*str1 = NULL;
X		return;
X	}
X
X	str = (char *) alloc((unsigned)strlen(buf)+1);
X	Strcpy(str,buf);
X	*str1 = str;
X}
X
X#endif /*OVLB*/
X#ifdef OVL0
X
Xstatic const char *ghostnames[] = {
X	/* these names should have length < PL_NSIZ */
X	/* Capitalize the names for aesthetics -dgk */
X	"Adri", "Andries", "Andreas", "Bert", "David", "Dirk", "Emile",
X	"Frans", "Fred", "Greg", "Hether", "Jay", "John", "Jon", "Karnov",
X	"Kay", "Kenny", "Kevin", "Maud", "Michiel", "Mike", "Peter", "Robert",
X	"Ron", "Tom", "Wilmar", "Nick Danger", "Phoenix", "Havok",
X	"Stephan", "Lance Braccus", "Shadowhawk"
X};
X
Xchar *
Xx_monnam(mtmp, vb)
Xregister struct monst *mtmp;
Xint vb;
X{
X#ifdef LINT	/* static char buf[BUFSZ]; */
X	char buf[BUFSZ];
X#else
X	static char buf[BUFSZ];
X#endif
X	boolean isinvis = (mtmp->minvis && mtmp->data != &mons[PM_STALKER]
X				&& mtmp->data != &mons[PM_GHOST]);
X
X	buf[0] = '\0';
X#if defined(ALTARS) && defined(THEOLOGY)
X	if(mtmp->ispriest) return(priestname(mtmp));
X#endif
X	if(mtmp->isshk) {
X		Strcpy(buf, shkname(mtmp));
X		if (mtmp->data == &mons[PM_SHOPKEEPER] && !mtmp->minvis)
X		    return(buf);
X		/* For normal shopkeepers, just 'Asidonhopo'.
X		 * For unusual ones, 'Asidonhopo the invisible shopkeeper'
X		 * or 'Asidonhopo the blue dragon'.
X		 */
X		Strcat(buf, " ");
X	} else if(mtmp->mnamelth && !vb) {
X		if(isinvis) {
X		    Strcpy(buf, "the invisible ");
X		    Strcat(buf, NAME(mtmp));
X		} else 
X		    Strcpy(buf, NAME(mtmp));
X		return(buf);
X	}
X
X	switch(mtmp->data->mlet) {
X	    case S_GHOST:
X		{ register const char *gn = (const char *) mtmp->mextra;
X		  if(!*gn) {		/* might also look in scorefile */
X		    gn = ghostnames[rn2(SIZE(ghostnames))];
X		    Strcpy((char *) mtmp->mextra, !rn2(5) ? (const char *)plname : gn);
X		  }
X		  if (Hallucination) {
X		    Strcat(buf, "the ");
X		    Strcat(buf, rndmonnam());
X		  }
X		  else
X		    Sprintf(buf, "%s's ghost", (char *) mtmp->mextra);
X		}
X		break;
X	    default:
X		if (mtmp->minvis)
X			Strcat(buf, "the invisible ");
X		else if (!type_is_pname(mtmp->data) || Hallucination
X				|| mtmp->data == &mons[PM_WIZARD_OF_YENDOR])
X			Strcat(buf, "the ");
X		Strcat(buf, Hallucination ? rndmonnam() : mtmp->data->mname);
X	}
X	if(vb && mtmp->mnamelth) {
X		Strcat(buf, " called ");
X		Strcat(buf, NAME(mtmp));
X	}
X	return(buf);
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xchar *
Xlmonnam(mtmp)
Xregister struct monst *mtmp;
X{
X	return(x_monnam(mtmp, 1));
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xchar *
Xmon_nam(mtmp)
Xregister struct monst *mtmp;
X{
X	return(x_monnam(mtmp, 0));
X}
X
Xchar *
XMonnam(mtmp)
Xregister struct monst *mtmp;
X{
X	register char *bp = mon_nam(mtmp);
X
X	if('a' <= *bp && *bp <= 'z') *bp += ('A' - 'a');
X	return(bp);
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xchar *
Xa_monnam(mtmp,adj)
Xregister struct monst *mtmp;
Xregister const char *adj;
X{
X	register char *bp = mon_nam(mtmp);
X#ifdef LINT	/* static char buf[BUFSZ]; */
X	char buf[BUFSZ];
X#else
X	static char buf[BUFSZ];
X#endif
X
X	if(!strncmp(bp, "the ", 4)) bp += 4;
X	Sprintf(buf, "the %s %s", adj, bp);
X	return(buf);
X}
X
X/* sometimes we don't want an article in front of definite names */
X
Xchar *
Xa2_monnam(mtmp,adj)
Xregister struct monst *mtmp;
Xregister const char *adj;
X{
X	register char *bp = mon_nam(mtmp);
X#ifdef LINT	/* static char buf[BUFSZ]; */
X	char buf[BUFSZ];
X#else
X	static char buf[BUFSZ];
X#endif
X
X	if(!strncmp(bp, "the ", 4))
X		Sprintf(buf, "the %s %s", adj, bp+4);
X	else
X		Sprintf(buf, "%s %s", adj, bp);
X	return(buf);
X}
X
Xchar *
XAmonnam(mtmp, adj)
Xregister struct monst *mtmp;
Xregister const char *adj;
X{
X	register char *bp = a_monnam(mtmp,adj);
X
X	*bp = 'T';
X	return(bp);
X}
X
Xchar *
XXmonnam(mtmp)
Xregister struct monst *mtmp;
X{
X	register char *bp = Monnam(mtmp);
X
X	if(!strncmp(bp, "The ", 4) && !type_is_pname(mtmp->data)) {
X		if(index(vowels,*(bp+4))) {
X			*((++bp)+1) = 'n';
X		} else
X			bp += 2;
X		*bp = 'A';
X	}
X	return(bp);
X}
X
Xchar *
Xdefmonnam(mtmp)
Xregister struct monst *mtmp;
X{
X	register char *bp = Xmonnam(mtmp);
X
X	if (!strncmp(bp,"A ",2) || !strncmp(bp,"An ",3)) *bp = 'a';
X	return(bp);
X}
X
Xconst char *
Xrndmonnam() {  /* Random name of monster type, if hallucinating */
X	int name;
X
X	do {
X		name = rn2(PM_ARCHEOLOGIST);
X		/* archeologist: first player class */
X	} while(type_is_pname(&mons[name]) || (mons[name].geno & G_NOGEN));
X	return(mons[name].mname);
X}
X
Xconst char *pronoun_pairs[][2] = {
X	{"him", "her"}, {"Him", "Her"}, {"his", "her"}, {"His", "Her"},
X	{"he", "she"}, {"He", "She"},
X	{0, 0}
X};
X
Xchar *
Xself_pronoun(str, pronoun)
Xconst char *str;
Xconst char *pronoun;
X{
X	static char NEARDATA buf[BUFSZ];
X	register int i;
X
X	for(i=0; pronoun_pairs[i][0]; i++) {
X		if(!strncmp(pronoun, pronoun_pairs[i][0], 3)) {
X			Sprintf(buf, str, pronoun_pairs[i][flags.female]);
X			return buf;
X		}
X	}
X	impossible("never heard of pronoun %s?", pronoun);
X	Sprintf(buf, str, pronoun_pairs[i][0]);
X	return buf;
X}
X
X#ifdef REINCARNATION
Xconst char *
Xroguename() /* Name of a Rogue player */
X{
X	char *i, *opts;
X
X	if(opts = getenv("ROGUEOPTS")) {
X		for(i=opts; *i; i++)
X			if (!strncmp("name=",i,5)) {
X				char *j;
X				if (j=index(i+5,','))
X					*j = (char)0;
X				return i+5;
X			}
X	}
X	return rn2(3) ? (rn2(2) ? "Michael Toy" : "Kenneth Arnold")
X		: "Glenn Wichman";
X}
X#endif
X
X#endif /* OVLB */
END_OF_FILE
if test 13564 -ne `wc -c <'src/do_name.c'`; then
    echo shar: \"'src/do_name.c'\" unpacked with wrong size!
fi
# end of 'src/do_name.c'
fi
if test -f 'src/sp_lev.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/sp_lev.c'\"
else
echo shar: Extracting \"'src/sp_lev.c'\" \(13593 characters\)
sed "s/^X//" >'src/sp_lev.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)sp_lev.c	3.0	89/01/11
X/*	Copyright (c) 1989 by Jean-Christophe Collet */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*
X * This file contains the various functions that are related to the special
X * levels.
X * It contains also the special level loader.
X *
X */
X
X#include "hack.h"
X
X#ifdef STRONGHOLD
X#include "sp_lev.h"
X
X#if defined(MACOS) || (defined(MSDOS) && !defined(AMIGA))
X# define RDMODE "rb"
X#else
X# define RDMODE "r"
X#endif
X
X#define LEFT	1
X#define CENTER	2
X#define RIGHT	3
X#define TOP	1
X#define BOTTOM	3
X
Xstatic walk NEARDATA walklist[50];
Xextern int x_maze_max, y_maze_max;
X
X#ifdef MACOS
Xchar **Map;
X#else
Xstatic char Map[COLNO][ROWNO];
X#endif
Xstatic char robjects[10], rloc_x[10], rloc_y[10], rmonst[10],
X	ralign[3] = { A_CHAOS, A_NEUTRAL, A_LAW };
Xstatic xchar NEARDATA xstart, NEARDATA ystart, NEARDATA xsize, NEARDATA ysize;
X
Xstatic void FDECL(make_walls_nondiggable, (XCHAR_P,XCHAR_P,XCHAR_P,XCHAR_P));
Xstatic int NDECL(rnddoor);
Xstatic int NDECL(rndtrap);
Xstatic void FDECL(get_location, (schar *,schar *));
Xstatic void FDECL(shuffle, (char *,XCHAR_P));
Xstatic void FDECL(shuffle2, (char *,char *,XCHAR_P));
Xstatic boolean FDECL(load_rooms, (FILE *));
Xstatic void FDECL(maze1xy, (coord *));
Xstatic boolean FDECL(load_maze, (FILE *));
X
X/*
X * Make walls of the area (x1, y1, x2, y2) non diggable
X */
X
Xstatic void
Xmake_walls_nondiggable(x1,y1,x2,y2)
Xxchar x1, y1, x2, y2;
X{
X	register xchar x, y;
X
X	for(y = y1; y <= y2; y++)
X	    for(x = x1; x <= x2; x++)
X		if(IS_WALL(levl[x][y].typ))
X		    levl[x][y].diggable |= W_NONDIGGABLE;
X}
X
X/*
X * Choose randomly the state (nodoor, open, closed or locked) for a door
X */
X
Xstatic int
Xrnddoor()
X{
X	int i;
X	
X	i = 1 << rn2(5);
X	i >>= 1;
X	return i;
X}
X
X/* 
X * Select a random trap
X */
X
Xstatic int
Xrndtrap()
X{
X	return(rnd(TRAPNUM-1));
X}
X
X/* 
X * Coordinates in special level files are handled specially:
X *
X *	if x or y is -11, we generate a random coordinate.
X *	if x or y is between -1 and -10, we read one from the corresponding
X *	register (x0, x1, ... x9).
X *	if x or y is nonnegative, we convert it from relative to the local map
X *	to global coordinates.
X */
X
Xstatic void
Xget_location(x, y)
Xschar *x, *y;
X{
X	int cpt = 0;
X
X	if (*x >= 0) {			/* normal locations */
X		*x += xstart;
X		*y += ystart;
X	} else if (*x > -11) {		/* special locations */
X		*y = ystart + rloc_y[ - *y - 1];
X		*x = xstart + rloc_x[ - *x - 1];
X	} else {			/* random location */
X		do {
X		    *x = xstart + rn2((int)xsize);
X		    *y = ystart + rn2((int)ysize);
X		} while (cpt < 100 &&
X			 levl[*x][*y].typ != ROOM &&
X			 levl[*x][*y].typ != CORR);
X		if(cpt >= 100)
X		    panic("get_location: can't find a place!");
X	}
X
X	if (*x < 0 || *x > x_maze_max || *y < 0 || *y > y_maze_max) {
X	    impossible("get_location: (%d,%d) out of bounds", *x, *y);
X	    *x = x_maze_max; *y = y_maze_max;
X	}
X}
X
X/*
X * Shuffle the registers for locations, objects or monsters
X */
X
Xstatic void
Xshuffle(list, n)
Xchar list[];
Xxchar n;
X{
X	int i, j;
X	char k;
X
X	for(i = n-1; i; i--) {
X		j = rn2(i);
X
X		k = list[j];
X		list[j] = list[i];
X		list[i] = k;
X	}
X}
X
X/* 
X * Shuffle two arrays in the same order (for rloc_x & rloc_y)
X */
X
Xstatic void
Xshuffle2(list1, list2, n)
Xchar list1[], list2[];
Xxchar n;
X{
X	int i, j;
X	char k1, k2;
X
X	for(i = n-1; i; i--) {
X		j = rn2(i);
X
X		k1 = list1[j];
X		k2 = list2[j];
X
X		list1[j] = list1[i];
X		list2[j] = list2[i];
X
X		list1[i] = k1;
X		list2[i] = k2;
X	}
X}
X
X/* 
X * NOT YET IMPLEMENTED!!!
X */
X
Xstatic boolean
Xload_rooms(fd)
XFILE *fd;
X{
X	return FALSE;
X}
X
X/*
X * Select a random coordinate in the maze.
X *
X * We want a place not 'touched' by the loader.  That is, a place in
X * the maze outside every part of the special level.
X */
X
Xstatic void
Xmaze1xy(m)
Xcoord *m;
X{
X	do {
X		m->x = rn1(x_maze_max - 3, 3);
X		m->y = rn1(y_maze_max - 3, 3);
X	} while (!(m->x % 2) || !(m->y % 2) || Map[m->x][m->y]);
X}
X
X/* 
X * The Big Thing: special maze loader
X *
X * Could be cleaner, but it works.
X */
X
Xstatic boolean
Xload_maze(fd)
XFILE *fd;
X{
X    xchar   x, y, n, typ;
X    char    c;
X
X    xchar   numpart = 0, nwalk = 0;
X    uchar   halign, valign;
X
X    int     xi, yi, dir;
X    coord   mm;
X    int     mapcount, mapcountmax, mapfact;
X
X    region  tmpregion;
X    door    tmpdoor;
X    trap    tmptrap;
X    monster tmpmons;
X    object  tmpobj;
X    drawbridge tmpdb;
X    walk    tmpwalk;
X    digpos  tmpdig;
X    lad     tmplad;
X#ifdef ALTARS
X    altar   tmpaltar;
X#endif
X
X    /* shuffle alignments */
X    shuffle(ralign,3);
X
X    /* Initialize map */
X    xupstair = yupstair = xdnstair = ydnstair = doorindex = 0;
X    for(x = 2; x <= x_maze_max; x++)
X	for(y = 2; y <= y_maze_max; y++) {
X#ifndef WALLIFIED_MAZE
X	    levl[x][y].typ = STONE;
X#else
X	    levl[x][y].typ = ((x % 2) && (y % 2)) ? STONE : HWALL;
X#endif
X	    Map[x][y] = 0;
X	}
X
X    /* Start reading the file */
X    numpart = fgetc(fd); /* Number of parts */
X    if (!numpart || numpart > 9)
X	panic("load_maze error: numpart = %d", (int) numpart);
X
X    while (numpart--) {
X	halign = fgetc(fd); /* Horizontal alignment */
X	valign = fgetc(fd); /* Vertical alignment */
X	xsize  = fgetc(fd); /* size in X */
X	ysize  = fgetc(fd); /* size in Y */
X
X	switch((int) halign) {
X	    case LEFT:	    xstart = 3; 				break;
X	    case CENTER:    xstart = 2+((x_maze_max-2-xsize)/2);	break;
X	    case RIGHT:     xstart = x_maze_max-xsize-1;		break;
X	}
X	switch((int) valign) {
X	    case TOP:	    ystart = 3; 				break;
X	    case CENTER:    ystart = 2+((y_maze_max-2-ysize)/2);	break;
X	    case BOTTOM:    ystart = y_maze_max-ysize-1;		break;
X	}
X	if (!(xstart % 2)) xstart++;
X	if (!(ystart % 2)) ystart++;
X
X	/* Load the map */
X	for(y = ystart; y < ystart+ysize; y++)
X	    for(x = xstart; x < xstart+xsize; x++) {
X		levl[x][y].typ = fgetc(fd);
X		initsym(x,y);
X		/* secret doors default closed */
X		if (levl[x][y].typ == SDOOR)
X		  levl[x][y].doormask = D_CLOSED;
X		Map[x][y] = 1;
X	    }
X
X	n = fgetc(fd); /* Random objects */
X	if(n) {
X		(void) fread((genericptr_t)robjects, 1, (int) n, fd);
X		shuffle(robjects, n);
X	}
X
X	n = fgetc(fd); /* Random locations */
X	if(n) {
X		(void) fread((genericptr_t)rloc_x, 1, (int) n, fd);
X		(void) fread((genericptr_t)rloc_y, 1, (int) n, fd);
X		shuffle2(rloc_x, rloc_y, n);
X	}
X
X	n = fgetc(fd); /* Random monsters */
X	if(n) {
X		(void) fread((genericptr_t)rmonst, 1, (int) n, fd);
X		shuffle(rmonst, n);
X	}
X
X	n = fgetc(fd); /* Number of subrooms */
X	while(n--) {
X		(void) fread((genericptr_t)&tmpregion, sizeof(tmpregion), 1, fd);
X		if (nroom >= MAXNROFROOMS) continue;
X
X		get_location(&tmpregion.x1, &tmpregion.y1);
X		get_location(&tmpregion.x2, &tmpregion.y2);
X
X		rooms[nroom].lx = tmpregion.x1;
X		rooms[nroom].ly = tmpregion.y1;
X		rooms[nroom].hx = tmpregion.x2;
X		rooms[nroom].hy = tmpregion.y2;
X		rooms[nroom].rtype = tmpregion.rtype;
X		rooms[nroom].rlit = tmpregion.rlit;
X		if (tmpregion.rlit == 1)
X			for(x = rooms[nroom].lx-1; x <= rooms[nroom].hx+1; x++)
X				for(y = rooms[nroom].ly-1; y <= rooms[nroom].hy+1; y++)
X					levl[x][y].lit = 1;
X
X		rooms[nroom].fdoor = rooms[nroom].doorct = 0;
X
X		++nroom;
X		rooms[nroom].hx = -1;
X	}
X
X	n = fgetc(fd); /* Number of doors */
X	while(n--) {
X		struct mkroom *croom = &rooms[0], *broom;
X		int tmp;
X
X		(void) fread((genericptr_t)&tmpdoor, sizeof(tmpdoor), 1, fd);
X
X		x = tmpdoor.x;	y = tmpdoor.y;
X		typ = tmpdoor.mask == -1 ? rnddoor() : tmpdoor.mask;
X
X		get_location(&x, &y);
X		levl[x][y].doormask = typ;
X		mnewsym(x,y);
X
X		/* Now the complicated part, list it with each subroom */
X		/* The dog move and mail daemon routines use this */
X		while(croom->hx >= 0 && doorindex < DOORMAX) {
X		    if(croom->hx >= x-1 && croom->lx <= x+1 &&
X		       croom->hy >= y-1 && croom->ly <= y+1) {
X			/* Found it */
X			croom->doorct++;
X
X			/* Append or insert into doors[] */
X			broom = croom+1;
X			if(broom->hx < 0) tmp = doorindex;
X			else
X			    for(tmp = doorindex; tmp > broom->fdoor; tmp--)
X				doors[tmp] = doors[tmp-1];
X
X			doors[tmp].x = x;
X			doors[tmp].y = y;
X			doorindex++;
X
X			for( ; broom->hx >= 0; broom++) broom->fdoor++;
X		    }
X		    croom++;
X		}
X	}
X
X	n = fgetc(fd); /* Number of traps */
X	while(n--) {
X		(void) fread((genericptr_t)&tmptrap, sizeof(tmptrap), 1, fd);
X
X		x = tmptrap.x;	y = tmptrap.y;
X		typ = (tmptrap.type == -1 ? rndtrap() : tmptrap.type);
X
X		get_location(&x, &y);
X		(void) maketrap(x, y, typ);
X	}
X
X	n = fgetc(fd);	/* Number of monsters */
X	while(n--) {
X		(void) fread((genericptr_t)&tmpmons, sizeof(tmpmons), 1, fd);
X
X		x = tmpmons.x;	y = tmpmons.y;
X		get_location(&x, &y);
X
X		if	(tmpmons.class >= 0)
X			c = tmpmons.class;
X		else if (tmpmons.class > -11)
X			c = rmonst[-tmpmons.class - 1];
X		else
X			c = 0;
X
X		if (!c)
X			(void) makemon((struct permonst *) 0, x, y);
X		else if (tmpmons.id != -1)
X			(void) makemon(&mons[tmpmons.id], x, y);
X		else
X			(void) makemon(mkclass(c), x, y);
X	}
X
X	n = fgetc(fd); /* Number of objects */
X	while(n--) {
X		(void) fread((genericptr_t) &tmpobj, sizeof(object),1, fd);
X
X		x = tmpobj.x;  y = tmpobj.y;
X		get_location(&x, &y);
X
X		if	(tmpobj.class >= 0)
X			c = tmpobj.class;
X		else if (tmpobj.class > -11)
X			c = robjects[-tmpobj.class - 1];
X		else
X			c = 0;
X
X		if (!c)
X			(void) mkobj_at(0, x, y, TRUE);
X		else if (tmpobj.id != -1)
X			(void) mksobj_at(tmpobj.id, x, y);
X		else
X			(void) mkobj_at(c, x, y, TRUE);
X	}
X
X	n = fgetc(fd); /* Number of drawbridges */
X	while(n--) {
X		(void) fread((genericptr_t)&tmpdb, sizeof(tmpdb), 1, fd);
X
X		x = tmpdb.x;  y = tmpdb.y;
X		get_location(&x, &y);
X
X		if (!create_drawbridge(x, y, tmpdb.dir, tmpdb.open))
X		    impossible("Cannot create drawbridge.");
X	}
X
X	n = fgetc(fd); /* Number of mazewalks */
X	while(n--) {
X		(void) fread((genericptr_t)&tmpwalk, sizeof(tmpwalk), 1, fd);
X
X		get_location(&tmpwalk.x, &tmpwalk.y);
X
X		walklist[nwalk++] = tmpwalk;
X	}
X
X	n = fgetc(fd); /* Number of non_diggables */
X	while(n--) {
X		(void) fread((genericptr_t)&tmpdig, sizeof(tmpdig), 1, fd);
X
X		get_location(&tmpdig.x1, &tmpdig.y1);
X		get_location(&tmpdig.x2, &tmpdig.y2);
X
X		make_walls_nondiggable(tmpdig.x1, tmpdig.y1,
X				       tmpdig.x2, tmpdig.y2);
X	}
X
X	n = fgetc(fd); /* Number of ladders */
X	while(n--) {
X		(void) fread((genericptr_t)&tmplad, sizeof(tmplad), 1, fd);
X
X		x = tmplad.x;  y = tmplad.y;
X		get_location(&x, &y);
X
X		levl[x][y].typ = LADDER;
X		if (tmplad.up == 1) {
X			xupladder = x;	yupladder = y;
X			levl[x][y].ladder = LA_UP;
X		} else {
X			xdnladder = x;	ydnladder = y;
X			levl[x][y].ladder = LA_DOWN;
X		}
X	}
X
X#ifdef ALTARS
X	n = fgetc(fd); /* Number of altars */
X	while(n--) {
X		(void) fread((genericptr_t)&tmpaltar, sizeof(tmpaltar), 1, fd);
X
X		x = tmpaltar.x;  y = tmpaltar.y;
X		get_location(&x, &y);
X
X		typ = tmpaltar.align == -11 ? rn2(3) :
X		      (tmpaltar.align < 0    ? ralign[-tmpaltar.align-1] :
X					      tmpaltar.align);
X		if (tmpaltar.shrine)
X		    typ |= A_SHRINE;
X
X		levl[x][y].typ = ALTAR;
X		levl[x][y].altarmask = typ;
X	}
X#endif /* ALTARS /**/
X    }
X
X    while(nwalk--) {
X	    xi = walklist[nwalk].x;
X	    yi = walklist[nwalk].y;
X	    dir = walklist[nwalk].dir;
X
X	    move(&xi, &yi, dir);
X	    x = xi;
X	    y = yi;
X
X#ifndef WALLIFIED_MAZE
X	    levl[x][y].typ = CORR;
X#else
X	    levl[x][y].typ = ROOM;
X#endif
X
X	    /*
X	     * We must be sure that the parity of the coordinates for
X	     * walkfrom() is odd.  But we must also take into account
X	     * what direction was chosen.
X	     */
X	    if(!(x % 2))
X		if (dir == W_EAST)
X		    x++;
X		else
X		    x--;
X
X#ifndef WALLIFIED_MAZE
X	    levl[x][y].typ = CORR;
X#else
X	    levl[x][y].typ = ROOM;
X#endif
X
X	    if (!(y % 2))
X		if (dir == W_SOUTH)
X		    y++;
X		else
X		    y--;
X
X	    walkfrom(x, y);
X    }
X    wallification(2, 2, x_maze_max, y_maze_max, TRUE);
X
X    /*
X     * If there's a significant portion of maze unused by the special level,
X     * we don't want it empty.
X     *
X     * Makes the number of traps, monsters, etc. proportional
X     * to the size of the maze.
X     */
X    mapcountmax = mapcount = (x_maze_max - 2) * (y_maze_max - 2);
X
X    for(x = 2; x < x_maze_max; x++)
X	for(y = 2; y < y_maze_max; y++)
X	    if(Map[x][y]) mapcount--;
X
X    if (mapcount > (int) (mapcountmax / 10)) {
X	    mapfact = (int) ((mapcount * 100L) / mapcountmax);
X	    for(x = rnd((int) (20 * mapfact) / 100); x; x--) {
X		    maze1xy(&mm);
X		    (void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y, TRUE);
X	    }
X	    for(x = rnd((int) (12 * mapfact) / 100); x; x--) {
X		    maze1xy(&mm);
X		    (void) mksobj_at(BOULDER, mm.x, mm.y);
X	    }
X	    maze1xy(&mm);
X	    (void) makemon(&mons[PM_MINOTAUR], mm.x, mm.y);
X	    for(x = rnd((int) (12 * mapfact) / 100); x; x--) {
X		    maze1xy(&mm);
X		    (void) makemon((struct permonst *) 0, mm.x, mm.y);
X	    }
X	    for(x = rn2((int) (15 * mapfact) / 100); x; x--) {
X		    maze1xy(&mm);
X		    mkgold(0L,mm.x,mm.y);
X	    }
X	    for(x = rn2((int) (15 * mapfact) / 100); x; x--) {
X		    maze1xy(&mm);
X		    (void) maketrap(mm.x, mm.y,rndtrap());
X	    }
X    }
X    return TRUE;
X}
X
X/*
X * General loader
X */
X
Xboolean
Xload_special(name)
Xconst char *name;
X{
X	FILE *fd;
X	boolean result;
X	schar c;
X
X#ifdef OS2_CODEVIEW
X	{
X	char tmp[PATHLEN];
X
X	Strcpy(tmp,hackdir);
X	append_slash(tmp);
X	Strcat(tmp,name);
X	fd = fopen(tmp, RDMODE);
X#else
X	fd = fopen(name, RDMODE);
X# ifdef MACOS
X	if (!fd)
X		fd = openFile(name, RDMODE);
X# endif
X#endif
X#ifdef OS2_CODEVIEW
X	}
X#endif
X	if (!fd) return FALSE;
X
X	if ((c = fgetc(fd)) == EOF) {
X		(void)fclose(fd);
X		return FALSE;
X	}
X
X	switch (c) {
X		case 1: 	/* Alas, this is not yet implemented. */
X		    result = load_rooms(fd);
X		    break;
X		case 2: 	/* But this is implemented :-) */
X		    result = load_maze(fd);
X		    break;
X		default:	/* ??? */
X		    result = FALSE;
X	}
X	(void)fclose(fd);
X	return result;
X}
X#endif /* STRONGHOLD /**/
END_OF_FILE
if test 13593 -ne `wc -c <'src/sp_lev.c'`; then
    echo shar: \"'src/sp_lev.c'\" unpacked with wrong size!
fi
# end of 'src/sp_lev.c'
fi
echo shar: End of archive 42 \(of 56\).
cp /dev/null ark42isdone
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