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