games-request@tekred.TEK.COM (12/03/87)
Submitted by: mike@genat.UUCP (Mike Stephenson) Comp.sources.games: Volume 3, Issue 16 Archive-name: nethack2.2/Part16 #! /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 16 (of 20)." # Contents: README.OLD config.h dogmove.c fountain.c prisym.c # termcap.c write.c # Wrapped by billr@tekred on Tue Dec 1 16:25:11 1987 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f README.OLD -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"README.OLD\" else echo shar: Extracting \"README.OLD\" \(7714 characters\) sed "s/^X//" >README.OLD <<'END_OF_README.OLD' X NetHack V1.0 README X X This file contains information on NetHack, it's history, features, Xand installation proceedures. X X For a detailed history of the game, see the README.ORIG file, which Xcontains three separate readme files, dating back to the original release of Xthe game (then named hack) by Jay Fenlason. X X History: X ========== X X NetHack is the product of literally dozens of people's work. I have Xa list of *some* of those who made major additions to the game which appears Xbelow: X XJay Fenlason wrote the original release of "Hack", with help from X Kenny Woodland, Mike Thome and Jon Payne. X XAndries Brouwer did a major re-write on the program and publshed (at least) X two versions to the Usenet. X XDon Kneller ported the 1.0.3 version of Hack to the PC, creating PC-Hack. X X The following folks didn't actually re-write the game, or port it to Xa new machine, but have made significant contributions to the playability of Xthe game: X Xins_akaa@jhunix.UUCP (Ken Arromdee) X X New character classes. X New weapons code. X Armor weights implemented. X New tools code. X Polymorph self code. X additional bug fixes. X Xsrt@ucla-cs (Scott R. Turner) X X Rockmole & Keystone Kops code. X Squeeky Board & Magic traps. X Fountain code. X more bug fixes. X Xgil@cornell.UUCP (Gil Neiger) X X Magic Marker code. X Fountain code enhancements. X Enhancements to dozens of routines. X more bug fixes (esp. in hack.zap.c) X Xericb@hplsla.UUCP (Eric Backus) X X #dip mods to fountain code. X yet more bug fixes. X X As for myself, I have added new character classes and traps, the XThrone Room, spellbooks and spellcasting, implemented code for praying and Xmade some enhancements to the endgame. X X NetHack is an integrated version of two major "flavors" of Hack, XUnix and PC Hack. It is designed so that you should be able to compile it Xin either one of the target enviornments. The filenames of all modules have Xbeen modified to correspond with the PC-Hack standards implemented by Don XKneller. X X config.h X ========== X X As distributed, it is set up to compile on my machine (a Pyramid 98xe Xin the Berkeley universe). Due to the large number of "features" in NetHack, Xthe config file (config.h) is used to select the target options. X X Here is a list of the currently supported options: X XSPELLS Spell casting code XPRAYERS Prayer code XKAA Various changes made by Ken Arromdee XMARKER Magic marker modification XNEWCLASS New classes, traps, and Throne Rooms. XSAFE_ATTACK Safe attack code XPROBING Wand of probing code XDIAGS Diagnostics after death/quit XSORTING Sorted inventory XDGK Additional features by Don Kneller (PC specific) XDGKMOD Additional features by Don Kneller (Non-PC specific) XREDO support for redoing last command XHARD Enhanced wizard code among other things. XNEWTRAPS Magic and Squeeky board traps XFREEHAND Cannot use Pick-axe without wielding it. XSPIDERS Spiders and webs XFOUNTAINS Fountain code XKOPS Keystone Kops XROCKMOLE Rockmoles X XStatus Line options: X XGOLD_ON_BOTL XEXP_ON_BOTL X X In a number of cases, code written for one specific version of Hack Xor another was separated out and given it's own designation (eg. REDO has Xbeen moved out of DGKMOD which was moved out of DGK from PC-HACK). X X Some New Features: X ==================== X X Some of the old code (eg. KOPS) has been enhanced to allow for more Xfunctionality. Here's a couple of examples - you can find out the rest for Xyourself in the traditional Hack style :-) X X Kops now throw cream pies (thank/blame KAA for the suggestion). X X The wizard may not stay dead!!! X X There are a couple of new types of demons. X X Demons may not be aggressive. X X There are lots more of these little gems, with sufficient hints in Xvarious fortune cookies to give away enough clues. X X Makefiles: X ============ X X The Unix "Makefile" has been enhanced to make installation cleaner Xand also to allow "initialization" of the play directories (WARNING: this Xwill destroy old score files!!!). The PC Makefile hasn't been upgraded in Xthis respect. X X The program "makedefs" has been modified in order to allow limited Xuse of "#ifdef/#else/#endif" sets in objects.h. Makedefs will only generate Xone #define for any number of ocurrences of a given object name string. In Xaddition, "makedefs" also generates alternate defines for "DEAD_xxxxx" in Xthose cases where a monster has been given an alternate identity. X X Makedefs has also been modified in order that it may be used to Xinitialize the following variable def files: X X objects.h -o option, see above. X trap.h -t option, trap type defines. X date.h -d option, date string. X data -D option, optional monster names. X rumors -r option, optional rumor addition. X X To compile the program on any 4.n or Sys V system, you should only Xneed to copy "Makefile.unix" to "Makefile", set up "Makefile" and "config.h", Xthen type "make". On a Xenix system, use "Makefile.xenix" and similarly set Xup "Makefile" and "config.h", with "STUPID" defined. At this point in time, XI can get the Xenix version to build, but it will immediately dump core on Xinvocation. X X Known Problems: X ================= X X There are several known problem areas and deficiencies in the code Xwhich I haven't yet addressed, prefering to get the really fatal bugs out of Xthe way. Here's a short list of things someone out there might want to work Xon (and it is by no means complete): X X - The WALKIES code is really crude. Fido get's mnexto()'d you when X he gets out of the effective leash range. I haven't yet been able X to integrate leashed movement into dogmove(). You might just want X to comment out the #define in config.h. X X - ROCKMOLES have some problems with screen updating. I didn't make X any changes to the code I received, and have noticed some distinct X problems with walls not being set to "door" until the rockmole X moves off the cell. X X - There are some problems in the item selection code, the usual effect X of which is to leave the cursor sitting at some arbitrary point on X the screen instead of returning it to the upper left hand corner or X onto the "@". This doesn't affect the screen updating, so I have X ignored it up to now. X X - REDO may not be completely implemented. I am still working on it X here but would appreciate any help anyone out there might want to X give. X X I fully expect that about one week's worth of play on the net will Xresult in a couple dozen bugs being discovered. I would like to keep a lid Xon the potential explosion of different sub-versions of the game, so if you Xpossibly can, please send me the bug reports, instead of releasing them to Xthe general public. I will apply them to my code here, and will generate an Xupdate to the release when the mass of fixes (or mass * severity factor) gets Xlarge enough. This way, we should be able to keep most of the net up to a Xcertain level - this may turn out to be the first truely net maintained Xgame. Unless circumstances change, I will continue to consolidate fixes and Xmodifications to the game, and will continue to post to the net through Xcomp.sources.games, with notices of new patches/fixes/mods going out through Xrec.games.hack. X X Making Bug Reports: X ===================== X X To send bug reports, just E-Mail me at any one of the following net Xaddresses (in order of connectivity): X X seismo!mnetor!genat!mike X utzoo!mnetor!genat!mike X pyramid!pyrnj!genat!mike X utzoo!utgpu!genat!mike X X When you send in a bug report, please keep your code fragments as Xsmall as possible. Remember that each site along the way is paying for the Xtransmission of the code. X X Mike Stephenson X XMail: Genamation Inc. Phone: (416) 475-9434 X 351 Steelcase Rd. W X Markham, Ontario. UUCP: {seismo, utzoo}!mnetor!genat!mike X Canada L3R 3W1 END_OF_README.OLD if test 7714 -ne `wc -c <README.OLD`; then echo shar: \"README.OLD\" unpacked with wrong size! fi # end of overwriting check fi 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\" \(8162 characters\) sed "s/^X//" >config.h <<'END_OF_config.h' X/* SCCS Id: @(#)config.h 2.2 87/11/11 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ 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/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 */ X/* #define MSDOS /* define for MS-DOS (actually defined by compiler) */ X#define UNIX /* delete if no fork(), exec() available */ X/* #define GENIX /* Yet Another Unix Clone */ 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 "2.2a" /* 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 TERMINFO /* uses "curses" rather than termcap */ X X#ifdef __TURBOC__ X#define alloc malloc X#define signal ssignal 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 X#ifdef BSD X/* Use the high quality random number routines. */ Xextern long random(); X#define rand() random() X#define srand(seed) srandom(seed) X#else Xextern long lrand48(); X#define rand() lrand48() X#define srand(seed) srand48(seed) 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#define memcpy(d, s, n) bcopy(s, d, n) X#define memcmp(s1, s2, n) bcmp(s2, s1, n) 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 * otherwise: X * #define Bitfield(x,n) unsigned x:n 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 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 DOGNAME /* Name of your first dog as an option */ 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#define COM_COMPL /* Command line completion by John S. Bien */ X#define GRAPHICS /* Funky screen character support (Eric S. Raymond) */ X#define HACKOPTIONS /* Support DGK-style HACKOPTIONS processing (ESR) */ X#define RPH /* Various hacks by Richard P. Hughey */ X#define KJSMODS /* Various changes made by Kevin Sweet */ X#define BVH /* Additions by Bruce Holloway */ X#define SAC /* Soldiers, barracks by Steve Creps */ X X#if defined(MSDOS) && defined(GRAPHICS) X#define MSDOSCOLOR X#endif 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 8162 -ne `wc -c <config.h`; then echo shar: \"config.h\" 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\" \(7691 characters\) sed "s/^X//" >dogmove.c <<'END_OF_dogmove.c' X/* SCCS Id: @(#)dogmove.c 1.4 87/08/08 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#ifdef WALKIES X if(mtmp->mleashed) { X mtmp->mleashed = 0; X pline("Your leash goes slack..."); X } X#endif X if(cansee(omx,omy)) X pline("%s dies%s.", Monnam(mtmp), X (mtmp->mhp >= 1) ? "" : " from hunger"); X else 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) 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 7691 -ne `wc -c <dogmove.c`; then echo shar: \"dogmove.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\" \(7618 characters\) sed "s/^X//" >fountain.c <<'END_OF_fountain.c' X/* SCCS Id: @(#)fountain.c 2.1 87/10/19 X/* fountain.c v 1.4.3 */ X X/* X * Revision 1.4.3 87/11/25 19:16:00 M. Stephenson X * Implemented levitation bug fixes. X * X * Revision 1.4.2 87/10/19 11:48:00 M. Stephenson X * Implementation of KJS bug fixes. 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 struct obj *mkobj_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 if((mtmp = mkmon_at('&',u.ux,u.uy))) { X pline("You have unleashed a water demon!"); X X /* Give those on low levels a (slightly) better chance of survival */ X if ( rnd(100) > (80 + dlevel)) { X pline("Grateful for his release, he grants you a wish!"); X makewish(); X mondied(mtmp); X } X } X} X Xdowaternymph() /* Water Nymph */ { X register struct monst *mtmp; X if((mtmp = mkmon_at('N',u.ux,u.uy))) { X X pline("You have attracted a water nymph!"); 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(3) && (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 register int fate = rnd(30); X X if(Levitation) pline("You are floating high above the fountain."); X else if (fate < 10) { X pline("The cool draught refreshes you."); X lesshungry(rnd(10)); 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),"unrefrigerated orange juice"); 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 register struct monst *mtmp; X X if(!fmon) 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 } 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 default: X break; X } X } X dryup(); X} X Xdipfountain(obj) Xregister struct obj *obj; X{ X register int fate = rnd(30); X X if(Levitation) pline("You are floating high above the fountain."); X else 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 X#ifndef RPH X && !strcmp(ONAME(obj), "Excalibur") X#endif X ) { 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#ifndef RPH X if(obj->spe < 5) obj->spe = 5; X#else X /* otherwise +rnd(10) / +5 "Super"sword */ X oname(obj, "Excalibur"); X#endif X#ifdef KAA X obj->dknown = 1; /* blessed */ X#endif 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 } X dryup(); X return(0); X} X#endif END_OF_fountain.c if test 7618 -ne `wc -c <fountain.c`; then echo shar: \"fountain.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f prisym.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"prisym.c\" else echo shar: Extracting \"prisym.c\" \(7263 characters\) sed "s/^X//" >prisym.c <<'END_OF_prisym.c' X/* SCCS Id: @(#)prisym.c 2.0 87/09/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X X#include <stdio.h> X#include "hack.h" X Xextern xchar scrlx, scrhx, scrly, scrhy; /* corners from pri.c */ X Xatl(x,y,ch) Xregister x,y; X{ X register struct rm *crm = &levl[x][y]; X X if(x<0 || x>COLNO-1 || y<0 || y>ROWNO-1){ X impossible("atl(%d,%d,%c)",x,y,ch); X return; X } X if(crm->seen && crm->scrsym == ch) return; X crm->scrsym = ch; X crm->new = 1; X on_scr(x,y); X} X Xon_scr(x,y) Xregister x,y; X{ X if(x < scrlx) scrlx = x; X if(x > scrhx) scrhx = x; X if(y < scrly) scrly = y; X if(y > scrhy) scrhy = y; X} X X/* call: (x,y) - display X (-1,0) - close (leave last symbol) X (-1,-1)- close (undo last symbol) X (-1,let)-open: initialize symbol X (-2,let)-change let X*/ X Xtmp_at(x,y) int x,y; { Xstatic schar prevx, prevy; Xstatic char let; X if((int)x == -2){ /* change let call */ X let = y; X return; X } X if((int)x == -1 && (int)y >= 0){ /* open or close call */ X let = y; X prevx = -1; X return; X } X if(prevx >= 0 && cansee(prevx,prevy)) { X delay_output(); X prl(prevx, prevy); /* in case there was a monster */ X at(prevx, prevy, levl[prevx][prevy].scrsym); X } X if(x >= 0){ /* normal call */ X if(cansee(x,y)) at(x,y,let); X prevx = x; X prevy = y; X } else { /* close call */ X let = 0; X prevx = -1; X } X} X X/* like the previous, but the symbols are first erased on completion */ XTmp_at(x,y) int x,y; { Xstatic char let; Xstatic xchar cnt; Xstatic coord tc[COLNO]; /* but watch reflecting beams! */ Xregister xx,yy; X if((int)x == -1) { X if(y > 0) { /* open call */ X let = y; X cnt = 0; X return; X } X /* close call (do not distinguish y==0 and y==-1) */ X while(cnt--) { X xx = tc[cnt].x; X yy = tc[cnt].y; X prl(xx, yy); X at(xx, yy, levl[xx][yy].scrsym); X } X cnt = let = 0; /* superfluous */ X return; X } X if((int)x == -2) { /* change let call */ X let = y; X return; X } X /* normal call */ X if(cansee(x,y)) { X if(cnt) delay_output(); X at(x,y,let); X tc[cnt].x = x; X tc[cnt].y = y; X if(++cnt >= COLNO) panic("Tmp_at overflow?"); X levl[x][y].new = 0; /* prevent pline-nscr erasing --- */ X } X} X Xcurs_on_u(){ X curs(u.ux, u.uy+2); X} X Xpru() X{ X if(u.udispl && (Invisible || u.udisx != u.ux || u.udisy != u.uy)) X /* if(! levl[u.udisx][u.udisy].new) */ X if(!vism_at(u.udisx, u.udisy)) X newsym(u.udisx, u.udisy); X if(Invisible) { X u.udispl = 0; X prl(u.ux,u.uy); X } else X if(!u.udispl || u.udisx != u.ux || u.udisy != u.uy) { X atl(u.ux, u.uy, u.usym); X u.udispl = 1; X u.udisx = u.ux; X u.udisy = u.uy; X } X levl[u.ux][u.uy].seen = 1; X} X X#ifndef NOWORM X#include "wseg.h" Xextern struct wseg *m_atseg; X#endif X X/* print a position that is visible for @ */ Xprl(x,y) X{ X register struct rm *room; X register struct monst *mtmp; X register struct obj *otmp; X register struct trap *ttmp; X X if(x == u.ux && y == u.uy && (!Invisible)) { X pru(); X return; X } X if(!isok(x,y)) return; X room = &levl[x][y]; X if((!room->typ) || X (IS_ROCK(room->typ) && levl[u.ux][u.uy].typ == CORR)) X return; X if((mtmp = m_at(x,y)) && !mtmp->mhide && X (!mtmp->minvis || See_invisible)) { X#ifndef NOWORM X if(m_atseg) X pwseg(m_atseg); X else X#endif X pmon(mtmp); X } X else if((otmp = o_at(x,y)) && room->typ != POOL) X atl(x,y,Hallucination ? rndobjsym() : otmp->olet); X#ifdef SPIDERS X else if((!mtmp || mtmp->data == PM_SPIDER) && X (ttmp = t_at(x,y)) && ttmp->ttyp == WEB) X atl(x,y,WEB_SYM); X#endif X else if(mtmp && (!mtmp->minvis || See_invisible)) { X /* must be a hiding monster, but not hiding right now */ X /* assume for the moment that long worms do not hide */ X pmon(mtmp); X } X else if(g_at(x,y) && room->typ != POOL) X atl(x,y,Hallucination ? rndobjsym() : GOLD_SYM); X else if(!room->seen || room->scrsym == STONE_SYM) { X room->new = room->seen = 1; X newsym(x,y); X on_scr(x,y); X } X room->seen = 1; X} X Xchar Xnews0(x,y) Xregister xchar x,y; X{ X register struct obj *otmp; X register struct trap *ttmp; X struct rm *room; X register char tmp; X X room = &levl[x][y]; X if(!room->seen) tmp = STONE_SYM; X else if(room->typ == POOL) tmp = POOL_SYM; X else if(!Blind && (otmp = o_at(x,y))) X tmp = Hallucination ? rndobjsym() : otmp->olet; X else if(!Blind && g_at(x,y)) X tmp = Hallucination ? rndobjsym() : GOLD_SYM; X else if(x == xupstair && y == yupstair) tmp = UP_SYM; X else if(x == xdnstair && y == ydnstair) tmp = DN_SYM; X#ifdef SPIDERS X else if((ttmp = t_at(x,y)) && ttmp->ttyp == WEB) tmp = WEB_SYM; X else if(ttmp && ttmp->tseen) tmp = TRAP_SYM; X#else X else if((ttmp = t_at(x,y)) && ttmp->tseen) tmp = TRAP_SYM; X#endif X else switch(room->typ) { X case SCORR: X case SDOOR: X tmp = room->scrsym; /* %% wrong after killing mimic ! */ X break; X case HWALL: X tmp = room->scrsym; /* OK for corners only */ X if (!IS_CORNER(tmp)) X tmp = HWALL_SYM; X break; X case VWALL: X tmp = VWALL_SYM; X break; X case LDOOR: X case DOOR: X tmp = DOOR_SYM; X break; X case CORR: X tmp = CORR_SYM; X break; X case ROOM: X if(room->lit || cansee(x,y) || Blind) tmp = ROOM_SYM; X else tmp = STONE_SYM; X break; X#ifdef FOUNTAINS X case FOUNTAIN: X tmp = FOUNTAIN_SYM; X break; X#endif X#ifdef NEWCLASS X case THRONE: X tmp = THRONE_SYM; X break; X#endif X/* X case POOL: X tmp = POOL_SYM; X break; X*/ X default: X tmp = ERRCHAR; X } X return(tmp); X} X Xnewsym(x,y) Xregister x,y; X{ X atl(x,y,news0(x,y)); X} X X/* used with wand of digging (or pick-axe): fill scrsym and force display */ X/* also when a POOL evaporates */ Xmnewsym(x,y) Xregister x,y; X{ X register struct rm *room; X char newscrsym; X X if(!vism_at(x,y)) { X room = &levl[x][y]; X newscrsym = news0(x,y); X if(room->scrsym != newscrsym) { X room->scrsym = newscrsym; X room->seen = 0; X } X } X} X Xnosee(x,y) Xregister x,y; X{ X register struct rm *room; X X if(!isok(x,y)) return; X room = &levl[x][y]; X if(room->scrsym == ROOM_SYM && !room->lit && !Blind) { X room->scrsym = ' '; X room->new = 1; X on_scr(x,y); X } X} X X#ifndef QUEST Xprl1(x,y) Xregister x,y; X{ X if(u.dx) { X if(u.dy) { X prl(x-(2*u.dx),y); X prl(x-u.dx,y); X prl(x,y); X prl(x,y-u.dy); X prl(x,y-(2*u.dy)); X } else { X prl(x,y-1); X prl(x,y); X prl(x,y+1); X } X } else { X prl(x-1,y); X prl(x,y); X prl(x+1,y); X } X} X Xnose1(x,y) Xregister x,y; X{ X if(u.dx) { X if(u.dy) { X nosee(x,u.uy); X nosee(x,u.uy-u.dy); X nosee(x,y); X nosee(u.ux-u.dx,y); X nosee(u.ux,y); X } else { X nosee(x,y-1); X nosee(x,y); X nosee(x,y+1); X } X } else { X nosee(x-1,y); X nosee(x,y); X nosee(x+1,y); X } X} X#endif /* QUEST /**/ X Xvism_at(x,y) Xregister x,y; X{ X register struct monst *mtmp; X X if(x == u.ux && y == u.uy && !Invisible) return(1); X X if(mtmp = m_at(x,y)) return((Blind && Telepat) || canseemon(mtmp)); X X return(0); X} X X#ifdef NEWSCR Xpobj(obj) register struct obj *obj; { Xregister int show = (!obj->oinvis || See_invisible) && X cansee(obj->ox,obj->oy); X if(obj->odispl){ X if(obj->odx != obj->ox || obj->ody != obj->oy || !show) X if(!vism_at(obj->odx,obj->ody)){ X newsym(obj->odx, obj->ody); X obj->odispl = 0; X } X } X if(show && !vism_at(obj->ox,obj->oy)){ X atl(obj->ox,obj->oy,obj->olet); X obj->odispl = 1; X obj->odx = obj->ox; X obj->ody = obj->oy; X } X} X#endif /* NEWSCR /**/ X Xunpobj(obj) register struct obj *obj; { X/* if(obj->odispl){ X if(!vism_at(obj->odx, obj->ody)) X newsym(obj->odx, obj->ody); X obj->odispl = 0; X } X*/ X if(!vism_at(obj->ox,obj->oy)) X newsym(obj->ox,obj->oy); X} END_OF_prisym.c if test 7263 -ne `wc -c <prisym.c`; then echo shar: \"prisym.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\" \(8400 characters\) sed "s/^X//" >termcap.c <<'END_OF_termcap.c' X/* SCCS Id: @(#)termcap.c 2.1 87/10/19 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X X#include <stdio.h> X#include <ctype.h> /* for isdigit() */ X#include "hack.h" /* for ROWNO, COLNO, *HI, *HE */ X#ifdef GENIX X#define void int /* jhn - mod to prevent compiler from bombing */ X#endif X Xextern char *tgetstr(), *tgoto(), *getenv(); Xextern long *alloc(); X X#ifndef TERMINFO X# ifndef LINT Xextern /* it is defined in libtermlib (libtermcap) */ X# endif X short ospeed; /* terminal baudrate; used by tputs */ X#endif Xstatic char tbuf[512]; Xstatic char *HO, *CL, *CE, *UP, *CM, *ND, *XD, *BC, *SO, *SE, *TI, *TE; Xstatic char *VS, *VE, *US, *UE; 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# ifdef MSDOSCOLOR /* creps@silver.bacs.indiana.edu */ X TI = "\033[44;37m"; X TE = "\033[0m"; X VS = VE = ""; X SO = "\033[31m"; X SE = "\033[44;37m"; X# else X TI = TE = VS = VE = ""; X SO = "\033[7m"; X SE = "\033[0m"; X# endif X CD = "\033"; X CO = COLNO; X LI = ROWNO; X# if defined(DGK) || defined(SORTING) X# ifdef MSDOSCOLOR X HI = "\033[32m"; X HE = "\033[44;37m"; X# else X HI = "\033[4m"; X HE = "\033[0m"; X# endif X# endif X#else /* MSDOS /**/ X register char *term; X register char *tptr; X char *tbufptr, *pc; X register int i; 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 US = tgetstr("us", &tbufptr); X UE = tgetstr("ue", &tbufptr); X SG = tgetnum("sg"); /* -1: not fnd; else # of spaces left by so */ X if(!SO || !SE || (SG > 0)) SO = SE = US = UE = 0; X TI = tgetstr("ti", &tbufptr); X TE = tgetstr("te", &tbufptr); X VS = VE = ""; X# ifdef SORTING X /* Get rid of padding numbers for HI and HE. Hope they X * aren't really needed!!! HI and HE are ouputted to the X * pager as a string - so how can you send it NULLS??? X * -jsb X */ X HI = (char *) alloc(strlen(SO) + 1); X HE = (char *) alloc(strlen(SE) + 1); X i = 0; X while(isdigit(SO[i])) i++; X strcpy(HI, &SO[i]); X i = 0; X while(isdigit(SE[i])) i++; X strcpy(HE, &SE[i]); 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#ifdef MSDOSCOLOR X init_hilite(); X#endif 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/*#ifdef MSDOSCOLOR X/* xputs(TI); X/*#endif X*/ 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#ifdef MSDOSCOLOR X xputs(TI); X#endif X home(); 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#ifdef TERMINFO X tputs("$<50>", 1, xputs); X#else X tputs("50", 1, xputs); X#endif 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} X X#ifdef MSDOSCOLOR X X#define ESCCHR '\033' X#define HILITE_ATTRIB 1 /* highlight */ X X#define HILITE_MONSTER 1 /* red */ X#define HILITE_OBJECT 2 /* green */ X Xinit_hilite() X{ X register int hilen, def_background; X X /* find default background color */ X hilen = strlen(HI) - 1; X if (hilen < 5) def_background = 0; /* black */ X else { X if (!isdigit(HI[hilen-1])) def_background = 0; X else def_background = HI[hilen-1]; X } X X HI_MON = (char *) alloc(sizeof("E[0;33;44m")); X sprintf(HI_MON, "%c[%d;3%d;4%dm", ESCCHR, HILITE_ATTRIB, X HILITE_MONSTER, def_background); X HI_OBJ = (char *) alloc(sizeof("E[0;33;44m")); X sprintf(HI_OBJ, "%c[%d;3%d;4%dm", ESCCHR, HILITE_ATTRIB, X HILITE_OBJECT, def_background); X} X X#endif /* MSDOSCOLOR */ END_OF_termcap.c if test 8400 -ne `wc -c <termcap.c`; then echo shar: \"termcap.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f write.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"write.c\" else echo shar: Extracting \"write.c\" \(3837 characters\) sed "s/^X//" >write.c <<'END_OF_write.c' X/* SCCS Id: @(#)write.c 2.0 87/09/16 X */ X X#include "hack.h" X Xextern char pl_character[]; X X#ifdef MARKER X X/* X * returns basecost of a scroll X */ Xint Xcost(scroll) Xregister struct obj *scroll; X{ X switch(scroll->otyp) { X# ifdef MAIL X case SCR_MAIL: X return(0); X break; X# endif X case SCR_LIGHT: X case SCR_GOLD_DETECTION: X case SCR_FOOD_DETECTION: X case SCR_MAGIC_MAPPING: X case SCR_AMNESIA: X case SCR_FIRE: X return(8); X break; X case SCR_DESTROY_ARMOR: X case SCR_DAMAGE_WEAPON: X case SCR_CREATE_MONSTER: X case SCR_PUNISHMENT: X return(10); X break; X case SCR_CONFUSE_MONSTER: X return(12); X break; X case SCR_IDENTIFY: X return(14); X break; X case SCR_ENCHANT_ARMOR: X case SCR_REMOVE_CURSE: X case SCR_ENCHANT_WEAPON: X return(16); X break; X case SCR_SCARE_MONSTER: X case SCR_TAMING: X case SCR_TELEPORTATION: X return(20); X break; X case SCR_GENOCIDE: X return(30); X break; X case SCR_BLANK_PAPER: X default: X impossible("You can't write such a weird scroll!"); X } X return(1000); X} X X Xdowrite(pen) X register struct obj *pen; X{ X register struct obj *paper; X char namebuf[BUFSZ], scrbuf[BUFSZ]; X register struct obj *newscroll; X extern struct obj *readobjnam(), *addinv(); X int basecost, actualcost; X int newquan; X X if(!pen) X return(0); X if(pen->otyp != MAGIC_MARKER) { X pline("You can't write with that!"); X return(0); X } X X /* get paper to write on */ X paper = getobj("?","write on"); X if(!paper) X return(0); X if(!(objects[paper->otyp].oc_name_known)) { X pline("In your haste, you rip the scroll to pieces."); X useup(paper); X return(1); X } X# ifndef KAA X/* If this is included, the strategy would be to name all scrolls so that X * you can test them for blankness with a magic marker. This is tedious, X * thus, let's make it easier. */ X if(!(objects[paper->otyp].oc_name_known)) { X pline("In your haste, you rip the scroll to pieces."); X useup(paper); X return(0); X } X# endif X if(paper->otyp != SCR_BLANK_PAPER) { X pline("You fool, that scroll's not blank!"); X return(0); X } X X /* what to write */ X pline("What do you want to write? "); X getlin(namebuf); X if(namebuf[0] == '\033' || !namebuf[0]) X return(0); X strcpy(scrbuf,"scroll of "); X strcat(scrbuf,namebuf); X newscroll = readobjnam(scrbuf); X if(newscroll->olet != SCROLL_SYM || X newscroll->otyp == SCR_BLANK_PAPER) { X pline("You can't write that!"); X pline("It's obscene!"); X return(0); X } X X /* see if there's enough ink */ X basecost = cost(newscroll); X if(pen->spe < basecost/2) { X pline("You marker is too dried out to write that!"); X obfree(newscroll, (struct obj *) 0); X return(0); X } X X /* we're really going to write now, so calculate X * cost and useup old scroll X */ X actualcost = rn1(basecost/2,basecost/2); X useup(paper); X X /* dry out marker */ X if(pen->spe < actualcost) { X pline("Your marker dries out!"); X pline("The scroll is now useless and disappears!"); X pen->spe = 0; X obfree(newscroll, (struct obj *) 0); X return(1); X } X pen->spe -= actualcost; X# ifdef KAA /* Since the KAA modification allows writing on unknown blank X paper, identify blank paper. */ X objects[SCR_BLANK_PAPER].oc_name_known=1; X# endif X X /* can't write if we don't know it - unless we're lucky */ X if(!(objects[newscroll->otyp].oc_name_known) && X# ifdef KAA X !(objects[newscroll->otyp].oc_uname) && X# endif X ((pl_character[0] == 'W' && rn2(3)) || X (pl_character[0] != 'W' && rn2(10)))) { X pline("You don't know how to write that!"); X pline("You write \"Shah was here!\" and the scroll disappears."); X obfree(newscroll, (struct obj *) 0); X return(1); X } X X /* and now you know it! */ X objects[newscroll->otyp].oc_name_known = 1; X X /* success - don't forget to fool prinv() */ X newscroll = addinv(newscroll); X newquan = newscroll->quan; X newscroll->quan = 1; X prinv(newscroll); X newscroll->quan = newquan; X X return(1); X} X# endif /* MARKER /**/ END_OF_write.c if test 3837 -ne `wc -c <write.c`; then echo shar: \"write.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 16 \(of 20\). cp /dev/null ark16isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 20 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