home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume16
/
nethack31
/
part66
< prev
next >
Wrap
Internet Message Format
|
1993-02-04
|
59KB
Path: uunet!news.tek.com!master!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v16i074: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part66/108
Message-ID: <4377@master.CNA.TEK.COM>
Date: 1 Feb 93 19:51:10 GMT
Sender: news@master.CNA.TEK.COM
Lines: 2090
Approved: billr@saab.CNA.TEK.COM
Xref: uunet comp.sources.games:1624
Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
Posting-number: Volume 16, Issue 74
Archive-name: nethack31/Part66
Supersedes: nethack3p9: Volume 10, Issue 46-102
Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
#! /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 66 (of 108)."
# Contents: include/flag.h src/read.c src/vault.c
# Wrapped by billr@saab on Wed Jan 27 16:09:12 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'include/flag.h' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'include/flag.h'\"
else
echo shar: Extracting \"'include/flag.h'\" \(3541 characters\)
sed "s/^X//" >'include/flag.h' <<'END_OF_FILE'
X/* SCCS Id: @(#)flag.h 3.1 90/22/02 */
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#ifndef FLAG_H
X#define FLAG_H
X
Xstruct flag {
X#ifdef AMIFLUSH
X boolean amiflush; /* kill typeahead */
X#endif
X boolean beginner;
X#ifdef MICRO
X boolean BIOS; /* use IBM or ST BIOS calls when appropriate */
X#endif
X boolean botl; /* partially redo status line */
X boolean botlx; /* print an entirely new bottom line */
X boolean cbreak; /* in cbreak mode, rogue format */
X boolean confirm; /* confirm before hitting tame monsters */
X boolean debug; /* in debugging mode */
X#define wizard flags.debug
X boolean DECgraphics; /* use DEC VT-xxx extended character set */
X boolean echo; /* 1 to echo characters */
X boolean end_disclose; /* identify inv and props upon exit */
X boolean end_own; /* list all own scores */
X boolean explore; /* in exploration mode */
X#define discover flags.explore
X boolean female;
X boolean friday13; /* it's Friday the 13th */
X boolean help; /* look in data file for info about stuff */
X boolean IBMgraphics; /* use IBM extended character set */
X boolean ignintr; /* ignore interrupts */
X#ifdef INSURANCE
X boolean ins_chkpt; /* checkpoint as appropriate */
X#endif
X boolean invlet_constant; /* let objects keep their inventory symbol */
X boolean legacy; /* print game entry "story" */
X boolean lit_corridor; /* show a dark corr as lit if it is in sight */
X boolean made_amulet;
X boolean move;
X boolean mv;
X boolean news; /* print news */
X boolean nopick; /* do not pickup objects (as when running) */
X boolean null; /* OK to send nulls to the terminal */
X boolean num_pad; /* use numbers for movement commands */
X boolean pickup; /* whether you pickup or move and look */
X#ifdef MAC
X boolean popup_dialog; /* put queries in pop up dialogs instead of
X in the message window */
X#endif
X#ifdef MICRO
X boolean rawio; /* Whether can use rawio (IOCTL call) */
X#endif
X boolean rest_on_space; /* space means rest */
X boolean safe_dog; /* give complete protection to the dog */
X#ifdef EXP_ON_BOTL
X boolean showexp; /* show experience points */
X#endif
X#ifdef SCORE_ON_BOTL
X boolean showscore; /* show score */
X#endif
X boolean silent; /* whether the bell rings or not */
X boolean sortpack; /* sorted inventory */
X boolean soundok; /* ok to tell about sounds heard */
X boolean standout; /* use standout for --More-- */
X boolean time; /* display elapsed 'time' */
X boolean tombstone; /* print tombstone */
X#ifdef TEXTCOLOR
X boolean use_color; /* use color graphics */
X boolean hilite_pet; /* hilight pets on monochome displays */
X#endif
X boolean verbose; /* max battle info */
X
X boolean window_inited; /* true if init_nhwindows() completed */
X unsigned end_top, end_around; /* describe desired score list */
X unsigned ident; /* social security number for each monster */
X unsigned moonphase;
X#define NEW_MOON 0
X#define FULL_MOON 4
X unsigned msg_history; /* hint: # of top lines to save */
X unsigned no_of_wizards; /* 0, 1 or 2 (wizard and his shadow) */
X /* reset from 2 to 1, but never to 0 */
X unsigned run; /* 0: h (etc), 1: H (etc), 2: fh (etc) */
X /* 3: FH, 4: ff+, 5: ff-, 6: FF+, 7: FF- */
X#ifdef MAC_GRAPHICS_ENV
X boolean large_font; /* draw in larger fonts (say, 12pt instead
X of 9pt) */
X boolean MACgraphics; /* use Macintosh extended character set, as
X as defined in the special font HackFont */
X#endif
X};
X
Xextern struct flag NEARDATA flags;
X
X#endif /* FLAG_H */
END_OF_FILE
if test 3541 -ne `wc -c <'include/flag.h'`; then
echo shar: \"'include/flag.h'\" unpacked with wrong size!
fi
# end of 'include/flag.h'
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'\" \(30996 characters\)
sed "s/^X//" >'src/read.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)read.c 3.1 92/12/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
X/* elven armor vibrates warningly when enchanted beyond a limit */
X#define is_elven_armor(optr) ((optr)->otyp == ELVEN_LEATHER_HELM\
X || (optr)->otyp == ELVEN_MITHRIL_COAT\
X || (optr)->otyp == ELVEN_CLOAK\
X || (optr)->otyp == ELVEN_SHIELD\
X || (optr)->otyp == ELVEN_BOOTS)
X
X#ifdef OVLB
X
Xboolean known;
X
Xstatic const char NEARDATA readable[] =
X { ALL_CLASSES, SCROLL_CLASS, SPBOOK_CLASS, 0 };
Xstatic const char all_count[] = { ALLOW_COUNT, ALL_CLASSES, 0 };
X
Xstatic void FDECL(wand_explode, (struct obj *));
Xstatic void NDECL(do_class_genocide);
Xstatic void FDECL(stripspe,(struct obj *));
Xstatic void FDECL(p_glow1,(struct obj *));
Xstatic void FDECL(p_glow2,(struct obj *,const char *));
Xstatic void FDECL(forget,(BOOLEAN_P));
X
X#endif /* OVLB */
X
X#ifndef OVERLAY
XSTATIC_DCL void FDECL(set_lit, (int,int,genericptr_t));
X#endif
X
X#ifdef OVLB
X
Xint
Xdoread()
X{
X register struct obj *scroll;
X register boolean confused;
X
X known = FALSE;
X if(check_capacity(NULL)) return (0);
X scroll = getobj(readable, "read");
X if(!scroll) return(0);
X
X /* outrumor has its own blindness check */
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 if (scroll->oclass != SCROLL_CLASS
X && scroll->oclass != SPBOOK_CLASS) {
X pline(silly_thing_to, "read");
X return(0);
X } else if (Blind) {
X const char *what = 0;
X if (scroll->oclass == SPBOOK_CLASS)
X what = "mystic runes";
X else if (!scroll->dknown)
X what = "formula on the scroll";
X if (what) {
X pline("Being blind, you cannot read the %s.", what);
X return(0);
X }
X }
X
X confused = (Confusion != 0);
X if(scroll->oclass == SPBOOK_CLASS) {
X if(confused) {
X You("cannot grasp the meaning of this tome.");
X return(0);
X } else
X return(study_book(scroll));
X }
X#ifndef NO_SIGNAL
X scroll->in_use = TRUE; /* scroll, not spellbook, now being read */
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) {
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)
X useup(scroll);
X#ifndef NO_SIGNAL
X else scroll->in_use = FALSE;
X#endif
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 if (obj->otyp == OIL_LAMP || obj->otyp == BRASS_LANTERN)
X obj->age = 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 const char *color;
X{
X Your("%s %s%s for a moment.",
X xname(otmp),
X Blind ? "vibrates" : "glows ",
X Blind ? (const char *)"" : Hallucination ? hcolor() : color);
X}
X
X/*
X * recharge an object; curse_bless is -1 if the recharging implement
X * was cursed, +1 if blessed, 0 otherwise.
X */
Xvoid
Xrecharge(obj, curse_bless)
Xstruct obj *obj;
Xint curse_bless;
X{
X register int n;
X boolean is_cursed, is_blessed;
X
X is_cursed = curse_bless < 0;
X is_blessed = curse_bless > 0;
X
X if (obj->oclass == WAND_CLASS) {
X if (obj->otyp == WAN_WISHING) {
X if (obj->recharged) { /* recharged once already? */
X wand_explode(obj);
X return;
X }
X if (is_cursed) stripspe(obj);
X else if (is_blessed) {
X if (obj->spe != 3) {
X obj->spe = 3;
X p_glow2(obj,blue);
X } else {
X wand_explode(obj);
X return;
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 } else {
X if (is_cursed) stripspe(obj);
X else if (is_blessed) {
X if (objects[obj->otyp].oc_dir == NODIR) {
X n = rn1(5,11);
X if (obj->spe < n) obj->spe = n;
X else obj->spe++;
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 }
X } else if (obj->oclass == RING_CLASS &&
X objects[obj->otyp].oc_charged) {
X /* charging does not affect ring's curse/bless status */
X int s = is_blessed ? rnd(3) : is_cursed ? -rnd(2) : 1;
X boolean is_on = (obj == uleft || obj == uright);
X
X /* destruction depends on current state, not adjustment */
X if (obj->spe > rn2(7) || obj->spe <= -5) {
X Your("%s pulsates momentarily, then explodes!",
X xname(obj));
X if (is_on) Ring_gone(obj);
X s = rnd(3 * abs(obj->spe)); /* amount of damage */
X useup(obj);
X losehp(s, "exploding ring", KILLED_BY_AN);
X } else {
X long mask = is_on ? (obj == uleft ? LEFT_RING :
X RIGHT_RING) : 0L;
X Your("%s spins %sclockwise for a moment.",
X xname(obj), s < 0 ? "counter" : "");
X /* cause attributes and/or properties to be updated */
X if (is_on) Ring_off(obj);
X obj->spe += s; /* update the ring while it's off */
X if (is_on) setworn(obj, mask), Ring_on(obj);
X /* oartifact: if a touch-sensitive artifact ring is
X ever created the above will need to be revised */
X }
X } else {
X switch(obj->otyp) {
X case MAGIC_MARKER:
X if (is_cursed) stripspe(obj);
X else if (obj->recharged) {
X if (obj->spe < 3)
X Your("marker seems permanently dried out.");
X else
X pline(nothing_happens);
X } else if (is_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 obj->recharged = 1;
X } else {
X if (obj->spe < 50) obj->spe = 50;
X else obj->spe++;
X p_glow2(obj,White);
X obj->recharged = 1;
X }
X break;
X case OIL_LAMP:
X case BRASS_LANTERN:
X if (is_cursed) {
X stripspe(obj);
X if (obj->lamplit) {
X if (!Blind)
X pline("%s goes out!", The(xname(obj)));
X obj->lamplit = 0;
X check_lamps();
X }
X } else if (is_blessed) {
X obj->spe = 1;
X obj->age = 1500;
X p_glow2(obj,blue);
X } else {
X obj->spe = 1;
X obj->age += 750;
X if (obj->age > 1500) obj->age = 1500;
X p_glow1(obj);
X }
X break;
X case CRYSTAL_BALL:
X if (is_cursed) stripspe(obj);
X else if (is_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 HORN_OF_PLENTY:
X case BAG_OF_TRICKS:
X if (is_cursed) stripspe(obj);
X else if (is_blessed) {
X if (obj->spe <= 10)
X obj->spe += rn1(10, 6);
X else obj->spe += rn1(5, 6);
X p_glow2(obj,blue);
X } else {
X obj->spe += rnd(5);
X p_glow1(obj);
X }
X break;
X default:
X You("have a feeling of loss.");
X break;
X } /* switch */
X }
X}
X
X/*
X * forget some things (e.g. after reading a scroll of amnesia). abs(howmuch)
X * controls the level of forgetfulness; 0 == part of the map, 1 == all of
X * of map, 2 == part of map + spells, 3 == all of map + spells.
X */
X
Xstatic void
Xforget(howmuch)
Xboolean howmuch;
X{
X register int zx, zy;
X register struct trap *trap;
X
X if (Punished) u.bc_felt = 0; /* forget felt ball&chain */
X
X known = TRUE;
X for(zx = 0; zx < COLNO; zx++) for(zy = 0; zy < ROWNO; zy++)
X if (howmuch & 1 || rn2(7)) {
X /* Zonk all memory of this location. */
X levl[zx][zy].seen = levl[zx][zy].waslit = 0;
X levl[zx][zy].glyph = cmap_to_glyph(S_stone);
X }
X
X /* forget all traps (except the one the hero is in :-) */
X for (trap = ftrap; trap; trap = trap->ntrap)
X if (trap->tx != u.ux || trap->ty != u.uy) trap->tseen = 0;
X
X /*
X * Make sure that what was seen is restored correctly. To do this,
X * we need to go blind for an instant --- turn off the display,
X * then restart it. All this work is needed to correctly handle
X * walls which are stone on one side and wall on the other. Turning
X * off the seen bit above will make the wall revert to stone, but
X * there are cases where we don't want this to happen. The easiest
X * thing to do is to run it through the vision system again, which
X * is always correct.
X */
X docrt(); /* this correctly will reset vision */
X
X if(howmuch & 2) losespells();
X}
X
Xint
Xseffects(sobj)
Xregister struct obj *sobj;
X{
X register int cval;
X register boolean confused = (Confusion != 0);
X register struct obj *otmp;
X
X exercise(A_WIS, TRUE); /* just for trying */
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(sobj);
X break;
X#endif
X case SCR_ENCHANT_ARMOR:
X {
X register schar s;
X otmp = some_armor();
X if(!otmp) {
X strange_feeling(sobj,
X !Blind ? "Your skin glows then fades." :
X "Your skin feels warm for a moment.");
X exercise(A_CON, !sobj->cursed);
X exercise(A_STR, !sobj->cursed);
X return(1);
X }
X if(confused) {
X otmp->oerodeproof = !(sobj->cursed);
X if(Blind) {
X otmp->rknown = FALSE;
X Your("%s feels warm for a moment.",
X xname(otmp));
X } else {
X otmp->rknown = TRUE;
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 : golden,
X sobj->cursed ? "glow" :
X (is_shield(otmp) ? "layer" : "shield"));
X }
X if (otmp->oerodeproof && otmp->oeroded) {
X otmp->oeroded = 0;
X Your("%s %ss good as new!",
X xname(otmp), Blind ? "feel" : "look");
X }
X break;
X }
X if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
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 ? nul : 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->cursed ? -1 :
X otmp->spe >= 9 ? (rn2(otmp->spe) == 0) :
X sobj->blessed ? rnd(3-otmp->spe/3) : 1;
X if (s >= 0 && otmp->otyp >= GRAY_DRAGON_SCALES &&
X otmp->otyp <= YELLOW_DRAGON_SCALES) {
X /* dragon scales get turned into dragon scale mail */
X Your("%s merges and hardens!", xname(otmp));
X setworn((struct obj *)0, W_ARM);
X /* assumes same order */
X otmp->otyp = GRAY_DRAGON_SCALE_MAIL +
X otmp->otyp - GRAY_DRAGON_SCALES;
X otmp->cursed = 0;
X if (sobj->blessed) {
X otmp->spe++;
X otmp->blessed = 1;
X }
X otmp->known = 1;
X setworn(otmp, W_ARM);
X break;
X }
X Your("%s %s%s%s for a %s.",
X xname(otmp),
X s == 0 ? "violently " : nul,
X Blind ? "vibrates" : "glows ",
X Blind ? nul : Hallucination ? hcolor() :
X sobj->cursed ? Black : silver,
X (s*s>1) ? "while" : "moment");
X otmp->cursed = sobj->cursed;
X if (!otmp->blessed || sobj->cursed)
X otmp->blessed = sobj->blessed;
X if (s) {
X otmp->spe += s;
X adj_abon(otmp, s);
X }
X
X /* an elven magic clue, cookie@keebler */
X if((otmp->spe > ((otmp->otyp == ELVEN_MITHRIL_COAT) ? 5 : 3))
X && (is_elven_armor(otmp) || !rn2(7)))
X Your("%s suddenly vibrates %s.",
X xname(otmp),
X Blind ? "again" : "unexpectedly");
X break;
X }
X case SCR_DESTROY_ARMOR:
X {
X otmp = some_armor();
X if(confused) {
X if(!otmp) {
X strange_feeling(sobj,"Your bones itch.");
X exercise(A_STR, FALSE);
X exercise(A_CON, FALSE);
X return(1);
X }
X otmp->oerodeproof = sobj->cursed;
X p_glow2(otmp,purple);
X break;
X }
X if(!sobj->cursed || !otmp || !otmp->cursed) {
X if(!destroy_arm(otmp)) {
X strange_feeling(sobj,"Your skin itches.");
X exercise(A_STR, FALSE);
X exercise(A_CON, FALSE);
X return(1);
X }
X } else { /* armor and scroll both cursed */
X Your("%s vibrates.", xname(otmp));
X if (otmp->spe >= -6) otmp->spe--;
X make_stunned(HStun + rn1(10, 10), TRUE);
X }
X }
X break;
X case SCR_CONFUSE_MONSTER:
X case SPE_CONFUSE_MONSTER:
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 ? nul : Hallucination ? hcolor() : purple);
X make_confused(HConfusion + rnd(100),FALSE);
X } else {
X pline("A %s%s surrounds your %s.",
X Blind ? nul : Hallucination ? hcolor() : red,
X Blind ? "faint buzz" : " glow",
X body_part(HEAD));
X make_confused(0L,TRUE);
X }
X } else {
X if (!sobj->blessed) {
X Your("%s%s %s%s.",
X makeplural(body_part(HAND)),
X Blind ? "" : " begin to glow",
X Blind ? (const char *)"tingle" : Hallucination ? hcolor() : red,
X u.umconf ? " even more" : "");
X u.umconf++;
X } else {
X if (Blind)
X Your("%s tingle %s sharply.",
X makeplural(body_part(HAND)),
X u.umconf ? "even more" : "very");
X else
X Your("%s glow a%s brilliant %s.",
X makeplural(body_part(HAND)),
X u.umconf ? "n even more" : "",
X Hallucination ? hcolor() : red);
X u.umconf += rn1(8, 2);
X }
X }
X break;
X case SCR_SCARE_MONSTER:
X case SPE_CAUSE_FEAR:
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->mfrozen = mtmp->msleep = 0;
X mtmp->mcanmove = 1;
X } else
X if (! resist(mtmp, sobj->oclass, 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 if(sobj->otyp == SCR_SCARE_MONSTER)
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 (Blind)
X You("don't remember there being any magic words on this scroll.");
X else
X pline("This scroll seems to be blank.");
X known = TRUE;
X break;
X case SCR_REMOVE_CURSE:
X case SPE_REMOVE_CURSE:
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 uncurse(obj);
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 case SPE_CREATE_MONSTER:
X { register int cnt = 1;
X
X if(!rn2(73) && !sobj->blessed) cnt += rnd(4);
X if(confused || sobj->cursed) cnt += 12;
X while(cnt--) {
X#if defined(WIZARD) || defined(EXPLORE_MODE)
X if((!wizard && !discover) || !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->oclass == WEAPON_CLASS ||
X uwep->otyp == PICK_AXE ||
X uwep->otyp == UNICORN_HORN) && confused) {
X /* oclass check added 10/25/86 GAN */
X uwep->oerodeproof = !(sobj->cursed);
X if(Blind) {
X uwep->rknown = FALSE;
X Your("weapon feels warm for a moment.");
X } else {
X uwep->rknown = TRUE;
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 : golden,
X sobj->cursed ? "glow" : "shield");
X }
X if (uwep->oerodeproof && uwep->oeroded) {
X uwep->oeroded = 0;
X Your("%s good as new!",
X aobjnam(uwep, Blind ? "feel" : "look"));
X }
X } else return !chwepon(sobj,
X sobj->cursed ? -1 :
X !uwep ? 1 :
X uwep->spe >= 9 ? (rn2(uwep->spe) == 0) :
X sobj->blessed ? rnd(3-uwep->spe/3) : 1);
X break;
X case SCR_TAMING:
X case SPE_CHARM_MONSTER:
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(isok(u.ux+i, u.uy+j) && (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 pline("%s calms down.", Monnam(mtmp));
X mtmp->mpeaceful = 1;
X }
X } else if(!resist(mtmp, sobj->oclass, 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 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, sobj);
X break;
X case SCR_TELEPORTATION:
X if(confused || sobj->cursed) level_tele();
X else {
X if (sobj->blessed && !Teleport_control) {
X known = TRUE;
X if (yn("Do you wish to teleport?")=='n')
X break;
X }
X tele();
X if(Teleport_control || !couldsee(u.ux0, u.uy0) ||
X (distu(u.ux0, u.uy0) >= 16))
X 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 case SPE_DETECT_FOOD:
X if (food_detect(sobj))
X return(1); /* nothing detected */
X break;
X case SPE_IDENTIFY:
X cval = rn2(5);
X goto id;
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 id:
X if(invent && !confused) {
X int ret;
X do {
X ret = ggetobj("identify", identify, cval);
X } while(cval && (cval -= ret));
X }
X return(1);
X case SCR_CHARGING:
X if (confused) {
X You("feel charged up!");
X if (u.uen < u.uenmax)
X u.uen = u.uenmax;
X else
X u.uen = (u.uenmax += d(5,4));
X flags.botl = 1;
X break;
X }
X known = TRUE;
X pline("This is a charging scroll.");
X otmp = getobj(all_count, "charge");
X if (!otmp) break;
X recharge(otmp, sobj->cursed ? -1 : (sobj->blessed ? 1 : 0));
X break;
X case SCR_MAGIC_MAPPING:
X if (level.flags.nommap) {
X Your("mind is filled with crazy lines!");
X if (Hallucination)
X pline("Wow! Modern art.");
X else
X Your("head spins in bewilderment.");
X make_confused(HConfusion + rnd(30), FALSE);
X break;
X }
X known = TRUE;
X case SPE_MAGIC_MAPPING:
X if (level.flags.nommap) {
X Your("head spins as something blocks the spell!");
X make_confused(HConfusion + rnd(30), FALSE);
X break;
X }
X pline("A map coalesces in your mind!");
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, you can't grasp the details.");
X }
X break;
X case SCR_AMNESIA:
X known = TRUE;
X forget( ((!sobj->blessed) << 1) | (!confused || sobj->cursed) );
X if (Hallucination) /* Ommmmmm! */
X Your("mind releases itself from mundane concerns.");
X else if (!strncmpi(plname, "Maud", 4))
X pline("As your mind turns inward on itself, you forget everything else.");
X else if (rn2(2))
X pline("Who was that Maud person anyway?");
X else
X pline("Thinking of Maud you forget everything else.");
X exercise(A_WIS, FALSE);
X break;
X case SCR_FIRE:
X /*
X * Note: Modifications have been made as of 3.0 to allow for
X * some damage 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("feel 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", KILLED_BY_AN);
X }
X return(1);
X }
X if (Underwater)
X pline("The water around you vaporizes violently!");
X else
X pline("The scroll erupts in a tower of flame!");
X explode(u.ux, u.uy, 11, (2*(rn1(3, 3) + 2 * cval) + 1)/3,
X SCROLL_CLASS);
X return(1);
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
Xwand_explode(obj)
Xregister struct obj *obj;
X{
X Your("%s vibrates violently, and explodes!",xname(obj));
X nhbell();
X losehp(rn2(2*(u.uhpmax+1)/3),"exploding wand", KILLED_BY_AN);
X useup(obj);
X exercise(A_STR, FALSE);
X}
X
X/*
X * Low-level lit-field update routine.
X */
XSTATIC_PTR void
Xset_lit(x,y,val)
Xint x, y;
Xgenericptr_t val;
X{
X levl[x][y].lit = (val == (genericptr_t)-1) ? 0 : 1;
X return;
X}
X
Xvoid
Xlitroom(on,obj)
Xregister boolean on;
Xstruct obj *obj;
X{
X /* first produce the text (provided you're not blind) */
X if(Blind) goto do_it;
X if(!on) {
X if(u.uswallow) {
X pline("It seems even darker in here than before.");
X return;
X }
X You("are surrounded by darkness!");
X } else {
X if(u.uswallow){
X if (is_animal(u.ustuck->data))
X pline("%s stomach is lit.",
X s_suffix(Monnam(u.ustuck)));
X else
X if (is_whirly(u.ustuck->data))
X pline("%s shines briefly.",
X Monnam(u.ustuck));
X else
X pline("%s glistens.", Monnam(u.ustuck));
X return;
X }
X pline("A lit field surrounds you!");
X }
X
Xdo_it:
X /* No-op in water - can only see the adjacent squares and that's it! */
X if (Underwater || Is_waterlevel(&u.uz)) return;
X /*
X * If we are darkening the room and the hero is punished but not
X * blind, then we have to pick up and replace the ball and chain so
X * that we don't remember them if they are out of sight.
X */
X if (Punished && !on && !Blind)
X move_bc(1, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
X
X#ifdef REINCARNATION
X if (Is_rogue_level(&u.uz)) {
X /* Can't use do_clear_area because MAX_RADIUS is too small */
X /* rogue lighting must light the entire room */
X int rnum = levl[u.ux][u.uy].roomno - ROOMOFFSET;
X int rx, ry;
X if(rnum >= 0) {
X for(rx = rooms[rnum].lx-1; rx <= rooms[rnum].hx+1; rx++)
X for(ry = rooms[rnum].ly-1; ry <= rooms[rnum].hy+1; ry++)
X set_lit(rx, ry, (genericptr_t)((on)? 1 : -1));
X rooms[rnum].rlit = on;
X }
X /* hallways remain dark on the rogue level */
X } else
X#endif
X do_clear_area(u.ux,u.uy,
X (obj && obj->oclass==SCROLL_CLASS && obj->blessed) ? 9 : 5,
X set_lit, (genericptr_t)((on)? 1 : -1));
X
X /*
X * If we are not blind, then force a redraw on all positions in sight
X * by temporarily blinding the hero. The vision recalculation will
X * correctly update all previously seen positions *and* correctly
X * set the waslit bit [could be messed up from above].
X */
X if (!Blind) {
X vision_recalc(2);
X
X /* replace ball&chain */
X if (Punished && !on)
X move_bc(0, 0, uball->ox, uball->oy, uchain->ox, uchain->oy);
X }
X
X vision_full_recalc = 1; /* delayed vision recalculation */
X}
X
Xstatic void
Xdo_class_genocide()
X{
X register int i, j, immunecnt, gonecnt, goodcnt, class;
X char buf[BUFSZ];
X
X for(j=0; ; j++) {
X if (j >= 5) {
X pline(thats_enough_tries);
X return;
X }
X do {
X getlin("What class of monsters do you wish to genocide? [type a letter]",
X buf);
X } while (buf[0]=='\033' || strlen(buf) != 1);
X immunecnt = gonecnt = goodcnt = 0;
X class = def_char_to_monclass(buf[0]);
X for(i = 0; i < NUMMONS; i++) {
X if(mons[i].mlet == class) {
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 && class != 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; i < NUMMONS; i++) {
X if(mons[i].mlet == class) {
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_format = KILLED_BY_AN;
X killer = "scroll of genocide";
X#ifdef POLYSELF
X if (u.umonnum >= 0)
X You("feel dead inside.");
X else
X#endif
X done(GENOCIDED);
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 : (const char *)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 getlin("What monster do you want to genocide? [type the name]",
X buf);
X
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.ualign.type));
X if (is_demon(ptr)) adjalign(sgn(u.ualign.type));
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 }
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_format = KILLED_BY_AN;
X killer = "genocide spell";
X#ifdef POLYSELF
X /* Polymorphed characters will die as soon as they're rehumanized. */
X if(u.umonnum >= 0) You("feel dead inside.");
X else
X#endif
X done(GENOCIDED);
X return;
X }
X#ifdef POLYSELF
X else if (ptr == uasmon) 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 if (!(ptr->geno & G_EXTINCT)) {
X pline("Sent in some %s.", makeplural(buf));
X j = rn1(3, 4);
X for(i=1; i<=j; i++) {
X struct monst *mmon = makemon(ptr, u.ux, u.uy);
X struct obj *otmp;
X
X while ((otmp = mmon->minvent) != 0) {
X mmon->minvent = otmp->nobj;
X dealloc_obj(otmp);
X }
X }
X }
X}
X
X#endif /* OVLB */
X#ifdef OVLB
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 += 160 * (1 + sobj->cursed);
X return;
X }
X setworn(mkobj(CHAIN_CLASS, TRUE), W_CHAIN);
X setworn(mkobj(BALL_CLASS, TRUE), W_BALL);
X uball->spe = 1; /* special ball (see save) */
X
X /*
X * Place ball & chain if not swallowed. If swallowed, the ball &
X * chain variables will be set at the next call to placebc().
X */
X if (!u.uswallow) {
X placebc();
X if (Blind) set_bc(1); /* set up ball and chain variables */
X newsym(u.ux,u.uy); /* see ball&chain if can't see self */
X }
X}
X
Xvoid
Xunpunish()
X{ /* remove the ball and chain */
X freeobj(uchain);
X newsym(uchain->ox,uchain->oy);
X dealloc_obj(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 || *mtype==PM_ALIGNED_PRIEST || *mtype==PM_ANGEL) {
X *mtype = PM_HUMAN_ZOMBIE;
X return TRUE;
X }
X return FALSE;
X}
X
X#if defined(WIZARD) || defined(EXPLORE_MODE)
Xboolean
Xcreate_particular()
X{
X char buf[BUFSZ];
X int which, tries = 0;
X
X do {
X getlin("Create what kind of monster? [type the name]", buf);
X which = name_to_mon(buf);
X if (which < 0) pline("I've never heard of such monsters.");
X else break;
X } while (++tries < 5);
X if (tries == 5) pline(thats_enough_tries);
X else {
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 */
X
X#endif /* OVLB */
X
X/*read.c*/
END_OF_FILE
if test 30996 -ne `wc -c <'src/read.c'`; then
echo shar: \"'src/read.c'\" unpacked with wrong size!
fi
# end of 'src/read.c'
fi
if test -f 'src/vault.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/vault.c'\"
else
echo shar: Extracting \"'src/vault.c'\" \(18951 characters\)
sed "s/^X//" >'src/vault.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)vault.c 3.1 93/01/15 */
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 "vault.h"
X
XSTATIC_DCL struct monst *NDECL(findgd);
X
X#ifdef OVLB
X
Xstatic boolean FDECL(clear_fcorr, (struct monst *,BOOLEAN_P));
Xstatic void FDECL(restfakecorr,(struct monst *));
Xstatic boolean FDECL(in_fcorridor, (struct monst *,int,int));
Xstatic void FDECL(move_gold,(struct obj *,int));
Xstatic void FDECL(wallify_vault,(struct monst *));
X
Xstatic boolean
Xclear_fcorr(grd, forceshow)
Xregister struct monst *grd;
Xregister boolean forceshow;
X{
X register int fcx, fcy, fcbeg;
X register struct monst *mtmp;
X
X while((fcbeg = EGD(grd)->fcbeg) < EGD(grd)->fcend) {
X fcx = EGD(grd)->fakecorr[fcbeg].fx;
X fcy = EGD(grd)->fakecorr[fcbeg].fy;
X if((grd->mhp <= 0 || !in_fcorridor(grd, u.ux, u.uy)) &&
X EGD(grd)->gddone)
X forceshow = TRUE;
X if((u.ux == fcx && u.uy == fcy && grd->mhp > 0) ||
X (!forceshow && cansee(fcx,fcy))) return(FALSE);
X if ((mtmp = m_at(fcx,fcy)) != 0) {
X if(mtmp->isgd) return(FALSE);
X else if(!in_fcorridor(grd, u.ux, u.uy)) {
X#ifdef SOUNDS
X if(mtmp->mpeaceful) yelp(mtmp);
X#endif
X rloc(mtmp);
X }
X }
X levl[fcx][fcy].typ = EGD(grd)->fakecorr[fcbeg].ftyp;
X map_background(fcx,fcy, 1);
X if(!ACCESSIBLE(levl[fcx][fcy].typ)) block_point(fcx,fcy);
X EGD(grd)->fcbeg++;
X }
X if(grd->mhp <= 0) {
X pline("The corridor disappears.");
X if(IS_ROCK(levl[u.ux][u.uy].typ)) You("are encased in rock.");
X }
X return(TRUE);
X}
X
Xstatic void
Xrestfakecorr(grd)
Xregister struct monst *grd;
X{
X /* it seems you left the corridor - let the guard disappear */
X if(clear_fcorr(grd, FALSE)) mongone(grd);
X}
X
Xboolean
Xgrddead(grd) /* called in mon.c */
Xregister struct monst *grd;
X{
X register boolean dispose = clear_fcorr(grd, TRUE);
X
X if(!dispose) {
X /* see comment by newpos in gd_move() */
X remove_monster(grd->mx, grd->my);
X newsym(grd->mx, grd->my);
X place_monster(grd, 0, 0);
X EGD(grd)->ogx = grd->mx;
X EGD(grd)->ogy = grd->my;
X dispose = clear_fcorr(grd, TRUE);
X }
X return(dispose);
X}
X
Xstatic boolean
Xin_fcorridor(grd, x, y)
Xregister struct monst *grd;
Xint x, y;
X{
X register int fci;
X
X for(fci = EGD(grd)->fcbeg; fci < EGD(grd)->fcend; fci++)
X if(x == EGD(grd)->fakecorr[fci].fx &&
X y == EGD(grd)->fakecorr[fci].fy)
X return(TRUE);
X return(FALSE);
X}
X
XSTATIC_OVL
Xstruct monst *
Xfindgd() {
X
X register struct monst *mtmp;
X
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->isgd && on_level(&(EGD(mtmp)->gdlevel), &u.uz))
X return(mtmp);
X return((struct monst *)0);
X}
X
X#endif /* OVLB */
X#ifdef OVL0
X
Xchar
Xvault_occupied(array)
Xchar *array;
X{
X register char *ptr;
X
X for (ptr = array; *ptr; ptr++)
X if (rooms[*ptr - ROOMOFFSET].rtype == VAULT)
X return(*ptr);
X return('\0');
X}
X
Xvoid
Xinvault()
X{
X
X#ifdef BSD_43_BUG
X int dummy; /* hack to avoid schain botch */
X#endif
X struct monst *guard;
X int vaultroom = (int)vault_occupied(u.urooms);
X
X if(!vaultroom) {
X u.uinvault = 0;
X return;
X }
X
X vaultroom -= ROOMOFFSET;
X
X guard = findgd();
X if(++u.uinvault % 30 == 0 && !guard) { /* if time ok and no guard now. */
X char buf[BUFSZ];
X register int x, y, dd, gx, gy;
X int lx = 0, ly = 0;
X
X /* first find the goal for the guard */
X for(dd = 2; (dd < ROWNO || dd < COLNO); dd++) {
X for(y = u.uy-dd; y <= u.uy+dd; ly = y, y++) {
X if(y < 0 || y > ROWNO-1) continue;
X for(x = u.ux-dd; x <= u.ux+dd; lx = x, x++) {
X if(y != u.uy-dd && y != u.uy+dd && x != u.ux-dd)
X x = u.ux+dd;
X if(x < 1 || x > COLNO-1) continue;
X if(levl[x][y].typ == CORR) {
X if(x < u.ux) lx = x + 1;
X else if(x > u.ux) lx = x - 1;
X else x = lx;
X if(y < u.uy) ly = y + 1;
X else if(y > u.uy) ly = y - 1;
X else y = ly;
X if(levl[lx][ly].typ != STONE && levl[lx][ly].typ != CORR)
X goto incr_radius;
X goto fnd;
X }
X }
X }
Xincr_radius: ;
X }
X impossible("Not a single corridor on this level??");
X tele();
X return;
Xfnd:
X gx = x; gy = y;
X
X /* next find a good place for a door in the wall */
X x = u.ux; y = u.uy;
X if(levl[x][y].typ != ROOM) { /* player dug a door and is in it */
X if(levl[x+1][y].typ == ROOM) x = x + 1;
X else if(levl[x][y+1].typ == ROOM) y = y + 1;
X else if(levl[x-1][y].typ == ROOM) x = x - 1;
X else if(levl[x][y-1].typ == ROOM) y = y - 1;
X else if(levl[x+1][y+1].typ == ROOM) {
X x = x + 1;
X y = y + 1;
X } else if (levl[x-1][y-1].typ == ROOM) {
X x = x - 1;
X y = y - 1;
X } else if (levl[x+1][y-1].typ == ROOM) {
X x = x + 1;
X y = y - 1;
X } else if (levl[x-1][y+1].typ == ROOM) {
X x = x - 1;
X y = y + 1;
X }
X }
X while(levl[x][y].typ == ROOM) {
X register int dx,dy;
X
X dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
X dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
X if(abs(gx-x) >= abs(gy-y))
X x += dx;
X else
X y += dy;
X }
X if(x == u.ux && y == u.uy) {
X if(levl[x+1][y].typ == HWALL || levl[x+1][y].typ == DOOR)
X x = x + 1;
X else if(levl[x-1][y].typ == HWALL || levl[x-1][y].typ == DOOR)
X x = x - 1;
X else if(levl[x][y+1].typ == VWALL || levl[x][y+1].typ == DOOR)
X y = y + 1;
X else if(levl[x][y-1].typ == VWALL || levl[x][y-1].typ == DOOR)
X y = y - 1;
X else return;
X }
X
X /* make something interesting happen */
X if(!(guard = makemon(&mons[PM_GUARD], x, y))) return;
X guard->isgd = 1;
X guard->mpeaceful = 1;
X set_malign(guard);
X EGD(guard)->gddone = 0;
X EGD(guard)->ogx = x;
X EGD(guard)->ogy = y;
X assign_level(&(EGD(guard)->gdlevel), &u.uz);
X EGD(guard)->vroom = vaultroom;
X EGD(guard)->warncnt = 0;
X
X if(!cansee(guard->mx, guard->my)) {
X mongone(guard);
X return;
X }
X
X reset_faint(); /* if fainted - wake up */
X pline("Suddenly one of the Vault's guards enters!");
X newsym(guard->mx,guard->my);
X if (Strangled
X#ifdef POLYSELF
X || uasmon->msound == MS_SILENT
X#endif
X ) {
X verbalize("I'll be back when you're ready to speak to me!");
X mongone(guard);
X return;
X }
X stop_occupation(); /* if occupied, stop it *now* */
X do {
X getlin("\"Hello stranger, who are you?\" -",buf);
X } while (!letter(buf[0]));
X
X if(!strcmp(buf, "Croesus") || !strcmp(buf, "Kroisos")) {
X verbalize("Oh, yes, of course. Sorry to have disturbed you.");
X mongone(guard);
X return;
X }
X clear_nhwindow(WIN_MESSAGE);
X verbalize("I don't know you.");
X if (!u.ugold && !hidden_gold())
X verbalize("Please follow me.");
X else {
X if (!u.ugold)
X verbalize("You have hidden gold.");
X verbalize("Most likely all your gold was stolen from this vault.");
X verbalize("Please drop that gold and follow me.");
X }
X EGD(guard)->gdx = gx;
X EGD(guard)->gdy = gy;
X EGD(guard)->fcbeg = 0;
X EGD(guard)->fakecorr[0].fx = x;
X EGD(guard)->fakecorr[0].fy = y;
X if(IS_WALL(levl[x][y].typ))
X EGD(guard)->fakecorr[0].ftyp = levl[x][y].typ;
X else { /* the initial guard location is a dug door */
X int vlt = EGD(guard)->vroom;
X xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
X xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
X
X if(x == lowx-1 && y == lowy-1)
X EGD(guard)->fakecorr[0].ftyp = TLCORNER;
X else if(x == hix+1 && y == lowy-1)
X EGD(guard)->fakecorr[0].ftyp = TRCORNER;
X else if(x == lowx-1 && y == hiy+1)
X EGD(guard)->fakecorr[0].ftyp = BLCORNER;
X else if(x == hix+1 && y == hiy+1)
X EGD(guard)->fakecorr[0].ftyp = BRCORNER;
X else if(y == lowy-1 || y == hiy+1)
X EGD(guard)->fakecorr[0].ftyp = HWALL;
X else if(x == lowx-1 || x == hix+1)
X EGD(guard)->fakecorr[0].ftyp = VWALL;
X }
X levl[x][y].typ = DOOR;
X levl[x][y].doormask = D_NODOOR;
X EGD(guard)->fcend = 1;
X EGD(guard)->warncnt = 1;
X }
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
Xstatic void
Xmove_gold(gold, vroom)
Xstruct obj *gold;
Xint vroom;
X{
X xchar nx, ny;
X
X remove_object(gold);
X newsym(gold->ox, gold->oy);
X nx = rooms[vroom].lx + rn2(2);
X ny = rooms[vroom].ly + rn2(2);
X place_object(gold, nx, ny);
X stackobj(gold);
X newsym(nx,ny);
X}
X
Xstatic void
Xwallify_vault(grd)
Xstruct monst *grd;
X{
X int x, y;
X int vlt = EGD(grd)->vroom;
X char tmp_viz;
X xchar lowx = rooms[vlt].lx, hix = rooms[vlt].hx;
X xchar lowy = rooms[vlt].ly, hiy = rooms[vlt].hy;
X register struct obj *gold;
X register boolean fixed = FALSE;
X register boolean movedgold = FALSE;
X
X for(x = lowx-1; x <= hix+1; x++)
X for(y = lowy-1; y <= hiy+1; y += (hiy-lowy+2)) {
X if(!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
X struct monst *mon;
X
X if((mon = m_at(x, y)) && grd->mx != x && grd->my != y) {
X if (mon->data->msound != MS_SILENT)
X You("hear a scream.");
X rloc(m_at(x,y));
X }
X if ((gold = g_at(x, y)) != 0) {
X move_gold(gold, EGD(grd)->vroom);
X movedgold = TRUE;
X }
X if(x == lowx-1 && y == lowy-1)
X levl[x][y].typ = TLCORNER;
X else if(x == hix+1 && y == lowy-1)
X levl[x][y].typ = TRCORNER;
X else if(x == lowx-1 && y == hiy+1)
X levl[x][y].typ = BLCORNER;
X else if(x == hix+1 && y == hiy+1)
X levl[x][y].typ = BRCORNER;
X else levl[x][y].typ = HWALL;
X
X levl[x][y].doormask = 0;
X /*
X * hack: player knows walls are restored because of the
X * message, below, so show this on the screen.
X */
X tmp_viz = viz_array[y][x];
X viz_array[y][x] = IN_SIGHT|COULD_SEE;
X newsym(x,y);
X viz_array[y][x] = tmp_viz;
X block_point(x,y);
X fixed = TRUE;
X }
X }
X for(x = lowx-1; x <= hix+1; x += (hix-lowx+2))
X for(y = lowy; y <= hiy; y++) {
X if(!IS_WALL(levl[x][y].typ) && !in_fcorridor(grd, x, y)) {
X if(MON_AT(x, y) && grd->mx != x && grd->my != y) {
X You("hear a scream.");
X rloc(m_at(x,y));
X }
X if ((gold = g_at(x, y)) != 0) {
X move_gold(gold, EGD(grd)->vroom);
X movedgold = TRUE;
X }
X levl[x][y].typ = VWALL;
X levl[x][y].doormask = 0;
X tmp_viz = viz_array[y][x];
X viz_array[y][x] = IN_SIGHT|COULD_SEE;
X newsym(x,y);
X viz_array[y][x] = tmp_viz;
X block_point(x,y);
X fixed = TRUE;
X }
X }
X
X if(movedgold || fixed) {
X if(in_fcorridor(grd, grd->mx, grd->my) || cansee(grd->mx, grd->my))
X pline("The guard whispers an incantation.");
X else You("hear a distant chant.");
X if(movedgold)
X pline("A mysterious force moves the gold into the vault.");
X if(fixed)
X pline("The damaged vault's walls are magically restored!");
X }
X}
X
X/*
X * return 1: guard moved, 0: guard didn't, -1: let m_move do it, -2: died
X */
Xint
Xgd_move(grd)
Xregister struct monst *grd;
X{
X int x, y, nx, ny, m, n;
X int dx, dy, gx, gy, fci;
X uchar typ;
X struct fakecorridor *fcp;
X register struct egd *egrd = EGD(grd);
X register struct rm *crm;
X register boolean goldincorridor = FALSE,
X u_in_vault = vault_occupied(u.urooms)? TRUE : FALSE,
X grd_in_vault = *in_rooms(grd->mx, grd->my, VAULT)?
X TRUE : FALSE;
X boolean disappear_msg_seen = FALSE, semi_dead = (grd->mhp <= 0);
X register boolean u_carry_gold = ((u.ugold + hidden_gold()) > 0L);
X
X if(!on_level(&(egrd->gdlevel), &u.uz)) return(-1);
X nx = ny = m = n = 0;
X if(!u_in_vault && !grd_in_vault)
X wallify_vault(grd);
X if(!grd->mpeaceful) {
X if(semi_dead) {
X egrd->gddone =1;
X goto newpos;
X }
X if(!u_in_vault &&
X (grd_in_vault ||
X (in_fcorridor(grd, grd->mx, grd->my) &&
X !in_fcorridor(grd, u.ux, u.uy)))) {
X rloc(grd);
X wallify_vault(grd);
X (void) clear_fcorr(grd, TRUE);
X goto letknow;
X }
X if(!in_fcorridor(grd, grd->mx, grd->my))
X (void) clear_fcorr(grd, TRUE);
X return(-1);
X }
X if(abs(egrd->ogx - grd->mx) > 1 ||
X abs(egrd->ogy - grd->my) > 1)
X return(-1); /* teleported guard - treat as monster */
X if(egrd->fcend == 1) {
X if(u_in_vault &&
X (u_carry_gold || um_dist(grd->mx, grd->my, 1))) {
X if(egrd->warncnt == 3)
X verbalize("I repeat, %sfollow me!",
X u_carry_gold ? (!u.ugold ?
X "drop that hidden gold and " :
X "drop that gold and ") : "");
X if(egrd->warncnt == 7) {
X m = grd->mx;
X n = grd->my;
X verbalize("You've been warned, knave!");
X mnexto(grd);
X levl[m][n].typ = egrd->fakecorr[0].ftyp;
X newsym(m,n);
X grd->mpeaceful = 0;
X return(-1);
X }
X /* not fair to get mad when (s)he's fainted or paralyzed */
X if(!is_fainted() && multi >= 0) egrd->warncnt++;
X return(0);
X }
X
X if (!u_in_vault)
X if (u_carry_gold) { /* player teleported */
X m = grd->mx;
X n = grd->my;
X rloc(grd);
X levl[m][n].typ = egrd->fakecorr[0].ftyp;
X newsym(m,n);
X grd->mpeaceful = 0;
Xletknow:
X if(!cansee(grd->mx, grd->my))
X You("hear the shrill sound of a guard's whistle.");
X else
X You(um_dist(grd->mx, grd->my, 2) ?
X "see an angry %s approaching." :
X "are confronted by an angry %s.",
X l_monnam(grd));
X return(-1);
X } else {
X verbalize("Well, be gone your way.");
X wallify_vault(grd);
X egrd->gddone = 1;
X goto cleanup;
X }
X }
X
X if(egrd->fcend > 1) {
X if(egrd->fcend > 2 && in_fcorridor(grd, grd->mx, grd->my) &&
X !egrd->gddone && !in_fcorridor(grd, u.ux, u.uy) &&
X levl[egrd->fakecorr[0].fx][egrd->fakecorr[0].fy].typ
X == egrd->fakecorr[0].ftyp) {
X pline("The guard, confused, disappears.");
X disappear_msg_seen = TRUE;
X goto cleanup;
X }
X if(u_carry_gold &&
X (in_fcorridor(grd, u.ux, u.uy) ||
X /* cover a 'blind' spot */
X (egrd->fcend > 1 && u_in_vault))) {
X if(!grd->mx) {
X restfakecorr(grd);
X return(-2);
X }
X if(egrd->warncnt < 6) {
X egrd->warncnt = 6;
X verbalize("Drop all your gold, scoundrel!");
X return(0);
X } else {
X verbalize("So be it, rogue!");
X grd->mpeaceful = 0;
X return(-1);
X }
X }
X }
X for(fci = egrd->fcbeg; fci < egrd->fcend; fci++)
X if(g_at(egrd->fakecorr[fci].fx, egrd->fakecorr[fci].fy)){
X m = egrd->fakecorr[fci].fx;
X n = egrd->fakecorr[fci].fy;
X goldincorridor = TRUE;
X }
X if(goldincorridor && !egrd->gddone) {
X x = grd->mx;
X y = grd->my;
X if (m == u.ux && n == u.uy) {
X struct obj *gold = g_at(m,n);
X /* Grab the gold from between the hero's feet. */
X grd->mgold += gold->quan;
X delobj(gold);
X newsym(m,n);
X } else if (m == x && n == y) {
X mpickgold(grd); /* does a newsym */
X } else {
X /* just for insurance... */
X if (MON_AT(m, n) && m != grd->mx && n != grd->my) {
X verbalize("Out of my way, scum!");
X rloc(m_at(m, n));
X }
X remove_monster(grd->mx, grd->my);
X place_monster(grd, m, n);
X mpickgold(grd); /* does a newsym */
X }
X if(cansee(m,n))
X pline("%s%s picks up the gold.", Monnam(grd),
X grd->mpeaceful ? " calms down and" : "");
X if(x != grd->mx || y != grd->my) {
X remove_monster(grd->mx, grd->my);
X place_monster(grd, x, y);
X newsym(grd->mx,grd->my);
X }
X if(!grd->mpeaceful) return(-1);
X else {
X egrd->warncnt = 5;
X return(0);
X }
X }
X if(um_dist(grd->mx, grd->my, 1) || egrd->gddone) {
X if(!egrd->gddone && !rn2(10)) verbalize("Move along!");
X restfakecorr(grd);
X return(0); /* didn't move */
X }
X x = grd->mx;
X y = grd->my;
X
X if(u_in_vault) goto nextpos;
X
X /* look around (hor & vert only) for accessible places */
X for(nx = x-1; nx <= x+1; nx++) for(ny = y-1; ny <= y+1; ny++) {
X if((nx == x || ny == y) && (nx != x || ny != y) && isok(nx, ny)) {
X
X typ = (crm = &levl[nx][ny])->typ;
X if(!IS_STWALL(typ) && !IS_POOL(typ)) {
X
X if(in_fcorridor(grd, nx, ny))
X goto nextnxy;
X
X if(*in_rooms(nx,ny,VAULT))
X continue;
X
X /* seems we found a good place to leave him alone */
X egrd->gddone = 1;
X if(ACCESSIBLE(typ)) goto newpos;
X#ifdef STUPID
X if (typ == SCORR)
X crm->typ = CORR;
X else
X crm->typ = DOOR;
X#else
X crm->typ = (typ == SCORR) ? CORR : DOOR;
X#endif
X if(crm->typ == DOOR) crm->doormask = D_NODOOR;
X goto proceed;
X }
X }
Xnextnxy: ;
X }
Xnextpos:
X nx = x;
X ny = y;
X gx = egrd->gdx;
X gy = egrd->gdy;
X dx = (gx > x) ? 1 : (gx < x) ? -1 : 0;
X dy = (gy > y) ? 1 : (gy < y) ? -1 : 0;
X if(abs(gx-x) >= abs(gy-y)) nx += dx; else ny += dy;
X
X while((typ = (crm = &levl[nx][ny])->typ) != 0) {
X /* in view of the above we must have IS_WALL(typ) or typ == POOL */
X /* must be a wall here */
X if(isok(nx+nx-x,ny+ny-y) && !IS_POOL(typ) &&
X IS_ROOM(levl[nx+nx-x][ny+ny-y].typ)){
X crm->typ = DOOR;
X crm->doormask = D_NODOOR;
X goto proceed;
X }
X if(dy && nx != x) {
X nx = x; ny = y+dy;
X continue;
X }
X if(dx && ny != y) {
X ny = y; nx = x+dx; dy = 0;
X continue;
X }
X /* I don't like this, but ... */
X if(IS_ROOM(typ)) {
X crm->typ = DOOR;
X crm->doormask = D_NODOOR;
X goto proceed;
X }
X break;
X }
X crm->typ = CORR;
Xproceed:
X if (cansee(nx,ny))
X newsym(nx,ny);
X
X fcp = &(egrd->fakecorr[egrd->fcend]);
X if(egrd->fcend++ == FCSIZ) panic("fakecorr overflow");
X fcp->fx = nx;
X fcp->fy = ny;
X fcp->ftyp = typ;
Xnewpos:
X if(egrd->gddone) {
X /* The following is a kluge. We need to keep */
X /* the guard around in order to be able to make */
X /* the fake corridor disappear as the player */
X /* moves out of it, but we also need the guard */
X /* out of the way. We send the guard to never- */
X /* never land. We set ogx ogy to mx my in order */
X /* to avoid a check at the top of this function. */
X /* At the end of the process, the guard is killed */
X /* in restfakecorr(). */
Xcleanup:
X x = grd->mx; y = grd->my;
X
X wallify_vault(grd);
X remove_monster(grd->mx, grd->my);
X newsym(grd->mx,grd->my);
X place_monster(grd, 0, 0);
X egrd->ogx = grd->mx;
X egrd->ogy = grd->my;
X restfakecorr(grd);
X if(!semi_dead && (in_fcorridor(grd, u.ux, u.uy) ||
X cansee(x, y))) {
X if (!disappear_msg_seen)
X pline("Suddenly, the guard disappears.");
X return(1);
X }
X return(-2);
X }
X egrd->ogx = grd->mx; /* update old positions */
X egrd->ogy = grd->my;
X remove_monster(grd->mx, grd->my);
X place_monster(grd, nx, ny);
X newsym(grd->mx,grd->my);
X restfakecorr(grd);
X return(1);
X}
X
X/* Routine when dying or quitting with a vault guard around */
Xvoid
Xpaygd()
X{
X
X register struct monst *grd = findgd();
X struct obj *gold;
X int gx,gy;
X char buf[BUFSZ];
X
X if (!u.ugold || !grd) return;
X
X if (u.uinvault) {
X Your("%ld zorkmid%s goes into the Magic Memory Vault.",
X u.ugold, plur(u.ugold));
X gx = u.ux;
X gy = u.uy;
X } else {
X if(grd->mpeaceful) { /* guard has no "right" to your gold */
X mongone(grd);
X return;
X }
X mnexto(grd);
X pline("%s remits your gold to the vault.", Monnam(grd));
X gx = rooms[EGD(grd)->vroom].lx + rn2(2);
X gy = rooms[EGD(grd)->vroom].ly + rn2(2);
X Sprintf(buf,
X "To Croesus: here's the gold recovered from the %s %s...",
X player_mon()->mname, plname);
X make_engr_at(gx, gy, buf, 0L, ENGRAVE);
X }
X place_object(gold = mkgoldobj(u.ugold), gx, gy);
X stackobj(gold);
X mongone(grd);
X}
X
Xlong
Xhidden_gold()
X{
X register long value = 0L;
X register struct obj *obj;
X
X for (obj = invent; obj; obj = obj->nobj)
X if (Is_container(obj))
X value += contained_gold(obj);
X
X return(value);
X}
X
X#ifdef SOUNDS
Xboolean
Xgd_sound() /* prevent "You hear footsteps.." when inappropriate */
X{
X register struct monst *grd = findgd();
X
X return(grd == (struct monst *)0);
X}
X#endif
X
X#endif /* OVLB */
X
X/*vault.c*/
END_OF_FILE
if test 18951 -ne `wc -c <'src/vault.c'`; then
echo shar: \"'src/vault.c'\" unpacked with wrong size!
fi
# end of 'src/vault.c'
fi
echo shar: End of archive 66 \(of 108\).
cp /dev/null ark66isdone
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 57 58 59 60 \
61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
101 102 103 104 105 106 107 108 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 108 archives.
echo "Now execute 'rebuild.sh'"
rm -f ark10[0-8]isdone 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