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