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