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