billr@saab.CNA.TEK.COM (Bill Randle) (07/12/90)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu>
Posting-number: Volume 10, Issue 65
Archive-name: nethack3p9/Part20
Supersedes: NetHack3: Volume 7, Issue 56-93
#! /bin/sh
# This is a shell archive. Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file". To overwrite existing
# files, type "sh file -c". You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g.. If this archive is complete, you
# will see the following message at the end:
# "End of archive 20 (of 56)."
# Contents: src/apply.c src/polyself.c
# Wrapped by billr@saab on Wed Jul 11 17:11:20 1990
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/apply.c' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/apply.c'\"
else
echo shar: Extracting \"'src/apply.c'\" \(34008 characters\)
sed "s/^X//" >'src/apply.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)apply.c 3.0 88/10/24
X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */
X/* NetHack may be freely redistributed. See license for details. */
X
X#define MONATTK_H /* comment line for pre-compiled headers */
X/* block some unused #defines to avoid overloading some cpp's */
X#include "hack.h"
X#include "edog.h"
X
X#ifdef MUSIC
X#define IS_INSTRUMENT(typ) ((typ) >= FLUTE && (typ) <= DRUM_OF_EARTHQUAKE)
X#endif /* MUSIC /**/
X
X#ifdef OVLB
X
Xstatic const char NEARDATA tools[] = { TOOL_SYM, 0 };
X
Xstatic boolean NEARDATA did_dig_msg;
X
Xstatic struct monst *FDECL(bchit, (int, int, int, CHAR_P));
Xstatic void FDECL(use_camera, (struct obj *));
Xstatic void FDECL(use_stethoscope, (struct obj *));
Xstatic void FDECL(use_whistle, (struct obj *));
Xstatic void FDECL(use_magic_whistle, (struct obj *));
X#ifdef WALKIES
Xstatic void FDECL(use_leash, (struct obj *));
X#endif
XSTATIC_DCL int NDECL(dig);
Xstatic boolean FDECL(wield_tool, (struct obj *));
Xstatic int FDECL(use_pick_axe, (struct obj *));
X#ifdef MEDUSA
Xstatic void FDECL(use_mirror, (struct obj *));
X#endif
Xstatic void FDECL(use_lamp, (struct obj *));
Xstatic void FDECL(use_crystal_ball, (struct obj *));
Xstatic void FDECL(use_tinning_kit, (struct obj *));
X
X/* version of bhit for cameras and mirrors */
Xstatic
Xstruct monst *
Xbchit(ddx,ddy,range,sym) register int ddx,ddy,range; char sym; {
X register struct monst *mtmp = (struct monst *) 0;
X register int bchx = u.ux, bchy = u.uy;
X
X if(sym) {
X Tmp_at2(-1, sym); /* open call */
X#ifdef TEXTCOLOR
X Tmp_at2(-3, WHITE);
X#endif
X }
X while(range--) {
X bchx += ddx;
X bchy += ddy;
X if(MON_AT(bchx, bchy)) {
X mtmp = m_at(bchx,bchy);
X break;
X }
X if(!ZAP_POS(levl[bchx][bchy].typ) || closed_door(bchx, bchy)) {
X bchx -= ddx;
X bchy -= ddy;
X break;
X }
X if(sym) Tmp_at2(bchx, bchy);
X }
X if(sym) Tmp_at2(-1, -1);
X return(mtmp);
X}
X
Xstatic void
Xuse_camera(obj) /* register */ struct obj *obj; {
Xregister struct monst *mtmp;
X if(!getdir(1)){ /* ask: in what direction? */
X flags.move = multi = 0;
X return;
X }
X if(u.uswallow) {
X You("take a picture of %s's %s.", mon_nam(u.ustuck),
X is_animal(u.ustuck->data)? "stomach" : "interior");
X return;
X }
X if(obj->cursed && !rn2(2)) goto blindu;
X if(u.dz) {
X You("take a picture of the %s.",
X (u.dz > 0) ? "floor" : "ceiling");
X return;
X }
X if(!u.dx && !u.dy && !u.dz) {
Xblindu:
X if(!Blind) {
X You("are blinded by the flash!");
X make_blinded((long)rnd(25),FALSE);
X }
X return;
X }
X if(mtmp = bchit(u.dx, u.dy, COLNO, '!')) {
X if(mtmp->msleep){
X mtmp->msleep = 0;
X pline("The flash awakens %s.", mon_nam(mtmp)); /* a3 */
X } else
X if(mtmp->data->mlet != S_YLIGHT)
X if(mtmp->mcansee || mtmp->mblinded){
X register int tmp = dist(mtmp->mx,mtmp->my);
X register int tmp2;
X if(cansee(mtmp->mx,mtmp->my))
X pline("%s is blinded by the flash!", Monnam(mtmp));
X if(mtmp->data == &mons[PM_GREMLIN]) {
X /* Rule #1: Keep them out of the light. */
X kludge("%s cries out in pain!", Monnam(mtmp));
X if (mtmp->mhp > 1) mtmp->mhp--;
X }
X setmangry(mtmp);
X if(tmp < 9 && !mtmp->isshk && rn2(4)) {
X mtmp->mflee = 1;
X if(rn2(4)) mtmp->mfleetim = rnd(100);
X }
X if(tmp < 3) {
X mtmp->mcansee = 0;
X mtmp->mblinded = 0;
X } else {
X tmp2 = mtmp->mblinded;
X tmp2 += rnd(1 + 50/tmp);
X if(tmp2 > 127) tmp2 = 127;
X mtmp->mblinded = tmp2;
X mtmp->mcansee = 0;
X }
X }
X }
X}
X
X/* Strictly speaking it makes no sense for usage of a stethoscope to
X not take any time; however, unless it did, the stethoscope would be
X almost useless. */
Xstatic void
Xuse_stethoscope(obj) register struct obj *obj; {
Xregister struct monst *mtmp;
Xregister struct rm *lev;
Xregister int rx, ry;
X if(!freehand()) {
X You("have no free %s!", body_part(HAND));
X return;
X }
X if (!getdir(1)) {
X flags.move=multi=0;
X return;
X }
X if(u.dz < 0 || (u.dz && Levitation)) {
X You("can't reach the %s!", u.dz<0 ? "ceiling" : "floor");
X return;
X }
X if(obj->cursed && !rn2(2)) {
X You("hear your heart beat.");
X return;
X }
X if(u.dz) {
X#ifdef STRONGHOLD
X if (dlevel == stronghold_level)
X You("hear the crackling of hellfire.");
X else
X#endif
X pline("The floor seems healthy enough.");
X return;
X }
X if (Stunned || (Confusion && !rn2(5))) confdir();
X if (!u.dx && !u.dy && !u.dz) {
X ustatusline();
X return;
X }
X rx = u.ux + u.dx; ry = u.uy + u.dy;
X if(u.uswallow) {
X mstatusline(u.ustuck);
X return;
X }
X if (!isok(rx,ry)) {
X You("hear a faint typing noise.");
X return;
X }
X lev = &levl[rx][ry];
X if(MON_AT(rx, ry)) {
X mtmp = m_at(rx,ry);
X mstatusline(mtmp);
X if (mtmp->mundetected) {
X mtmp->mundetected = 0;
X if (cansee(rx,ry)) pmon(mtmp);
X }
X return;
X }
X if(lev->typ == SDOOR) {
X You("hear a hollow sound! This must be a secret door!");
X lev->typ = DOOR;
X lev->seen = 0; /* force prl */
X prl(rx,ry);
X return;
X }
X if(lev->typ == SCORR) {
X You("hear a hollow sound! This must be a secret passage!");
X lev->typ = CORR;
X lev->seen = 0; /* force prl */
X prl(rx,ry);
X return;
X }
X You("hear nothing special.");
X}
X
X/* ARGSUSED */
Xstatic void
Xuse_whistle(obj)
Xstruct obj *obj; {
X You("produce a high whistling sound.");
X wake_nearby();
X}
X
Xstatic void
Xuse_magic_whistle(obj)
Xstruct obj *obj; {
X register struct monst *mtmp = fmon;
X
X if(obj->cursed && !rn2(2)) {
X You("produce a high-pitched humming noise.");
X wake_nearby();
X } else {
X You("produce a %s whistling sound.", Hallucination
X ? "normal" : "strange");
X while(mtmp) {
X if(mtmp->mtame) mnexto(mtmp);
X mtmp = mtmp->nmon;
X }
X }
X}
X
Xboolean
Xum_dist(x,y,n)
Xregister xchar x, y, n;
X{
X return(abs(u.ux - x) > n || abs(u.uy - y) > n);
X}
X
X#endif /* OVLB */
X
X#ifdef WALKIES
X#define MAXLEASHED 2
X
X#ifdef OVLB
X
Xint
Xnumber_leashed()
X{
X register int i = 0;
X register struct obj *obj;
X
X for(obj = invent; obj; obj = obj->nobj)
X if(obj->otyp == LEASH && obj->leashmon != 0) i++;
X return(i);
X}
X
Xvoid
Xo_unleash(otmp) /* otmp is about to be destroyed or stolen */
Xregister struct obj *otmp;
X{
X register struct monst *mtmp;
X
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->m_id == (unsigned)otmp->leashmon)
X mtmp->mleashed = 0;
X otmp->leashmon = 0;
X}
X
Xvoid
Xm_unleash(mtmp) /* mtmp is about to die, or become untame */
Xregister struct monst *mtmp;
X{
X register struct obj *otmp;
X
X for(otmp = invent; otmp; otmp = otmp->nobj)
X if(otmp->otyp == LEASH &&
X otmp->leashmon == (int)mtmp->m_id)
X otmp->leashmon = 0;
X mtmp->mleashed = 0;
X}
X
Xvoid
Xunleash_all() /* player is about to die (for bones) */
X{
X register struct obj *otmp;
X register struct monst *mtmp;
X
X for(otmp = invent; otmp; otmp = otmp->nobj)
X if(otmp->otyp == LEASH) otmp->leashmon = 0;
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->mtame) mtmp->mleashed = 0;
X}
X
X/* ARGSUSED */
Xstatic void
Xuse_leash(obj)
Xstruct obj *obj;
X{
X register int x, y;
X register struct monst *mtmp;
X
X if(!obj->leashmon && number_leashed() >= MAXLEASHED) {
X You("can't leash additional pets.");
X return;
X }
X
X if(!getdir(1)) return;
X
X x = u.ux + u.dx;
X y = u.uy + u.dy;
X
X if((x == u.ux) && (y == u.uy)) {
X pline("Leash yourself? Very funny...");
X return;
X }
X
X if(!MON_AT(x, y)) {
X pline("There is no creature here.");
X return;
X }
X
X mtmp = m_at(x, y);
X
X if(!mtmp->mtame) {
X pline("%s is not %s!", Monnam(mtmp), (!obj->leashmon) ?
X "leashable" : "leashed");
X return;
X }
X if(!obj->leashmon) {
X if(mtmp->mleashed) {
X pline("This %s is already leashed!", lmonnam(mtmp)+4);
X return;
X }
X You("slip the leash around your %s.", lmonnam(mtmp)+4);
X mtmp->mleashed = 1;
X obj->leashmon = (int)mtmp->m_id;
X if(mtmp->msleep) mtmp->msleep = 0;
X return;
X }
X if(obj->leashmon != (int)mtmp->m_id) {
X pline("This leash is not attached to that creature!");
X return;
X } else {
X if(obj->cursed) {
X pline("The leash wouldn't come off!");
X return;
X }
X mtmp->mleashed = 0;
X obj->leashmon = 0;
X You("remove the leash from your %s.",
X /* a hack to include the dogs full name. +4 eliminates */
X /* the 'the' at the start of the name */
X lmonnam(mtmp)+4);
X }
X return;
X}
X
X#endif /* OVLB */
X#ifdef OVL1
X
Xboolean
Xnext_to_u()
X{
X register struct monst *mtmp;
X register struct obj *otmp;
X
X for(mtmp = fmon; mtmp; mtmp = mtmp->nmon)
X if(mtmp->mleashed) {
X if(dist(mtmp->mx,mtmp->my) > 2) mnexto(mtmp);
X if(dist(mtmp->mx,mtmp->my) > 2) {
X for(otmp = invent; otmp; otmp = otmp->nobj)
X if(otmp->otyp == LEASH &&
X otmp->leashmon == (int)mtmp->m_id) {
X if(otmp->cursed) return(FALSE);
X You("feel %s leash go slack.",
X (number_leashed() > 1) ? "a" : "the");
X mtmp->mleashed = 0;
X otmp->leashmon = 0;
X }
X }
X }
X return(TRUE);
X}
X
X#endif /* OVL1 */
X#ifdef OVLB
Xstruct obj *
Xget_mleash(mtmp) /* assuming mtmp->mleashed has been checked */
Xregister struct monst *mtmp;
X{
X register struct obj *otmp;
X
X otmp = invent;
X while(otmp) {
X if(otmp->otyp == LEASH && otmp->leashmon == (int)mtmp->m_id)
X return(otmp);
X otmp = otmp->nobj;
X }
X return((struct obj *)0);
X}
X#endif /* OVLB */
X
X#endif /* WALKIES */
X#ifdef OVL0
X
X#ifdef WALKIES
Xvoid
Xcheck_leash(x, y)
Xregister xchar x, y;
X{
X register struct obj *otmp;
X register struct monst *mtmp = fmon;
X
X for(otmp = invent; otmp; otmp = otmp->nobj)
X if(otmp->otyp == LEASH && otmp->leashmon != 0) {
X while(mtmp) {
X if((int)mtmp->m_id == otmp->leashmon &&
X (dist2(u.ux,u.uy,mtmp->mx,mtmp->my) >
X dist2(x,y,mtmp->mx,mtmp->my))
X ) {
X if(otmp->cursed) {
X if(um_dist(mtmp->mx, mtmp->my, 5)) {
X pline("%s chokes to death!",Monnam(mtmp));
X mondied(mtmp);
X } else
X if(um_dist(mtmp->mx, mtmp->my, 3))
X pline("%s chokes on the leash!",
X Monnam(mtmp));
X } else {
X if(um_dist(mtmp->mx, mtmp->my, 5)) {
X pline("%s's leash snaps loose!",Monnam(mtmp));
X m_unleash(mtmp);
X } else {
X if(um_dist(mtmp->mx, mtmp->my, 3)) {
X You("pull on the leash.");
X# ifdef SOUNDS
X if (mtmp->data->msound != MS_SILENT)
X switch(rn2(3)) {
X case 0: growl(mtmp); break;
X case 1: yelp(mtmp); break;
X default: whimper(mtmp); break;
X }
X# endif
X }
X }
X }
X }
X mtmp = mtmp->nmon;
X }
X }
X}
X
X#endif /* WALKIES */
X
X#endif /* OVL0 */
X#ifdef OVLB
X
XSTATIC_OVL int
Xdig() {
X register struct rm *lev;
X register int dpx = dig_pos.x, dpy = dig_pos.y;
X
X lev = &levl[dpx][dpy];
X /* perhaps a nymph stole his pick-axe while he was busy digging */
X /* or perhaps he teleported away */
X if(u.uswallow || !uwep || uwep->otyp != PICK_AXE ||
X dig_level != dlevel ||
X ((dig_down && (dpx != u.ux || dpy != u.uy)) ||
X (!dig_down && dist(dpx,dpy) > 2)))
X return(0);
X
X if(dig_down && is_maze_lev) {
X pline("The floor here is too hard to dig in.");
X return(0);
X }
X if(!dig_down && IS_ROCK(lev->typ) && !may_dig(dpx,dpy)) {
X pline("This wall is too hard to dig into.");
X return(0);
X }
X if(Fumbling && !rn2(3)) {
X switch(rn2(3)) {
X case 0: if(!welded(uwep)) {
X You("fumble and drop your %s.", xname(uwep));
X dropx(uwep);
X setuwep((struct obj *)0);
X } else {
X pline("Ouch! Your %s bounces and hits you!",
X xname(uwep));
X set_wounded_legs(RIGHT_SIDE, 5 + rnd(5));
X }
X break;
X case 1: pline("Bang! You hit with the broad side of the %s!",
X xname(uwep)); break;
X default: Your("swing misses its mark.");
X break;
X }
X return(0);
X }
X dig_effort += 10 + abon() + uwep->spe + rn2(5);
X if(dig_down) {
X if(dig_effort > 250) {
X dighole();
X dig_level = -1;
X return(0); /* done with digging */
X }
X if(dig_effort > 50) {
X register struct trap *ttmp = t_at(dpx,dpy);
X
X if(!ttmp) {
X ttmp = maketrap(dpx,dpy,PIT);
X ttmp->tseen = 1;
X if(Invisible) newsym(ttmp->tx,ttmp->ty);
X You("have dug a pit.");
X u.utrap = rn1(4,2);
X u.utraptype = TT_PIT;
X dig_level = -1;
X return(0);
X }
X }
X } else
X if(dig_effort > 100) {
X register const char *digtxt;
X register struct obj *obj;
X
X if(obj = sobj_at(STATUE, dpx, dpy)) {
X if (break_statue(obj))
X digtxt = "The statue shatters.";
X else
X /* it was a statue trap; break_statue()
X * printed a message and updated the screen
X */
X digtxt = NULL;
X } else if(obj = sobj_at(BOULDER, dpx, dpy)) {
X fracture_rock(obj);
X digtxt = "The boulder falls apart.";
X } else if(!lev->typ || lev->typ == SCORR) {
X lev->typ = CORR;
X digtxt = "You succeeded in cutting away some rock.";
X } else if(IS_WALL(lev->typ)) {
X#ifdef STUPID
X if (is_maze_lev)
X lev->typ = ROOM;
X else
X lev->typ = DOOR;
X#else
X lev->typ = is_maze_lev ? ROOM : DOOR;
X#endif
X digtxt = "You just made an opening in the wall.";
X } else if(lev->typ == SDOOR) {
X lev->typ = DOOR;
X digtxt = "You just broke through a secret door.";
X if(!(lev->doormask & D_TRAPPED))
X lev->doormask = D_BROKEN;
X } else if(closed_door(dpx, dpy)) {
X digtxt = "You just broke a hole through the door.";
X if(!(lev->doormask & D_TRAPPED))
X lev->doormask = D_BROKEN;
X } else return(0); /* statue or boulder got taken */
X mnewsym(dpx, dpy);
X prl(dpx, dpy);
X if (digtxt) pline(digtxt); /* after mnewsym & prl */
X if(IS_DOOR(lev->typ) && (lev->doormask & D_TRAPPED)) {
X b_trapped("door");
X lev->doormask = D_NODOOR;
X mnewsym(dpx, dpy);
X prl(dpx, dpy);
X }
X dig_level = -1;
X return(0);
X } else {
X if(IS_WALL(lev->typ) || closed_door(dpx, dpy)) {
X register int rno = inroom(dpx,dpy);
X
X if(rno >= 0 && rooms[rno].rtype >= SHOPBASE) {
X pline("This %s seems too hard to dig into.",
X IS_DOOR(lev->typ) ? "door" : "wall");
X return(0);
X }
X } else if (!IS_ROCK(lev->typ) && !sobj_at(STATUE, dpx, dpy)
X && !sobj_at(BOULDER, dpx, dpy))
X return(0); /* statue or boulder got taken */
X if(!did_dig_msg) {
X You("hit the %s with all your might.",
X sobj_at(STATUE, dpx, dpy) ? "statue" :
X sobj_at(BOULDER, dpx, dpy) ? "boulder" :
X IS_DOOR(lev->typ) ? "door" : "rock");
X did_dig_msg = TRUE;
X }
X }
X return(1);
X}
X
X/* When will hole be finished? Very rough indication used by shopkeeper. */
Xint
Xholetime() {
X if(occupation != dig || !in_shop(u.ux, u.uy)) return(-1);
X return((250 - dig_effort)/20);
X}
X
Xvoid
Xdighole()
X{
X register struct trap *ttmp = t_at(u.ux, u.uy);
X
X if(is_maze_lev
X#ifdef ENDGAME
X || dlevel == ENDLEVEL
X#endif
X ) {
X pline("The floor here seems too hard to dig in.");
X } else {
X if(IS_FURNITURE(levl[u.ux][u.uy].typ)) {
X#if defined(ALTARS) && defined(THEOLOGY)
X if(IS_ALTAR(levl[u.ux][u.uy].typ)) {
X altar_wrath(u.ux, u.uy);
X if(in_temple(u.ux, u.uy)) angry_priest();
X }
X#endif
X levl[u.ux][u.uy].typ = ROOM;
X levl[u.ux][u.uy].altarmask = 0;
X }
X if(ttmp)
X ttmp->ttyp = TRAPDOOR;
X else
X ttmp = maketrap(u.ux, u.uy, TRAPDOOR);
X ttmp->tseen = 1;
X if(Invisible) newsym(ttmp->tx,ttmp->ty);
X pline("You've made a hole in the floor.");
X if(!u.ustuck && !Levitation) { /* KAA */
X if(in_shop(u.ux, u.uy))
X shopdig(1);
X#ifdef WALKIES
X if(!next_to_u())
X You("are jerked back by your pet!");
X else {
X#endif
X You("fall through...");
X if(u.utraptype == TT_PIT) {
X u.utrap = 0;
X u.utraptype = 0;
X }
X unsee();
X#ifdef MACOS
X segments |= SEG_APPLY;
X#endif
X goto_level(dlevel+1, FALSE, TRUE);
X#ifdef WALKIES
X }
X#endif
X }
X }
X}
X
Xstatic boolean
Xwield_tool(obj)
Xstruct obj *obj;
X{
X if(uwep && uwep->cursed) {
X /* Andreas Bormann - ihnp4!decvax!mcvax!unido!ab */
X if(flags.verbose) {
X pline("Since your weapon is welded to your %s,",
X bimanual(uwep) ?
X makeplural(body_part(HAND))
X : body_part(HAND));
X pline("you cannot wield that %s.", xname(obj));
X }
X return(FALSE);
X }
X# ifdef POLYSELF
X if(cantwield(uasmon)) {
X You("can't hold it strongly enough.");
X return(FALSE);
X }
X# endif
X unweapon = TRUE;
X You("now wield %s.", doname(obj));
X setuwep(obj);
X if (uwep != obj) return(FALSE); /* rewielded old object after dying */
X return(TRUE);
X}
X
Xstatic int
Xuse_pick_axe(obj)
Xstruct obj *obj;
X{
X char dirsyms[12];
X register char *dsp = dirsyms;
X register const char *sdp = flags.num_pad ? ndir : sdir;
X register struct rm *lev;
X register int rx, ry, res = 0;
X register boolean isclosedoor = FALSE;
X
X if(obj != uwep)
X if (!wield_tool(obj)) return(0);
X else res = 1;
X
X while(*sdp) {
X (void) movecmd(*sdp); /* sets u.dx and u.dy and u.dz */
X rx = u.ux + u.dx;
X ry = u.uy + u.dy;
X if(u.dz > 0 || (u.dz == 0 && isok(rx, ry) &&
X (IS_ROCK(levl[rx][ry].typ)
X || sobj_at(STATUE, rx, ry)
X || sobj_at(BOULDER, rx, ry))))
X *dsp++ = *sdp;
X sdp++;
X }
X *dsp = 0;
X pline("In what direction do you want to dig? [%s] ", dirsyms);
X if(!getdir(0)) /* no txt */
X return(res);
X if(u.uswallow && attack(u.ustuck)) /* return(1) */;
X else if(u.dz < 0) You("cannot reach the ceiling.");
X else if(!u.dx && !u.dy && !u.dz) {
X char buf[BUFSZ];
X int dam;
X
X dam = rnd(2) + dbon() + obj->spe;
X if (dam <= 0) dam = 1;
X You("hit yourself with your own pick-axe.");
X /* self_pronoun() won't work twice in a sentence */
X Strcpy(buf, self_pronoun("killed %sself with %%s own pick-axe",
X "him"));
X losehp(dam, self_pronoun(buf, "his"), NO_KILLER_PREFIX);
X flags.botl=1;
X return(1);
X } else if(u.dz == 0) {
X if(Stunned || (Confusion && !rn2(5))) confdir();
X rx = u.ux + u.dx;
X ry = u.uy + u.dy;
X lev = &levl[rx][ry];
X if(MON_AT(rx, ry) && attack(m_at(rx, ry)))
X return(1);
X if(!isok(rx, ry)) {
X pline("Clash!");
X return(1);
X }
X isclosedoor = closed_door(rx, ry);
X if(!IS_ROCK(lev->typ)
X && !isclosedoor
X && !sobj_at(STATUE, rx, ry)
X && !sobj_at(BOULDER, rx, ry)) {
X /* ACCESSIBLE or POOL */
X You("swing your %s through thin air.",
X aobjnam(obj, NULL));
X } else {
X if(dig_pos.x != rx || dig_pos.y != ry
X || dig_level != dlevel || dig_down) {
X dig_down = FALSE;
X dig_pos.x = rx;
X dig_pos.y = ry;
X dig_level = dlevel;
X dig_effort = 0;
X You("start %s.",
X sobj_at(STATUE, rx, ry) ?
X "chipping the statue" :
X sobj_at(BOULDER, rx, ry) ?
X "hitting the boulder" :
X isclosedoor ? "chopping at the door" :
X "digging");
X } else
X You("continue %s.",
X sobj_at(STATUE, rx, ry) ?
X "chipping the statue" :
X sobj_at(BOULDER, rx, ry) ?
X "hitting the boulder" :
X isclosedoor ? "chopping at the door" :
X "digging");
X did_dig_msg = FALSE;
X set_occupation(dig, "digging", 0);
X }
X } else if(Levitation) {
X You("cannot reach the floor.");
X } else {
X if(dig_pos.x != u.ux || dig_pos.y != u.uy
X || dig_level != dlevel || !dig_down) {
X dig_down = TRUE;
X dig_pos.x = u.ux;
X dig_pos.y = u.uy;
X dig_level = dlevel;
X dig_effort = 0;
X You("start digging in the floor.");
X if(in_shop(u.ux, u.uy))
X shopdig(0);
X } else
X You("continue digging in the floor.");
X did_dig_msg = FALSE;
X set_occupation(dig, "digging", 0);
X }
X return(1);
X}
X
X#define WEAK 3 /* from eat.c */
X
X#ifdef MEDUSA
Xstatic void
Xuse_mirror(obj)
Xstruct obj *obj;
X{
X register struct monst *mtmp;
X register char mlet;
X
X if(!getdir(1)){ /* ask: in what direction? */
X flags.move = multi = 0;
X return;
X }
X if(obj->cursed && !rn2(2)) {
X if (!Blind)
X pline("The mirror gets foggy and doesn't reflect!");
X return;
X }
X if(!u.dx && !u.dy && !u.dz) {
X if(!Blind && !Invisible) {
X#ifdef POLYSELF
X if(u.umonnum == PM_FLOATING_EYE) {
X pline("Yikes! You've frozen yourself!");
X nomul(-rnd((MAXULEV+6) - (int)u.ulevel));
X } else if (u.usym == S_VAMPIRE || u.usym == S_DEMON)
X You("don't seem to reflect anything.");
X else if(u.umonnum == PM_UMBER_HULK) {
X pline("Huh? That doesn't look like you!");
X make_confused(HConfusion + d(3,4),FALSE);
X } else
X#endif
X if (Hallucination) You("look %s.", hcolor());
X else if (Sick)
X You("look peaked.");
X else if (u.uhs >= WEAK)
X You("look undernourished.");
X#ifdef POLYSELF
X else if (u.usym == S_NYMPH
X#ifdef INFERNO
X || u.umonnum==PM_SUCCUBUS
X#endif
X )
X You("look beautiful in the mirror.");
X#ifdef INFERNO
X else if (u.umonnum == PM_INCUBUS)
X You("look handsome in the mirror.");
X#endif
X#endif
X else You("look as %s as ever.",
X ACURR(A_CHA) > 14 ?
X (poly_gender()==1 ? "beautiful" : "handsome") :
X "ugly");
X } else {
X if (Luck <= 10 && rn2(4-Luck/3) || !HTelepat ||
X (u.ukilled_medusa
X#ifdef HARD
X && u.udemigod
X#endif
X )) {
X You("can't see your %s %s.",
X ACURR(A_CHA) > 14 ?
X (poly_gender()==1 ? "beautiful" : "handsome") :
X "ugly",
X body_part(FACE));
X } else {
X static char buf[35];
X const char *tm, *tl; int ll;
X if (!u.ukilled_medusa && rn2(4)) {
X tm = "n ugly snake-headed monster";
X ll = dlevel - medusa_level;
X }
X else {
X tm = " powerful wizard";
X ll = dlevel - wiz_level;
X }
X if (ll < -10) tl = "far below you";
X else if (ll < -1) tl = "below you";
X else if (ll == -1) {
X Sprintf(buf, "under your %s", makeplural(
X body_part(FOOT)));
X tl = buf;
X } else if (ll == 0) tl = "very close to you";
X else if (ll == 1) {
X Sprintf(buf, "above your %s", body_part(HEAD));
X tl = buf;
X } else if (ll > 10) tl = "far above you";
X else tl = "above you";
X You("get an impression that a%s lives %s.",
X tm, tl);
X }
X }
X return;
X }
X if(u.uswallow) {
X You("reflect %s's %s.", mon_nam(u.ustuck),
X is_animal(u.ustuck->data)? "stomach" : "interior");
X return;
X }
X if(u.dz) {
X You("reflect the %s.",
X (u.dz > 0) ? "floor" : "ceiling");
X return;
X }
X if(!(mtmp = bchit(u.dx, u.dy, COLNO, 0)) || !haseyes(mtmp->data))
X return;
X
X mlet = mtmp->data->mlet;
X if(mtmp->msleep) {
X if(!Blind)
X pline ("%s is tired and doesn't look at your mirror.",
X Monnam(mtmp));
X mtmp->msleep = 0;
X } else if (!mtmp->mcansee) {
X if (!Blind)
X pline("%s can't see anything at the moment.", Monnam(mtmp));
X /* some monsters do special things */
X } else if (mlet == S_VAMPIRE || mlet == S_DEMON || mlet == S_GHOST ||
X (mtmp->minvis && !perceives(mtmp->data) && !See_invisible)) {
X if (!Blind)
X pline ("%s doesn't seem to reflect anything.", Monnam(mtmp));
X } else if(!mtmp->mcan && mtmp->data == &mons[PM_MEDUSA]) {
X if (!Blind)
X pline("%s is turned to stone!", Monnam(mtmp));
X stoned = TRUE;
X killed(mtmp);
X } else if(!mtmp->mcan && !mtmp->minvis &&
X mtmp->data == &mons[PM_FLOATING_EYE]) {
X int tmp = d((int)mtmp->m_lev, (int)mtmp->data->mattk[0].damd);
X if (!rn2(4)) tmp = 120;
X /* Note: floating eyes cannot use their abilities while invisible,
X * but medusas and umber hulks can.
X */
X if (!Blind)
X pline("%s is frozen by its reflection.",Monnam(mtmp));
X mtmp->mcanmove = 0;
X if (mtmp->mfrozen + tmp > 127)
X mtmp->mfrozen = 127;
X else mtmp->mfrozen += tmp;
X } else if(!mtmp->mcan && mtmp->data == &mons[PM_UMBER_HULK]) {
X if (!Blind)
X pline ("%s has confused itself!", Monnam(mtmp));
X mtmp->mconf = 1;
X } else if(!mtmp->mcan && !mtmp->minvis && (mlet == S_NYMPH
X#ifdef INFERNO
X || mtmp->data==&mons[PM_SUCCUBUS]
X#endif
X )) {
X if (!Blind) {
X pline ("%s looks beautiful in your mirror.",Monnam(mtmp));
X pline ("She decides to take it!");
X } else pline ("It steals your mirror!");
X setnotworn(obj); /* in case mirror was wielded */
X freeinv(obj);
X mpickobj(mtmp,obj);
X rloc(mtmp);
X } else if (mlet != S_UNICORN && !humanoid(mtmp->data) &&
X (!mtmp->minvis || perceives(mtmp->data)) && rn2(5)) {
X if (!Blind)
X pline ("%s is frightened by its reflection%s.",
X Monnam(mtmp), (mtmp->minvis && !See_invisible
X && !Telepat) ?
X ", though you see nothing" : "");
X mtmp->mflee = 1;
X mtmp->mfleetim += d(2,4);
X } else if (!Blind) {
X if (mtmp->minvis && !See_invisible)
X pline("%s doesn't seem to reflect anything.",
X Monnam(mtmp));
X else if (mtmp->minvis && !perceives(mtmp->data))
X pline("%s doesn't seem to be aware of its reflection.",
X Monnam(mtmp));
X else
X pline("%s doesn't seem to mind %s reflection.",
X Monnam(mtmp), (is_female(mtmp) ? "her" :
X is_human(mtmp->data) ? "his" : "its"));
X }
X}/* use_mirror */
X
X#endif
X
Xstatic void
Xuse_lamp(obj)
Xstruct obj *obj;
X{
X if(obj->spe <= 0 || obj->otyp == MAGIC_LAMP ) {
X pline("This lamp has no oil.");
X return;
X }
X if(obj->cursed && !rn2(2))
X pline("The lamp flickers on for a moment and dies.");
X else litroom(TRUE);
X obj->spe -= 1;
X}
X
Xstatic void
Xuse_crystal_ball(obj)
X struct obj *obj;
X{
X char buf[BUFSZ];
X int oops, ret;
X
X if (Blind) {
X pline("Too bad you can't see the crystal ball.");
X return;
X }
X oops = (rnd(20) > ACURR(A_INT) || obj->cursed);
X if (oops && (obj->spe > 0)) {
X switch(rnd(5)) {
X case 1 : pline("The crystal ball is too much to comprehend!");
X break;
X case 2 : pline("The crystal ball confuses you!");
X make_confused(HConfusion + rnd(100),FALSE);
X break;
X case 3 : pline("The crystal ball damages your vision!");
X make_blinded(Blinded + rnd(100),FALSE);
X break;
X case 4 : pline("The crystal ball zaps your mind!");
X make_hallucinated(Hallucination + rnd(100),FALSE);
X break;
X case 5 : pline("The crystal ball explodes!");
X useup(obj);
X losehp(rnd(30), "exploding crystal ball",
X KILLED_BY_AN);
X break;
X }
X obj->spe -= 1;
X return;
X }
X
X pline("What do you want to look for? ");
X getlin(buf);
X clrlin();
X if (!buf[0] || buf[0] == '\033') {
X if(flags.verbose) pline("Never mind.");
X return;
X }
X You("peer into the crystal ball.");
X nomul(-rnd(10));
X nomovemsg = "";
X if(obj->spe <= 0)
X pline("The vision is unclear.");
X else {
X obj->spe -= 1;
X switch(buf[0]) {
X case GOLD_SYM : ret = gold_detect((struct obj *)0);
X break;
X case '^' : ret = trap_detect((struct obj *)0);
X break;
X case FOOD_SYM : ret = food_detect((struct obj *)0);
X break;
X case POTION_SYM :
X case GEM_SYM :
X case TOOL_SYM :
X case WEAPON_SYM :
X case WAND_SYM :
X case SCROLL_SYM :
X#ifdef SPELLS
X case SPBOOK_SYM :
X#endif
X case ARMOR_SYM : ret = object_detect((struct obj *)0);
X break;
X default : lcase(buf);
X if (!strncmp(buf,"gold",4) || !strncmp(buf,"money",5))
X ret = gold_detect((struct obj *)0);
X else if (!strncmp(buf,"trap",4))
X ret = trap_detect((struct obj *)0);
X else if (!strncmp(buf,"food",4) ||
X !strncmp(buf,"dead",4) ||
X !strncmp(buf,"corpse",6))
X ret = food_detect((struct obj *)0);
X else if (!strncmp(buf,"obj",3) ||
X !strncmp(buf,"the",3) ||
X !strncmp(buf,"a ",2) ||
X !strncmp(buf,"an ",3))
X /* || strstr(buf, " of") */
X ret = object_detect((struct obj *)0);
X else ret = monster_detect((struct obj *)0);
X break;
X }
X if (ret)
X if (!rn2(100)) /* make them nervous */
X You("see the Wizard of Yendor gazing out at you.");
X else pline("The vision is unclear.");
X }
X return;
X}
X
Xstatic const char NEARDATA cuddly[] = { TOOL_SYM, 0 };
X
Xint
Xdorub()
X{
X struct obj *obj = getobj(cuddly, "rub");
X
X if(!obj || (obj != uwep && !wield_tool(obj))) return 0;
X
X /* now uwep is obj */
X if (uwep->otyp == MAGIC_LAMP) {
X if (uwep->spe > 0 && !rn2(3)) {
X uwep->spe = 0;
X djinni_from_bottle(uwep);
X makeknown(MAGIC_LAMP);
X } else if (rn2(2) && !Blind)
X You("see a puff of smoke.");
X else pline(nothing_happens);
X } else pline(nothing_happens);
X return 1;
X}
X
Xint
Xdojump()
X{
X coord cc;
X register struct monst *mtmp;
X if (!Jumping) {
X You("can't jump very far.");
X return 0;
X } else if (u.uswallow) {
X pline("You've got to be kidding!");
X return 0;
X } else if (u.ustuck) {
X kludge("You cannot escape from %s!",
X mon_nam(u.ustuck));
X return 0;
X } else if (inv_weight() > -5) {
X You("are carrying too much to jump!");
X return 0;
X } else if (u.uhunger <= 100 || ACURR(A_STR) < 6) {
X You("lack the strength to jump!");
X return 0;
X }
X pline("Where do you want to jump?");
X cc.x = u.ux;
X cc.y = u.uy;
X getpos(&cc, 1, "the desired position");
X if (dist(cc.x, cc.y) > 9) {
X pline("Too far!");
X return 0;
X } else if (!cansee(cc.x, cc.y)) {
X You("cannot see where to land!");
X return 0;
X } else if (MON_AT(cc.x, cc.y)) {
X mtmp = m_at(cc.x, cc.y);
X You("cannot trample %s!", mon_nam(mtmp));
X return 0;
X } else if (!isok(cc.x, cc.y) ||
X#ifdef POLYSELF
X (IS_ROCK(levl[cc.x][cc.y].typ) && !passes_walls(uasmon)) ||
X#else
X IS_ROCK(levl[cc.x][cc.y].typ) ||
X#endif
X sobj_at(BOULDER, cc.x, cc.x) ) {
X You("cannot jump there!");
X return 0;
X } else {
X teleds(cc.x, cc.y);
X nomul(-1);
X nomovemsg = "";
X morehungry(rnd(25));
X return 1;
X }
X}
X
Xstatic void
Xuse_tinning_kit(obj)
Xregister struct obj *obj;
X{
X register struct obj *corpse, *can = (struct obj *)0;
X
X /* This takes only 1 move. If this is to be changed to take many
X * moves, we've got to deal with decaying corpses...
X */
X if (!(corpse = floorfood("can", 1))) return;
X if (corpse->oeaten) {
X You("cannot tin something which is partly eaten.");
X return;
X }
X if ((corpse->corpsenm == PM_COCKATRICE)
X#ifdef POLYSELF
X && !resists_ston(uasmon)
X#endif
X && !uarmg) {
Xpline("Tinning a cockatrice corpse without gloves was not a very wise move...");
X You("turn to stone...");
X killer_format = KILLED_BY;
X killer = "trying to tin a cockatrice without gloves";
X done(STONING);
X }
X if (mons[corpse->corpsenm].cnutrit == 0) {
X You("can't tin something that insubstantial!");
X return;
X }
X if(can = mksobj(TIN,FALSE)) {
X int savequan;
X
X can->corpsenm = corpse->corpsenm;
X can->quan = 1; /*Defeat the occasional creation of pairs of tins */
X can->owt = weight(can);
X can->known = 1;
X can->spe = -1; /* Mark tinned tins. No spinach allowed... */
X can->cursed = obj->cursed;
X can->blessed = obj->blessed;
X can = addinv(can);
X savequan = can->quan;
X can->quan = 1;
X if (inv_cnt() <= 52) {
X prinv(can);
X can->quan = savequan;
X } else {
X pline("You make, but cannot pick up, %s.", doname(can));
X /* can->quan = savequan; */
X /* unnecessary since savequan = quan = 1 here */
X dropx(can);
X }
X if (carried(corpse)) useup(corpse);
X else useupf(corpse);
X } else impossible("Tinning failed.");
X}
X
Xint
Xuse_unicorn_horn(obj)
Xstruct obj *obj;
X{
X boolean blessed = (obj && obj->blessed);
X boolean did_something = FALSE;
X
X if (obj && obj->cursed) {
X switch (rn2(6)) {
X static char buf[BUFSZ];
X case 0: make_sick(Sick ? 1L : (long)(20 + rn2(20)), TRUE);
X Strcpy(buf, xname(obj));
X u.usick_cause = (const char *)buf;
X break;
X case 1: make_blinded(Blinded + (long) rnd(100), TRUE);
X break;
X case 2: if (!Confusion)
X You("suddenly feel %s.",
X Hallucination ? "trippy" : "confused");
X make_confused(HConfusion + (long) rnd(100), TRUE);
X break;
X case 3: make_stunned(HStun + (long) rnd(100), TRUE);
X break;
X case 4: adjattrib(rn2(6), -1, FALSE);
X break;
X case 5: make_hallucinated(Hallucination + (long) rnd(100),
X TRUE);
X break;
X }
X return 1;
X }
X
X if (Sick) {
X make_sick(0L, TRUE);
X did_something++;
X }
X if (Blinded > (long)(u.ucreamed+1) && (!did_something || blessed)) {
X make_blinded(u.ucreamed ? (long)(u.ucreamed+1) : 0L, TRUE);
X did_something++;
X }
X if (Hallucination && (!did_something || blessed)) {
X make_hallucinated(0L, TRUE);
X did_something++;
X }
X if (Vomiting && (!did_something || blessed)) {
X make_vomiting(0L, TRUE);
X did_something++;
X }
X if (HConfusion && (!did_something || blessed)) {
X make_confused(0L, TRUE);
X did_something++;
X }
X if (HStun && (!did_something || blessed)) {
X make_stunned(0L, TRUE);
X did_something++;
X }
X if (!did_something || blessed) {
X register int j;
X int did_stat = 0;
X int i = rn2(A_MAX);
X for(j=0; j<A_MAX; j++) {
X if ((blessed || j==i) && ABASE(i) < AMAX(i)) {
X did_something++;
X /* They may have to use it several times... */
X if (!did_stat) {
X did_stat++;
X pline("This makes you feel good!");
X }
X ABASE(i)++;
X flags.botl = 1;
X }
X }
X }
X if (!did_something) pline(nothing_happens);
X return !!did_something;
X}
X
Xint
Xdoapply() {
X register struct obj *obj;
X register int res = 1;
X
X obj = getobj(tools, "use or apply");
X if(!obj) return 0;
X
X check_unpaid(obj);
X
X#ifdef MUSIC
X if (IS_INSTRUMENT(obj->otyp)) {
X res = do_play_instrument(obj);
X return (res);
X }
X#endif /* MUSIC /**/
X
X switch(obj->otyp){
X case EXPENSIVE_CAMERA:
X use_camera(obj); break;
X case CREDIT_CARD:
X case LOCK_PICK:
X case SKELETON_KEY:
X case KEY:
X (void) pick_lock(obj);
X break;
X case BAG_OF_TRICKS:
X if(obj->spe > 0) {
X register int cnt = 1;
X
X obj->spe -= 1;
X if(!rn2(23)) cnt += rn2(7) + 1;
X while(cnt--)
X (void) makemon((struct permonst *) 0, u.ux, u.uy);
X makeknown(BAG_OF_TRICKS);
X }
X break;
X case LARGE_BOX:
X case CHEST:
X case ICE_BOX:
X case SACK:
X case BAG_OF_HOLDING:
X use_container(obj, 1); break;
X case PICK_AXE:
X res = use_pick_axe(obj);
X break;
X case TINNING_KIT:
X use_tinning_kit(obj);
X break;
X case MAGIC_WHISTLE:
X if(pl_character[0] == 'W' || u.ulevel > (MAXULEV/3)) {
X use_magic_whistle(obj);
X break;
X }
X /* fall into next case */
X case WHISTLE:
X use_whistle(obj);
X break;
X#ifdef MEDUSA
X case MIRROR:
X use_mirror(obj);
X break;
X#endif
X case LAMP:
X case MAGIC_LAMP:
X use_lamp(obj);
X break;
X case CRYSTAL_BALL:
X use_crystal_ball(obj);
X break;
X#ifdef WALKIES
X case LEASH:
X use_leash(obj);
X break;
X#endif
X case MAGIC_MARKER:
X dowrite(obj);
X break;
X case TIN_OPENER:
X if(!carrying(TIN)) {
X You("have no tin to open.");
X goto xit;
X }
X You("cannot open a tin without eating or discarding its contents.");
X if(flags.verbose)
X pline("In order to eat, use the 'e' command.");
X if(obj != uwep)
X pline("Opening the tin will be much easier if you wield the tin opener.");
X goto xit;
X
X case STETHOSCOPE:
X res = 0;
X use_stethoscope(obj);
X break;
X case FIGURINE:
X You("set the figurine on the ground and it transforms.");
X make_familiar(obj);
X useup(obj);
X break;
X case BLINDFOLD:
X if (obj == ublindf) {
X if(cursed(obj)) break;
X else Blindf_off(obj);
X }
X else if (!ublindf) Blindf_on(obj);
X else You("are already wearing a blindfold!");
X break;
X case UNICORN_HORN:
X res = use_unicorn_horn(obj);
X break;
X default:
X pline("Sorry, I don't know how to use that.");
X xit:
X nomul(0);
X return 0;
X }
X nomul(0);
X return res;
X}
X
X#endif /* OVLB */
END_OF_FILE
if test 34008 -ne `wc -c <'src/apply.c'`; then
echo shar: \"'src/apply.c'\" unpacked with wrong size!
fi
# end of 'src/apply.c'
fi
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'\" \(21103 characters\)
sed "s/^X//" >'src/polyself.c' <<'END_OF_FILE'
X/* SCCS Id: @(#)polyself.c 3.0 89/11/21
X/* Polymorph self routine. Copyright (C) 1987, 1988, 1989 by Ken Arromdee */
X/* NetHack may be freely redistributed. See license for details. */
X
X#include "hack.h"
X
X#ifdef POLYSELF
X#ifdef OVLB
Xstatic void NDECL(break_armor);
Xstatic void FDECL(drop_weapon,(int));
Xstatic void NDECL(skinback);
Xstatic void NDECL(uunstick);
Xstatic boolean sticky;
X#endif /* OVLB */
X#endif
X
X#ifdef OVLB
X
Xvoid
Xnewman()
X{
X int tmp, tmp2;
X char buf[BUFSZ];
X
X if (!rn2(10)) {
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+5, flags.female ? "woman" : "man");
X }
X#ifdef POLYSELF
X if (u.umonnum != -1) {
X u.acurr = u.macurr; /* restore old attribs */
X u.amax = u.mamax;
X }
X u.usym = S_HUMAN;
X u.umonnum = -1;
X if (u.uundetected) u.uundetected = 0;
X prme();
X u.mtimedone = u.mh = u.mhmax = 0;
X#endif
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 tmp = u.uhpmax;
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#ifdef SPELLS
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#endif
X redist_attr();
X u.uhunger = rn1(500,500);
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#ifdef POLYSELF
X }
X#endif
X }
X#ifdef POLYSELF
X set_uasmon();
X#endif
X You("feel like a new %sman!", flags.female ? "wo" : "");
X#ifdef WIZARD
X if(!wizard) {
X#endif
Xnewname: more();
X do {
X pline("What is your new name? ");
X getlin(buf);
X } while (buf[0]=='\033' || buf[0]==0);
X if (!strcmp(plname,buf)) {
X pline("That is the same as your old name!");
X goto newname;
X }
X (void)strncpy(plname, buf, sizeof(plname)-1);
X#ifdef VMS
X Sprintf(SAVEF, "[.save]%d%s", getuid(), plname);
X regularize(SAVEF+7);
X Strcat(SAVEF, ";1");
X#else
X# ifdef MSDOS
X (void)strcpy(SAVEF, SAVEP);
X {
X int i = strlen(SAVEF);
X (void)strncat(SAVEF, plname, 8);
X regularize(SAVEF+i);
X }
X (void)strcat(SAVEF, ".sav");
X# else
X Sprintf(SAVEF, "save/%d%s", getuid(), plname);
X regularize(SAVEF+5); /* avoid . or / in name */
X# endif
X#endif
X#ifdef WIZARD
X }
X#endif
X flags.botl = 1;
X#ifdef POLYSELF
X skinback();
X find_ac();
X if (sticky) uunstick();
X#endif
X}
X
X#ifdef POLYSELF
Xvoid
Xpolyself()
X{
X char buf[BUFSZ];
X int mntmp = -1;
X int tries=0;
X boolean draconian = (uarm && uarm->otyp==DRAGON_SCALE_MAIL &&
X uarm->corpsenm >= PM_GRAY_DRAGON &&
X uarm->corpsenm <= PM_YELLOW_DRAGON);
X boolean iswere = (u.ulycn > -1 || is_were(uasmon));
X boolean isvamp = (u.usym == S_VAMPIRE || u.umonnum == PM_VAMPIRE_BAT);
X /* We have to calculate sticky in multiple places since we might go
X * through any one of them without going through the others.
X */
X sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
X
X if(!Polymorph_control && !draconian && !iswere && !isvamp) {
X if (rn2(20) > ACURR(A_CON)) {
X You("shudder for a moment.");
X losehp(rn2(30),"system shock", KILLED_BY_AN);
X return;
X }
X }
X
X if (Polymorph_control) {
X do {
X pline("Become what kind of monster? [type the name] ");
X getlin(buf);
X mntmp = name_to_mon(buf);
X if (mntmp < 0)
X pline("I've never heard of such monsters.");
X else if (!polyok(&mons[mntmp]))
X You("cannot polymorph into that.");
X else break;
X } while(++tries < 5);
X if (tries==5) pline(thats_enough_tries);
X } else if (draconian || iswere || isvamp) {
X /* special changes that don't require polyok() */
X if (draconian) {
X mntmp = uarm->corpsenm;
X if (!(mons[mntmp].geno & G_GENOD)) {
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 if (Inhell && !Fire_resistance) {
X You("burn to a crisp.");
X killer_format = KILLED_BY;
X killer = "losing fire resistance after polymorphing";
X while(1) {
X done(BURNING);
X You("continue burning.");
X }
X }
X}
X
Xint
Xpolymon(mntmp) /* returns 1 if polymorph successful */
X int mntmp;
X{
X int tmp;
X sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
X
X if (mons[mntmp].geno & G_GENOD) {
X You("feel rather %s-ish.",mons[mntmp].mname);
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 } 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 }
X tmp = u.umonnum;
X u.umonnum = mntmp;
X set_uasmon();
X u.usym = mons[mntmp].mlet;
X
X if (tmp != mntmp)
X You("turn into %s!", an(mons[mntmp].mname));
X else
X You("feel like a new %s!", mons[mntmp].mname);
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 if (u.usym == S_DRAGON && mntmp >= PM_GRAY_DRAGON) u.mhmax = 80;
X#ifdef GOLEMS
X else if (is_golem(uasmon)) u.mhmax = golemhp(mntmp);
X#endif /* GOLEMS */
X else {
X
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 if (uskin && mntmp != uskin->corpsenm)
X skinback();
X break_armor();
X drop_weapon(1);
X if (u.uundetected && !hides_under(uasmon)) u.uundetected = 0;
X else if (hides_under(uasmon) && (OBJ_AT(u.ux, u.uy) ||
X levl[u.ux][u.uy].gmask))
X u.uundetected = 1;
X prme();
X if (!sticky && !u.uswallow && u.ustuck && sticks(uasmon)) u.ustuck = 0;
X else if (sticky && !sticks(uasmon)) uunstick();
X u.mtimedone = 500 + rn2(500);
X if (u.ulevel < mons[mntmp].mlevel)
X /* Low level characters can't become high level monsters for long */
X u.mtimedone = u.mtimedone * u.ulevel / mons[mntmp].mlevel;
X flags.botl = 1;
X if (flags.verbose) {
X if (can_breathe(uasmon))
X pline("Use the command #monster to use your breath weapon.");
X if (attacktype(uasmon, AT_SPIT))
X pline("Use the command #monster to spit venom.");
X if (u.usym == S_NYMPH)
X pline("Use the command #monster to remove an iron ball.");
X if (u.usym == S_UMBER)
X pline("Use the command #monster to confuse monsters.");
X if (is_hider(uasmon))
X pline("Use the command #monster to hide.");
X if (is_were(uasmon))
X pline("Use the command #monster to summon help.");
X if (webmaker(uasmon))
X pline("Use the command #monster to spin a web.");
X if (u.usym == S_UNICORN)
X pline("Use the command #monster to use your horn.");
X if (lays_eggs(uasmon) || u.umonnum == PM_QUEEN_BEE)
X pline("Use the command #sit to lay an egg.");
X }
X find_ac();
X return(1);
X}
X
Xstatic void
Xbreak_armor() {
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 (void) Armor_gone();
X useup(otmp);
X }
X if (otmp = uarmc) {
X Your("cloak tears apart!");
X (void) Cloak_off();
X useup(otmp);
X }
X#ifdef SHIRT
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 You("shrink out of your cloak!");
X (void) Cloak_off();
X dropx(otmp);
X }
X#ifdef SHIRT
X if (otmp = uarmu) {
X 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 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 sticky = sticks(uasmon) && u.ustuck && !u.uswallow;
X
X u.mh = u.mhmax = u.mtimedone = 0;
X u.acurr = u.macurr; /* restore old strength */
X u.amax = u.mamax;
X u.usym = S_HUMAN;
X u.umonnum = -1;
X skinback();
X set_uasmon();
X You("return to %sn form!", (pl_character[0] == 'E')? "elve" : "huma");
X
X if (u.uhp < 1) done(DIED);
X if (!Fire_resistance && Inhell) {
X You("burn to a crisp.");
X killer_format = KILLED_BY;
X killer = "losing fire resistance after rehumanization";
X while(1) {
X done(BURNING);
X You("continue burning.");
X }
X }
X if (!uarmg) selftouch("No longer petrify-resistant, you");
X if (sticky) uunstick();
X nomul(0);
X if (u.uundetected) u.uundetected = 0;
X prme();
X flags.botl = 1;
X find_ac();
X}
X
Xint
Xdobreathe() {
X if(!getdir(1)) 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(1)) return(0);
X otmp = mksobj(u.umonnum==PM_COBRA ? BLINDING_VENOM : ACID_VENOM, 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 register struct trap *ttmp = t_at(u.ux,u.uy);
X
X if (Levitation) {
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 if (ttmp) switch (ttmp->ttyp) {
X case SPIKED_PIT:
X case PIT: You("spin a web, covering up the pit.");
X deltrap(ttmp);
X if (Invisible) newsym(u.ux, u.uy);
X return(1);
X case WEB: You("make the web thicker.");
X return(1);
X case SQBRD: 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 TRAPDOOR: if (!is_maze_lev) {
X You("web over the trap door.");
X deltrap(ttmp);
X if (Invisible) newsym(u.ux, u.uy);
X return 1;
X }
X /* Fall through */
X case MGTRP:
X case POLY_TRAP:
X case DART_TRAP:
X case ARROW_TRAP:
X#ifdef SPELLS
X case ANTI_MAGIC:
X#endif
X case LANDMINE:
X case SLP_GAS_TRAP:
X case BEAR_TRAP:
X case RUST_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 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
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->mimic)
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#ifdef MACOS
X char mac_tbuf[80];
X if(!flags.silent) SysBeep(1);
X Sprintf(mac_tbuf, "Really confuse %s?", mon_nam(mtmp));
X if(UseMacAlertText(128, mac_tbuf) != 1) continue;
X#else
X pline("Really confuse %s? ", mon_nam(mtmp));
X (void) fflush(stdout);
X if (yn() != 'y') continue;
X#endif
X setmangry(mtmp);
X }
X if (!mtmp->mcanmove || mtmp->mstun || mtmp->msleep ||
X !mtmp->mcansee)
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's gaze!", 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#ifdef MEDUSA
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#endif
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 prme();
X } else {
X newsym(u.ux,u.uy);
X u.uundetected = 1;
X }
X return(1);
X}
X
Xstatic void
Xuunstick()
X{
X kludge("%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) || (u.usym==S_CENTAUR &&
X (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 (u.usym==S_SNAKE || u.usym==S_NAGA || u.usym==S_WORM)
X 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 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 (uasmon->mflags2 & M2_FEM) return 1;
X# ifdef INFERNO
X if (u.umonnum == PM_INCUBUS) return 0;
X# endif
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) && defined(GOLEMS)
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 }
X}
X#endif /* POLYSELF && GOLEMS */
X
X#endif /* OVLB */
END_OF_FILE
if test 21103 -ne `wc -c <'src/polyself.c'`; then
echo shar: \"'src/polyself.c'\" unpacked with wrong size!
fi
# end of 'src/polyself.c'
fi
echo shar: End of archive 20 \(of 56\).
cp /dev/null ark20isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 ; do
if test ! -f ark${I}isdone ; then
MISSING="${MISSING} ${I}"
fi
done
if test "${MISSING}" = "" ; then
echo You have unpacked all 56 archives.
rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
echo You still need to unpack the following archives:
echo " " ${MISSING}
fi
## End of shell archive.
exit 0