billr@saab.CNA.TEK.COM (Bill Randle) (07/25/89)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu> Posting-number: Volume 7, Issue 87 Archive-name: NetHack3/Part32 #! /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 32 (of 38)." # Contents: auxil/castle.des include/config.h include/objclass.h # src/bones.c src/rumors.c src/unixunix.c src/vault.c src/wizard.c # Wrapped by billr@saab on Sun Jul 23 21:33:17 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'auxil/castle.des' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'auxil/castle.des'\" else echo shar: Extracting \"'auxil/castle.des'\" \(7219 characters\) sed "s/^X//" >'auxil/castle.des' <<'END_OF_FILE' X# SCCS Id: @(#)castle.des 3.0 89/07/02 X# Copyright (c) 1989 by Jean-Christophe Collet X# NetHack may be freely redistributed. See license for details. X# X# This is the stronghold level : X# there are several ways to enter it : X# - opening the drawbridge (wand of opening, knock spell, playing X# the appropriate tune) X# X# - enter via the back entry (this suppose a ring of levitation, boots X# of water walking, etc.) X# X# Note : If you don't play the right tune, you get indications like in the X# MasterMind game... X# X# To motivate the player : there are 4 storerooms (armors, weapons, food and X# gems) and a wand of wishing in one of the 4 towers... X XMAZE:"castle" XGEOMETRY:center,center XMAP X}}}}}}}}} }}}}}}}}} X}-------}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}-------} X}| |-----------------------------------------------| |} X}| + + |} X}-------------------------------+-----------------------------} X}}}}}}| | + | S S |}}}}}} X }| | | | | | |} X }| ------------ ---------S---------} X }| { + + \ S + X }| ------------ ---------S---------} X }| | | | | | |} X}}}}}}| | + | S S |}}}}}} X}-------------------------------+-----------------------------} X}| + + |} X}| |-----------------------------------------------| |} X}-------}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}}-------} X}}}}}}}}} }}}}}}}}} XENDMAP X# Random registers initialisation XRANDOM_OBJECTS:'[',')','*','%' XRANDOM_PLACES:(04,02),(58,02),(04,14),(58,14) XRANDOM_MONSTERS:'l','n','E','H','M','O','R','T','X','Z' X# Doors XDOOR:closed,(07,03) XDOOR:closed,(55,03) XDOOR:locked,(32,04) XDOOR:locked,(26,05) XDOOR:locked,(46,05) XDOOR:locked,(48,05) XDOOR:locked,(47,07) XDOOR:closed,(15,08) XDOOR:closed,(26,08) XDOOR:locked,(38,08) XDOOR:locked,(56,08) XDOOR:locked,(47,09) XDOOR:locked,(26,11) XDOOR:locked,(46,11) XDOOR:locked,(48,11) XDOOR:locked,(32,12) XDOOR:closed,(07,13) XDOOR:closed,(55,13) X# The drawbridge XDRAWBRIDGE:(05,08),east,closed X# Storeroom number 1 XOBJECT:object[0],random,(39,05) XOBJECT:object[0],random,(40,05) XOBJECT:object[0],random,(41,05) XOBJECT:object[0],random,(42,05) XOBJECT:object[0],random,(43,05) XOBJECT:object[0],random,(44,05) XOBJECT:object[0],random,(45,05) XOBJECT:object[0],random,(39,06) XOBJECT:object[0],random,(40,06) XOBJECT:object[0],random,(41,06) XOBJECT:object[0],random,(42,06) XOBJECT:object[0],random,(43,06) XOBJECT:object[0],random,(44,06) XOBJECT:object[0],random,(45,06) X# Storeroom number 2 XOBJECT:object[1],random,(49,05) XOBJECT:object[1],random,(50,05) XOBJECT:object[1],random,(51,05) XOBJECT:object[1],random,(52,05) XOBJECT:object[1],random,(53,05) XOBJECT:object[1],random,(54,05) XOBJECT:object[1],random,(55,05) XOBJECT:object[1],random,(49,06) XOBJECT:object[1],random,(50,06) XOBJECT:object[1],random,(51,06) XOBJECT:object[1],random,(52,06) XOBJECT:object[1],random,(53,06) XOBJECT:object[1],random,(54,06) XOBJECT:object[1],random,(55,06) X# Storeroom number 3 XOBJECT:object[2],random,(39,10) XOBJECT:object[2],random,(40,10) XOBJECT:object[2],random,(41,10) XOBJECT:object[2],random,(42,10) XOBJECT:object[2],random,(43,10) XOBJECT:object[2],random,(44,10) XOBJECT:object[2],random,(45,10) XOBJECT:object[2],random,(39,11) XOBJECT:object[2],random,(40,11) XOBJECT:object[2],random,(41,11) XOBJECT:object[2],random,(42,11) XOBJECT:object[2],random,(43,11) XOBJECT:object[2],random,(44,11) XOBJECT:object[2],random,(45,11) X# Storeroom number 4 XOBJECT:object[3],random,(49,10) XOBJECT:object[3],random,(50,10) XOBJECT:object[3],random,(51,10) XOBJECT:object[3],random,(52,10) XOBJECT:object[3],random,(53,10) XOBJECT:object[3],random,(54,10) XOBJECT:object[3],random,(55,10) XOBJECT:object[3],random,(49,11) XOBJECT:object[3],random,(50,11) XOBJECT:object[3],random,(51,11) XOBJECT:object[3],random,(52,11) XOBJECT:object[3],random,(53,11) XOBJECT:object[3],random,(54,11) XOBJECT:object[3],random,(55,11) X# THE WAND OF WISHING in 1 of the 4 towers XOBJECT:'/',"wishing",place[0] X# The treasure of the lord XOBJECT:'(',"chest",(37,08) X# Traps XTRAP:"trapdoor",(40,08) XTRAP:"trapdoor",(44,08) XTRAP:"trapdoor",(48,08) XTRAP:"trapdoor",(52,08) XTRAP:"trapdoor",(55,08) X# Soldiers guarding the entry hall XMONSTER:'@',"soldier",(08,06) XMONSTER:'@',"soldier",(09,05) XMONSTER:'@',"soldier",(11,05) XMONSTER:'@',"soldier",(12,06) XMONSTER:'@',"soldier",(08,10) XMONSTER:'@',"soldier",(09,11) XMONSTER:'@',"soldier",(11,11) XMONSTER:'@',"soldier",(12,10) XMONSTER:'@',"lieutenant",(09,08) X# Soldiers guarding the towers XMONSTER:'@',"soldier",(03,02) XMONSTER:'@',"soldier",(05,02) XMONSTER:'@',"soldier",(57,02) XMONSTER:'@',"soldier",(59,02) XMONSTER:'@',"soldier",(03,14) XMONSTER:'@',"soldier",(05,14) XMONSTER:'@',"soldier",(57,14) XMONSTER:'@',"soldier",(59,14) X# The four dragons that are guarding the storerooms XMONSTER:'D',random,(47,05) XMONSTER:'D',random,(47,06) XMONSTER:'D',random,(47,10) XMONSTER:'D',random,(47,11) X# Eels in the moat XMONSTER:';',"giant eel",(05,07) XMONSTER:';',"giant eel",(05,09) XMONSTER:';',"giant eel",(57,07) XMONSTER:';',"giant eel",(57,09) X# The throne room and the court monsters XMONSTER:monster[0],random,(27,05) XMONSTER:monster[1],random,(30,05) XMONSTER:monster[2],random,(33,05) XMONSTER:monster[3],random,(36,05) XMONSTER:monster[4],random,(28,06) XMONSTER:monster[5],random,(31,06) XMONSTER:monster[6],random,(34,06) XMONSTER:monster[7],random,(37,06) XMONSTER:monster[8],random,(27,07) XMONSTER:monster[9],random,(30,07) XMONSTER:monster[0],random,(33,07) XMONSTER:monster[1],random,(36,07) XMONSTER:monster[2],random,(28,08) XMONSTER:monster[3],random,(31,08) XMONSTER:monster[4],random,(34,08) XMONSTER:monster[5],random,(27,09) XMONSTER:monster[6],random,(30,09) XMONSTER:monster[7],random,(33,09) XMONSTER:monster[8],random,(36,09) XMONSTER:monster[9],random,(28,10) XMONSTER:monster[0],random,(31,10) XMONSTER:monster[1],random,(34,10) XMONSTER:monster[2],random,(37,10) XMONSTER:monster[3],random,(27,11) XMONSTER:monster[4],random,(30,11) XMONSTER:monster[5],random,(33,11) XMONSTER:monster[6],random,(36,11) X# MazeWalks XMAZEWALK:(00,10),west XMAZEWALK:(62,06),east X# Non diggable walls XNON_DIGGABLE:(00,00,62,16) X# Subrooms: X# Throne room XREGION:(27,05,37,11),lit,"throne" X# Antechamber XREGION:(07,05,14,11),lit,"ordinary" X# Storerooms XREGION:(39,05,45,06),lit,"ordinary" XREGION:(39,10,45,11),lit,"ordinary" XREGION:(49,05,55,06),lit,"ordinary" XREGION:(49,10,55,11),lit,"ordinary" X# Corners XREGION:(02,02,06,03),lit,"ordinary" XREGION:(56,02,60,03),lit,"ordinary" XREGION:(02,13,06,14),lit,"ordinary" XREGION:(56,13,60,14),lit,"ordinary" X# Barracks XREGION:(16,05,25,06),lit,"ordinary" XREGION:(16,10,25,11),lit,"ordinary" X# Outside XREGION:(00,05,05,11),lit,"ordinary" XREGION:(57,05,62,11),lit,"ordinary" X# Hallways X#REGION:(08,03,54,03),unlit,"ordinary" X#REGION:(08,13,54,13),unlit,"ordinary" X#REGION:(16,08,25,08),unlit,"ordinary" X#REGION:(39,08,55,08),unlit,"ordinary" END_OF_FILE if test 7219 -ne `wc -c <'auxil/castle.des'`; then echo shar: \"'auxil/castle.des'\" unpacked with wrong size! fi # end of 'auxil/castle.des' fi if test -f 'include/config.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'include/config.h'\" else echo shar: Extracting \"'include/config.h'\" \(6527 characters\) sed "s/^X//" >'include/config.h' <<'END_OF_FILE' X/* SCCS Id: @(#)config.h 3.0 89/06/23 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#ifndef CONFIG_H /* make sure the compiler does not see the typedefs twice */ X#define CONFIG_H X X X/* X * Section 1: OS selection. X * Select the version of the OS you are using. X * For "UNIX" select either SYSV or BSD in unixconf.h X */ X X#define UNIX /* delete if no fork(), exec() available */ X X#ifdef __MSDOS__ /* Turbo C auto-defines __MSDOS__, others MSDOS */ X#define MSDOS /* define for MS-DOS (actually defined by compiler) */ X#else X/* # define MSDOS /* define for MS-DOS and most other micros */ X/* # define AMIGA /* define for Commodore-Amiga */ X/* #define TOS /* for Atari 520/1040 */ X X/* #define STUPID /* avoid some complicated expressions if X your C compiler chokes on them */ X/* #define STUPID_CPP /* use many small functions instead of macros to X avoid overloading limited preprocessors */ X/* #define TERMINFO /* uses terminfo rather than termcap */ X /* should be defined for most, but not all, SYSV */ X/* #define MINIMAL_TERM /* if a terminal handles highlighting or tabs poorly, X try this define, used in pager.c and termcap.c */ X#endif X X X X/* X * Section 2: Some global parameters and filenames. X * Commenting out WIZARD, LOGFILE, or NEWS removes that feature X * from the game; otherwise set the appropriate wizard name. X * LOGFILE and NEWS refer to files in the playground. X */ X X#ifndef WIZARD /* allow for compile-time or Makefile changes */ X#define WIZARD "izchak" /* the person allowed to use the -D option */ X#endif X X#define LOGFILE "logfile" /* larger file for debugging purposes */ X#define NEWS "news" /* the file containing the latest hack news */ X X X#define CHDIR /* delete if no chdir() available */ X X#ifdef CHDIR X/* X * If you define HACKDIR, then this will be the default playground; X * otherwise it will be the current directory. X */ X#define HACKDIR "/usr/games/lib/nethackdir" X X/* X * Some system administrators are stupid enough to make Hack suid root X * or suid daemon, where daemon has other powers besides that of reading or X * writing Hack files. In such cases one should be careful with chdir's X * since the user might create files in a directory of his choice. X * Of course SECURE is meaningful only if HACKDIR is defined. X */ X/* #define SECURE /* do setuid(getuid()) after chdir() */ X X/* X * If it is desirable to limit the number of people that can play Hack X * simultaneously, define HACKDIR, SECURE and MAX_NR_OF_PLAYERS. X * #define MAX_NR_OF_PLAYERS 6 X */ X#endif /* CHDIR /**/ X X X X/* X * Section 3: Definitions that may vary with system type. X * For example, both schar and uchar should be short ints on X * the AT&T 3B2/3B5/etc. family. X */ X X/* X * Uncomment the following line if your compiler doesn't understand the X * 'void' type (and thus would give all sorts of compile errors without X * this definition). X */ X/* #define void int /* define if no "void" data type. */ X X#include "tradstdc.h" X X/* X * type schar: small signed integers (8 bits suffice) (eg. TOS) X * X * typedef char schar; X * X * will do when you have signed characters; otherwise use X * X * typedef short int schar; X */ Xtypedef signed char schar; X X/* X * type uchar: small unsigned integers (8 bits suffice - but 7 bits do not) X * X * typedef unsigned char uchar; X * X * will be satisfactory if you have an "unsigned char" type; X * otherwise use X * X * typedef unsigned short int uchar; X */ Xtypedef unsigned char uchar; X X/* X * Various structures have the option of using bitfields to save space. X * If your C compiler handles bitfields well (e.g., it can initialize structs X * containing bitfields), you can define BITFIELDS. Otherwise, the game will X * allocate a separate character for each bitfield. (The bitfields used never X * have more than 7 bits, and most are only 1 bit.) X */ X#define BITFIELDS /* Good bitfield handling */ X X X X/* X * Section 4: THE FUN STUFF!!! X * X * Conditional compilation of special options are controlled here. X * If you define the following flags, you will add not only to the X * complexity of the game but also to the size of the load module. X */ X X#define SPELLS /* Spell casting by M. Stephenson */ X#define POLYSELF /* Polymorph self code by Ken Arromdee */ X#define THRONES /* Thrones and Courts by M. Stephenson */ X#define PROBING /* Wand of probing code by Gil Neiger */ X#define REDO /* support for redoing last command - DGK */ X#define HARD /* Enhanced wizard code by M. Stephenson */ X#define WALKIES /* Leash code by M. Stephenson */ X#define FOUNTAINS /* Fountain code by SRT (+ GAN + EB) */ X#define KOPS /* Keystone Kops by Scott R. Turner */ X#define COM_COMPL /* Command line completion by John S. Bien */ X#define MEDUSA /* Mirrors and the Medusa by Richard P. Hughey */ X#define NAMED_ITEMS /* Special named items handling */ X#define ARMY /* Soldiers, barracks by Steve Creps */ X#define SHIRT /* Hawaiian shirt code by Steve Linhart */ X#define THEOLOGY /* Smarter gods - The Unknown Hacker */ X#define SINKS /* Kitchen sinks - Janet Walz */ X#define COMPRESS "/usr/local/compress" /* the location of 'compress' */ X /* Compressed bones / save files - Izchak Miller */ X/* #define ZEROCOMP /* Zero-run compression of files - Olaf Seibert */ X /* Use only if COMPRESS is not used */ X#define SOUNDS /* Add more life to the dungeon */ X#define REINCARNATION /* Rogue-like levels */ X#define ELBERETH /* Allow for disabling the E word - Mike 3point */ X#define WORM /* Long worms */ X#define ORACLE /* Include another source of information */ X#define EXPLORE_MODE /* Allow non-scoring play with additional powers */ X#define ALTARS /* Sacrifice sites - Jean-Christophe Collet */ X#define WALLIFIED_MAZE /* Fancy mazes - Jean-Christophe Collet */ X#ifdef HARD X#define SEDUCE /* Succubi/incubi additions, by KAA, suggested by IM */ X#endif X#define STRONGHOLD /* Challenging special levels - Jean-Christophe Collet*/ X#define MUSIC /* Musical instruments - Jean-Christophe Collet */ X#define GOLEMS /* Golems, by KAA */ X#define TOLKIEN /* More varieties of objects and monsters */ X#define KICK /* Allow kicking things besides doors -Izchak Miller */ X X#ifdef REDO X#define DOAGAIN '\001' /* The "redo" key Used in tty.c and cmd.c */ X#endif X X#define EXP_ON_BOTL /* Show experience on bottom line */ X/* #define SCORE_ON_BOTL /* added by Gary Erickson (erickson@ucivax) */ X X X X#include "global.h" /* Define everything else according to choices above */ X X#endif /* CONFIG_H /**/ END_OF_FILE if test 6527 -ne `wc -c <'include/config.h'`; then echo shar: \"'include/config.h'\" unpacked with wrong size! fi # end of 'include/config.h' fi if test -f 'include/objclass.h' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'include/objclass.h'\" else echo shar: Extracting \"'include/objclass.h'\" \(2613 characters\) sed "s/^X//" >'include/objclass.h' <<'END_OF_FILE' X/* SCCS Id: @(#)objclass.h 3.0 89/01/10 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#ifndef OBJCLASS_H X#define OBJCLASS_H X X/* definition of a class of objects */ X Xstruct objclass { X char *oc_name; /* actual name */ X char *oc_descr; /* description when name unknown */ X char *oc_uname; /* called by user */ X Bitfield(oc_name_known,1); X Bitfield(oc_merge,1); /* merge otherwise equal objects */ X Bitfield(oc_bool,1); X#define oc_bimanual oc_bool /* for weapons */ X#define oc_bulky oc_bool /* for armor */ X#define oc_charged oc_bool /* for rings & tools: allow +n or (n) */ X Bitfield(oc_material,4); X#define GLASS 1 X#define WOOD 2 X#define METAL 4 X#define MINERAL 8 X uchar oc_oprop; /* property (invis, &c.) conveyed */ X char oc_olet; X int oc_prob; /* probability for mkobj() */ X schar oc_delay; /* delay when using such an object */ X uchar oc_weight; X int oc_cost; /* base cost in shops */ X schar oc_oc1, oc_oc2; X int oc_oi; X#define nutrition oc_oi /* for foods */ X#define w_propellor oc_oi /* for weapons */ X#define WP_BOW 1 X#define WP_SLING 2 X#define WP_CROSSBOW 3 X#define a_ac oc_oc1 /* for armors - only used in ARM_BONUS */ X#define ARM_BONUS(obj) ((10 - objects[obj->otyp].a_ac) + obj->spe) X#define a_can oc_oc2 /* for armors */ X#define bits oc_oc1 /* for wands */ X /* wands */ X#define NODIR 1 X#define IMMEDIATE 2 X#define RAY 4 X /* Check the AD&D rules! The FIRST is small monster damage. */ X#define wsdam oc_oc1 /* for weapons, PICK_AXE, rocks, and gems */ X#define wldam oc_oc2 /* for weapons, PICK_AXE, rocks, and gems */ X X#define g_val oc_cost /* for gems: value on exit */ X X#ifdef SPELLS X#define spl_lev oc_oi /* for books: spell level */ X#endif X}; X Xextern struct objclass objects[]; X X/* definitions of all object-symbols */ X X#define RANDOM_SYM '\0' /* used for generating random objects */ X#define ILLOBJ_SYM '\\' X#define AMULET_SYM '"' X#define FOOD_SYM '%' X#define WEAPON_SYM ')' X#define TOOL_SYM '(' X#define BALL_SYM '0' X#define CHAIN_SYM '_' X#define ROCK_SYM '`' X#define ARMOR_SYM '[' X#define POTION_SYM '!' X#define SCROLL_SYM '?' X#define WAND_SYM '/' X#define RING_SYM '=' X#define GEM_SYM '*' X#define GOLD_SYM '$' X#define VENOM_SYM '.' X#ifdef SPELLS X#define SPBOOK_SYM '+' /* actually SPELL-book */ X#endif X/* Other places with explicit knowledge of object symbols: X * pager.c: if(q == '%') pline("%% a piece of food"); X */ X Xstruct fruit { X char fname[PL_FSIZ]; X int fid; X struct fruit *nextf; X}; X#define newfruit() (struct fruit *)alloc(sizeof(struct fruit)) X#endif /* OBJCLASS_H */ END_OF_FILE if test 2613 -ne `wc -c <'include/objclass.h'`; then echo shar: \"'include/objclass.h'\" unpacked with wrong size! fi # end of 'include/objclass.h' fi if test -f 'src/bones.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/bones.c'\" else echo shar: Extracting \"'src/bones.c'\" \(7037 characters\) sed "s/^X//" >'src/bones.c' <<'END_OF_FILE' X/* SCCS Id: @(#)bones.c 3.0 88/04/13 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 TOS X#define OMASK 0x8000 X#else X#define OMASK 0 X#endif X X#ifdef DGK Xchar bones[FILENAME]; X#else Xchar bones[] = "bones.xx"; X#endif X X#ifdef COMPRESS Xstatic char cmd[60], proxy[20]; X Xstatic void Xcompress_bones() X{ X Strcpy(cmd, COMPRESS); X Strcat(cmd, " "); X# ifdef COMPRESS_OPTIONS X Strcat(cmd, COMPRESS_OPTIONS); X Strcat(cmd, " "); X# endif X Strcat(cmd, bones); X (void) system(cmd); X} X#endif /* COMPRESS */ X Xstatic boolean Xno_bones_level(lev) Xint lev; X{ X return (lev == medusa_level || X lev == wiz_level X#ifdef STRONGHOLD X || lev == stronghold_level || X (lev >= tower_level && lev <= tower_level+2) X#endif X#ifdef ENDGAME X || lev == ENDLEVEL X#endif X ); X} X Xstatic void Xgoodfruit(id) Xint id; X{ X register struct fruit *f; X X for(f=ffruit; f; f=f->nextf) { X if(f->fid == -id) { X f->fid = id; X return; X } X } X} X X/* save bones and possessions of a deceased adventurer */ Xvoid Xsavebones(){ X register int fd, x, y; X register struct obj *otmp; X register struct trap *ttmp; X register struct monst *mtmp, *mtmp2; X struct fruit *f; X X if(dlevel <= 0 || dlevel > MAXLEVEL) return; X if(no_bones_level(dlevel)) return; /* no bones for specific levels */ X if(!rn2(1 + (dlevel>>2)) /* not so many ghosts on low levels */ X#ifdef WIZARD X && !wizard X#endif X ) return; X#ifdef EXPLORE_MODE X /* don't let multiple restarts generate multiple copies of objects X * in bones files */ X if(discover) return; X#endif X X name_file(bones, dlevel); X#ifdef COMPRESS X Strcpy(proxy, bones); X Strcat(proxy, ".Z"); X X if((fd = open(proxy, OMASK)) >= 0) { X#else X if((fd = open(bones, OMASK)) >= 0) { X#endif X (void) close(fd); X#ifdef WIZARD X if(wizard) X pline("Bones file already exists."); X#endif X return; X } X#ifdef WALKIES X unleash_all(); X#endif X /* in case these characters are not in their home bases */ X mtmp2 = fmon; X while((mtmp = mtmp2)) { X mtmp2 = mtmp->nmon; X if(mtmp->iswiz) mongone(mtmp); X#ifdef MEDUSA X if(mtmp->data == &mons[PM_MEDUSA]) mongone(mtmp); X#endif X } X /* mark all fruits as nonexistent; when we come to them we'll mark X * them as existing (using goodfruit()) X */ X for(f=ffruit; f; f=f->nextf) f->fid = -f->fid; X X /* drop everything; the corpse's possessions are usually cursed */ X otmp = invent; X while(otmp) { X otmp->ox = u.ux; X otmp->oy = u.uy; X otmp->owornmask = 0; X if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); X if(rn2(5)) curse(otmp); X if(!otmp->nobj){ X otmp->nobj = fobj; X fobj = invent; X invent = 0; /* superfluous */ X levl[u.ux][u.uy].omask = 1; X break; X } X otmp = otmp->nobj; X } X if (u.ugrave_arise == -1) { X if(!(mtmp = makemon(&mons[PM_GHOST], u.ux, u.uy))) return; X Strcpy((char *) mtmp->mextra, plname); X } else { X in_mklev = TRUE; X /* tricks makemon() into allowing monster creation on your square */ X mons[u.ugrave_arise].pxlth += strlen(plname); X mtmp = makemon(&mons[u.ugrave_arise], u.ux, u.uy); X mons[u.ugrave_arise].pxlth -= strlen(plname); X in_mklev = FALSE; X if (!mtmp) return; X Strcpy(NAME(mtmp), plname); X mtmp->mnamelth = strlen(plname); X atl(u.ux, u.uy, mtmp->data->mlet); X Your("body rises from the dead as a%s %s...", X index(vowels, *(mons[u.ugrave_arise].mname)) ? "n" : "", X mons[u.ugrave_arise].mname); X } X mtmp->m_lev = (u.ulevel ? u.ulevel : 1); X mtmp->mhp = mtmp->mhpmax = u.uhpmax; X mtmp->msleep = 1; X if(u.ugold) mkgold(u.ugold, u.ux, u.uy); X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon){ X for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj) { X otmp->dknown = otmp->bknown = 0; X if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); X if(uses_known(otmp)) otmp->known = 0; X if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) { X otmp->spe = -1; /* no longer the actual amulet */ X curse(otmp); X } X } X mtmp->m_id = 0; X mtmp->mlstmv = 0L; X if(mtmp->mtame) mtmp->mtame = mtmp->mpeaceful = 0; X if(mtmp->mdispl) unpmon(mtmp); X } X for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) X ttmp->tseen = 0; X X for(otmp = fobj; otmp; otmp = otmp->nobj) { X X otmp->o_id = 0; X if (((otmp->otyp != CORPSE && otmp->otyp != STATUE) X || otmp->corpsenm < PM_ARCHEOLOGIST) X#ifdef NAMED_ITEMS X && !is_artifact(otmp) X#endif X ) X otmp->onamelth = 0; X if(uses_known(otmp)) otmp->known = 0; X if(otmp->otyp == SLIME_MOLD) goodfruit(otmp->spe); X otmp->dknown = otmp->bknown = 0; X otmp->invlet = 0; X#ifdef MAIL X if (otmp->otyp == SCR_MAIL) X otmp->spe = 1; X#endif X#ifdef POLYSELF X if (otmp->otyp == EGG) X otmp->spe = 0; X#endif X if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) { X otmp->spe = -1; /* no longer the actual amulet */ X curse(otmp); X } X } X X for(x=0; x<COLNO; x++) for(y=0; y<ROWNO; y++) X levl[x][y].seen = levl[x][y].new = levl[x][y].scrsym = 0; X X#ifdef MSDOS X fd = open(bones, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FCMASK); X#else X fd = creat(bones, FCMASK); X#endif X if(fd < 0) { X#ifdef WIZARD X if(wizard) X pline("Cannot create bones file - creat failed"); X#endif X return; X } X savefruitchn(fd); X#ifdef DGK X savelev(fd,dlevel, COUNT | WRITE); X#else X savelev(fd,dlevel); X#endif X#ifdef ZEROCOMP X bflush(fd); X#endif X (void) close(fd); X#ifdef COMPRESS X compress_bones(); X#endif X} X Xint Xgetbones() { X register int fd; X register int ok; X X /* wizard check added by GAN 02/05/87 */ X if(rn2(3) /* only once in three times do we find bones */ X#ifdef WIZARD X && !wizard X#endif X ) return(0); X if(no_bones_level(dlevel)) return(0); X name_file(bones, dlevel); X#ifdef COMPRESS X if((fd = open(bones, OMASK)) >= 0) goto gotbones; X Strcpy(proxy, bones); X Strcat(proxy, ".Z"); X if((fd = open(proxy, OMASK)) < 0) return(0); X else { X (void) close(fd); X Strcpy(cmd, COMPRESS); X Strcat(cmd, " -d "); /* uncompress */ X# ifdef COMPRESS_OPTIONS X Strcat(cmd, COMPRESS_OPTIONS); X Strcat(cmd, " "); X# endif X Strcat(cmd,proxy); X (void) system(cmd); X } X#endif X if((fd = open(bones, OMASK)) < 0) return(0); X#ifdef COMPRESS Xgotbones: X#endif X if((ok = uptodate(fd)) != 0){ X#ifdef WIZARD X if(wizard) { X pline("Get bones? "); X if(yn() == 'n') { X (void) close(fd); X# ifdef COMPRESS X compress_bones(); X# endif X return(0); X } X } X#endif X#ifdef ZEROCOMP X minit(); X#endif X getlev(fd, 0, dlevel, TRUE); X } X (void) close(fd); X#ifdef WIZARD X if(wizard) { X pline("Unlink bones? "); X if(yn() == 'n') { X# ifdef COMPRESS X compress_bones(); X# endif X return(ok); X } X } X#endif X if(unlink(bones) < 0){ X pline("Cannot unlink %s.", bones); X return(0); X } X return(ok); X} X X/* construct the string file.level X * This assumes there is space on the end of 'file' to append X * a two digit number. This is true for 'bones' and 'level' X * but be careful if you use it for other things -dgk X */ Xvoid Xname_file(file, level) Xchar *file; Xint level; X{ X char *tf; X X if (tf = rindex(file, '.')) X Sprintf(tf+1, "%d", level); X#ifdef MSDOS /* for glo() */ X else if (tf = eos(file)) X Sprintf(tf, ".%d", level); X#endif X return; X} END_OF_FILE if test 7037 -ne `wc -c <'src/bones.c'`; then echo shar: \"'src/bones.c'\" unpacked with wrong size! fi # end of 'src/bones.c' fi if test -f 'src/rumors.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/rumors.c'\" else echo shar: Extracting \"'src/rumors.c'\" \(6078 characters\) sed "s/^X//" >'src/rumors.c' <<'END_OF_FILE' X/* SCCS Id: @(#)rumors.c 3.0 89/02/08 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X/* hack.rumors.c - version 1.0.3 */ X X#include "hack.h" /* for RUMORFILE and BSD (index) */ X X/* Rumors has been entirely rewritten to speed up the access. This is X * essential when working from floppies. Using fseek() the way that's done X * here means rumors following longer rumors are output more often than those X * following shorter rumors. Also, you may see the same rumor more than once X * in a particular game (although the odds are highly against it), but X * this also happens with real fortune cookies. Besides, a person can X * just read the rumor file if they desire. -dgk X */ X X/* The rumors file consists of a long giving the number of bytes of useful/true X * rumors, followed by the true rumors (one per line), followed by the useless/ X * false/misleading/cute rumors (one per line). X */ X X/* The oracle file consists of a number of multiple-line records, separated X * (but not terminated) by "-----" lines. X */ X Xlong first_rumor = sizeof(long); Xlong true_rumor_size, false_rumor_size, end_rumor_file; X#ifdef ORACLE Xlong oracle_size; X#endif X Xstatic void Xinit_rumors() X{ X register FILE *fp; X X if(fp = fopen(RUMORFILE, "r")) { X (void) fread((genericptr_t)&true_rumor_size,sizeof(long),1,fp); X (void) fseek(fp, 0L, 2); X end_rumor_file = ftell(fp); X false_rumor_size = (end_rumor_file-sizeof(long)) - true_rumor_size; X (void) fclose(fp); X } else { X pline("Can't open rumors file!"); X end_rumor_file = -1; /* don't try to open it again */ X } X#ifdef ORACLE X if(fp = fopen(ORACLEFILE, "r")) { X (void) fseek(fp, 0L, 2); X oracle_size = ftell(fp); X (void) fclose(fp); X } else { X pline("Can't open oracles file!"); X oracle_size = -1; /* don't try to open it again */ X } X#endif X} X X Xvoid Xoutrumor(truth,cookie) Xint truth; /* 1=true, -1=false, 0=either */ Xboolean cookie; X{ X static const char fortune_msg[] = X "This cookie has a scrap of paper inside."; X char line[COLNO]; X char *endp; X FILE *rumors; X long tidbit, beginning; X X if (cookie && Blind) { X pline(fortune_msg); X pline("What a pity that you cannot read it!"); X return; X } X if (end_rumor_file < 0) /* We couldn't open RUMORFILE */ X return; X if(rumors = fopen(RUMORFILE, "r")) { X if (!end_rumor_file) { /* if this is the first outrumor() */ X init_rumors(); X } X if (!truth) truth = (rn2(100) >= 50 ? 1 : -1); X /* otherwise, 50% chance of being true */ X switch(truth) { X case 1: beginning = first_rumor; X tidbit = Rand() % true_rumor_size; X break; X case -1: beginning = first_rumor + true_rumor_size; X tidbit = true_rumor_size + Rand() % false_rumor_size; X break; X } X (void) fseek(rumors, first_rumor + tidbit, 0); X (void) fgets(line, COLNO, rumors); X if (!fgets(line, COLNO, rumors) || (truth == 1 && X (ftell(rumors) > true_rumor_size + sizeof(long)))) { X /* reached end of rumors -- go back to beginning */ X (void) fseek(rumors, beginning, 0); X (void) fgets(line, COLNO, rumors); X } X if (endp = index(line, '\n')) *endp = 0; X if (cookie) { X pline(fortune_msg); X pline("It reads:"); X } else pline("Tidbit of information #%ld: ",tidbit); X pline(line); X (void) fclose(rumors); X } else { X pline("Can't open rumors file!"); X end_rumor_file = -1; /* don't try to open it again */ X } X} X X#ifdef ORACLE Xstatic void Xoutoracle() X{ X char line[COLNO]; X char *endp; X FILE *oracles; X X if (oracle_size < 0) /* We couldn't open ORACLEFILE */ X return; X if(oracles = fopen(ORACLEFILE, "r")) { X if (!oracle_size) { /* if this is the first outrumor() */ X init_rumors(); X } X (void) fseek(oracles, Rand() % oracle_size, 0); X (void) fgets(line, COLNO, oracles); X while (1) X if (!fgets(line, COLNO, oracles)) { X /* reached end of oracle info -- go back to beginning */ X (void) fseek(oracles, 0L, 0); X break; X } else if (!strncmp(line,"-----",5)) { X /* found end of an oracle proclamation */ X break; X } X pline("The Oracle meditates for a moment and then intones: "); X cornline(0,NULL); X while (fgets(line, COLNO, oracles) && strncmp(line,"-----",5)) { X if (endp = index(line, '\n')) *endp = 0; X cornline(1,line); X } X cornline(2,""); X (void) fclose(oracles); X } else { X pline("Can't open oracles file!"); X oracle_size = -1; /* don't try to open it again */ X } X} X Xint Xdoconsult(oracl) Xregister struct monst *oracl; X{ X register char ans; X X multi = 0; X (void) inshop(); X X if(!oracl) { X pline("There is no one here to consult."); X return(0); X } X if(!oracl->mpeaceful) { X pline("The Oracle is in no mood for consultations."); X return(0); X } else { X if(!u.ugold) { X You("have no money."); X return(0); X } X pline("\"Wilt thou settle for a minor consultation?\" (50 Zorkmids) "); X ans = ynq(); X if(ans == 'y') { X if(u.ugold < 50) { X You("don't even have enough money for that!"); X return(0); X } X u.ugold -= 50; X oracl->mgold += 50; X flags.botl = 1; X outrumor(1, FALSE); X return(1); X } else if(ans == 'q') return(0); X else { X pline("\"Then dost thou desire a major one?\" (1000 Zorkmids) "); X if (yn() != 'y') return(0); X } X if(u.ugold < 1000) { X pline("The Oracle scornfully takes all your money and says:"); Xcornline(0,NULL); Xcornline(1,"\"...it is rather disconcerting to be confronted with the"); Xcornline(1,"following theorem from [Baker, Gill, and Solovay, 1975]."); Xcornline(1,""); Xcornline(1,"Theorem 7.18 There exist recursive languages A and B such that"); Xcornline(1," (1) P(A) == NP(A), and"); Xcornline(1," (2) P(B) != NP(B)"); Xcornline(1,""); Xcornline(1,"This provides impressive evidence that the techniques that are"); Xcornline(1,"currently available will not suffice for proving that P != NP or"); Xcornline(1,"that P == NP.\" [Garey and Johnson, p. 185.]"); Xcornline(2,""); X oracl->mgold += u.ugold; X u.ugold = 0; X flags.botl = 1; X return(1); X } X u.ugold -= 1000; X oracl->mgold += 1000; X flags.botl = 1; X outoracle(); X return(1); X } X} X X#endif END_OF_FILE if test 6078 -ne `wc -c <'src/rumors.c'`; then echo shar: \"'src/rumors.c'\" unpacked with wrong size! fi # end of 'src/rumors.c' fi if test -f 'src/unixunix.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/unixunix.c'\" else echo shar: Extracting \"'src/unixunix.c'\" \(6970 characters\) sed "s/^X//" >'src/unixunix.c' <<'END_OF_FILE' X/* SCCS Id: @(#)unixunix.c 3.0 88/04/13 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X/* This file collects some Unix dependencies; pager.c contains some more */ X X/* X * The time is used for: X * - seed for rand() X * - year on tombstone and yymmdd in record file X * - phase of the moon (various monsters react to NEW_MOON or FULL_MOON) X * - night and midnight (the undead are dangerous at midnight) X * - determination of what files are "very old" X */ X X/* block some unused #defines to avoid overloading some cpp's */ X#define MONATTK_H X#include "hack.h" /* mainly for index() which depends on BSD */ X X#include <errno.h> X#include <sys/stat.h> X Xvoid Xsetrandom() X{ X#ifdef SYSV X (void) Srand((long) time ((time_t *) 0)); X#else X#ifdef ULTRIX X Srand((int)time((time_t *)0)); X#else X (void) Srand((int) time ((long *) 0)); X#endif /* ULTRIX */ X#endif /* SYSV */ X X} X Xstatic struct tm * Xgetlt() X{ X time_t date; X X#ifdef BSD X (void) time((long *)(&date)); X#else X (void) time(&date); X#endif X#if defined(ULTRIX) || defined(BSD) X return(localtime((long *)(&date))); X#else X return(localtime(&date)); X#endif /* ULTRIX */ X} X Xint Xgetyear() X{ X return(1900 + getlt()->tm_year); X} X Xchar * Xgetdate() X{ X#ifdef LINT /* static char datestr[7]; */ X char datestr[7]; X#else X static char datestr[7]; X#endif X register struct tm *lt = getlt(); X X Sprintf(datestr, "%2d%2d%2d", X lt->tm_year, lt->tm_mon + 1, lt->tm_mday); X if(datestr[2] == ' ') datestr[2] = '0'; X if(datestr[4] == ' ') datestr[4] = '0'; X return(datestr); X} X Xint Xphase_of_the_moon() /* 0-7, with 0: new, 4: full */ X{ /* moon period: 29.5306 days */ X /* year: 365.2422 days */ X register struct tm *lt = getlt(); X register int epact, diy, goldn; X X diy = lt->tm_yday; X goldn = (lt->tm_year % 19) + 1; X epact = (11 * goldn + 18) % 30; X if ((epact == 25 && goldn > 11) || epact == 24) X epact++; X X return( (((((diy + epact) * 6) + 11) % 177) / 22) & 7 ); X} X Xint Xnight() X{ X register int hour = getlt()->tm_hour; X X return(hour < 6 || hour > 21); X} X Xint Xmidnight() X{ X return(getlt()->tm_hour == 0); X} X Xstatic struct stat buf, hbuf; X Xvoid Xgethdate(name) char *name; { X/* old version - for people short of space */ X/* X/* register char *np; X/* if(stat(name, &hbuf)) X/* error("Cannot get status of %s.", X/* (np = rindex(name, '/')) ? np+1 : name); X/* X/* version using PATH from: seismo!gregc@ucsf-cgl.ARPA (Greg Couch) */ X X X/* X * The problem with #include <sys/param.h> is that this include file X * does not exist on all systems, and moreover, that it sometimes includes X * <sys/types.h> again, so that the compiler sees these typedefs twice. X */ X#define MAXPATHLEN 1024 X Xregister char *np, *path; Xchar filename[MAXPATHLEN+1]; X if (index(name, '/') != NULL || (path = getenv("PATH")) == NULL) X path = ""; X X for (;;) { X if ((np = index(path, ':')) == NULL) X np = path + strlen(path); /* point to end str */ X if (np - path <= 1) /* %% */ X Strcpy(filename, name); X else { X (void) strncpy(filename, path, np - path); X filename[np - path] = '/'; X Strcpy(filename + (np - path) + 1, name); X } X if (stat(filename, &hbuf) == 0) X return; X if (*np == '\0') X break; X path = np + 1; X } X error("Cannot get status of %s.", X (np = rindex(name, '/')) ? np+1 : name); X} X Xint Xuptodate(fd) Xint fd; X{ X if(fstat(fd, &buf)) { X pline("Cannot get status of saved level? "); X return(0); X } X if(buf.st_mtime < hbuf.st_mtime) { X pline("Saved level is out of date. "); X return(0); X } X return(1); X} X X/* see whether we should throw away this xlock file */ Xstatic int Xveryold(fd) Xint fd; X{ X register int i; X time_t date; X X if(fstat(fd, &buf)) return(0); /* cannot get status */ X if(buf.st_size != sizeof(int)) return(0); /* not an xlock file */ X#ifdef BSD X (void) time((long *)(&date)); X#else X (void) time(&date); X#endif X if(date - buf.st_mtime < 3L*24L*60L*60L) { /* recent */ X extern int errno; X int lockedpid; /* should be the same size as hackpid */ X X if(read(fd, (char *)&lockedpid, sizeof(lockedpid)) != X sizeof(lockedpid)) X /* strange ... */ X return(0); X X /* From: Rick Adams <seismo!rick> X /* This will work on 4.1cbsd, 4.2bsd and system 3? & 5. X /* It will do nothing on V7 or 4.1bsd. */ X#ifndef NETWORK X /* It will do a VERY BAD THING if the playground is shared X by more than one machine! -pem */ X if(!(kill(lockedpid, 0) == -1 && errno == ESRCH)) X#endif X return(0); X } X (void) close(fd); X for(i = 1; i <= MAXLEVEL+1; i++) { /* try to remove all */ X glo(i); X (void) unlink(lock); X } X glo(0); X if(unlink(lock)) return(0); /* cannot remove it */ X return(1); /* success! */ X} X Xvoid Xgetlock() X{ X extern int errno; X register int i = 0, fd; X X#ifdef HARD X /* idea from rpick%ucqais@uccba.uc.edu X * prevent automated rerolling of characters X * test input (fd0) so that tee'ing output to get a screen dump still X * works X * also incidentally prevents development of any hack-o-matic programs X */ X if (!isatty(0)) X error("You must play from a terminal."); X#endif X X (void) fflush(stdout); X X /* we ignore QUIT and INT at this point */ X if (link(HLOCK, LLOCK) == -1) { X register int errnosv = errno; X X perror(HLOCK); X Printf("Cannot link %s to %s\n", LLOCK, HLOCK); X switch(errnosv) { X case ENOENT: X Printf("Perhaps there is no (empty) file %s ?\n", HLOCK); X break; X case EACCES: X Printf("It seems you don't have write permission here.\n"); X break; X case EEXIST: X Printf("(Try again or rm %s.)\n", LLOCK); X break; X default: X Printf("I don't know what is wrong."); X } X getret(); X error(""); X /*NOTREACHED*/ X } X X regularize(lock); X glo(0); X if(locknum > 25) locknum = 25; X X do { X if(locknum) lock[0] = 'a' + i++; X X if((fd = open(lock, 0)) == -1) { X if(errno == ENOENT) goto gotlock; /* no such file */ X perror(lock); X (void) unlink(LLOCK); X error("Cannot open %s", lock); X } X X if(veryold(fd)) /* if true, this closes fd and unlinks lock */ X goto gotlock; X (void) close(fd); X } while(i < locknum); X X (void) unlink(LLOCK); X error(locknum ? "Too many hacks running now." X : "There is a game in progress under your name."); Xgotlock: X fd = creat(lock, FCMASK); X if(unlink(LLOCK) == -1) X error("Cannot unlink %s.", LLOCK); X if(fd == -1) { X error("cannot creat lock file."); X } else { X if(write(fd, (char *) &hackpid, sizeof(hackpid)) X != sizeof(hackpid)){ X error("cannot write lock"); X } X if(close(fd) == -1) { X error("cannot close lock"); X } X } X} X Xvoid Xregularize(s) /* normalize file name - we don't like .'s, /'s, spaces */ Xregister char *s; X{ X register char *lp; X X while((lp=index(s, '.')) || (lp=index(s, '/')) || (lp=index(s,' '))) X *lp = '_'; X#ifdef SYSV X /* avoid problems with 14 character file name limit */ X# ifdef COMPRESS X if(strlen(s) > 10) X /* leave room for .e from error and .Z from compress */ X s[10] = '\0'; X# else X if(strlen(s) > 12) X /* leave room for .e from error */ X s[12] = '\0'; X# endif X#endif X} END_OF_FILE if test 6970 -ne `wc -c <'src/unixunix.c'`; then echo shar: \"'src/unixunix.c'\" unpacked with wrong size! fi # end of 'src/unixunix.c' fi if test -f 'src/vault.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/vault.c'\" else echo shar: Extracting \"'src/vault.c'\" \(6435 characters\) sed "s/^X//" >'src/vault.c' <<'END_OF_FILE' X/* SCCS Id: @(#)vault.c 3.0 88/10/25 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" X Xstatic struct monst *guard; Xstatic int gdlevel; X X#include "vault.h" X Xstatic void Xrestfakecorr() X{ X register int fcx, fcy, fcbeg; X register struct rm *crm; X X while((fcbeg = EGD->fcbeg) < EGD->fcend) { X fcx = EGD->fakecorr[fcbeg].fx; X fcy = EGD->fakecorr[fcbeg].fy; X if((u.ux == fcx && u.uy == fcy) || cansee(fcx,fcy) || X m_at(fcx,fcy)) X return; X crm = &levl[fcx][fcy]; X crm->typ = EGD->fakecorr[fcbeg].ftyp; X if(!crm->typ) crm->seen = 0; X newsym(fcx,fcy); X EGD->fcbeg++; X } X /* it seems he left the corridor - let the guard disappear */ X mongone(guard); X guard = 0; X} X Xstatic int Xgoldincorridor() X{ X register int fci; X X for(fci = EGD->fcbeg; fci < EGD->fcend; fci++) X if(g_at(EGD->fakecorr[fci].fx, EGD->fakecorr[fci].fy)) X return(1); X return(0); X} X Xvoid Xsetgd() X{ X register struct monst *mtmp; X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) if(mtmp->isgd){ X guard = mtmp; X gdlevel = dlevel; X return; X } X guard = 0; X} X Xvoid Xinvault() X{ X register int tmp = inroom(u.ux, u.uy); X X if(tmp < 0 || rooms[tmp].rtype != VAULT) { X u.uinvault = 0; X return; X } X if(++u.uinvault % 50 == 0 && (!guard || gdlevel != dlevel)) { X char buf[BUFSZ]; X register int x, y, dd, gx, gy; X X /* first find the goal for the guard */ X for(dd = 1; (dd < ROWNO || dd < COLNO); dd++) { X for(y = u.uy-dd; y <= u.uy+dd; y++) { X if(y < 0 || y > ROWNO-1) continue; X for(x = u.ux-dd; x <= u.ux+dd; x++) { X if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd) X x = u.ux+dd; X if(x < 0 || x > COLNO-1) continue; X if(levl[x][y].typ == CORR) goto fnd; X } X } X } X impossible("Not a single corridor on this level??"); X tele(); X return; Xfnd: X gx = x; gy = y; X X /* next find a good place for a door in the wall */ X x = u.ux; y = u.uy; X while(levl[x][y].typ == ROOM) { X register int dx,dy; X X dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; X dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; X if(abs(gx-x) >= abs(gy-y)) X x += dx; X else X y += dy; X } X X /* make something interesting happen */ X if(!(guard = makemon(&mons[PM_GUARD], x, y))) return; X guard->isgd = guard->mpeaceful = 1; X EGD->gddone = 0; X gdlevel = dlevel; X if(!cansee(guard->mx, guard->my)) { X mongone(guard); X guard = 0; X return; X } X X pline("Suddenly one of the Vault's guards enters!"); X pmon(guard); X do { X pline("\"Hello stranger, who are you?\" - "); X getlin(buf); X } while (!letter(buf[0])); X X if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) { X pline("\"Oh, yes, of course. Sorry to have disturbed you.\""); X mongone(guard); X guard = 0; X return; X } X clrlin(); X pline("\"I don't know you.\""); X if(!u.ugold) X pline("\"Please follow me.\""); X else { X pline("\"Most likely all that gold was stolen from this vault.\""); X pline("\"Please drop that gold and follow me.\""); X } X EGD->gdx = gx; X EGD->gdy = gy; X EGD->fcbeg = 0; X EGD->fakecorr[0].fx = x; X EGD->fakecorr[0].fy = y; X EGD->fakecorr[0].ftyp = levl[x][y].typ; X levl[x][y].typ = DOOR; X levl[x][y].doormask = D_NODOOR; X EGD->fcend = 1; X } X} X Xint Xgd_move(){ X register int x, y, dx, dy, gx, gy, nx, ny, typ, i; X register struct fakecorridor *fcp; X register struct rm *crm; X if(!guard || gdlevel != dlevel){ X impossible("Where is the guard?"); X return(2); /* died */ X } X if(u.ugold || goldincorridor()) X return(0); /* didn't move */ X if(dist(guard->mx,guard->my) > 1 || EGD->gddone) { X restfakecorr(); X return(0); /* didn't move */ X } X x = guard->mx; X y = guard->my; X /* look around (hor & vert only) for accessible places */ X for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) { X if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) { X X typ = (crm = &levl[nx][ny])->typ; X if(!IS_STWALL(typ) && !IS_POOL(typ)) { X X for(i = EGD->fcbeg; i < EGD->fcend; i++) X if(EGD->fakecorr[i].fx == nx && EGD->fakecorr[i].fy == ny) X goto nextnxy; X X if((i = inroom(nx,ny)) >= 0 && rooms[i].rtype == VAULT) X continue; X X /* seems we found a good place to leave him alone */ X EGD->gddone = 1; X if(ACCESSIBLE(typ)) goto newpos; X X crm->typ = (typ == SCORR) ? CORR : DOOR; X if(crm->typ == DOOR) crm->doormask = D_NODOOR; X goto proceed; X } X } Xnextnxy: ; X } X nx = x; X ny = y; X gx = EGD->gdx; X gy = EGD->gdy; X dx = (gx > x) ? 1 : (gx < x) ? -1 : 0; X dy = (gy > y) ? 1 : (gy < y) ? -1 : 0; X if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy; X X while((typ = (crm = &levl[nx][ny])->typ) != 0) { X /* in view of the above we must have IS_WALL(typ) or typ == POOL */ X /* must be a wall here */ X if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) && X SPACE_POS(levl[nx+nx-x][ny+ny-y].typ)){ X crm->typ = DOOR; X crm->doormask = D_NODOOR; X goto proceed; X } X if(dy && nx != x) { X nx = x; ny = y+dy; X continue; X } X if(dx && ny != y) { X ny = y; nx = x+dx; dy = 0; X continue; X } X /* I don't like this, but ... */ X crm->typ = DOOR; X crm->doormask = D_NODOOR; X goto proceed; X } X crm->typ = CORR; Xproceed: X if(cansee(nx,ny)) { X mnewsym(nx,ny); X prl(nx,ny); X } X fcp = &(EGD->fakecorr[EGD->fcend]); X if(EGD->fcend++ == FCSIZ) panic("fakecorr overflow"); X fcp->fx = nx; X fcp->fy = ny; X fcp->ftyp = typ; Xnewpos: X if(EGD->gddone) nx = ny = 0; X levl[guard->mx][guard->my].mmask = 0; X levl[nx][ny].mmask = 1; X guard->mx = nx; X guard->my = ny; X pmon(guard); X restfakecorr(); X return(1); X} X Xvoid Xgddead(){ X guard = 0; X} X Xvoid Xreplgd(mtmp,mtmp2) Xregister struct monst *mtmp, *mtmp2; X{ X if(mtmp == guard) X guard = mtmp2; X} X X/* Routine when dying or quitting with a vault guard around */ Xvoid Xpaygd() X{ X register int i; X int gx,gy; X char buf[BUFSZ]; X X if (!u.ugold) return; X X if (u.uinvault) { X Your("%ld Zorkmids goes into the Magic Memory Vault.", X u.ugold); X mkgold(u.ugold, u.ux, u.uy); X u.ugold = 0L; X } else if (guard) { X mnexto(guard); X pmon(guard); X pline("%s remits your gold to the vault.", Monnam(guard)); X for(i=0; i<=nroom; i++) X if (rooms[i].rtype==VAULT) break; X if (i > nroom) { X impossible("no vault?"); X return; X } X gx = rooms[i].lx + rn2(2); X gy = rooms[i].ly + rn2(2); X mkgold(u.ugold, gx, gy); X u.ugold = 0L; X Sprintf(buf, X "To Croesus: here's the gold recovered from the %s %s...", X player_mon()->mname, plname); X make_engr_at(gx, gy, buf); X } X if (guard) mongone(guard); X} END_OF_FILE if test 6435 -ne `wc -c <'src/vault.c'`; then echo shar: \"'src/vault.c'\" unpacked with wrong size! fi # end of 'src/vault.c' fi if test -f 'src/wizard.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/wizard.c'\" else echo shar: Extracting \"'src/wizard.c'\" \(7415 characters\) sed "s/^X//" >'src/wizard.c' <<'END_OF_FILE' X/* SCCS Id: @(#)wizard.c 3.0 88/04/11 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X/* wizard code - inspired by rogue code from Merlyn Leroy (digi-g!brian) */ X/* - heavily modified to give the wiz balls. (genat!mike) */ X/* - dewimped and given some maledictions. -3. */ X X#include "hack.h" X X#ifdef HARD X/* TODO: Expand this list. */ Xstatic const int nasties[] = { X PM_COCKATRICE, PM_ETTIN, PM_STALKER, PM_MINOTAUR, PM_RED_DRAGON, X PM_GREEN_DRAGON, PM_OWLBEAR, PM_PURPLE_WORM, PM_ROCK_TROLL, PM_XAN, X PM_GREMLIN, PM_UMBER_HULK, PM_VAMPIRE_LORD, PM_XORN, PM_ZRUTY, X#ifdef ARMY X PM_CAPTAIN, X#endif X }; X#endif /* HARD */ X X/* TODO: investigate this. */ Xstatic const char wizapp[] = { X S_HUMAN, S_DEMON, S_VAMPIRE, S_DRAGON, S_TROLL, S_UMBER, X S_XORN, S_XAN, S_COCKATRICE, S_EYE, S_NAGA, S_TRAPPER, X /* '1' /* Historical reference */ }; X X/* If he has found the Amulet, make the wizard appear after some time */ Xvoid Xamulet(){ X register struct monst *mtmp; X X if(!flags.made_amulet || !flags.no_of_wizards) X return; X /* find wizard, and wake him if necessary */ X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) X if(mtmp->iswiz && mtmp->msleep && !rn2(40)) X if(u.uhave_amulet) { X mtmp->msleep = 0; X if(dist(mtmp->mx,mtmp->my) > 2) X pline( X "You get the creepy feeling that somebody noticed your taking the Amulet." X ); X return; X } X} X Xint Xmon_has_amulet(mtmp) Xregister struct monst *mtmp; X{ X register struct obj *otmp; X X for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj){ X if(otmp->otyp == AMULET_OF_YENDOR && otmp->spe >= 0) return(1); X } X return(0); X} X X/* the wiz's prime directive */ Xint Xwiz_get_amulet(mtmp) Xregister struct monst *mtmp; X{ X /* if he doesn't have the amulet */ X if(!mon_has_amulet(mtmp)) X if(u.uhave_amulet) { X X /* player has it, dog them til he gets it or dies */ X mnexto(mtmp); X } else { X register struct obj *otmp; X X /* if it is lying around someplace, he teleports to it */ X for(otmp = fobj; otmp; otmp = otmp->nobj) X if(otmp->otyp == AMULET_OF_YENDOR && !otmp->spe) { X if(u.ux == otmp->ox && u.uy == otmp->oy) { X /* player is standing on it */ X mnexto(mtmp); X return(0); X } X if(!levl[otmp->ox][otmp->oy].mmask || X (mtmp->mx == otmp->ox && mtmp->my == otmp->oy)) { X X /* teleport to it and pick it up */ X levl[mtmp->mx][mtmp->my].mmask = 0; X levl[otmp->ox][otmp->oy].mmask = 1; X mtmp->mx = otmp->ox; X mtmp->my = otmp->oy; X freeobj(otmp); X mpickobj(mtmp, otmp); X pmon(mtmp); X return(1); X } X break; X } X /* we don't know where it is */ X } X X /* he has it or can't find it */ X /* secondary goal - stayin' alive */ X X /* if wounded, hole up on or near the stairs (to block them) */ X if(mtmp->mhp < 20 + rnd(10)) X if (mtmp->mx != xupstair && mtmp->my != yupstair) X mnearto(mtmp,xupstair,yupstair,TRUE); X X /* if you're not around, cast healing spells */ X if(dist(mtmp->mx,mtmp->my) > (BOLT_LIM * BOLT_LIM)) X if(mtmp->mhp <= mtmp->mhpmax - 8) { X mtmp->mhp += rnd(8); X return(1); X } X /* healthy wiz with nothing to do */ X else if(!rn2(5)) X mnexto(mtmp); X X /* the effect is that below 30 hp, wily wiz teleports X again and again, unless/until he blocks the stairs. X X if you keep away from the wounded wiz, he sits X there healing himself, until he gets healthy X and decides to punish you some more. -3. */ X X return(0); X} X Xvoid Xaggravate() X{ X register struct monst *mtmp; X X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) { X mtmp->msleep = 0; X if(mtmp->mfroz && !rn2(5)) X mtmp->mfroz = 0; X } X} X Xvoid Xclonewiz() X{ X register struct monst *mtmp2; X X if(mtmp2 = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy)) { X mtmp2->msleep = mtmp2->mtame = mtmp2->mpeaceful = 0; X if (!u.uhave_amulet && rn2(2)) { /* give clone a fake */ X mtmp2->minvent = mksobj(AMULET_OF_YENDOR,FALSE); X mtmp2->minvent->spe = -1; X } X unpmon(mtmp2); X mtmp2->mappearance = wizapp[rn2(SIZE(wizapp))]; X pmon(mtmp2); X } X} X X#ifdef HARD Xvoid Xnasty() { X register struct monst *mtmp; X register int i, tmp; X X if(!rn2(10) && Inhell) dsummon(&mons[PM_WIZARD_OF_YENDOR]); X else { X tmp = (u.ulevel > 3) ? u.ulevel/3 : 1; /* just in case -- rph */ X X for(i = rnd(tmp); i > 0; --i) X if((mtmp = makemon(&mons[nasties[rn2(SIZE(nasties))]], u.ux, u.uy))) { X X mtmp->msleep = mtmp->mpeaceful = mtmp->mtame = 0; X } else X (void)makemon((struct permonst *)0, u.ux, u.uy); /* GENOD? */ X } X return; X} X X/* Let's resurrect the wizard, for some unexpected fun. */ Xvoid Xresurrect() X{ X register struct monst *mtmp; X X if(mtmp = makemon(&mons[PM_WIZARD_OF_YENDOR], u.ux, u.uy)) { X mtmp->msleep = mtmp->mtame = mtmp->mpeaceful = 0; X pline("A voice booms out..."); X pline("\"So thou thought thou couldst kill me, fool.\""); X } X X} X X/* Here, we make trouble for the poor shmuck who actually */ X/* managed to do in the Wizard. */ Xvoid Xintervene() { X X switch(rn2(6)) { X X case 0: X case 1: You("feel vaguely nervous."); X break; X case 2: if (!Blind) X You("notice a %s glow surrounding you.", X Hallucination ? hcolor() : black); X rndcurse(); X break; X case 3: aggravate(); X break; X case 4: nasty(); X break; X case 5: if (!flags.no_of_wizards) resurrect(); X break; X } X} X Xvoid Xwizdead(mtmp) Xregister struct monst *mtmp; X{ X flags.no_of_wizards--; X if(! u.udemigod) { X X u.udemigod = TRUE; X u.udg_cnt = rn1(250, 50); X X /* Make the wizard meaner the next time he appears */ X mtmp->data->mlevel++; X mtmp->data->ac--; X } else X mtmp->data->mlevel++; X} X#endif /* HARD /**/ X Xconst char *random_insult[] = { X "antic", X "blackguard", X "caitiff", X "chucklehead", X "coistrel", X "craven", X "cretin", X "cur", X "dastard", X "demon fodder", X "dimwit", X "dolt", X "fool", X "footpad", X "imbecile", X "knave", X "maledict", X "miscreant", X "niddering", X "poltroon", X "rattlepate", X "reprobate", X "scapegrace", X "varlet", X "villein", /* (sic.) */ X "wittol", X "worm", X "wretch", X}; X Xconst char *random_malediction[] = { X "Hell shall soon claim thy remains,", X "I chortle at thee, pathetic", X "Prepare to die,", X "Resistance is useless,", X "Surrender or die, thou", X "There shall be no mercy, yon", X "Thou shalt repent of thy cunning,", X "Thou art as a flea to me,", X "Thou art doomed,", X "Thy fate is sealed,", X "Verily, thou shalt be one dead" X/* "Go play leapfrog with a unicorn,", */ X}; X X/* Insult the player */ Xvoid Xcuss(mtmp) Xregister struct monst *mtmp; X{ X switch (rn2(5)) { X case 0: pline("%s casts aspersions on your ancestry.", X Monnam(mtmp)); X break; X case 1: pline("%s laughs fiendishly.", /* typical bad guy action */ X Monnam(mtmp)); X break; X default: X if (u.uhave_amulet && !rn2(SIZE(random_insult))) X pline("\"Relinquish the amulet, %s!\"", X random_insult[rn2(SIZE(random_insult))]); X else if (u.uhp < 5 && !rn2(2)) /* Panic */ X pline(rn2(2) ? X "\"Even now thy life force ebbs, %s!\"" : X "\"Savor thy breath, %s, it be thine last!\"", X random_insult[rn2(SIZE(random_insult))]); X else if (mtmp->mhp < 5 && !rn2(2)) /* Parthian shot */ X pline(rn2(2) ? X "\"I shall return.\"" : X "\"I'll be back.\""); X else X pline("\"%s %s!\"", X random_malediction[rn2(SIZE(random_malediction))], X random_insult[rn2(SIZE(random_insult))]); X } X} END_OF_FILE if test 7415 -ne `wc -c <'src/wizard.c'`; then echo shar: \"'src/wizard.c'\" unpacked with wrong size! fi # end of 'src/wizard.c' fi echo shar: End of archive 32 \(of 38\). cp /dev/null ark32isdone 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 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 38 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0