home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Usenet 1994 January
/
usenetsourcesnewsgroupsinfomagicjanuary1994.iso
/
sources
/
games
/
volume16
/
nethack31
/
part73
< prev
next >
Wrap
Internet Message Format
|
1993-02-06
|
60KB
Path: uunet!news.tek.com!master!saab!billr
From: billr@saab.CNA.TEK.COM (Bill Randle)
Newsgroups: comp.sources.games
Subject: v16i081: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part73/108
Message-ID: <4444@master.CNA.TEK.COM>
Date: 5 Feb 93 19:19:47 GMT
Sender: news@master.CNA.TEK.COM
Lines: 2273
Approved: billr@saab.CNA.TEK.COM
Xref: uunet comp.sources.games:1632
Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
Posting-number: Volume 16, Issue 81
Archive-name: nethack31/Part73
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 73 (of 108)."
# Contents: src/polyself.c src/trap.c1 src/version.c
# Wrapped by billr@saab on Wed Jan 27 16:09:16 1993
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/polyself.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/polyself.c'\"
else
echo shar: Extracting \"'src/polyself.c'\" \(23505 characters\)
sed "s/^X//" >'src/polyself.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)polyself.c 3.1 92/11/24
X/* Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
X/* NetHack may be freely redistributed. See license for details. */
X
X/* Polymorph self routine. */
X
X#include "hack.h"
X
X#ifdef OVLB
X#ifdef POLYSELF
Xstatic void NDECL(polyman);
Xstatic void NDECL(break_armor);
Xstatic void FDECL(drop_weapon,(int));
Xstatic void NDECL(skinback);
Xstatic void NDECL(uunstick);
Xstatic int FDECL(armor_to_dragon,(int));
X
X/* make a (new) human out of the player */
Xstatic void
Xpolyman()
X{
X boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
X
X if (u.umonnum != -1) {
X u.acurr = u.macurr; /* restore old attribs */
X u.amax = u.mamax;
X u.umonnum = -1;
X flags.female = u.mfemale;
X }
X u.usym = S_HUMAN;
X set_uasmon();
X
X u.mh = u.mhmax = 0;
X u.mtimedone = 0;
X skinback();
X u.uundetected = 0;
X newsym(u.ux,u.uy);
X
X if (sticky) uunstick();
X find_ac();
X if(!Levitation && !u.ustuck &&
X (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy)))
X spoteffects();
X}
X#endif /* POLYSELF */
X
Xvoid
Xchange_sex()
X{
X flags.female = !flags.female;
X max_rank_sz();
X if (pl_character[0] == 'P')
X Strcpy(pl_character+6, flags.female ? "ess" : "");
X if (pl_character[0] == 'C')
X Strcpy(pl_character+4, flags.female ? "woman" : "man");
X}
X
Xvoid
Xnewman()
X{
X int tmp, tmp2;
X
X if (!rn2(10)) change_sex();
X
X tmp = u.uhpmax;
X tmp2 = u.ulevel;
X u.ulevel = u.ulevel-2+rn2(5);
X if (u.ulevel > 127 || u.ulevel == 0) u.ulevel = 1;
X if (u.ulevel > MAXULEV) u.ulevel = MAXULEV;
X
X adjabil(tmp2, (int)u.ulevel);
X
X /* random experience points for the new experience level */
X u.uexp = rndexp();
X#ifndef LINT
X u.uhpmax = (u.uhpmax-10)*(long)u.ulevel/tmp2 + 19 - rn2(19);
X#endif
X/* If it was u.uhpmax*u.ulevel/tmp+9-rn2(19), then a 1st level character
X with 16 hp who polymorphed into a 3rd level one would have an average
X of 48 hp. */
X#ifdef LINT
X u.uhp = u.uhp + tmp;
X#else
X u.uhp = u.uhp * (long)u.uhpmax/tmp;
X#endif
X
X tmp = u.uenmax;
X#ifndef LINT
X u.uenmax = u.uenmax * (long)u.ulevel/tmp2 + 9 - rn2(19);
X#endif
X if (u.uenmax < 0) u.uenmax = 0;
X#ifndef LINT
X u.uen = (tmp ? u.uen * (long)u.uenmax / tmp : u.uenmax);
X#endif
X
X redist_attr();
X u.uhunger = rn1(500,500);
X newuhs(FALSE);
X Sick = 0;
X Stoned = 0;
X if (u.uhp <= 0 || u.uhpmax <= 0) {
X#ifdef POLYSELF
X if(Polymorph_control) {
X if (u.uhp <= 0) u.uhp = 1;
X if (u.uhpmax <= 0) u.uhpmax = 1;
X } else {
X#endif
X Your("new form doesn't seem healthy enough to survive.");
X killer_format = KILLED_BY_AN;
X killer="unsuccessful polymorph";
X done(DIED);
X pline("Revived, you are in just as bad a shape as before.");
X done(DIED);
X#ifdef POLYSELF
X }
X#endif
X }
X#ifdef POLYSELF
X polyman();
X#endif
X You("feel like a new %sman!", flags.female ? "wo" : "");
X flags.botl = 1;
X (void) encumber_msg();
X}
X
X#ifdef POLYSELF
Xvoid
Xpolyself()
X{
X char buf[BUFSZ];
X int mntmp = -1;
X int tries=0;
X boolean draconian = (uarm &&
X uarm->otyp >= GRAY_DRAGON_SCALE_MAIL &&
X uarm->otyp <= YELLOW_DRAGON_SCALES);
X
X boolean iswere = (u.ulycn > -1 || is_were(uasmon));
X boolean isvamp = (u.usym == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT);
X
X if(!Polymorph_control && !draconian && !iswere && !isvamp) {
X if (rn2(20) > ACURR(A_CON)) {
X You(shudder_for_moment);
X losehp(rn2(30),"system shock", KILLED_BY_AN);
X exercise(A_CON, FALSE);
X return;
X }
X }
X
X if (Polymorph_control) {
X do {
X getlin("Become what kind of monster? [type the name]",
X buf);
X mntmp = name_to_mon(buf);
X if (mntmp < 0)
X pline("I've never heard of such monsters.");
X /* Note: humans are illegal as monsters, but an
X * illegal monster forces newman(), which is what we
X * want if they specified a human.... */
X else if (!polyok(&mons[mntmp]) &&
X ((pl_character[0] == 'E') ? !is_elf(&mons[mntmp])
X : !is_human(&mons[mntmp])) )
X You("cannot polymorph into that.");
X else break;
X } while(++tries < 5);
X if (tries==5) pline(thats_enough_tries);
X /* allow skin merging, even when polymorph is controlled */
X if (draconian &&
X (mntmp == armor_to_dragon(uarm->otyp) || tries == 5))
X goto do_merge;
X } else if (draconian || iswere || isvamp) {
X /* special changes that don't require polyok() */
X if (draconian) {
X do_merge:
X mntmp = armor_to_dragon(uarm->otyp);
X if (!(mons[mntmp].geno & G_GENOD)) {
X /* allow G_EXTINCT */
X You("merge with your scaly armor.");
X uskin = uarm;
X uarm = (struct obj *)0;
X }
X } else if (iswere) {
X if (is_were(uasmon))
X mntmp = PM_HUMAN; /* Illegal; force newman() */
X else
X mntmp = u.ulycn;
X } else {
X if (u.usym == S_VAMPIRE)
X mntmp = PM_VAMPIRE_BAT;
X else
X mntmp = PM_VAMPIRE;
X }
X if (polymon(mntmp))
X return;
X }
X
X if (mntmp < 0) {
X tries = 0;
X do {
X mntmp = rn2(PM_ARCHEOLOGIST);
X /* All valid monsters are from 0 to PM_ARCHEOLOGIST-1 */
X } while(!polyok(&mons[mntmp]) && tries++ < 200);
X }
X
X /* The below polyok() fails either if everything is genocided, or if
X * we deliberately chose something illegal to force newman().
X */
X if (!polyok(&mons[mntmp]) || !rn2(5))
X newman();
X else if(!polymon(mntmp)) return;
X
X if (!uarmg) selftouch("No longer petrify-resistant, you");
X}
X
X/* (try to) make a mntmp monster out of the player */
Xint
Xpolymon(mntmp) /* returns 1 if polymorph successful */
Xint mntmp;
X{
X boolean sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
X boolean dochange = FALSE;
X int tmp;
X
X if (mons[mntmp].geno & G_GENOD) { /* allow G_EXTINCT */
X You("feel rather %s-ish.",mons[mntmp].mname);
X exercise(A_WIS, TRUE);
X return(0);
X }
X
X if (u.umonnum == -1) {
X /* Human to monster; save human stats */
X u.macurr = u.acurr;
X u.mamax = u.amax;
X u.mfemale = flags.female;
X } else {
X /* Monster to monster; restore human stats, to be
X * immediately changed to provide stats for the new monster
X */
X u.acurr = u.macurr;
X u.amax = u.mamax;
X flags.female = u.mfemale;
X }
X
X if (is_male(&mons[mntmp])) {
X if(flags.female) dochange = TRUE;
X } else if (is_female(&mons[mntmp])) {
X if(!flags.female) dochange = TRUE;
X } else if (!is_neuter(&mons[mntmp])) {
X if(!rn2(10)) dochange = TRUE;
X }
X if (dochange) {
X flags.female = !flags.female;
X You("%s %s %s!",
X (u.umonnum != mntmp) ? "turn into a" : "feel like a new",
X flags.female ? "female" : "male",
X mons[mntmp].mname);
X } else {
X if (u.umonnum != mntmp)
X You("turn into %s!", an(mons[mntmp].mname));
X else
X You("feel like a new %s!", mons[mntmp].mname);
X }
X
X u.umonnum = mntmp;
X u.usym = mons[mntmp].mlet;
X set_uasmon();
X
X /* New stats for monster, to last only as long as polymorphed.
X * Currently only strength gets changed.
X */
X if(strongmonst(&mons[mntmp])) ABASE(A_STR) = AMAX(A_STR) = 118;
X
X if (resists_ston(uasmon) && Stoned) { /* parnes@eniac.seas.upenn.edu */
X Stoned = 0;
X You("no longer seem to be petrifying.");
X }
X if (u.usym == S_FUNGUS && Sick) {
X Sick = 0;
X You("no longer feel sick.");
X }
X
X if (u.usym == S_DRAGON && mntmp >= PM_GRAY_DRAGON)
X u.mhmax = 8 * mons[mntmp].mlevel;
X else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp);
X else {
X /*
X tmp = adj_lev(&mons[mntmp]);
X * We can't do this, since there's no such thing as an
X * "experience level of you as a monster" for a polymorphed
X * character.
X */
X tmp = mons[mntmp].mlevel;
X if (!tmp) u.mhmax = rnd(4);
X else u.mhmax = d(tmp, 8);
X }
X u.mh = u.mhmax;
X
X u.mtimedone = rn1(500, 500);
X if (u.ulevel < mons[mntmp].mlevel)
X /* Low level characters can't become high level monsters for long */
X#ifdef DUMB
X {
X /* DRS/NS 2.2.6 messes up -- Peter Kendell */
X int mtd = u.mtimedone,
X ulv = u.ulevel,
X mlv = mons[mntmp].mlevel;
X
X u.mtimedone = mtd * ulv / mlv;
X }
X#else
X u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel;
X#endif
X
X if (uskin && mntmp != armor_to_dragon(uskin->otyp))
X skinback();
X break_armor();
X drop_weapon(1);
X if (hides_under(uasmon))
X u.uundetected = OBJ_AT(u.ux, u.uy);
X else
X u.uundetected = 0;
X newsym(u.ux,u.uy); /* Change symbol */
X
X if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0;
X else if (sticky && !sticks(uasmon)) uunstick();
X
X if (flags.verbose) {
X static const char use_thec[] = "Use the command #%s to %s.";
X static const char monsterc[] = "monster";
X if (can_breathe(uasmon))
X pline(use_thec,monsterc,"use your breath weapon");
X if (attacktype(uasmon, AT_SPIT))
X pline(use_thec,monsterc,"spit venom");
X if (u.usym == S_NYMPH)
X pline(use_thec,monsterc,"remove an iron ball");
X if (u.usym == S_UMBER)
X pline(use_thec,monsterc,"confuse monsters");
X if (is_hider(uasmon))
X pline(use_thec,monsterc,"hide");
X if (is_were(uasmon))
X pline(use_thec,monsterc,"summon help");
X if (webmaker(uasmon))
X pline(use_thec,monsterc,"spin a web");
X if (u.umonnum == PM_GREMLIN)
X pline(use_thec,monsterc,"multiply in a fountain");
X if (u.usym == S_UNICORN)
X pline(use_thec,monsterc,"use your horn");
X if (u.umonnum == PM_MIND_FLAYER)
X pline(use_thec,monsterc,"for a mental blast");
X if (uasmon->msound == MS_SHRIEK) /* worthless, actually */
X pline(use_thec,monsterc,"shriek");
X if ((lays_eggs(uasmon) || u.umonnum==PM_QUEEN_BEE) && flags.female)
X pline(use_thec,"sit","lay an egg");
X }
X find_ac();
X if((!Levitation && !u.ustuck && !is_flyer(uasmon) &&
X (is_pool(u.ux,u.uy) || is_lava(u.ux,u.uy))) ||
X (Underwater && !is_swimmer(uasmon)))
X spoteffects();
X if (passes_walls(uasmon) && u.utrap && u.utraptype == TT_INFLOOR) {
X u.utrap = 0;
X pline("The rock seems to no longer trap you.");
X }
X flags.botl = 1;
X vision_full_recalc = 1;
X exercise(A_CON, FALSE);
X exercise(A_WIS, TRUE);
X (void) encumber_msg();
X return(1);
X}
X
Xstatic void
Xbreak_armor()
X{
X struct obj *otmp;
X
X if (breakarm(uasmon)) {
X if (otmp = uarm) {
X if (donning(otmp)) cancel_don();
X You("break out of your armor!");
X exercise(A_STR, FALSE);
X (void) Armor_gone();
X useup(otmp);
X }
X if (otmp = uarmc) {
X if(otmp->oartifact) {
X Your("cloak falls off!");
X (void) Cloak_off();
X dropx(otmp);
X } else {
X Your("cloak tears apart!");
X (void) Cloak_off();
X useup(otmp);
X }
X }
X#ifdef TOURIST
X if (uarmu) {
X Your("shirt rips to shreds!");
X useup(uarmu);
X }
X#endif
X } else if (sliparm(uasmon)) {
X if (otmp = uarm) {
X if (donning(otmp)) cancel_don();
X Your("armor falls around you!");
X (void) Armor_gone();
X dropx(otmp);
X }
X if (otmp = uarmc) {
X if (is_whirly(uasmon))
X Your("cloak falls, unsupported!");
X else You("shrink out of your cloak!");
X (void) Cloak_off();
X dropx(otmp);
X }
X#ifdef TOURIST
X if (otmp = uarmu) {
X if (is_whirly(uasmon))
X You("seep right through your shirt!");
X else You("become much too small for your shirt!");
X setworn((struct obj *)0, otmp->owornmask & W_ARMU);
X dropx(otmp);
X }
X#endif
X }
X if (nohands(uasmon) || verysmall(uasmon)) {
X if (otmp = uarmg) {
X if (donning(otmp)) cancel_don();
X /* Drop weapon along with gloves */
X You("drop your gloves%s!", uwep ? " and weapon" : "");
X drop_weapon(0);
X (void) Gloves_off();
X dropx(otmp);
X }
X if (otmp = uarms) {
X You("can no longer hold your shield!");
X (void) Shield_off();
X dropx(otmp);
X }
X if (otmp = uarmh) {
X if (donning(otmp)) cancel_don();
X Your("helmet falls to the floor!");
X (void) Helmet_off();
X dropx(otmp);
X }
X if (otmp = uarmf) {
X if (donning(otmp)) cancel_don();
X if (is_whirly(uasmon))
X Your("boots fall away!");
X else Your("boots %s off your feet!",
X verysmall(uasmon) ? "slide" : "are pushed");
X (void) Boots_off();
X dropx(otmp);
X }
X }
X}
X
Xstatic void
Xdrop_weapon(alone)
Xint alone;
X{
X struct obj *otmp;
X if (otmp = uwep) {
X /* !alone check below is currently superfluous but in the
X * future it might not be so if there are monsters which cannot
X * wear gloves but can wield weapons
X */
X if (!alone || cantwield(uasmon)) {
X if (alone) You("find you must drop your weapon!");
X uwepgone();
X dropx(otmp);
X }
X }
X}
X
Xvoid
Xrehumanize()
X{
X polyman();
X You("return to %sn form!", (pl_character[0] == 'E')? "elve" : "huma");
X
X if (u.uhp < 1) done(DIED);
X if (!uarmg) selftouch("No longer petrify-resistant, you");
X nomul(0);
X
X flags.botl = 1;
X vision_full_recalc = 1;
X (void) encumber_msg();
X}
X
Xint
Xdobreathe() {
X if (Strangled) {
X You("can't breathe. Sorry.");
X return(0);
X }
X if (!getdir(NULL)) return(0);
X if (rn2(4))
X You("produce a loud and noxious belch.");
X else {
X register struct attack *mattk;
X register int i;
X
X for(i = 0; i < NATTK; i++) {
X mattk = &(uasmon->mattk[i]);
X if(mattk->aatyp == AT_BREA) break;
X }
X buzz((int) (20 + mattk->adtyp-1), (int)mattk->damn,
X u.ux, u.uy, u.dx, u.dy);
X }
X return(1);
X}
X
Xint
Xdospit() {
X struct obj *otmp;
X
X if (!getdir(NULL)) return(0);
X otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM, TRUE, FALSE);
X otmp->spe = 1; /* to indicate it's yours */
X (void) throwit(otmp);
X return(1);
X}
X
Xint
Xdoremove() {
X if (!Punished) {
X You("are not chained to anything!");
X return(0);
X }
X unpunish();
X return(1);
X}
X
Xint
Xdospinweb()
X{
X register struct trap *ttmp = t_at(u.ux,u.uy);
X
X if (Levitation || Is_airlevel(&u.uz)
X || Underwater || Is_waterlevel(&u.uz)) {
X You("must be on the ground to spin a web.");
X return(0);
X }
X if (u.uswallow) {
X You("release web fluid inside %s.", mon_nam(u.ustuck));
X if (is_animal(u.ustuck->data)) {
X expels(u.ustuck, u.ustuck->data, TRUE);
X return(0);
X }
X if (is_whirly(u.ustuck->data)) {
X int i;
X
X for (i = 0; i < NATTK; i++)
X if (u.ustuck->data->mattk[i].aatyp == AT_ENGL)
X break;
X if (i == NATTK)
X impossible("Swallower has no engulfing attack?");
X else {
X char sweep[30];
X
X sweep[0] = '\0';
X switch(u.ustuck->data->mattk[i].adtyp) {
X case AD_FIRE:
X Strcpy(sweep, "ignites and ");
X break;
X case AD_ELEC:
X Strcpy(sweep, "fries and ");
X break;
X case AD_COLD:
X Strcpy(sweep,
X "freezes, shatters and ");
X break;
X }
X pline("The web %sis swept away!", sweep);
X }
X return(0);
X } /* default: a nasty jelly-like creature */
X pline("The web dissolves into %s.", mon_nam(u.ustuck));
X return(0);
X }
X if (u.utrap) {
X You("cannot spin webs while stuck in a trap.");
X return(0);
X }
X exercise(A_DEX, TRUE);
X if (ttmp) switch (ttmp->ttyp) {
X case PIT:
X case SPIKED_PIT: You("spin a web, covering up the pit.");
X deltrap(ttmp);
X delallobj(u.ux, u.uy);
X if (Invisible) newsym(u.ux, u.uy);
X return(1);
X case SQKY_BOARD: pline("The squeaky board is muffled.");
X deltrap(ttmp);
X if (Invisible) newsym(u.ux, u.uy);
X return(1);
X case TELEP_TRAP:
X case LEVEL_TELEP:
X Your("webbing vanishes!");
X return(0);
X case WEB: You("make the web thicker.");
X return(1);
X case TRAPDOOR:
X You("web over the trap door.");
X deltrap(ttmp);
X if (Invisible) newsym(u.ux, u.uy);
X return 1;
X case ARROW_TRAP:
X case DART_TRAP:
X case BEAR_TRAP:
X case LANDMINE:
X case SLP_GAS_TRAP:
X case RUST_TRAP:
X case MAGIC_TRAP:
X case ANTI_MAGIC:
X case POLY_TRAP:
X You("have triggered a trap!");
X dotrap(ttmp);
X return(1);
X default:
X impossible("Webbing over trap type %d?", ttmp->ttyp);
X return(0);
X }
X ttmp = maketrap(u.ux, u.uy, WEB);
X ttmp->tseen = 1;
X if (Invisible) newsym(u.ux, u.uy);
X return(1);
X}
X
Xint
Xdosummon()
X{
X You("call upon your brethren for help!");
X exercise(A_WIS, TRUE);
X if (!were_summon(uasmon,TRUE))
X pline("But none arrive.");
X return(1);
X}
X
Xint
Xdoconfuse()
X{
X register struct monst *mtmp;
X int looked = 0;
X char qbuf[QBUFSZ];
X
X if (Blind) {
X You("can't see anything to gaze at.");
X return 0;
X }
X for (mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X if (canseemon(mtmp)) {
X looked = 1;
X if (Invis && !perceives(mtmp->data))
X pline("%s seems not to notice your gaze.", Monnam(mtmp));
X else if (mtmp->minvis && !See_invisible)
X You("can't see where to gaze at %s.", Monnam(mtmp));
X else if (mtmp->m_ap_type == M_AP_FURNITURE
X || mtmp->m_ap_type == M_AP_OBJECT)
X continue;
X else if (flags.safe_dog && !Confusion && !Hallucination
X && mtmp->mtame) {
X if (mtmp->mnamelth)
X You("avoid gazing at %s.", NAME(mtmp));
X else
X You("avoid gazing at your %s.",
X mtmp->data->mname);
X } else {
X if (flags.confirm && mtmp->mpeaceful && !Confusion
X && !Hallucination) {
X Sprintf(qbuf, "Really confuse %s?", mon_nam(mtmp));
X if (yn(qbuf) != 'y') continue;
X setmangry(mtmp);
X }
X if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleep ||
X !mtmp->mcansee || !haseyes(mtmp->data))
X continue;
X if (!mtmp->mconf)
X Your("gaze confuses %s!", mon_nam(mtmp));
X else
X pline("%s is getting more and more confused.",
X Monnam(mtmp));
X mtmp->mconf = 1;
X if ((mtmp->data==&mons[PM_FLOATING_EYE]) && !mtmp->mcan) {
X You("are frozen by %s gaze!",
X s_suffix(mon_nam(mtmp)));
X nomul((u.ulevel > 6 || rn2(4)) ?
X -d((int)mtmp->m_lev+1,
X (int)mtmp->data->mattk[0].damd)
X : -200);
X return 1;
X }
X if ((mtmp->data==&mons[PM_MEDUSA]) && !mtmp->mcan) {
X pline("Gazing at the awake Medusa is not a very good idea.");
X /* as if gazing at a sleeping anything is fruitful... */
X You("turn to stone...");
X done(STONING);
X }
X }
X }
X }
X if (!looked) You("gaze at no place in particular.");
X return 1;
X}
X
Xint
Xdohide()
X{
X if (u.uundetected || u.usym == S_MIMIC_DEF) {
X You("are already hiding.");
X return(0);
X }
X if (u.usym == S_MIMIC) {
X u.usym = S_MIMIC_DEF;
X } else {
X u.uundetected = 1;
X }
X newsym(u.ux,u.uy);
X return(1);
X}
X
Xint
Xdomindblast()
X{
X struct monst *mtmp, *nmon;
X
X You("concentrate.");
X if (rn2(3)) return 0;
X pline("A wave of psychic energy pours out.");
X for(mtmp=fmon; mtmp; mtmp = nmon) {
X int u_sen;
X
X nmon = mtmp->nmon;
X if (distu(mtmp->mx, mtmp->my) > BOLT_LIM * BOLT_LIM)
X continue;
X if(mtmp->mpeaceful)
X continue;
X u_sen = telepathic(mtmp->data) && !mtmp->mcansee;
X if (u_sen || (telepathic(mtmp->data) && rn2(2)) || !rn2(10)) {
X pline("You lock in on %s's %s.", mon_nam(mtmp),
X u_sen ? "telepathy" :
X telepathic(mtmp->data) ? "latent telepathy" :
X "mind");
X mtmp->mhp -= rnd(15);
X if (mtmp->mhp <= 0)
X killed(mtmp);
X }
X }
X return 1;
X}
X
Xstatic void
Xuunstick()
X{
X pline("%s is no longer in your clutches.", Monnam(u.ustuck));
X u.ustuck = 0;
X}
X
Xstatic void
Xskinback()
X{
X if (uskin) {
X Your("skin returns to its original form.");
X uarm = uskin;
X uskin = (struct obj *)0;
X }
X}
X#endif
X
X#endif /* OVLB */
X#ifdef OVL1
Xconst char *
Xbody_part(part)
Xint part;
X{
X /* Note: it is assumed these will never be >22 characters long,
X * plus the trailing null, after pluralizing (since sometimes a
X * buffer is made a fixed size and must be able to hold it)
X */
X static const char NEARDATA *humanoid_parts[] = { "arm", "eye", "face", "finger",
X "fingertip", "foot", "hand", "handed", "head", "leg",
X "light headed", "neck", "spine", "toe" };
X#ifdef POLYSELF
X static const char NEARDATA *jelly_parts[] = { "pseudopod", "dark spot", "front",
X "pseudopod extension", "pseudopod extremity",
X "pseudopod root", "grasp", "grasped", "cerebral area",
X "lower pseudopod", "viscous", "middle", "surface",
X "pseudopod extremity" },
X NEARDATA *animal_parts[] = { "forelimb", "eye", "face", "foreclaw", "claw tip",
X "rear claw", "foreclaw", "clawed", "head", "rear limb",
X "light headed", "neck", "spine", "rear claw tip" },
X NEARDATA *horse_parts[] = { "forelimb", "eye", "face", "forehoof", "hoof tip",
X "rear hoof", "foreclaw", "hooved", "head", "rear limb",
X "light headed", "neck", "backbone", "rear hoof tip" },
X NEARDATA *sphere_parts[] = { "appendage", "optic nerve", "body", "tentacle",
X "tentacle tip", "lower appendage", "tentacle", "tentacled",
X "body", "lower tentacle", "rotational", "equator", "body",
X "lower tentacle tip" },
X NEARDATA *fungus_parts[] = { "mycelium", "visual area", "front", "hypha",
X "hypha", "root", "strand", "stranded", "cap area",
X "rhizome", "sporulated", "stalk", "root", "rhizome tip" },
X NEARDATA *vortex_parts[] = { "region", "eye", "front", "minor current",
X "minor current", "lower current", "swirl", "swirled",
X "central core", "lower current", "addled", "center",
X "currents", "edge" },
X NEARDATA *snake_parts[] = { "vestigial limb", "eye", "face", "large scale",
X "large scale tip", "rear region", "scale gap", "scale gapped",
X "head", "rear region", "light headed", "neck", "length",
X "rear scale" };
X
X if (humanoid(uasmon) && (part==ARM || part==FINGER || part==FINGERTIP
X || part==HAND || part==HANDED)) return humanoid_parts[part];
X if (u.usym==S_CENTAUR || u.usym==S_UNICORN) return horse_parts[part];
X if (slithy(uasmon)) return snake_parts[part];
X if (u.usym==S_EYE) return sphere_parts[part];
X if (u.usym==S_JELLY || u.usym==S_PUDDING || u.usym==S_BLOB)
X return jelly_parts[part];
X if (u.usym==S_VORTEX || u.usym==S_ELEMENTAL) return vortex_parts[part];
X if (u.usym==S_FUNGUS) return fungus_parts[part];
X if (humanoid(uasmon)) return humanoid_parts[part];
X return animal_parts[part];
X#else
X return humanoid_parts[part];
X#endif
X}
X
X#endif /* OVL1 */
X#ifdef OVL0
X
Xint
Xpoly_gender()
X{
X/* Returns gender of polymorphed player; 0/1=same meaning as flags.female,
X * 2=none.
X * Used in:
X * - Seduction by succubus/incubus
X * - Talking to nymphs (sounds.c)
X * Not used in:
X * - Messages given by nymphs stealing armor (they can't steal from
X * incubi/succubi/nymphs, and nonhumanoids can't wear armor).
X * - Amulet of change (must refer to real gender no matter what
X * polymorphed into).
X * - Priest/Priestess, Caveman/Cavewoman (ditto)
X * - Polymorph self (only happens when human)
X * - Shopkeeper messages (since referred to as "creature" and not "sir"
X * or "lady" when polymorphed)
X */
X#ifdef POLYSELF
X if (!humanoid(uasmon)) return 2;
X#endif
X return flags.female;
X}
X
X#endif /* OVL0 */
X#ifdef OVLB
X
X#if defined(POLYSELF)
Xvoid
Xugolemeffects(damtype, dam)
Xint damtype, dam;
X{
X int heal = 0;
X /* We won't bother with "slow"/"haste" since players do not
X * have a monster-specific slow/haste so there is no way to
X * restore the old velocity once they are back to human.
X */
X if (u.umonnum != PM_FLESH_GOLEM && u.umonnum != PM_IRON_GOLEM)
X return;
X switch (damtype) {
X case AD_ELEC: if (u.umonnum == PM_IRON_GOLEM)
X heal = dam / 6; /* Approx 1 per die */
X break;
X case AD_FIRE: if (u.umonnum == PM_IRON_GOLEM)
X heal = dam;
X break;
X }
X if (heal && (u.mh < u.mhmax)) {
X u.mh += heal;
X if (u.mh > u.mhmax) u.mh = u.mhmax;
X flags.botl = 1;
X pline("Strangely, you feel better than before.");
X exercise(A_STR, TRUE);
X }
X}
X
Xstatic int
Xarmor_to_dragon(atyp)
Xint atyp;
X{
X switch(atyp) {
X case GRAY_DRAGON_SCALE_MAIL:
X case GRAY_DRAGON_SCALES:
X return PM_GRAY_DRAGON;
X case RED_DRAGON_SCALE_MAIL:
X case RED_DRAGON_SCALES:
X return PM_RED_DRAGON;
X case ORANGE_DRAGON_SCALE_MAIL:
X case ORANGE_DRAGON_SCALES:
X return PM_ORANGE_DRAGON;
X case WHITE_DRAGON_SCALE_MAIL:
X case WHITE_DRAGON_SCALES:
X return PM_WHITE_DRAGON;
X case BLACK_DRAGON_SCALE_MAIL:
X case BLACK_DRAGON_SCALES:
X return PM_BLACK_DRAGON;
X case BLUE_DRAGON_SCALE_MAIL:
X case BLUE_DRAGON_SCALES:
X return PM_BLUE_DRAGON;
X case GREEN_DRAGON_SCALE_MAIL:
X case GREEN_DRAGON_SCALES:
X return PM_GREEN_DRAGON;
X case YELLOW_DRAGON_SCALE_MAIL:
X case YELLOW_DRAGON_SCALES:
X return PM_YELLOW_DRAGON;
X default:
X return -1;
X }
X}
X#endif /* POLYSELF */
X
X#endif /* OVLB */
X
X/*polyself.c*/
END_OF_FILE
if test 23505 -ne `wc -c <'src/polyself.c'`; then
echo shar: \"'src/polyself.c'\" unpacked with wrong size!
fi
# end of 'src/polyself.c'
fi
if test -f 'src/trap.c1' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/trap.c1'\"
else
echo shar: Extracting \"'src/trap.c1'\" \(29997 characters\)
sed "s/^X//" >'src/trap.c1' <<'END_OF_FILE'
X/* SCCS Id: @(#)trap.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#ifdef OVLB
Xconst char *traps[TRAPNUM] = {
X "",
X "n arrow trap",
X " dart trap",
X " falling rock trap",
X " squeaky board",
X " bear trap",
X " land mine",
X " sleeping gas trap",
X " rust trap",
X " fire trap",
X " pit",
X " spiked pit",
X " trapdoor",
X " teleportation trap",
X " level teleporter",
X " magic portal",
X " web",
X " statue trap",
X " magic trap",
X "n anti-magic field"
X#ifdef POLYSELF
X ," polymorph trap"
X#endif
X};
X
X#endif /* OVLB */
X
Xstatic void FDECL(domagicportal,(struct trap *));
Xstatic void NDECL(dofiretrap);
Xstatic void NDECL(domagictrap);
Xstatic boolean FDECL(emergency_disrobe,(boolean *));
XSTATIC_DCL boolean FDECL(thitm, (int, struct monst *, struct obj *, int));
X
X#ifdef OVLB
X
Xstatic int FDECL(teleok, (int,int,BOOLEAN_P));
Xstatic void NDECL(vtele);
Xstatic void FDECL(no_fall_through, (BOOLEAN_P));
X
X/* Generic rust-armor function. Returns TRUE if a message was printed;
X * "print", if set, means to print a message (and thus to return TRUE) even
X * if the item could not be rusted; otherwise a message is printed and TRUE is
X * returned only for rustable items.
X */
Xboolean
Xrust_dmg(otmp, ostr, type, print)
Xregister struct obj *otmp;
Xregister const char *ostr;
Xint type;
Xboolean print;
X{
X static const char NEARDATA *action[] = { "smoulder", "rust", "rot", "corrode" };
X static const char NEARDATA *msg[] = { "burnt", "rusted", "rotten", "corroded" };
X boolean vulnerable = FALSE;
X boolean plural;
X boolean grprot = FALSE;
X
X if (!otmp) return(FALSE);
X switch(type) {
X case 0:
X case 2: vulnerable = is_flammable(otmp); break;
X case 1: vulnerable = is_rustprone(otmp); grprot = TRUE; break;
X case 3: vulnerable = is_corrodeable(otmp); grprot = TRUE; break;
X }
X
X if (!print && (!vulnerable || otmp->oerodeproof || otmp->oeroded == MAX_ERODE))
X return FALSE;
X
X plural = is_gloves(otmp) || is_boots(otmp);
X
X if (!vulnerable)
X if (flags.verbose)
X Your("%s %s not affected.", ostr, plural ? "are" : "is");
X else if (otmp->oeroded < MAX_ERODE) {
X if (grprot && otmp->greased)
X grease_protect(otmp,ostr,plural);
X else if (otmp->oerodeproof || (otmp->blessed && !rnl(4))) {
X if (flags.verbose)
X pline("Somehow, your %s %s not affected.",
X ostr, plural ? "are" : "is");
X } else {
X Your("%s %s%s%s!", ostr, action[type],
X plural ? "" : "s",
X otmp->oeroded+1 == MAX_ERODE ? " completely" :
X otmp->oeroded ? " further" : "");
X otmp->oeroded++;
X }
X } else
X if (flags.verbose)
X Your("%s %s%s completely %s.", ostr,
X Blind ? "feel" : "look",
X plural ? "" : "s", msg[type]);
X return(TRUE);
X}
X
Xvoid
Xgrease_protect(otmp,ostr,plu)
Xregister struct obj *otmp;
Xregister const char *ostr;
Xregister boolean plu;
X{
X static const char txt[] = "protected by the layer of grease!";
X
X if (ostr)
X Your("%s %s %s",ostr,plu ? "are" : "is",txt);
X else
X Your("%s %s",aobjnam(otmp,"are"),txt);
X if (!rn2(2)) {
X pline("The grease dissolves.");
X otmp->greased = 0;
X }
X}
X
Xstruct trap *
Xmaketrap(x,y,typ)
Xregister int x, y, typ;
X{
X register struct trap *ttmp;
X register boolean oldplace;
X
X if (ttmp = t_at(x,y)) {
X oldplace = TRUE;
X if (u.utrap && (x == u.ux) && (y == u.uy) &&
X ((u.utraptype == TT_BEARTRAP && typ != BEAR_TRAP) ||
X (u.utraptype == TT_WEB && typ != WEB) ||
X (u.utraptype == TT_PIT && typ != PIT && typ != SPIKED_PIT)))
X u.utrap = 0;
X } else {
X oldplace = FALSE;
X ttmp = newtrap();
X ttmp->tx = x;
X ttmp->ty = y;
X }
X ttmp->ttyp = typ;
X switch(typ) {
X case STATUE_TRAP: /* create a "living" statue */
X (void) mkcorpstat(STATUE, &mons[rndmonnum()], x, y, FALSE);
X break;
X case PIT:
X case SPIKED_PIT:
X case TRAPDOOR:
X levl[x][y].doormask = 0; /* subsumes altarmask, icedpool... */
X if (IS_ROOM(levl[x][y].typ))
X levl[x][y].typ = ROOM;
X break;
X }
X ttmp->tseen = 0;
X ttmp->once = 0;
X ttmp->dst.dnum = -1;
X ttmp->dst.dlevel = -1;
X if (!oldplace) {
X ttmp->ntrap = ftrap;
X ftrap = ttmp;
X }
X return(ttmp);
X}
X
Xstatic int
Xteleok(x, y, trapok)
Xregister int x, y;
Xboolean trapok;
X{ /* might throw him into a POOL
X * removed by GAN 10/20/86
X */
X#ifdef STUPID
X boolean tmp1, tmp2, tmp3, tmp4;
X# ifdef POLYSELF
X tmp1 = isok(x,y) && (!IS_ROCK(levl[x][y].typ) ||
X passes_walls(uasmon)) && !MON_AT(x, y);
X# else
X tmp1 = isok(x,y) && !IS_ROCK(levl[x][y].typ) && !MON_AT(x, y);
X# endif
X tmp2 = !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y));
X tmp3 = !(is_pool(x,y) &&
X !(Levitation || Wwalking || Magical_breathing
X# ifdef POLYSELF
X || is_flyer(uasmon) || is_swimmer(uasmon)
X || is_clinger(uasmon)
X# endif
X )) && !closed_door(x,y);
X tmp4 = !is_lava(x,y);
X return(tmp1 && tmp2 && tmp3 && tmp4);
X#else
X return( isok(x,y) &&
X# ifdef POLYSELF
X (!IS_ROCK(levl[x][y].typ) || passes_walls(uasmon)) &&
X# else
X !IS_ROCK(levl[x][y].typ) &&
X# endif
X !MON_AT(x, y) &&
X !sobj_at(BOULDER,x,y) && (trapok || !t_at(x,y)) &&
X !(is_pool(x,y) &&
X !(Levitation || Wwalking || Magical_breathing
X# ifdef POLYSELF
X || is_flyer(uasmon) || is_swimmer(uasmon)
X || is_clinger(uasmon)
X# endif
X )) && !is_lava(x,y) && !closed_door(x,y));
X#endif
X /* Note: gold is permitted (because of vaults) */
X}
X
Xboolean
Xsafe_teleds()
X{
X register int nux, nuy;
X short tcnt = 0;
X
X do {
X nux = rnd(COLNO-1);
X nuy = rn2(ROWNO);
X } while (!teleok(nux, nuy, tcnt>200) && tcnt++ < 400);
X
X if (tcnt < 400) {
X teleds(nux, nuy);
X return TRUE;
X } else
X return FALSE;
X}
X
Xstatic void
Xvtele()
X{
X register struct mkroom *croom = search_special(VAULT);
X coord c;
X
X if(croom && somexy(croom, &c) && teleok(c.x,c.y,FALSE)) {
X teleds(c.x,c.y);
X return;
X }
X tele();
X}
X
Xstatic void
Xno_fall_through(td)
Xboolean td;
X{
X /* floor objects get a chance of falling down. the case
X * where the hero does NOT fall down is treated here. the
X * case where the hero does fall down is treated in goto_level().
X * reason: the target level of the fall is not determined here,
X * and it need not be the next level. if we want falling
X * objects to arrive near the player, we must call impact_drop()
X * _after_ the target level is determined.
X */
X impact_drop((struct obj *)0, u.ux, u.uy, 0);
X if (!td) {
X display_nhwindow(WIN_MESSAGE, FALSE);
X pline("The opening under you closes up.");
X }
X}
X
Xvoid
Xfall_through(td)
Xboolean td; /* td == TRUE : trapdoor */
X{
X register int newlevel = dunlev(&u.uz);
X
X if(Blind && Levitation) return;
X
X do {
X newlevel++;
X } while(!rn2(4) && newlevel < dunlevs_in_dungeon(&u.uz));
X
X if(td) pline("A trap door opens up under you!");
X else pline("The floor opens up under you!");
X
X if(Levitation || u.ustuck || !Can_fall_thru(&u.uz)
X#ifdef POLYSELF
X || is_flyer(uasmon) || is_clinger(uasmon)
X#endif
X || (Inhell && !u.uevent.invoked &&
X newlevel == dunlevs_in_dungeon(&u.uz))
X ) {
X You("don't fall in.");
X no_fall_through(td);
X return;
X }
X#ifdef WALKIES
X if(!next_to_u()) {
X You("are jerked back by your pet!");
X no_fall_through(td);
X return;
X }
X#endif
X if(*u.ushops) shopdig(1);
X if(Is_stronghold(&u.uz)) goto_hell(TRUE, TRUE);
X else {
X d_level dtmp;
X dtmp.dnum = u.uz.dnum;
X dtmp.dlevel = newlevel;
X goto_level(&dtmp, FALSE, TRUE, FALSE);
X if(!td) pline("The hole in the ceiling above you closes up.");
X }
X}
X
Xvoid
Xdotrap(trap)
Xregister struct trap *trap;
X{
X register int ttype = trap->ttyp;
X register struct monst *mtmp;
X register struct obj *otmp;
X
X nomul(0);
X if(trap->tseen && !Fumbling &&
X#ifdef POLYSELF
X !((ttype == PIT || ttype == SPIKED_PIT) && !is_clinger(uasmon)) &&
X#else
X !(ttype == PIT || ttype == SPIKED_PIT) &&
X#endif
X !(ttype == MAGIC_PORTAL || ttype == ANTI_MAGIC) && !rn2(5))
X You("escape a%s.", traps[ttype]);
X else {
X seetrap(trap);
X switch(ttype) {
X case ARROW_TRAP:
X pline("An arrow shoots out at you!");
X otmp = mksobj(ARROW, TRUE, FALSE);
X otmp->quan = 1L;
X otmp->owt = weight(otmp);
X if(thitu(8,dmgval(otmp,uasmon),otmp,"arrow"))
X obfree(otmp, (struct obj *)0);
X else {
X place_object(otmp, u.ux, u.uy);
X otmp->nobj = fobj;
X fobj = otmp;
X stackobj(otmp);
X newsym(u.ux, u.uy);
X }
X break;
X case DART_TRAP:
X pline("A little dart shoots out at you!");
X otmp = mksobj(DART, TRUE, FALSE);
X otmp->quan = 1L;
X otmp->owt = weight(otmp);
X if (!rn2(6)) otmp->opoisoned = 1;
X if(thitu(7,dmgval(otmp,uasmon),otmp,"little dart")) {
X if (otmp->opoisoned)
X poisoned("dart",A_CON,"poison dart",10);
X obfree(otmp, (struct obj *)0);
X } else {
X place_object(otmp, u.ux, u.uy);
X otmp->nobj = fobj;
X fobj = otmp;
X stackobj(otmp);
X newsym(u.ux, u.uy);
X }
X break;
X case ROCKTRAP:
X {
X int dmg = d(2,6); /* should be std ROCK dmg? */
X
X otmp = mksobj_at(ROCK, u.ux, u.uy, TRUE);
X otmp->quan = 1L;
X otmp->owt = weight(otmp);
X
X pline("A trap door in the ceiling opens and a rock falls on your %s!",
X body_part(HEAD));
X
X if (uarmh)
X if(is_metallic(uarmh)) {
X pline("Fortunately, you are wearing a hard helmet.");
X dmg = 2;
X } else if (flags.verbose)
X Your("%s does not protect you.", xname(uarmh));
X
X stackobj(otmp);
X newsym(u.ux,u.uy); /* map the rock */
X
X losehp(dmg, "falling rock", KILLED_BY_AN);
X exercise(A_STR, FALSE);
X }
X break;
X
X case SQKY_BOARD: /* stepped on a squeaky board */
X if (Levitation
X#ifdef POLYSELF
X || is_flyer(uasmon) || is_clinger(uasmon)
X#endif
X ) {
X if (Hallucination) You("notice a crease in the linoleum.");
X else You("notice a loose board below you.");
X } else {
X pline("A board beneath you squeaks loudly.");
X wake_nearby();
X }
X break;
X
X case BEAR_TRAP:
X if(Levitation
X#ifdef POLYSELF
X || is_flyer(uasmon)) {
X You("%s over a bear trap.",
X Levitation ? "float" : "fly");
X#else
X ) {
X You("float over a bear trap.");
X#endif
X break;
X }
X#ifdef POLYSELF
X if(amorphous(uasmon)) {
X pline("A bear trap closes harmlessly through you.");
X break;
X }
X#endif
X u.utrap = rn1(4, 4);
X u.utraptype = TT_BEARTRAP;
X pline("A bear trap closes on your %s!",
X body_part(FOOT));
X#ifdef POLYSELF
X if(u.umonnum == PM_OWLBEAR || u.umonnum == PM_BUGBEAR)
X You("howl in anger!");
X#endif
X exercise(A_DEX, FALSE);
X break;
X
X case SLP_GAS_TRAP:
X if(Sleep_resistance) {
X You("are enveloped in a cloud of gas!");
X break;
X }
X pline("A cloud of gas puts you to sleep!");
X flags.soundok = 0;
X nomul(-rnd(25));
X u.usleep = 1;
X nomovemsg = "You wake up.";
X afternmv = Hear_again;
X break;
X
X case RUST_TRAP:
X#ifdef POLYSELF
X if (u.umonnum == PM_IRON_GOLEM) {
X pline("A gush of water hits you!");
X You("are covered with rust!");
X rehumanize();
X break;
X } else
X if (u.umonnum == PM_GREMLIN && rn2(3)) {
X pline("A gush of water hits you!");
X if(mtmp = cloneu()) {
X mtmp->mhpmax = (u.mhmax /= 2);
X You("multiply.");
X }
X break;
X }
X#endif
X /* Unlike monsters, traps cannot aim their rust attacks at
X * you, so instead of looping through and taking either the
X * first rustable one or the body, we take whatever we get,
X * even if it is not rustable.
X */
X switch (rn2(5)) {
X case 0:
X pline("A gush of water hits you on the %s!",
X body_part(HEAD));
X (void) rust_dmg(uarmh, "helmet", 1, TRUE);
X break;
X case 1:
X pline("A gush of water hits your left %s!",
X body_part(ARM));
X if (rust_dmg(uarms, "shield", 1, TRUE)) break;
X if (uwep && bimanual(uwep))
X goto two_hand;
X /* Two goto statements in a row--aaarrrgggh! */
Xglovecheck: (void) rust_dmg(uarmg, "gauntlets", 1, TRUE);
X /* Not "metal gauntlets" since it gets called
X * even if it's leather for the message
X */
X break;
X case 2:
X pline("A gush of water hits your right %s!",
X body_part(ARM));
Xtwo_hand: erode_weapon(FALSE);
X goto glovecheck;
X default:
X pline("A gush of water hits you!");
X if (uarmc) (void) rust_dmg(uarmc, "cloak", 1, TRUE);
X else if (uarm)
X (void) rust_dmg(uarm, "armor", 1, TRUE);
X#ifdef TOURIST
X else if (uarmu)
X (void) rust_dmg(uarmu, "shirt", 1, TRUE);
X#endif
X }
X break;
X
X case FIRE_TRAP:
X dofiretrap();
X break;
X
X case PIT:
X if (Levitation
X#ifdef POLYSELF
X || is_flyer(uasmon) || is_clinger(uasmon)
X#endif
X ) {
X if(Blind) break;
X if(trap->tseen)
X You("see a pit below you.");
X else {
X pline("A pit opens up under you!");
X You("don't fall in!");
X }
X break;
X }
X You("fall into a pit!");
X#ifdef POLYSELF
X if (!passes_walls(uasmon))
X#endif
X u.utrap = rn1(6,2);
X u.utraptype = TT_PIT;
X losehp(rnd(6),"fell into a pit", NO_KILLER_PREFIX);
X if (Punished && !carried(uball)) {
X unplacebc();
X ballfall();
X placebc();
X }
X selftouch("Falling, you");
X exercise(A_STR, FALSE);
X vision_full_recalc = 1; /* vision limits change */
X break;
X case SPIKED_PIT:
X if (Levitation
X#ifdef POLYSELF
X || is_flyer(uasmon) || is_clinger(uasmon)
X#endif
X ) {
X if(Blind) break;
X pline("A pit full of spikes opens up under you!");
X You("don't fall in!");
X break;
X }
X You("fall into a pit!");
X You("land on a set of sharp iron spikes!");
X#ifdef POLYSELF
X if (!passes_walls(uasmon))
X#endif
X u.utrap = rn1(6,2);
X u.utraptype = TT_PIT;
X losehp(rnd(10),"fell into a pit of iron spikes",
X NO_KILLER_PREFIX);
X if(!rn2(6)) poisoned("spikes",A_STR,"fall onto poison spikes",8);
X if (Punished && !carried(uball)) {
X unplacebc();
X ballfall();
X placebc();
X }
X selftouch("Falling, you");
X vision_full_recalc = 1; /* vision limits change */
X exercise(A_STR, FALSE);
X exercise(A_DEX, FALSE);
X break;
X
X case TRAPDOOR:
X if(!Can_fall_thru(&u.uz))
X panic("Trapdoors cannot exist on this level.");
X fall_through(TRUE);
X break;
X
X case TELEP_TRAP:
X if(In_endgame(&u.uz) || Antimagic) {
X if(Antimagic)
X shieldeff(u.ux, u.uy);
X You("feel a wrenching sensation.");
X#ifdef WALKIES
X } else if(!next_to_u()) {
X You(shudder_for_moment);
X#endif
X } else if(trap->once) {
X deltrap(trap);
X newsym(u.ux,u.uy); /* get rid of trap symbol */
X vtele();
X } else
X tele();
X break;
X case LEVEL_TELEP:
X You("%s onto a level teleport trap!",
X Levitation ? (const char *)"float" :
X#ifdef POLYSELF
X locomotion(uasmon, "step"));
X#else
X (const char *)"step");
X#endif
X if(Antimagic) {
X shieldeff(u.ux, u.uy);
X }
X if(Antimagic || In_endgame(&u.uz)) {
X You("feel a wrenching sensation.");
X break;
X }
X if(!Blind)
X You("are momentarily blinded by a flash of light.");
X else
X You("are momentarily disoriented.");
X deltrap(trap);
X newsym(u.ux,u.uy); /* get rid of trap symbol */
X level_tele();
X break;
X
X case WEB: /* Our luckless player has stumbled into a web. */
X#ifdef POLYSELF
X if (amorphous(uasmon)) {
X if (acidic(uasmon) || u.umonnum == PM_GELATINOUS_CUBE)
X {
X deltrap(trap);
X newsym(u.ux,u.uy);/* update position */
X You("dissolve a spider web.");
X break;
X }
X You("flow through a spider web.");
X break;
X }
X if (uasmon->mlet == S_SPIDER) {
X pline("There is a spider web here.");
X break;
X }
X#endif
X You("%s into a spider web!",
X Levitation ? (const char *)"float" :
X#ifdef POLYSELF
X locomotion(uasmon, "stumble"));
X#else
X (const char *)"stumble");
X#endif
X u.utraptype = TT_WEB;
X
X /* Time stuck in the web depends on your strength. */
X {
X register int str = ACURR(A_STR);
X
X if (str == 3) u.utrap = rn1(6,6);
X else if (str < 6) u.utrap = rn1(6,4);
X else if (str < 9) u.utrap = rn1(4,4);
X else if (str < 12) u.utrap = rn1(4,2);
X else if (str < 15) u.utrap = rn1(2,2);
X else if (str < 18) u.utrap = rnd(2);
X else if (str < 69) u.utrap = 1;
X else {
X u.utrap = 0;
X You("tear through the web!");
X deltrap(trap);
X newsym(u.ux,u.uy); /* get rid of trap symbol */
X }
X }
X break;
X
X case STATUE_TRAP:
X deltrap(trap);
X newsym(u.ux,u.uy); /* get rid of trap symbol */
X for(otmp=level.objects[u.ux][u.uy];
X otmp; otmp = otmp->nexthere)
X if(otmp->otyp == STATUE)
X if(mtmp=makemon(&mons[otmp->corpsenm],u.ux,u.uy)) {
X pline("The statue comes to life!");
X /* mimic statues become seen mimics */
X if(mtmp->m_ap_type) seemimic(mtmp);
X delobj(otmp);
X break;
X }
X break;
X
X case MAGIC_TRAP: /* A magic trap. */
X if (!rn2(30)) {
X deltrap(trap);
X newsym(u.ux,u.uy); /* update position */
X You("are caught in a magical explosion!");
X losehp(rnd(10), "magical explosion", KILLED_BY_AN);
X Your("body absorbs some of the magical energy!");
X u.uen = (u.uenmax += 2);
X } else domagictrap();
X break;
X
X case ANTI_MAGIC:
X if(Antimagic) {
X shieldeff(u.ux, u.uy);
X You("feel momentarily lethargic.");
X } else drain_en(rnd((int)u.ulevel) + 1);
X break;
X
X#ifdef POLYSELF
X case POLY_TRAP:
X if(Antimagic) {
X shieldeff(u.ux, u.uy);
X You("feel momentarily different.");
X /* Trap did nothing; don't remove it --KAA */
X } else {
X deltrap(trap); /* delete trap before polymorph */
X newsym(u.ux,u.uy); /* get rid of trap symbol */
X You("feel a change coming over you.");
X polyself();
X }
X break;
X#endif
X
X case LANDMINE: {
X if (Levitation
X#ifdef POLYSELF
X || is_flyer(uasmon)
X#endif
X ) {
X You("see a trigger in a pile of soil below you.");
X if (rn2(3)) break;
X pline("KAABLAMM!!! The air currents set it off!");
X } else {
X pline("KAABLAMM!!! You triggered a land mine!");
X set_wounded_legs(LEFT_SIDE, rn1(35, 41));
X set_wounded_legs(RIGHT_SIDE, rn1(35, 41));
X }
X losehp(rnd(16), "land mine", KILLED_BY_AN);
X /* wake everything on the level */
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon) {
X if(mtmp->msleep) mtmp->msleep = 0;
X }
X deltrap(t_at(u.ux, u.uy)); /* mines only explode once */
X newsym(u.ux,u.uy); /* get rid of trap symbol */
X }
X break;
X
X case MAGIC_PORTAL:
X#ifdef WALKIES
X if(!next_to_u())
X You(shudder_for_moment);
X else
X#endif
X domagicportal(trap);
X break;
X
X default:
X impossible("You hit a trap of type %u", trap->ttyp);
X }
X }
X}
X
X#endif /* OVLB */
X
X#ifdef WALKIES
X
XSTATIC_DCL boolean FDECL(teleport_pet, (struct monst *));
X
X#ifdef OVLB
X
XSTATIC_OVL boolean
Xteleport_pet(mtmp)
Xregister struct monst *mtmp;
X{
X register struct obj *otmp;
X
X if(mtmp->mleashed) {
X otmp = get_mleash(mtmp);
X if(!otmp)
X impossible("%s is leashed, without a leash.", Monnam(mtmp));
X if(otmp->cursed) {
X# ifdef SOUNDS
X yelp(mtmp);
X# endif
X return FALSE;
X } else {
X Your("leash goes slack.");
X m_unleash(mtmp);
X return TRUE;
X }
X }
X return TRUE;
X}
X
X#endif /* OVLB */
X
X#endif /* WALKIES */
X
X#ifdef OVLB
X
Xvoid
Xseetrap(trap)
X register struct trap *trap;
X{
X if(!trap->tseen) {
X trap->tseen = 1;
X newsym(trap->tx, trap->ty);
X }
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xint
Xmintrap(mtmp)
Xregister struct monst *mtmp;
X{
X register struct trap *trap = t_at(mtmp->mx, mtmp->my);
X boolean trapkilled = FALSE, tdoor = FALSE;
X struct permonst *mptr = mtmp->data;
X struct obj *otmp;
X
X if(!trap) {
X mtmp->mtrapped = 0; /* perhaps teleported? */
X } else if (mtmp->mtrapped) { /* was in trap */
X if(!rn2(40))
X if (sobj_at(BOULDER, mtmp->mx, mtmp->my) &&
X ((trap->ttyp == PIT) ||
X (trap->ttyp == SPIKED_PIT))) {
X if (!rn2(2)) {
X mtmp->mtrapped = 0;
X fill_pit(mtmp->mx, mtmp->my);
X }
X } else
X mtmp->mtrapped = 0;
X } else {
X register int tt = trap->ttyp;
X
X /* A bug fix for dumb messages by ab@unido.
X */
X int in_sight = canseemon(mtmp);
X
X if(mtmp->mtrapseen & (1 << tt)) {
X /* it has been in such a trap - perhaps it escapes */
X if(rn2(4)) return(0);
X }
X mtmp->mtrapseen |= (1 << tt);
X switch (tt) {
X case ARROW_TRAP:
X otmp = mksobj(ARROW, TRUE, FALSE);
X otmp->quan = 1L;
X otmp->owt = weight(otmp);
X if(in_sight) seetrap(trap);
X if(thitm(8, mtmp, otmp, 0)) trapkilled = TRUE;
X break;
X case DART_TRAP:
X otmp = mksobj(DART, TRUE, FALSE);
X otmp->quan = 1L;
X otmp->owt = weight(otmp);
X if (!rn2(6)) otmp->opoisoned = 1;
X if(in_sight) seetrap(trap);
X if(thitm(7, mtmp, otmp, 0)) trapkilled = TRUE;
X break;
X case ROCKTRAP:
X otmp = mksobj(ROCK, TRUE, FALSE);
X otmp->quan = 1L;
X otmp->owt = weight(otmp);
X if(in_sight) seetrap(trap);
X if(!is_whirly(mptr) && !passes_walls(mptr) &&
X thitm(0, mtmp, otmp, d(2, 6)))
X trapkilled = TRUE;
X break;
X
X case SQKY_BOARD: {
X register struct monst *ztmp = fmon;
X
X if(is_flyer(mptr)) break;
X /* stepped on a squeaky board */
X if (in_sight) {
X pline("A board beneath %s squeaks loudly.", mon_nam(mtmp));
X seetrap(trap);
X } else
X You("hear a distant squeak.");
X /* wake up nearby monsters */
X while(ztmp) {
X if(dist2(mtmp->mx,mtmp->my,ztmp->mx,ztmp->my) < 40)
X if(ztmp->msleep) ztmp->msleep = 0;
X ztmp = ztmp->nmon;
X }
X break;
X }
X
X case BEAR_TRAP:
X if(mptr->msize > MZ_SMALL &&
X !amorphous(mptr) && !is_flyer(mptr)) {
X mtmp->mtrapped = 1;
X if(in_sight) {
X pline("%s is caught in a bear trap!",
X Monnam(mtmp));
X seetrap(trap);
X } else
X if((mptr == &mons[PM_OWLBEAR]
X || mptr == &mons[PM_BUGBEAR])
X && flags.soundok)
X You("hear the roaring of an angry bear!");
X }
X break;
X
X case SLP_GAS_TRAP:
X if(!resists_sleep(mptr) &&
X !mtmp->msleep && mtmp->mcanmove) {
X mtmp->mcanmove = 0;
X mtmp->mfrozen = rnd(25);
X if (in_sight) {
X pline("%s suddenly falls asleep!",
X Monnam(mtmp));
X seetrap(trap);
X }
X }
X break;
X
X case RUST_TRAP:
X if (in_sight) {
X pline("A gush of water hits %s!", mon_nam(mtmp));
X seetrap(trap);
X }
X if (mptr == &mons[PM_IRON_GOLEM]) {
X if (in_sight)
X pline("%s falls to pieces!", Monnam(mtmp));
X else if(mtmp->mtame)
X pline("May %s rust in peace.",
X mon_nam(mtmp));
X mondied(mtmp);
X trapkilled = TRUE;
X } else if (mptr == &mons[PM_GREMLIN] && rn2(3)) {
X struct monst *mtmp2 = clone_mon(mtmp);
X
X if (mtmp2) {
X mtmp2->mhpmax = (mtmp->mhpmax /= 2);
X if(in_sight)
X pline("%s multiplies.", Monnam(mtmp));
X }
X }
X break;
X
X case FIRE_TRAP:
X if (in_sight)
X pline("A tower of flame bursts from the floor under %s!",
X mon_nam(mtmp));
X if(resists_fire(mptr)) {
X if (in_sight) {
X shieldeff(mtmp->mx,mtmp->my);
X pline("%s is uninjured.", Monnam(mtmp));
X }
X } else {
X int num=rnd(6);
X
X if (thitm(0, mtmp, (struct obj *)0, num))
X trapkilled = TRUE;
X else mtmp->mhpmax -= num;
X }
X (void) destroy_mitem(mtmp, SCROLL_CLASS, AD_FIRE);
X (void) destroy_mitem(mtmp, SPBOOK_CLASS, AD_FIRE);
X (void) destroy_mitem(mtmp, POTION_CLASS, AD_FIRE);
X if (in_sight) seetrap(trap);
X break;
X
X case PIT:
X case SPIKED_PIT:
X if ( !is_flyer(mptr) &&
X (!mtmp->wormno || (count_wsegs(mtmp) < 6)) &&
X !is_clinger(mptr) ) {
X if (!passes_walls(mptr))
X mtmp->mtrapped = 1;
X if(in_sight) {
X pline("%s falls into a pit!", Monnam(mtmp));
X seetrap(trap);
X }
X if(thitm(0, mtmp, (struct obj *)0,
X rnd((tt==PIT) ? 6 : 10)))
X trapkilled = TRUE;
X }
X break;
X
X case TRAPDOOR:
X if(!Can_fall_thru(&u.uz))
X panic("Trapdoors cannot exist on this level.");
X
X if ( (mptr == &mons[PM_WUMPUS]) ||
X (mtmp->wormno && count_wsegs(mtmp) > 5) ) break;
X tdoor = TRUE;
X /* Fall through */
X case LEVEL_TELEP:
X /* long worms w/tails can now change levels! - Norm */
X if (!is_flyer(mptr)) {
X register int nlev;
X d_level tolevel;
X#ifdef WALKIES
X if(teleport_pet(mtmp)) {
X#endif
X if(tdoor) {
X if(Is_stronghold(&u.uz))
X assign_level(&tolevel, &valley_level);
X else if(Is_botlevel(&u.uz)) {
X pline("%s avoids the trap.",
X Monnam(mtmp));
X break;
X } else get_level(&tolevel,depth(&u.uz)+1);
X } else {
X#ifdef MULDGN
X if(Is_knox(&u.uz)) {
X rloc(mtmp);
X break;
X }
X#endif
X nlev = rnd(3);
X if(!rn2(2)) nlev = -(nlev);
X nlev = dunlev(&u.uz) + nlev;
X if(nlev > dunlevs_in_dungeon(&u.uz)) {
X nlev = dunlevs_in_dungeon(&u.uz);
X /* teleport up if already on bottom */
X if (Is_botlevel(&u.uz))
X nlev -= rnd(3);
X }
X if (nlev < 1) {
X nlev = 1;
X if (dunlev(&u.uz) == 1) {
X nlev += rnd(3);
X if (nlev >
X dunlevs_in_dungeon(&u.uz))
X nlev =
X dunlevs_in_dungeon(&u.uz);
X }
X }
X /* can't seem to go anywhere */
X /* (possible in short dungeons) */
X if (nlev == dunlev(&u.uz)) {
X rloc(mtmp);
X break;
X }
X nlev = dungeons[u.uz.dnum].depth_start +
X nlev;
X get_level(&tolevel, nlev);
X }
X if(in_sight) {
X pline("Suddenly, %s disappears out of sight.", mon_nam(mtmp));
X seetrap(trap);
X }
X migrate_to_level(mtmp,
X ledger_no(&tolevel), 0);
X return(3); /* no longer on this level */
X#ifdef WALKIES
X }
X#endif
X }
X break;
X
X case TELEP_TRAP:
X case MAGIC_PORTAL:
X#ifdef WALKIES
X if(teleport_pet(mtmp)) {
X#endif
X /* Note: don't remove the trap if a vault. Other-
X * wise the monster will be stuck there, since
X * the guard isn't going to come for it...
X * Also: don't remove if magic portal. In short,
X * don't remove :-)
X */
X if (in_sight) {
X pline("%s suddenly disappears!",
X Monnam(mtmp));
X seetrap(trap);
X }
X if (trap->once) vloc(mtmp);
X else rloc(mtmp);
X#ifdef WALKIES
X }
X#endif
X break;
X
X case WEB:
X /* Monster in a web. */
X if (mptr->mlet == S_SPIDER) break;
X if (amorphous(mptr)) {
X if (acidic(mptr) ||
X mptr == &mons[PM_GELATINOUS_CUBE]) {
X if (in_sight)
X pline("%s dissolves a spider web.",
X Monnam(mtmp));
X deltrap(trap);
X break;
X }
X if (in_sight)
X pline("%s flows through a spider web.",
X Monnam(mtmp));
X break;
X }
X switch (monsndx(mptr)) {
X case PM_FIRE_ELEMENTAL:
X if (in_sight)
X pline("%s burns a spider web!", Monnam(mtmp));
X deltrap(trap);
X break;
X case PM_OWLBEAR: /* Eric Backus */
X case PM_BUGBEAR:
X if (!in_sight) {
X You("hear the roaring of a confused bear!");
X mtmp->mtrapped = 1;
X break;
X }
X /* fall though */
X default:
X if (in_sight)
X pline("%s is caught in a spider web.",
X Monnam(mtmp));
X mtmp->mtrapped = 1;
X break;
X }
X break;
X
X case STATUE_TRAP:
X break;
X
X case MAGIC_TRAP:
X /* A magic trap. Monsters immune. */
X break;
X case ANTI_MAGIC:
X break;
X
X case LANDMINE: {
X register struct monst *mntmp = fmon;
X
X if(rn2(3))
X break; /* monsters usually don't set it off */
X if(is_flyer(mptr)) {
X if (in_sight) {
X pline("A trigger appears in a pile of soil below %s.", Monnam(mtmp));
X seetrap(trap);
X }
X if (rn2(3)) break;
X if (in_sight)
X pline("The air currents set it off!");
X } else if(in_sight)
X pline("KAABLAMM!!! %s triggers a land mine!",
X Monnam(mtmp));
X if (!in_sight)
X pline("Kaablamm! You hear an explosion in the distance!");
X deltrap(trap);
X if(thitm(0, mtmp, (struct obj *)0, rnd(16)))
X trapkilled = TRUE;
X /* wake everything on the level */
X while(mntmp) {
X if(mntmp->msleep)
X mntmp->msleep = 0;
X mntmp = mntmp->nmon;
X }
X if (unconscious()) {
X multi = -1;
X nomovemsg="The explosion awakens you!";
X }
X break;
X }
X
X#ifdef POLYSELF
X case POLY_TRAP:
X if(!resist(mtmp, WAND_CLASS, 0, NOTELL)) {
X (void) newcham(mtmp, (struct permonst *)0);
X if (in_sight) seetrap(trap);
X }
X break;
X#endif
X
X default:
X impossible("Some monster encountered a strange trap of type %d.", tt);
X }
X }
X if(trapkilled) return 2;
X return mtmp->mtrapped;
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
X
Xvoid
Xselftouch(arg)
Xconst char *arg;
X{
X if(uwep && (uwep->otyp == CORPSE && uwep->corpsenm == PM_COCKATRICE)
X#ifdef POLYSELF
X && !resists_ston(uasmon)
X#endif
X ){
X pline("%s touch the cockatrice corpse.", arg);
X#ifdef POLYSELF
X if(poly_when_stoned(uasmon) && polymon(PM_STONE_GOLEM))
X return;
X#endif
X You("turn to stone...");
X killer_format = KILLED_BY;
X killer = "touching a cockatrice corpse";
X done(STONING);
X }
X}
X
Xvoid
Xfloat_up()
X{
X if(u.utrap) {
X if(u.utraptype == TT_PIT) {
X u.utrap = 0;
X You("float up, out of the pit!");
X vision_full_recalc = 1; /* vision limits change */
X fill_pit(u.ux, u.uy);
X } else if (u.utraptype == TT_INFLOOR) {
X Your("body pulls upward, but your %s are still stuck.",
X makeplural(body_part(LEG)));
X } else {
X You("float up, only your %s is still stuck.",
X body_part(LEG));
X }
X }
X else if(Is_waterlevel(&u.uz))
X pline("It feels as though you'd lost some weight.");
X else if(u.uinwater)
X spoteffects();
X else if (Hallucination)
X pline("Up, up, and awaaaay! You're walking on air!");
X else if(Is_airlevel(&u.uz))
X You("gain control over your movements.");
X else
X You("start to float in the air!");
X}
X
Xvoid
Xfill_pit(x, y)
Xint x, y;
X{
X struct obj *otmp;
X struct trap *t;
X
X if ((t = t_at(x, y)) &&
X ((t->ttyp == PIT) || (t->ttyp == SPIKED_PIT)) &&
X (otmp = sobj_at(BOULDER, x, y))) {
X freeobj(otmp);
X (void) flooreffects(otmp, x, y, "settle");
X }
X}
X
END_OF_FILE
if test 29997 -ne `wc -c <'src/trap.c1'`; then
echo shar: \"'src/trap.c1'\" unpacked with wrong size!
fi
# end of 'src/trap.c1'
fi
if test -f 'src/version.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/version.c'\"
else
echo shar: Extracting \"'src/version.c'\" \(818 characters\)
sed "s/^X//" >'src/version.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)version.c 3.1 92/01/04 */
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 "date.h"
X#ifndef BETA
X# if defined(MICRO) && !defined(AMIGA) && !defined(TOS)
X# include "patchlev.h"
X# else
X# include "patchlevel.h"
X# endif
X#endif
X
Xint
Xdoversion()
X{
X#ifdef BETA
X pline("%s NetHack Beta Version %s - last build %s.",
X#else
X pline("%s NetHack Version %s.%d - last build %s.",
X#endif
X PORT_ID, VERSION,
X#ifndef BETA
X PATCHLEVEL,
X#endif
X BUILD_DATE); /* from date.h, generated by 'makedefs' */
X return 0;
X}
X
Xint
Xdoextversion()
X{
X display_file(OPTIONS_USED, TRUE);
X return 0;
X}
X
X#ifdef MICRO
Xboolean
Xcomp_times(filetime)
Xlong filetime;
X{
X return (filetime < BUILD_TIME);
X}
X#endif
X
X/*version.c*/
END_OF_FILE
if test 818 -ne `wc -c <'src/version.c'`; then
echo shar: \"'src/version.c'\" unpacked with wrong size!
fi
# end of 'src/version.c'
fi
echo shar: End of archive 73 \(of 108\).
cp /dev/null ark73isdone
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