games-request@tekred.TEK.COM (07/28/87)
Submitted by: mike@genat.UUCP (Mike Stephenson) Comp.sources.games: Volume 2, Issue 11 Archive-name: nethack/Part11 #! /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 11 (of 16)." # Contents: README.OLD cmd.c data.base save.c spell.c worn.c # Wrapped by billr@tekred on Tue Jul 28 09:49:40 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\" \(10200 characters\) sed "s/^X//" >README.OLD <<'END_OF_README.OLD' X X This file consists of all previous README files for the game, as Xreleased with the original version (Jay F.), first usenet version (Andries B.), Xand PC-Hack (Don K.). This way "README" is current for this version. X X Mike Stephenson X X-- Original README file -------------------------------------------------------- X XThis is export hack, my first semester programming project. X XTo set it up for your system, you will have to do the following: X 1: create a hack uid, to own the top ten list, etc. X 2: create a hack directory "/usr/lib/game/hack" is the default. X 2.5: make the directory 700 mode. /* sav files go in there...*/ X 3: modify hack.main.c to use the new directory. X 4: modify hack.main.c so it uses the new hack gid. Gid accounts can Xgo into magic mode without the password, can get cores with ^G, etc. X(make sure gid isn't checked anywhere else...) X 5: recompile hack. X 6: put it in games after making it set-uid hack. X 8: fix the bugs I undobtedly left in it. X 9: tell me what you think of it. X X Hack uses the UCB file /etc/termcap to get your terminal escape codes. XIf you don't use it, you will have to make extensive changes to hack.pri.c X XIf you find any bugs (That you think I don't know about), or have any Xawesome new changes (Like a better save (One that works!)), or have ANY Xquestions, write me X Jay Fenlason X 29 East St. X Sudbury Mass. X 01776 X Xor call me at (617) 443-5036. Since I have both a modem and a teen-age Xsister, Good Luck. X X XHack is split (roughly) into several source files that do different things. XI have tried to fit all the procedures having to do with a certain segment Xof the game into a single file, but the job is not the best in the world. XThe rough splits are: X Xhack.c General random stuff and things I never got around to moving. Xhack.main.c main() and other random procedures, also the lock file stuff. Xhack.mon.c Monsters, moving, attacking, etc. Xhack.do.c drink, eat, read, wield, save, etc. Xhack.do1.c zap, wear, remove, etc... Xhack.pri.c stuff having to do with the screen, most of the terminal X independant stuff is in here. Xhack.lev.c temp files and calling of mklev. X XBecause of the peculiar restraints on our system, I make mklev (create Xa level) a separate procedure execd by hack when needed. The source for Xmklev is (Naturaly) mklev.c. You may want to put mklev back into hack. XGood luck. X XMost of hack was written by me, with help from X Kenny Woodland (KW) (general random things including X the original BUZZ()) X Mike Thome (MT) (The original chamelian) X and Jon Payne (JP) (The original lock file kludge and X the massive CURS()) X XThis entire program would not have been possible without the SFSU Logo XWorkshop. I am eternally grateful to all of our students (Especially K.L.), Xwithout whom I would never have seen Rogue. I am especially grateful to XMike Clancy, without whose generous help I would never have gotten to play XROGUE. X X-- Hack 1.0.x README file ------------------------------------------------------ X XHack is a display oriented dungeons & dragons - like game. XBoth display and command structure resemble rogue. X(For a game with the same structure but entirely different display - Xa real cave instead of dull rectangles - try Quest) X XHack was originally written by Jay Fenlason (at lincolnsudbury: X 29 East St., Sudbury Mass., 01776) with help from X Kenny Woodland, Mike Thome and Jon Payne. XBasically it was an implementation of Rogue, however, with 52+ instead of 26 X monster types. XThe current version is more than thrice as large (with such new features as X the dog, the long worms, the shops, etc.) and almost entirely rewritten X (only the display routines are the original ones - I must rewrite these X too one day; especially when you are blind strange things still happen). X XFiles for hack: X hack The actual game X record Top 100 list (just start with an empty file) X news Tells about recent changes in hack, or bugs found ... X (Just start with no news file.) X data Auxiliary file used by hack to give you the names X and sometimes some more information on the X objects and monsters. X help Introductory information (no doubt outdated). X hh Compactified version of help. X perm An empty file used for locking purposes. X rumors Texts for fortune cookies. X (Some of these contain information on the game, X others are just plain stupid. Additional rumors X are appreciated.) X hack.sh A shell script. X (We have hack.sh in /usr/games/hack and X hack in /usr/games/lib/hackdir/hack and all the other X hack stuff in /usr/games/lib/hackdir - perhaps this X will make the script clear. X There is no need for you to use it.) X READ_ME This file. X Original_READ_ME Jay Fenlason's READ_ME X XSystem files used: X /etc/termcap Used in conjunction with the environment variable X $TERM. X /bin/cat X /usr/ucb/more X /bin/sh Used when $SHELL is undefined. X XHow to install hack: X0. Compile the sources. Perhaps you should first look at the file config.h X and define BSD if you are on a BSDtype system, X define STUPID if your C-compiler chokes on complicated expressions. X Make sure schar and uchar represent signed and unsigned types. X If your C compiler doesnt allow initialization of bit fields X change Bitfield. When config.h looks reasonable, say 'make'. X (Perhaps you have to change TERMLIB in the makefile.) X1. If it didnt exist already, introduce a loginname `play' . X2. The program hack resides in a directory so that it is executable X for everybody and is suid play: X ---s--s--x 1 play 206848 Apr 3 00:17 hack X Perhaps you wish to restrict playing to certain hours, or have games X running under nice; in that case you might write a program play.c X such that the program play is suid play and executable for everybody X while all the games in /usr/games are readable or executable for X play only; all the program play does is asking for the name of a game, X checking that time-of-day and system load do not forbid playing, X and then executing the game. Thus: X -r-sr-sr-x 1 play 13312 May 24 12:52 play X ---x------ 1 play 206848 Apr 3 00:17 hack X If you are worried about security you might let play do X chroot("/usr/games") so that no player can get access to the rest X of the system via shell escapes and the likes. X If you #define SECURE in config.h then hack will not setuid(getuid()) X before executing a chdir(). Hack will always do setuid(getuid()) with X a fork. If you do not define UNIX then hack will not fork. X3. The rest of the stuff belonging to hack sits in a subdirectory hackdir X (on our system /usr/games/lib/hackdir) with modes X drwx------ 3 play 1024 Aug 9 09:03 hackdir X Here all the temporary files will be created (with names like xlock.17 X or user.5). X4. If you are not really short on file space, creating a subdirectory X hackdir/save (modes again drwx------) will enable users to save their X unfinished games. X XThe program hack is called X$ hack [-d hackdir] [maxnrofplayers] X(for playing) or X$ hack [-d hackdir] -s [listofusers | limit | all] X(for seeing part of the scorelist). XThe shell file hack (in this kit called hack.sh) takes care of Xcalling hack with the right arguments. X XSend complaints, bug reports, suggestions for improvements to Xmcvax!aeb - in real life Andries Brouwer. X X-- PC Hack 3.51 README file ---------------------------------------------------- X X Welcome to the sources for PC HACK (version 3.51). X XIntroduction X------------ XThis is a version of the public domain program HACK 1.03 (copyright XStichting Mathematisch Centrum, Amsterdam, 1984, 1985.) implemented Xunder MSDOS with the Microsoft(tm) C v3.0 compiler. X XYou may copy this version of PC HACK and make any changes you want to Xit. You may give it away, but you may not sell it. X X XThe sources are in ARC format in HACK351S.ARC. The commands: X X C> arc51 e hack351s makefile make.* X C> arc51 e hack351s *.h X C> arc51 e hack351s *.c X Xwill unpack the files. X XWith a hard disk system, you should be able to type `make' and the sources Xwill start to be compiled. This takes a long time. A floppy disk system Xdoes not really have enough storage. X X XCompiling X--------- XThe LARGE compiler model is used. To add WIZARD mode, add a -DWIZARD Xto the MAKEFILE, or a #define WIZARD to the CONFIG.H file. X XThe MAKEFILE included with PC HACK 3.51 sources is for my version of MAKE. XIt is very similar to UNIX(tm) `make'. See MAKE.DOC for details. X XTo compile the sources by hand the command for each `filename.c' file is: X msc -AL -DREGBUG -DLINT_ARGS -Ot -Gs filename.c; X X XLinking X------- XI used the Microsoft 8086 Linker version 3.01 X XTo link the *.obj files by hand, the command is: X link @linkfile X XWhere the contents of the linkfile (not supplied) should be: X Xdecl.obj apply.obj bones.obj cmd.obj do.obj + Xdo_name.obj do_wear.obj dog.obj eat.obj + Xend.obj engrave.obj fight.obj hack.obj + Xinvent.obj ioctl.obj lev.obj main.obj + Xmakemon.obj mhitu.obj mklev.obj mkmaze.obj + Xmkobj.obj mkshop.obj mon.obj monst.obj + Xo_init.obj objnam.obj options.obj pager.obj + Xpotion.obj pri.obj read.obj rip.obj + Xrumors.obj save.obj search.obj shk.obj + Xshknam.obj steal.obj termcap.obj + Xtimeout.obj topl.obj track.obj trap.obj + Xtty.obj unix.obj u_init.obj vault.obj + Xwield.obj wizard.obj worm.obj worn.obj + Xzap.obj version.obj rnd.obj alloc.obj + Xmsdos.obj Xhack /NOIG /STACK:4000; X X XDifferences from UNIX HACK X-------------------------- XChanges that were introduced to port UNIX HACK to the MSDOS environment Xare surrounded with `#ifdef MSDOS', `#endif' directives. X XOther changes I have made are surrounded by `#ifdef DGK', `#endif' Xdirectives. It should be possible to compile these sources without Xany of my changes by removing the `#define DGK' line from CONFIG.H. X XAlso, functions I have added are mainly restricted to the file msdos.c, Xalthough some of them are in other places (ie. wizard.c) X X XFinally X------- XIf you have any questions, contact me at one of: X X Don Kneller X UUCP: ...ucbvax!ucsfcgl!kneller X ARPA: kneller@ucsf-cgl.ARPA X BITNET: kneller@ucsfcgl.BITNET X USMAIL: D. G. Kneller X 2 Panoramic Way #204 X Berkeley, CA 94704 X X-------------------------------------------------------------------------------- XEND OF FILE END_OF_README.OLD if test 10200 -ne `wc -c <README.OLD`; then echo shar: \"README.OLD\" unpacked with wrong size! fi # end of overwriting check fi if test -f cmd.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"cmd.c\" else echo shar: Extracting \"cmd.c\" \(10152 characters\) sed "s/^X//" >cmd.c <<'END_OF_cmd.c' X/* SCCS Id: @(#)cmd.c 1.3 87/07/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* cmd.c - version 1.0.3 */ X X#include "hack.h" X#include "func_tab.h" X Xint doredraw(),doredotopl(),dodrop(),dodrink(),doread(),dosearch(),dopickup(), Xdoversion(),doweararm(),dowearring(),doremarm(),doddoremarm(),doremring(), Xdopay(),doapply(),dosave(),dowield(),ddoinv(),dozap(),ddocall(),dowhatis(), Xdoengrave(),dotele(),dohelp(),doeat(),doddrop(),do_mname(),doidtrap(), Xdoprwep(),doprarm(),doprring(),doprgold(),dodiscovered(),dotypeinv(),dolook(), Xdoset(),doup(), dodown(), done1(), donull(), dothrow(), doextcmd(), dodip(), Xdopray(), doextlist(); X#ifdef NEWCLASS Xint dosit(); X#endif X#ifdef SPELLS Xint docast(), dovspell(), doxcribe(); X#endif X#ifdef SHELL Xint dosh(); X#endif X#ifdef SUSPEND Xint dosuspend(); X#endif X#ifdef KAA Xint doremove(), dobreathe(); X# ifdef KOPS Xint dowipe(); X# endif X#endif X Xint rndobjsym(), rndmonsym(); Xchar *hcolor(), *rndmonnam(), *defmonnam(); X Xextern char *occtxt; Xextern int (*occupation)(); X X# ifdef DGKMOD Xint dotogglepickup(), doMSCversion(); X# ifdef DEBUG Xint dodebug(); X# endif X Xstatic int (*timed_occ_fn)(); X X/* Count down by decrementing multi */ Xtimed_occupation() { X (*timed_occ_fn)(); X if (multi > 0) X multi--; X return (multi > 0); X} X X/* If a time is given, use it to timeout this function, otherwise the X * function times out by its own means. X */ Xvoid Xset_occupation(fn, txt, time) Xint (*fn)(); Xchar *txt; X{ X if (time) { X occupation = timed_occupation; X timed_occ_fn = fn; X } else X occupation = fn; X occtxt = txt; X occtime = 0; X} X#endif /* DGKMOD */ X X#ifdef REDO X/* Provide a means to redo the last command. The flag `in_doagain' is set X * to true while redoing the command. This flag is tested in commands that X * require additional input (like `throw' which requires a thing and a X * direction), and the input prompt is not shown. Also, while in_doagain is X * TRUE, no keystrokes can be saved into the saveq. X */ X#define BSIZE 20 Xstatic char pushq[BSIZE], saveq[BSIZE]; Xstatic int phead, ptail, shead, stail; Xint in_doagain; X Xchar Xpopch() { X /* If occupied, return 0, letting tgetch know a character should X * be read from the keyboard. If the character read is not the X * ABORT character (as checked in main.c), that character will be X * pushed back on the pushq. X */ X if (occupation) return(0); X if (in_doagain) return ((shead != stail) ? saveq[stail++] : 0); X else return ((phead != ptail) ? pushq[ptail++] : 0); X} X X/* A ch == 0 resets the pushq */ Xvoid Xpushch(ch) Xchar ch; X{ X if (!ch) X phead = ptail = 0; X if (phead < BSIZE) X pushq[phead++] = ch; X} X X/* A ch == 0 resets the saveq. Only save keystrokes when not X * replaying a previous command. X */ Xvoid Xsavech(ch) Xchar ch; X{ X if (!in_doagain) { X if (!ch) X phead = ptail = shead = stail = 0; X else if (shead < BSIZE) X saveq[shead++] = ch; X } X} X# endif /* REDO */ X Xstruct func_tab cmdlist[]={ X {'\020', doredotopl}, X {'\022', doredraw}, X {'\024', dotele}, X#ifdef SUSPEND X {'\032', dosuspend}, X#endif X {'a', doapply}, X {'A', doddoremarm}, X/* 'b', 'B' : go sw */ X {'c', ddocall}, X {'C', do_mname}, X {'d', dodrop}, X {'D', doddrop}, X {'e', doeat}, X {'E', doengrave}, X/* Soon to be X {'f', dofight, "fighting"}, X {'F', doFight, "fighting"}, X */ X/* 'g', 'G' : multiple go */ X/* 'h', 'H' : go west */ X {'I', dotypeinv}, /* Robert Viduya */ X {'i', ddoinv}, X/* 'j', 'J', 'k', 'K', 'l', 'L', 'm', 'M', 'n', 'N' : move commands */ X/* 'o', doopen, */ X {'O', doset}, X {'p', dopay}, X {'P', dowearring}, X {'q', dodrink}, X {'Q', done1}, X {'r', doread}, X {'R', doremring}, X {'s', dosearch, "searching"}, X {'S', dosave}, X {'t', dothrow}, X {'T', doremarm}, X/* 'u', 'U' : go ne */ X {'v', doversion}, X {'w', dowield}, X {'W', doweararm}, X#ifdef SPELLS X {'x', dovspell}, /* Mike Stephenson */ X {'X', doxcribe}, /* Mike Stephenson */ X#endif X/* 'y', 'Y' : go nw */ X {'z', dozap}, X/* 'Z' : UNUSED */ X {'<', doup}, X {'>', dodown}, X {'/', dowhatis}, X {'?', dohelp}, X#ifdef SHELL X {'!', dosh}, X#endif X {'.', donull, "waiting"}, X {' ', donull, "waiting"}, X {',', dopickup}, X {':', dolook}, X {'^', doidtrap}, X {'\\', dodiscovered}, /* Robert Viduya */ X#ifdef DGKMOD X {'@', dotogglepickup}, X {'V', doMSCversion}, X# ifdef DEBUG_DOESNT_WORK X {'\004', dodebug}, /* generic debug function */ X# endif X#endif X {WEAPON_SYM, doprwep}, X {ARMOR_SYM, doprarm}, X {RING_SYM, doprring}, X {'$', doprgold}, X {'#', doextcmd}, X {0,0,0} X}; X Xstruct ext_func_tab extcmdlist[] = { X#ifdef KAA X "breathe", "breathe like a dragon", dobreathe, X#endif X#ifdef SPELLS X "cast", "cast a spell", docast, X#endif X "dip", "dip an object into something", dodip, X "pray", "pray to the gods for help", dopray, X#ifdef KAA X "remove", "remove a cursed item", doremove, X#endif X#ifdef NEWCLASS X "sit", "sit down", dosit, X#endif X#if defined(KOPS) && defined(KAA) X "wipe", "wipe your face off", dowipe, X#endif X "?", "get this list of extended commands", doextlist, X (char *) 0, (char *) 0, donull X}; X Xextern char *parse(), lowc(), unctrl(), quitchars[]; X Xrhack(cmd) Xregister char *cmd; X{ X register struct func_tab *tlist = cmdlist; X boolean firsttime = FALSE; X register res; X X if(!cmd) { X firsttime = TRUE; X flags.nopick = 0; X cmd = parse(); X } X#ifdef REDO X if (*cmd == DOAGAIN && !in_doagain && saveq[0]) { X in_doagain = TRUE; X stail = 0; X rhack((char *) 0); /* read and execute command */ X in_doagain = FALSE; X return; X } X X /* Special case of *cmd == ' ' handled better below */ X if(!*cmd || *cmd == 0377) { X#else X if(!*cmd || *cmd == 0377 || (flags.no_rest_on_space && *cmd == ' ')){ X#endif X bell(); X flags.move = 0; X return(0); /* probably we just had an interrupt */ X } X if(movecmd(*cmd)) { X walk: X if(multi) flags.mv = 1; X domove(); X return; X } X if(movecmd(lowc(*cmd))) { X flags.run = 1; X rush: X if(firsttime){ X if(!multi) multi = COLNO; X u.last_str_turn = 0; X } X flags.mv = 1; X#ifdef QUEST X if(flags.run >= 4) finddir(); X if(firsttime){ X u.ux0 = u.ux + u.dx; X u.uy0 = u.uy + u.dy; X } X#endif X domove(); X return; X } X if((*cmd == 'g' && movecmd(cmd[1])) || movecmd(unctrl(*cmd))) { X flags.run = 2; X goto rush; X } X if(*cmd == 'G' && movecmd(lowc(cmd[1]))) { X flags.run = 3; X goto rush; X } X if(*cmd == 'm' && movecmd(cmd[1])) { X flags.run = 0; X flags.nopick = 1; X goto walk; X } X if(*cmd == 'M' && movecmd(lowc(cmd[1]))) { X flags.run = 1; X flags.nopick = 1; X goto rush; X } X#ifdef QUEST X if(*cmd == cmd[1] && (*cmd == 'g' || *cmd == 'G')) { X flags.run = 4; X if(*cmd == 'G') flags.run += 2; X if(cmd[2] == '-') flags.run += 1; X goto rush; X } X#endif X while(tlist->f_char) { X if(*cmd == tlist->f_char){ X#ifdef DGKMOD X /* Special case of *cmd == ' ' handled here */ X if (*cmd == ' ' && flags.no_rest_on_space) X break; X X /* Now control-A can stop lengthy commands */ X if (tlist->f_text && !occupation && multi) X set_occupation(tlist->f_funct, tlist->f_text, X multi); X#endif X res = (*(tlist->f_funct))(); X if(!res) { X flags.move = 0; X multi = 0; X } X return; X } X tlist++; X } X { char expcmd[10]; X register char *cp = expcmd; X while(*cmd && cp-expcmd < sizeof(expcmd)-2) { X if(*cmd >= 040 && *cmd < 0177) X *cp++ = *cmd++; X else { X *cp++ = '^'; X *cp++ = *cmd++ ^ 0100; X } X } X *cp++ = 0; X pline("Unknown command '%s'.", expcmd); X } X multi = flags.move = 0; X} X Xdoextcmd() /* here after # - now read a full-word command */ X{ X char buf[BUFSZ]; X register struct ext_func_tab *efp = extcmdlist; X X pline("# "); X getlin(buf); X clrlin(); X if(buf[0] == '\033') X return(0); X while(efp->ef_txt) { X if(!strcmp(efp->ef_txt, buf)) X return((*(efp->ef_funct))()); X efp++; X } X pline("%s: unknown command.", buf); X return(0); X} X Xdoextlist() /* here after #? - now list all full-word commands */ X{ X register struct ext_func_tab *efp = extcmdlist; X char buf[BUFSZ]; X X set_pager(0); X if(page_line("") || X page_line(" Extended Command Set:") || X page_line("")) goto quit; X X while(efp->ef_txt) { X X (void)sprintf(buf, " %-8s - %s.", efp->ef_txt, efp->ef_desc); X if(page_line(buf)) goto quit; X efp++; X } X set_pager(1); X return(0); Xquit: X set_pager(2); X return(0); X} X Xchar Xlowc(sym) Xchar sym; X{ X return( (sym >= 'A' && sym <= 'Z') ? sym+'a'-'A' : sym ); X} X Xchar Xunctrl(sym) Xchar sym; X{ X return( (sym >= ('A' & 037) && sym <= ('Z' & 037)) ? sym + 0140 : sym ); X} X X/* 'rogue'-like direction commands */ Xchar sdir[] = "hykulnjb><"; Xschar xdir[10] = { -1,-1, 0, 1, 1, 1, 0,-1, 0, 0 }; Xschar ydir[10] = { 0,-1,-1,-1, 0, 1, 1, 1, 0, 0 }; Xschar zdir[10] = { 0, 0, 0, 0, 0, 0, 0, 0, 1,-1 }; X Xmovecmd(sym) /* also sets u.dz, but returns false for <> */ Xchar sym; X{ X register char *dp; X X u.dz = 0; X if(!(dp = index(sdir, sym))) return(0); X u.dx = xdir[dp-sdir]; X u.dy = ydir[dp-sdir]; X u.dz = zdir[dp-sdir]; X return(!u.dz); X} X Xgetdir(s) Xboolean s; X{ X char dirsym; X X#ifdef REDO X if (!in_doagain) X#endif X if(s) pline("In what direction?"); X dirsym = readchar(); X#ifdef REDO X savech(dirsym); X#endif X#ifdef KAA X if(dirsym == '.' || dirsym == 's') X u.dx = u.dy = u.dz = 0; X else X#endif X if(!movecmd(dirsym) && !u.dz) { X if(!index(quitchars, dirsym)) X pline("What a strange direction!"); X return(0); X } X if(Confusion && !u.dz) confdir(); X return(1); X} X Xconfdir() X{ X register x = rn2(8); X u.dx = xdir[x]; X u.dy = ydir[x]; X} X X#ifdef QUEST Xfinddir(){ Xregister int i, ui = u.di; X for(i = 0; i <= 8; i++){ X if(flags.run & 1) ui++; else ui += 7; X ui %= 8; X if(i == 8){ X pline("Not near a wall."); X flags.move = multi = 0; X return(0); X } X if(!isroom(u.ux+xdir[ui], u.uy+ydir[ui])) X break; X } X for(i = 0; i <= 8; i++){ X if(flags.run & 1) ui += 7; else ui++; X ui %= 8; X if(i == 8){ X pline("Not near a room."); X flags.move = multi = 0; X return(0); X } X if(isroom(u.ux+xdir[ui], u.uy+ydir[ui])) X break; X } X u.di = ui; X u.dx = xdir[ui]; X u.dy = ydir[ui]; X} X Xisroom(x,y) register x,y; { /* what about POOL? */ X return(isok(x,y) && (levl[x][y].typ == ROOM || X (levl[x][y].typ >= LDOOR && flags.run >= 6))); X} X#endif /* QUEST /**/ X Xisok(x,y) register x,y; { X /* x corresponds to curx, so x==1 is the first column. Ach. %% */ X return(x >= 1 && x <= COLNO-1 && y >= 0 && y <= ROWNO-1); X} END_OF_cmd.c if test 10152 -ne `wc -c <cmd.c`; then echo shar: \"cmd.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f data.base -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"data.base\" else echo shar: Extracting \"data.base\" \(9619 characters\) sed "s/^X//" >data.base <<'END_OF_data.base' X NetHack & Quest data file - version 1.0 X@ human (or you) X- a wall X| a wall X+ a door X. the floor of a room X a dark part of a room X# a corridor X} water filled area X< the staircase to the previous level X> the staircase to the next level X^ a trap X$ a pile, pot or chest of gold X%% a piece of food X! a potion X* a gem X? a scroll X= a ring X/ a wand X[ a suit of armor X) a weapon X( a useful item (camera, key, rope etc.) X0 an iron ball X_ an iron chain X` an enormous rock (or opulant throne) X" an amulet X, a trapper X: a chameleon X; a giant eel X' a lurker above X& a demon XA a giant ant XB a giant bat XC a centaur; X Of all the monsters put together by the Greek imagination X the Centaurs (Kentauroi) constituted a class in themselves. X Despite a strong streak of sensuality in their make-up, X their normal behaviour was moral, and they took a kindly X thought of man's welfare. The attempted outrage of Nessos on X Deianeira, and that of the whole tribe of Centaurs on the X Lapith women, are more than offset by the hospitality of X Pholos and by the wisdom of Cheiron, physician, prophet, X lyrist, and the instructor of Achilles. Further, the Cen- X taurs were peculiar in that their nature, which united the X body of a horse with the trunk and head of a man, involved X an unthinkable duplication of vital organs and important X members. So grotesque a combination seems almost un-Greek. X These strange creatures were said to live in the caves and X clefts of the mountains, myths associating them especially X with the hills of Thessaly and the range of Erymanthos. X [Mythology of all races, Vol. 1, pp. 270-271] XD a dragon; X In the West the dragon was the natural enemy of man. Although X preferring to live in bleak and desolate regions, whenever it was X seen among men it left in its wake a trail of destruction and X disease. Yet any attempt to slay this beast was a perilous under- X taking. For the dragon's assailant had to contend not only with X clouds of sulphurous fumes pouring from its fire-breathing nos- X trils, but also with the thrashings of its tail, the most deadly X part of its serpent-like body. X [From: Mythical Beasts by Deirdre Headon (The Leprechaun Library)] XE a floating eye XF a freezing sphere XG a gnome; X ... And then a gnome came by, carrying a bundle, an old fellow X three times as large as an imp and wearing clothes of a sort, X especially a hat. And he was clearly just as frightened as the X imps though he could not go so fast. Ramon Alonzo saw that there X must be some great trouble that was vexing magical things; and, X since gnomes speak the language of men, and will answer if spoken X to gently, he raised his hat, and asked of the gnome his name. X The gnome did not stop his hasty shuffle a moment as he answered X 'Alaraba' and grabbed the rim of his hat but forgot to doff it. X 'What is the trouble, Alaraba?' said Ramon Alonzo. X 'White magic. Run!' said the gnome ... X [From: The Charwoman's Shadow, by Lord Dunsany.] XH a hobgoblin; X Hobgoblin. Used by the Puritans and in later times for X wicked goblin spirits, as in Bunyan's 'Hobgoblin nor foul X friend', but its more correct use is for the friendly spir- X its of the brownie type. In 'A midsummer night's dream' a X fairy says to Shakespeare's Puck: X Those that Hobgoblin call you, and sweet Puck, X You do their work, and they shall have good luck: X Are you not he? X and obviously Puck would not wish to be called a hobgoblin X if that was an ill-omened word. X Hobgoblins are on the whole, good-humoured and ready to be X helpful, but fond of practical joking, and like most of the X fairies rather nasty people to annoy. Boggarts hover on the X verge of hobgoblindom. Bogles are just over the edge. X One Hob mentioned by Henderson, was Hob Headless who haunted X the road between Hurworth and Neasham, but could not cross X the little river Kent, which flowed into the Tess. He was X exorcised and laid under a large stone by the roadside for X ninety-nine years and a day. If anyone was so unwary as to X sit on that stone, he would be unable to quit it for ever. X The ninety-nine years is nearly up, so trouble may soon be X heard of on the road between Hurworth and Neasham. X [Katharine Briggs, A dictionary of Fairies] XI an invisible stalker XJ a jackal XK a kobold XL a leprechaun; X The Irish Leprechaun is the Faeries' shoemaker and is known X under various names in different parts of Ireland: Cluri- X caune in Cork, Lurican in Kerry, Lurikeen in Kildare and Lu- X rigadaun in Tipperary. Although he works for the Faeries, X the Leprechaun is not of the same species. He is small, has X dark skin and wears strange clothes. His nature has some- X thing of the manic-depressive about it: first he is quite X happy, whistling merrily as he nails a sole on to a shoe; a X few minutes later, he is sullen and morose, drunk on his X home-made heather ale. The Leprechaun's two great loves are X tobacco and whiskey, and he is a first-rate con-man, impos- X sible to out-fox. No one, no matter how clever, has ever X managed to cheat him out of his hidden pot of gold or his X magic shilling. At the last minute he always thinks of some X way to divert his captor's attention and vanishes in the X twinkling of an eye. X [From: A Field Guide to the Little People X by Nancy Arrowsmith & George Moorse. ] XM a mimic XN a nymph XO an orc XP a purple worm XQ a quasit XR a rust monster XS a snake XT a troll XU an umber hulk XV a vampire XW a wraith XX a xorn XY a yeti XZ a zombie Xa an acid blob Xb a giant beetle Xc a cockatrice; X Once in a great while, when the positions of the stars are X just right, a seven-year-old rooster will lay an egg. Then, X along will come a snake, to coil around the egg, or a toad, X to squat upon the egg, keeping it warm and helping it to X hatch. When it hatches, out comes a creature called basil- X isk, or cockatrice, the most deadly of all creatures. A sin- X gle glance from its yellow, piercing toad's eyes will kill X both man and beast. Its power of destruction is said to be X so great that sometimes simply to hear its hiss can prove X fatal. Its breath is so venomenous that it causes all vege- X tation to wither. X There is, however, one creature which can withstand the X basilisk's deadly gaze, and this is the weasel. No one knows X why this is so, but although the fierce weasel can slay the X basilisk, it will itself be killed in the struggle. Perhaps X the weasel knows the basilisk's fatal weakness: if it ever X sees its own reflection in a mirror it will perish instant- X ly. But even a dead basilisk is dangerous, for it is said X that merely touching its lifeless body can cause a person to X sicken and die. X [From: Mythical Beasts by Deirdre Headon (The Leprechaun X Library) and other sources. ] Xd a dog Xe an ettin Xf a fog cloud Xg a gelatinous cube Xh a homunculus Xi an imp; X ... imps ... little creatures of two feet high that could X gambol and jump prodigiously; ... X [From: The Charwoman's Shadow, by Lord Dunsany.] X X An 'imp' is an off-shoot or cutting. Thus an 'ymp tree' was X a grafted tree, or one grown from a cutting, not from seed. X 'Imp' properly means a small devil, an off-shoot of Satan, X but the distinction between goblins or bogles and imps from X hell is hard to make, and many in the Celtic countries as X well as the English Puritans regarded all fairies as devils. X The fairies of tradition often hover uneasily between the X ghostly and the diabolic state. X [Katharine Briggs, A dictionary of Fairies] Xj a jaguar Xk a killer bee Xl a leocrotta Xm a minotaur Xn a nurse Xo an owlbear Xp a piercer Xq a quivering blob Xr a giant rat Xs a scorpion Xt a tengu; X The tengu was the most troublesome creature of Japanese X legend. Part bird and part man, with red beak for a nose X and flashing eyes, the tengu was notorious for stirring up X feuds and prolonging enmity between families. Indeed, the X belligerent tengus were supposed to have been man's first X instructors in the use of arms. X [From: Mythical Beasts by Deirdre Headon X (The Leprechaun Library). ] Xu a unicorn; X Men have always sought the elusive unicorn, for the single X twisted horn which projected from its forehead was thought X to be a powerful talisman. It was said that the unicorn had X simply to dip the tip of its horn in a muddy pool for the X water to become pure. Men also believed that to drink from X this horn was a protection against all sickness, and that if X the horn was ground to a powder it would act as an antidote X to all poisons. Less than 200 years ago in France, the horn X of a unicorn was used in a ceremony to test the royal food X for poison. X Although only the size of a small horse, the unicorn is a X very fierce beast, capable of killing an elephant with a X single thrust from its horn. Its fleetness of foot also X makes this solitary creature difficult to capture. However, X it can be tamed and captured by a maiden. Made gentle by the X sight of a virgin, the unicorn can be lured to lay its head X in her lap, and in this docile mood, the maiden may secure X it with a golden rope. X [From: Mythical Beasts by Deirdre Headon X (The Leprechaun Library). ] Xv a violet fungi Xw a long worm; X From its teeth the crysknife can be manufactured. X~ the tail of a long worm Xx a xan; X The xan were animals sent to prick the legs of the Lords of Xibalba. Xy a yellow light Xz a zruty; X The zruty are wild and gigantic beings, living in the wildernesses X of the Tatra mountains. X1 The wizard of Yendor X2 The mail daemon END_OF_data.base if test 9619 -ne `wc -c <data.base`; then echo shar: \"data.base\" unpacked with wrong size! fi # end of overwriting check fi if test -f save.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"save.c\" else echo shar: Extracting \"save.c\" \(10331 characters\) sed "s/^X//" >save.c <<'END_OF_save.c' X/* SCCS Id: @(#)save.c 1.3 87/07/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* save.c - version 1.0.3 */ X X#include <signal.h> X#include <stdio.h> X#include "hack.h" Xextern char genocided[60]; /* defined in Decl.c */ Xextern char fut_geno[60]; /* idem */ Xextern struct permonst pm_wizard; /* since the wizard evolves */ X Xextern char SAVEF[], nul[]; Xextern char pl_character[PL_CSIZ]; Xextern long lseek(); Xextern struct obj *restobjchn(); Xextern struct monst *restmonchn(); X Xdosave(){ X clear_screen(); X fflush(stdout); X if(dosave0(0)) { X settty("Be seeing you ...\n"); X exit(0); X } X#ifdef lint X return(0); X#endif X} X X#ifndef NOSAVEONHANGUP Xhangup(){ X (void) dosave0(1); X exit(1); X} X#endif X X/* returns 1 if save successful */ Xdosave0(hu) int hu; { X register fd, ofd; X int tmp; /* not register ! */ X#ifdef DGK X long fds, needed; X extern long bytes_counted; X int mode; X#endif X#ifdef UNIX X (void) signal(SIGHUP, SIG_IGN); X#endif X (void) signal(SIGINT, SIG_IGN); X#ifdef DGK X if (!saveDiskPrompt(0)) X return 0; X fd = open(SAVEF, O_WRONLY | O_BINARY | O_CREAT, FMASK); X#else X fd = creat(SAVEF, FMASK); X#endif X if(fd < 0) { X if(!hu) pline("Cannot open save file. (Continue or Quit)"); X (void) unlink(SAVEF); /* ab@unido */ X return(0); X } X if(flags.moonphase == FULL_MOON) /* ut-sally!fletcher */ X u.uluck--; /* and unido!ab */ X#ifdef DGKMOD X home(); X cl_end(); X#endif X#ifdef DGK X msmsg("Saving: "); X mode = COUNT; Xagain: X savelev(fd, dlevel, mode); X /* count_only will be set properly by savelev */ X#else X savelev(fd,dlevel); X#endif X saveobjchn(fd, invent); X saveobjchn(fd, fcobj); X savemonchn(fd, fallen_down); X tmp = getuid(); X bwrite(fd, (char *) &tmp, sizeof tmp); X bwrite(fd, (char *) &flags, sizeof(struct flag)); X bwrite(fd, (char *) &dlevel, sizeof dlevel); X bwrite(fd, (char *) &maxdlevel, sizeof maxdlevel); X bwrite(fd, (char *) &moves, sizeof moves); X bwrite(fd, (char *) &u, sizeof(struct you)); X#ifdef SPELLS X bwrite(fd, (char *) spl_book, sizeof(struct spell) * (MAXSPELL + 1)); X#endif X if(u.ustuck) X bwrite(fd, (char *) &(u.ustuck->m_id), sizeof u.ustuck->m_id); X bwrite(fd, (char *) pl_character, sizeof pl_character); X bwrite(fd, (char *) genocided, sizeof genocided); X bwrite(fd, (char *) fut_geno, sizeof fut_geno); X#ifdef HARD X bwrite(fd, (char *) &pm_wizard, sizeof(struct permonst)); X#endif X savenames(fd); X#ifdef DGK X if (mode == COUNT) { X /* make sure there is enough disk space */ X needed = bytes_counted; X for (tmp = 1; tmp <= maxdlevel; tmp++) X if (tmp != dlevel && fileinfo[tmp].where) X needed += fileinfo[tmp].size + (sizeof tmp); X fds = freediskspace(SAVEF); X if (needed > fds) { X pline("There is insufficient space on SAVE disk."); X pline("Require %ld bytes but only have %ld.", needed, X fds); X flushout(); X (void) close(fd); X (void) unlink(SAVEF); X return 0; X } X mode = WRITE; X goto again; X } X#endif X for(tmp = 1; tmp <= maxdlevel; tmp++) { X extern int hackpid; X#ifdef DGK X if (tmp == dlevel || !fileinfo[tmp].where) continue; X if (fileinfo[tmp].where != ACTIVE) X swapin_file(tmp); X#else X extern boolean level_exists[]; X X if(tmp == dlevel || !level_exists[tmp]) continue; X#endif X glo(tmp); X#ifdef DGK X msmsg("."); X#endif X if((ofd = open(lock, 0)) < 0) { X if(!hu) pline("Error while saving: cannot read %s.", lock); X (void) close(fd); X (void) unlink(SAVEF); X if(!hu) done("tricked"); X return(0); X } X getlev(ofd, hackpid, tmp); X (void) close(ofd); X bwrite(fd, (char *) &tmp, sizeof tmp); /* level number */ X#ifdef DGK X savelev(fd,tmp,WRITE); /* actual level */ X#else X savelev(fd,tmp); /* actual level */ X#endif X (void) unlink(lock); X } X (void) close(fd); X glo(dlevel); X (void) unlink(lock); /* get rid of current level --jgm */ X glo(0); X (void) unlink(lock); X return(1); X} X Xdorecover(fd) Xregister fd; X{ X register nfd; X int tmp; /* not a register ! */ X unsigned mid; /* idem */ X struct obj *otmp; X extern boolean restoring; X#ifdef DGK X struct flag oldflags; X X oldflags = flags; /* Save flags set in the config file */ X#endif X restoring = TRUE; X getlev(fd, 0, 0); X invent = restobjchn(fd); X for(otmp = invent; otmp; otmp = otmp->nobj) X if(otmp->owornmask) X setworn(otmp, otmp->owornmask); X fcobj = restobjchn(fd); X fallen_down = restmonchn(fd); X mread(fd, (char *) &tmp, sizeof tmp); X if(tmp != getuid()) { /* strange ... */ X (void) close(fd); X (void) unlink(SAVEF); X puts("Saved game was not yours."); X restoring = FALSE; X return(0); X } X mread(fd, (char *) &flags, sizeof(struct flag)); X#ifdef DGK X /* Some config file OPTIONS take precedence over those in save file. X */ X flags.rawio = oldflags.rawio; X flags.DECRainbow = oldflags.DECRainbow; X flags.IBMBIOS = oldflags.IBMBIOS; X#endif X mread(fd, (char *) &dlevel, sizeof dlevel); X mread(fd, (char *) &maxdlevel, sizeof maxdlevel); X mread(fd, (char *) &moves, sizeof moves); X mread(fd, (char *) &u, sizeof(struct you)); X#ifdef SPELLS X mread(fd, (char *) spl_book, sizeof(struct spell) * (MAXSPELL + 1)); X#endif X if(u.ustuck) X mread(fd, (char *) &mid, sizeof mid); X mread(fd, (char *) pl_character, sizeof pl_character); X mread(fd, (char *) genocided, sizeof genocided); X mread(fd, (char *) fut_geno, sizeof fut_geno); X#ifdef HARD X mread(fd, (char *) &pm_wizard, sizeof(struct permonst)); X#endif X restnames(fd); X#ifdef DGK X msmsg("\n"); X cl_end(); X msmsg("You got as far as level %d%s.\n", maxdlevel, X flags.debug ? " in WIZARD mode" : ""); X cl_end(); X msmsg("Restoring: "); X#endif X while(1) { X if(read(fd, (char *) &tmp, sizeof tmp) != sizeof tmp) X break; X getlev(fd, 0, tmp); X glo(tmp); X#ifdef DGK X msmsg("."); X nfd = open(lock, O_WRONLY | O_BINARY | O_CREAT | O_TRUNC, FMASK); X#else X nfd = creat(lock, FMASK); X#endif X if (nfd < 0) panic("Cannot open temp file %s!\n", lock); X#ifdef DGK X if (!savelev(nfd, tmp, COUNT | WRITE)) { X X /* The savelev can't proceed because the size required X * is greater than the available disk space. X */ X msmsg("\nNot enough space on `%s' to restore your game.\n", X levels); X X /* Remove levels and bones that may have been created. X */ X (void) close(nfd); X eraseall(levels, alllevels); X eraseall(levels, allbones); X X /* Perhaps the person would like to play without a X * RAMdisk. X */ X if (ramdisk) { X /* PlaywoRAMdisk may not return, but if it does X * it is certain that ramdisk will be 0. X */ X playwoRAMdisk(); X (void) lseek(fd, 0L, 0); /* Rewind save file */ X return dorecover(fd); /* and try again */ X } else { X msmsg("Be seeing you ...\n"); X exit(0); X } X } X#else X savelev(nfd,tmp); X#endif X (void) close(nfd); X } X (void) lseek(fd, 0L, 0); X getlev(fd, 0, 0); X (void) close(fd); X (void) unlink(SAVEF); X if(Punished) { X for(otmp = fobj; otmp; otmp = otmp->nobj) X if(otmp->olet == CHAIN_SYM) goto chainfnd; X panic("Cannot find the iron chain?"); X chainfnd: X uchain = otmp; X if(!uball){ X for(otmp = fobj; otmp; otmp = otmp->nobj) X if(otmp->olet == BALL_SYM && otmp->spe) X goto ballfnd; X panic("Cannot find the iron ball?"); X ballfnd: X uball = otmp; X } X } X if(u.ustuck) { X register struct monst *mtmp; X X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) X if(mtmp->m_id == mid) goto monfnd; X panic("Cannot find the monster ustuck."); X monfnd: X u.ustuck = mtmp; X } X#ifndef QUEST X setsee(); /* only to recompute seelx etc. - these weren't saved */ X#endif X#ifdef DGK X gameDiskPrompt(); X#endif X docrt(); X restoring = FALSE; X return(1); X} X Xstruct obj * Xrestobjchn(fd) Xregister fd; X{ X register struct obj *otmp, *otmp2; X register struct obj *first = 0; X int xl; X#ifdef lint X /* suppress "used before set" warning from lint */ X otmp2 = 0; X#endif X while(1) { X mread(fd, (char *) &xl, sizeof(xl)); X if(xl == -1) break; X otmp = newobj(xl); X if(!first) first = otmp; X else otmp2->nobj = otmp; X mread(fd, (char *) otmp, (unsigned) xl + sizeof(struct obj)); X if(!otmp->o_id) otmp->o_id = flags.ident++; X otmp2 = otmp; X } X if(first && otmp2->nobj){ X impossible("Restobjchn: error reading objchn."); X otmp2->nobj = 0; X } X return(first); X} X#ifdef MSDOS Xstruct monst * Xrestmonchn(fd) Xregister fd; X{ X register struct monst *mtmp, *mtmp2; X register struct monst *first = 0; X int xl; X int monsindex; X extern struct permonst li_dog, dog, la_dog; X#ifdef KAA X extern struct permonst hell_hound; X# ifdef HARD X extern struct permonst d_lord, d_prince; X# endif X#endif X X#ifdef lint X /* suppress "used before set" warning from lint */ X mtmp2 = 0; X#endif /* lint /**/ X while(1) { X mread(fd, (char *) &xl, sizeof(xl)); X if(xl == -1) break; X mtmp = newmonst(xl); X if(!first) first = mtmp; X else mtmp2->nmon = mtmp; X mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst)); X if(!mtmp->m_id) X mtmp->m_id = flags.ident++; X monsindex = *((int *)&mtmp->data); X if (monsindex == -1) /* Special fake index */ X mtmp->data = &li_dog; X else if (monsindex == -2) /* Special fake index */ X mtmp->data = &dog; X else if (monsindex == -3) /* Special fake index */ X mtmp->data = &la_dog; X#ifdef KAA X else if (monsindex == -4) X mtmp->data = &hell_hound; X# ifdef HARD X else if (monsindex == -5) X permonstp = &d_lord; X X else if (monsindex == -6) X permonstp = &d_prince; X# endif X#endif X else X mtmp->data = &mons[monsindex]; X if(mtmp->minvent) X mtmp->minvent = restobjchn(fd); X mtmp2 = mtmp; X } X if(first && mtmp2->nmon){ X impossible("Restmonchn: error reading monchn."); X mtmp2->nmon = 0; X } X return(first); X} X#else Xstruct monst * Xrestmonchn(fd) Xregister fd; X{ X register struct monst *mtmp, *mtmp2; X register struct monst *first = 0; X int xl; X X struct permonst *monbegin; X long differ; X X mread(fd, (char *)&monbegin, sizeof(monbegin)); X differ = (char *)(&mons[0]) - (char *)(monbegin); X X#ifdef lint X /* suppress "used before set" warning from lint */ X mtmp2 = 0; X#endif X while(1) { X mread(fd, (char *) &xl, sizeof(xl)); X if(xl == -1) break; X mtmp = newmonst(xl); X if(!first) first = mtmp; X else mtmp2->nmon = mtmp; X mread(fd, (char *) mtmp, (unsigned) xl + sizeof(struct monst)); X if(!mtmp->m_id) X mtmp->m_id = flags.ident++; X mtmp->data = (struct permonst *) X ((char *) mtmp->data + differ); X if(mtmp->minvent) X mtmp->minvent = restobjchn(fd); X mtmp2 = mtmp; X } X if(first && mtmp2->nmon){ X impossible("Restmonchn: error reading monchn."); X mtmp2->nmon = 0; X } X return(first); X} X#endif END_OF_save.c if test 10331 -ne `wc -c <save.c`; then echo shar: \"save.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f spell.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"spell.c\" else echo shar: Extracting \"spell.c\" \(9414 characters\) sed "s/^X//" >spell.c <<'END_OF_spell.c' X/* SCCS Id: @(#)spell.c 1.3 87/07/14 X/* hack.spell.c - version 1.0.1 M. Stephenson 07-04-86 */ X X#include "hack.h" X#ifdef SPELLS Xextern char *nomovemsg; X Xdoxcribe() { X register struct obj *book; X struct obj *getobj(); X register boolean confused = (Confusion != 0); X register boolean oops; X register schar delay; X register int booktype; X register int i; X X book = getobj("+", "transcribe"); X if(!book) return(0); X X if(Blind) { X pline("Being blind, you cannot read the mystic runes."); X useup(book); /* well, if you are stupid... */ X return(0); X } X X if(confused) { X pline("Being confused, you cannot grasp the meaning of this tome."); X useup(book); /* and more stupidity... */ X return(0); X } X booktype = book->otyp; X oops = !rn2(u.ulevel - objects[booktype].spl_lev + 7); X switch(booktype) { X X/* level 1 spells */ X case SPE_HEALING: X case SPE_DETECT_MONSTERS: X case SPE_FORCE_BOLT: X case SPE_LIGHT: X case SPE_SLEEP: X/* level 2 spells */ X case SPE_MAGIC_MISSILE: X case SPE_CONFUSE_MONSTER: X case SPE_SLOW_MONSTER: X case SPE_CURE_BLINDNESS: X case SPE_CREATE_MONSTER: X case SPE_DETECT_FOOD: X delay = -objects[booktype].oc_delay; X break; X/* level 3 spells */ X case SPE_HASTE_SELF: X case SPE_CAUSE_FEAR: X case SPE_CURE_SICKNESS: X case SPE_DETECT_UNSEEN: X case SPE_EXTRA_HEALING: X case SPE_CHARM_MONSTER: X/* level 4 spells */ X case SPE_LEVITATION: X case SPE_RESTORE_STRENGTH: X case SPE_INVISIBILITY: X case SPE_FIREBALL: X case SPE_DETECT_TREASURE: X delay = -(objects[booktype].spl_lev - 1) * objects[booktype].oc_delay; X break; X/* level 5 spells */ X case SPE_REMOVE_CURSE: X case SPE_MAGIC_MAPPING: X case SPE_CONE_OF_COLD: X case SPE_IDENTIFY: X case SPE_DIG: X/* level 6 spells */ X case SPE_TURN_UNDEAD: X case SPE_POLYMORPH: X case SPE_CREATE_FAMILIAR: X case SPE_TELEPORT_AWAY: X delay = -objects[booktype].spl_lev * objects[booktype].oc_delay; X break; X/* level 7 spells */ X case SPE_CANCELLATION: X case SPE_FINGER_OF_DEATH: X case SPE_GENOCIDE: X delay = -8 * objects[booktype].oc_delay; X break; X/* impossible */ X default: X impossible("Unknown spell-book, %d;", booktype); X return(0); X } X X pline("You begin to transcribe the spell."); X if(oops || book->cursed) { X cursed_book(objects[booktype].spl_lev); X nomul(delay); /* study time */ X } else { X nomul(delay); /* study time */ X for(i = 0; i < MAXSPELL; i++) { X if(spl_book[i].sp_id == booktype) { X nomovemsg = "Oh, you already know that one!"; X useup(book); X return(1); X } else if (spl_book[i].sp_id == NO_SPELL) { X spl_book[i].sp_id = booktype; X spl_book[i].sp_lev = objects[booktype].spl_lev; X spl_book[i].sp_flags = objects[booktype].bits; X nomovemsg = "You add the spell to your books."; X objects[booktype].oc_name_known = 1; X useup(book); X return(1); X } X } X impossible("Too many spells in spellbook!"); X } X useup(book); X return(1); X} X Xcursed_book(level) X register int level; X{ X register int nobj, cnt, onum; X register struct obj *otmp; X X switch(rnd(level)) { X case 0: X pline("you feel a wrenching sensation."); X tele(); /* teleport him */ X break; X case 1: X pline("you feel threatened."); X aggravate(); X break; X case 2: X if(!Blind) pline("a cloud of darkness falls upon you."); X Blind += rn1(100,250); X seeoff(0); X break; X case 3: X if (u.ugold <= 0) { X pline("you feel a strange sensation."); X } else { X pline("you notice you have no gold!"); X u.ugold = 0; X flags.botl = 1; X } X break; X case 4: X pline("These runes were just too much to comprehend."); X HConfusion += rn1(7,16); X break; X case 5: X pline("The book was coated with contact poison!"); X if(Poison_resistance) { X losestr(rn1(1,2)); X losehp(rnd(6), "contact poison"); X } else { X losestr(rn1(4,3)); X losehp(rnd(10), "contact poison"); X } X break; X case 6: X pline("As you read the book, it explodes in your face!"); X losehp (2*rnd(10)+5, "exploding rune"); X break; X case 7: X /* curse a few inventory items at random! */ X nobj = 0; X for (otmp = invent; otmp; otmp = otmp->nobj) nobj++; X X for (cnt = rnd(6); cnt > 0; cnt--) { X X onum = rn2(nobj); X for(otmp = invent; onum != 0; onum--) otmp = otmp->nobj; X otmp->cursed++; X } X break; X } X return(0); X} X Xdocast() X{ X register int spell, energy; X register boolean confused = (Confusion != 0); X register struct obj *pseudo; X struct obj *mksobj(); X X spell = getspell(); X if (!spell) return(0); X else { X X energy = spellev(spell); X if(energy > u.uen) { X pline("You are too weak to cast that spell."); X return(0); X } else if ((u.uhunger <= 100) || (u.ustr < 6)) { X pline("You miss the strength for that spell."); X return(0); X } else { X morehungry(energy * 10); X u.uen -= energy; X } X } X#ifdef HARD X if ((rn2(10) + u.ulevel + u.uluck - spellev(spell)) < 0) { X X pline("Fizzle....."); X return(0); X } X#endif X X/* pseudo is a temporary "false" object containing the spell stats. */ X pseudo = mksobj(spellid(spell)); X pseudo->quan = 20; /* do not let useup get it */ X switch(pseudo->otyp) { X X/* These spells are all duplicates of wand effects */ X case SPE_FORCE_BOLT: X case SPE_SLEEP: X case SPE_MAGIC_MISSILE: X case SPE_SLOW_MONSTER: X case SPE_FIREBALL: X case SPE_CONE_OF_COLD: X case SPE_DIG: X case SPE_TURN_UNDEAD: X case SPE_POLYMORPH: X case SPE_TELEPORT_AWAY: X case SPE_CANCELLATION: X case SPE_FINGER_OF_DEATH: X case SPE_LIGHT: X case SPE_DETECT_UNSEEN: X if (!(objects[pseudo->otyp].bits & NODIR)) getdir(1); X weffects(pseudo); X break; X/* These are all duplicates of scroll effects */ X case SPE_CONFUSE_MONSTER: X case SPE_DETECT_FOOD: X case SPE_CAUSE_FEAR: X case SPE_CHARM_MONSTER: X case SPE_REMOVE_CURSE: X case SPE_MAGIC_MAPPING: X case SPE_CREATE_MONSTER: X case SPE_IDENTIFY: X case SPE_GENOCIDE: X seffects(pseudo); X break; X case SPE_HASTE_SELF: X case SPE_DETECT_TREASURE: X case SPE_DETECT_MONSTERS: X case SPE_LEVITATION: X case SPE_RESTORE_STRENGTH: X case SPE_INVISIBILITY: X peffects(pseudo); X break; X case SPE_HEALING: X pline("You feel a bit better."); X healup(rnd(8), 1, 0, 0); X break; X case SPE_CURE_BLINDNESS: X healup(0, 0, 0, 1); X break; X case SPE_CURE_SICKNESS: X pline("You are no longer ill."); X healup(0, 0, 1, 0); X break; X case SPE_EXTRA_HEALING: X pline("You feel a fair bit better."); X healup(d(2,8), 1, 0, 0); X break; X case SPE_CREATE_FAMILIAR: X { register struct monst *mtmp; X struct monst *makedog(); X X mtmp = makedog(); X if(mtmp) { X /* make it into something else */ X (void) newcham(mtmp, &mons[dlevel+14+rn2(CMNUM-14-dlevel)]); X if(confused) X mtmp->mtame = mtmp->mpeaceful = 0; X } X } X break; X default: X impossible("Unknown spell %d attempted.", spell); X obfree(pseudo, (struct obj *)0); X return(0); X } X flags.botl = 1; X obfree(pseudo, (struct obj *)0); /* now, get rid of it */ X return(1); X} X Xgetspell() { X X register int max, ilet, i; X char lets[BUFSZ], buf[BUFSZ]; X X if (spl_book[0].sp_id == NO_SPELL) { X X pline("You don't know any spells right now."); X return(0); X } else { X X for(max = 1; (max < MAXSPELL) && (spl_book[max].sp_id != NO_SPELL); max++); X if (max >= MAXSPELL) { X X impossible("Too many spells memorized."); X return(0); X } X X for(i = 0; (i < max) && (i < 26); buf[++i] = 0) buf[i] = 'a' + i; X for(i = 26; (i < max) && (i < 52); buf[++i] = 0) buf[i] = 'A' + i - 26; X X if (max == 1) strcpy(lets, "a"); X else if (max < 27) sprintf(lets, "a-%c", 'a' + max - 1); X else if (max == 27) sprintf(lets, "a-z A"); X else sprintf(lets, "a-z A-%c", 'A' + max - 27); X for(;;) { X X pline("Cast which spell [%s ?]: ", lets); X if ((ilet = readchar()) == '?') { X dovspell(); X continue; X } else if ((ilet == '\033')||(ilet == '\n')||(ilet == ' ')) X return(0); X else for(i = 0; buf[i] != 0; i++) if(ilet == buf[i]) return(++i); X pline("You don't know that spell."); X } X } X} X Xlosespells() { X register boolean confused = (Confusion != 0); X register int n, nzap, i; X X for(n = 0;(spl_book[n].sp_id != NO_SPELL) && (n < MAXSPELL); n++); X if (!n) return; X if (n < MAXSPELL) { X nzap = rnd(n); X if (nzap < n) nzap += confused; X for (i = 0; i < nzap; i++) spl_book[n-i-1].sp_id = NO_SPELL; X } else impossible("Too many spells in spellbook!"); X return; X} X Xdovspell() { X X register int max, i, side; X char buf[BUFSZ], X *spellname(); X X if (spl_book[0].sp_id == NO_SPELL) { X X pline("You don't know any spells right now."); X return(0); X } else { X X for(max = 1; (max < MAXSPELL) && (spl_book[max].sp_id != NO_SPELL); max++); X if (max >= MAXSPELL) { X X impossible("Too many spells memorized."); X return(0); X } X } X set_pager(0); X side = (max + 1) / 2; X if(page_line("Currently known spells:") || page_line("")) goto quit; X X for(i = 1; i <= side; i++) { X X if((i < side) || !(max % 2)) { X X (void) sprintf(buf, "%c - (%d) %22s %c - (%d) %22s", X spellet(i), spellev(i), spellname(i), X spellet(i + side), spellev(i + side), spellname(i + side)); X } else { X X (void) sprintf(buf, "%c - (%d) %22s", spellet(i), spellev(i), spellname(i)); X } X if(page_line(buf)) goto quit; X } X X set_pager(1); X return(0); Xquit: X set_pager(2); X return(0); X} X Xspellet(spl) { X X if (spl < 27) return('a' + spl - 1); X else return('A' + spl - 27); X} X Xspellev(spl) { X X return(spl_book[spl-1].sp_lev); X} X Xchar * Xspellname(spl) { X X return(objects[spl_book[spl-1].sp_id].oc_name); X} X Xspellid(spl) { X X return(spl_book[spl-1].sp_id); X} X X#endif /* SPELLS /**/ END_OF_spell.c if test 9414 -ne `wc -c <spell.c`; then echo shar: \"spell.c\" unpacked with wrong size! fi # end of overwriting check fi if test -f worn.c -a "${1}" != "-c" ; then echo shar: Will not over-write existing file \"worn.c\" else echo shar: Extracting \"worn.c\" \(1402 characters\) sed "s/^X//" >worn.c <<'END_OF_worn.c' X/* SCCS Id: @(#)worn.c 1.3 87/07/14 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* worn.c - version 1.0.2 */ X X#include "hack.h" X Xstruct worn { X long w_mask; X struct obj **w_obj; X} worn[] = { X { W_ARM, &uarm }, X { W_ARM2, &uarm2 }, X { W_ARMH, &uarmh }, X { W_ARMS, &uarms }, X { W_ARMG, &uarmg }, X { W_RINGL, &uleft }, X { W_RINGR, &uright }, X { W_WEP, &uwep }, X { W_BALL, &uball }, X { W_CHAIN, &uchain }, X { 0, 0 } X}; X Xsetworn(obj, mask) Xregister struct obj *obj; Xlong mask; X{ X register struct worn *wp; X register struct obj *oobj; X X for(wp = worn; wp->w_mask; wp++) if(wp->w_mask & mask) { X oobj = *(wp->w_obj); X if(oobj && !(oobj->owornmask & wp->w_mask)) X impossible("Setworn: mask = %ld.", wp->w_mask); X if(oobj) oobj->owornmask &= ~wp->w_mask; X if(obj && oobj && wp->w_mask == W_ARM){ X if(uarm2) { X impossible("Setworn: uarm2 set?"); X } else X setworn(uarm, W_ARM2); X } X *(wp->w_obj) = obj; X if(obj) obj->owornmask |= wp->w_mask; X } X if(uarm2 && !uarm) { X uarm = uarm2; X uarm2 = 0; X uarm->owornmask ^= (W_ARM | W_ARM2); X } X} X X/* called e.g. when obj is destroyed */ Xsetnotworn(obj) register struct obj *obj; { X register struct worn *wp; X X for(wp = worn; wp->w_mask; wp++) X if(obj == *(wp->w_obj)) { X *(wp->w_obj) = 0; X obj->owornmask &= ~wp->w_mask; X } X if(uarm2 && !uarm) { X uarm = uarm2; X uarm2 = 0; X uarm->owornmask ^= (W_ARM | W_ARM2); X } X} END_OF_worn.c if test 1402 -ne `wc -c <worn.c`; then echo shar: \"worn.c\" unpacked with wrong size! fi # end of overwriting check fi echo shar: End of archive 11 \(of 16\). cp /dev/null ark11isdone 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