From mipos3!omepd!littlei!reed!tektronix!tekgen!tekred!games-request Sat Dec 5 14:49:00 PST 1987 Article 129 of comp.sources.games: Path: td2cad!mipos3!omepd!littlei!reed!tektronix!tekgen!tekred!games-request From: games-request@tekred.TEK.COM Newsgroups: comp.sources.games Subject: v03i018: NetHack2.2 - display oriented dungeons and dragons, Part18/20 Message-ID: <1905@tekred.TEK.COM> Date: 3 Dec 87 16:57:42 GMT Sender: billr@tekred.TEK.COM Lines: 2181 Approved: billr@tekred.TEK.COM Submitted by: mike@genat.UUCP (Mike Stephenson) Comp.sources.games: Volume 3, Issue 18 Archive-name: nethack2.2/Part18 #! /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 Makefile.pc <<'END_OF_Makefile.pc' X# SCCS Id: @(#)Makefile.pc 2.2 87/11/11 X# Makefile for NetHack (PC) version 1.0 written using X# Microsoft(tm) "C" v3.0 or better. X# X# Large memory model, register bug, remove stack probes: XWIZARD= XV = 35 XCFLAGS = -A$(MODEL) -DREGBUG -DLINT_ARGS -DVER=$V $(WIZARD) -Ot -Gs -Gt100 X XLIBS = XLFLAGS = XMODEL = L XSETARGV = $(LIB)\$(MODEL)SETARGV X.SUFFIXES: .exe .obj .c X.c.obj:; cl $(CFLAGS) -c $*.c X.c.exe:; X cl $(CFLAGS) -c $*.c X link $*.obj $(SETARGV), $@,, $(LIBS) $(LFLAGS); X X# The game name XGAME = hack.exe X X# The game directory XGAMEDIR = \h X X# All object modules XOBJS = decl.obj apply.obj bones.obj cmd.obj do.obj dothrow.obj\ X do_name.obj do_wear.obj dog.obj dogmove.obj eat.obj end.obj \ X engrave.obj fight.obj fountain.obj hack.obj invent.obj \ X lev.obj main.obj makemon.obj mhitu.obj mklev.obj \ X mkmaze.obj mkobj.obj mkshop.obj mon.obj monmove.obj\ X monst.obj o_init.obj objnam.obj options.obj \ X pager.obj polyself.obj potion.obj pray.obj pri.obj prisym.obj\ X read.obj rip.obj rumors.obj save.obj \ X search.obj shk.obj shknam.obj sit.obj spell.obj steal.obj \ X termcap.obj timeout.obj topl.obj topten.obj track.obj trap.obj \ X tty.obj unix.obj u_init.obj vault.obj wield.obj \ X wizard.obj worm.obj worn.obj write.obj zap.obj \ X version.obj rnd.obj alloc.obj msdos.obj X X# The main target - you may want to try both of these alternatives. X# X$(GAME) : $(OBJS) X# link $(OBJS), $(GAME) /NOIG /STACK:4000 /CP:1; X# link $(OBJS), $(GAME) /NOIG /STACK:0xa00 /CP:1; X X X# variable auxilary files. X# XVARAUX = data rumors X Xinstall : $(GAME) $(VARAUX) X - exepack $(GAME) $(GAMEDIR)\$(GAME) X - exemod $(GAMEDIR)\$(GAME) /max 1 X Xclean : X erase $(GAME) X Xspotless: clean X erase *.obj X erase main.c X erase tty.c X erase unix.c X Xsrcs : X copy makefile \tmp X copy *.c \tmp X copy *.h \tmp X copy \local\make\make.doc \tmp X copy \local\make\make.ini \tmp X copy \bin\make.exe \tmp X cd \tmp X time X touch *.* X arc m hack$Vs * *.* X cd $(CWD) X X X# Other dependencies X# XRUMORFILES= rumors.bas rumors.kaa rumors.mrx X Xmakedefs.exe: makedefs.c alloc.obj config.h X cl -AL makedefs.c alloc.obj X X Xrumors : config.h $(RUMORFILES) makedefs.exe X makedefs.exe -r X Xdata : config.h data.bas makedefs.exe X makedefs.exe -d X Xonames.h : config.h objects.h makedefs.exe X makedefs.exe -o X X# Below is a kluge. date.h should actually depend on any source X# module being changed. (but hack.h is close enough for most). X# Xdate.h : hack.h makedefs.exe X makedefs.exe -D X Xtrap.h : config.h makedefs.exe X makedefs.exe -t X Xmain.obj : pcmain.c hack.h X $(CC) $(CFLAGS) -Fo$@ -c pcmain.c X Xtty.obj : pctty.c hack.h msdos.h X $(CC) $(CFLAGS) -Fo$@ -c pctty.c X Xunix.obj : pcunix.c hack.h mkroom.h X $(CC) $(CFLAGS) -Fo$@ -c pcunix.c X Xdecl.obj : hack.h mkroom.h Xapply.obj : hack.h edog.h mkroom.h Xbones.obj : hack.h Xhack.obj : hack.h Xcmd.obj : hack.h func_tab.h Xdo.obj : hack.h Xdo_name.obj : hack.h Xdo_wear.obj : hack.h Xdog.obj : hack.h edog.h mkroom.h Xdogmove.obj : hack.h mfndpos.h edog.h mkroom.h Xdothrow.obj : hack.h Xeat.obj : hack.h Xend.obj : hack.h Xengrave.obj : hack.h Xfight.obj : hack.h Xfountain.obj : hack.h mkroom.h Xinvent.obj : hack.h wseg.h Xioctl.obj : config.h Xlev.obj : hack.h mkroom.h wseg.h Xmakemon.obj : hack.h Xmhitu.obj : hack.h Xmklev.obj : hack.h mkroom.h Xmkmaze.obj : hack.h mkroom.h Xmkobj.obj : hack.h Xmkshop.obj : hack.h mkroom.h eshk.h Xmon.obj : hack.h mfndpos.h Xmonmove.obj : hack.h mfndpos.h Xmonst.obj : hack.h eshk.h Xmsdos.obj : msdos.h Xo_init.obj : config.h objects.h onames.h Xobjnam.obj : hack.h Xoptions.obj : hack.h Xpager.obj : hack.h Xpolyself.obj : hack.h Xpotion.obj : hack.h Xpray.obj : hack.h Xpri.obj : hack.h Xprisym.obj : hack.h wseg.h Xread.obj : hack.h Xrip.obj : hack.h Xrumors.obj : hack.h Xsave.obj : hack.h Xsearch.obj : hack.h Xshk.obj : hack.h mfndpos.h mkroom.h eshk.h Xshknam.obj : hack.h Xsit.obj : hack.h Xspell.obj : hack.h Xsteal.obj : hack.h Xtermcap.obj : hack.h Xtimeout.obj : hack.h Xtopl.obj : hack.h Xtopten.obj : hack.h Xtrack.obj : hack.h Xtrap.obj : hack.h edog.h mkroom.h Xu_init.obj : hack.h Xvault.obj : hack.h mkroom.h Xwield.obj : hack.h Xwizard.obj : hack.h Xworm.obj : hack.h wseg.h Xworn.obj : hack.h Xwrite.obj : hack.h Xzap.obj : hack.h Xversion.obj : hack.h date.h Xextern.h: config.h spell.h obj.h X touch extern.h Xhack.h: extern.h flag.h gold.h monst.h objclass.h rm.h trap.h you.h X touch hack.h Xobjects.h: config.h objclass.h X touch objects.h Xyou.h: config.h onames.h permonst.h X touch you.h END_OF_Makefile.pc if test 4450 -ne `wc -c Makefile.tcc <<'END_OF_Makefile.tcc' X# SCCS Id: @(#)Makefile.tcc 2.2 87/11/11 X# Makefile for NetHack (PC) version 1.0 written using X# Turbo C v1.0 X# X# Unfortunately, large model is limited to a total of 64K global data X# Huge memory model, remove stack probes, optimize for space: XWIZARD= XV = 14 XCFLAGS = -m$(MODEL) -DLINT_ARGS -DVER=$(V) $(WIZARD) -N- -Z -K- -O -w-pro -w-nod X X# The game name XGAME = hack.exe X X# The game directory XGAMEDIR = . X X# The directory containing the libraries XLIBDIR = c:\c\lib X X# All object modules XOBJS = decl.obj apply.obj bones.obj cmd.obj do.obj dothrow.obj\ X do_name.obj do_wear.obj dog.obj dogmove.obj eat.obj end.obj \ X engrave.obj fight.obj fountain.obj hack.obj invent.obj \ X lev.obj main.obj makemon.obj mhitu.obj mklev.obj \ X mkmaze.obj mkobj.obj mkshop.obj mon.obj monmove.obj\ X monst.obj o_init.obj objnam.obj options.obj \ X pager.obj polyself.obj potion.obj pray.obj pri.obj prisym.obj\ X read.obj rip.obj rumors.obj save.obj \ X search.obj shk.obj shknam.obj sit.obj spell.obj steal.obj \ X termcap.obj timeout.obj topl.obj topten.obj track.obj trap.obj \ X tty.obj unix.obj u_init.obj vault.obj wield.obj \ X wizard.obj worm.obj worn.obj write.obj zap.obj \ X version.obj rnd.obj alloc.obj msdos.obj X X# The main target X# X$(GAME) : $(OBJS) X link /x:400 $(LIBDIR)\c0$(MODEL).obj @objs.lnk,$(GAME),,$(LIBDIR)\c$(MODEL).lib X X# variable auxilary files. X# XVARAUX = data rumors X Xinstall : $(GAME) $(VARAUX) X - exepack $(GAME) $(GAMEDIR)\$(GAME) X - exemod $(GAMEDIR)\$(GAME) /max 1 X Xclean : X erase $(GAME) X Xspotless: clean X erase *.obj X erase main.c X erase tty.c X erase unix.c X Xsrcs : X copy makefile \tmp X copy *.c \tmp X copy *.h \tmp X copy \local\make\make.doc \tmp X copy \local\make\make.ini \tmp X copy \bin\make.exe \tmp X cd \tmp X time X touch *.* X arc m hack$Vs * *.* X cd $(CWD) X X X# Other dependencies X# XRUMORFILES= rumors.bas rumors.kaa rumors.mrx X Xmakedefs.exe: makedefs.c alloc.obj config.h X cl -AL makedefs.c alloc.obj X X Xrumors : config.h $(RUMORFILES) makedefs.exe X makedefs.exe -r X Xdata : config.h data.bas makedefs.exe X makedefs.exe -d X Xonames.h : config.h objects.h makedefs.exe X makedefs.exe -o X X# Below is a kluge. date.h should actually depend on any source X# module being changed. (but hack.h is close enough for most). X# Xdate.h : hack.h makedefs.exe X makedefs.exe -D X Xtrap.h : config.h makedefs.exe X makedefs.exe -t X Xmain.obj : pcmain.c hack.h X $(CC) $(CFLAGS) -Fo$@ -c pcmain.c X Xtty.obj : pctty.c hack.h msdos.h X $(CC) $(CFLAGS) -Fo$@ -c pctty.c X Xunix.obj : pcunix.c hack.h mkroom.h X $(CC) $(CFLAGS) -Fo$@ -c pcunix.c X Xdecl.obj : hack.h mkroom.h Xapply.obj : hack.h edog.h mkroom.h Xbones.obj : hack.h Xhack.obj : hack.h Xcmd.obj : hack.h func_tab.h Xdo.obj : hack.h Xdo_name.obj : hack.h Xdo_wear.obj : hack.h Xdog.obj : hack.h edog.h mkroom.h Xdogmove.obj : hack.h mfndpos.h edog.h mkroom.h Xdothrow.obj : hack.h Xeat.obj : hack.h Xend.obj : hack.h Xengrave.obj : hack.h Xfight.obj : hack.h Xfountain.obj : hack.h mkroom.h Xinvent.obj : hack.h wseg.h Xioctl.obj : config.h Xlev.obj : hack.h mkroom.h wseg.h Xmakemon.obj : hack.h Xmhitu.obj : hack.h Xmklev.obj : hack.h mkroom.h Xmkmaze.obj : hack.h mkroom.h Xmkobj.obj : hack.h Xmkshop.obj : hack.h mkroom.h eshk.h Xmon.obj : hack.h mfndpos.h Xmonmove.obj : hack.h mfndpos.h Xmonst.obj : hack.h eshk.h Xmsdos.obj : msdos.h Xo_init.obj : config.h objects.h onames.h Xobjnam.obj : hack.h Xoptions.obj : hack.h Xpager.obj : hack.h Xpolyself.obj : hack.h Xpotion.obj : hack.h Xpray.obj : hack.h Xpri.obj : hack.h Xprisym.obj : hack.h wseg.h Xread.obj : hack.h Xrip.obj : hack.h X tcc -c $(CFLAGS) -d- rip.c Xrumors.obj : hack.h Xsave.obj : hack.h Xsearch.obj : hack.h Xshk.obj : hack.h mfndpos.h mkroom.h eshk.h Xshknam.obj : hack.h Xsit.obj : hack.h Xspell.obj : hack.h Xsteal.obj : hack.h Xtermcap.obj : hack.h Xtimeout.obj : hack.h Xtopl.obj : hack.h Xtopten.obj : hack.h Xtrack.obj : hack.h Xtrap.obj : hack.h edog.h mkroom.h Xu_init.obj : hack.h Xvault.obj : hack.h mkroom.h Xwield.obj : hack.h Xwizard.obj : hack.h Xworm.obj : hack.h wseg.h Xworn.obj : hack.h Xwrite.obj : hack.h Xzap.obj : hack.h Xversion.obj : hack.h date.h Xextern.h: config.h spell.h obj.h X touch extern.h Xhack.h: extern.h flag.h gold.h monst.h objclass.h rm.h trap.h you.h X touch hack.h Xobjects.h: config.h objclass.h X touch objects.h Xyou.h: config.h onames.h permonst.h X touch you.h END_OF_Makefile.tcc if test 4329 -ne `wc -c dog.c <<'END_OF_dog.c' X/* SCCS Id: @(#)dog.c 1.4 87/08/08 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* dog.c - version 1.0.3 */ X X#include "hack.h" Xextern struct monst *makemon(); X#include "edog.h" X#include "mkroom.h" X X#ifdef DOGNAME Xchar dogname[63]; X#endif /* DOGNAME */ X Xstruct permonst li_dog = X { "little dog", 'd',2,18,6,0,1,6,sizeof(struct edog) }; Xstruct permonst dog = X { "dog", 'd',4,16,5,0,1,6,sizeof(struct edog) }; Xstruct permonst la_dog = X { "large dog", 'd',6,15,4,0,2,4,sizeof(struct edog) }; X Xstruct monst * Xmakedog(){ Xregister struct monst *mtmp = makemon(&li_dog,u.ux,u.uy); X if(!mtmp) return((struct monst *) 0); /* dogs were genocided */ X#ifdef DOGNAME X if (dogname[0]) { X register struct monst *mtmp2; X mtmp->mnamelth = strlen(dogname); X mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth); X *mtmp2 = *mtmp; X strcpy(NAME(mtmp2), dogname); X replmon(mtmp, mtmp2); X mtmp = mtmp2; X } X#endif /* DOGNAME */ X initedog(mtmp); X return(mtmp); X} X Xinitedog(mtmp) register struct monst *mtmp; { X mtmp->mtame = mtmp->mpeaceful = 1; X#ifdef WALKIES X mtmp->mleashed = 0; X#endif X EDOG(mtmp)->hungrytime = 1000 + moves; X EDOG(mtmp)->eattime = 0; X EDOG(mtmp)->droptime = 0; X EDOG(mtmp)->dropdist = 10000; X EDOG(mtmp)->apport = 10; X EDOG(mtmp)->whistletime = 0; X} X X/* attach the monsters that went down (or up) together with @ */ Xstruct monst *mydogs = 0; Xstruct monst *fallen_down = 0; /* monsters that fell through a trapdoor */ X /* they will appear on the next level @ goes to, even if he goes up! */ X Xlosedogs(){ Xregister struct monst *mtmp; X while(mtmp = mydogs){ X mydogs = mtmp->nmon; X mtmp->nmon = fmon; X fmon = mtmp; X mnexto(mtmp); X } X while(mtmp = fallen_down){ X fallen_down = mtmp->nmon; X mtmp->nmon = fmon; X#ifdef WALKIES X mtmp->mleashed = 0; X#endif X fmon = mtmp; X rloc(mtmp); X } X} X Xkeepdogs(){ Xregister struct monst *mtmp; X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) X if(dist(mtmp->mx,mtmp->my) < 3 && follower(mtmp) X && !mtmp->msleep && !mtmp->mfroz) { X#ifdef DGKMOD X /* Bug "fix" for worm changing levels collapsing dungeon X */ X if (mtmp->data->mlet == 'w') { X if (canseemon(mtmp) || (Blind && Telepat)) X pline("The worm can't fit down the stairwell!"); X#ifdef WALKIES X pline("The leash slides off the slimy worm!"); X mtmp->mleashed = 0; X#endif X continue; X } X#endif X relmon(mtmp); X mtmp->nmon = mydogs; X mydogs = mtmp; X unpmon(mtmp); X keepdogs(); /* we destroyed the link, so use recursion */ X return; /* (admittedly somewhat primitive) */ X } X} X Xfall_down(mtmp) register struct monst *mtmp; { X relmon(mtmp); X mtmp->nmon = fallen_down; X fallen_down = mtmp; X#ifdef WALKIES X if (mtmp->mleashed) { X X pline("The leash comes off!"); X mtmp->mleashed = 0; X } X#endif X unpmon(mtmp); X mtmp->mtame = 0; X} X X/* return quality of food; the lower the better */ Xdogfood(obj) register struct obj *obj; { X switch(obj->olet) { X case FOOD_SYM: X return( X (obj->otyp == TRIPE_RATION) ? DOGFOOD : X (obj->otyp < CARROT) ? ACCFOOD : X (obj->otyp < CORPSE) ? MANFOOD : X (poisonous(obj) || obj->age + 50 <= moves || X obj->otyp == DEAD_COCKATRICE) X ? POISON : CADAVER X ); X default: X if(!obj->cursed) return(APPORT); X /* fall into next case */ X case BALL_SYM: X case CHAIN_SYM: X case ROCK_SYM: X return(UNDEF); X } X} X X/* return roomnumber or -1 */ Xinroom(x,y) xchar x,y; { X#ifndef QUEST X register struct mkroom *croom = &rooms[0]; X while(croom->hx >= 0){ X if(croom->hx >= x-1 && croom->lx <= x+1 && X croom->hy >= y-1 && croom->ly <= y+1) X return(croom - rooms); X croom++; X } X#endif X return(-1); /* not in room or on door */ X} X Xtamedog(mtmp, obj) Xregister struct monst *mtmp; Xregister struct obj *obj; X{ X register struct monst *mtmp2; X X /* worst case, at least he'll be peaceful. */ X mtmp->mpeaceful = 1; X if(flags.moonphase == FULL_MOON && night() && rn2(6)) X return(0); X X /* If we cannot tame him, at least he's no longer afraid. */ X mtmp->mflee = 0; X mtmp->mfleetim = 0; X if(mtmp->mtame || mtmp->mfroz || X#ifndef NOWORM X mtmp->wormno || X#endif X mtmp->isshk || mtmp->isgd || index(" @12", mtmp->data->mlet)) X return(0); /* no tame long worms? */ X if(obj) { X if(dogfood(obj) >= MANFOOD) return(0); X if(cansee(mtmp->mx,mtmp->my)){ X pline("%s devours the %s.", Monnam(mtmp), X objects[obj->otyp].oc_name); X } X obfree(obj, (struct obj *) 0); X } X mtmp2 = newmonst(sizeof(struct edog) + mtmp->mnamelth); X *mtmp2 = *mtmp; X mtmp2->mxlth = sizeof(struct edog); X if(mtmp->mnamelth) (void) strcpy(NAME(mtmp2), NAME(mtmp)); X initedog(mtmp2); X replmon(mtmp,mtmp2); X return(1); X} END_OF_dog.c if test 4557 -ne `wc -c help <<'END_OF_help' X Welcome to NetHack! ( description of version 1.0 ) X X NetHack is a Dungeons and Dragons like game where you (the adventurer) Xdescend into the depths of the dungeon in search of the Amulet of Yendor X(reputed to be hidden on the twentieth level). You are accompanied by a Xlittle dog that can help you in many ways and can be trained to do all Xsorts of things. On the way you will find useful (or useless) items, (quite Xpossibly with magic properties) and assorted monsters. You attack a monster Xby trying to move into the space a monster is in (but often it is much Xwiser to leave it alone). X X Unlike most adventure games, which give you a verbal description of Xyour location, hack gives you a visual image of the dungeon level you are on. X X Hack uses the following symbols: X A to Z and a to z: monsters. You can find out what a letter Xrepresents by saying "/ (letter)", as in "/A", which will tell you that 'A' Xis a giant ant. X - and | These form the walls of a room (or maze). X . this is the floor of a room. X # this is a corridor. X > this is the staircase to the next level. X < the staircase to the previous level. X ` A large boulder. X @ You (usually). X ^ A trap. X ) A weapon of some sort. X ( Some other useful object (key, rope, dynamite, camera, ...) X [ A suit of armor. X % A piece of food (not necessarily healthy ...). X / A wand. X = A ring. X ? A scroll. X ! A magic potion. X + A spellbook containing a spell you can learn; X (but usually a doorway). X } A pool of water X { A fountain (your dungeon may not have these). X \ An opulent throne (You may not have this either). X $ A pile or pot of gold. X XCommands: X Hack knows the following commands: X ? help: print this list. X Q Quit the game. X S Save the game. X ! Escape to a shell. X ^Z Suspend the game. X < up: go up the staircase (if you are standing on it). X > down: go down (just like up). X kjhlyubn - go one step in the direction indicated. X k: north (i.e., to the top of the screen), X j: south, h: west, l: east, y: ne, u: nw, b: se, n: sw. X KJHLYUBN - Go in that direction until you hit a wall or run X into something. X m (followed by one of kjhlyubn): move without picking up X any objects. X M (followed by one of KJHLYUBN): Move far, no pickup. X g (followed by one of kjhlyubn): move until something X interesting is found. X G (followed by one of KJHLYUBN): as previous, but forking X of corridors is not considered interesting. X i print your inventory. X I print selected parts of your inventory, like in X I* - print all gems in inventory; X IU - print all unpaid items; X IX - print all used up items that are on your shopping bill; X I$ - count your money. X s search for secret doors and traps around you. X ^ ask for the type of a trap you found earlier. X ) ask for current wielded weapon. X [ ask for current armor. X = ask for current rings. X $ count how many gold pieces you are carrying. X . rest, do nothing. X , pick up some things. X : look at what is here. X ^T teleport. X ^R redraw the screen. X ^P repeat last message X (subsequent ^P's repeat earlier messages). X / (followed by any symbol): tell what this symbol represents. X If you see fancy graphics on your screen it may ask you to X specify a location rather than taking a symbol argument. X \ tell what has been discovered. X e eat food. X w wield weapon. w- means: wield nothing, use bare hands. X q drink (quaff) a potion. X r read a scroll. X P Put on a ring. X R Remove Ring. X W Wear armor. X T Takeoff armor. X A Remove some or all armor. X X transcribe (learn) a spell. X x print a list of know spells. X z zap a wand. X Z cast a spell. X t throw an object or shoot an arrow. X p pay your shopping bill. X d drop something. d7a: drop seven items of object a. X D Drop several things. X In answer to the question "What kinds of things do you X want to drop? [!%= au]" you should give zero or more X object symbols possibly followed by 'a' and/or 'u'. X 'a' means: drop all such objects, without asking for X confirmation. X 'u' means: drop only unpaid objects (when in a shop). X a use, apply - Generic command for using a key to lock X or unlock a door, using a camera, using a rope, etc. X c call: name a certain object or class of objects. X C Call: Name an individual monster. X E Engrave: Write a message in the dust on the floor. X E- means: use fingers for writing. X O Set options. You will be asked to enter an option line. X If this is empty, the current options are reported. X Otherwise it should be a list of options separated by commas. X Possible boolean options are: oneline, time, news, tombstone, X rest_on_space, fixinvlet, beginner, male, female. X They can be negated by prefixing them with '!' or "no". X A string option is name; it supplies the answer to the question X "Who are you?"; it may have a suffix. X A compound option is endgame; it is followed by a description X of what parts of the list of topscorers should be printed X when the game is finished. X Usually one will not want to use the 'O' command, but instead X put a HACKOPTIONS="...." line in one's environment. X v prints the version number. X V prints a longer identification of the version, including the X history of the game. X # introduces one of the "extended" commands. To get a list of X the commands you can use with "#" type "#?". The extended X commands you can use depends upon what options the game was X compiled with, along with your class and what type of monster X you most closely resemble at a given moment. X X You can put a number before a command to repeat it that many times, X as in "20s" or "40.". X X At present, some information is displayed on the bottom line. X You see on what dungeon level you are, how many hit points you have X now (and will have when fully recovered), what your armor class is X (the lower the better), your strength, experience level and the X state of your stomach. Optionally, you may or may not see other X information such as magical energy, how much gold you have, etc. X X Have Fun, and Good Hacking! X X X END_OF_help if test 5999 -ne `wc -c mkmaze.c <<'END_OF_mkmaze.c' X/* SCCS Id: @(#)mkmaze.c 2.1 87/10/18 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X X#include "hack.h" X#include "mkroom.h" /* not really used */ Xextern struct monst *makemon(); Xextern struct permonst pm_wizard; Xextern struct obj *mkobj_at(); Xstruct permonst hell_hound = X { "hell hound", 'd', 12, 14, 2, 20, 3, 6, 0 }; X Xmakemaz() X{ X int x,y; X register zx,zy; X coord mm; X boolean al = (dlevel >= 30 && !flags.made_amulet); X X for(x = 2; x < COLNO-1; x++) X for(y = 2; y < ROWNO-1; y++) X levl[x][y].typ = (x%2 && y%2) ? 0 : HWALL; X#ifndef RPH X if(al) { X#else /* make decoy wizard levels */ X if((dlevel == u.wiz_level) || X (!rn2(3) && (dlevel > u.medusa_level+1))) { X#endif X register struct monst *mtmp; X X zx = 2*(COLNO/4) - 1; X zy = 2*(ROWNO/4) - 1; X for(x = zx-2; x < zx+4; x++) for(y = zy-2; y <= zy+2; y++) { X levl[x][y].typ = X (y == zy-2 || y == zy+2 || x == zx-2 || x == zx+3) ? POOL : X (y == zy-1 || y == zy+1 || x == zx-1 || x == zx+2) ? HWALL: X ROOM; X } X#ifdef RPH X if (dlevel == u.wiz_level) { X#endif X (void) mkobj_at(AMULET_SYM, zx, zy); X flags.made_amulet = 1; X walkfrom(zx+4, zy); X if(mtmp = makemon(&hell_hound, zx, zy)) X mtmp->msleep = 1; X if(mtmp = makemon(PM_WIZARD, zx+1, zy)) { X mtmp->msleep = 1; X flags.no_of_wizards = 1; X } X#ifdef RPH X } else { X struct obj *ot; X /* make a cheap plastic imitation */ X if (ot = mkobj_at(AMULET_SYM, zx, zy)) X ot-> spe = -1; X walkfrom(zx+4,zy); X if (mtmp = makemon(&hell_hound, zx, zy)) X mtmp->msleep = 1; X mkmon_at ('&', zx+1,zy); X } X#endif X } else { X mazexy(&mm); X zx = mm.x; X zy = mm.y; X walkfrom(zx,zy); X#ifdef RPH X if (!rn2(10) || (dlevel == u.medusa_level + 1)) X#endif X (void) mksobj_at(WAN_WISHING, zx, zy); X (void) mkobj_at(ROCK_SYM, zx, zy); /* put a rock on top of it */ X } X X for(x = 2; x < COLNO-1; x++) X for(y = 2; y < ROWNO-1; y++) { X switch(levl[x][y].typ) { X case HWALL: X levl[x][y].scrsym = HWALL_SYM; X break; X case ROOM: X levl[x][y].scrsym = ROOM_SYM; X break; X } X } X for(x = rn1(8,11); x; x--) { X mazexy(&mm); X (void) mkobj_at(rn2(2) ? GEM_SYM : 0, mm.x, mm.y); X } X for(x = rn1(10,2); x; x--) { X mazexy(&mm); X (void) mkobj_at(ROCK_SYM, mm.x, mm.y); X } X mazexy(&mm); X (void) makemon(PM_MINOTAUR, mm.x, mm.y); X for(x = rn1(5,7); x; x--) { X mazexy(&mm); X (void) makemon((struct permonst *) 0, mm.x, mm.y); X } X for(x = rn1(6,7); x; x--) { X mazexy(&mm); X mkgold(0L,mm.x,mm.y); X } X for(x = rn1(6,7); x; x--) X mktrap(0,1,(struct mkroom *) 0); X mazexy(&mm); X levl[(xupstair = mm.x)][(yupstair = mm.y)].scrsym = UP_SYM; X levl[xupstair][yupstair].typ = STAIRS; X xdnstair = ydnstair = 0; X} X X#ifdef DGK X/* Make the mazewalk iterative by faking a stack. This is needed to X * ensure the mazewalk is successful in the limited stack space of X * the program. This iterative version uses the mimumum amount of stack X * that is totally safe. X */ Xwalkfrom(x,y) Xint x,y; X{ X#define CELLS (ROWNO * COLNO) / 4 /* a maze cell is 4 squares */ X char mazex[CELLS + 1], mazey[CELLS + 1]; /* char's are OK */ X int q, a, dir, pos; X int dirs[4]; X X pos = 1; X mazex[pos] = (char) x; X mazey[pos] = (char) y; X while (pos) { X x = (int) mazex[pos]; X y = (int) mazey[pos]; X levl[x][y].typ = ROOM; X q = 0; X for (a = 0; a < 4; a++) X if(okay(x, y, a)) dirs[q++]= a; X if (!q) X pos--; X else { X dir = dirs[rn2(q)]; X move(&x, &y, dir); X levl[x][y].typ = ROOM; X move(&x, &y, dir); X pos++; X if (pos > CELLS) X panic("Overflow in walkfrom"); X mazex[pos] = (char) x; X mazey[pos] = (char) y; X } X } X} X#else X Xwalkfrom(x,y) int x,y; { Xregister int q,a,dir; Xint dirs[4]; X levl[x][y].typ = ROOM; X while(1) { X q = 0; X for(a = 0; a < 4; a++) X if(okay(x,y,a)) dirs[q++]= a; X if(!q) return; X dir = dirs[rn2(q)]; X move(&x,&y,dir); X levl[x][y].typ = ROOM; X move(&x,&y,dir); X walkfrom(x,y); X } X} X#endif /* DGK /**/ X Xmove(x,y,dir) Xregister int *x, *y; Xregister int dir; X{ X switch(dir){ X case 0: --(*y); break; X case 1: (*x)++; break; X case 2: (*y)++; break; X case 3: --(*x); break; X } X} X Xokay(x,y,dir) Xint x,y; Xregister int dir; X{ X move(&x,&y,dir); X move(&x,&y,dir); X if(x<3 || y<3 || x>COLNO-3 || y>ROWNO-3 || levl[x][y].typ != 0) X return(0); X else X return(1); X} X Xmazexy(cc) Xcoord *cc; X{ X cc->x = 3 + 2*rn2(COLNO/2 - 2); X cc->y = 3 + 2*rn2(ROWNO/2 - 2); X return(0); X} END_OF_mkmaze.c if test 4414 -ne `wc -c mkobj.c <<'END_OF_mkobj.c' X/* SCCS Id: @(#)mkobj.c 2.2 87/11/29 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X X#include "hack.h" X#ifdef SPELLS Xchar mkobjstr[] = "))[[!!!!????+%%%%/=**))[[!!!!????+%%%%/=**(%"; X#else Xchar mkobjstr[] = "))[[!!!!????%%%%/=**))[[!!!!????%%%%/=**(%"; X#endif X Xstruct obj *mkobj(), *mksobj(); X Xstruct obj * Xmkobj_at(let,x,y) Xregister int let,x,y; X{ X register struct obj *otmp = mkobj(let); X otmp->ox = x; X otmp->oy = y; X otmp->nobj = fobj; X fobj = otmp; X return(otmp); X} X Xstruct obj * Xmksobj_at(otyp,x,y) Xregister int otyp,x,y; X{ X register struct obj *otmp = mksobj(otyp); X otmp->ox = x; X otmp->oy = y; X otmp->nobj = fobj; X return((fobj = otmp)); X} X X#ifdef RPH Xstruct obj * Xmk_named_obj_at (let, x, y, nm, lth) /* used for named corpses */ Xregister let, x, y; Xchar * nm; Xregister int lth; X{ X register struct obj *otmp; X register struct obj *obj2; X X if (lth == 0) return (mkobj_at (let,x,y)); X X otmp = mkobj(let); X obj2 = newobj(lth); X *obj2 = *otmp; X obj2->onamelth = lth; X (void) strcpy (ONAME(obj2), nm); X free( (char *)otmp); X obj2->ox = x; X obj2->oy = y; X obj2->nobj = fobj; X fobj = obj2; X return(obj2); X} X#endif X Xstruct obj * Xmkobj(let) { Xint realtype; X switch (let) { X case RANDOM_SYM: { X realtype=probtype(mkobjstr[rn2(sizeof(mkobjstr)-1)]); X break; X } X case '3': { realtype = DEAD_SOLDIER; break; } X case '9': { realtype = DEAD_GIANT; break; } X case '&': { realtype = DEAD_DEMON; break; } X default: realtype = letter(let) ? X CORPSE + ((let>'Z') ? (let-'a'+'Z'-'@'+1) : (let-'@')) X : probtype(let); X } X return(mksobj(realtype)); X} X X Xstruct obj zeroobj; X Xstruct obj * Xmksobj(otyp) Xregister otyp; X{ X register struct obj *otmp; X char let = objects[otyp].oc_olet; X X otmp = newobj(0); X *otmp = zeroobj; X otmp->age = moves; X otmp->o_id = flags.ident++; X otmp->quan = 1; X otmp->olet = let; X otmp->otyp = otyp; X otmp->dknown = index( X#ifdef KAA X#ifdef SPELLS X "/=!?*+)", X#else X "/=!?*)", X#endif X#else X#ifdef SPELLS X "/=!?*+", X#else X "/=!?*", X#endif X#endif X let) ? 0 : 1; X switch(let) { X case WEAPON_SYM: X otmp->quan = (otmp->otyp <= ROCK) ? rn1(6,6) : 1; X if(!rn2(11)) otmp->spe = rne(2); X else if(!rn2(10)) { X otmp->cursed = 1; X otmp->spe = -rne(2); X } X break; X case FOOD_SYM: X if(otmp->otyp >= CORPSE) break; X#ifdef NOT_YET_IMPLEMENTED X /* if tins are to be identified, need to adapt doname() etc */ X if(otmp->otyp == TIN) X otmp->spe = rnd(...); X#endif X /* fall into next case */ X case GEM_SYM: X otmp->quan = rn2(6) ? 1 : 2; X case TOOL_SYM: X case CHAIN_SYM: X case BALL_SYM: X case ROCK_SYM: X case POTION_SYM: X case SCROLL_SYM: X case AMULET_SYM: X break; X#ifdef SPELLS X case SPBOOK_SYM: X if(!rn2(17)) otmp->cursed = 1; X break; X#endif X case ARMOR_SYM: X if(!rn2(8)) otmp->cursed = 1; X if(!rn2(10)) otmp->spe = rne(2); X else if(!rn2(9)) { X otmp->spe = -rne(2); X otmp->cursed = 1; X } X break; X case WAND_SYM: X#ifdef HARD X if(otmp->otyp == WAN_WISHING) otmp->spe = rnd(3); else X#else X if(otmp->otyp == WAN_WISHING) otmp->spe = 3; else X#endif X otmp->spe = rn1(5, X (objects[otmp->otyp].bits & NODIR) ? 11 : 4); X break; X case RING_SYM: X if(objects[otmp->otyp].bits & SPEC) { X if(!rn2(3)) { X otmp->cursed = 1; X otmp->spe = -rne(3); X } else otmp->spe = rne(3); X } else if(otmp->otyp == RIN_TELEPORTATION || X otmp->otyp == RIN_POLYMORPH || X otmp->otyp == RIN_AGGRAVATE_MONSTER || X otmp->otyp == RIN_HUNGER || !rn2(9)) X otmp->cursed = 1; X break; X default: X panic("impossible mkobj %d, sym '%c'.", otmp->otyp, let); X } X otmp->owt = weight(otmp); X return(otmp); X} X Xletter(c) { X return(('@' <= c && c <= 'Z') || ('a' <= c && c <= 'z')); X} X Xweight(obj) Xregister struct obj *obj; X{ Xregister int wt = objects[obj->otyp].oc_weight; X return(wt ? wt*obj->quan : (obj->quan + 1)/2); X} X Xmkgold(num,x,y) Xregister long num; X{ X register struct gold *gold; X register long amount = (num ? num : 1 + (rnd(dlevel+2) * rnd(30))); X X if(gold = g_at(x,y)) X gold->amount += amount; X else { X gold = newgold(); X gold->ngold = fgold; X gold->gx = x; X gold->gy = y; X gold->amount = amount; X fgold = gold; X /* do sth with display? */ X } X} END_OF_mkobj.c if test 4114 -ne `wc -c monst.h <<'END_OF_monst.h' X/* SCCS Id: @(#)monst.h 2.1 87/09/28 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X Xstruct monst { X struct monst *nmon; X struct permonst *data; X unsigned m_id; X xchar mx,my; X xchar mdx,mdy; /* if mdispl then pos where last displayed */ X#define MTSZ 4 X coord mtrack[MTSZ]; /* monster track */ X schar mhp,mhpmax; X char mappearance; /* nonzero for undetected 'M's and for '1's */ X Bitfield(mimic,1); /* undetected mimic */ X Bitfield(mdispl,1); /* mdx,mdy valid */ X Bitfield(minvis,1); /* invisible */ X Bitfield(cham,1); /* shape-changer */ X Bitfield(mhide,1); /* hides beneath objects */ X Bitfield(mundetected,1); /* not seen in present hiding place */ X Bitfield(mspeed,2); X Bitfield(mflee,1); /* fleeing */ X Bitfield(mfleetim,7); /* timeout for mflee */ X Bitfield(msleep,1); X Bitfield(mfroz,1); X Bitfield(mconf,1); X Bitfield(mcan,1); /* has been cancelled */ X Bitfield(mtame,1); /* implies peaceful */ X Bitfield(mpeaceful,1); /* does not attack unprovoked */ X Bitfield(isshk,1); /* is shopkeeper */ X Bitfield(isgd,1); /* is guard */ X Bitfield(mcansee,1); /* cansee 1, temp.blinded 0, blind 0 */ X Bitfield(mblinded,7); /* cansee 0, temp.blinded n, blind 0 */ X Bitfield(mtrapped,1); /* trapped in a pit or bear trap */ X Bitfield(mnamelth,6); /* length of name (following mxlth) */ X#ifndef NOWORM X Bitfield(wormno,5); /* at most 31 worms on any level */ X#endif X#ifdef WALKIES X Bitfield(mleashed,1); /* monster is on a leash */ X#endif X long mtrapseen; /* bitmap of traps we've been trapped in */ X long mlstmv; /* prevent two moves at once */ X struct obj *minvent; X long mgold; X unsigned mxlth; /* length of following data */ X /* in order to prevent alignment problems mextra should X be (or follow) a long int */ X long mextra[1]; /* monster dependent info */ X}; X X#define newmonst(xl) (struct monst *) alloc((unsigned)(xl) + sizeof(struct monst)) X Xextern struct monst *fmon; Xextern struct monst *fallen_down; Xstruct monst *m_at(); X X/* these are in mspeed */ X#define MSLOW 1 /* slow monster */ X#define MFAST 2 /* speeded monster */ X X#define NAME(mtmp) (((char *) mtmp->mextra) + mtmp->mxlth) X#define MREGEN "TVi1" X#define UNDEAD "ZVW " END_OF_monst.h if test 2160 -ne `wc -c nethack.6 <<'END_OF_nethack.6' X.TH NETHACK 6 "21 September 1987" X.UC 4 X.SH NAME Xhack \- Exploring The Mazes of Menace X.SH SYNOPSIS X.B /usr/games/net[hack quest] X[ X.B \-d X.I directory X] X[ X.B \-n X] X[ X.B \-u X.I playername X] X.br X.B /usr/games/net[hack quest] X[ X.B \-d X.I directory X] X.B \-s X[ X.B \-X X] X[ X.I playernames X] X.SH DESCRIPTION X.PP X.I NetHack Xis a display oriented Dungeons & Dragons(tm) - 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 NetQuest.) X.PP XTo get started you really only need to know two commands. The command X.B ? Xwill give you a list of the available commands and the command X.B / Xwill identify the things you see on the screen. X.PP XTo win the game (as opposed to merely playing to beat other people high Xscores) you must locate the Amulet of Yendor which is somewhere below Xthe 20th level of the dungeon and get it out. Nobody has achieved this Xyet and if somebody does, he will probably go down in history as a hero Xamong heros. X.PP XWhen the game ends, either by your death, when you quit, or if you escape Xfrom the caves, X.I hack Xwill give you (a fragment of) the list of top scorers. The scoring Xis based on many aspects of your behavior but a rough estimate is Xobtained by taking the amount of gold you've found in the cave plus four Xtimes your (real) experience. Precious stones may be worth a lot of gold Xwhen brought to the exit. XThere is a 10% penalty for getting yourself killed. X.PP XThe administration of the game is kept in the directory specified with the X.B \-d Xoption, or, if no such option is given, in the directory specified by Xthe environment variable HACKDIR, or, if no such variable exists, in Xthe current directory. This same directory contains several auxiliary Xfiles such as lockfiles and the list of topscorers and a subdirectory X.I save Xwhere games are saved. XThe game administrator may however choose to install hack with a fixed Xplaying ground, usually /usr/games/lib/nethackdir. X.PP XThe X.B \-n Xoption suppresses printing of the news. X.PP XThe X.B \-u X.I playername Xoption supplies the answer to the question "Who are you?". XWhen X.I playername Xhas as suffix one of X.B \-T \-S \-K \-F \-C \-W \-N \-A \-P \-V \-E \-H Xthen this supplies the answer to the question "What kind of character ... ?". X.PP XThe X.B \-s Xoption will print out the list of your scores. It may be followed by arguments X.B \-X Xwhere X is one of the letters C, B, K, S, T, W, N, A, P, V, E, H to print the Xscores of Cave(wo)men, Barbarians, Knights, Samurai, Tourists, Wizards, XNinjas, Archaeologists, Priest(esse)s, Valkyries, Elves, or Healers. XIt may also be followed by one or more player names to print the scores of the Xplayers mentioned. X.SH AUTHORS X.PP XJay Fenlason (+ Kenny Woodland, Mike Thome and Jon Payne) wrote the Xoriginal hack, very much like rogue (but full of bugs). X.PP XAndries Brouwer continuously deformed their sources into the current Xversion - in fact an entirely different game. X.PP XMike Stephenson has continued the perversion of sources adding various Xwarped character classes and sadistic traps with the help of many strange Xpeople who reside in that place between the worlds, the Usenet Zone. X.PP XDon Kneller, Gil Neiger, Scott Turner and Ken Arromdee deserve special Xmention in this regard. X.PP XThe resulting mess is now called NetHack (or NetQuest), to denote its Xdevelopment by the Usenet. Andries Brouwer has made this request for the Xdistinction, as he may eventually release a new version of his own. X.SH FILES X.DT X.ta \w'data, rumors\ \ \ 'u Xnethack The hack program. X.br Xnetquest The quest program. X.br Xdata, rumors Data files used by hack. X.br Xhelp, hh Help data files. X.br Xrecord The list of topscorers. X.br Xsave A subdirectory containing the saved X.br X games. X.br Xbones_dd Descriptions of the ghost and X.br X belongings of a deceased adventurer. X.br Xxlock.dd Description of a dungeon level. X.br Xsafelock Lock file for xlock. X.br Xrecord_lock Lock file for record. X.SH ENVIRONMENT X.DT X.ta \w'HACKPAGER, PAGER\ \ \ 'u XUSER or LOGNAME Your login name. X.br XHOME Your home directory. X.br XSHELL Your shell. X.br XTERM The type of your terminal. X.br XHACKPAGER, PAGER Pager used instead of default pager. X.br XMAIL Mailbox file. X.br XMAILREADER Reader used instead of default X.br X (probably /bin/mail or /usr/ucb/mail). X.br XHACKDIR Playground. X.br XHACKOPTIONS String predefining several hack options X.br X (see help file). X.br X XSeveral other environment variables are used in debugging (wizard) mode, Xlike GENOCIDED, INVENT, MAGIC and SHOPTYPE. X.SH BUGS X.PP XProbably infinite. X.PP XDungeons & Dragons is a Trademark of TSR Inc. END_OF_nethack.6 if test 4669 -ne `wc -c pctty.c <<'END_OF_pctty.c' X/* SCCS Id: @(#)pctty.c 2.1 87/11/09 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* tty.c - (PC) version */ X X/* With thanks to the people who sent code for SYSV - hpscdi!jon, X * arnold@ucsf-cgl, wcs@bo95b, cbcephus!pds and others. X */ X X#include X#include "hack.h" X#include "func_tab.h" X Xstatic char erase_char, kill_char; X X/* X * Get initial state of terminal, set ospeed (for termcap routines) X * and switch off tab expansion if necessary. X * Called by startup() in termcap.c and after returning from ! or ^Z X */ Xgettty(){ X erase_char = '\b'; X kill_char = 21; /* cntl-U */ X flags.cbreak = TRUE; X#ifdef DGK X disable_ctrlP(); /* turn off ^P processing */ X#endif X} X X/* reset terminal to original state */ Xsettty(s) char *s; { X end_screen(); X if(s) printf(s); X (void) fflush(stdout); X#ifdef DGK X enable_ctrlP(); /* turn on ^P processing */ X#endif X} X X X/* fatal error */ X/*VARARGS1*/ Xerror(s,x,y) char *s; { X end_screen(); X putchar('\n'); X printf(s,x,y); X putchar('\n'); X exit(1); X} X X/* X * Read a line closed with '\n' into the array char bufp[BUFSZ]. X * (The '\n' is not stored. The string is closed with a '\0'.) X * Reading can be interrupted by an escape ('\033') - now the X * resulting string is "\033". X */ Xgetlin(bufp) Xregister char *bufp; X{ X register char *obufp = bufp; X register int c; X X flags.toplin = 2; /* nonempty, no --More-- required */ X for(;;) { X (void) fflush(stdout); X if((c = getchar()) == EOF) { X *bufp = 0; X return; X } X if(c == '\033') { X *obufp = c; X obufp[1] = 0; X return; X } X if(c == erase_char || c == '\b') { X if(bufp != obufp) { X bufp--; X putstr("\b \b"); /* putsym converts \b */ X } else bell(); X } else if(c == '\n') { X *bufp = 0; X return; X } else if(' ' <= c && c < '\177') { X /* avoid isprint() - some people don't have it X ' ' is not always a printing char */ X *bufp = c; X bufp[1] = 0; X putstr(bufp); X if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO) X bufp++; X } else if(c == kill_char || c == '\177') { /* Robert Viduya */ X /* this test last - @ might be the kill_char */ X while(bufp != obufp) { X bufp--; X putstr("\b \b"); X } X } else X bell(); X } X} X Xgetret() { X cgetret(""); X} X Xcgetret(s) Xregister char *s; X{ X putsym('\n'); X if(flags.standout) X standoutbeg(); X putstr("Hit "); X putstr(flags.cbreak ? "space" : "return"); X putstr(" to continue: "); X if(flags.standout) X standoutend(); X xwaitforspace(s); X} X Xchar morc; /* tell the outside world what char he used */ X Xxwaitforspace(s) Xregister char *s; /* chars allowed besides space or return */ X{ Xregister int c; X X morc = 0; X while((c = readchar()) != '\n') { X if(flags.cbreak) { X if(c == ' ') break; X if(s && index(s,c)) { X morc = c; X break; X } X bell(); X } X } X} X Xstatic int last_multi; X Xchar * Xparse() X{ X static char inline[COLNO]; X register foo; X X flags.move = 1; X if(!Invisible) curs_on_u(); else home(); X multi = 0; X#ifdef DGK X while((foo = readchar()) >= '0' && foo <= '9') { X multi = 10*multi+foo-'0'; X if (multi < 0 || multi > LARGEST_INT) X multi = LARGEST_INT; X if (multi > 9) { X remember_topl(); X home(); X cl_end(); X printf("Count: %d", multi); X } X last_multi = multi; X } X# ifdef REDO X if (foo == DOAGAIN || in_doagain) X multi = last_multi; X else { X savech(0); /* reset input queue */ X savech(foo); X } X# endif X X#else /* DGK */ X X while((foo = readchar()) >= '0' && foo <= '9') X multi = 10*multi+foo-'0'; X X#endif /* DGK */ X X if(multi) { X multi--; X save_cm = inline; X } X inline[0] = foo; X inline[1] = 0; X if(foo == 'g' || foo == 'G'){ X inline[1] = getchar(); X#ifdef REDO X savech(inline[1]); X#endif X inline[2] = 0; X } X if(foo == 'm' || foo == 'M'){ X inline[1] = getchar(); X#ifdef REDO X savech(inline[1]); X#endif X inline[2] = 0; X } X clrlin(); X return(inline); X} X Xchar Xreadchar() { X register int sym; X X (void) fflush(stdout); X sym = getchar(); X if(flags.toplin == 1) X flags.toplin = 2; X return((char) sym); X} X#ifdef COM_COMPL X/* Read in an extended command - doing command line completion for X * when enough character have been entered to make a unique command. X * This is just a modified getlin(). -jsb X */ Xget_ext_cmd(bufp) Xregister char *bufp; X{ X register char *obufp = bufp; X register int c; X int com_index, index; X X flags.toplin = 2; /* nonempty, no --More-- required */ X X for(;;) { X (void) fflush(stdout); X if((c = readchar()) == EOF) { X *bufp = 0; X return; X } X if(c == '\033') { X *obufp = c; X obufp[1] = 0; X return; X } X if(c == erase_char || c == '\b') { X if(bufp != obufp) { X bufp--; X putstr("\b \b"); /* putsym converts \b */ X } else bell(); X } else if(c == '\n') { X *bufp = 0; X return; X } else if(' ' <= c && c < '\177') { X /* avoid isprint() - some people don't have it X ' ' is not always a printing char */ X *bufp = c; X bufp[1] = 0; X index = 0; X com_index = -1; X X while(extcmdlist[index].ef_txt != (char *) 0){ X if(!strncmp(obufp, extcmdlist[index].ef_txt, X strlen(obufp))) X if(com_index == -1) /* No matches yet*/ X com_index = index; X else /* More than 1 match */ X com_index = -2; X index++; X } X if(com_index >= 0){ X strcpy(obufp, X extcmdlist[com_index].ef_txt); X /* finish print our string */ X putstr(bufp); X bufp = obufp; /* reset it */ X if(strlen(obufp) < BUFSIZ-1 && X strlen(obufp) < COLNO) X /* set bufp at the end of our X * string X */ X bufp += strlen(obufp); X } else { X putstr(bufp); X if(bufp-obufp < BUFSZ-1 && bufp-obufp < COLNO) X bufp++; X } X } else if(c == kill_char || c == '\177') { /* Robert Viduya */ X /* this test last - @ might be the kill_char */ X while(bufp != obufp) { X bufp--; X putstr("\b \b"); X } X } else X bell(); X } X X} X#endif COM_COMPL END_OF_pctty.c if test 5759 -ne `wc -c steal.c <<'END_OF_steal.c' X/* SCCS Id: @(#)steal.c 1.4 87/08/08 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* steal.c - version 1.0.3 */ X X#include "hack.h" X Xlong /* actually returns something that fits in an int */ Xsomegold(){ X return( (u.ugold < 100) ? u.ugold : X (u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) ); X} X Xstealgold(mtmp) register struct monst *mtmp; { Xregister struct gold *gold = g_at(u.ux, u.uy); Xregister long tmp; X if(gold && ( !u.ugold || gold->amount > u.ugold || !rn2(5))) { X mtmp->mgold += gold->amount; X freegold(gold); X if(Invisible) newsym(u.ux, u.uy); X pline("%s quickly snatches some gold from between your feet!", X Monnam(mtmp)); X if(!u.ugold || !rn2(5)) { X rloc(mtmp); X mtmp->mflee = 1; X } X } else if(u.ugold) { X u.ugold -= (tmp = somegold()); X pline("Your purse feels lighter."); X mtmp->mgold += tmp; X rloc(mtmp); X mtmp->mflee = 1; X flags.botl = 1; X } X} X X/* steal armor after he finishes taking it off */ Xunsigned stealoid; /* object to be stolen */ Xunsigned stealmid; /* monster doing the stealing */ Xstealarm(){ X register struct monst *mtmp; X register struct obj *otmp; X X for(otmp = invent; otmp; otmp = otmp->nobj) X if(otmp->o_id == stealoid) { X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) X if(mtmp->m_id == stealmid) { X if(dist(mtmp->mx,mtmp->my) < 3) { X freeinv(otmp); X pline("%s steals %s!", Monnam(mtmp), doname(otmp)); X mpickobj(mtmp,otmp); X mtmp->mflee = 1; X rloc(mtmp); X } X break; X } X break; X } X stealoid = 0; X} X X/* returns 1 when something was stolen */ X/* (or at least, when N should flee now) */ X/* avoid stealing the object stealoid */ Xsteal(mtmp) Xstruct monst *mtmp; X{ X register struct obj *otmp; X register tmp; X register named = 0; X X if(!invent){ X if(Blind) X pline("Somebody tries to rob you, but finds nothing to steal."); X else X pline("%s tries to rob you, but she finds nothing to steal!", X Monnam(mtmp)); X return(1); /* let her flee */ X } X tmp = 0; X for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2) X tmp += ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1); X tmp = rn2(tmp); X for(otmp = invent; otmp; otmp = otmp->nobj) if(otmp != uarm2) X if((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING)) ? 5 : 1)) X < 0) break; X if(!otmp) { X impossible("Steal fails!"); X return(0); X } X if(otmp->o_id == stealoid) X return(0); X if((otmp->owornmask & (W_ARMOR | W_RING))){ X switch(otmp->olet) { X case RING_SYM: X ringoff(otmp); X break; X case ARMOR_SYM: X if(multi < 0 || otmp == uarms){ X setworn((struct obj *) 0, otmp->owornmask & W_ARMOR); X break; X } X { int curssv = otmp->cursed; X otmp->cursed = 0; X stop_occupation(); X if(flags.female) X pline("%s charms you. You gladly hand over your humble garments.", X Monnam(mtmp)); X else X pline("%s seduces you and %s off your %s.", X Amonnam(mtmp, Blind ? "gentle" : "beautiful"), X otmp->cursed ? "helps you to take" X : "you start taking", X (otmp == uarmg) ? "gloves" : X (otmp == uarmh) ? "helmet" : "armor"); X named++; X (void) armoroff(otmp); X otmp->cursed = curssv; X if(multi < 0){ X extern char *nomovemsg; X extern int (*afternmv)(); X /* X multi = 0; X nomovemsg = 0; X afternmv = 0; X */ X stealoid = otmp->o_id; X stealmid = mtmp->m_id; X afternmv = stealarm; X return(0); X } X break; X } X default: X impossible("Tried to steal a strange worn thing."); X } X } X else if(otmp == uwep) setuwep((struct obj *) 0); X X if(Punished && otmp == uball){ X Punished = 0; X freeobj(uchain); X free((char *) uchain); X uchain = (struct obj *) 0; X uball->spe = 0; X uball = (struct obj *) 0; /* superfluous */ X } X freeinv(otmp); X pline("%s stole %s.", named ? "She" : Monnam(mtmp), doname(otmp)); X mpickobj(mtmp,otmp); X return((multi < 0) ? 0 : 1); X} X Xmpickobj(mtmp,otmp) Xregister struct monst *mtmp; Xregister struct obj *otmp; X{ X otmp->nobj = mtmp->minvent; X mtmp->minvent = otmp; X} X Xstealamulet(mtmp) Xregister struct monst *mtmp; X{ X register struct obj *otmp; X X for(otmp = invent; otmp; otmp = otmp->nobj) { X if(otmp->olet == AMULET_SYM) { X /* might be an imitation one */ X if(otmp == uwep) setuwep((struct obj *) 0); X freeinv(otmp); X mpickobj(mtmp,otmp); X pline("%s stole %s!", Monnam(mtmp), doname(otmp)); X return(1); X } X } X return(0); X} X X/* release the objects the killed animal has stolen */ Xrelobj(mtmp,show) Xregister struct monst *mtmp; Xregister show; X{ X register struct obj *otmp, *otmp2; X X for(otmp = mtmp->minvent; otmp; otmp = otmp2){ X otmp->ox = mtmp->mx; X otmp->oy = mtmp->my; X otmp2 = otmp->nobj; X otmp->nobj = fobj; X fobj = otmp; X stackobj(fobj); X if(show & cansee(mtmp->mx,mtmp->my)) X atl(otmp->ox,otmp->oy,Hallucination?rndobjsym() : otmp->olet); X } X mtmp->minvent = (struct obj *) 0; X if(mtmp->mgold || mtmp->data->mlet == 'L') { X register long tmp; X X tmp = (mtmp->mgold > 10000) ? 10000 : mtmp->mgold; X mkgold((long)(tmp + d(dlevel,30)), mtmp->mx, mtmp->my); X if(show & cansee(mtmp->mx,mtmp->my)) X atl(mtmp->mx,mtmp->my, Hallucination ? rndobjsym() : GOLD_SYM); X } X} END_OF_steal.c if test 5084 -ne `wc -c worm.c <<'END_OF_worm.c' X/* SCCS Id: @(#)worm.c 1.4 87/08/08 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* worm.c - version 1.0.2 */ X X#include "hack.h" X#ifndef NOWORM X#include "wseg.h" X Xstruct wseg *wsegs[32]; /* linked list, tail first */ Xstruct wseg *wheads[32]; Xlong wgrowtime[32]; X Xgetwn(mtmp) struct monst *mtmp; { Xregister tmp; X for(tmp=1; tmp<32; tmp++) if(!wsegs[tmp]) { X mtmp->wormno = tmp; X return(1); X } X return(0); /* level infested with worms */ X} X X/* called to initialize a worm unless cut in half */ Xinitworm(mtmp) struct monst *mtmp; { Xregister struct wseg *wtmp; Xregister tmp = mtmp->wormno; X if(!tmp) return; X wheads[tmp] = wsegs[tmp] = wtmp = newseg(); X wgrowtime[tmp] = 0; X wtmp->wx = mtmp->mx; X wtmp->wy = mtmp->my; X/* wtmp->wdispl = 0; */ X wtmp->nseg = 0; X} X Xworm_move(mtmp) struct monst *mtmp; { Xregister struct wseg *wtmp, *whd; Xregister tmp = mtmp->wormno; X wtmp = newseg(); X wtmp->wx = mtmp->mx; X wtmp->wy = mtmp->my; X wtmp->nseg = 0; X/* wtmp->wdispl = 0; */ X (whd = wheads[tmp])->nseg = wtmp; X wheads[tmp] = wtmp; X if(cansee(whd->wx,whd->wy)){ X unpmon(mtmp); X atl(whd->wx, whd->wy, '~'); X whd->wdispl = 1; X } else whd->wdispl = 0; X if(wgrowtime[tmp] <= moves) { X if(!wgrowtime[tmp]) wgrowtime[tmp] = moves + rnd(5); X else wgrowtime[tmp] += 2+rnd(15); X mtmp->mhpmax += 3; X mtmp->mhp += 3; X return; X } X whd = wsegs[tmp]; X wsegs[tmp] = whd->nseg; X remseg(whd); X} X Xworm_nomove(mtmp) register struct monst *mtmp; { Xregister tmp; Xregister struct wseg *wtmp; X tmp = mtmp->wormno; X wtmp = wsegs[tmp]; X if(wtmp == wheads[tmp]) return; X if(wtmp == 0 || wtmp->nseg == 0) panic("worm_nomove?"); X wsegs[tmp] = wtmp->nseg; X remseg(wtmp); X mtmp->mhp -= 3; /* mhpmax not changed ! */ X} X Xwormdead(mtmp) register struct monst *mtmp; { Xregister tmp = mtmp->wormno; Xregister struct wseg *wtmp, *wtmp2; X if(!tmp) return; X mtmp->wormno = 0; X for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp2){ X wtmp2 = wtmp->nseg; X remseg(wtmp); X } X wsegs[tmp] = 0; X} X Xwormhit(mtmp) register struct monst *mtmp; { Xregister tmp = mtmp->wormno; Xregister struct wseg *wtmp; X if(!tmp) return; /* worm without tail */ X for(wtmp = wsegs[tmp]; wtmp; wtmp = wtmp->nseg) X (void) hitu(mtmp,1); X} X Xwormsee(tmp) register unsigned tmp; { Xregister struct wseg *wtmp = wsegs[tmp]; X if(!wtmp) panic("wormsee: wtmp==0"); X for(; wtmp->nseg; wtmp = wtmp->nseg) X if(!cansee(wtmp->wx,wtmp->wy) && wtmp->wdispl){ X newsym(wtmp->wx, wtmp->wy); X wtmp->wdispl = 0; X } X} X Xpwseg(wtmp) register struct wseg *wtmp; { X if(!wtmp->wdispl){ X atl(wtmp->wx, wtmp->wy, '~'); X wtmp->wdispl = 1; X } X} X Xcutworm(mtmp,x,y,weptyp) Xregister struct monst *mtmp; Xregister xchar x,y; Xregister uchar weptyp; /* uwep->otyp or 0 */ X{ X register struct wseg *wtmp, *wtmp2; X register struct monst *mtmp2; X register tmp,tmp2; X if(mtmp->mx == x && mtmp->my == y) return; /* hit headon */ X X /* cutting goes best with axe or sword */ X tmp = rnd(20); X if(weptyp == LONG_SWORD || weptyp == TWO_HANDED_SWORD || X weptyp == SCIMITAR || weptyp == SHORT_SWORD || X weptyp == BROAD_SWORD || weptyp == AXE || weptyp == KATANA) X tmp += 5; X if(tmp < 12) return; X X /* if tail then worm just loses a tail segment */ X tmp = mtmp->wormno; X wtmp = wsegs[tmp]; X if(wtmp->wx == x && wtmp->wy == y){ X wsegs[tmp] = wtmp->nseg; X remseg(wtmp); X return; X } X X /* cut the worm in two halves */ X mtmp2 = newmonst(0); X *mtmp2 = *mtmp; X mtmp2->mxlth = mtmp2->mnamelth = 0; X X /* sometimes the tail end dies */ X if(rn2(3) || !getwn(mtmp2)){ X monfree(mtmp2); X tmp2 = 0; X } else { X tmp2 = mtmp2->wormno; X wsegs[tmp2] = wsegs[tmp]; X wgrowtime[tmp2] = 0; X } X do { X if(wtmp->nseg->wx == x && wtmp->nseg->wy == y){ X if(tmp2) wheads[tmp2] = wtmp; X wsegs[tmp] = wtmp->nseg->nseg; X remseg(wtmp->nseg); X wtmp->nseg = 0; X if(tmp2){ X pline("You cut the worm in half."); X mtmp2->mhpmax = mtmp2->mhp = X d(mtmp2->data->mlevel, 8); X mtmp2->mx = wtmp->wx; X mtmp2->my = wtmp->wy; X mtmp2->nmon = fmon; X fmon = mtmp2; X unpmon(mtmp2); /* MRS */ X pmon(mtmp2); X } else { X pline("You cut off part of the worm's tail."); X remseg(wtmp); X } X mtmp->mhp /= 2; X return; X } X wtmp2 = wtmp->nseg; X if(!tmp2) remseg(wtmp); X wtmp = wtmp2; X } while(wtmp->nseg); X panic("Cannot find worm segment"); X} X Xremseg(wtmp) register struct wseg *wtmp; { X if(wtmp->wdispl) X newsym(wtmp->wx, wtmp->wy); X free((char *) wtmp); X} X#endif /* NOWORM /**/ END_OF_worm.c if test 4392 -ne `wc -c