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