games-request@tekred.TEK.COM (07/28/87)
Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 2, Issue 13
Archive-name: nethack/Part13
#! /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 13 (of 16)."
# Contents: config.h do_name.c dogmove.c dothrow.c end.c fountain.c
# termcap.c
# Wrapped by billr@tekred on Tue Jul 28 09:49:45 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f config.h -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"config.h\"
else
echo shar: Extracting \"config.h\" \(7601 characters\)
sed "s/^X//" >config.h <<'END_OF_config.h'
X/* SCCS Id: @(#)config.h 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* config.h - version 1.0.3 */
X
X#ifndef CONFIG /* make sure the compiler does not see the typedefs twice */
X#define CONFIG
X
X#define CHDIR /* delete if no chdir() available */
X
X/*
X * Some include files are in a different place under SYSV
X * BSD SYSV
X * <strings.h> <string.h>
X * <sys/wait.h> <wait.h>
X * <sys/time.h> <time.h>
X * <sgtty.h> <termio.h>
X * Some routines are called differently
X * index strchr
X * rindex strrchr
X * Also, the code for suspend and various ioctls is only given for BSD4.2
X * (I do not have access to a SYSV system.)
X */
X/* #define MSDOS /* define for MS-DOS (actually defined by compiler) */
X#define UNIX /* delete if no fork(), exec() available */
X#define BSD /* defind for 4.n BSD */
X/* #define SYSV /* define for System V */
X
X/* #define BETA /* if a beta-test copy [MRS] */
X#define VERSION "1.3d" /* version number. */
X
X#define PYRAMID_BUG /* avoid a bug on the Pyramid */
X/* #define APOLLO /* same for the Apollo */
X/* #define STUPID /* avoid some complicated expressions if
X your C compiler chokes on them */
X/* #define NOWAITINCLUDE /* neither <wait.h> nor <sys/wait.h> exists */
X#ifdef MSDOS
X#define NOWAITINCLUDE
X#endif
X
X#define WIZARD "mike" /* the person allowed to use the -D option */
X#define RECORD "record"/* the file containing the list of topscorers */
X#define NEWS "news" /* the file containing the latest hack news */
X#define HELP "help" /* the file containing a description of the commands */
X#define SHELP "hh" /* abbreviated form of the same */
X#define RUMORFILE "rumors" /* a file with fortune cookies */
X#define DATAFILE "data" /* a file giving the meaning of symbols used */
X#define FMASK 0660 /* file creation mask */
X
X#ifdef UNIX
X#define HLOCK "perm" /* an empty file used for locking purposes */
X#define LLOCK "safelock" /* link to previous */
X
X/*
X * Define DEF_PAGER as your default pager, e.g. "/bin/cat" or "/usr/ucb/more"
X * If defined, it can be overridden by the environment variable PAGER.
X * Hack will use its internal pager if DEF_PAGER is not defined.
X * (This might be preferable for security reasons.)
X * #define DEF_PAGER ".../mydir/mypager"
X */
X
X/*
X * If you define MAIL, then the player will be notified of new mail
X * when it arrives. If you also define DEF_MAILREADER then this will
X * be the default mail reader, and can be overridden by the environment
X * variable MAILREADER; otherwise an internal pager will be used.
X * A stat system call is done on the mailbox every MAILCKFREQ moves.
X */
X#define MAIL
X#define DEF_MAILREADER "/usr/bin/mail" /* or e.g. /bin/mail */
X#define MAILCKFREQ 1
X
X
X#define SHELL /* do not delete the '!' command */
X
X#ifdef BSD
X#define SUSPEND /* let ^Z suspend the game */
X#endif
X#endif /* UNIX /**/
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/* size of terminal screen is (at least) (ROWNO+2) by COLNO */
X#define COLNO 80
X#define ROWNO 22
X
X#ifdef BSD
X#include <strings.h> /* declarations for strcat etc. */
X#else
X#include <string.h> /* idem on System V */
X#define index strchr
X#define rindex strrchr
X#endif
X
X/*
X * small signed integers (8 bits suffice)
X * typedef char schar;
X * will do when you have signed characters; otherwise use
X * typedef short int schar;
X */
Xtypedef char schar;
X
X/*
X * small unsigned integers (8 bits suffice - but 7 bits do not)
X * - these are usually object types; be careful with inequalities! -
X * typedef unsigned char uchar;
X * will be satisfactory if you have an "unsigned char" type; otherwise use
X * typedef unsigned short int uchar;
X */
Xtypedef unsigned char uchar;
X
X/*
X * small integers in the range 0 - 127, usually coordinates
X * although they are nonnegative they must not be declared unsigned
X * since otherwise comparisons with signed quantities are done incorrectly
X */
Xtypedef schar xchar;
Xtypedef xchar boolean; /* 0 or 1 */
X#define TRUE 1
X#define FALSE 0
X
X/*
X * Declaration of bitfields in various structs; if your C compiler
X * doesnt handle bitfields well, e.g., if it is unable to initialize
X * structs containing bitfields, then you might use
X * #define Bitfield(x,n) uchar x
X * since the bitfields used never have more than 7 bits. (Most have 1 bit.)
X */
X#define Bitfield(x,n) uchar x
X
X#define SIZE(x) (int)(sizeof(x) / sizeof(x[0]))
X
X#ifdef MSDOS
X#include <fcntl.h>
X#define exit msexit /* do chdir first */
X#ifdef getchar
X# undef getchar
X#endif /* getchar /**/
X#define getchar tgetch
X#define DGK /* MS DOS specific enhancements by dgk */
X
X#ifdef DGK
X# include "msdos.h" /* contains necessary externs for msdos.c */
X# define SHELL /* via exec of COMMAND.COM */
X# define PATHLEN 64 /* maximum pathlength */
X# define FILENAME 80 /* maximum filename length (conservative) */
X# define FROMPERM 1 /* for ramdisk use */
X# define TOPERM 2 /* for ramdisk use */
X# define glo(x) name_file(lock, x) /* name_file used for bones */
X# define IS_CORNER(x) ((x) == symbol.tlcorn || (x) == symbol.trcorn\
X || (x) == symbol.blcorn || (x)==symbol.brcorn)
X /* screen symbols for using character graphics. */
X struct symbols {
X unsigned char vwall, hwall, tlcorn, trcorn, blcorn, brcorn;
X unsigned char door, room, corr;
X };
X extern struct symbols symbol;
X extern char *configfile;
X#endif /* DGK /**/
X#endif /* MSDOS /**/
X
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 PRAYERS /* Prayer code by M. Stephenson */
X#define KAA /* Various changes made by Ken Arromdee */
X#define MARKER /* Magic marker modification from Gil Neiger */
X#define NEWCLASS /* Samurai/Ninja etc. by M. Stephenson */
X#define SAFE_ATTACK /* Safe attack code by Don Kneller */
X#define PROBING /* Wand of probing code by Gil Neiger */
X#define DIAGS /* Diagnostics after death/quit by Gil Neiger */
X#define SORTING /* Sorted inventory by Don Kneller */
X#define DGKMOD /* Additional features by Don Kneller */
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 NEWTRAPS /* Magic and Squeeky board traps by Scott R. Turner*/
X#define FREEHAND /* Cannot use Pick-axe without wielding it. */
X#define SPIDERS /* Spiders and webs by Scott R. Turner */
X#define FOUNTAINS /* Fountain code by SRT (+ GAN + EB) */
X#define KOPS /* Keystone Kops by Scott R. Turner */
X#define ROCKMOLE /* Rockmoles by Scott R. Turner */
X
X/*
X * Status Line options.
X */
X
X#define GOLD_ON_BOTL
X#define EXP_ON_BOTL
X
X#ifdef REDO
X#define DOAGAIN '\001' /* Used in tty.c and cmd.c */
X#endif
X
X#ifdef DGKMOD
X#define LARGEST_INT ((1 << 15) - 1)
X#endif
X
X#endif /* CONFIG /**/
END_OF_config.h
if test 7601 -ne `wc -c <config.h`; then
echo shar: \"config.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f do_name.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"do_name.c\"
else
echo shar: Extracting \"do_name.c\" \(7462 characters\)
sed "s/^X//" >do_name.c <<'END_OF_do_name.c'
X/* SCCS Id: @(#)do_name.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* do_name.c - version 1.0.3 */
X
X#include <stdio.h>
X#include "hack.h"
Xextern char plname[];
Xextern char *rndmonnam();
X
Xcoord
Xgetpos(force,goal) int force; char *goal; {
Xregister cx,cy,i,c;
Xextern char sdir[]; /* defined in hack.c */
Xextern schar xdir[], ydir[]; /* idem */
Xextern char *visctrl(); /* see below */
Xcoord cc;
X pline("(For instructions type a ?)");
X cx = u.ux;
X cy = u.uy;
X curs(cx,cy+2);
X while((c = readchar()) != '.'){
X for(i=0; i<8; i++) if(sdir[i] == c){
X if(1 <= cx + xdir[i] && cx + xdir[i] <= COLNO)
X cx += xdir[i];
X if(0 <= cy + ydir[i] && cy + ydir[i] <= ROWNO-1)
X cy += ydir[i];
X goto nxtc;
X }
X if(c == '?'){
X pline("Use [hjkl] to move the cursor to %s.", goal);
X pline("Type a . when you are at the right place.");
X } else {
X pline("Unknown direction: '%s' (%s).",
X visctrl(c),
X force ? "use hjkl or ." : "aborted");
X if(force) goto nxtc;
X cc.x = -1;
X cc.y = 0;
X return(cc);
X }
X nxtc: ;
X curs(cx,cy+2);
X }
X cc.x = cx;
X cc.y = cy;
X return(cc);
X}
X
Xdo_mname(){
Xchar buf[BUFSZ];
Xcoord cc;
Xregister int cx,cy,lth,i;
Xregister struct monst *mtmp, *mtmp2;
Xextern char *lmonnam();
X cc = getpos(0, "the monster you want to name");
X cx = cc.x;
X cy = cc.y;
X if(cx < 0) return(0);
X#ifdef DGKMOD
X if (cx == u.ux && cy == u.uy) {
X pline("This ugly monster is called %s and cannot be renamed.",
X plname);
X return(1);
X }
X if (!cansee(cx, cy) || !(mtmp = m_at(cx, cy)) || mtmp->mimic) {
X pline("I see no monster there.");
X return(1);
X }
X#else
X mtmp = m_at(cx,cy);
X if(!mtmp){
X if(cx == u.ux && cy == u.uy)
X pline("This ugly monster is called %s and cannot be renamed.",
X plname);
X else
X pline("There is no monster there.");
X return(1);
X }
X if(mtmp->mimic){
X pline("I see no monster there.");
X return(1);
X }
X if(!cansee(cx,cy)) {
X pline("I cannot see a monster there.");
X return(1);
X }
X#endif
X pline("What do you want to call %s? ", lmonnam(mtmp));
X getlin(buf);
X clrlin();
X if(!*buf || *buf == '\033')
X return(1);
X lth = strlen(buf)+1;
X if(lth > 63){
X buf[62] = 0;
X lth = 63;
X }
X mtmp2 = newmonst(mtmp->mxlth + lth);
X *mtmp2 = *mtmp;
X for(i=0; i<mtmp->mxlth; i++)
X ((char *) mtmp2->mextra)[i] = ((char *) mtmp->mextra)[i];
X mtmp2->mnamelth = lth;
X (void) strcpy(NAME(mtmp2), buf);
X replmon(mtmp,mtmp2);
X return(1);
X}
X
X/*
X * This routine changes the address of obj . Be careful not to call it
X * when there might be pointers around in unknown places. For now: only
X * when obj is in the inventory.
X */
Xdo_oname(obj) register struct obj *obj; {
Xregister struct obj *otmp, *otmp2;
Xregister lth;
Xchar buf[BUFSZ];
X pline("What do you want to name %s? ", doname(obj));
X getlin(buf);
X clrlin();
X if(!*buf || *buf == '\033')
X return;
X lth = strlen(buf)+1;
X if(lth > 63){
X buf[62] = 0;
X lth = 63;
X }
X otmp2 = newobj(lth);
X *otmp2 = *obj;
X otmp2->onamelth = lth;
X (void) strcpy(ONAME(otmp2), buf);
X
X setworn((struct obj *) 0, obj->owornmask);
X setworn(otmp2, otmp2->owornmask);
X
X /* do freeinv(obj); etc. by hand in order to preserve
X the position of this object in the inventory */
X if(obj == invent) invent = otmp2;
X else for(otmp = invent; ; otmp = otmp->nobj){
X if(!otmp)
X panic("Do_oname: cannot find obj.");
X if(otmp->nobj == obj){
X otmp->nobj = otmp2;
X break;
X }
X }
X /* obfree(obj, otmp2); /* now unnecessary: no pointers on bill */
X free((char *) obj); /* let us hope nobody else saved a pointer */
X}
X
Xddocall()
X{
X register struct obj *obj;
X char ch;
X
X#ifdef REDO
X if (!in_doagain)
X#endif
X pline("Do you want to name an individual object? [ny] ");
X switch(ch = readchar()) {
X case '\033':
X break;
X case 'y':
X#ifdef REDO
X savech(ch);
X#endif
X obj = getobj("#", "name");
X if(obj) do_oname(obj);
X break;
X default:
X#ifdef REDO
X savech(ch);
X#endif
X#ifdef KAA
X obj = getobj("?!=/*", "call");
X#else
X obj = getobj("?!=/", "call");
X#endif
X if(obj) docall(obj);
X }
X return(0);
X}
X
Xdocall(obj)
Xregister struct obj *obj;
X{
X char buf[BUFSZ];
X struct obj otemp;
X register char **str1;
X extern char *xname();
X register char *str;
X
X otemp = *obj;
X otemp.quan = 1;
X otemp.onamelth = 0;
X str = xname(&otemp);
X pline("Call %s %s: ", index(vowels,*str) ? "an" : "a", str);
X getlin(buf);
X clrlin();
X if(!*buf || *buf == '\033')
X return;
X str = newstring(strlen(buf)+1);
X (void) strcpy(str,buf);
X str1 = &(objects[obj->otyp].oc_uname);
X if(*str1) free(*str1);
X *str1 = str;
X}
X
Xchar *ghostnames[] = { /* these names should have length < PL_NSIZ */
X#ifdef DGKMOD
X /* Capitalize the names for asthetics -dgk
X */
X "Adri", "Andries", "Andreas", "Bert", "David", "Dirk", "Emile",
X "Frans", "Fred", "Greg", "Hether", "Jay", "John", "Jon", "Karnov",
X "Kay", "Kenny", "Maud", "Michiel", "Mike", "Peter", "Robert",
X "Ron", "Tom", "Wilmar", "Nick Danger", "Phoenix", "Miracleman"
X#else
X "adri", "andries", "andreas", "bert", "david", "dirk", "emile",
X "frans", "fred", "greg", "hether", "jay", "john", "jon", "kay",
X "kenny", "maud", "michiel", "mike", "peter", "robert", "ron",
X "tom", "wilmar"
X#endif
X};
X
Xchar *
Xxmonnam(mtmp, vb) register struct monst *mtmp; int vb; {
Xstatic char buf[BUFSZ]; /* %% */
Xextern char *shkname();
X if(mtmp->mnamelth && !vb) {
X (void) strcpy(buf, NAME(mtmp));
X return(buf);
X }
X switch(mtmp->data->mlet) {
X case ' ':
X { register char *gn = (char *) mtmp->mextra;
X if(!*gn) { /* might also look in scorefile */
X gn = ghostnames[rn2(SIZE(ghostnames))];
X if(!rn2(2)) (void)
X strcpy((char *) mtmp->mextra, !rn2(5) ? plname : gn);
X }
X (void) sprintf(buf, "%s's ghost", gn);
X }
X break;
X case '@':
X if(mtmp->isshk) {
X (void) strcpy(buf, shkname(mtmp));
X break;
X }
X /* fall into next case */
X default:
X (void) sprintf(buf, "the %s%s",
X mtmp->minvis ? "invisible " : "",
X (Hallucination ? rndmonnam() : mtmp->data->mname));
X }
X if(vb && mtmp->mnamelth) {
X (void) strcat(buf, " called ");
X (void) strcat(buf, NAME(mtmp));
X }
X return(buf);
X}
X
Xchar *
Xlmonnam(mtmp) register struct monst *mtmp; {
X return(xmonnam(mtmp, 1));
X}
X
Xchar *
Xmonnam(mtmp) register struct monst *mtmp; {
X return(xmonnam(mtmp, 0));
X}
X
Xchar *
XMonnam(mtmp) register struct monst *mtmp; {
Xregister char *bp = monnam(mtmp);
X if('a' <= *bp && *bp <= 'z') *bp += ('A' - 'a');
X return(bp);
X}
X
Xchar *
Xamonnam(mtmp,adj)
Xregister struct monst *mtmp;
Xregister char *adj;
X{
X register char *bp = monnam(mtmp);
X static char buf[BUFSZ]; /* %% */
X
X if(!strncmp(bp, "the ", 4)) bp += 4;
X (void) sprintf(buf, "the %s %s", adj, bp);
X return(buf);
X}
X
Xchar *
XAmonnam(mtmp, adj)
Xregister struct monst *mtmp;
Xregister char *adj;
X{
X register char *bp = amonnam(mtmp,adj);
X
X *bp = 'T';
X return(bp);
X}
X
Xchar *
XXmonnam(mtmp) register struct monst *mtmp; {
Xregister char *bp = Monnam(mtmp);
X if(!strncmp(bp, "The ", 4)) {
X#ifdef KAA
X if(index("AEIOUaeio",*(bp+4))) {
X bp += 1; *(bp+1) = 'n';
X } else
X#endif
X bp += 2;
X *bp = 'A';
X }
X return(bp);
X}
X
Xchar *
Xdefmonnam(mtmp) register struct monst *mtmp; {
Xregister char *bp = Xmonnam(mtmp);
X if (!strncmp(bp,"A ",2) || !strncmp(bp,"An ",3))
X *bp = 'a';
X return(bp);
X}
X
Xchar *
Xrndmonnam() { /* Random name of monster type, if hallucinating */
Xint x;
X if ((x=rn2(CMNUM+2)) != CMNUM+1) return (&mons[x])->mname;
X return("giant eel");
X}
X
Xchar *
Xvisctrl(c)
Xchar c;
X{
Xstatic char ccc[3];
X if(c < 040) {
X ccc[0] = '^';
X ccc[1] = c + 0100;
X ccc[2] = 0;
X } else {
X ccc[0] = c;
X ccc[1] = 0;
X }
X return(ccc);
X}
END_OF_do_name.c
if test 7462 -ne `wc -c <do_name.c`; then
echo shar: \"do_name.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dogmove.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"dogmove.c\"
else
echo shar: Extracting \"dogmove.c\" \(7601 characters\)
sed "s/^X//" >dogmove.c <<'END_OF_dogmove.c'
X/* SCCS Id: @(#)dogmove.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* dogmove.c - version 1.0 */
X
X#include "hack.h"
X#include "mfndpos.h"
X#include "mkroom.h"
X#include "edog.h"
X
X/* return 0 (no move), 1 (move) or 2 (dead) */
Xdog_move(mtmp, after) register struct monst *mtmp; {
X#ifndef REGBUG
Xregister
X#endif
X int nx,ny,omx,omy,appr,nearer,j;
Xint udist,chi,i,whappr;
Xregister struct monst *mtmp2;
Xregister struct permonst *mdat = mtmp->data;
Xregister struct edog *edog = EDOG(mtmp);
Xstruct obj *obj;
Xstruct trap *trap;
Xxchar cnt,chcnt,nix,niy;
Xschar dogroom,uroom;
Xxchar gx,gy,gtyp,otyp; /* current goal */
Xcoord poss[9];
Xlong info[9];
X#define GDIST(x,y) ((x-gx)*(x-gx) + (y-gy)*(y-gy))
X#define DDIST(x,y) ((x-omx)*(x-omx) + (y-omy)*(y-omy))
X
X if(moves <= edog->eattime) return(0); /* dog is still eating */
X omx = mtmp->mx;
X omy = mtmp->my;
X whappr = (moves - EDOG(mtmp)->whistletime < 5);
X if(moves > edog->hungrytime + 500 && !mtmp->mconf){
X mtmp->mconf = 1;
X mtmp->mhpmax /= 3;
X if(mtmp->mhp > mtmp->mhpmax)
X mtmp->mhp = mtmp->mhpmax;
X if(cansee(omx,omy))
X pline("%s is confused from hunger.", Monnam(mtmp));
X else pline("You feel worried about %s.", monnam(mtmp));
X } else
X if(moves > edog->hungrytime + 750 || mtmp->mhp < 1){
X if(cansee(omx,omy))
X pline("%s dies from hunger.", Monnam(mtmp));
X else
X#ifdef WALKIES
X mtmp->mleashed = 0;
X pline("Your leash goes slack...");
X#endif
X pline("You have a sad feeling for a moment, then it passes.");
X mondied(mtmp);
X return(2);
X }
X dogroom = inroom(omx,omy);
X uroom = inroom(u.ux,u.uy);
X udist = dist(omx,omy);
X
X /* maybe we tamed him while being swallowed --jgm */
X if(!udist) return(0);
X
X /* if we are carrying sth then we drop it (perhaps near @) */
X /* Note: if apport == 1 then our behaviour is independent of udist */
X if(mtmp->minvent){
X if(!rn2(udist) || !rn2((int) edog->apport))
X if(rn2(10) < edog->apport){
X relobj(mtmp, (int) mtmp->minvis);
X if(edog->apport > 1) edog->apport--;
X edog->dropdist = udist; /* hpscdi!jon */
X edog->droptime = moves;
X }
X } else {
X if(obj = o_at(omx,omy)) if(!index("0_", obj->olet)){
X if((otyp = dogfood(obj)) <= CADAVER){
X nix = omx;
X niy = omy;
X goto eatobj;
X }
X if(obj->owt < 10*mtmp->data->mlevel)
X if(rn2(20) < edog->apport+3)
X if(rn2(udist) || !rn2((int) edog->apport)){
X freeobj(obj);
X unpobj(obj);
X /* if(levl[omx][omy].scrsym == obj->olet)
X newsym(omx,omy); */
X mpickobj(mtmp,obj);
X }
X }
X }
X
X gtyp = UNDEF; /* no goal as yet */
X gx = gy = 0; /* suppress 'used before set' message */
X#ifdef WALKIES
X /* If he's on a leash, he's not going anywhere. */
X if(mtmp->mleashed) {
X
X gtyp = APPORT;
X gx = u.ux;
X gy = u.uy;
X } else
X#endif
X /* first we look for food */
X for(obj = fobj; obj; obj = obj->nobj) {
X otyp = dogfood(obj);
X if(otyp > gtyp || otyp == UNDEF) continue;
X if(inroom(obj->ox,obj->oy) != dogroom) continue;
X if(otyp < MANFOOD &&
X (dogroom >= 0 || DDIST(obj->ox,obj->oy) < 10)) {
X if(otyp < gtyp || (otyp == gtyp &&
X DDIST(obj->ox,obj->oy) < DDIST(gx,gy))){
X gx = obj->ox;
X gy = obj->oy;
X gtyp = otyp;
X }
X } else
X if(gtyp == UNDEF && dogroom >= 0 &&
X uroom == dogroom &&
X !mtmp->minvent && edog->apport > rn2(8)){
X gx = obj->ox;
X gy = obj->oy;
X gtyp = APPORT;
X }
X }
X
X if(gtyp == UNDEF ||
X (gtyp != DOGFOOD && gtyp != APPORT && moves < edog->hungrytime)){
X if(dogroom < 0 || dogroom == uroom){
X gx = u.ux;
X gy = u.uy;
X#ifndef QUEST
X } else {
X int tmp = rooms[dogroom].fdoor;
X cnt = rooms[dogroom].doorct;
X
X gx = gy = FAR; /* random, far away */
X while(cnt--){
X if(dist(gx,gy) >
X dist(doors[tmp].x, doors[tmp].y)){
X gx = doors[tmp].x;
X gy = doors[tmp].y;
X }
X tmp++;
X }
X /* here gx == FAR e.g. when dog is in a vault */
X if(gx == FAR || (gx == omx && gy == omy)){
X gx = u.ux;
X gy = u.uy;
X }
X#endif
X }
X appr = (udist >= 9) ? 1 : (mtmp->mflee) ? -1 : 0;
X if(after && udist <= 4 && gx == u.ux && gy == u.uy)
X return(0);
X if(udist > 1){
X if(!IS_ROOM(levl[u.ux][u.uy].typ) || !rn2(4) ||
X whappr ||
X (mtmp->minvent && rn2((int) edog->apport)))
X appr = 1;
X }
X /* if you have dog food he'll follow you more closely */
X if(appr == 0){
X obj = invent;
X while(obj){
X if(obj->otyp == TRIPE_RATION){
X appr = 1;
X break;
X }
X obj = obj->nobj;
X }
X }
X } else appr = 1; /* gtyp != UNDEF */
X if(mtmp->mconf) appr = 0;
X
X if(gx == u.ux && gy == u.uy && (dogroom != uroom || dogroom < 0)) {
X extern coord *gettrack();
X register coord *cp;
X cp = gettrack(omx,omy);
X if(cp){
X gx = cp->x;
X gy = cp->y;
X }
X }
X
X nix = omx;
X niy = omy;
X cnt = mfndpos(mtmp,poss,info,ALLOW_M | ALLOW_TRAPS);
X chcnt = 0;
X chi = -1;
X for(i=0; i<cnt; i++){
X nx = poss[i].x;
X ny = poss[i].y;
X#ifdef WALKIES
X /* if leashed, we drag him along. */
X if(dist(nx, ny) > 4 && mtmp->mleashed) continue;
X#endif
X if(info[i] & ALLOW_M) {
X mtmp2 = m_at(nx,ny);
X if(mtmp2->data->mlevel >= mdat->mlevel+2 ||
X mtmp2->data->mlet == 'c')
X continue;
X if(after) return(0); /* hit only once each move */
X
X if(hitmm(mtmp, mtmp2) == 1 && rn2(4) &&
X mtmp2->mlstmv != moves &&
X hitmm(mtmp2,mtmp) == 2) return(2);
X return(0);
X }
X
X /* dog avoids traps */
X /* but perhaps we have to pass a trap in order to follow @ */
X if((info[i] & ALLOW_TRAPS) && (trap = t_at(nx,ny))){
X if(!trap->tseen && rn2(40)) continue;
X if(rn2(10)) continue;
X }
X
X /* dog eschewes cursed objects */
X /* but likes dog food */
X obj = fobj;
X while(obj){
X if(obj->ox != nx || obj->oy != ny)
X goto nextobj;
X if(obj->cursed) goto nxti;
X if(obj->olet == FOOD_SYM &&
X (otyp = dogfood(obj)) < MANFOOD &&
X (otyp < ACCFOOD || edog->hungrytime <= moves)){
X /* Note: our dog likes the food so much that he
X might eat it even when it conceals a cursed object */
X nix = nx;
X niy = ny;
X chi = i;
X eatobj:
X edog->eattime =
X moves + obj->quan * objects[obj->otyp].oc_delay;
X if(edog->hungrytime < moves)
X edog->hungrytime = moves;
X edog->hungrytime +=
X 5*obj->quan * objects[obj->otyp].nutrition;
X mtmp->mconf = 0;
X if(cansee(nix,niy))
X pline("%s ate %s.", Monnam(mtmp), doname(obj));
X /* perhaps this was a reward */
X if(otyp != CADAVER)
X edog->apport += 200/(edog->dropdist+moves-edog->droptime);
X delobj(obj);
X goto newdogpos;
X }
X nextobj:
X obj = obj->nobj;
X }
X
X for(j=0; j<MTSZ && j<cnt-1; j++)
X if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
X if(rn2(4*(cnt-j))) goto nxti;
X
X/* Some stupid C compilers cannot compute the whole expression at once. */
X nearer = GDIST(nx,ny);
X nearer -= GDIST(nix,niy);
X nearer *= appr;
X if((nearer == 0 && !rn2(++chcnt)) || nearer<0 ||
X (nearer > 0 && !whappr &&
X ((omx == nix && omy == niy && !rn2(3))
X || !rn2(12))
X )){
X nix = nx;
X niy = ny;
X if(nearer < 0) chcnt = 0;
X chi = i;
X }
X nxti: ;
X }
Xnewdogpos:
X if(nix != omx || niy != omy){
X if(info[chi] & ALLOW_U){
X (void) hitu(mtmp, d(mdat->damn, mdat->damd)+1);
X return(0);
X }
X mtmp->mx = nix;
X mtmp->my = niy;
X for(j=MTSZ-1; j>0; j--) mtmp->mtrack[j] = mtmp->mtrack[j-1];
X mtmp->mtrack[0].x = omx;
X mtmp->mtrack[0].y = omy;
X }
X#ifdef WALKIES
X /* an incredible kluge, but the only way to keep pooch near
X * after he spends time eating or in a trap, etc...
X */
X else if(mtmp->mleashed && dist(omx, omy) > 4) mnexto(mtmp);
X#endif
X
X if(mintrap(mtmp) == 2) { /* he died */
X#ifdef WALKIES
X mtmp->mleashed = 0;
X#endif
X return(2);
X }
X pmon(mtmp);
X return(1);
X}
END_OF_dogmove.c
if test 7601 -ne `wc -c <dogmove.c`; then
echo shar: \"dogmove.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f dothrow.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"dothrow.c\"
else
echo shar: Extracting \"dothrow.c\" \(6819 characters\)
sed "s/^X//" >dothrow.c <<'END_OF_dothrow.c'
X/* SCCS Id: @(#)dothrow.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* dothrow.c - version 1.0 */
X
X/* Contains code for 't' (throw) */
X
X#include "hack.h"
X
Xextern struct obj *splitobj(), *addinv();
Xextern boolean hmon();
Xextern struct monst youmonst;
Xextern char *Doname();
X#ifdef KAA
Xextern char *xname();
X#endif
X
Xstruct monst *bhit(), *boomhit();
Xdothrow()
X{
X register struct obj *obj;
X
X obj = getobj("#)", "throw"); /* it is also possible to throw food */
X /* (or jewels, or iron balls ... ) */
X if(!obj || !getdir(1)) /* ask "in what direction?" */
X return(0);
X if(obj->owornmask & (W_ARMOR | W_RING)){
X pline("You can't throw something you are wearing.");
X return(0);
X }
X#ifdef KAA
X if(obj->otyp == ENORMOUS_ROCK && u.usym != '9') {
X pline("It's too heavy.");
X return(1);
X }
X if(!u.dx && !u.dy && !u.dz) {
X pline("You cannot throw an object at yourself.");
X return(0);
X }
X#endif
X u_wipe_engr(2);
X
X if(obj == uwep){
X if(obj->cursed){
X pline("Your weapon is welded to your hand.");
X return(1);
X }
X if(obj->quan > 1)
X setuwep(splitobj(obj, 1));
X else
X setuwep((struct obj *) 0);
X }
X else if(obj->quan > 1)
X (void) splitobj(obj, 1);
X freeinv(obj);
X return(throwit(obj));
X}
X
Xthrowit(obj)
X register struct obj *obj;
X{
X register struct monst *mon;
X
X if(u.uswallow) {
X mon = u.ustuck;
X bhitpos.x = mon->mx;
X bhitpos.y = mon->my;
X } else if(u.dz) {
X if(u.dz < 0) {
X pline("%s hits the ceiling, then falls back on top of your head.",
X Doname(obj)); /* note: obj->quan == 1 */
X if(obj->olet == POTION_SYM)
X potionhit(&youmonst, obj);
X else {
X if(uarmh) pline("Fortunately, you are wearing a helmet!");
X losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object");
X dropy(obj);
X }
X } else hitfloor(obj);
X return(1);
X
X } else if(obj->otyp == BOOMERANG) {
X mon = boomhit(u.dx, u.dy);
X if(mon == &youmonst) { /* the thing was caught */
X (void) addinv(obj);
X return(1);
X }
X } else {
X if(obj->otyp == PICK_AXE && shkcatch(obj))
X return(1);
X
X mon = bhit(u.dx, u.dy, (obj->otyp == ICE_BOX) ? 1 :
X (!Punished || obj != uball) ? 8 : !u.ustuck ? 5 : 1,
X obj->olet,
X (int (*)()) 0, (int (*)()) 0, obj);
X }
X if(mon) {
X /* awake monster if sleeping */
X wakeup(mon);
X if(thitmonst(mon, obj)) return(1);
X }
X if(!u.uswallow) {
X /* the code following might become part of dropy() */
X if(obj->otyp == CRYSKNIFE)
X obj->otyp = WORM_TOOTH;
X obj->ox = bhitpos.x;
X obj->oy = bhitpos.y;
X obj->nobj = fobj;
X fobj = obj;
X /* prevent him from throwing articles to the exit and escaping */
X /* subfrombill(obj); */
X stackobj(obj);
X if(Punished && obj == uball &&
X (bhitpos.x != u.ux || bhitpos.y != u.uy)){
X freeobj(uchain);
X unpobj(uchain);
X if(u.utrap){
X if(u.utraptype == TT_PIT)
X pline("The ball pulls you out of the pit!");
X#ifdef SPIDERS
X else if(u.utraptype == TT_WEB) {
X pline("The ball pulls you out of the web!");
X pline("The web is destroyed!");
X deltrap(t_at(u.ux,u.uy));
X }
X#endif
X else {
X register long side =
X rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
X pline("The ball pulls you out of the bear trap.");
X pline("Your %s leg is severely damaged.",
X (side == LEFT_SIDE) ? "left" : "right"); set_wounded_legs(side, 500+rn2(1000));
X losehp(2, "thrown ball");
X }
X u.utrap = 0;
X }
X unsee();
X uchain->nobj = fobj;
X fobj = uchain;
X u.ux = uchain->ox = bhitpos.x - u.dx;
X u.uy = uchain->oy = bhitpos.y - u.dy;
X setsee();
X (void) inshop();
X }
X if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
X } else
X mpickobj(u.ustuck,obj);
X return(1);
X}
X
Xhitfloor(obj)
X register struct obj *obj;
X{
X pline("%s hits the floor.", Doname(obj));
X if(obj->otyp == EXPENSIVE_CAMERA) {
X pline("It is shattered in a thousand pieces!");
X obfree(obj, Null(obj));
X } else if(obj->otyp == EGG) {
X pline("\"Splash!\"");
X obfree(obj, Null(obj));
X#ifdef KAA
X } else if(obj->otyp == CREAM_PIE) {
X pline("What a mess!");
X obfree(obj, Null(obj));
X#endif
X } else if(obj->olet == POTION_SYM) {
X pline("The flask breaks, and you smell a peculiar odor ...");
X potionbreathe(obj);
X obfree(obj, Null(obj));
X } else
X dropy(obj);
X}
X
Xthitmonst(mon, obj)
X register struct monst *mon;
X register struct obj *obj;
X{
X register int tmp;
X
X if(obj->olet == WEAPON_SYM) {
X tmp = -1+u.ulevel+mon->data->ac+abon();
X if(obj->otyp < DART) {
X if(!uwep ||
X uwep->otyp != obj->otyp+(BOW-ARROW))
X tmp -= 4;
X else {
X tmp += uwep->spe;
X }
X } else
X if(obj->otyp == BOOMERANG) tmp += 4;
X tmp += obj->spe;
X if(u.uswallow || tmp >= rnd(20)) {
X if(hmon(mon,obj,1) == TRUE){
X /* mon still alive */
X#ifndef NOWORM
X cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
X#endif
X } else mon = 0;
X /* weapons thrown disappear sometimes */
X if(obj->otyp < BOOMERANG && rn2(3)) {
X /* check bill; free */
X obfree(obj, (struct obj *) 0);
X return(1);
X }
X } else miss(objects[obj->otyp].oc_name, mon);
X } else if(obj->otyp == HEAVY_IRON_BALL) {
X tmp = -1+u.ulevel+mon->data->ac+abon();
X if(!Punished || obj != uball) tmp += 2;
X if(u.utrap) tmp -= 2;
X if(u.uswallow || tmp >= rnd(20)) {
X if(hmon(mon,obj,1) == FALSE)
X mon = 0; /* he died */
X } else miss("iron ball", mon);
X#ifdef KAA
X } else if (obj->otyp == ENORMOUS_ROCK) {
X tmp = 15+mon->data->ac; /* Very likely to hit! */
X if (hmon(mon, obj, 1) == FALSE) mon=0;
X else miss("enormous rock",mon);
X } else if(obj->otyp == CREAM_PIE &&
X (u.ulevel > rn2(10)) || u.ustuck == mon) {
X pline("The cream pie splashes over %s%s!",monnam(mon),
X index("aEfgy",mon->data->mlet) ? "" : "'s face");
X obfree(obj, (struct obj *) 0);
X if(mon->msleep) mon->msleep = 0;
X setmangry(mon);
X mon->mcansee = 0;
X mon->mblinded += rnd(25);
X if (mon->mblinded <= 0) mon->mblinded = 127;
X return(1);
X#endif
X } else if(obj->olet == POTION_SYM && u.ulevel > rn2(15)) {
X potionhit(mon, obj);
X return(1);
X } else {
X pline("The %s misses %s.",xname(obj),
X cansee(bhitpos.x,bhitpos.y) ? monnam(mon) : "it");
X
X if(obj->olet == FOOD_SYM && mon->data->mlet == 'd')
X if(tamedog(mon,obj)) return(1);
X if(obj->olet == GEM_SYM && mon->data->mlet == 'u' &&
X !mon->mtame){
X char buf[BUFSZ];
X char *nogood = " is not interested in your junk.";
X char *addluck = " graciously accepts your gift.";
X
X strcpy(buf,Monnam(mon));
X
X if(obj->dknown &&
X objects[obj->otyp].oc_name_known) {
X if(objects[obj->otyp].g_val > 0) {
X u.uluck += 5;
X strcat(buf,addluck);
X } else
X strcat(buf,nogood);
X } else { /* value unknown to @ */
X u.uluck++;
X strcat(buf,addluck);
X }
X if(u.uluck > LUCKMAX) /* dan@ut-ngp */
X u.uluck = LUCKMAX;
X pline(buf);
X mpickobj(mon, obj);
X rloc(mon);
X return(1);
X }
X }
X return(0);
X}
END_OF_dothrow.c
if test 6819 -ne `wc -c <dothrow.c`; then
echo shar: \"dothrow.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f end.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"end.c\"
else
echo shar: Extracting \"end.c\" \(7029 characters\)
sed "s/^X//" >end.c <<'END_OF_end.c'
X/* SCCS Id: @(#)end.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* end.c - version 1.0.3 */
X
X#include <stdio.h>
X#include <signal.h>
X#include "hack.h"
X#define Sprintf (void) sprintf
Xextern char plname[], pl_character[];
X
Xxchar maxdlevel = 1;
Xint done_stopprint;
Xint done_hup;
X
X
Xdone1()
X{
X (void) signal(SIGINT,SIG_IGN);
X#if defined(WIZARD) && defined(UNIX)
X if(wizard) {
X pline("Dump core?");
X if(readchar() == 'y') {
X (void) signal(SIGINT,done1);
X abort();
X }
X }
X#endif
X pline("Really quit?");
X if(readchar() != 'y') {
X (void) signal(SIGINT,done1);
X clrlin();
X (void) fflush(stdout);
X if(multi > 0) nomul(0);
X return(0);
X }
X done("quit");
X /* NOTREACHED */
X}
X
Xdone_intr(){
X done_stopprint++;
X (void) signal(SIGINT, SIG_IGN);
X#ifdef UNIX
X (void) signal(SIGQUIT, SIG_IGN);
X#endif
X}
X
X#ifdef UNIX
Xdone_hangup(){
X done_hup++;
X (void) signal(SIGHUP, SIG_IGN);
X done_intr();
X}
X#endif
X
Xdone_in_by(mtmp) register struct monst *mtmp; {
Xstatic char buf[BUFSZ];
X pline("You die ...");
X if(mtmp->data->mlet == ' '){
X Sprintf(buf, "the ghost of %s", (char *) mtmp->mextra);
X killer = buf;
X } else if(mtmp->mnamelth) {
X Sprintf(buf, "%s called %s",
X mtmp->data->mname, NAME(mtmp));
X killer = buf;
X } else if(mtmp->minvis) {
X Sprintf(buf, "invisible %s", mtmp->data->mname);
X killer = buf;
X } else killer = mtmp->data->mname;
X done("died");
X}
X
X/*VARARGS1*/
Xboolean panicking;
X
Xpanic(str,a1,a2,a3,a4,a5,a6)
Xchar *str;
X{
X if(panicking++) abort(); /* avoid loops - this should never happen*/
X /* was exit(1) */
X home(); cls();
X puts(" Suddenly, the dungeon collapses.");
X fputs(" ERROR: ", stdout);
X printf(str,a1,a2,a3,a4,a5,a6);
X more(); /* contains a fflush() */
X#ifdef WIZARD
X# ifdef UNIX
X if (wizard) abort(); /* generate core dump */
X# endif
X#endif
X done("panicked");
X}
X
X/* called with arg "died", "drowned", "escaped", "quit", "choked", "panicked",
X "burned", "starved" or "tricked" */
X/* Be careful not to call panic from here! */
Xdone(st1)
Xregister char *st1;
X{
X#ifdef DIAGS
X char c;
X#endif
X#ifdef WIZARD
X extern char *nomovemsg;
X
X if(wizard && index("bcds", *st1)){
X char buf[BUFSZ];
X pline("Die? ");
X getlin(buf);
X if(index("yY",buf[0])) goto die;
X u.uswldtim = 0;
X if(u.uhpmax < 0) u.uhpmax = 100; /* arbitrary */
X u.uhp = u.uhpmax;
X pline("Ok, so you don't die.");
X nomovemsg = "You survived that attempt on your life.";
X flags.move = 0;
X if(multi > 0) multi = 0; else multi = -1;
X flags.botl = 1;
X return;
X }
X#endif /* WIZARD /**/
Xdie:
X (void) signal(SIGINT, done_intr);
X#ifdef UNIX
X (void) signal(SIGQUIT, done_intr);
X (void) signal(SIGHUP, done_hangup);
X#endif
X if(*st1 == 'q' && u.uhp < 1){
X st1 = "died";
X killer = "quit while already on Charon's boat";
X }
X if(*st1 == 's') killer = "starvation"; else
X if(*st1 == 'd' && st1[1] == 'r') killer = "drowning"; else
X if(*st1 == 'p') killer = "panic"; else
X if(*st1 == 't') killer = "trickery"; else
X if(!index("bcd", *st1)) killer = st1;
X paybill();
X clearlocks();
X if(flags.toplin == 1) more();
X#ifdef DIAGS
X pline("Do you want to have your possessions identified? [Yynq] ");
X if ((c = readchar()) == 'y' || c == 'Y') {
X struct obj *obj;
X for(obj = invent; obj && !done_stopprint; obj = obj->nobj)
X identify(obj);
X pline("That's all, folks!"), more();
X }
X if (c == 'q' || c == 'Y') done_stopprint++;
X#endif
X if(index("bcds", *st1)){
X#ifdef WIZARD
X if(wizard) {
X char buf[BUFSZ];
X pline("Save bones? ");
X getlin(buf);
X if(buf[0] == 'y') savebones();
X } else
X#endif
X savebones();
X if(!flags.notombstone) outrip();
X }
X if(*st1 == 'c') killer = st1; /* after outrip() */
X settty((char *) 0); /* does a clear_screen() */
X if(!done_stopprint)
X printf("Goodbye %s %s...\n\n", pl_character, plname);
X { long int tmp;
X tmp = u.ugold - u.ugold0;
X if(tmp < 0)
X tmp = 0;
X if(*st1 == 'd' || *st1 == 'b')
X tmp -= tmp/10;
X u.urexp += tmp;
X u.urexp += 50 * maxdlevel;
X if(maxdlevel > 20)
X u.urexp += 1000*((maxdlevel > 30) ? 10 : maxdlevel - 20);
X }
X if(*st1 == 'e') {
X extern struct monst *mydogs;
X register struct monst *mtmp;
X register struct obj *otmp;
X#ifdef DGKMOD
X long i;
X#else
X register int i;
X#endif
X register unsigned worthlessct = 0;
X boolean has_amulet = FALSE;
X
X killer = st1;
X keepdogs();
X mtmp = mydogs;
X if(mtmp) {
X if(!done_stopprint) printf("You");
X while(mtmp) {
X if(!done_stopprint)
X printf(" and %s", monnam(mtmp));
X if(mtmp->mtame)
X u.urexp += mtmp->mhp;
X mtmp = mtmp->nmon;
X }
X if(!done_stopprint)
X printf("\nescaped from the dungeon with %ld points,\n",
X u.urexp);
X } else
X if(!done_stopprint)
X printf("You escaped from the dungeon with %ld points,\n",
X u.urexp);
X for(otmp = invent; otmp; otmp = otmp->nobj) {
X if(otmp->olet == GEM_SYM){
X objects[otmp->otyp].oc_name_known = 1;
X#ifdef DGKMOD
X i = (long) otmp->quan *
X objects[otmp->otyp].g_val;
X#else
X i = otmp->quan*objects[otmp->otyp].g_val;
X#endif
X if(i == 0) {
X worthlessct += otmp->quan;
X continue;
X }
X u.urexp += i;
X#ifndef DGKMOD
X if(!done_stopprint)
X printf("\t%s (worth %d Zorkmids),\n",
X#else
X printf(" %s (worth %ld Zorkmids),\n",
X#endif
X doname(otmp), i);
X } else if(otmp->olet == AMULET_SYM) {
X otmp->known = 1;
X i = (otmp->spe < 0) ? 2 : 5000;
X u.urexp += i;
X#ifndef DGKMOD
X if(!done_stopprint)
X printf("\t%s (worth %d Zorkmids),\n",
X#else
X printf(" %s (worth %d Zorkmids),\n",
X#endif
X doname(otmp), i);
X if(otmp->spe >= 0) {
X has_amulet = TRUE;
X killer = "escaped (with amulet)";
X }
X }
X }
X if(worthlessct)
X#ifndef DGKMOD
X if(!done_stopprint)
X printf("\t%u worthless piece%s of coloured glass,\n",
X#else
X printf(" %u worthless piece%s of coloured glass,\n",
X#endif
X worthlessct, plur(worthlessct));
X if(has_amulet) u.urexp *= 2;
X } else
X if(!done_stopprint)
X printf("You %s on dungeon level %d with %ld points,\n",
X st1, dlevel, u.urexp);
X if(!done_stopprint)
X printf("and %ld piece%s of gold, after %ld move%s.\n",
X u.ugold, plur(u.ugold), moves, plur(moves));
X if(!done_stopprint)
X printf("You were level %u with a maximum of %d hit points when you %s.\n",
X u.ulevel, u.uhpmax, st1);
X if(*st1 == 'e' && !done_stopprint){
X getret(); /* all those pieces of coloured glass ... */
X cls();
X }
X#ifdef WIZARD
X if(!wizard)
X#endif
X topten();
X if(done_stopprint) printf("\n\n");
X#ifdef APOLLO
X getret();
X#endif
X exit(0);
X}
Xclearlocks(){
X#ifdef DGK
X eraseall(levels, alllevels);
X if (ramdisk)
X eraseall(permbones, alllevels);
X#else
X# ifdef UNIX
Xregister x;
X (void) signal(SIGHUP,SIG_IGN);
X for(x = maxdlevel; x >= 0; x--) {
X glo(x);
X (void) unlink(lock); /* not all levels need be present */
X }
X# endif
X#endif
X}
X
X#ifdef NOSAVEONHANGUP
Xhangup()
X{
X (void) signal(SIGINT, SIG_IGN);
X clearlocks();
X exit(1);
X}
X#endif
X
X/* it is the callers responsibility to check that there is room for c */
Xcharcat(s,c) register char *s, c; {
X while(*s) s++;
X *s++ = c;
X *s = 0;
X}
END_OF_end.c
if test 7029 -ne `wc -c <end.c`; then
echo shar: \"end.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f fountain.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"fountain.c\"
else
echo shar: Extracting \"fountain.c\" \(7103 characters\)
sed "s/^X//" >fountain.c <<'END_OF_fountain.c'
X/* SCCS Id: @(#)fountain.c 1.3 87/07/14
X/* fountain.c v 1.4.1 */
X
X/*
X * Revision 1.4.1 87/05/20 11:53:00 M. Stephenson
X * Implementation of KAA bug fixes.
X *
X * Revision 1.4 87/05/04 17:39:00 M. Stephenson
X * Integration of independent modifications
X *
X * Revision 1.3 87/03/02 Eric Backus
X * Rearranged, and dipfountain added
X *
X * Revision 1.2 87/03/01 13:59:59 gil
X * patches
X *
X * Revision 1.1 87/02/11 15:14:10 gil
X * Initial revision
X *
X */
X
X/* Code for drinking from fountains. */
X/* Scott R. Turner, srt@ucla, 10/27/86 */
X
X#include "hack.h"
X
Xextern struct monst *mkmon_at();
Xextern char genocided[];
X
X#ifdef FOUNTAINS
X#define somex() ((rand()%(croom->hx-croom->lx+1))+croom->lx)
X#define somey() ((rand()%(croom->hy-croom->ly+1))+croom->ly)
X
Xdowatersnakes() /* Fountain of snakes! */ {
X register int num = rnd(6);
X if (!index(genocided, 'S')) {
X
X pline("Good Lord! An endless stream of snakes pours forth!");
X while(num-- > 0) (void) mkmon_at('S',u.ux,u.uy);
X } else
X pline("The fountain bubbles furiously for a moment, then calms.");
X}
X
Xdowaterdemon() /* Water demon */ {
Xregister struct monst *mtmp;
X
X pline("You have unleashed a water demon!");
X mtmp = mkmon_at('&',u.ux,u.uy);
X if (rnd(100)>97) {
X pline("He is grateful for his release and grants you a wish!");
X makewish();
X mondied(mtmp);
X }
X}
X
Xdowaternymph() /* Water Nymph */ {
X register struct monst *mtmp;
X if(!index(genocided, 'N')) {
X
X pline("You have attracted a water nymph!");
X mtmp = mkmon_at('N',u.ux,u.uy);
X mtmp->msleep = 0;
X } else
X pline("A large bubble rises to the surface and pops.");
X}
X
X#include "mkroom.h"
X
Xdogushforth() /* Gushing forth in this room */ {
Xregister int num = rnd(10);
Xregister xchar mx,my;
Xregister int tryct = 0;
Xregister int uroom = inroom(u.ux, u.uy);
Xregister struct mkroom *croom = &rooms[uroom];
Xregister int madepool = 0;
X
X if(croom->hx < 0 || has_upstairs(croom) ||
X has_dnstairs(croom)) {
X pline("Your thirst is quenched.");
X return;
X }
X while(num--) {
X do {
X if(++tryct > 200) {
X if(madepool)
X pline("Water gushes forth from the overflowing fountain!");
X else
X pline("Your thirst is quenched.");
X return;
X }
X mx = somex();
X my = somey();
X } while(nexttodoor(mx,my) || !((mx+my)%2) ||
X (mx == u.ux && my == u.uy) ||
X (IS_POOL(levl[mx][my].typ)));
X
X /* Put a pool at mx, my */
X
X levl[mx][my].typ = POOL;
X atl(mx,my,POOL_SYM);
X madepool = 1;
X }
X
X pline("Water gushes forth from the overflowing fountain!");
X}
X
Xdofindgem() /* Find a gem in the sparkling waters. */ {
X
X if (!Blind) pline("You spot a gem in the sparkling waters!");
X mkobj_at('*',u.ux,u.uy);
X}
X
Xdryup(){
X if (!rn2(5) && (levl[u.ux][u.uy].typ == FOUNTAIN)) {
X pline("The fountain dries up!");
X levl[u.ux][u.uy].typ = ROOM;
X if(Invis) newsym(u.ux, u.uy);
X }
X}
X
Xdrinkfountain(){
X
X /* What happens when you drink from a fountain? */
X
X register int fate = rnd(30);
X
X if (fate < 10) {
X pline("The cool draught refreshes you.");
X lesshungry(rnd(10));
X }
X else
X switch (fate) {
X
X case 20: /* Foul water */
X
X pline("The water is foul! You gag and vomit.");
X morehungry(rnd(20)+10);
X if(Sick) {
X Sick = 0;
X pline("What a relief!");
X }
X break;
X
X case 21: /* Poisonous */
X
X pline("The water is contaminated!");
X if (Poison_resistance) {
X pline("Perhaps it is run off from the nearby orange farm.");
X losehp(rnd(4),"contaminated water");
X break;
X }
X losestr(rn1(4,3));
X losehp(rnd(10),"contaminated water");
X break;
X
X case 22: /* Fountain of snakes! */
X dowatersnakes();
X break;
X
X case 23: /* Water demon */
X dowaterdemon();
X break;
X
X case 24: /* Curse an item... */ {
X register struct obj *obj;
X
X pline("This water's no good!");
X morehungry(rnd(20)+10);
X for(obj = invent; obj ; obj = obj->nobj)
X if (!rn2(5)) obj->cursed++;
X break;
X }
X
X case 25: /* See invisible */
X
X pline("You see an image of someone stalking you.");
X pline("But it disappears.");
X HSee_invisible |= INTRINSIC;
X break;
X
X case 26: /* See Monsters */{
X
X register struct monst *mtmp;
X if(!fmon) {
X pline("You feel oddly disturbed.");
X } else {
X cls();
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->mx > 0)
X at(mtmp->mx,mtmp->my,mtmp->data->mlet);
X prme();
X pline("You sense the presence of monsters.");
X more();
X docrt();
X }
X break; }
X
X case 27: /* Find a gem in the sparkling waters. */
X dofindgem();
X break;
X
X case 28: /* Water Nymph */
X dowaternymph();
X break;
X
X case 29: /* Scare */ {
X register struct monst *mtmp;
X
X pline("This water gives you bad breath!");
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X mtmp->mflee = 1;
X }
X break;
X
X case 30: /* Gushing forth in this room */
X dogushforth();
X break;
X }
X
X dryup();
X
X}
X
Xdipfountain(obj)
Xregister struct obj *obj;
X{
X register int fate = rnd(30);
X
X if(fate<10)
X if(!obj->rustfree &&
X /* Only swords affected here */
X (obj->otyp == LONG_SWORD ||
X obj->otyp == KATANA ||
X obj->otyp == BROAD_SWORD ||
X obj->otyp == SHORT_SWORD ||
X obj->otyp == TWO_HANDED_SWORD)) {
X if(obj->spe > -6) {
X pline("Your weapon rusts somewhat.");
X obj->spe--;
X } else pline("Your weapon looks quite rusted.");
X } else pline("Well, it looks wet now.");
X else if(fate<14)
X if(obj->otyp == LONG_SWORD && !strcmp(ONAME(obj),"Excalibur")){
X /* The lady of the lake acts! - Eric Backus */
X /* Be *REAL* nice to him */
X pline("A murky hand from the depths reaches up to bless the sword.");
X pline("As the hand retreats, the fountain disappears!");
X if(obj->spe < 5) obj->spe = 5;
X obj->cursed = 0;
X obj->rustfree = 1;
X levl[u.ux][u.uy].typ = ROOM;
X if(Invis) newsym(u.ux, u.uy);
X return(0);
X } else pline ("Well, it looks wet now.");
X else
X switch (fate) {
X case 16: /* Curse the item */
X pline("Well, it looks wet now.");
X obj->cursed = 1;
X break;
X case 17:
X case 18:
X case 19:
X case 20: /* Uncurse the item */
X if(obj->cursed) {
X pline("The water glows for a moment.");
X obj->cursed = 0;
X } else {
X pline("A feeling of loss comes over you.");
X }
X break;
X case 21: /* Water Demon */
X dowaterdemon();
X break;
X case 22: /* Water Nymph */
X dowaternymph();
X break;
X case 23: /* An Endless Stream Of Snakes */
X dowatersnakes();
X break;
X case 24: /* Find a gem */
X dofindgem();
X break;
X case 25: /* Water gushes forth */
X dogushforth();
X break;
X case 26: /* Strange feeling */
X pline("A strange tingling runs up your arm.");
X break;
X case 27: /* Strange feeling */
X pline("You feel a sudden chill.");
X break;
X case 28: /* Strange feeling */
X pline("An urge to take a bath nearly overwhelms you.");
X break;
X case 29: /* You see coins */
X pline("Far below you, you see coins glistening in the water.");
X break;
X default:
X break;
X }
X dryup();
X return(0);
X}
X#endif
END_OF_fountain.c
if test 7103 -ne `wc -c <fountain.c`; then
echo shar: \"fountain.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f termcap.c -a "${1}" != "-c" ; then
echo shar: Will not over-write existing file \"termcap.c\"
else
echo shar: Extracting \"termcap.c\" \(6845 characters\)
sed "s/^X//" >termcap.c <<'END_OF_termcap.c'
X/* SCCS Id: @(#)termcap.c 1.3 87/07/14
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* termcap.c - version 1.0.3 */
X
X#include <stdio.h>
X#include "config.h" /* for ROWNO and COLNO */
X#include "hack.h" /* for *HI, *HE */
Xextern char *tgetstr(), *tgoto(), *getenv();
Xextern long *alloc();
X
X#ifndef lint
Xextern /* it is defined in libtermlib (libtermcap) */
X#endif
X short ospeed; /* terminal baudrate; used by tputs */
Xstatic char tbuf[512];
Xstatic char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE;
Xstatic char *VS, *VE;
Xstatic int SG;
Xstatic char PC = '\0';
Xchar *CD; /* tested in pri.c: docorner() */
Xint CO, LI; /* used in pri.c and whatis.c */
X
X#ifdef MSDOS
Xstatic char tgotobuf[20];
X#define tgoto(fmt, x, y) (sprintf(tgotobuf, fmt, y+1, x+1), tgotobuf)
X#endif /* MSDOS /**/
X
Xstartup()
X{
X#ifdef MSDOS
X HO = "\033[H";
X CL = "\033[2J";
X CE = "\033[K";
X UP = "\033[1A";
X CM = "\033[%d;%dH"; /* used with function tgoto() */
X ND = "\033[1C";
X XD = "\033[1B";
X BC = "\033[1D";
X SO = "\033[7m";
X SE = "\033[0m";
X TI = TE = VS = VE = "";
X CD = "\033";
X CO = COLNO;
X LI = ROWNO;
X#if defined(DGK) || defined(SORTING)
X /* Both HI and HE have 4 characters. The function let_to_name()
X * in msdos.c uses this length when creating a buffer. If you
X * make HI and HE longer, you must also change the length of buf[]
X * in let_to_name()
X */
X HI = "\033[4m";
X HE = "\033[0m";
X#endif
X#else
X register char *term;
X register char *tptr;
X char *tbufptr, *pc;
X
X tptr = (char *) alloc(1024);
X
X tbufptr = tbuf;
X if(!(term = getenv("TERM")))
X error("Can't get TERM.");
X if(!strncmp(term, "5620", 4))
X flags.nonull = 1; /* this should be a termcap flag */
X if(tgetent(tptr, term) < 1)
X error("Unknown terminal type: %s.", term);
X if(pc = tgetstr("pc", &tbufptr))
X PC = *pc;
X if(!(BC = tgetstr("bc", &tbufptr))) {
X if(!tgetflag("bs"))
X error("Terminal must backspace.");
X BC = tbufptr;
X tbufptr += 2;
X *BC = '\b';
X }
X HO = tgetstr("ho", &tbufptr);
X CO = tgetnum("co");
X LI = tgetnum("li");
X if(CO < COLNO || LI < ROWNO+2)
X setclipped();
X if(!(CL = tgetstr("cl", &tbufptr)))
X error("Hack needs CL.");
X ND = tgetstr("nd", &tbufptr);
X if(tgetflag("os"))
X error("Hack can't have OS.");
X CE = tgetstr("ce", &tbufptr);
X UP = tgetstr("up", &tbufptr);
X /* It seems that xd is no longer supported, and we should use
X a linefeed instead; unfortunately this requires resetting
X CRMOD, and many output routines will have to be modified
X slightly. Let's leave that till the next release. */
X XD = tgetstr("xd", &tbufptr);
X/* not: XD = tgetstr("do", &tbufptr); */
X if(!(CM = tgetstr("cm", &tbufptr))) {
X if(!UP && !HO)
X error("Hack needs CM or UP or HO.");
X printf("Playing hack on terminals without cm is suspect...\n");
X getret();
X }
X SO = tgetstr("so", &tbufptr);
X SE = tgetstr("se", &tbufptr);
X SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */
X if(!SO || !SE || (SG > 0)) SO = SE = 0;
X#ifdef SORTING
X HI = SO; /* I know... Its a kluge. (MRS) */
X HE = SE;
X#endif
X CD = tgetstr("cd", &tbufptr);
X set_whole_screen(); /* uses LI and CD */
X if(tbufptr-tbuf > sizeof(tbuf)) error("TERMCAP entry too big...\n");
X free(tptr);
X#endif /* MSDOS /**/
X}
X
Xstart_screen()
X{
X xputs(TI);
X xputs(VS);
X#ifdef DGK
X /* Select normal ASCII and line drawing character sets.
X */
X if (flags.DECRainbow)
X xputs("\033(B\033)0");
X#endif
X}
X
Xend_screen()
X{
X clear_screen();
X xputs(VE);
X xputs(TE);
X}
X
X/* Cursor movements */
Xextern xchar curx, cury;
X
Xcurs(x, y)
Xregister int x, y; /* not xchar: perhaps xchar is unsigned and
X curx-x would be unsigned as well */
X{
X
X if (y == cury && x == curx)
X return;
X if(!ND && (curx != x || x <= 3)) { /* Extremely primitive */
X cmov(x, y); /* bunker!wtm */
X return;
X }
X if(abs(cury-y) <= 3 && abs(curx-x) <= 3)
X nocmov(x, y);
X else if((x <= 3 && abs(cury-y)<= 3) || (!CM && x<abs(curx-x))) {
X (void) putchar('\r');
X curx = 1;
X nocmov(x, y);
X } else if(!CM) {
X nocmov(x, y);
X } else
X cmov(x, y);
X}
X
Xnocmov(x, y)
X{
X if (cury > y) {
X if(UP) {
X while (cury > y) { /* Go up. */
X xputs(UP);
X cury--;
X }
X } else if(CM) {
X cmov(x, y);
X } else if(HO) {
X home();
X curs(x, y);
X } /* else impossible("..."); */
X } else if (cury < y) {
X if(XD) {
X while(cury < y) {
X xputs(XD);
X cury++;
X }
X } else if(CM) {
X cmov(x, y);
X } else {
X while(cury < y) {
X xputc('\n');
X curx = 1;
X cury++;
X }
X }
X }
X if (curx < x) { /* Go to the right. */
X if(!ND) cmov(x, y); else /* bah */
X /* should instead print what is there already */
X while (curx < x) {
X xputs(ND);
X curx++;
X }
X } else if (curx > x) {
X while (curx > x) { /* Go to the left. */
X xputs(BC);
X curx--;
X }
X }
X}
X
Xcmov(x, y)
Xregister x, y;
X{
X xputs(tgoto(CM, x-1, y-1));
X cury = y;
X curx = x;
X}
X
Xxputc(c) char c; {
X (void) fputc(c, stdout);
X}
X
Xxputs(s) char *s; {
X#ifdef MSDOS
X fputs(s, stdout);
X#else
X tputs(s, 1, xputc);
X#endif
X}
X
Xcl_end() {
X if(CE)
X xputs(CE);
X else { /* no-CE fix - free after Harold Rynes */
X /* this looks terrible, especially on a slow terminal
X but is better than nothing */
X register cx = curx, cy = cury;
X
X while(curx < COLNO) {
X xputc(' ');
X curx++;
X }
X curs(cx, cy);
X }
X}
X
Xclear_screen() {
X xputs(CL);
X xputs(HO);
X curx = cury = 1;
X}
X
Xhome()
X{
X if(HO)
X xputs(HO);
X else if(CM)
X xputs(tgoto(CM, 0, 0));
X else
X curs(1, 1); /* using UP ... */
X curx = cury = 1;
X}
X
Xstandoutbeg()
X{
X if(SO) xputs(SO);
X}
X
Xstandoutend()
X{
X if(SE) xputs(SE);
X}
X
Xbacksp()
X{
X xputs(BC);
X curx--;
X}
X
Xbell()
X{
X#ifdef DGKMOD
X if (flags.silent) return;
X#endif /* DGKMOD /**/
X (void) putchar('\007'); /* curx does not change */
X (void) fflush(stdout);
X}
X
Xstatic short tmspc10[] = { /* from termcap */
X 0, 2000, 1333, 909, 743, 666, 500, 333, 166, 83, 55, 41, 20, 10, 5
X};
X
Xdelay_output() {
X /* delay 50 ms - could also use a 'nap'-system call */
X /* BUG: if the padding character is visible, as it is on the 5620
X then this looks terrible. */
X#ifdef MSDOS
X /* simulate the delay with "cursor here" */
X register i;
X for (i = 0; i < 3; i++) {
X cmov(curx, cury);
X (void) fflush(stdout);
X }
X#else
X if(!flags.nonull)
X tputs("50", 1, xputc);
X
X /* cbosgd!cbcephus!pds for SYS V R2 */
X /* is this terminfo, or what? */
X /* tputs("$<50>", 1, xputc); */
X
X else if(ospeed > 0 || ospeed < SIZE(tmspc10)) if(CM) {
X /* delay by sending cm(here) an appropriate number of times */
X register int cmlen = strlen(tgoto(CM, curx-1, cury-1));
X register int i = 500 + tmspc10[ospeed]/2;
X
X while(i > 0) {
X cmov(curx, cury);
X i -= cmlen*tmspc10[ospeed];
X }
X }
X#endif /* MSDOS /**/
X}
X
Xcl_eos() /* free after Robert Viduya */
X{ /* must only be called with curx = 1 */
X
X if(CD)
X xputs(CD);
X else {
X register int cx = curx, cy = cury;
X while(cury <= LI-2) {
X cl_end();
X xputc('\n');
X curx = 1;
X cury++;
X }
X cl_end();
X curs(cx, cy);
X }
X}
END_OF_termcap.c
if test 6845 -ne `wc -c <termcap.c`; then
echo shar: \"termcap.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 13 \(of 16\).
cp /dev/null ark13isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 16 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