[comp.sources.games] v10i089: nethack3p9 - display oriented dungeons & dragons

billr@saab.CNA.TEK.COM (Bill Randle) (07/14/90)

Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 89
Archive-name: nethack3p9/Part44
Supersedes: NetHack3: Volume 7, Issue 56-93



#! /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 44 (of 56)."
# Contents:  src/attrib.c src/dothrow.c src/mkroom.c src/mthrowu.c
#   src/steal.c
# Wrapped by billr@saab on Wed Jul 11 17:11:59 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/attrib.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/attrib.c'\"
else
echo shar: Extracting \"'src/attrib.c'\" \(11892 characters\)
sed "s/^X//" >'src/attrib.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)attrib.c	3.0	90/2/15
X/*	Copyright 1988, 1989, 1990, M. Stephenson		  */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*  attribute modification routines. */
X
X#include "hack.h"
X
X#ifdef OVLB
X
Xconst char	*plusattr[] = {	/* part of the output on gain of attribute */
X
X	"strong", "smart", "wise", "agile", "tough", "charismatic"
X};
X
Xconst char	*minusattr[] = { /* part of the output on loss of attribute */
X
X	"weak", "stupid", "foolish", "clumsy", "vulnerable", "ugly"
X};
X
Xstruct attribs	attrmax = {	/* max values for the attributes */
X
X	118, 18, 18, 18, 18, 18
X},
X		attrmin = {	/* min values for the attributes */
X
X	3, 3, 3, 3, 3, 3
X};
X
Xconst struct innate {
X
X	schar	ulevel;
X	long	*ability;
X	const char *gainstr, *losestr;
X}	a_abil[] = { {	 1, &(Stealth), "", "" },
X		     {   1, &(Fast), "", "" },
X		     {  10, &(Searching), "perceptive", "" },
X		     {	 0, 0, 0, 0 } },
X
X	b_abil[] = { {	 1, &(HPoison_resistance), "", "" },
X		     {   7, &(Fast), "quick", "slow" },
X		     {  15, &(Stealth), "stealthy", "" },
X		     {	 0, 0, 0, 0 } },
X
X	c_abil[] = { {	 7, &(Fast), "quick", "slow" },
X		     {	15, &(Warning), "sensitive", "" },
X		     {	 0, 0, 0, 0 } },
X
X	e_abil[] = { {   1, &(Fast), "", "" },
X		     {	 1, &(HSee_invisible), "", "" },
X		     {	 1, &(Searching), "", "" },
X		     {	 1, &(HSleep_resistance), "", "" },
X		     {	 0, 0, 0, 0 } },
X
X	h_abil[] = { {	 1, &(HPoison_resistance), "", "" },
X		     {	15, &(Warning), "sensitive", "" },
X		     {	 0, 0, 0, 0 } },
X
X	k_abil[] = { {	 7, &(Fast), "quick", "slow" },
X		     {	 0, 0, 0, 0 } },
X
X	p_abil[] = { {	15, &(Warning), "sensitive", "" },
X		     {  20, &(HFire_resistance), "cool", "warmer" },
X		     {	 0, 0, 0, 0 } },
X
X	r_abil[] = { {	 1, &(Stealth), "", ""  },
X		     {  10, &(Searching), "perceptive", "" },
X		     {	 0, 0, 0, 0 } },
X
X	s_abil[] = { {	 1, &(Fast), "", "" },
X		     {  15, &(Stealth), "stealthy", "" },
X		     {	 0, 0, 0, 0 } },
X
X	t_abil[] = { {	10, &(Searching), "perceptive", "" },
X		     {	20, &(HPoison_resistance), "hardy", "" },
X		     {	 0, 0, 0, 0 } },
X
X	v_abil[] = { {	 1, &(HCold_resistance), "", "" },
X		     {	 1, &(Stealth), "", "" },
X		     {   7, &(Fast), "quick", "slow" },
X		     {	 0, 0, 0, 0 } },
X
X	w_abil[] = { {	15, &(Warning), "sensitive", "" },
X		     {  17, &(HTeleport_control), "controlled","uncontrolled" },
X		     {	 0, 0, 0, 0 } };
X
Xconst struct clattr {
X
X	struct	attribs	base, dist;
X 	schar	align, aligntyp;
X	schar	shp, hd, xlev, ndx;
X/* According to AD&D, HD for some classes (ex. Wizard) should be smaller
X * (4-sided for wizards).  But this is not AD&D, and using the AD&D
X * rule here produces an unplayable character.  This I have used a minimum
X * of an 10-sided hit die for everything.  Another AD&D change: wizards get
X * a minimum strength of 6 since without one you can't teleport or cast
X * spells. --KAA
X */
X	const struct	innate *abil;
X}	a_attr = { {	 7, 10, 10,  7,  7,  7 },  /* Archeologist */
X		   {	20, 20, 20, 10, 20, 10 },
X		    10,  1, 13, 10, 14,  2, a_abil },
X
X	b_attr = { {	16,  7,  7, 15, 16,  6 },  /* Barbarian */
X		   {	30,  6,  7, 20, 30,  7 },
X		    10, -1, 16, 12, 10,  3, b_abil },
X
X	c_attr = { {	10,  7,  7,  7,  8,  6 },  /* Caveman (fighter) */
X		   {	30,  6,  7, 20, 30,  7 },
X		     0,  1, 16, 10, 10,  3, c_abil },
X
X/*
X	e_attr = { {	13, 13, 14,  6, 14,  6 },
X */
X	e_attr = { {	13, 13, 13,  9, 13,  7 },  /* Elf (ranger) */
X		   {	30, 10, 10, 20, 20, 10 },
X		    10,  1, 15, 10, 11,  2, e_abil },
X
X	h_attr = { {	 7,  7, 13,  7, 11, 16 },  /* Healer (druid) */
X		   {	15, 20, 20, 15, 25, 10 },
X		    10,  1, 13, 10, 20,  2, h_abil },
X
X	k_attr = { {	13,  7, 14,  8, 10, 17 },  /* Knight (paladin) */
X		   {	20, 15, 15, 10, 20, 10 },
X		    10,  1, 16, 10, 10,  3, k_abil },
X
X	p_attr = { {	 7,  7, 10,  7,  7,  7 },  /* Priest (cleric) */
X		   {	15, 10, 30, 15, 20, 10 },
X		     0,  0, 14, 10, 10,  2, p_abil },
X
X	r_attr = { {	 7,  7,  7, 10,  7,  6 },  /* Rogue (thief) */
X		   {	20, 10, 10, 30, 20, 10 },
X		    10, -1, 12, 10, 11,  2, r_abil },
X
X	s_attr = { {	10,  8,  7, 10, 17,  6 },  /* Samurai (fighter/thief) */
X		   {	30, 10, 10, 30, 14, 10 },
X		    10,  1, 15, 10, 11,  2, s_abil },
X
X	t_attr = { {	 7, 10,  6,  7,  7, 10 },  /* Tourist */
X		   {	15, 10, 10, 15, 30, 20 },
X		     0,  0, 10, 10, 14,  1, t_abil },
X
X	v_attr = { {	10,  7,  7,  7, 10,  7 },  /* Valkyrie (fighter) */
X		   {	30,  6,  7, 20, 30,  7 },
X		     0, -1, 16, 10, 10,  3, v_abil },
X
X	w_attr = { {	 7, 10,  7,  7,  7,  7 },  /* Wizard (magic-user) */
X		   {	10, 30, 10, 20, 20, 10 },
X		     0,  0, 12, 10, 12,  1, w_abil },
X
X	X_attr = { {	 3,  3,  3,  3,  3,  3 },
X		   {	20, 15, 15, 15, 20, 15 },
X		     0,  0, 12, 10, 14,  1,  0 };
X
Xstatic const struct clattr NEARDATA *NDECL(clx);
Xstatic void NDECL(init_align);
X
Xvoid
Xadjattrib(ndx, incr, silent)
X
X	int	ndx, incr;
X	boolean	silent;
X{
X	if(!incr) return;
X
X	if(incr > 0) {
X	    if((AMAX(ndx) >= attrmax.a[ndx]) && (ACURR(ndx) >= AMAX(ndx))) {
X
X		if(!silent && flags.verbose)
X		    pline("You're already as %s as you can get.",
X			  plusattr[ndx]);
X		ABASE(ndx) = AMAX(ndx) = attrmax.a[ndx]; /* just in case */
X		return;
X	    }
X
X	    ABASE(ndx) += incr;
X	    if(ABASE(ndx) > AMAX(ndx)) {
X		incr = ABASE(ndx) - AMAX(ndx);
X		AMAX(ndx) += incr;
X		if(AMAX(ndx) > attrmax.a[ndx])
X		    AMAX(ndx) = attrmax.a[ndx];
X		ABASE(ndx) = AMAX(ndx);
X	    }
X	} else {
X	    if((AMAX(ndx) <= attrmin.a[ndx]) && (ABASE(ndx) == AMAX(ndx))) {
X		if(!silent && flags.verbose)
X		    pline("You're already as %s as you can get.",
X			  minusattr[ndx]);
X		ABASE(ndx) = AMAX(ndx) = attrmin.a[ndx]; /* just in case */
X		return;
X	    }
X
X	    ABASE(ndx) += incr;
X	    if(ABASE(ndx) < attrmin.a[ndx]) {
X		incr = ABASE(ndx) - attrmin.a[ndx];
X		ABASE(ndx) = attrmin.a[ndx];
X		AMAX(ndx) += incr;
X		if(AMAX(ndx) < attrmin.a[ndx])
X		    AMAX(ndx) = attrmin.a[ndx];
X	    }
X	}
X	if(!silent)
X	    You("feel %s%s!",
X		  (incr > 1) ? "very ": "",
X		  (incr > 0) ? plusattr[ndx] : minusattr[ndx]);
X	flags.botl = 1;
X	return;
X}
X
Xvoid
Xgainstr(otmp, incr)
X	register struct obj *otmp;
X	register int incr;
X{
X	int num = 1;
X
X	if(incr) num = incr;
X	else {
X	    if(ABASE(A_STR) < 18) num = (rn2(4) ? 1 : rnd(6) );
X	    else if (ABASE(A_STR) < 103) num = rnd(10);
X	}
X	adjattrib(A_STR, (otmp && otmp->cursed) ? -num : num, TRUE);
X}
X
Xvoid
Xlosestr(num)	/* may kill you; cause may be poison or monster like 'a' */
X	register int num;
X{
X	int ustr = ABASE(A_STR) - num;
X
X	while(ustr < 3) {
X		ustr++;
X		num--;
X		u.uhp -= 6;
X		u.uhpmax -= 6;
X	}
X	adjattrib(A_STR, -num, TRUE);
X}
X
Xvoid
Xchange_luck(n)
X	register schar n;
X{
X	u.uluck += n;
X	if (u.uluck < 0 && u.uluck < LUCKMIN)	u.uluck = LUCKMIN;
X	if (u.uluck > 0 && u.uluck > LUCKMAX)	u.uluck = LUCKMAX;
X}
X
Xint
Xstone_luck(parameter)
Xboolean parameter; /* So I can't think up of a good name.  So sue me. --KAA */
X{
X	register struct obj *otmp;
X	register int bonchance = 0;
X
X	for(otmp = invent; otmp; otmp=otmp->nobj)
X	    if(otmp->otyp == LUCKSTONE) {
X		if (otmp->cursed) bonchance -= (int)otmp->quan;
X		else if (otmp->blessed) bonchance += otmp->quan;
X		else if (parameter) bonchance += otmp->quan;
X	    }
X
X	return sgn(bonchance);
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xvoid
Xrestore_attrib() {
X
X	int	i;
X
X	for(i = 0; i < A_MAX; i++) {	/* all temporary losses/gains */
X
X	   if(ATEMP(i) && ATIME(i)) {
X		if(!(--(ATIME(i)))) { /* countdown for change */
X		    ATEMP(i) += ATEMP(i) > 0 ? -1 : 1;
X
X		    if(ATEMP(i)) /* reset timer */
X			ATIME(i) = 100 / ACURR(A_CON);
X		}
X	    }
X	}
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xstatic const struct	clattr *
Xclx()  {
X
X	register const struct	clattr	*attr;
X
X	switch	(pl_character[0]) {
X
X	    case 'A':	attr = &a_attr;
X			break;
X	    case 'B':	attr = &b_attr;
X			break;
X	    case 'C':	attr = &c_attr;
X			break;
X	    case 'E':	attr = &e_attr;
X			break;
X	    case 'H':	attr = &h_attr;
X			break;
X	    case 'K':	attr = &k_attr;
X			break;
X	    case 'P':	attr = &p_attr;
X			break;
X	    case 'R':	attr = &r_attr;
X			break;
X	    case 'S':	attr = &s_attr;
X			break;
X	    case 'T':	attr = &t_attr;
X			break;
X	    case 'V':	attr = &v_attr;
X			break;
X	    case 'W':	attr = &w_attr;
X			break;
X	    default:	/* unknown type */
X			attr = &X_attr;
X			break;
X	}
X	return(attr);
X}
X
Xstatic void
Xinit_align() {	/* called from newhp if u.ulevel is 0 */
X
X	register const struct	clattr	*attr = clx();
X
X	u.ualign = (int)attr->align;
X	u.ualigntyp = attr->aligntyp;
X}
X
Xvoid
Xinit_attr(np)
X	register int	np;
X{
X	register int	i, x, tryct;
X	register const struct	clattr	*attr = clx();
X
X	for(i = 0; i < A_MAX; i++) {
X
X	    ABASE(i) = AMAX(i) = attr->base.a[i];
X	    ATEMP(i) = ATIME(i) = 0;
X	    np -= attr->base.a[i];
X	}
X
X	tryct = 0;
X	while(np > 0 && tryct < 100) {
X
X	    x = rn2(100);
X	    for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++);
X	    if(i >= A_MAX) continue; /* impossible */
X
X	    if(ABASE(i) >= attrmax.a[i]) {
X
X		tryct++;
X		continue;
X	    }
X	    tryct = 0;
X	    ABASE(i)++;
X	    AMAX(i)++;
X	    np--;
X	}
X
X	tryct = 0;
X	while(np < 0 && tryct < 100) {		/* for redistribution */
X
X	    x = rn2(100);
X	    for(i = 0; (i < A_MAX) && ((x -= attr->dist.a[i]) > 0); i++);
X	    if(i >= A_MAX) continue; /* impossible */
X
X	    if(ABASE(i) <= attrmin.a[i]) {
X
X		tryct++;
X		continue;
X	    }
X	    tryct = 0;
X	    ABASE(i)--;
X	    AMAX(i)--;
X	    np++;
X	}
X}
X
Xvoid
Xredist_attr() {
X
X	register int i, tmp;
X
X	for(i = 0; i < A_MAX; i++) {
X	    if (i==A_INT || i==A_WIS) continue;
X		/* Polymorphing doesn't change your mind */
X	    tmp = AMAX(i);
X	    AMAX(i) += (rn2(5)-2);
X	    if (AMAX(i) > attrmax.a[i]) AMAX(i) = attrmax.a[i];
X	    if (AMAX(i) < attrmin.a[i]) AMAX(i) = attrmin.a[i];
X	    ABASE(i) = ABASE(i) * AMAX(i) / tmp;
X	    /* ABASE(i) > attrmax.a[i] is impossible */
X	    if (ABASE(i) < attrmin.a[i]) ABASE(i) = attrmin.a[i];
X	}
X}
X
Xvoid
Xadjabil(oldlevel,newlevel)
Xint oldlevel, newlevel;
X{
X	register const struct clattr	*attr = clx();
X#ifdef __GNULINT__
X	/* this is the "right" definition */
X	register const struct innate	*abil = attr->abil;
X#else
X	/* this one satisfies more compilers */
X	register struct innate	*abil = (struct innate *)attr->abil;
X#endif
X
X	if(abil) {
X	    for(; abil->ability; abil++) {
X		if(oldlevel < abil->ulevel && newlevel >= abil->ulevel) {
X			if(!(*(abil->ability) & INTRINSIC)) {
X			    *(abil->ability) |= INTRINSIC;
X			    if(strlen(abil->gainstr))
X				You("feel %s!", abil->gainstr);
X			}
X		} else if (oldlevel >= abil->ulevel && newlevel < abil->ulevel) {
X			if((*(abil->ability) & INTRINSIC)) {
X			    *(abil->ability) &= ~INTRINSIC;
X			    if(strlen(abil->losestr))
X				You("feel %s!", abil->losestr);
X			    else if(strlen(abil->gainstr))
X				You("feel less %s!", abil->gainstr);
X			}
X		}
X	    }
X	}
X}
X
Xint
Xnewhp() {
X	register const struct clattr	*attr = clx();
X	int	hp, conplus;
X
X	if(u.ulevel == 0) {
X
X		hp = attr->shp;
X		init_align();	/* initialize alignment stuff */
X		return hp;
X	} else {
X
X	    if(u.ulevel < attr->xlev)
X		hp = rnd(attr->hd);
X	    else
X		hp = attr->ndx;
X	}
X
X	switch(ACURR(A_CON)) {
X		case	3:	conplus = -2; break;
X		case	4:
X		case	5:
X		case	6:	conplus = -1; break;
X		case	15:
X		case	16:	conplus = 1; break;
X		case	17:	conplus = 2; break;
X		case	18:	conplus = 3; break;
X		default:	conplus = 0;
X	}
X	hp += conplus;
X	return((hp <= 0) ? 1 : hp);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xschar
Xacurr(x)
Xint x;
X{ 
X	register int tmp = (u.abon.a[x] + u.atemp.a[x] + u.acurr.a[x]);
X
X	if (x == A_STR) {
X		if (uarmg && uarmg->otyp == GAUNTLETS_OF_POWER) return(125);
X		else return((tmp >= 125) ? 125 : (tmp <= 3) ? 3 : tmp);
X	} 
X	else return((tmp >= 25) ? 25 : (tmp <= 3) ? 3 : tmp);
X}
X
X#endif /* OVL0 */
X#ifdef OVL2
X
X/* avoid possible problems with alignment overflow, and provide a centralized
X * location for any future alignment limits
X */
Xvoid
Xadjalign(n)
Xregister int n;
X{
X	register int newalign = u.ualign + n;
X
X	if(n < 0) {
X		if(newalign < u.ualign)
X			u.ualign = newalign;
X	} else
X		if(newalign > u.ualign)
X			u.ualign = newalign;
X}
X
X#endif /* OVL2 */
END_OF_FILE
if test 11892 -ne `wc -c <'src/attrib.c'`; then
    echo shar: \"'src/attrib.c'\" unpacked with wrong size!
fi
# end of 'src/attrib.c'
fi
if test -f 'src/dothrow.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/dothrow.c'\"
else
echo shar: Extracting \"'src/dothrow.c'\" \(11651 characters\)
sed "s/^X//" >'src/dothrow.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)dothrow.c	3.0	89/11/15
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/* Contains code for 't' (throw) */
X
X#include "hack.h"
X
Xstatic void FDECL(hitfloor, (struct obj *));
Xstatic void FDECL(gem_accept, (struct monst *, struct obj *));
Xstatic boolean NDECL(martial);
Xstatic int FDECL(throw_gold, (struct obj *));
Xstatic const char NEARDATA toss_objs[] = { '0', GOLD_SYM, '#', WEAPON_SYM, 0 };
X#ifdef WORM
Xextern boolean notonhead;
X#endif
X
Xint
Xdothrow() {
X	register struct obj *obj;
X
X	obj = getobj(toss_objs, "throw");
X	/* it is also possible to throw food */
X	/* (or jewels, or iron balls... ) */
X
X	if(!obj || !getdir(1)) {       /* ask "in what direction?" */
X		if(obj && obj->olet == GOLD_SYM) u.ugold += OGOLD(obj);
X		return(0);
X	}
X
X	if(obj->olet == GOLD_SYM) return(throw_gold(obj));
X
X	if(!canletgo(obj,"throw"))
X		return(0);
X	if(obj->otyp == BOULDER
X#ifdef POLYSELF
X					&& !throws_rocks(uasmon)
X#endif
X								) {
X		pline("It's too heavy.");
X		return(1);
X	}
X	if(!u.dx && !u.dy && !u.dz) {
X		You("cannot throw an object at yourself.");
X		return(0);
X	}
X	u_wipe_engr(2);
X
X	if(obj == uwep) {
X	    if(welded(obj)) {
X		weldmsg(obj, FALSE);
X		return(1);
X	    }
X	    if(obj->quan > 1)
X		setuwep(splitobj(obj, 1));
X	    else {
X		setuwep((struct obj *)0);
X		if (uwep) return(1); /* unwielded, died, rewielded */
X	    }
X	}
X	else if(obj->quan > 1)
X		(void) splitobj(obj, 1);
X	freeinv(obj);
X	return(throwit(obj));
X}
X
Xstatic void
Xhitfloor(obj)
Xregister struct obj *obj;
X{
X#ifdef ALTARS
X	if (IS_ALTAR(levl[u.ux][u.uy].typ)) doaltarobj(obj);
X	else
X#endif
X		pline("%s hits the floor.", Doname2(obj));
X	if (breaks(obj, TRUE)) return;
X	else if(obj->olet == POTION_SYM) {
X		pline("The flask breaks, and you smell a peculiar odor...");
X		potionbreathe(obj);
X		obfree(obj, (struct obj *)0);
X	} else
X		dropy(obj);
X}
X
Xint
Xthrowit(obj)
Xregister struct obj *obj;
X{
X	register struct monst *mon;
X	register int range;
X
X	if(u.uswallow) {
X		mon = u.ustuck;
X		bhitpos.x = mon->mx;
X		bhitpos.y = mon->my;
X	} else if(u.dz) {
X	  if(u.dz < 0) {
X	    pline("%s hits the ceiling, then falls back on top of your %s.",
X		Doname2(obj),		/* note: obj->quan == 1 */
X		body_part(HEAD));
X	    if(obj->olet == POTION_SYM)
X		potionhit(&youmonst, obj);
X	    else {
X		if(uarmh) pline("Fortunately, you are wearing a helmet!");
X		losehp(uarmh ? 1 : rnd((int)(obj->owt)), "falling object",
X			KILLED_BY_AN);
X		if (!breaks(obj, TRUE)) dropy(obj);
X	    }
X	  } else hitfloor(obj);
X	  return(1);
X
X	} else if(obj->otyp == BOOMERANG) {
X		mon = boomhit(u.dx, u.dy);
X		if(mon == &youmonst) {		/* the thing was caught */
X			(void) addinv(obj);
X			return(1);
X		}
X	} else {
X		if(shkcatch(obj))
X		    return(1);
X
X		range = (int)((ACURR(A_STR) > 18 ? 20 : ACURR(A_STR))/2 - obj->owt/4);
X		if (obj == uball) {
X			if (u.ustuck) range = 1;
X			else if (range >= 5) range = 5;
X		}
X		if (range < 1) range = 1;
X
X		if ((obj->olet == WEAPON_SYM || obj->olet == GEM_SYM) &&
X		    uwep &&
X		    objects[obj->otyp].w_propellor ==
X			-objects[uwep->otyp].w_propellor)
X				range++;
X#ifdef POLYSELF
X		if (obj->otyp == BOULDER) range = 20;
X#endif
X
X		mon = bhit(u.dx, u.dy, range, obj->olet,
X			(int (*)()) 0, (int (*)()) 0, obj);
X	}
X	if(mon) {
X		/* awake monster if sleeping */
X		wakeup(mon);
X#ifdef WORM
X		if(bhitpos.x != mon->mx || bhitpos.y != mon->my)
X			notonhead = TRUE;
X#endif
X		if(thitmonst(mon, obj)) return(1);
X	}
X	if(!u.uswallow)  {
X		char let = obj->olet;
X
X		/* the code following might become part of dropy() */
X		if (breaks(obj, TRUE)) {
X			tmp_at(-1, let);
X#ifdef TEXTCOLOR
X			tmp_at(-3, (int)objects[obj->otyp].oc_color);
X#else
X			tmp_at(-3, (int)AT_OBJ);
X#endif
X			tmp_at(bhitpos.x, bhitpos.y);
X			tmp_at(-1, -1);
X			return(1);
X		}
X		if(flooreffects(obj,bhitpos.x,bhitpos.y)) return(1);
X#ifdef WORM
X		if(obj->otyp == CRYSKNIFE)
X			obj->otyp = WORM_TOOTH;
X#endif
X		obj->nobj = fobj;
X		fobj = obj;
X		place_object(obj, bhitpos.x, bhitpos.y);
X		if(obj != uball && costly_spot(bhitpos.x, bhitpos.y) &&
X		   !(mon && mon->isshk && bhitpos.x == mon->mx &&
X		     bhitpos.y == mon->my && !(obj->unpaid)))
X			sellobj(obj);
X		stackobj(obj);
X		if(obj == uball &&
X			(bhitpos.x != u.ux || bhitpos.y != u.uy)){
X			if(u.utrap){
X				if(u.utraptype == TT_PIT)
X					pline("The ball pulls you out of the pit!");
X				else if(u.utraptype == TT_WEB)  {
X					pline("The ball pulls you out of the web!");
X					pline("The web is destroyed!");
X					deltrap(t_at(u.ux,u.uy));
X				} else {
X				register long side =
X					rn2(3) ? LEFT_SIDE : RIGHT_SIDE;
X				pline("The ball pulls you out of the bear trap.");
X				Your("%s %s is severely damaged.",
X					(side == LEFT_SIDE) ? "left" : "right",
X					body_part(LEG));
X				set_wounded_legs(side, 500+rn2(1000));
X				losehp(2, "leg damage from being pulled out of a bear trap",
X					KILLED_BY);
X				}
X				u.utrap = 0;
X			}
X			unsee();
X			u.ux = bhitpos.x - u.dx;
X			u.uy = bhitpos.y - u.dy;
X			movobj(uchain,u.ux,u.uy);
X			setsee();
X			spoteffects();
X		}
X		if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
X	}  else
X		mpickobj(u.ustuck,obj);
X	return(1);
X}
X
Xint
Xthitmonst(mon, obj)
Xregister struct monst *mon;
Xregister struct obj   *obj;
X{
X	register int	tmp; /* Base chance to hit */
X
X	/* Differences from melee weapons:
X	 *
X	 * Dex still gives a bonus, but strength does not.
X	 * Polymorphed players lacking attacks may still throw.
X	 * There's a base -2 to hit.
X	 * No bonuses for fleeing or stunned targets (they don't dodge
X	 *    melee blows as readily, but dodging arrows is hard anyway).
X	 * Not affected by traps, etc...
X	 * Certain items which don't in themselves do damage ignore tmp.
X	 */
X	tmp = -2 + Luck + mon->data->ac;
X#ifdef POLYSELF
X	if (u.umonnum >= 0) tmp += uasmon->mlevel;
X	else
X#endif
X		tmp += u.ulevel;
X	if(ACURR(A_DEX) < 4) tmp -= 3;
X	else if(ACURR(A_DEX) < 6) tmp -= 2;
X	else if(ACURR(A_DEX) < 8) tmp -= 1;
X	else if(ACURR(A_DEX) > 15) tmp += (ACURR(A_DEX) - 15);
X
X	if(mon->msleep) {
X		mon->msleep = 0;
X		tmp += 2;
X	}
X	if(!mon->mcanmove) {
X		tmp += 4;
X		if(!rn2(10)) {
X			mon->mcanmove = 1;
X			mon->mfrozen = 0;
X		}
X	}
X	if (is_orc(mon->data) && pl_character[0]=='E') tmp++;
X	if (u.uswallow && mon == u.ustuck) tmp += 1000; /* Guaranteed hit */
X
X	if(obj->olet == GEM_SYM && mon->data->mlet == S_UNICORN) {
X		if (mon->mtame) {
X			kludge("%s catches and drops the %s.",
X				Monnam(mon), xname(obj));
X			return(0);
X		} else {
X			kludge("%s catches the %s.", Monnam(mon), xname(obj));
X			gem_accept(mon, obj);
X			return(1);
X		}
X	}
X	if(obj->olet == WEAPON_SYM || obj->otyp == PICK_AXE ||
X	   obj->otyp == UNICORN_HORN || obj->olet == GEM_SYM) {
X		if(obj->otyp < DART || obj->olet == GEM_SYM) {
X		    if (!uwep ||
X			objects[obj->otyp].w_propellor !=
X			-objects[uwep->otyp].w_propellor)
X			    tmp -= 4;
X		    else    tmp += uwep->spe;
X		} else if(obj->otyp == BOOMERANG) tmp += 4;
X		tmp += obj->spe;
X		tmp += hitval(obj, mon->data);
X		if(tmp >= rnd(20)) {
X			if(hmon(mon,obj,1) == TRUE){
X			  /* mon still alive */
X#ifdef WORM
X			  cutworm(mon,bhitpos.x,bhitpos.y,obj->otyp);
X#endif
X			} else mon = 0;
X			/* projectiles thrown disappear sometimes */
X			if((obj->otyp < BOOMERANG || obj->olet == GEM_SYM)
X								&& rn2(3)) {
X				/* check bill; free */
X				obfree(obj, (struct obj *)0);
X				return(1);
X			}
X		} else miss(xname(obj), mon);
X	} else if(obj->otyp == HEAVY_IRON_BALL) {
X		if(obj != uball) tmp += 2;
X		if(tmp >= rnd(20)) {
X			if(hmon(mon,obj,1) == FALSE)
X				mon = 0;	/* he died */
X		} else miss(xname(obj), mon);
X	} else if (obj->otyp == BOULDER) {
X		tmp += 6;  /* Likely to hit! */
X		if(tmp >= rnd(20)) {
X			if(hmon(mon,obj,1) == FALSE)
X				mon = 0;	/* he died */
X		} else miss(xname(obj), mon);
X	} else if((obj->otyp == CREAM_PIE
X#ifdef POLYSELF
X			|| obj->otyp == BLINDING_VENOM
X#endif
X					) && ACURR(A_DEX) >= rnd(10)) {
X		(void) hmon(mon,obj,1); /* can't die from it */
X#ifdef POLYSELF
X	} else if(obj->otyp == ACID_VENOM && ACURR(A_DEX) >= rnd(10)) {
X		if(hmon(mon,obj,1) == FALSE)
X			mon = 0;
X#endif
X	} else if(obj->olet == POTION_SYM && ACURR(A_DEX) >= rnd(15)) {
X		potionhit(mon, obj);
X		return(1);
X	} else {
X		pline("The %s misses %s.", xname(obj),
X			cansee(bhitpos.x,bhitpos.y) ? mon_nam(mon) : "it");
X		if(obj->olet == FOOD_SYM && is_domestic(mon->data))
X			if(tamedog(mon,obj)) return(1);
X	}
X	return(0);
X}
X
Xstatic void
Xgem_accept(mon, obj)
Xregister struct monst *mon;
Xregister struct obj *obj;
X{
X	char buf[BUFSZ];
X	static const char NEARDATA nogood[] = " is not interested in your junk.";
X	static const char NEARDATA maybeluck[] = " hesitatingly accepts your gift.";
X	static const char NEARDATA addluck[] = " graciously accepts your gift.";
X
X	Strcpy(buf,Monnam(mon));
X
X	mon->mpeaceful = 1;
X	if(obj->dknown && objects[obj->otyp].oc_name_known)  {
X		if(objects[obj->otyp].g_val > 0)  {
X		    if(mon->data == &mons[
X				((u.ualigntyp== U_CHAOTIC) ? PM_BLACK_UNICORN :
X				 (u.ualigntyp == U_LAWFUL) ? PM_WHITE_UNICORN
X						  : PM_GRAY_UNICORN)]) {
X			    Strcat(buf, addluck);
X			    change_luck(5);
X		    } else {
X			    Strcat(buf, maybeluck);
X			    change_luck(rn2(7)-3);
X		    }
X		} else {
X		    Strcat(buf,nogood);
X		    goto nopick;
X		}
X	}  else  {  /* value unknown to @ */
X		change_luck(1);
X		Strcat(buf,addluck);
X	}
X	mpickobj(mon, obj);
Xnopick:
X	if(!Blind) pline(buf);
X	rloc(mon);
X}
X
X/* returns 0 if object doesn't break	*/
X/* returns 1 if object broke 		*/
Xint
Xbreaks(obj, loose)
Xregister struct obj   *obj;
Xregister boolean loose;		/* if not loose, obj is in fobj chain */
X{
X	switch(obj->otyp) {
X#ifdef MEDUSA
X		case MIRROR:
X			change_luck(-2);	/* and fall through */
X#endif
X		case EXPENSIVE_CAMERA:
X		case CRYSTAL_BALL:
X			if(!Blind)
X			    pline("%s shatters into a thousand pieces!",
X				Doname2(obj));
X			else You("hear something shatter!");
X			break;
X		case EGG:
X			pline("Splat!");
X			break;
X		case CREAM_PIE:
X			pline("What a mess!");
X			break;
X		case ACID_VENOM:
X		case BLINDING_VENOM:
X			pline("Splash!");
X			break;
X		default:
X			return 0;
X	}
X
X	if(loose) {
X		unpobj(obj);
X		obfree(obj, (struct obj *)0);
X	} else {
X		addtobill(obj, FALSE);
X		delobj(obj);
X	}
X	return(1);
X}
X
Xstatic boolean 
Xmartial() 
X{
X	return((pl_character[0] == 'S' || pl_character[0] == 'P'));
X}
X
Xstatic int
Xthrow_gold(obj)
Xstruct obj *obj;
X{
X	int range = 0, odx, ody;
X	long zorks = OGOLD(obj);
X	register struct monst *mon;
X
X	free((genericptr_t) obj);
X	if(zorks < 0) {
X		/* watch negative overflows a la drop() */
X		u.ugold += zorks;
X	pline("The LRS would be very interested to know you have that much.");
X		return(0);
X	}
X
X	if(u.uswallow) {
X		if (is_animal(u.ustuck->data))
X			pline("The gold disappears in the %s's entrails.", 
X			      mon_nam(u.ustuck));
X		else
X			pline("The gold disappears into %s.",
X			      mon_nam(u.ustuck));
X		u.ustuck->mgold += zorks;
X		return(1);
X	}
X
X	if(u.dz) {
X	  	if(u.dz < 0) {
X	    pline("The gold hits the ceiling, then falls back on top of your %s.",
X		    body_part(HEAD));
X		    /* some self damage? */
X		    if(uarmh) pline("Fortunately, you are wearing a helmet!");
X		} else pline("The gold hits the floor.");
X		bhitpos.x = u.ux; /* a msg is needed here */
X		bhitpos.y = u.uy;
X		goto skip;
X	}
X
X	range = rnd((int)ACURR(A_STR));
X	if(martial()) range = range + rnd(3);
X
X	/* see if the gold has a place to move into */
X	odx = u.ux + u.dx;
X	ody = u.uy + u.dy;
X	if(bad_kick_throw_pos(odx,ody)) {
X		bhitpos.x = u.ux;
X		bhitpos.y = u.uy;
X	} else {
X		if (mon = ghit(u.dx, u.dy, range))
X		    if (ghitm(mon, zorks))	/* was it caught? */
X			zorks = 0;
X	}
Xskip:
X	if (zorks)	/* perhaps it was caught */
X	    mkgold(zorks, bhitpos.x, bhitpos.y);
X	if(cansee(bhitpos.x, bhitpos.y)) prl(bhitpos.x,bhitpos.y);
X	return(1);
X}
END_OF_FILE
if test 11651 -ne `wc -c <'src/dothrow.c'`; then
    echo shar: \"'src/dothrow.c'\" unpacked with wrong size!
fi
# end of 'src/dothrow.c'
fi
if test -f 'src/mkroom.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/mkroom.c'\"
else
echo shar: Extracting \"'src/mkroom.c'\" \(11429 characters\)
sed "s/^X//" >'src/mkroom.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)mkroom.c	3.0	88/11/24
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X/*
X * Entry points:
X *	mkroom() -- make and stock a room of a given type
X *	nexttodoor() -- return TRUE if adjacent to a door
X *	has_dnstairs() -- return TRUE if given room has a down staircase
X *	has_upstairs() -- return TRUE if given room has an up staircase
X *	dist2() -- Euclidean square-of-distance function
X *	courtmon() -- generate a court monster
X */
X
X#define MONATTK_H	/* comment line for pre-compiled headers */
X/* block some unused #defines to avoid overloading some cpp's */
X#include "hack.h"
X
X#ifdef OVLB
Xstatic boolean FDECL(isbig, (struct mkroom *));
Xstatic struct mkroom * FDECL(pick_room,(BOOLEAN_P));
Xstatic void NDECL(mkshop), FDECL(mkzoo,(int)), NDECL(mkswamp);
X#ifdef ORACLE
Xstatic void NDECL(mkdelphi);
X#endif
X#if defined(ALTARS) && defined(THEOLOGY)
Xstatic void NDECL(mktemple);
X#endif
X
Xstatic struct permonst * NDECL(morguemon);
X#ifdef ARMY
Xstatic struct permonst * NDECL(squadmon);
X#endif
X#endif /* OVLB */
X
X#define sq(x) ((x)*(x))
X
X#ifdef OVLB
X
Xstatic boolean
Xisbig(sroom)
Xregister struct mkroom *sroom;
X{
X	register int area = (sroom->hx - sroom->lx) * (sroom->hy - sroom->ly);
X	return( area > 20 );
X}
X
Xvoid
Xmkroom(roomtype)
X/* make and stock a room of a given type */
Xint	roomtype;
X{
X
X    if (roomtype >= SHOPBASE)
X	mkshop();	/* someday, we should be able to specify shop type */
X    else switch(roomtype) {
X#ifdef THRONES
X	case COURT:	mkzoo(COURT); break;
X#endif
X	case ZOO:	mkzoo(ZOO); break;
X	case BEEHIVE:	mkzoo(BEEHIVE); break;
X	case MORGUE:	mkzoo(MORGUE); break;
X	case BARRACKS:	mkzoo(BARRACKS); break;
X	case SWAMP:	mkswamp(); break;
X#ifdef ORACLE
X	case DELPHI:	mkdelphi(); break;
X#endif
X#if defined(ALTARS) && defined(THEOLOGY)
X	case TEMPLE:	mktemple(); break;
X#endif
X	default:	impossible("Tried to make a room of type %d.", roomtype);
X    }
X}
X
Xstatic void
Xmkshop()
X{
X	register struct mkroom *sroom;
X	int i = -1;
X#ifdef WIZARD
X# ifdef __GNULINT__
X	register char *ep = (char *)0;
X# else
X	register char *ep;
X# endif
X
X	/* first determine shoptype */
X	if(wizard){
X		ep = getenv("SHOPTYPE");
X		if(ep){
X			if(*ep == 'z' || *ep == 'Z'){
X				mkzoo(ZOO);
X				return;
X			}
X			if(*ep == 'm' || *ep == 'M'){
X				mkzoo(MORGUE);
X				return;
X			}
X			if(*ep == 'b' || *ep == 'B'){
X				mkzoo(BEEHIVE);
X				return;
X			}
X#ifdef THRONES
X			if(*ep == 't' || *ep == 'T' || *ep == '\\'){
X				mkzoo(COURT);
X				return;
X			}
X#endif
X#ifdef ARMY
X			if(*ep == 's' || *ep == 'S'){
X				mkzoo(BARRACKS);
X				return;
X			}
X#endif /* ARMY */
X#if defined(ALTARS) && defined(THEOLOGY)
X			if(*ep == '_'){
X				mktemple();
X				return;
X			}
X#endif
X			if(*ep == '}'){
X				mkswamp();
X				return;
X			}
X			for(i=0; shtypes[i].name; i++)
X				if(*ep == shtypes[i].symb) goto gottype;
X			if(*ep == 'g' || *ep == 'G')
X				i = 0;
X			else
X				i = -1;
X		}
X	}
Xgottype:
X#endif
X	for(sroom = &rooms[0]; ; sroom++){
X		if(sroom->hx < 0) return;
X		if(sroom - rooms >= nroom) {
X			pline("rooms not closed by -1?");
X			return;
X		}
X		if(sroom->rtype != OROOM) continue;
X		if(!sroom->rlit || has_dnstairs(sroom) || has_upstairs(sroom))
X			continue;
X		if(
X#ifdef WIZARD
X		   (wizard && ep && sroom->doorct != 0) ||
X#endif
X			sroom->doorct == 1) break;
X	}
X
X	if(i < 0) {			/* shoptype not yet determined */
X	    register int j;
X
X	    /* pick a shop type at random */
X	    for(j = rn2(100), i = 0; j -= shtypes[i].prob; i++)
X		if (j < 0)	break;
X
X	    /* big rooms cannot be wand or book shops,
X	     * - so make them general stores
X	     */
X	    if(isbig(sroom) && (shtypes[i].symb == WAND_SYM
X#ifdef SPELLS
X				|| shtypes[i].symb == SPBOOK_SYM
X#endif
X								)) i = 0;
X	}
X	sroom->rtype = SHOPBASE + i;
X
X	/* stock the room with a shopkeeper and artifacts */
X	stock_room(&(shtypes[i]), sroom);
X}
X
Xstatic struct mkroom *
Xpick_room(strict)
Xregister boolean strict;
X/* pick an unused room, preferably with only one door */
X{
X	register struct mkroom *sroom;
X	register int i = nroom;
X
X	for(sroom = &rooms[rn2(nroom)]; i--; sroom++) {
X		if(sroom == &rooms[nroom])
X			sroom = &rooms[0];
X		if(sroom->hx < 0)
X			return (struct mkroom *)0;
X		if(sroom->rtype != OROOM)	continue;
X		if(!strict) {
X		    if(has_upstairs(sroom) || (has_dnstairs(sroom) && rn2(3)))
X			continue;
X		} else if(has_upstairs(sroom) || has_dnstairs(sroom))
X			continue;
X		if(sroom->doorct == 1 || !rn2(5))
X			return sroom;
X	}
X	return (struct mkroom *)0;
X}
X
Xstatic void
Xmkzoo(type)
Xint type;
X{
X	register struct mkroom *sroom;
X	struct monst *mon;
X	register int sx,sy,i;
X	int sh, tx, ty, goldlim = 500 * dlevel;
X
X	if(!(sroom = pick_room(FALSE))) return;
X
X	sroom->rtype = type;
X	sh = sroom->fdoor;
X	switch(type) {
X#ifdef __GNULINT__
X	    default:
X		/* make sure tx and ty are initialized */
X#endif
X	    case COURT:
X		tx = somex(sroom); ty = somey(sroom); break;
X		/* TODO: try to ensure the enthroned monster is an M2_PRINCE */
X	    case BEEHIVE:
X		tx = sroom->lx + (sroom->hx - sroom->lx + 1)/2;
X		ty = sroom->ly + (sroom->hy - sroom->ly + 1)/2;
X		break;
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		mon = makemon(
X#ifdef THRONES
X		    (type == COURT) ? courtmon() :
X#endif
X#ifdef ARMY
X		    (type == BARRACKS) ? squadmon() :
X#endif
X		    (type == MORGUE) ? morguemon() :
X		    (type == BEEHIVE) ?
X			(sx == tx && sy == ty ? &mons[PM_QUEEN_BEE] : 
X			 &mons[PM_KILLER_BEE]) :
X		    (struct permonst *) 0,
X		   sx, sy);
X		if(mon) {
X			mon->msleep = 1;
X#ifdef THRONES
X			if (type==COURT && mon->mpeaceful) {
X				mon->mpeaceful = 0;
X				mon->malign = max(3,abs(mon->data->maligntyp));
X			}
X#endif
X		}
X		switch(type) {
X		    case ZOO:
X			i = sq(dist2(sx,sy,doors[sh].x,doors[sh].y));
X			if(i >= goldlim) i = 5*dlevel;
X			goldlim -= i;
X			mkgold((long)(10 + rn2(i)), sx, sy);
X			break;
X		    case MORGUE:
X			if(!rn2(5))
X			    (void) mk_tt_object(CORPSE, sx, sy);
X			if(!rn2(10))	/* lots of treasure buried with dead */
X			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
X			break;
X		    case BEEHIVE:
X			if(!rn2(3))
X			    (void) mksobj_at(LUMP_OF_ROYAL_JELLY, sx, sy);
X			break;
X		    case BARRACKS:
X			if(!rn2(20))	/* the payroll and some loot */
X			    (void) mksobj_at((rn2(3)) ? LARGE_BOX : CHEST, sx, sy);
X			break;
X		}
X	}
X#ifdef THRONES
X	if(type == COURT)  {
X		levl[tx][ty].typ = THRONE;
X		levl[tx][ty].scrsym = THRONE_SYM;
X
X		sx = somex(sroom);
X		sy = somey(sroom);
X		mkgold((long) rn1(50 * dlevel,10), sx, sy);
X		(void) mksobj_at(CHEST, sx, sy);    /* the royal coffers */
X	}
X#endif
X
X}
X
Xstatic struct permonst *
Xmorguemon()
X{
X	register int i = rn2(100), hd = rn2(dlevel);
X
X	if(hd > 10 && i < 10)
X		return((Inhell) ? mkclass(S_DEMON) : &mons[ndemon()]);
X	if(hd > 8 && i > 85)
X		return(mkclass(S_VAMPIRE));
X
X	return((i < 20) ? &mons[PM_GHOST]
X			: (i < 40) ? &mons[PM_WRAITH] : mkclass(S_ZOMBIE));
X}
X
Xstatic void
Xmkswamp()	/* Michiel Huisjes & Fred de Wilde */
X{
X	register struct mkroom *sroom;
X	register int sx,sy,i,eelct = 0;
X
X	for(i=0; i<5; i++) {		/* 5 tries */
X		sroom = &rooms[rn2(nroom)];
X		if(sroom->hx < 0 || sroom->rtype != OROOM ||
X		   has_upstairs(sroom) || has_dnstairs(sroom))
X			continue;
X
X		/* satisfied; make a swamp */
X		sroom->rtype = SWAMP;
X		for(sx = sroom->lx; sx <= sroom->hx; sx++)
X		for(sy = sroom->ly; sy <= sroom->hy; sy++)
X		if(!OBJ_AT(sx, sy) && levl[sx][sy].gmask == 0 &&
X		   !MON_AT(sx, sy) && !t_at(sx,sy) && !nexttodoor(sx,sy)) {
X		    if((sx+sy)%2) {
X			levl[sx][sy].typ = POOL;
X			levl[sx][sy].scrsym = POOL_SYM;
X			if(!eelct || !rn2(4)) {
X				(void) makemon(mkclass(S_EEL), sx, sy);
X				eelct++;
X			}
X		    } else if(!rn2(4))	/* swamps tend to be moldy */
X			(void) makemon(mkclass(S_FUNGUS), sx, sy);
X		}
X	}
X}
X
X#ifdef ORACLE
Xstatic void
Xmkdelphi()
X{
X	register struct mkroom *sroom;
X	register struct monst *oracl;
X	int dy,xx,yy;
X
X	if(doorindex >= DOORMAX) return;
X	if(!(sroom = pick_room(FALSE))) return;
X
X	if(!place_oracle(sroom,&dy,&xx,&yy)) return;
X
X	if(MON_AT(xx, yy))
X	    rloc(m_at(xx, yy)); /* insurance */
X
X	/* set up Oracle and environment */
X	if(!(oracl = makemon(&mons[PM_ORACLE],xx,yy))) return;
X	sroom->rtype = DELPHI;
X	oracl->mpeaceful = 1;
X
X	yy -= dy;
X	if(accessible(xx-1, yy))
X	    (void) mkcorpstat(STATUE, &mons[PM_FOREST_CENTAUR], xx-1, yy);
X	if(accessible(xx, yy))
X	    (void) mkcorpstat(STATUE, &mons[PM_MOUNTAIN_CENTAUR], xx, yy);
X	if(accessible(xx+1,yy))
X	    (void) mkcorpstat(STATUE, &mons[PM_PLAINS_CENTAUR], xx+1, yy);
X# ifdef FOUNTAINS
X	mkfount(0,sroom);
X# endif
X}
X#endif
X
X#if defined(ALTARS) && defined(THEOLOGY)
Xvoid
Xshrine_pos(sx,sy,troom)
Xint *sx,*sy;
Xstruct mkroom *troom;
X{
X	*sx = troom->lx + ((troom->hx - troom->lx) / 2);
X	*sy = troom->ly + ((troom->hy - troom->ly) / 2);
X}
X
Xstatic void
Xmktemple()
X{
X	register struct mkroom *sroom;
X	int sx,sy;
X
X	if(!(sroom = pick_room(TRUE))) return;
X
X	/* set up Priest and shrine */
X	sroom->rtype = TEMPLE;
X	shrine_pos(&sx,&sy,sroom);
X	/*
X	 * In temples, shrines are blessed altars
X	 * located in the center of the room
X	 */
X	levl[sx][sy].typ = ALTAR;
X	levl[sx][sy].scrsym = ALTAR_SYM;
X	levl[sx][sy].altarmask = rn2((int)A_LAW+1);
X	priestini(dlevel, sx, sy, (int) levl[sx][sy].altarmask);
X 	levl[sx][sy].altarmask |= A_SHRINE;
X}
X#endif
X
Xboolean
Xnexttodoor(sx,sy)
Xregister int sx, sy;
X{
X	register int dx, dy;
X	register struct rm *lev;
X	for(dx = -1; dx <= 1; dx++) for(dy = -1; dy <= 1; dy++) {
X		if(!isok(sx+dx, sy+dy)) continue;
X		if(IS_DOOR((lev = &levl[sx+dx][sy+dy])->typ) ||
X		    lev->typ == SDOOR)
X			return(TRUE);
X	}
X	return(FALSE);
X}
X
Xboolean
Xhas_dnstairs(sroom)
Xregister struct mkroom *sroom;
X{
X	return(sroom->lx <= xdnstair && xdnstair <= sroom->hx &&
X		   sroom->ly <= ydnstair && ydnstair <= sroom->hy);
X}
X
Xboolean
Xhas_upstairs(sroom)
Xregister struct mkroom *sroom;
X{
X	return(sroom->lx <= xupstair && xupstair <= sroom->hx &&
X		   sroom->ly <= yupstair && yupstair <= sroom->hy);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xint
Xdist2(x0,y0,x1,y1)
Xint x0, y0, x1, y1;
X{
X	register int dx = x0 - x1, dy = y0 - y1;
X	return sq(dx) + sq(dy);
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
X#ifdef THRONES
Xstruct permonst *
Xcourtmon()
X{
X	int     i = rn2(60) + rn2(3*dlevel);
X	if (i > 100)		return(mkclass(S_DRAGON));
X	else if (i > 95)	return(mkclass(S_GIANT));
X	else if (i > 85)	return(mkclass(S_TROLL));
X	else if (i > 75)	return(mkclass(S_CENTAUR));
X	else if (i > 60)	return(mkclass(S_ORC));
X	else if (i > 45)	return(&mons[PM_BUGBEAR]);
X	else if (i > 30)	return(&mons[PM_HOBGOBLIN]);
X	else if (i > 15)	return(mkclass(S_GNOME));
X	else			return(mkclass(S_KOBOLD));
X}
X#endif /* THRONES /**/
X
X#ifdef ARMY
X#define	    NSTYPES	(PM_CAPTAIN-PM_SOLDIER+1)
X
Xstruct {
X    unsigned	pm;
X    unsigned	prob;
X}   squadprob[NSTYPES] = {
X    PM_SOLDIER, 80, PM_SERGEANT, 15, PM_LIEUTENANT, 4, PM_CAPTAIN, 1
X};
X
Xstatic struct permonst *
Xsquadmon() {	    /* return soldier types. */
X
X	register struct permonst *ptr;
X	register int	i, cpro, sel_prob = rnd(80+dlevel);
X
X	for(cpro = i = 0; i < NSTYPES; i++)
X	    if((cpro += squadprob[i].prob) > sel_prob) {
X
X		ptr = &mons[squadprob[i].pm];
X		goto gotone;
X	    }
X	ptr = &mons[squadprob[rn2(NSTYPES)].pm];
Xgotone:
X	if(!(ptr->geno & G_GENOD))  return(ptr);
X	else			    return((struct permonst *) 0);
X}
X#endif /* ARMY /* */
X
X#endif /* OVLB */
END_OF_FILE
if test 11429 -ne `wc -c <'src/mkroom.c'`; then
    echo shar: \"'src/mkroom.c'\" unpacked with wrong size!
fi
# end of 'src/mkroom.c'
fi
if test -f 'src/mthrowu.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/mthrowu.c'\"
else
echo shar: Extracting \"'src/mthrowu.c'\" \(12098 characters\)
sed "s/^X//" >'src/mthrowu.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)mthrowu.c	3.0	89/11/22
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include	"hack.h"
X
XSTATIC_DCL int FDECL(movedist,(int,int,int,int));
XSTATIC_DCL void FDECL(drop_throw,(struct obj *,BOOLEAN_P,int,int));
XSTATIC_DCL void FDECL(m_throw,(int,int,int,int,int,struct obj *));
X
X#define URETREATING(x,y) (movedist(u.ux,u.uy,x,y) > movedist(u.ux0,u.uy0,x,y))
X
Xboolean FDECL(lined_up, (struct monst *));
X
X#ifndef OVLB
X
XSTATIC_DCL const char *breathwep[];
X
X#else /* OVLB */
X
Xschar NEARDATA tbx = 0, NEARDATA tby = 0;
X	/* used for direction of throw, buzz, etc. */
X
XSTATIC_OVL const char NEARDATA *breathwep[] = {    "fragments",
X				"fire",
X				"sleep gas",
X				"frost",
X				"death",
X				"lightning",
X				"poison gas",
X				"acid"
X};
X
Xint
Xthitu(tlev, dam, obj, name)	/* u is hit by sth, but not a monster */
X	register int tlev, dam;
X	struct obj *obj;
X	register const char *name;
X{
X	const char *onm = an(name);
X	boolean is_acid = (obj && obj->otyp == ACID_VENOM);
X
X	if(u.uac + tlev <= rnd(20)) {
X		if(Blind || !flags.verbose) pline("It misses.");
X		else You("are almost hit by %s!", onm);
X		return(0);
X	} else {
X		if(Blind || !flags.verbose) You("are hit!");
X		else You("are hit by %s!", onm);
X#ifdef POLYSELF
X		if (obj && obj->otyp == SILVER_ARROW && (u.ulycn != -1 ||
X				is_demon(uasmon) || u.usym == S_VAMPIRE ||
X				(u.usym == S_IMP && u.umonnum != PM_TENGU))) {
X			dam += rnd(20);
X			pline("The %sarrow sears your flesh!",
X				Blind ? "" : "silver ");
X		}
X		if (is_acid && resists_acid(uasmon))
X			pline("It doesn't seem to hurt you.");
X		else {
X#endif
X			if (is_acid) pline("It burns!");
X			losehp(dam, name, KILLED_BY_AN);
X#ifdef POLYSELF
X		}
X#endif
X		return(1);
X	}
X}
X
X/* Be sure this corresponds with what happens to player-thrown objects in
X * dothrow.c (for consistency). --KAA
X */
X
XSTATIC_OVL void
Xdrop_throw(obj, ohit, x, y)
Xregister struct obj *obj;
Xboolean ohit;
Xint x,y;
X{
X	int create;
X
X	if (obj->otyp == CREAM_PIE || obj->olet == VENOM_SYM)
X		create = 0;
X	else if (ohit &&
X		 ((obj->otyp >= ARROW && obj->otyp <= SHURIKEN) ||
X		  obj->otyp == ROCK))
X		create = !rn2(3);
X	else create = 1;
X	if (create && !flooreffects(obj,x,y)) {
X		place_object(obj, x, y);
X		obj->nobj = fobj;
X		fobj = obj;
X		stackobj(fobj);
X	} else free((genericptr_t)obj);
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
XSTATIC_OVL void
Xm_throw(x, y, dx, dy, range, obj)
X	register int x,y,dx,dy,range;		/* direction and range */
X	register struct obj *obj;
X{
X	register struct monst *mtmp;
X	struct obj *singleobj;
X	char sym = obj->olet;
X	int damage;
X	int hitu, blindinc=0;
X
X	bhitpos.x = x;
X	bhitpos.y = y;
X
X	singleobj = splitobj(obj, (int)obj->quan-1);
X	/* splitobj leaves the new object in the chain (i.e. the monster's
X	 * inventory).  Remove it.  We can do this in 1 line, but it's highly
X	 * dependent on the fact that we know splitobj() places it immediately
X	 * after obj.
X	 */
X	obj->nobj = singleobj->nobj;
X
X	if(sym) {
X		tmp_at(-1, sym);	/* open call */
X#ifdef TEXTCOLOR
X		tmp_at(-3, (int)objects[obj->otyp].oc_color);
X#else
X		tmp_at(-3, (int)AT_OBJ);
X#endif
X	}
X	while(range-- > 0) { /* Actually the loop is always exited by break */
X		boolean vis;
X
X		bhitpos.x += dx;
X		bhitpos.y += dy;
X		vis = cansee(bhitpos.x, bhitpos.y);
X		if(MON_AT(bhitpos.x, bhitpos.y)) {
X		    mtmp = m_at(bhitpos.x,bhitpos.y);
X
X		    if(mtmp->data->ac + 8 + obj->spe <= rnd(20)) {
X			if (!vis) pline("It is missed.");
X			else miss(distant_name(singleobj,xname), mtmp);
X			if (!range) { /* Last position; object drops */
X			    drop_throw(singleobj, 0, mtmp->mx, mtmp->my);
X			    break;
X			}
X		    } else {
X			damage = dmgval(obj, mtmp->data);
X			if (damage < 1) damage = 1;
X			if (obj->otyp==ACID_VENOM && resists_acid(mtmp->data))
X			    damage = 0;
X			if (!vis) pline("It is hit%s", exclam(damage));
X			else hit(distant_name(singleobj,xname),
X							mtmp,exclam(damage));
X			if (obj->opoisoned) {
X			    if (resists_poison(mtmp->data)) {
X				if (vis)
X				  pline("The poison doesn't seem to affect %s.",
X								mon_nam(mtmp));
X			    } else {
X				if (rn2(30)) damage += rnd(6);
X				else {
X				    if (vis)
X					pline("The poison was deadly...");
X				    damage = mtmp->mhp;
X				}
X			    }
X			}
X			if (obj->otyp==SILVER_ARROW && (is_were(mtmp->data)
X				|| is_demon(mtmp->data)
X				|| mtmp->data->mlet == S_VAMPIRE
X				|| (mtmp->data->mlet==S_IMP
X					&& mtmp->data != &mons[PM_TENGU]))) {
X			    if (vis) pline("The silver arrow sears %s's flesh!",
X				mon_nam(mtmp));
X			    else pline("Its flesh is seared!");
X			    damage += rnd(20);
X			}
X			if (obj->otyp==ACID_VENOM && cansee(mtmp->mx,mtmp->my)){
X			    if (resists_acid(mtmp->data)) {
X				pline("%s is unaffected.", vis ? Monnam(mtmp)
X					: "It");
X				damage = 0;
X			    } else if (vis)
X				pline("The acid burns %s!", mon_nam(mtmp));
X			    else pline("It is burned!");
X			}
X			mtmp->mhp -= damage;
X			if(mtmp->mhp < 1) {
X			    pline("%s is %s!", vis ? Monnam(mtmp) : "It",
X			       (is_demon(mtmp->data) || 
X					is_undead(mtmp->data) || !vis) ?
X				 "destroyed" : "killed");
X			    mondied(mtmp);
X			}
X
X			if((obj->otyp == CREAM_PIE) ||
X			   (obj->otyp == BLINDING_VENOM)) {
X			    if (vis)
X				pline("%s is blinded by the %s.",
X				      Monnam(mtmp), xname(singleobj));
X			    if(mtmp->msleep) mtmp->msleep = 0;
X			    mtmp->mcansee = 0;
X			    {
X				register unsigned rnd_tmp = rnd(25) + 20;
X				if((mtmp->mblinded + rnd_tmp) > 127)
X					mtmp->mblinded = 127;
X				else mtmp->mblinded += rnd_tmp;
X			    }
X			}
X			drop_throw(singleobj, 1, bhitpos.x, bhitpos.y);
X			break;
X		    }
X		}
X		if (bhitpos.x == u.ux && bhitpos.y == u.uy) {
X			if (multi) nomul(0);
X
X			switch(obj->otyp) {
X			    int dam;
X			    case CREAM_PIE:
X			    case BLINDING_VENOM:
X				hitu = thitu(8, 0, singleobj, xname(singleobj));
X				break;
X			    default:
X				dam = dmgval(obj, uasmon);
X				if (dam < 1) dam = 1;
X				hitu = thitu(8+obj->spe, dam, singleobj,
X					xname(singleobj));
X			}
X			if (hitu && obj->opoisoned)
X			    /* it's safe to call xname twice because it's the
X			       same object both times... */
X			    poisoned(xname(singleobj), A_STR, xname(singleobj), 10);
X			if(hitu && (obj->otyp == CREAM_PIE ||
X				     obj->otyp == BLINDING_VENOM)) {
X			    blindinc = rnd(25);
X			    if(obj->otyp == CREAM_PIE) {
X				if(!Blind) pline("Yecch!  You've been creamed.");
X				else	pline("There's something sticky all over your %s.", body_part(FACE));
X			    } else {	/* venom in the eyes */
X				if(Blindfolded) /* nothing */ ;
X				else if(!Blind) pline("The venom blinds you.");
X				else	Your("%s sting.",
X					makeplural(body_part(EYE)));
X			    }
X			}
X			stop_occupation();
X			if (hitu || !range) {
X			    drop_throw(singleobj, hitu, u.ux, u.uy);
X			    break;
X			}
X		} else if (!range	/* reached end of path */
X			/* missile hits edge of screen */
X			|| !isok(bhitpos.x+dx,bhitpos.y+dy)
X			/* missile hits the wall */
X			|| IS_WALL(levl[bhitpos.x+dx][bhitpos.y+dy].typ)
X			|| levl[bhitpos.x+dx][bhitpos.y+dy].typ == SDOOR
X			|| levl[bhitpos.x+dx][bhitpos.y+dy].typ == SCORR
X#ifdef SINKS
X			/* Thrown objects "sink" */
X			|| IS_SINK(levl[bhitpos.x][bhitpos.y].typ)
X#endif
X								) {
X		    drop_throw(singleobj, 0, bhitpos.x, bhitpos.y);
X		    break;
X		}
X		tmp_at(bhitpos.x, bhitpos.y);
X	}
X	tmp_at(bhitpos.x, bhitpos.y);
X	tmp_at(-1, -1);
X	/* blindfold keeps substances out of your eyes */
X	if (blindinc && !Blindfolded) {
X		u.ucreamed += blindinc;
X		make_blinded(Blinded + blindinc,FALSE);
X	}
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
X/* Remove an item from the monster's inventory.
X */
Xvoid
Xm_useup(mon, obj)
Xstruct monst *mon;
Xstruct obj *obj;
X{
X	struct obj *otmp, *prev;
X
X	if (obj->quan > 1) {
X		obj->quan--;
X		return;
X	}
X	prev = ((struct obj *) 0);
X	for (otmp = mon->minvent; otmp; otmp = otmp->nobj) {
X		if (otmp == obj) {
X			if (prev)
X				prev->nobj = obj->nobj;
X			else
X				mon->minvent = obj->nobj;
X			free((genericptr_t) obj);
X			break;
X		}
X		prev = otmp;
X	}
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
X/* Always returns 0??? -SAC */
Xint
Xthrwmu(mtmp)	/* monster throws item at you */
Xregister struct monst *mtmp;
X{
X	struct obj *otmp, *select_rwep();
X	register xchar x, y;
X
X	if(lined_up(mtmp)) {
X
X	    if((otmp = select_rwep(mtmp))) {
X
X		/* If you are coming toward the monster, the monster
X		 * should try to soften you up with missiles.  If you are
X		 * going away, you are probably hurt or running.  Give
X		 * chase, but if you are getting too far away, throw.
X		 */
X		x = mtmp->mx;
X		y = mtmp->my;
X		if(!URETREATING(x,y) ||
X		   !rn2(BOLT_LIM-movedist(x,mtmp->mux,y,mtmp->muy)))
X		{
X		    unsigned savequan = otmp->quan;
X		    const char *verb = "throws";
X
X		    if (otmp->otyp == ARROW
X#ifdef TOLKIEN
X			|| otmp->otyp == ELVEN_ARROW
X			|| otmp->otyp == ORCISH_ARROW
X#endif
X			|| otmp->otyp == CROSSBOW_BOLT) verb = "shoots";
X		    otmp->quan = 1;
X		    if (canseemon(mtmp))
X			pline("%s %s %s!", Monnam(mtmp), verb, an(xname(otmp)));
X		    otmp->quan = savequan;
X		    m_throw(mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), 
X			movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy), otmp);
X		    if (!otmp->quan) m_useup(mtmp, otmp);
X		    nomul(0);
X		    return 0;
X		}
X	    }
X	}
X	return 0;
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xint
Xspitmu(mtmp, mattk)		/* monster spits substance at you */
Xregister struct monst *mtmp;
Xregister struct attack *mattk;
X{
X	register struct obj *otmp;
X
X	if(mtmp->mcan) {
X
X	    if(flags.soundok)
X		pline("A dry rattle comes from %s's throat", mon_nam(mtmp));
X	    return 0;
X	}
X	if(lined_up(mtmp)) {
X		switch (mattk->adtyp) {
X		    case AD_BLND:
X		    case AD_DRST:
X			otmp = mksobj(BLINDING_VENOM, FALSE);
X			break;
X		    default:
X			impossible("bad attack type in spitmu");
X				/* fall through */
X		    case AD_ACID:
X			otmp = mksobj(ACID_VENOM, FALSE);
X			break;
X		}
X		if(!rn2(BOLT_LIM-movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy))) {
X		    if (canseemon(mtmp))
X			pline("%s spits venom!", Monnam(mtmp));
X		    m_throw(mtmp->mx, mtmp->my, sgn(tbx), sgn(tby), 
X			movedist(mtmp->mx,mtmp->mux,mtmp->my,mtmp->muy), otmp);
X		    nomul(0);
X		    return 0;
X		}
X	}
X	return 0;
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xint
Xbreamu(mtmp, mattk)			/* monster breathes at you (ranged) */
X	register struct monst *mtmp;
X	register struct attack  *mattk;
X{
X	if(lined_up(mtmp)) {
X
X	    if(mtmp->mcan) {
X		if(flags.soundok) {
X		    if(canseemon(mtmp))
X			pline("%s coughs.", Monnam(mtmp));
X		    else
X			You("hear a cough.");
X		}
X		return(0);
X	    }
X	    if(rn2(3)) {
X
X		if((mattk->adtyp >= 1) && (mattk->adtyp < 11)) {
X
X		    if(canseemon(mtmp))
X			pline("%s breathes %s!", Monnam(mtmp),
X			      breathwep[mattk->adtyp-1]);
X		    buzz((int) (-20 - (mattk->adtyp-1)), (int)mattk->damn,
X			 mtmp->mx, mtmp->my, sgn(tbx), sgn(tby));
X		    nomul(0);
X		} else impossible("Breath weapon %d used", mattk->adtyp-1);
X	    }
X	}
X	return(1);
X}
X
Xboolean
Xlinedup(ax, ay, bx, by)
Xregister xchar ax, ay, bx, by;
X{
X	register xchar x, y;
X
X	tbx = ax - bx;	/* These two values are set for use */
X	tby = ay - by;	/* after successful return.	    */
X
X	if((!tbx || !tby || abs(tbx) == abs(tby)) /* straight line or diagonal */
X	   && movedist(tbx, 0,  tby, 0) < BOLT_LIM) {
X
X		/* Check if there are any dead squares between.  If so,
X		 * it will not be possible to shoot.
X		 */
X		x = bx; y = by;
X		while(x != ax || y != ay) {
X
X		    if(!accessible(x, y)) return FALSE;
X		    x += sgn(tbx), y += sgn(tby);
X		}
X		return TRUE;
X	}
X	return FALSE;
X}
X
Xboolean
Xlined_up(mtmp)		/* is mtmp in position to use ranged attack? */
X	register struct monst *mtmp;
X{
X	return(linedup(mtmp->mux,mtmp->muy,mtmp->mx,mtmp->my));
X}
X
X#endif /* OVL1 */
X#ifdef OVL0
X
X/* Check if a monster is carrying a particular item.
X */
Xstruct obj *
Xm_carrying(mtmp, type)
Xstruct monst *mtmp;
Xint type;
X{
X	register struct obj *otmp;
X
X	for(otmp = mtmp->minvent; otmp; otmp = otmp->nobj)
X		if(otmp->otyp == type)
X			return(otmp);
X	return((struct obj *) 0);
X}
X
X#endif /* OVL0 */
X#ifdef OVL1
X
XSTATIC_OVL int
Xmovedist(x0, x1, y0, y1)
Xint x0, x1, y0, y1;
X{
X	register int absdx, absdy;
X
X	absdx = abs(x1 - x0);
X	absdy = abs(y1 - y0);
X
X	return (max(absdx,absdy));
X}
X
X#endif /* OVL1 */
END_OF_FILE
if test 12098 -ne `wc -c <'src/mthrowu.c'`; then
    echo shar: \"'src/mthrowu.c'\" unpacked with wrong size!
fi
# end of 'src/mthrowu.c'
fi
if test -f 'src/steal.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/steal.c'\"
else
echo shar: Extracting \"'src/steal.c'\" \(7653 characters\)
sed "s/^X//" >'src/steal.c' <<'END_OF_FILE'
X/*	SCCS Id: @(#)steal.c	3.0	88/07/06
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed.  See license for details. */
X
X#include "hack.h"
X
XSTATIC_DCL int NDECL(stealarm);
X
X#ifdef OVLB
Xstatic const char * FDECL(equipname, (struct obj *));
X
Xstatic const char *
Xequipname(otmp)
X
X	register struct obj *otmp;
X{
X
X	return (
X#ifdef SHIRT
X		(otmp == uarmu) ? "shirt" :
X#endif
X		(otmp == uarmf) ? "boots" :
X		(otmp == uarms) ? "shield" :
X		(otmp == uarmg) ? "gloves" :
X		(otmp == uarmc) ? "cloak" :
X		(otmp == uarmh) ? "helmet" : "armor");
X}
X
Xlong		/* actually returns something that fits in an int */
Xsomegold(){
X#ifdef LINT	/* long conv. ok */
X	return(0L);
X#else
X	return (long)( (u.ugold < 100) ? u.ugold :
X		(u.ugold > 10000) ? rnd(10000) : rnd((int) u.ugold) );
X#endif
X}
X
Xvoid
Xstealgold(mtmp)
Xregister struct monst *mtmp;
X{
X	register struct gold *gold = g_at(u.ux, u.uy);
X	register 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 %s!",
X			Blind ? "It" : Monnam(mtmp), makeplural(body_part(FOOT)));
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		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 int stealoid;		/* object to be stolen */
Xunsigned int stealmid;		/* monster doing the stealing */
X
XSTATIC_OVL int
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(otmp->unpaid) subfrombill(otmp);
X		  freeinv(otmp);
X		  pline("%s steals %s!", Blind ? "It" : 
X					Monnam(mtmp), doname(otmp));
X		  mpickobj(mtmp,otmp);
X		  mtmp->mflee = 1;
X		  rloc(mtmp);
X		break;
X	      }
X	    break;
X	  }
X	return stealoid = 0;
X}
X
X/* Returns 1 when something was stolen (or at least, when N should flee now)
X * Returns -1 if the monster died in the attempt
X * Avoid stealing the object stealoid
X */
Xint
Xsteal(mtmp)
Xstruct monst *mtmp;
X{
X	register struct obj *otmp;
X	register int tmp;
X	register int named = 0;
X
X	/* the following is true if successful on first of two attacks. */
X	if(!monnear(mtmp, u.ux, u.uy)) return(0);
X
X	if(!invent){
X	    /* Not even a thousand men in armor can strip a naked man. */
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
X	if(Adornment & LEFT_RING) {
X	    otmp = uleft;
X	    goto gotobj;
X	} else if(Adornment & RIGHT_RING) {
X	    otmp = uright;
X	    goto gotobj;
X	}
X
X	tmp = 0;
X	for(otmp = invent; otmp; otmp = otmp->nobj) if(!uarm || otmp != uarmc)
X	    tmp += ((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1);
X	tmp = rn2(tmp);
X	for(otmp = invent; otmp; otmp = otmp->nobj) if(!uarm || otmp != uarmc)
X  	    if((tmp -= ((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL)) ? 5 : 1))
X			< 0) break;
X	if(!otmp) {
X		impossible("Steal fails!");
X		return(0);
X	}
X	/* can't steal gloves while wielding - so steal the wielded item. */
X	if (otmp == uarmg && uwep)
X	    otmp = uwep;
X	/* can't steal armor while wearing cloak - so steal the cloak. */
X	else if(otmp == uarm && uarmc) otmp = uarmc;
X#ifdef SHIRT
X	else if(otmp == uarmu && uarmc) otmp = uarmc;
X	else if(otmp == uarmu && uarm) otmp = uarm;
X#endif
Xgotobj:
X	if(otmp->o_id == stealoid) return(0);
X
X#ifdef WALKIES
X	if(otmp->otyp == LEASH && otmp->leashmon) o_unleash(otmp);
X#endif
X
X	if((otmp->owornmask & (W_ARMOR | W_RING | W_AMUL | W_TOOL))){
X		switch(otmp->olet) {
X		case TOOL_SYM:
X			Blindf_off(otmp);
X			break;
X		case AMULET_SYM:
X			Amulet_off();
X			break;
X		case RING_SYM:
X			Ring_gone(otmp);
X			break;
X		case ARMOR_SYM:
X			/* Stop putting on armor which has been stolen. */
X			if (donning(otmp)) {
X			  cancel_don();
X			  if (otmp == uarm)  (void) Armor_off();
X			  /* else if (otmp == uarmc) (void) Cloak_off(); */
X			  else if (otmp == uarmf) (void) Boots_off();
X			  else if (otmp == uarmg) (void) Gloves_off();
X			  else if (otmp == uarmh) (void) Helmet_off();
X			  /* else if (otmp == uarms) (void) Shield_off(); */
X			  else 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 %s your %s.",
X				  Blind ? "She" : Monnam(mtmp),
X				  curssv ? "let her take" : "hand over",
X				  equipname(otmp));
X			else
X			    pline("%s seduces you and %s off your %s.",
X				  Blind ? "It" : Amonnam(mtmp, "beautiful"),
X				  curssv ? "helps you to take" : "you start taking",
X				  equipname(otmp));
X			named++;
X			/* the following is to set multi for later on */
X			(void) nomul(-objects[otmp->otyp].oc_delay);
X
X			if (otmp == uarm)  (void) Armor_off();
X			else if (otmp == uarmc) (void) Cloak_off();
X			else if (otmp == uarmf) (void) Boots_off();
X			else if (otmp == uarmg) (void) Gloves_off();
X			else if (otmp == uarmh) (void) Helmet_off();
X			else if (otmp == uarms) (void) Shield_off();
X			else setworn((struct obj *)0, otmp->owornmask & W_ARMOR);
X			otmp->cursed = curssv;
X			if(multi < 0){
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) uwepgone();
X
X	if(otmp == uball) unpunish();
X
X	freeinv(otmp);
X	pline("%s stole %s.", named ? "She" : (Blind ? "It" : Monnam(mtmp)), doname(otmp));
X	mpickobj(mtmp,otmp);
X	if (otmp->otyp == CORPSE && otmp->corpsenm == PM_COCKATRICE
X	    && !resists_ston(mtmp->data)) {
X	    pline("%s turns to stone.", Blind ? "It" : Monnam(mtmp));
X	    stoned = TRUE;
X	    xkilled(mtmp, 0);
X	    return -1;
X	}
X	return((multi < 0) ? 0 : 1);
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xvoid
Xmpickobj(mtmp,otmp)
Xregister struct monst *mtmp;
Xregister struct obj *otmp;
X{
X	otmp->nobj = mtmp->minvent;
X	mtmp->minvent = otmp;
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xvoid
Xstealamulet(mtmp)
Xregister struct monst *mtmp;
X{
X	register struct obj *otmp;
X
X	for(otmp = invent; otmp; otmp = otmp->nobj) {
X	    if(otmp->otyp == AMULET_OF_YENDOR) {
X		/* might be an imitation one */
X		setnotworn(otmp);
X		freeinv(otmp);
X		mpickobj(mtmp,otmp);
X		pline("%s stole %s!", Blind ? "It":Monnam(mtmp), doname(otmp));
X		rloc(mtmp);
X		return;
X	    }
X	}
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
X/* release the objects the killed animal has stolen */
Xvoid
Xrelobj(mtmp,show)
Xregister struct monst *mtmp;
Xregister int show;
X{
X	register struct obj *otmp, *otmp2;
X
X	for(otmp = mtmp->minvent; otmp; otmp = otmp2){
X		otmp2 = otmp->nobj;
X		if (flooreffects(otmp,mtmp->mx,mtmp->my)) continue;
X		place_object(otmp, mtmp->mx, mtmp->my);
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 == S_LEPRECHAUN) {
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}
X
X#endif /* OVL0 */
END_OF_FILE
if test 7653 -ne `wc -c <'src/steal.c'`; then
    echo shar: \"'src/steal.c'\" unpacked with wrong size!
fi
# end of 'src/steal.c'
fi
echo shar: End of archive 44 \(of 56\).
cp /dev/null ark44isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 56 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
    echo Building monst.c from monst.c1 and monst.c2
    cat src/monst.c1 src/monst.c2 > src/monst.c
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0