home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 October
/
usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso
/
games
/
volume7
/
nethack3
/
part14
< prev
next >
Wrap
Internet Message Format
|
1989-07-31
|
56KB
Path: uunet!zephyr.ens.tek.com!tektronix!tekgen!tekred!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v07i069: NetHack3 - display oriented dungeons & dragons (Ver. 3.0), Part14/38
Message-ID: <4322@tekred.CNA.TEK.COM>
Date: 24 Jul 89 05:03:52 GMT
Sender: nobody@tekred.CNA.TEK.COM
Lines: 2041
Approved: billr@saab.CNA.TEK.COM
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 7, Issue 69
Archive-name: NetHack3/Part14
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 14 (of 38)."
# Contents: include/coord.h src/monmove.c src/read.c
# Wrapped by billr@saab on Sun Jul 23 21:32:57 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'include/coord.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'include/coord.h'\"
else
echo shar: Extracting \"'include/coord.h'\" \(272 characters\)
sed "s/^X//" >'include/coord.h' <<'END_OF_FILE'
X/* SCCS Id: @(#)coord.h 3.0 88/04/25
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#ifndef COORD_H
X#define COORD_H
X
Xtypedef struct {
X xchar x,y;
X} coord;
X
X#endif /* COORD_H /* */
END_OF_FILE
if test 272 -ne `wc -c <'include/coord.h'`; then
echo shar: \"'include/coord.h'\" unpacked with wrong size!
fi
# end of 'include/coord.h'
fi
if test -f 'src/monmove.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/monmove.c'\"
else
echo shar: Extracting \"'src/monmove.c'\" \(20241 characters\)
sed "s/^X//" >'src/monmove.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)monmove.c 3.0 88/11/10
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X#include "mfndpos.h"
X#ifdef NAMED_ITEMS
X# include "artifact.h"
X#endif
X
Xstatic boolean /* TRUE : mtmp died */
Xmb_trapped(mtmp)
Xregister struct monst *mtmp;
X{
X if (flags.verbose) {
X if (cansee(mtmp->mx, mtmp->my))
X pline("KABOOM!! You see a door explode.");
X else if (flags.soundok)
X You("hear a distant explosion.");
X }
X mtmp->mstun = 1;
X mtmp->mhp -= rnd(15);
X if(mtmp->mhp <= 0) {
X mondied(mtmp);
X return(TRUE);
X }
X return(FALSE);
X}
X
Xboolean
Xmdig_tunnel(mtmp) /* FALSE: monster died */
Xregister struct monst *mtmp;
X{
X register struct rm *here;
X register int pile = rnd(12);
X boolean canseeit = cansee(mtmp->mx, mtmp->my);
X here = &levl[mtmp->mx][mtmp->my];
X
X if(IS_ROCK(here->typ)) {
X /* Just ate something. */
X if(here->typ == STONE) here->typ = CORR;
X else if(IS_WALL(here->typ) &&
X !(here->diggable & W_NONDIGGABLE)) {
X if(flags.soundok && flags.verbose && !rn2(5))
X You("hear the sound of crashing rock.");
X here->typ = DOOR;
X here->doormask = D_NODOOR;
X }
X }
X /* Eats away door if present & closed or locked */
X else if(IS_DOOR(here->typ) &&
X (here->doormask & (D_LOCKED | D_CLOSED))) {
X if(here->doormask & D_TRAPPED) {
X here->doormask = D_NODOOR;
X if(mb_trapped(mtmp)) return(FALSE);
X } else {
X if(!rn2(3) && flags.verbose) /* not too often.. */
X You("feel an unexpected draft of air.");
X here->doormask = D_BROKEN;
X }
X }
X else pile = 12; /* it doesn't leave rocks if it didn't dig */
X
X /* Left behind a pile? */
X if(pile < 5) {
X if(pile == 1)
X (void) mksobj_at(BOULDER, mtmp->mx, mtmp->my);
X else
X (void) mksobj_at(ROCK, mtmp->mx, mtmp->my);
X }
X if(canseeit) {
X here->seen = TRUE;
X newsym(mtmp->mx,mtmp->my);
X } else
X mnewsym(mtmp->mx,mtmp->my);
X return(TRUE);
X}
X
Xint
Xdochugw(mtmp)
X register struct monst *mtmp;
X{
X register int x = mtmp->mx;
X register int y = mtmp->my;
X register int rd = dochug(mtmp);
X register int dd;
X
X if(!rd && !mtmp->mpeaceful &&
X (dd = dist(mtmp->mx,mtmp->my)) < dist(x,y) &&
X dd < 100 && !canseemon(mtmp)) {
X#ifdef NAMED_ITEMS
X /* Note: this assumes we only want to warn against the monster which
X * the weapon does extra damage to, as there is no "monster which
X * the weapon warns against" field.
X */
X if(spec_ability(uwep,SPFX_WARN) && spec_dbon(uwep,mtmp->data,1))
X warnlevel = 100;
X else
X#endif
X if (Warning && mtmp->m_lev > warnlevel)
X warnlevel = mtmp->m_lev;
X }
X return(rd);
X}
X
Xboolean
Xonscary(x, y, mtmp)
Xint x, y;
Xstruct monst *mtmp;
X{
X if (mtmp->isshk || mtmp->isgd || mtmp->iswiz || !mtmp->mcansee ||
X mtmp->data->mlet == S_HUMAN || mtmp->mpeaceful)
X return(FALSE);
X return(
X#ifdef ELBERETH
X sengr_at("Elbereth", x, y) ||
X#endif
X sobj_at(SCR_SCARE_MONSTER, x, y) != (struct obj *)0);
X}
X
X/* returns 1 if monster died moving, 0 otherwise */
Xint
Xdochug(mtmp)
X register struct monst *mtmp;
X{
X register struct permonst *mdat = mtmp->data;
X register int tmp=0, inrange, nearby, scared, seescaryx,
X seescaryy;
X
X/* Pre-movement adjustments */
X
X if(mtmp->cham && !rn2(6)) /* polymorph chameleons */
X (void) newcham(mtmp, (struct permonst *)0);
X
X /* regenerate monsters */
X if((!(moves%20) || regenerates(mdat)) && mtmp->mhp < mtmp->mhpmax)
X mtmp->mhp++;
X if(mtmp->mspec_used) mtmp->mspec_used--;
X
X /* polymorph lycanthropes */
X were_change(mtmp);
X
X if(mtmp->mfroz) {
X if (Hallucination) pmon(mtmp);
X return(0); /* frozen monsters don't do anything */
X }
X
X if(mtmp->msleep) /* there is a chance we will wake it */
X if(!disturb(mtmp)) return(0);
X
X /* not frozen or sleeping: wipe out texts written in the dust */
X wipe_engr_at(mtmp->mx, mtmp->my, 1);
X
X /* confused monsters get unconfused with small probability */
X if(mtmp->mconf && !rn2(50)) mtmp->mconf = 0;
X
X /* stunned monsters get un-stunned with larger probability */
X if(mtmp->mstun && !rn2(10)) mtmp->mstun = 0;
X
X /* some monsters teleport */
X if(mtmp->mflee && !rn2(40) && can_teleport(mdat) && !mtmp->iswiz) {
X rloc(mtmp);
X return(0);
X }
X if(mdat->mmove < rnd(6)) return(0);
X
X /* fleeing monsters might regain courage */
X if(mtmp->mflee && !mtmp->mfleetim
X && mtmp->mhp == mtmp->mhpmax && !rn2(25)) mtmp->mflee = 0;
X
X set_apparxy(mtmp);
X /* Must be done after you move and before the monster does. The
X * set_apparxy() call in m_move() doesn't suffice since the variables
X * inrange, etc... all depend on stuff set by set_apparxy().
X */
X
X /* The Wizard's prime directive */
X /* may teleport, so do it before inrange is set */
X if(mtmp->iswiz)
X (void) wiz_get_amulet(mtmp);
X
X inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
X (BOLT_LIM * BOLT_LIM));
X nearby = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) < 3);
X /* Note: if your image is displaced, the monster sees the Elbereth
X * at your displaced position, thus never attacking your displaced
X * position, but possibly attacking you by accident. If you are
X * invisible, it sees the Elbereth at your real position, thus never
X * running into you by accident but possibly attacking the spot
X * where it guesses you are.
X */
X if (Invis && !perceives(mdat)) {
X seescaryx = mtmp->mux;
X seescaryy = mtmp->muy;
X } else {
X seescaryx = u.ux;
X seescaryy = u.uy;
X }
X scared = (nearby && onscary(seescaryx, seescaryy, mtmp));
X
X if(scared && !mtmp->mflee) {
X#ifdef POLYSELF
X if (!sticks(uasmon))
X#endif
X unstuck(mtmp); /* monster lets go when fleeing */
X mtmp->mflee = 1;
X mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
X }
X
X#ifdef HARD /* Demonic Blackmail!!! */
X if(nearby && is_demon(mdat) && mtmp->mpeaceful && !mtmp->mtame) {
X if (mtmp->mux != u.ux || mtmp->muy != u.uy) {
X pline("%s whispers something to thin air.",
X cansee(mtmp->mux, mtmp->muy) ? Monnam(mtmp) : "It");
X#ifdef POLYSELF
X if (is_demon(uasmon)) rloc(mtmp);
X /* "Good hunting, brother" */
X else
X#endif
X if (is_lord(mdat) || is_prince(mdat)) {
X /* use is_lord instead of is_dlord */
X mtmp->minvis = 0;
X /* Why? For the same reason in real demon talk */
X pline("%s gets angry.", Xmonnam(mtmp));
X mtmp->mpeaceful = 0;
X /* since no way is an image going to pay it off */
X }
X } else if(demon_talk(mtmp)) return(1); /* you paid it off */
X }
X#endif
X
X/* Now the actual movement phase */
X
X if(!nearby || mtmp->mflee || scared ||
X mtmp->mconf || mtmp->mstun || (mtmp->minvis && !rn2(3)) ||
X (mdat->mlet == S_LEPRECHAUN && !u.ugold && (mtmp->mgold || rn2(2))) ||
X (is_wanderer(mdat) && !rn2(4)) || (Conflict && !mtmp->iswiz) ||
X (!mtmp->mcansee && !rn2(4)) || mtmp->mpeaceful) {
X
X tmp = m_move(mtmp, 0);
X nearby = (dist(mtmp->mx, mtmp->my) < 3); /* recalc */
X scared = (nearby && onscary(seescaryx, seescaryy, mtmp));
X switch (tmp) {
X
X case 0: /* no movement, but it can still attack you */
X case 3: /* absolutely no movement */
X /* for pets, case 0 and 3 are equivalent */
X /* During hallucination, monster appearance should
X * still change - even if it doesn't move.
X */
X if(Hallucination) pmon(mtmp);
X break;
X case 1: /* monster moved */
X if(!nearby && ranged_attk(mdat)) break;
X else if(mdat->mmove <= 12) return(0);
X break;
X case 2: /* monster died */
X return(1);
X }
X
X inrange = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) <=
X (BOLT_LIM * BOLT_LIM));
X if(scared && !mtmp->mflee) {
X mtmp->mflee = 1;
X mtmp->mfleetim = (rn2(7) ? rnd(10) : rnd(100));
X }
X }
X
X/* Now, attack the player if possible - one attack set per monst */
X
X if(inrange && !noattacks(mdat) &&
X !mtmp->mpeaceful && !mtmp->mtame && u.uhp > 0 && !scared && tmp != 3)
X if(mattacku(mtmp)) return(1); /* monster died (e.g. exploded) */
X
X#ifdef WORM
X if(mtmp->wormno && !mtmp->mtame) wormhit(mtmp);
X#endif
X
X /* extra movement for fast monsters */
X if(mdat->mmove-12 > rnd(12)) tmp = m_move(mtmp, 1);
X return(tmp == 2);
X}
X
Xstatic const char practical[] = { WEAPON_SYM, GEM_SYM, FOOD_SYM, 0 };
Xstatic const char magical[] = {
X AMULET_SYM, POTION_SYM, SCROLL_SYM, WAND_SYM, RING_SYM,
X#ifdef SPELLS
X SPBOOK_SYM,
X#endif
X 0 };
Xstatic const char indigestion[] = { BALL_SYM, ROCK_SYM, 0 };
X
X#ifdef POLYSELF
Xstatic boolean
Xitsstuck(mtmp)
Xregister struct monst *mtmp;
X{
X if (sticks(uasmon) && mtmp==u.ustuck && !u.uswallow) {
X kludge("%s cannot escape from you!", Monnam(mtmp));
X return(TRUE);
X }
X return(FALSE);
X}
X#endif
X
Xint
Xm_move(mtmp, after)
Xregister struct monst *mtmp;
Xregister int after;
X{
X register struct monst *mtmp2;
X register int nx,ny,omx,omy,appr,nearer,cnt,i,j;
X xchar gx,gy,nix,niy,chcnt;
X schar chi;
X boolean likegold=0, likegems=0, likeobjs=0, likemagic=0, conceals=0;
X boolean likerock=0, can_tunnel=0;
X struct permonst *ptr = mtmp->data;
X schar mmoved = 0; /* not strictly nec.: chi >= 0 will do */
X coord poss[9];
X long info[9];
X long flag;
X
X if(mtmp->mtrapped) {
X i = mintrap(mtmp);
X if(i == 2) return(2); /* it died */
X if(i == 1) return(0); /* still in trap, so didn't move */
X }
X if(mtmp->mhide &&
X (levl[mtmp->mx][mtmp->my].omask || levl[mtmp->mx][mtmp->my].gmask) &&
X rn2(10))
X return(0); /* do not leave hiding place */
X if(mtmp->meating) {
X mtmp->meating--;
X return(3); /* still eating */
X }
X
X set_apparxy(mtmp);
X /* where does mtmp think you are? */
X /* Not necessary if m_move called from here, but necessary in
X * other calls of m_move (i.e. leprechauns dodging)
X */
X can_tunnel = tunnels(ptr) &&
X#ifdef REINCARNATION
X dlevel != rogue_level &&
X#endif
X (!needspick(ptr) || m_carrying(mtmp, PICK_AXE));
X#ifdef WORM
X if(mtmp->wormno) goto not_special;
X#endif
X /* my dog gets a special treatment */
X if(mtmp->mtame) return( dog_move(mtmp, after) );
X
X /* likewise for shopkeeper */
X if(mtmp->isshk) {
X mmoved = shk_move(mtmp);
X if(mmoved == -2) return(2);
X if(mmoved >= 0) goto postmov;
X mmoved = 0; /* follow player outside shop */
X }
X
X /* and for the guard */
X if(mtmp->isgd) {
X mmoved = gd_move();
X goto postmov;
X }
X
X /* and the wiz already got special treatment */
X if(mtmp->iswiz) {
X mmoved = 0;
X goto postmov;
X }
X#if defined(ALTARS) && defined(THEOLOGY)
X /* and for the priest */
X if(mtmp->ispriest) {
X mmoved = pri_move(mtmp);
X if(mmoved == -2) return(2);
X if(mmoved >= 0) goto postmov;
X mmoved = 0;
X }
X#endif
X#ifdef MAIL
X if(ptr == &mons[PM_MAIL_DAEMON]) {
X if(flags.soundok && canseemon(mtmp))
X pline("\"I'm late!\"");
X mongone(mtmp);
X return(2);
X }
X#endif
X
X /* teleport if that lies in our nature */
X if(ptr == &mons[PM_TENGU] && !rn2(5)) {
X if(mtmp->mhp < 7 || mtmp->mpeaceful || rn2(2))
X rloc(mtmp);
X else
X mnexto(mtmp);
X mmoved = 1;
X goto postmov;
X }
X#ifdef WORM
Xnot_special:
X#endif
X if(!mtmp->mflee && u.uswallow && u.ustuck != mtmp) return(1);
X appr = 1;
X if(mtmp->mflee) appr = -1;
X if(mtmp->mconf || (Invis && !perceives(ptr)) || !mtmp->mcansee ||
X (mtmp->mpeaceful && !mtmp->isshk) || /* allow shks to follow */
X ((ptr->mlet == S_STALKER || ptr->mlet == S_BAT ||
X ptr->mlet == S_YLIGHT) && !rn2(3)))
X appr = 0;
X omx = mtmp->mx;
X omy = mtmp->my;
X gx = mtmp->mux;
X gy = mtmp->muy;
X if(ptr == &mons[PM_LEPRECHAUN] && appr == 1 && mtmp->mgold > u.ugold)
X appr = -1;
X
X if(can_track(ptr)) {
X register coord *cp;
X schar mroom;
X
X mroom = inroom(omx,omy);
X if(mroom < 0 || mroom != inroom(u.ux,u.uy)){
X cp = gettrack(omx,omy);
X if(cp){
X gx = cp->x;
X gy = cp->y;
X }
X }
X }
X
X#ifdef REINCARNATION
X if (dlevel != rogue_level)
X#endif
X {
X register int pctload = (curr_mon_load(mtmp) * 100) /
X max_mon_load(mtmp);
X
X /* look for gold or jewels nearby */
X likegold = (likes_gold(ptr) && pctload < 95);
X likegems = (likes_gems(ptr) && pctload < 85);
X likeobjs = (likes_objs(ptr) && pctload < 75);
X likemagic = (likes_magic(ptr) && pctload < 85);
X likerock = (throws_rocks(ptr) && pctload < 50);
X conceals = hides_under(ptr);
X }
X
X#define SRCHRADIUS 25
X
X { xchar mind = SRCHRADIUS; /* not too far away */
X register int dd;
X
X /* cut down the search radius if it thinks character is closer. */
X if(dist2(mtmp->mux, mtmp->muy, omx, omy) < SRCHRADIUS &&
X !mtmp->mtame && !mtmp->mpeaceful) mind /= 2;
X
X if(likegold){
X register struct gold *gold;
X
X for(gold = fgold; gold; gold = gold->ngold)
X if((dd = dist2(omx,omy,gold->gx,gold->gy)) < mind){
X mind = dd;
X gx = gold->gx;
X gy = gold->gy;
X }
X }
X if((likegems || likeobjs || likemagic || likerock || conceals)
X && (!in_shop(omx, omy) || (!rn2(25) && !mtmp->isshk))) {
X register struct obj *otmp;
X
X for(otmp = fobj; otmp; otmp = otmp->nobj)
X if((likeobjs && index(practical, otmp->olet)) ||
X (likemagic && index(magical, otmp->olet)) ||
X (likerock && otmp->otyp == BOULDER) ||
X (likegems && otmp->olet == GEM_SYM &&
X otmp->otyp < LAST_GEM + 5) ||
X (conceals && !cansee(otmp->ox,otmp->oy)) ||
X (ptr == &mons[PM_GELATINOUS_CUBE] &&
X !index(indigestion, otmp->olet))
X ) {
X if(can_carry(mtmp,otmp))
X if(ptr->mlet != S_UNICORN ||
X objects[otmp->otyp].g_val != 0)
X if((dd = dist2(omx,omy,otmp->ox,otmp->oy)) < mind){
X mind = dd;
X gx = otmp->ox;
X gy = otmp->oy;
X }
X }
X }
X if(mind < SRCHRADIUS && appr == -1) {
X if(dist2(omx,omy,mtmp->mux,mtmp->muy) < 10) {
X gx = mtmp->mux;
X gy = mtmp->muy;
X } else
X appr = 1;
X }
X }
X nix = omx;
X niy = omy;
X flag = ALLOW_TRAPS;
X if (mtmp->mpeaceful) flag |= (ALLOW_SANCT | ALLOW_SSM);
X else flag |= ALLOW_U;
X if (ptr->mlet == S_UNICORN) flag |= NOTONL;
X if (passes_walls(ptr)) flag |= (ALLOW_WALL | ALLOW_ROCK);
X if (can_tunnel) flag |= ALLOW_DIG;
X if (is_human(ptr)) flag |= ALLOW_SSM;
X if (is_undead(ptr)) flag |= NOGARLIC;
X if (throws_rocks(ptr)) flag |= ALLOW_ROCK;
X cnt = mfndpos(mtmp, poss, info, flag);
X chcnt = 0;
X chi = -1;
X
X for(i=0; i < cnt; i++) {
X nx = poss[i].x;
X ny = poss[i].y;
X
X for(j=0; j < MTSZ && j < cnt-1; j++)
X if(nx == mtmp->mtrack[j].x && ny == mtmp->mtrack[j].y)
X if(rn2(4*(cnt-j))) goto nxti;
X
X nearer = (dist2(nx,ny,gx,gy) < dist2(nix,niy,gx,gy));
X
X if((appr == 1 && nearer) || (appr == -1 && !nearer) ||
X !mmoved || (!appr && !rn2(++chcnt))) {
X nix = nx;
X niy = ny;
X chi = i;
X mmoved = 1;
X }
X nxti: ;
X }
X
X if(mmoved) {
X#ifdef POLYSELF
X if (mmoved==1 && (u.ux != nix || u.uy != niy) && itsstuck(mtmp))
X return(3);
X#endif
X if((info[chi] & ALLOW_U) || (nix == u.ux && niy == u.uy)) {
X mtmp->mux = u.ux;
X mtmp->muy = u.uy;
X return(0);
X }
X /* The monster may attack another based on 1 of 2 conditions:
X * 1 - He may be under the "conflict" influence.
X * 2 - He may mistake the monster for your (displaced) image.
X * Pets get taken care of above and shouldn't reach this code.
X */
X if((info[chi] & ALLOW_M) ||
X (nix == mtmp->mux && niy == mtmp->muy)) {
X mtmp2 =
X (levl[nix][niy].mmask ? m_at(nix,niy) : (struct monst *)0);
X if(mattackm(mtmp, mtmp2) == 1 && rn2(4) &&
X mtmp2->mlstmv != moves && mattackm(mtmp2, mtmp) == 2)
X return(2);
X return(3);
X }
X#ifdef WORM
X /* The square now has a worm segment and must keep its mmask */
X if (!mtmp->wormno)
X#endif
X levl[omx][omy].mmask = 0;
X levl[nix][niy].mmask = 1;
X mtmp->mx = nix;
X mtmp->my = niy;
X for(j = MTSZ-1; j > 0; j--)
X mtmp->mtrack[j] = mtmp->mtrack[j-1];
X mtmp->mtrack[0].x = omx;
X mtmp->mtrack[0].y = omy;
X#ifdef WORM
X if(mtmp->wormno) worm_move(mtmp);
X#endif
X } else {
X if(ptr->mlet == S_UNICORN && rn2(2)) {
X rloc(mtmp);
X return(1);
X }
X#ifdef WORM
X if(mtmp->wormno) worm_nomove(mtmp);
X#endif
X }
Xpostmov:
X if(mmoved == 1) {
X boolean canseeit = cansee(mtmp->mx, mtmp->my);
X boolean abstain = (mtmp->mpeaceful && !mtmp->mtame);
X
X if(mintrap(mtmp) == 2) return(2); /* he died */
X
X /* open a door, or crash through it, if you can */
X if(IS_DOOR(levl[mtmp->mx][mtmp->my].typ)
X && !passes_walls(ptr) /* doesn't need to open doors */
X && !amorphous(ptr) /* ditto */
X && !can_tunnel /* taken care of below */
X ) {
X struct rm *here = &levl[mtmp->mx][mtmp->my];
X boolean btrapped = (here->doormask & D_TRAPPED);
X
X if(here->doormask & D_LOCKED && mtmp->isshk) {
X /* can't lock out shk */
X if(btrapped) {
X here->doormask = D_NODOOR;
X if(mb_trapped(mtmp)) return(2);
X } else {
X if (flags.verbose) {
X if (canseeit)
X You("see a door being unlocked and opened.");
X else if (flags.soundok)
X You("hear a door being unlocked and opened.");
X }
X here->doormask = D_ISOPEN;
X }
X } else if (here->doormask == D_CLOSED &&
X !nohands(mtmp->data)) {
X if(btrapped) {
X here->doormask = D_NODOOR;
X if(mb_trapped(mtmp)) return(2);
X } else {
X if (flags.verbose) {
X if (canseeit)
X You("see a door being opened.");
X else if (flags.soundok)
X You("hear the sound of a door opening.");
X }
X here->doormask = D_ISOPEN;
X }
X } else if(here->doormask & (D_LOCKED | D_CLOSED)) {
X /* mfndpos guarantees monster is a giant */
X if(btrapped) {
X here->doormask = D_NODOOR;
X if(mb_trapped(mtmp)) return(2);
X } else {
X if (flags.verbose) {
X if (canseeit)
X You("see a door crash open.");
X else if (flags.soundok)
X You("hear the sound of a door crashing open.");
X }
X if (here->doormask & D_LOCKED && !rn2(2))
X here->doormask = D_NODOOR;
X else here->doormask = D_BROKEN;
X }
X }
X }
X /* Maybe a rock mole just ate something? */
X if(can_tunnel) if(!mdig_tunnel(mtmp)) return(2); /* died? */
X
X if(levl[mtmp->mx][mtmp->my].gmask == 1) {
X /* Maybe a rock mole just ate some gold */
X if(ptr == &mons[PM_ROCK_MOLE]) meatgold(mtmp);
X if(likegold && (!abstain || !rn2(10))) mpickgold(mtmp);
X }
X if(levl[mtmp->mx][mtmp->my].omask == 1) {
X /* Maybe a rock mole just ate some metal object */
X if(ptr == &mons[PM_ROCK_MOLE]) meatgold(mtmp);
X /* Maybe a cube ate just about anything */
X if(ptr == &mons[PM_GELATINOUS_CUBE]) meatobj(mtmp);
X
X if ((!abstain || !rn2(10))
X && (!in_shop(mtmp->mx, mtmp->my) || !rn2(25))) {
X if(likeobjs) mpickstuff(mtmp, practical);
X if(likemagic) mpickstuff(mtmp, magical);
X if(likerock || likegems) mpickgems(mtmp);
X }
X }
X if(mtmp->mhide) mtmp->mundetected = (levl[mtmp->mx][mtmp->my].omask
X || levl[mtmp->mx][mtmp->my].gmask);
X
X /* set also in domove(), hack.c */
X if(u.uswallow && mtmp == u.ustuck) {
X u.ux = mtmp->mx;
X u.uy = mtmp->my;
X if(mtmp->mx != mtmp->mdx || mtmp->my != mtmp->mdy) {
X swallowed(0);
X mtmp->mdx = mtmp->mx;
X mtmp->mdy = mtmp->my;
X }
X }
X }
X pmon(mtmp);
X return(mmoved);
X}
X
Xvoid
Xset_apparxy(mtmp) /* where does mtmp think you are standing? */
X register struct monst *mtmp;
X{
X#define notseen (Invis && !perceives(mtmp->data))
X/* add cases as required. eg. Displacement ... */
X register int disp = (notseen ? 1 : Displaced ? 2 : 0);
X
X/* without something like the following, invis. and displ. are too */
X/* powerful. */
X register boolean gotu =
X (notseen ? !rn2(3) : Displaced ? !rn2(4) : FALSE);
X
X/* Monsters which know where you are don't suddenly forget, if you
X didn't move away. */
X if (mtmp->mux==u.ux && mtmp->muy==u.uy) gotu = 1;
X
X/* your dog follows your smell */
X if(!disp || mtmp->mtame || gotu ||
X/* If invisible but not displaced, staying around gets you 'discovered' */
X (!Displaced && u.dx == 0 && u.dy == 0)) {
X mtmp->mux = u.ux;
X mtmp->muy = u.uy;
X }
X else do {
X mtmp->mux = u.ux - disp + rn2(2*disp+1);
X mtmp->muy = u.uy - disp + rn2(2*disp+1);
X } while((mtmp->mux != u.ux || mtmp->muy != u.uy) &&
X ( (!passes_walls(mtmp->data) &&
X (!ACCESSIBLE(levl[mtmp->mux][mtmp->muy].typ) ||
X (IS_DOOR(levl[mtmp->mux][mtmp->muy].typ) &&
X (levl[mtmp->mux][mtmp->muy].doormask & (D_LOCKED | D_CLOSED)) &&
X !amorphous(mtmp->data)
X ))
X ) ||
X (disp==1 && mtmp->mux == mtmp->mx && mtmp->muy == mtmp->my)
X )
X );
X}
END_OF_FILE
if test 20241 -ne `wc -c <'src/monmove.c'`; then
echo shar: \"'src/monmove.c'\" unpacked with wrong size!
fi
# end of 'src/monmove.c'
fi
if test -f 'src/read.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/read.c'\"
else
echo shar: Extracting \"'src/read.c'\" \(30625 characters\)
sed "s/^X//" >'src/read.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)read.c 3.0 88/04/13
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
Xboolean known;
X
Xstatic const char readable[] = { '#', SCROLL_SYM,
X#ifdef SPELLS
X SPBOOK_SYM,
X#endif
X 0 };
X
Xstatic void explode P((struct obj *));
Xstatic void do_class_genocide();
X
Xint
Xdoread() {
X register struct obj *scroll;
X register boolean confused = (Confusion != 0);
X
X known = FALSE;
X scroll = getobj(readable, "read"); /* "#-" added by GAN 10/22/86 */
X if(!scroll) return(0);
X
X /* below added to allow reading of fortune cookies */
X if(scroll->otyp == FORTUNE_COOKIE) {
X if(flags.verbose)
X You("break up the cookie and throw away the pieces.");
X outrumor(bcsign(scroll), TRUE);
X useup(scroll);
X return(1);
X } else
X if(scroll->olet != SCROLL_SYM
X#ifdef SPELLS
X && scroll->olet != SPBOOK_SYM
X#endif
X ) {
X pline("That is a silly thing to read.");
X return(0);
X }
X
X if(Blind)
X#ifdef SPELLS
X if (scroll->olet == SPBOOK_SYM) {
X pline("Being blind, you cannot read the mystic runes.");
X return(0);
X } else
X#endif
X if (!scroll->dknown) {
X pline("Being blind, you cannot read the formula on the scroll.");
X return(0);
X }
X#ifdef SPELLS
X if(scroll->olet == SPBOOK_SYM) {
X if(confused) {
X You("cannot grasp the meaning of this tome.");
X useup(scroll);
X return(0);
X } else
X return(study_book(scroll));
X }
X#endif
X if(scroll->otyp != SCR_BLANK_PAPER) {
X if(Blind)
X pline("As you pronounce the formula on it, the scroll disappears.");
X else
X pline("As you read the scroll, it disappears.");
X if(confused) {
X if (Hallucination)
X pline("Being so trippy, you screw up...");
X else
X pline("Being confused, you mispronounce the magic words...");
X }
X }
X if(!seffects(scroll)) {
X if(!objects[scroll->otyp].oc_name_known) {
X if(known && !confused) {
X makeknown(scroll->otyp);
X more_experienced(0,10);
X } else if(!objects[scroll->otyp].oc_uname)
X docall(scroll);
X }
X if(!(scroll->otyp == SCR_BLANK_PAPER) || confused)
X useup(scroll);
X }
X return(1);
X}
X
Xstatic void
Xstripspe(obj)
Xregister struct obj *obj;
X{
X if (obj->blessed) pline(nothing_happens);
X else {
X if (obj->spe > 0) {
X obj->spe = 0;
X Your("%s vibrates briefly.",xname(obj));
X } else pline(nothing_happens);
X }
X}
X
Xstatic void
Xp_glow1(otmp)
Xregister struct obj *otmp;
X{
X Your("%s %s briefly.", xname(otmp),
X Blind ? "vibrates" : "glows");
X}
X
Xstatic void
Xp_glow2(otmp,color)
Xregister struct obj *otmp;
Xregister char *color;
X{
X Your("%s %s%s for a moment.",
X xname(otmp),
X Blind ? "vibrates" : "glows ",
X Blind ? "" : Hallucination ? hcolor() : color);
X}
X
Xint
Xseffects(sobj)
Xregister struct obj *sobj;
X{
X register int cval = 0;
X register boolean confused = (Confusion != 0);
X
X switch(sobj->otyp) {
X#ifdef MAIL
X case SCR_MAIL:
X known = TRUE;
X if (sobj->spe)
X pline("This seems to be junk mail addressed to the finder of the Eye of Larn.");
X /* note to the puzzled: the game Larn actually sends you junk
X * mail if you win!
X */
X else readmail(/* scroll */);
X break;
X#endif
X case SCR_ENCHANT_ARMOR:
X {
X register struct obj *otmp = some_armor();
X register schar s = 0;
X if(!otmp) {
X strange_feeling(sobj,
X !Blind ? "Your skin glows then fades." :
X "Your skin feels warm for a moment.");
X return(1);
X }
X if(confused) {
X if(Blind)
X Your("%s feels warm for a moment.",
X xname(otmp));
X else
X Your("%s is covered by a %s %s %s!",
X xname(otmp),
X sobj->cursed ? "mottled" : "shimmering",
X Hallucination ? hcolor() :
X sobj->cursed ? black : "gold",
X sobj->cursed ? "glow" :
X (is_shield(otmp) ? "layer" : "shield"));
X if(!(otmp->rustfree))
X otmp->rustfree = !(sobj->cursed);
X break;
X }
X#ifdef TOLKIEN
X if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
X#else
X if((otmp->spe > 3)
X#endif
X && rn2(otmp->spe) && !sobj->cursed) {
X Your("%s violently %s%s for a while, then evaporates.",
X xname(otmp),
X Blind ? "vibrates" : "glows ",
X Blind ? "" : Hallucination ? hcolor() : silver);
X if(is_cloak(otmp)) (void) Cloak_off();
X if(is_boots(otmp)) (void) Boots_off();
X if(is_helmet(otmp)) (void) Helmet_off();
X if(is_gloves(otmp)) (void) Gloves_off();
X if(is_shield(otmp)) (void) Shield_off();
X if(otmp == uarm) (void) Armor_gone();
X useup(otmp);
X break;
X }
X s = sobj->blessed ? rnd(3) : sobj->cursed ? -1 : 1;
X Your("%s %s%s for a %s.",
X xname(otmp),
X Blind ? "vibrates" : "glows ",
X Blind ? "" : Hallucination ? hcolor() :
X sobj->cursed ? black : silver,
X (s*s>1) ? "while" : "moment");
X otmp->cursed = sobj->cursed;
X otmp->blessed = sobj->blessed;
X otmp->spe += s;
X adj_abon(otmp, s);
X break;
X }
X case SCR_DESTROY_ARMOR:
X { register struct obj *otmp = some_armor();
X
X if(confused) {
X if(!otmp) {
X strange_feeling(sobj,"Your bones itch.");
X return(1);
X }
X p_glow2(otmp,purple);
X otmp->rustfree = sobj->cursed;
X break;
X }
X if(!sobj->cursed || (sobj->cursed && (!otmp || !otmp->cursed))) {
X if(!destroy_arm(otmp)) {
X strange_feeling(sobj,"Your skin itches.");
X return(1);
X }
X } else { /* armor and scroll both cursed */
X Your("%s vibrates", xname(otmp));
X otmp->spe--;
X make_stunned(HStun + rn1(10, 10), TRUE);
X }
X }
X break;
X case SCR_CONFUSE_MONSTER:
X#ifdef SPELLS
X case SPE_CONFUSE_MONSTER:
X#endif
X if(u.usym != S_HUMAN || sobj->cursed) {
X if(!HConfusion) You("feel confused.");
X make_confused(HConfusion + rnd(100),FALSE);
X } else if(confused) {
X if(!sobj->blessed) {
X Your("%s begin to %s%s.",
X makeplural(body_part(HAND)),
X Blind ? "tingle" : "glow ",
X Blind ? "" : Hallucination ? hcolor() : purple);
X make_confused(HConfusion + rnd(100),FALSE);
X } else {
X pline("A %s%s surrounds your %s.",
X Blind ? "" : Hallucination ? hcolor() : red,
X Blind ? "faint buzz" : " glow",
X body_part(HEAD));
X make_confused(0L,TRUE);
X }
X } else {
X Your("%s%s %s.",
X makeplural(body_part(HAND)),
X Blind ? "" : " begin to glow",
X Blind ? "tingle" : Hallucination ? hcolor() : red);
X u.umconf = 1;
X }
X break;
X case SCR_SCARE_MONSTER:
X#ifdef SPELLS
X case SPE_CAUSE_FEAR:
X#endif
X { register int ct = 0;
X register struct monst *mtmp;
X
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(cansee(mtmp->mx,mtmp->my)) {
X if(confused || sobj->cursed)
X mtmp->mflee = mtmp->mfroz = mtmp->msleep = 0;
X else
X if (! resist(mtmp, sobj->olet, 0, NOTELL))
X mtmp->mflee = 1;
X if(!mtmp->mtame) ct++; /* pets don't laugh at you */
X }
X if(!ct)
X You("hear %s in the distance.",
X (confused || sobj->cursed) ? "sad wailing" :
X "maniacal laughter");
X else
X#ifdef SPELLS
X if(sobj->otyp == SCR_SCARE_MONSTER)
X#endif
X You("hear %s close by.",
X (confused || sobj->cursed) ? "sad wailing" :
X "maniacal laughter");
X break;
X }
X case SCR_BLANK_PAPER:
X if(confused)
X You("try to read the strange patterns on this scroll, but it disappears.");
X else {
X pline("This scroll seems to be blank.");
X known = TRUE;
X }
X break;
X case SCR_REMOVE_CURSE:
X#ifdef SPELLS
X case SPE_REMOVE_CURSE:
X#endif
X { register struct obj *obj;
X if(confused)
X if (Hallucination)
X You("feel the power of the Force against you!");
X else
X You("feel like you need some help.");
X else
X if (Hallucination)
X You("feel in touch with the Universal Oneness.");
X else
X You("feel like someone is helping you.");
X
X if(sobj->cursed) pline("The scroll disintegrates.");
X else {
X for(obj = invent; obj ; obj = obj->nobj)
X if(sobj->blessed || obj->owornmask ||
X (obj->otyp == LOADSTONE)) {
X if(confused) blessorcurse(obj, 2);
X else obj->cursed = 0;
X }
X }
X if(Punished && !confused) unpunish();
X break;
X }
X case SCR_CREATE_MONSTER:
X#if defined(WIZARD) || defined(EXPLORE_MODE)
X if (wizard || discover)
X known = TRUE;
X#endif /* WIZARD || EXPLORE_MODE */
X#ifdef SPELLS
X case SPE_CREATE_MONSTER:
X#endif
X { register int cnt = 1;
X
X if(!rn2(73)) cnt += rnd(4);
X if(confused || sobj->cursed) cnt += 12;
X while(cnt--) {
X#if defined(WIZARD) || defined(EXPLORE_MODE)
X if(wizard || discover)
X if (!create_particular())
X#endif /* WIZARD || EXPLORE_MODE */
X (void) makemon (confused ? &mons[PM_ACID_BLOB] :
X (struct permonst *) 0, u.ux, u.uy);
X }
X break;
X }
X/* break; /*NOTREACHED*/
X case SCR_ENCHANT_WEAPON:
X if(uwep && (uwep->olet == WEAPON_SYM || uwep->olet == PICK_AXE)
X && confused) {
X /* olet check added 10/25/86 GAN */
X if(Blind)
X Your("weapon feels warm for a moment.");
X else
X Your("%s covered by a %s %s %s!",
X aobjnam(uwep, "are"),
X sobj->cursed ? "mottled" : "shimmering",
X Hallucination ? hcolor() :
X sobj->cursed ? purple : "gold",
X sobj->cursed ? "glow" : "shield");
X uwep->rustfree = !(sobj->cursed);
X } else return !chwepon(sobj, bcsign(sobj)*2+1);
X break;
X case SCR_TAMING:
X#ifdef SPELLS
X case SPE_CHARM_MONSTER:
X#endif
X { register int i,j;
X register int bd = confused ? 5 : 1;
X register struct monst *mtmp;
X
X for(i = -bd; i <= bd; i++) for(j = -bd; j <= bd; j++)
X if(levl[u.ux+i][u.uy+j].mmask && (mtmp = m_at(u.ux+i, u.uy+j))) {
X if(sobj->cursed) {
X if(!mtmp->mtame) mtmp->mpeaceful = 0;
X } else {
X if (mtmp->isshk) {
X if (!mtmp->mpeaceful) {
X kludge("%s calms down.", Monnam(mtmp));
X mtmp->mpeaceful = 1;
X }
X } else if(!resist(mtmp, sobj->olet, 0, NOTELL))
X (void) tamedog(mtmp, (struct obj *) 0);
X }
X }
X break;
X }
X case SCR_GENOCIDE:
X You("have found a scroll of genocide!");
X#ifdef SPELLS
X case SPE_GENOCIDE:
X#endif
X known = TRUE;
X if (sobj->blessed) do_class_genocide();
X else do_genocide(!sobj->cursed | (2 * !!Confusion));
X break;
X case SCR_LIGHT:
X if(!Blind) known = TRUE;
X litroom(!confused && !sobj->cursed);
X break;
X case SCR_TELEPORTATION:
X if(confused || sobj->cursed) level_tele();
X else {
X register int uroom = inroom(u.ux, u.uy);
X
X if (sobj->blessed && !Teleport_control) {
X known = TRUE;
X pline("Do you wish to teleport? ");
X if (yn()=='n') break;
X }
X tele();
X if(uroom != inroom(u.ux, u.uy)) known = TRUE;
X if(Teleport_control) known = TRUE;
X }
X break;
X case SCR_GOLD_DETECTION:
X if (confused || sobj->cursed) return(trap_detect(sobj));
X else return(gold_detect(sobj));
X case SCR_FOOD_DETECTION:
X#ifdef SPELLS
X case SPE_DETECT_FOOD:
X#endif
X if (food_detect(sobj))
X return(1); /* nothing detected */
X break;
X case SCR_IDENTIFY:
X /* known = TRUE; */
X if(confused)
X You("identify this as an identify scroll.");
X else
X pline("This is an identify scroll.");
X if (sobj->blessed || (!sobj->cursed && !rn2(5)))
X cval = rn2(5);
X /* Note: if rn2(5)==0, identify all items */
X else cval = 1;
X useup(sobj);
X makeknown(SCR_IDENTIFY);
X#ifdef SPELLS
X case SPE_IDENTIFY:
X#endif
X if(!confused)
X while(invent && !ggetobj("identify", identify, cval));
X return(1);
X case SCR_CHARGING:
X { register struct obj *obj;
X register int n;
X if (confused) {
X You("feel charged up!");
X break;
X }
X known = TRUE;
X pline("This is a charging scroll.");
X obj = getobj("0#", "charge");
X if (!obj) break;
X if (obj->olet != WAND_SYM) {
X switch(obj->otyp) {
X case MAGIC_MARKER:
X if (sobj->cursed) stripspe(obj);
X else if (sobj->blessed) {
X n = obj->spe;
X if (n < 50) obj->spe = 50;
X if (n >= 50 && n < 75) obj->spe = 75;
X if (n >= 75) obj->spe += 10;
X p_glow2(obj,blue);
X } else {
X if (obj->spe < 50) obj->spe = 50;
X else obj->spe++;
X p_glow2(obj,white);
X }
X break;
X case LAMP:
X if (sobj->cursed) stripspe(obj);
X else if (sobj->blessed) {
X n = rn2(11);
X if (obj->spe < n) obj->spe = n;
X else obj->spe += rnd(3);
X p_glow2(obj,blue);
X } else {
X obj->spe++;
X p_glow1(obj);
X }
X break;
X case MAGIC_LAMP:
X if (sobj->cursed) stripspe(obj);
X else if (sobj->blessed) {
X if (obj->spe == 1) pline(nothing_happens);
X else {
X obj->spe = 1;
X p_glow1(obj);
X }
X } else {
X if (obj->spe == 1) pline(nothing_happens);
X else {
X n = rn2(2);
X if (!n) {
X obj->spe = 1;
X p_glow1(obj);
X } else pline(nothing_happens);
X }
X }
X break;
X case CRYSTAL_BALL:
X if (sobj->cursed) stripspe(obj);
X else if (sobj->blessed) {
X obj->spe = 6;
X p_glow2(obj,blue);
X } else {
X if (obj->spe < 5) {
X obj->spe++;
X p_glow1(obj);
X } else pline(nothing_happens);
X }
X break;
X case BAG_OF_TRICKS:
X if (sobj->cursed) stripspe(obj);
X else if (sobj->blessed) {
X if (obj->spe <= 10)
X obj->spe += (5 + rnd(10));
X else obj->spe += (5 + rnd(5));
X p_glow2(obj,blue);
X } else {
X obj->spe += rnd(5);
X p_glow1(obj);
X }
X break;
X default:
X pline("The scroll %s%s, and disintegrates.",
X Blind ? "vibrates violently" : "glows ",
X Blind ? "" : Hallucination ? hcolor() : "dark red");
X } /* switch */
X break;
X }
X else {
X if (obj->otyp == WAN_WISHING) {
X if (obj->recharged) { /* recharged once already? */
X explode(obj);
X break;
X }
X if (sobj->cursed) stripspe(obj);
X else if (sobj->blessed) {
X if (obj->spe != 3) {
X obj->spe = 3;
X p_glow2(obj,blue);
X } else {
X explode(obj);
X break;
X }
X } else {
X if (obj->spe < 3) {
X obj->spe++;
X p_glow2(obj,blue);
X } else pline(nothing_happens);
X }
X obj->recharged = 1; /* another recharging disallowed */
X }
X else {
X if (sobj->cursed) stripspe(obj);
X else if (sobj->blessed) {
X if (objects[obj->otyp].bits & NODIR) {
X n = rn1(5,11);
X if (obj->spe < n) obj->spe = n;
X else obj->spe++;
X }
X else {
X n = rn1(5,4);
X if (obj->spe < n) obj->spe = n;
X else obj->spe++;
X }
X p_glow2(obj,blue);
X } else {
X obj->spe++;
X p_glow1(obj);
X }
X break;
X }
X }
X }
X break;
X case SCR_MAGIC_MAPPING:
X known = TRUE;
X pline("On this scroll %s a map.", confused ? "was" : "is");
X#ifdef SPELLS
X case SPE_MAGIC_MAPPING:
X#endif
X cval = (sobj->cursed && !confused);
X if(cval) HConfusion = 1; /* to screw up map */
X do_mapping();
X if(cval) {
X HConfusion = 0; /* restore */
X pline("Unfortunately, it is of a very poor quality.");
X }
X break;
X case SCR_AMNESIA:
X { register int zx, zy;
X
X known = TRUE;
X for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
X if(!confused || sobj->cursed || rn2(7))
X if(!cansee(zx,zy))
X levl[zx][zy].seen = levl[zx][zy].new =
X levl[zx][zy].scrsym = 0;
X docrt();
X if (Hallucination) /* Ommmmmm! */
X Your("mind releases itself from mundane concerns.");
X else if (!strncmp(plname, "Maud", 4))
X pline("As your mind turns inward on itself, you forget everything else.");
X else if (flags.female)
X pline("Who was that Maud person anyway?");
X else
X pline("Thinking of Maud you forget everything else.");
X#ifdef SPELLS
X if(!sobj->blessed) losespells();
X#endif
X break;
X }
X case SCR_FIRE:
X { register int num;
X register struct monst *mtmp;
X/*
X * Note: Modifications have been made as of 3.0 to allow for some damage
X * under all potential cases.
X */
X cval = bcsign(sobj);
X useup(sobj);
X makeknown(SCR_FIRE);
X if(confused) {
X if(Fire_resistance) {
X shieldeff(u.ux, u.uy);
X if(!Blind)
X pline("Oh, look, what a pretty fire in your %s.",
X makeplural(body_part(HAND)));
X else You("feal a pleasant warmth in your %s.",
X makeplural(body_part(HAND)));
X } else {
X pline("The scroll catches fire and you burn your %s.",
X makeplural(body_part(HAND)));
X losehp(1, "scroll of fire");
X }
X return(1);
X }
X pline("The scroll erupts in a tower of flame!");
X num = rnd(6) - 3 * cval;
X if(num <= 0 || Fire_resistance) {
X shieldeff(u.ux, u.uy);
X You("are uninjured.");
X } else {
X u.uhpmax -= num;
X losehp(num, "scroll of fire");
X }
X destroy_item(SCROLL_SYM, AD_FIRE);
X#ifdef SPELLS
X destroy_item(SPBOOK_SYM, AD_FIRE);
X#endif
X destroy_item(POTION_SYM, AD_FIRE);
X
X num = (2*(rn1(3, 3) + 2 * cval) + 1)/3;
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X if(dist(mtmp->mx,mtmp->my) < 3) {
X if (resists_fire(mtmp->data)) continue;
X if (u.uswallow) {
X if (mtmp != u.ustuck) continue;
X pline("%s gets heartburn.", Monnam(u.ustuck));
X num *= 2;
X }
X mtmp->mhp -= num; /* No saving throw! */
X if(resists_cold(mtmp->data))
X mtmp->mhp -= 3*num;
X if(mtmp->mhp < 1) {
X killed(mtmp);
X break; /* primitive */
X }
X }
X }
X return(1);
X }
X case SCR_PUNISHMENT:
X known = TRUE;
X if(confused || sobj->blessed) {
X You("feel guilty.");
X break;
X }
X punish(sobj);
X break;
X default:
X impossible("What weird effect is this? (%u)", sobj->otyp);
X }
X return(0);
X}
X
Xstatic void
Xexplode(obj)
Xregister struct obj *obj;
X{
X Your("%s vibrates violently, and explodes!",xname(obj));
X bell();
X losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand");
X useup(obj);
X}
X
Xint
Xidentify(otmp) /* also called by newmail() */
X register struct obj *otmp;
X{
X makeknown(otmp->otyp);
X otmp->known = otmp->dknown = otmp->bknown = 1;
X prinv(otmp);
X return(1);
X}
X
Xvoid
Xlitroom(on)
Xregister boolean on;
X{
X register int zx,zy;
X
X /* first produce the text (provided he is not blind) */
X if(Blind) goto do_it;
X if(!on) {
X if(u.uswallow || is_maze_lev || levl[u.ux][u.uy].typ == CORR ||
X !levl[u.ux][u.uy].lit) {
X pline("It seems even darker in here than before.");
X return;
X } else
X pline("It suddenly becomes dark in here.");
X } else {
X if(u.uswallow){
X pline("%s's stomach is lit.", Monnam(u.ustuck));
X return;
X }
X if(is_maze_lev){
X pline(nothing_happens);
X return;
X }
X if(levl[u.ux][u.uy].typ == CORR) {
X pline("The corridor lights up around you, then fades.");
X return;
X } else if(levl[u.ux][u.uy].lit) {
X pline("The light here seems better now.");
X return;
X } else
X pline("The room is lit.");
X }
X
Xdo_it:
X if(levl[u.ux][u.uy].lit == on)
X return;
X if (inroom(u.ux,u.uy) < 0)
X return;
X getcorners(&seelx,&seehx,&seely,&seehy,&seelx2,&seehx2,&seely2,&seehy2);
X
X for(zy = seely; zy <= seehy; zy++)
X for(zx = seelx; zx <= seehx; zx++) {
X levl[zx][zy].lit = on;
X if(!Blind && dist(zx,zy) > 2)
X if(on) prl(zx,zy); else nosee(zx,zy);
X }
X for(zy = seely2; zy <= seehy2; zy++)
X for(zx = seelx2; zx <= seehx2; zx++) {
X levl[zx][zy].lit = on;
X if(!Blind && dist(zx,zy) > 2)
X if(on) prl(zx,zy); else nosee(zx,zy);
X }
X if(!on) seehx = 0;
X}
X
Xstatic void
Xdo_class_genocide()
X{
X register int i, j, immunecnt, gonecnt, goodcnt;
X char buf[BUFSZ];
X
X for(j=0; ; j++) {
X if (j >= 5) {
X pline(thats_enough_tries);
X return;
X }
X pline("What class of monsters do you wish to genocide? [type a letter] ");
X do {
X getlin(buf);
X } while (buf[0]=='\033' || strlen(buf) != 1);
X immunecnt = gonecnt = goodcnt = 0;
X for(i=0; mons[i].mlet; i++) {
X if(mons[i].mlet == buf[0]) {
X if (!(mons[i].geno & G_GENO)) immunecnt++;
X else if(mons[i].geno & G_GENOD) gonecnt++;
X else goodcnt++;
X }
X }
X if (!goodcnt && buf[0] != S_HUMAN) {
X if (gonecnt)
X pline("All such monsters are already nonexistent.");
X else if (immunecnt)
X You("aren't permitted to genocide such monsters.");
X else
X pline("That symbol does not represent any monster.");
X continue;
X }
X for(i=0; mons[i].mlet; i++) {
X if(mons[i].mlet == buf[0]) {
X register struct monst *mtmp, *mtmp2;
X char *n = makeplural(mons[i].mname);
X
X if (&mons[i]==player_mon() || ((mons[i].geno & G_GENO)
X && !(mons[i].geno & G_GENOD))) {
X /* This check must be first since player monsters might
X * have G_GENOD or !G_GENO.
X */
X pline("Wiped out all %s.", n);
X if (&mons[i] == player_mon()) {
X u.uhp = -1;
X killer = "scroll of genocide";
X#ifdef POLYSELF
X if (u.umonnum >= 0)
X You("feel dead inside.");
X else
X#endif
X done("died");
X }
X /* for simplicity (and fairness) let's avoid
X * alignment changes here...
X */
X#ifdef POLYSELF
X if (i==u.umonnum) rehumanize();
X#endif
X mons[i].geno |= G_GENOD;
X for(mtmp = fmon; mtmp; mtmp = mtmp2) {
X mtmp2 = mtmp->nmon;
X if(mtmp->data == &mons[i])
X mondead(mtmp);
X }
X } else if (mons[i].geno & G_GENOD)
X pline("All %s are already nonexistent.", n);
X else
X You("aren't permitted to genocide %s%s.",
X i == PM_WIZARD_OF_YENDOR ? "the " : "",
X type_is_pname(&mons[i]) ? mons[i].mname : n);
X }
X }
X return;
X }
X}
X
X#define REALLY 1
X#define PLAYER 2
Xvoid
Xdo_genocide(how)
Xint how;
X/* 0 = no genocide; create monsters (cursed scroll) */
X/* 1 = normal genocide */
X/* 3 = forced genocide of player */
X{
X char buf[BUFSZ];
X register int i, j, killplayer = 0;
X register struct permonst *ptr;
X register struct monst *mtmp, *mtmp2;
X
X if (how & PLAYER) {
X ptr = player_mon();
X Strcpy(buf, ptr->mname);
X killplayer++;
X } else {
X for(j = 0; ; j++) {
X if(j >= 5) {
X pline(thats_enough_tries);
X return;
X }
X pline("What monster do you want to genocide? [type the name] ");
X getlin(buf);
X
X if(strlen(buf) && (!strncmp(buf, pl_character, PL_CSIZ))) {
X /* Note: pl_character starts with capitals and player_mon does not */
X ptr = player_mon();
X killplayer++;
X goto deadmeat;
X } else {
X i = name_to_mon(buf);
X if(i == -1 || (mons[i].geno & G_GENOD)) {
X pline("Such creatures do not exist in this world.");
X continue;
X }
X ptr = &mons[i];
X if (ptr == player_mon()) {
X killplayer++;
X goto deadmeat;
X }
X if (is_human(ptr)) adjalign(-sgn(u.ualigntyp));
X if (is_demon(ptr)) adjalign(sgn(u.ualigntyp));
X
X if(!(ptr->geno & G_GENO)) {
X if(flags.soundok) {
X if(flags.verbose)
X pline("A thunderous voice booms though the caverns:");
X pline("\"No, mortal! That will not be done.\"");
X }
X continue;
X }
X break;
X }
X }
X }
Xdeadmeat:
X if (Hallucination) {
X#ifdef POLYSELF
X if (u.umonnum != -1)
X Strcpy(buf,uasmon->mname);
X else
X#endif
X {
X Strcpy(buf, pl_character);
X buf[0] += 'a' - 'A';
X }
X } else Strcpy(buf,ptr->mname); /* make sure we have standard singular */
X if (how & REALLY) {
X pline("Wiped out all %s.", makeplural(buf));
X if(killplayer) {
X u.uhp = -1;
X killer = "genocide spell";
X#ifdef POLYSELF
X /* A polymorphed character will die as soon as he is rehumanized. */
X if(u.umonnum >= 0) You("feel dead inside.");
X else
X#endif
X done("died");
X return;
X }
X#ifdef POLYSELF
X else if ((how & REALLY) && ptr == &mons[u.umonnum]) rehumanize();
X#endif
X ptr->geno |= G_GENOD;
X for(mtmp = fmon; mtmp; mtmp = mtmp2) {
X mtmp2 = mtmp->nmon;
X if(mtmp->data == ptr)
X mondead(mtmp);
X }
X } else {
X pline("Sent in some %s.", makeplural(buf));
X j = rnd(3) + 3;
X for(i=1; i<=j; i++)
X (void) makemon(ptr, u.ux, u.uy);
X }
X}
X
Xstatic void
Xshow_map_spot(x, y)
Xregister int x, y;
X{
X register struct rm *lev;
X register int num;
X
X if((Confusion != 0) && rn2(7)) return;
X lev = &(levl[x][y]);
X if((num = lev->typ) == 0) return;
X
X if(num == SCORR) {
X lev->typ = CORR;
X lev->scrsym = CORR_SYM;
X /*
X * magic mapping shouldn't find secret doors,
X * especially on the stronghold level
X */
X } else if(lev->seen) return;
X if(num != ROOM)
X {
X lev->seen = lev->new = 1;
X if(lev->scrsym == STONE_SYM || !lev->scrsym)
X newsym(x, y);
X else on_scr(x, y);
X }
X}
X
Xvoid
Xdo_mapping() {
X register int zx, zy;
X
X for(zy = 0; zy < ROWNO; zy++)
X for(zx = 0; zx < COLNO; zx++)
X show_map_spot(zx, zy);
X}
X
Xvoid
Xdo_vicinity_map() {
X register int zx, zy;
X
X for(zy = (u.uy-5 < 0 ? 0 : u.uy-5);
X zy < (u.uy+6 > ROWNO ? ROWNO : u.uy+6); zy++)
X for(zx = (u.ux-9 < 0 ? 0 : u.ux-9);
X zx < (u.ux+10 > COLNO ? COLNO : u.ux+10); zx++)
X show_map_spot(zx, zy);
X}
X
Xint
Xdestroy_arm(atmp)
Xregister struct obj *atmp;
X{
X register struct obj *otmp;
X
X if((otmp = uarmc) && (!atmp || atmp == uarmc)) {
X Your("cloak crumbles and turns to dust!");
X (void) Cloak_off();
X useup(otmp);
X } else if((otmp = uarm) && (!atmp || atmp == uarm)) {
X Your("armor turns to dust and falls to the floor!");
X (void) Armor_gone();
X useup(otmp);
X#ifdef SHIRT
X } else if((otmp = uarmu) && (!atmp || atmp == uarmu)) {
X Your("shirt crumbles into tiny threads and falls apart!");
X useup(otmp);
X#endif
X } else if((otmp = uarmh) && (!atmp || atmp == uarmh)) {
X Your("helmet turns to dust and is blown away!");
X (void) Helmet_off();
X useup(otmp);
X } else if((otmp = uarmg) && (!atmp || atmp == uarmg)) {
X Your("gloves vanish!");
X (void) Gloves_off();
X useup(otmp);
X selftouch("You");
X } else if((otmp = uarmf) && (!atmp || atmp == uarmf)) {
X Your("boots disintegrate!");
X (void) Boots_off();
X useup(otmp);
X } else if((otmp =uarms) && (!atmp || atmp == uarms)) {
X Your("shield crumbles away!");
X (void) Shield_off();
X useup(otmp);
X } else return(0); /* could not destroy anything */
X
X return(1);
X}
X
X/* the detections are pulled out so they can */
X/* also be used in the crystal ball routine */
X/* returns 1 if nothing was detected */
X/* returns 0 if something was detected */
Xint
Xtrap_detect(sobj)
Xregister struct obj *sobj;
X/* sobj is null if crystal ball, *scroll if gold detection scroll */
X{
X register struct trap *ttmp;
X register struct obj *obj;
X register int door;
X boolean found = FALSE;
X coord cc;
X
X for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap) {
X if(ttmp->tx != u.ux || ttmp->ty != u.uy)
X goto outtrapmap;
X else found = TRUE;
X }
X for(obj = fobj; obj; obj = obj->nobj) {
X if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped)
X if (obj->ox != u.ux || obj->oy != u.uy)
X goto outtrapmap;
X else found = TRUE;
X }
X for(door=0; door<=doorindex; door++) {
X cc = doors[door];
X if (levl[cc.x][cc.y].doormask & D_TRAPPED)
X if (cc.x != u.ux || cc.x != u.uy)
X goto outtrapmap;
X else found = TRUE;
X }
X if(!found) {
X char buf[42];
X Sprintf(buf, "Your %s stop itching.",
X makeplural(body_part(TOE)));
X strange_feeling(sobj,buf);
X return(1);
X }
X /* traps exist, but only under me - no separate display required */
X Your("%s itch.", makeplural(body_part(TOE)));
X return(0);
Xouttrapmap:
X cls();
X#define SYMBOL (uchar)(Hallucination ? rndobjsym() : \
X (sobj && sobj->cursed) ? GOLD_SYM : TRAP_SYM)
X#define AT Hallucination || (sobj && sobj->cursed) ? AT_OBJ : AT_MAP
X for(ttmp = ftrap; ttmp; ttmp = ttmp->ntrap)
X at(ttmp->tx, ttmp->ty, SYMBOL, AT);
X for(obj = fobj; obj; obj = obj->nobj) {
X if ((obj->otyp==LARGE_BOX || obj->otyp==CHEST) && obj->otrapped)
X at(obj->ox, obj->oy, SYMBOL, AT);
X }
X for(door=0; door<=doorindex; door++) {
X cc = doors[door];
X if (levl[cc.x][cc.y].doormask & D_TRAPPED)
X at(cc.x, cc.y, SYMBOL, AT);
X }
X#undef SYMBOL
X#undef AT
X prme();
X if (sobj && sobj->cursed)
X You("feel very greedy.");
X else
X You("feel entrapped.");
X more();
X docrt();
X return(0);
X}
X
Xint
Xgold_detect(sobj)
Xregister struct obj *sobj;
X{
X register struct gold *gtmp;
X
X if(!fgold) {
X if(sobj)
X strange_feeling(sobj, "You feel materially poor.");
X return(1);
X } else {
X known = TRUE;
X for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
X if(gtmp->gx != u.ux || gtmp->gy != u.uy)
X goto outgoldmap;
X /* only under me - no separate display required */
X You("notice some gold between your %s.",
X makeplural(body_part(FOOT)));
X return(0);
X outgoldmap:
X cls();
X for(gtmp = fgold; gtmp; gtmp = gtmp->ngold)
X at( gtmp->gx, gtmp->gy,
X (uchar)(Hallucination ? rndobjsym() : GOLD_SYM),
X AT_OBJ);
X prme();
X You("feel very greedy, and sense gold!");
X more();
X docrt();
X }
X return(0);
X}
X
X/* food_detection is pulled out so that it */
X/* can also be used in the crystal ball routine */
X/* returns 1 if nothing was detected */
X/* returns 0 if something was detected */
Xint
Xfood_detect(sobj)
Xregister struct obj *sobj;
X{
X register boolean confused = (Confusion || (sobj && sobj->cursed));
X register int ct = 0, ctu = 0;
X register struct obj *obj;
X register char foodsym = confused ? POTION_SYM : FOOD_SYM;
X
X for(obj = fobj; obj; obj = obj->nobj)
X if(obj->olet == foodsym) {
X if(obj->ox == u.ux && obj->oy == u.uy) ctu++;
X else ct++;
X }
X if(!ct && !ctu) {
X if (sobj) strange_feeling(sobj,"Your nose twitches.");
X return(1);
X } else if(!ct) {
X known = TRUE;
X You("%s %s close nearby.", sobj ? "smell" : "sense",
X confused ? "something" : "food");
X } else {
X known = TRUE;
X cls();
X for(obj = fobj; obj; obj = obj->nobj)
X if(obj->olet == foodsym)
X at(obj->ox, obj->oy,
X (uchar)(Hallucination ? rndobjsym() : FOOD_SYM),
X AT_OBJ);
X prme();
X if (sobj) Your("nose tingles and you smell %s.",
X confused ? "something" : "food");
X else You("sense %s.", confused ? "something" : "food");
X more();
X docrt();
X }
X return(0);
X}
X
Xvoid
Xpunish(sobj)
Xregister struct obj *sobj;
X{
X You("are being punished for your misbehavior!");
X if(Punished){
X Your("iron ball gets heavier.");
X uball->owt += 15 * (1 + sobj->cursed);
X return;
X }
X setworn(mkobj_at(CHAIN_SYM, u.ux, u.uy), W_CHAIN);
X setworn(mkobj_at(BALL_SYM, u.ux, u.uy), W_BALL);
X uball->spe = 1; /* special ball (see save) */
X}
X
Xvoid
Xunpunish()
X{ /* remove the ball and chain */
X freeobj(uchain);
X unpobj(uchain);
X free((genericptr_t) uchain);
X setworn((struct obj *)0, W_CHAIN);
X uball->spe = 0;
X setworn((struct obj *)0, W_BALL);
X}
X
X/* some creatures have special data structures that only make sense in their
X * normal locations -- if the player tries to create one elsewhere, or to revive
X * one, the disoriented creature becomes a zombie
X */
Xboolean
Xcant_create(mtype)
Xint *mtype;
X{
X
X if (*mtype==PM_GUARD || *mtype==PM_SHOPKEEPER
X#if defined(ALTARS) && defined(THEOLOGY)
X || *mtype==PM_TEMPLE_PRIEST || *mtype==PM_TEMPLE_PRIESTESS
X#endif
X ) {
X *mtype = PM_HUMAN_ZOMBIE;
X return TRUE;
X } else
X return FALSE;
X}
X
X#if defined(WIZARD) || defined(EXPLORE_MODE)
Xboolean
Xcreate_particular()
X{
X char buf[BUFSZ];
X int which;
X
X do {
X pline("Create what kind of monster? [type the name] ");
X getlin(buf);
X } while(strlen(buf) < 1);
X which = name_to_mon(buf);
X if (which != -1) {
X if (!(mons[which].geno & G_GENOD) && cant_create(&which) &&
X !Blind) {
X if (mons[which].geno & G_GENOD)
Xpline("An image of the creature forms, wavers momentarily, then fades.");
X else
Xpline("The disoriented creature's eyes slowly glaze over.");
X }
X (void) makemon(&mons[which], u.ux, u.uy);
X return TRUE;
X }
X return FALSE;
X}
X#endif /* WIZARD || EXPLORE_MODE */
END_OF_FILE
if test 30625 -ne `wc -c <'src/read.c'`; then
echo shar: \"'src/read.c'\" unpacked with wrong size!
fi
# end of 'src/read.c'
fi
echo shar: End of archive 14 \(of 38\).
cp /dev/null ark14isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 38 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0