[comp.sources.games] v03i014: NetHack2.2 - display oriented dungeons and dragons, Part14/20

games-request@tekred.TEK.COM (12/02/87)

Submitted by: mike@genat.UUCP (Mike Stephenson)
Comp.sources.games: Volume 3, Issue 14
Archive-name: nethack2.2/Part14



#! /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 14 (of 20)."
# Contents:  README.ORIG data.base do_wear.c objclass.h pager.c
#   shknam.c
# Wrapped by billr@tekred on Tue Dec  1 16:25:08 1987
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f README.ORIG -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"README.ORIG\"
else
echo shar: Extracting \"README.ORIG\" \(10200 characters\)
sed "s/^X//" >README.ORIG <<'END_OF_README.ORIG'
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.ORIG
if test 10200 -ne `wc -c <README.ORIG`; then
    echo shar: \"README.ORIG\" 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\" \(9613 characters\)
sed "s/^X//" >data.base <<'END_OF_data.base'
X	NetHack & Quest data file - version 2.0
X@	human (or you in human guise)
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
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 venomous  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 9613 -ne `wc -c <data.base`; then
    echo shar: \"data.base\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f do_wear.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"do_wear.c\"
else
echo shar: Extracting \"do_wear.c\" \(8796 characters\)
sed "s/^X//" >do_wear.c <<'END_OF_do_wear.c'
X/*	SCCS Id: @(#)do_wear.c	2.0	87/09/15
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X#include <stdio.h>
X#include "hack.h"
Xextern char *nomovemsg;
Xextern char quitchars[];
Xextern char *Doname();
X
Xoff_msg(otmp) register struct obj *otmp; {
X	pline("You were wearing %s.", doname(otmp));
X}
X
Xdoremarm() {
X	register struct obj *otmp;
X	if(!uarm && !uarmh && !uarms && !uarmg) {
X		pline("Not wearing any armor.");
X		return(0);
X	}
X	otmp = (!uarmh && !uarms && !uarmg) ? uarm :
X		(!uarms && !uarm && !uarmg) ? uarmh :
X		(!uarmh && !uarm && !uarmg) ? uarms :
X		(!uarmh && !uarm && !uarms) ? uarmg :
X		getobj("[", "take off");
X	if(!otmp) return(0);
X	if(!(otmp->owornmask & (W_ARMOR - W_ARM2))) {
X		pline("You can't take that off.");
X		return(0);
X	}
X	if( otmp == uarmg && uwep && uwep->cursed ) {	/* myers@uwmacc */
X pline("You seem not able to take off the gloves while holding your weapon.");
X		return(0);
X	}
X	(void) armoroff(otmp);
X	return(1);
X}
X
Xdoremring() {
X	if(!uleft && !uright){
X		pline("Not wearing any ring.");
X		return(0);
X	}
X	if(!uleft)
X		return(dorr(uright));
X	if(!uright)
X		return(dorr(uleft));
X	if(uleft && uright) while(1) {
X		char answer;
X
X		pline("What ring, Right or Left? [ rl?]");
X		if(index(quitchars, (answer = readchar())))
X			return(0);
X		switch(answer) {
X		case 'l':
X		case 'L':
X			return(dorr(uleft));
X		case 'r':
X		case 'R':
X			return(dorr(uright));
X		case '?':
X			(void) doprring();
X			/* might look at morc here %% */
X		}
X	}
X	/* NOTREACHED */
X#ifdef LINT
X	return(0);
X#endif
X}
X
Xdorr(otmp) register struct obj *otmp; {
X	if(cursed(otmp)) return(0);
X	ringoff(otmp);
X	off_msg(otmp);
X	return(1);
X}
X
Xcursed(otmp) register struct obj *otmp; {
X	if(otmp->cursed){
X		pline("You can't. It appears to be cursed.");
X		return(1);
X	}
X	return(0);
X}
X
Xarmoroff(otmp) register struct obj *otmp; {
Xregister int delay = -objects[otmp->otyp].oc_delay;
X	if(cursed(otmp)) return(0);
X	setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
X	if(delay) {
X		nomul(delay);
X		switch(otmp->otyp) {
X		case HELMET:
X			nomovemsg = "You finished taking off your helmet.";
X			break;
X		case PAIR_OF_GLOVES:
X			nomovemsg = "You finished taking off your gloves";
X			break;
X		default:
X			nomovemsg = "You finished taking off your suit.";
X		}
X	} else {
X		off_msg(otmp);
X	}
X	return(1);
X}
X
Xdoweararm() {
X	register struct obj *otmp;
X	register int delay;
X	register int err = 0;
X	long mask = 0;
X
X#ifdef KAA
X	if(!index("@enozCGHIKLNOTUVWXYZ&",u.usym)) {
X		pline("Don't even bother.");
X		return(0);
X	}
X#endif
X	otmp = getobj("[", "wear");
X	if(!otmp) return(0);
X	if(otmp->owornmask & W_ARMOR) {
X		pline("You are already wearing that!");
X		return(0);
X	}
X	if(otmp->otyp == HELMET){
X		if(uarmh) {
X			pline("You are already wearing a helmet.");
X			err++;
X		} else
X			mask = W_ARMH;
X	} else if(otmp->otyp == SHIELD){
X		if(uarms) pline("You are already wearing a shield."), err++;
X		if(uwep && uwep->otyp == TWO_HANDED_SWORD)
X	pline("You cannot wear a shield and wield a two handed sword."), err++;
X		if(!err) mask = W_ARMS;
X	} else if(otmp->otyp == PAIR_OF_GLOVES) {
X		if(uarmg) {
X			pline("You are already wearing gloves.");
X			err++;
X		} else
X		if(uwep && uwep->cursed) {
X			pline("You cannot wear gloves over your weapon.");
X			err++;
X		} else
X			mask = W_ARMG;
X	} else {
X#ifdef KAA
X		if(cantweararm(u.usym)) {
X			pline("You can't wear armor!");
X			return(0);
X		}
X#endif
X		if(uarm) {
X			if(otmp->otyp != ELVEN_CLOAK || uarm2) {
X				pline("You are already wearing some armor.");
X				err++;
X			}
X		}
X		if(!err) mask = W_ARM;
X	}
X	if(welded(otmp)) {
X		if(!err++)
X			pline("%s is welded to your hand.", Doname(uwep));
X	}
X	if(err) return(0);
X	setworn(otmp, mask);
X	if(otmp == uwep)
X		setuwep((struct obj *) 0);
X	delay = -objects[otmp->otyp].oc_delay;
X	if(delay){
X		nomul(delay);
X		nomovemsg = "You finished your dressing maneuvre.";
X	}
X	otmp->known = 1;
X	return(1);
X}
X
Xdowearring() {
X	register struct obj *otmp;
X	long mask = 0;
X	long oldprop;
X
X	if(uleft && uright){
X		pline("There are no more ring-fingers to fill.");
X		return(0);
X	}
X	otmp = getobj("=", "wear");
X	if(!otmp) return(0);
X	if(otmp->owornmask & W_RING) {
X		pline("You are already wearing that!");
X		return(0);
X	}
X	if(otmp == uleft || otmp == uright) {
X		pline("You are already wearing that.");
X		return(0);
X	}
X	if(welded(otmp)) {
X		pline("%s is welded to your hand.", Doname(uwep));
X		return(0);
X	}
X	if(uleft) mask = RIGHT_RING;
X	else if(uright) mask = LEFT_RING;
X	else do {
X		char answer;
X
X		pline("What ring-finger, Right or Left? ");
X		if(index(quitchars, (answer = readchar())))
X			return(0);
X		switch(answer){
X		case 'l':
X		case 'L':
X			mask = LEFT_RING;
X			break;
X		case 'r':
X		case 'R':
X			mask = RIGHT_RING;
X			break;
X		}
X	} while(!mask);
X	setworn(otmp, mask);
X	if(otmp == uwep)
X		setuwep((struct obj *) 0);
X	oldprop = u.uprops[PROP(otmp->otyp)].p_flgs;
X	u.uprops[PROP(otmp->otyp)].p_flgs |= mask;
X	switch(otmp->otyp){
X	case RIN_LEVITATION:
X		if(!oldprop) float_up();
X		break;
X	case RIN_GAIN_STRENGTH:
X		u.ustr += otmp->spe;
X		u.ustrmax += otmp->spe;
X		if(u.ustr > 118) u.ustr = 118;
X		if(u.ustrmax > 118) u.ustrmax = 118;
X		flags.botl = 1;
X		break;
X	case RIN_INCREASE_DAMAGE:
X		u.udaminc += otmp->spe;
X		break;
X	case RIN_PROTECTION_FROM_SHAPE_CHAN:
X		rescham();
X		break;
X	}
X	prinv(otmp);
X	return(1);
X}
X
Xringoff(obj)
Xregister struct obj *obj;
X{
Xregister long mask;
X	mask = obj->owornmask & W_RING;
X	setworn((struct obj *) 0, obj->owornmask);
X	if(!(u.uprops[PROP(obj->otyp)].p_flgs & mask))
X		impossible("Strange... I didn't know you had that ring.");
X	u.uprops[PROP(obj->otyp)].p_flgs &= ~mask;
X	switch(obj->otyp) {
X	case RIN_FIRE_RESISTANCE:
X		/* Bad luck if the player is in hell... --jgm */
X		if (!Fire_resistance && dlevel >= 30) {
X			pline("The flames of Hell burn you to a crisp.");
X			killer = "stupidity in hell";
X			done("burned");
X		}
X		break;
X	case RIN_LEVITATION:
X		if(!Levitation) {	/* no longer floating */
X			float_down();
X		}
X		break;
X	case RIN_GAIN_STRENGTH:
X		u.ustr -= obj->spe;
X		u.ustrmax -= obj->spe;
X		if(u.ustr > 118) u.ustr = 118;
X		if(u.ustrmax > 118) u.ustrmax = 118;
X		flags.botl = 1;
X		break;
X	case RIN_INCREASE_DAMAGE:
X		u.udaminc -= obj->spe;
X		break;
X	case RIN_PROTECTION_FROM_SHAPE_CHAN:
X#ifdef DGKMOD
X		/* If you're no longer protected, let the chameleons
X		 * change shape again -dgk
X		 */
X		restartcham();
X#endif /* DGKMOD /**/
X		break;
X	}
X}
X
Xfind_ac(){
Xregister int uac = 10;
X#ifdef KAA
X	if (u.mtimedone) uac = mons[u.umonnum].ac;
X#endif
X	if(uarm) uac -= ARM_BONUS(uarm);
X	if(uarm2) uac -= ARM_BONUS(uarm2);
X	if(uarmh) uac -= ARM_BONUS(uarmh);
X	if(uarms) uac -= ARM_BONUS(uarms);
X	if(uarmg) uac -= ARM_BONUS(uarmg);
X	if(uleft && uleft->otyp == RIN_PROTECTION) uac -= uleft->spe;
X	if(uright && uright->otyp == RIN_PROTECTION) uac -= uright->spe;
X#ifdef PRAYERS
X	if (Protection & INTRINSIC) uac -= u.ublessed;
X#endif
X	if(uac != u.uac){
X		u.uac = uac;
X		flags.botl = 1;
X	}
X}
X
Xglibr(){
Xregister struct obj *otmp;
Xint xfl = 0;
X	if(!uarmg) if(uleft || uright) {
X		/* Note: at present also cursed rings fall off */
X		/* changed 10/30/86 by GAN */
X		pline("Your %s off your fingers.",
X#ifdef HARD
X			((uleft && !uleft->cursed) && (uright && !uright->cursed)) ? "rings slip" : "ring slips");
X#else
X			(uleft && uright) ? "rings slip" : "ring slips");
X#endif
X		xfl++;
X		if((otmp = uleft) != Null(obj)){
X			ringoff(uleft);
X			dropx(otmp);
X		}
X		if((otmp = uright) != Null(obj)){
X			ringoff(uright);
X			dropx(otmp);
X		}
X	}
X	if(((otmp = uwep) != Null(obj))
X#ifdef HARD
X	   && !otmp->cursed
X#endif
X	) {
X		/* Note: at present also cursed weapons fall */
X		/* changed 10/30/86 by GAN */
X		setuwep((struct obj *) 0);
X		dropx(otmp);
X		pline("Your weapon %sslips from your hands.",
X			xfl ? "also " : "");
X	}
X}
X
Xstruct obj *
Xsome_armor(){
Xregister struct obj *otmph = uarm;
X	if(uarmh && (!otmph || !rn2(4))) otmph = uarmh;
X	if(uarmg && (!otmph || !rn2(4))) otmph = uarmg;
X	if(uarms && (!otmph || !rn2(4))) otmph = uarms;
X	return(otmph);
X}
X
Xcorrode_armor(){
Xregister struct obj *otmph = some_armor();
X	if(otmph){
X		if(otmph->rustfree ||
X		   otmph->otyp == CRYSTAL_PLATE_MAIL ||
X		   otmph->otyp == ELVEN_CLOAK ||
X		   otmph->otyp == LEATHER_ARMOR ||
X		   otmph->otyp == STUDDED_LEATHER_ARMOR) {
X			pline("Your %s not affected!",
X				aobjnam(otmph, "are"));
X			return;
X		}
X		pline("Your %s!", aobjnam(otmph, "corrode"));
X		otmph->spe--;
X	}
X}
X
Xstatic
Xremarm(obj) register struct obj *obj; {
X	if(!obj || obj->olet != '[')
X		return(0);
X	(void) marmoroff(obj);
X	return(1);
X}
X
Xstatic
Xmarmoroff(otmp) register struct obj *otmp; {
Xregister int delay = -objects[otmp->otyp].oc_delay;
X	if(cursed(otmp)) return(0);
X	setworn((struct obj *) 0, otmp->owornmask & W_ARMOR);
X	if(delay)
X		nomul(delay);
X	off_msg(otmp);
X	nomovemsg = "You finished taking off your armor.";
X	return(1);
X}
X
Xdoddoremarm() {
X	return(ggetobj("take off",remarm,0));
X}
END_OF_do_wear.c
if test 8796 -ne `wc -c <do_wear.c`; then
    echo shar: \"do_wear.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f objclass.h -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"objclass.h\"
else
echo shar: Extracting \"objclass.h\" \(2228 characters\)
sed "s/^X//" >objclass.h <<'END_OF_objclass.h'
X/*	SCCS Id: @(#)objclass.h	2.1	87/09/23
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X/* definition of a class of objects */
X
Xstruct objclass {
X	char *oc_name;		/* actual name */
X	char *oc_descr;		/* description when name unknown */
X	char *oc_uname;		/* called by user */
X	Bitfield(oc_name_known,1);
X	Bitfield(oc_merge,1);	/* merge otherwise equal objects */
X	char oc_olet;
X	schar oc_prob;		/* probability for mkobj() */
X	schar oc_delay;		/* delay when using such an object */
X	uchar oc_weight;
X	schar oc_oc1, oc_oc2;
X	int oc_oi;
X#define	nutrition	oc_oi	/* for foods */
X#define	a_ac		oc_oc1	/* for armors - only used in ARM_BONUS */
X#define ARM_BONUS(obj)	((10 - objects[obj->otyp].a_ac) + obj->spe)
X#define	a_can		oc_oc2	/* for armors */
X#define bits		oc_oc1	/* for wands and rings */
X				/* wands */
X#define		NODIR		1
X#define		IMMEDIATE	2
X#define		RAY		4
X				/* rings */
X#define		SPEC		1	/* +n is meaningful */
X  /* Check the AD&D rules!  The FIRST is small monster damage. */
X#define	wsdam		oc_oc1	/* for weapons and PICK_AXE */
X#define	wldam		oc_oc2	/* for weapons and PICK_AXE */
X
X#define	g_val		oc_oi	/* for gems: value on exit */
X#ifdef MSDOS
X	int oc_descr_i;		/* where the description comes from */
X#endif
X#ifdef SPELLS
X#define spl_lev		oc_oi	/* for books: spell level */
X#endif
X};
X
Xextern struct objclass objects[];
X
X/* definitions of all object-symbols */
X
X#define	RANDOM_SYM	'\0'	/* used for generating random objects */
X#define	ILLOBJ_SYM	'\\'
X#define	AMULET_SYM	'"'
X#define	FOOD_SYM	'%'
X#define	WEAPON_SYM	')'
X#define	TOOL_SYM	'('
X#define	BALL_SYM	'0'
X#define	CHAIN_SYM	'_'
X#define	ROCK_SYM	'`'
X#define	ARMOR_SYM	'['
X#define	POTION_SYM	'!'
X#define	SCROLL_SYM	'?'
X#define	WAND_SYM	'/'
X#define	RING_SYM	'='
X#define	GEM_SYM		'*'
X#define	GOLD_SYM	'$'
X#ifdef SPELLS
X#define	SPBOOK_SYM	'+'	/* actually SPELL-book */
X#endif
X/* Other places with explicit knowledge of object symbols:
X * mklev.c:	"=/)%?![<>+"	(used for calculating Amulet apperances)
X * mkobj.c:	char mkobjstr[] = "))[[!!!!????%%%%/=**+";
X * apply.c:   otmp = getobj("0#%", "put in");
X * eat.c:     otmp = getobj("%", "eat");
X * invent.c:          if(index("!%?[)=*(0/+\"", sym)){
X * invent.c:    || index("%?!*+",otmp->olet))){
X */
END_OF_objclass.h
if test 2228 -ne `wc -c <objclass.h`; then
    echo shar: \"objclass.h\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f pager.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"pager.c\"
else
echo shar: Extracting \"pager.c\" \(10069 characters\)
sed "s/^X//" >pager.c <<'END_OF_pager.c'
X/*	SCCS Id: @(#)pager.c	2.1	87/11/09
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X/* This file contains the command routine dowhatis() and a pager. */
X/* Also readmail() and doshell(), and generally the things that
X   contact the outside world. */
X
X#include	<stdio.h>
X#include	<signal.h>
X#include	 "hack.h"
Xextern int CO, LI;	/* usually COLNO and ROWNO+2 */
Xextern char *CD;
Xextern char quitchars[];
Xextern char *getenv(), *getlogin();
Xint done1();
X
Xdowhatis()
X{
X	FILE *fp;
X	char bufr[BUFSZ+6];
X	register char *buf = &bufr[6], *ep, q;
X	extern char readchar();
X
X	if(!(fp = fopen(DATAFILE, "r")))
X		pline("Cannot open data file!");
X	else {
X#ifndef GRAPHICS
X		pline("Specify what? ");
X		q = readchar();
X#else
X		extern getpos();
X		coord	cc;
X		char	r;	
X
X		pline ("Specify unknown object by cursor ? [ynq] ");
X		while(!index("yYnNqQ", (q = readchar())) &&
X					      !index(quitchars, q))	bell();
X
X		if (q == 'n' || q == 'N') {
X			pline("Specify what? ");
X			r = readchar();
X		} else if (index(quitchars, q))
X			r = q;
X		else {
X			pline("Please move the cursor to the unknown object.");
X			getpos(&cc, TRUE, "the unknown object");
X			r = levl[cc.x][cc.y].scrsym;
X		}
X
X		if (r == showsyms.stone) q = defsyms.stone;
X		else if (r == showsyms.vwall) q = defsyms.vwall;
X		else if (r == showsyms.hwall) q = defsyms.hwall;
X		else if (r == showsyms.tlcorn) q = defsyms.tlcorn;
X		else if (r == showsyms.trcorn) q = defsyms.trcorn;
X		else if (r == showsyms.blcorn) q = defsyms.blcorn;
X		else if (r == showsyms.brcorn) q = defsyms.brcorn;
X		else if (r == showsyms.door) q = defsyms.door;
X		else if (r == showsyms.room) q = defsyms.room;
X		else if (r == showsyms.corr) q = defsyms.corr;
X		else if (r == showsyms.upstair) q = defsyms.upstair;
X		else if (r == showsyms.dnstair) q = defsyms.dnstair;
X		else if (r == showsyms.trap) q = defsyms.trap;
X#ifdef FOUNTAINS
X		else if (r == showsyms.pool) q = defsyms.pool;
X		else if (r == showsyms.fountain) q = defsyms.fountain;
X#endif
X#ifdef NEWCLASS
X		else if (r == showsyms.throne) q = defsyms.throne;
X#endif
X#ifdef SPIDERS
X		else if (r == showsyms.web) q = defsyms.web;
X		else
X		    q = r;
X#endif
X#endif /* GRAPHICS */
X#ifdef DGKMOD
X		if (index(quitchars, q)) {
X			(void) fclose(fp); /* sweet@scubed */
X			return(0);
X		}
X#endif
X#ifdef KJSMODS
X		if(q == '%') {
X			pline("%%       a piece of food");
X			(void) fclose(fp);
X			return(0);
X		} 
X#endif
X		if(q != '\t')
X		while(fgets(buf,BUFSZ,fp))
X		    if(*buf == q) {
X			ep = index(buf, '\n');
X			if(ep) *ep = 0;
X			/* else: bad data file */
X			/* Expand tab 'by hand' */
X			if(buf[1] == '\t'){
X				buf = bufr;
X#ifdef GRAPHICS
X				buf[0] = r;
X#else
X				buf[0] = q;
X#endif
X				(void) strncpy(buf+1, "       ", 7);
X			}
X			pline(buf);
X			if(ep[-1] == ';') {
X				pline("More info? ");
X				if(readchar() == 'y') {
X					page_more(fp,1); /* does fclose() */
X					return(0);
X				}
X			}
X			(void) fclose(fp); 	/* kopper@psuvax1 */
X			return(0);
X		    }
X		pline("I've never heard of such things.");
X		(void) fclose(fp);
X	}
X	return(0);
X}
X
X/* make the paging of a file interruptible */
Xstatic int got_intrup;
X
Xintruph(){
X	got_intrup++;
X}
X
X/* simple pager, also used from dohelp() */
Xpage_more(fp,strip)
XFILE *fp;
Xint strip;	/* nr of chars to be stripped from each line (0 or 1) */
X{
X	register char *bufr, *ep;
X#ifdef DGK
X	/* There seems to be a bug in ANSI.SYS  The first tab character
X	 * after a clear screen sequence is not expanded correctly.  Thus
X	 * expand the tabs by hand -dgk
X	 */
X	int tabstop = 8, spaces;
X	char buf[BUFSIZ], *bufp, *bufrp;
X
X	set_pager(0);
X	bufr = (char *) alloc((unsigned) CO);
X	while (fgets(buf, BUFSIZ, fp) && (!strip || *buf == '\t')){
X		bufp = buf;
X		bufrp = bufr;
X		while (*bufp && *bufp != '\n') {
X			if (*bufp == '\t') {
X				spaces = tabstop - (bufrp - bufr) % tabstop;
X				while (spaces--)
X					*bufrp++ = ' ';
X				bufp++;
X			} else
X				*bufrp++ = *bufp++;
X		}
X		*bufrp = '\0';
X#else
X	int (*prevsig)() = signal(SIGINT, intruph);
X
X	set_pager(0);
X	bufr = (char *) alloc((unsigned) CO);
X	bufr[CO-1] = 0;
X	while(fgets(bufr,CO-1,fp) && (!strip || *bufr == '\t')){
X		ep = index(bufr, '\n');
X		if(ep)
X			*ep = 0;
X#endif /* DGK /**/
X		if(page_line(bufr+strip)) {
X			set_pager(2);
X			goto ret;
X		}
X	}
X	set_pager(1);
Xret:
X	free(bufr);
X	(void) fclose(fp);
X#ifndef DGK
X	(void) signal(SIGINT, prevsig);
X	got_intrup = 0;
X#endif
X}
X
Xstatic boolean whole_screen = TRUE;
X#define	PAGMIN	12	/* minimum # of lines for page below level map */
X
Xset_whole_screen() {	/* called in termcap as soon as LI is known */
X	whole_screen = (LI-ROWNO-2 <= PAGMIN || !CD);
X}
X
X#ifdef NEWS
Xreadnews() {
X	register int ret;
X
X	whole_screen = TRUE;	/* force a docrt(), our first */
X	ret = page_file(NEWS, TRUE);
X	set_whole_screen();
X	return(ret);		/* report whether we did docrt() */
X}
X#endif
X
Xset_pager(mode)
Xregister int mode;	/* 0: open  1: wait+close  2: close */
X{
X	static boolean so;
X	if(mode == 0) {
X		if(!whole_screen) {
X			/* clear topline */
X			clrlin();
X			/* use part of screen below level map */
X			curs(1, ROWNO+4);
X		} else {
X			cls();
X		}
X		so = flags.standout;
X		flags.standout = 1;
X	} else {
X		if(mode == 1) {
X			curs(1, LI);
X			more();
X		}
X		flags.standout = so;
X		if(whole_screen)
X			docrt();
X		else {
X			curs(1, ROWNO+4);
X			cl_eos();
X		}
X	}
X}
X
Xpage_line(s)		/* returns 1 if we should quit */
Xregister char *s;
X{
X	extern char morc;
X
X	if(cury == LI-1) {
X		if(!*s)
X			return(0);	/* suppress blank lines at top */
X		putchar('\n');
X		cury++;
X		cmore("q\033");
X		if(morc) {
X			morc = 0;
X			return(1);
X		}
X		if(whole_screen)
X			cls();
X		else {
X			curs(1, ROWNO+4);
X			cl_eos();
X		}
X	}
X	xputs(s); xputc('\n');
X	cury++;
X	return(0);
X}
X
X/*
X * Flexible pager: feed it with a number of lines and it will decide
X * whether these should be fed to the pager above, or displayed in a
X * corner.
X * Call:
X *	cornline(0, title or 0)	: initialize
X *	cornline(1, text)	: add text to the chain of texts
X *	cornline(2, morcs)	: output everything and cleanup
X *	cornline(3, 0)		: cleanup
X */
X
Xcornline(mode, text)
Xint mode;
Xchar *text;
X{
X	static struct line {
X		struct line *next_line;
X		char *line_text;
X	} *texthead, *texttail;
X	static int maxlen;
X	static int linect;
X	register struct line *tl;
X
X	if(mode == 0) {
X		texthead = 0;
X		maxlen = 0;
X		linect = 0;
X		if(text) {
X			cornline(1, text);	/* title */
X			cornline(1, "");	/* blank line */
X		}
X		return;
X	}
X
X	if(mode == 1) {
X	    register int len;
X
X	    if(!text) return;	/* superfluous, just to be sure */
X	    linect++;
X	    len = strlen(text);
X	    if(len > maxlen)
X		maxlen = len;
X	    tl = (struct line *)
X		alloc((unsigned)(len + sizeof(struct line) + 1));
X	    tl->next_line = 0;
X	    tl->line_text = (char *)(tl + 1);
X	    (void) strcpy(tl->line_text, text);
X	    if(!texthead)
X		texthead = tl;
X	    else
X		texttail->next_line = tl;
X	    texttail = tl;
X	    return;
X	}
X
X	/* --- now we really do it --- */
X	if(mode == 2 && linect == 1)			    /* topline only */
X		pline(texthead->line_text);
X	else
X	if(mode == 2) {
X	    register int curline, lth;
X
X	    if(flags.toplin == 1) more();	/* ab@unido */
X	    remember_topl();
X
X	    lth = CO - maxlen - 2;		   /* Use full screen width */
X	    if (linect < LI && lth >= 10) {		     /* in a corner */
X		home ();
X		cl_end ();
X		flags.toplin = 0;
X		curline = 1;
X		for (tl = texthead; tl; tl = tl->next_line) {
X		    curs (lth, curline);
X		    if(curline > 1)
X			cl_end ();
X		    putsym(' ');
X		    xputs(tl->line_text);
X		    curline++;
X		}
X		curs (lth, curline);
X		cl_end ();
X		cmore (text);
X		home ();
X		cl_end ();
X		docorner (lth, curline-1);
X	    } else {					/* feed to pager */
X		set_pager(0);
X		for (tl = texthead; tl; tl = tl->next_line) {
X		    if (page_line (tl->line_text)) {
X			set_pager(2);
X			goto cleanup;
X		    }
X		}
X		if(text) {
X			cgetret(text);
X			set_pager(2);
X		} else
X			set_pager(1);
X	    }
X	}
X
Xcleanup:
X	while(tl = texthead) {
X		texthead = tl->next_line;
X		free((char *) tl);
X	}
X}
X
Xdohelp()
X{
X	char c;
X
X	pline ("Long or short help? ");
X	while (((c = readchar ()) != 'l') && (c != 's') && !index(quitchars,c))
X		bell ();
X	if (!index(quitchars, c))
X		(void) page_file((c == 'l') ? HELP : SHELP, FALSE);
X	return(0);
X}
X
Xpage_file(fnam, silent)	/* return: 0 - cannot open fnam; 1 - otherwise */
Xregister char *fnam;
Xboolean silent;
X{
X#ifdef DEF_PAGER			/* this implies that UNIX is defined */
X      {
X	/* use external pager; this may give security problems */
X
X	register int fd = open(fnam, 0);
X
X	if(fd < 0) {
X		if(!silent) pline("Cannot open %s.", fnam);
X		return(0);
X	}
X	if(child(1)){
X		extern char *catmore;
X
X		/* Now that child() does a setuid(getuid()) and a chdir(),
X		   we may not be able to open file fnam anymore, so make
X		   it stdin. */
X		(void) close(0);
X		if(dup(fd)) {
X			if(!silent) printf("Cannot open %s as stdin.\n", fnam);
X		} else {
X			execl(catmore, "page", (char *) 0);
X			if(!silent) printf("Cannot exec %s.\n", catmore);
X		}
X		exit(1);
X	}
X	(void) close(fd);
X      }
X#else
X      {
X	FILE *f;			/* free after Robert Viduya */
X
X	if ((f = fopen (fnam, "r")) == (FILE *) 0) {
X		if(!silent) {
X			home(); perror (fnam); flags.toplin = 1;
X			pline ("Cannot open %s.", fnam);
X		}
X		return(0);
X	}
X	page_more(f, 0);
X      }
X#endif /* DEF_PAGER /**/
X
X	return(1);
X}
X
X#ifdef UNIX
X#ifdef SHELL
Xdosh(){
Xregister char *str;
X	if(child(0)) {
X		if(str = getenv("SHELL"))
X			execl(str, str, (char *) 0);
X		else
X			execl("/bin/sh", "sh", (char *) 0);
X		pline("sh: cannot execute.");
X		exit(1);
X	}
X	return(0);
X}
X#endif /* SHELL /**/
X
Xchild(wt) {
Xregister int f = fork();
X	if(f == 0){		/* child */
X		settty((char *) 0);		/* also calls end_screen() */
X		(void) setuid(getuid());
X		(void) setgid(getgid());
X#ifdef CHDIR
X		(void) chdir(getenv("HOME"));
X#endif
X		return(1);
X	}
X	if(f == -1) {	/* cannot fork */
X		pline("Fork failed. Try again.");
X		return(0);
X	}
X	/* fork succeeded; wait for child to exit */
X	(void) signal(SIGINT,SIG_IGN);
X	(void) signal(SIGQUIT,SIG_IGN);
X	(void) wait((int *) 0);
X	gettty();
X	setftty();
X	(void) signal(SIGINT,done1);
X#ifdef WIZARD
X	if(wizard) (void) signal(SIGQUIT,SIG_DFL);
X#endif
X	if(wt) getret();
X	docrt();
X	return(0);
X}
X#endif /* UNIX /**/
END_OF_pager.c
if test 10069 -ne `wc -c <pager.c`; then
    echo shar: \"pager.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
if test -f shknam.c -a "${1}" != "-c" ; then 
  echo shar: Will not over-write existing file \"shknam.c\"
else
echo shar: Extracting \"shknam.c\" \(10228 characters\)
sed "s/^X//" >shknam.c <<'END_OF_shknam.c'
X/*	SCCS Id: @(#)shknam.c	2.1	87/09/23
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X
X/* shknam.c -- initialize a shop */
X
X#include "hack.h"
X#include "mkroom.h"
X#include "eshk.h"
X
Xextern struct monst *makemon();
X
Xstatic char *shkliquors[] = {
X    /* Ukraine */
X    "Njezjin", "Tsjernigof", "Gomel", "Ossipewsk", "Gorlowka",
X    /* N. Russia */
X    "Konosja", "Weliki Oestjoeg", "Syktywkar", "Sablja",
X    "Narodnaja", "Kyzyl",
X    /* Silezie */
X    "Walbrzych", "Swidnica", "Klodzko", "Raciborz", "Gliwice",
X    "Brzeg", "Krnov", "Hradec Kralove",
X    /* Schweiz */
X    "Leuk", "Brig", "Brienz", "Thun", "Sarnen", "Burglen", "Elm",
X    "Flims", "Vals", "Schuls", "Zum Loch",
X    ""
X};
X
Xstatic char *shkbooks[] = {
X    /* Eire */
X    "Skibbereen", "Kanturk", "Rath Luirc", "Ennistymon", "Lahinch",
X    "Kinnegad", "Lugnaquillia", "Enniscorthy", "Gweebarra",
X    "Kittamagh", "Nenagh", "Sneem", "Ballingeary", "Kilgarvan",
X    "Cahersiveen", "Glenbeigh", "Kilmihil", "Kiltamagh",
X    "Droichead Atha", "Inniscrone", "Clonegal", "Lisnaskea",
X    "Culdaff", "Dunfanaghy", "Inishbofin", "Kesh",
X    ""
X};
X
Xstatic char *shkarmors[] = {
X    /* Turquie */
X    "Demirci", "Kalecik", "Boyabai", "Yildizeli", "Gaziantep",
X    "Siirt", "Akhalataki", "Tirebolu", "Aksaray", "Ermenak",
X    "Iskenderun", "Kadirli", "Siverek", "Pervari", "Malasgirt",
X    "Bayburt", "Ayancik", "Zonguldak", "Balya", "Tefenni",
X    "Artvin", "Kars", "Makharadze", "Malazgirt", "Midyat",
X    "Birecik", "Kirikkale", "Alaca", "Polatli", "Nallihan",
X    ""
X};
X
Xstatic char *shkwands[] = {
X    /* Wales */
X    "Yr Wyddgrug", "Trallwng", "Mallwyd", "Pontarfynach",
X    "Rhaeader", "Llandrindod", "Llanfair-ym-muallt",
X    "Y-Fenni", "Measteg", "Rhydaman", "Beddgelert",
X    "Curig", "Llanrwst", "Llanerchymedd", "Caergybi",
X    /* Scotland */
X    "Nairn", "Turriff", "Inverurie", "Braemar", "Lochnagar",
X    "Kerloch", "Beinn a Ghlo", "Drumnadrochit", "Morven",
X    "Uist", "Storr", "Sgurr na Ciche", "Cannich", "Gairloch",
X    "Kyleakin", "Dunvegan",
X    ""
X};
X
Xstatic char *shkrings[] = {
X    /* Hollandse familienamen */
X    "Feyfer", "Flugi", "Gheel", "Havic", "Haynin", "Hoboken",
X    "Imbyze", "Juyn", "Kinsky", "Massis", "Matray", "Moy",
X    "Olycan", "Sadelin", "Svaving", "Tapper", "Terwen", "Wirix",
X    "Ypey",
X    /* Skandinaviske navne */
X    "Rastegaisa", "Varjag Njarga", "Kautekeino", "Abisko",
X    "Enontekis", "Rovaniemi", "Avasaksa", "Haparanda",
X    "Lulea", "Gellivare", "Oeloe", "Kajaani", "Fauske",
X    ""
X};
X
Xstatic char *shkfoods[] = {
X    /* Indonesia */
X    "Djasinga", "Tjibarusa", "Tjiwidej", "Pengalengan",
X    "Bandjar", "Parbalingga", "Bojolali", "Sarangan",
X    "Ngebel", "Djombang", "Ardjawinangun", "Berbek",
X    "Papar", "Baliga", "Tjisolok", "Siboga", "Banjoewangi",
X    "Trenggalek", "Karangkobar", "Njalindoeng", "Pasawahan",
X    "Pameunpeuk", "Patjitan", "Kediri", "Pemboeang", "Tringanoe",
X    "Makin", "Tipor", "Semai", "Berhala", "Tegal", "Samoe",
X    ""
X};
X
Xstatic char *shkweapons[] = {
X    /* Perigord */
X    "Voulgezac", "Rouffiac", "Lerignac", "Touverac", "Guizengeard",
X    "Melac", "Neuvicq", "Vanzac", "Picq", "Urignac", "Corignac",
X    "Fleac", "Lonzac", "Vergt", "Queyssac", "Liorac", "Echourgnac",
X    "Cazelon", "Eypau", "Carignan", "Monbazillac", "Jonzac",
X    "Pons", "Jumilhac", "Fenouilledes", "Laguiolet", "Saujon",
X    "Eymoutiers", "Eygurande", "Eauze", "Labouheyre",
X    ""
X};
X
Xstatic char *shkgeneral[] = {
X    /* Suriname */
X    "Hebiwerie", "Possogroenoe", "Asidonhopo", "Manlobbi",
X    "Adjama", "Pakka Pakka", "Kabalebo", "Wonotobo",
X    "Akalapi", "Sipaliwini",
X    /* Greenland */
X    "Annootok", "Upernavik", "Angmagssalik",
X    /* N. Canada */
X    "Aklavik", "Inuvik", "Tuktoyaktuk",
X    "Chicoutimi", "Ouiatchouane", "Chibougamau",
X    "Matagami", "Kipawa", "Kinojevis",
X    "Abitibi", "Maganasipi",
X    /* Iceland */
X    "Akureyri", "Kopasker", "Budereyri", "Akranes", "Bordeyri",
X    "Holmavik",
X    ""
X};
X
X/*
X * To add new shop types, all that is necessary is to edit the shtypes[] array.
X * See mkroom.h for the structure definition. Typically, you'll have to lower
X * some or all of the probability fields in old entries to free up some
X * percentage for the new type.
X *
X * The placement type field is not yet used but will be in the near future.
X *
X * The iprobs array in each entry defines the probabilities for various kinds
X * of artifacts to be present in the given shop type. You can associate with
X * each percentage either a generic artifact type (represented by one of the
X * *_SYM macros) or a specific artifact (represented by an onames.h define).
X * In the latter case, prepend it with a unary minus so the code can know
X * (by testing the sign) whether to use mkobj() or mksobj().
X */
Xstruct shclass shtypes[] = {
X	{"general store", RANDOM_SYM,
X#ifdef SPELLS
X	    47,
X#else
X	    50,
X#endif
X	    D_SHOP, {{100, RANDOM_SYM}, {0, 0}, {0, 0}}, shkgeneral},
X	{"used armor dealership", ARMOR_SYM, 14,
X	    D_SHOP, {{90, ARMOR_SYM}, {10, WEAPON_SYM}, {0, 0}}, shkarmors},
X	{"second hand bookstore", SCROLL_SYM, 10, D_SHOP,
X#ifdef SPELLS
X	    {{90, SCROLL_SYM}, {10, SPBOOK_SYM}, {0, 0}},
X#else
X	    {{100, SCROLL_SYM}, {0, 0}, {0, 0}},
X#endif
X	    shkbooks},
X	{"liquor emporium", POTION_SYM, 10, D_SHOP,
X	    {{100, POTION_SYM}, {0, 0}, {0, 0}}, shkliquors},
X	{"antique weapons outlet", WEAPON_SYM, 5, D_SHOP,
X	    {{90, WEAPON_SYM}, {10, ARMOR_SYM}, {0, 0}}, shkweapons},
X	{"delicatessen", FOOD_SYM, 5, D_SHOP,
X	    {{95, FOOD_SYM}, {5, POTION_SYM}, {0, 0}}, shkfoods},
X	{"jewelers", RING_SYM, 3, D_SHOP,
X	    {{90, RING_SYM}, {10, GEM_SYM}, {0, 0}}, shkrings},
X	{"quality apparel and accessories", WAND_SYM, 3, D_SHOP,
X	    {{90, WAND_SYM}, {5, -PAIR_OF_GLOVES}, {5, -ELVEN_CLOAK}},
X	     shkwands},
X#ifdef SPELLS
X	{"rare books", SPBOOK_SYM, 3, D_SHOP,
X	    {{90, SPBOOK_SYM}, {10, SCROLL_SYM}, {0, 0}}, shkbooks},
X#endif
X	{(char *)0, 0, 0, 0, {{0, 0}, {0, 0}, {0, 0}}, (char **)0}
X};
X
Xstatic void
Xmkshobj_at(shp, sx, sy)
X/* make an object of the appropriate type for a shop square */
Xstruct shclass *shp;
Xint sx, sy;
X{
X    register int	i, j;
X    register struct monst *mtmp;
X    int		atype;
X
X    /* select an appropriate artifact type at random */
X    for(j = rn2(100), i = 0; j -= shp->iprobs[i].iprob; i++)
X	if (j < 0)
X	    break;
X
X    /* generate the appropriate object */
X    if ((atype = shp->iprobs[i].itype) >= 0)	/* if a class was given */
X    {
X	/* the artifact may actually be a mimic */
X	if(rn2(100) < dlevel && !m_at(sx,sy) && (mtmp=makemon(PM_MIMIC,sx,sy)))
X	{
X	    mtmp->mimic = 1;
X	    mtmp->mappearance =	(atype && rn2(10) < dlevel) ? atype : ']';
X	    return;
X	}
X
X	/* it's not, go ahead and generate an article of the class */
X	(void) mkobj_at(atype, sx, sy);
X    }
X    else	/* particular object was to be generated */
X	(void) mksobj_at(-atype, sx, sy);
X}
X
Xvoid
Xfindname(nampt, nlp)
X/* extract a shopkeeper name for the given shop type */
Xchar *nampt;
Xchar *nlp[];
X{
X    register int i;
X
X    for(i = 0; i < dlevel; i++)
X	if (strlen(nlp[i]) == 0)
X	{
X	    /* Not enough names, try general name */
X	    if (nlp != shkgeneral)
X		findname(nampt, shkgeneral);
X	    else
X		(void) strcpy(nampt, "Dirk");
X	    return;
X	}
X    (void) strncpy(nampt, nlp[i], PL_NSIZ);
X    nampt[PL_NSIZ-1] = 0;
X}
X
Xstatic int
Xshkinit(shp, sroom)
X/* create a new shopkeeper in the given room */
Xstruct shclass	*shp;
Xstruct mkroom	*sroom;
X{
X    register int sh, sx, sy;
X    struct monst *shk;
X
X    /* place the shopkeeper in the given room */
X    sh = sroom->fdoor;
X    sx = doors[sh].x;
X    sy = doors[sh].y;
X
X    /* check that the shopkeeper placement is sane */
X    if(sx == sroom->lx-1) sx++; else
X	if(sx == sroom->hx+1) sx--; else
X	    if(sy == sroom->ly-1) sy++; else
X		if(sy == sroom->hy+1) sy--; else {
X#ifdef WIZARD
X		    /* Said to happen sometimes, but I've never seen it. */
X		    if(wizard) {
X			register int j = sroom->doorct;
X			extern int doorindex;
X
X			pline("Where is shopdoor?");
X			pline("Room at (%d,%d),(%d,%d).", sroom->lx, sroom->ly,
X			      sroom->hx, sroom->hy);
X			pline("doormax=%d doorct=%d fdoor=%d",
X			doorindex, sroom->doorct, sh);
X			while(j--) {
X			    pline("door [%d,%d]", doors[sh].x, doors[sh].y);
X			    sh++;
X			}
X			more();
X		    }
X#endif
X		    return(-1);
X		}
X
X    /* now initialize the shopkeeper's monster structure */
X#define	ESHK	((struct eshk *)(&(shk->mextra[0])))
X    if(!(shk = makemon(PM_SHK,sx,sy)))
X	return(-1);
X    shk->isshk = shk->mpeaceful = 1;
X    shk->msleep = 0;
X    shk->mtrapseen = ~0;	/* we know all the traps already */
X    ESHK->shoproom = sroom - rooms;
X    ESHK->shoplevel = dlevel;
X    ESHK->shd = doors[sh];
X    ESHK->shk.x = sx;
X    ESHK->shk.y = sy;
X    ESHK->robbed = 0;
X    ESHK->visitct = 0;
X    ESHK->following = 0;
X    shk->mgold = 1000 + 30*rnd(100);	/* initial capital */
X    ESHK->billct = 0;
X    findname(ESHK->shknam, shp->shknms);
X
X    return(sh);
X}
X
Xvoid
Xstock_room(shp, sroom)
X/* stock a newly-created room with artifacts */
Xstruct shclass	*shp;
Xregister struct mkroom *sroom;
X{
X    /*
X     * Someday soon we'll dispatch on the dist field of shclass to do
X     * different placements in this routine. Currently it only supports
X     * shop-style placement (all squares except a row nearest the first
X     * door get artifacts).
X     */
X    register int sx, sy, sh;
X
X    /* first, try to place a shopkeeper in the room */
X    if ((sh = shkinit(shp, sroom)) < 0)
X	return;
X
X    for(sx = sroom->lx; sx <= sroom->hx; sx++)
X	for(sy = sroom->ly; sy <= sroom->hy; sy++){
X	    if((sx == sroom->lx && doors[sh].x == sx-1) ||
X	       (sx == sroom->hx && doors[sh].x == sx+1) ||
X	       (sy == sroom->ly && doors[sh].y == sy-1) ||
X	       (sy == sroom->hy && doors[sh].y == sy+1)) continue;
X	    mkshobj_at(shp, sx, sy);
X	}
X
X    /*
X     * Special monster placements (if any) should go here: that way,
X     * monsters will sit on top of artifacts and not the other way around.
X     */
X}
X
Xsaleable(nshop, obj)			/* does "shop" stock this item type */
X	register int	nshop;
X	register struct	obj *obj;
X{
X	int i;
X
X	if(shtypes[nshop].symb == RANDOM_SYM) return(1);
X	else {
X	    for(i = 0; shtypes[nshop].iprobs[i].iprob; i++)
X		if(shtypes[nshop].iprobs[i].itype == obj->olet) return(1);
X	}
X	return(0);
X}
END_OF_shknam.c
if test 10228 -ne `wc -c <shknam.c`; then
    echo shar: \"shknam.c\" unpacked with wrong size!
fi
# end of overwriting check
fi
echo shar: End of archive 14 \(of 20\).
cp /dev/null ark14isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 20 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0