billr@saab.CNA.TEK.COM (Bill Randle) (07/24/89)
Submitted-by: Izchak Miller <izchak@linc.cis.upenn.edu> Posting-number: Volume 7, Issue 58 Archive-name: NetHack3/Part03 #! /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 3 (of 38)." # Contents: amiga/ami.lnk src/dbridge.c src/mhitu.c # Wrapped by billr@saab on Sun Jul 23 21:32:47 1989 PATH=/bin:/usr/bin:/usr/ucb ; export PATH if test -f 'amiga/ami.lnk' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'amiga/ami.lnk'\" else echo shar: Extracting \"'amiga/ami.lnk'\" \(761 characters\) sed "s/^X//" >'amiga/ami.lnk' <<'END_OF_FILE' X-w X-o Ram:NetHack X+ss Xamidos.o amitcap.o amitty.o amiunix.o amiwind.o alloc.o apply.o artifact.o Xattrib.o bones.o cmd.o dbridge.o decl.o demon.o do.o do_name.o do_wear.o Xdog.o dogmove.o dothrow.o eat.o end.o engrave.o exper.o extralev.o Xfountain.o hack.o invent.o lock.o main.o makemon.o mcastu.o mhitm.o mhitu.o Xmklev.o mkmaze.o mkobj.o mkshop.o mon.o mondata.o monmove.o monst.o Xmthrowu.o music.o o_init.o objects.o objnam.o options.o pager.o pickup.o Xpolyself.o potion.o pray.o pri.o prisym.o random.o read.o restore.o rip.o Xrnd.o rumors.o save.o search.o shk.o shknam.o sit.o sounds.o sp_lev.o Xspell.o steal.o timeout.o topl.o topten.o track.o trap.o u_init.o uhitm.o Xvault.o version.o weapon.o were.o wield.o wizard.o worm.o worn.o write.o Xzap.o X-lml -lcl END_OF_FILE if test 761 -ne `wc -c <'amiga/ami.lnk'`; then echo shar: \"'amiga/ami.lnk'\" unpacked with wrong size! fi # end of 'amiga/ami.lnk' fi if test -f 'src/dbridge.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/dbridge.c'\" else echo shar: Extracting \"'src/dbridge.c'\" \(7852 characters\) sed "s/^X//" >'src/dbridge.c' <<'END_OF_FILE' X/* SCCS Id: @(#)dbridge.c 3.0 88/18/12 X/* Copyright (c) 1989 by Jean-Christophe Collet */ X/* NetHack may be freely redistributed. See license for details. */ X X/* X * This file contains the drawbridge manipulation (create, open, close, X * destroy). X */ X X#include "hack.h" X Xboolean Xis_pool(x,y) Xint x,y; X{ X if(levl[x][y].typ == POOL || levl[x][y].typ == MOAT) return TRUE; X#ifdef STRONGHOLD X if(levl[x][y].typ == DRAWBRIDGE_UP && X (levl[x][y].drawbridgemask & DB_UNDER) == DB_MOAT) return TRUE; X#endif X return FALSE; X} X X#ifdef STRONGHOLD Xvoid Xinitsym(x,y) Xint x,y; X{ X char oldseen; X struct rm *crm = &levl[x][y]; X X oldseen = crm->seen; X crm->seen = 1; X crm->scrsym = news0(x,y); X crm->seen = oldseen; X} X Xstatic void Xredosym(x,y) Xint x,y; X{ X if(cansee(x,y)) { X if (Invisible || x != u.ux || y != u.uy) X newsym(x,y); X } else { X initsym(x,y); X levl[x][y].seen = 0; X } X} X X/* X * We want to know whether a wall (or a door) is the portcullis (passageway) X * of an eventual drawbridge. X * X * Return value: the direction of the drawbridge. X */ X Xint Xis_drawbridge_wall(x,y) Xint x,y; X{ X struct rm *lev; X X lev = &levl[x][y]; X if ( lev->typ == VWALL || lev->typ == DOOR) { X if (IS_DRAWBRIDGE(levl[x+1][y].typ) && X (levl[x+1][y].drawbridgemask & DB_DIR) == DB_WEST) X return (DB_WEST); X if (IS_DRAWBRIDGE(levl[x-1][y].typ) && X (levl[x-1][y].drawbridgemask & DB_DIR) == DB_EAST) X return (DB_EAST); X } X if ( lev->typ == HWALL || lev->typ == DOOR) { X if (IS_DRAWBRIDGE(levl[x][y-1].typ) && X (levl[x][y-1].drawbridgemask & DB_DIR) == DB_SOUTH) X return (DB_SOUTH); X if (IS_DRAWBRIDGE(levl[x][y+1].typ) && X (levl[x][y+1].drawbridgemask & DB_DIR) == DB_NORTH) X return (DB_NORTH); X } X return (-1); X} X X/* X* Use is_db_wall where you want to verify that a X* drawbridge "wall" is UP in the location x, y X* (instead of UP or DOWN, as with is_drawbridge_wall). X*/ Xboolean Xis_db_wall(x,y) Xint x,y; X{ X return( (levl[x][y].typ == VWALL || levl[x][y].typ == HWALL) && X levl[x][y].diggable & W_GATEWAY); X} X X/* X * Return true with x,y pointing to the drawbridge if x,y initially indicate X * a drawbridge or drawbridge wall. X */ Xboolean Xfind_drawbridge(x,y) Xint *x,*y; X{ X int dir; X X if (IS_DRAWBRIDGE(levl[*x][*y].typ)) X return TRUE; X dir = is_drawbridge_wall(*x,*y); X if (dir >= 0) { X switch(dir) { X case DB_NORTH: (*y)++; break; X case DB_SOUTH: (*y)--; break; X case DB_EAST: (*x)--; break; X case DB_WEST: (*x)++; break; X } X return TRUE; X } X return FALSE; X} X X/* X * Find the drawbridge wall associated with a drawbridge. X */ Xstatic void Xget_wall_for_db(x,y) Xint *x,*y; X{ X switch (levl[*x][*y].drawbridgemask & DB_DIR) { X case DB_NORTH: (*y)--; break; X case DB_SOUTH: (*y)++; break; X case DB_EAST: (*x)++; break; X case DB_WEST: (*x)--; break; X } X} X X/* X * Creation of a drawbridge at pos x,y. X * dir is the direction. X * flag must be put to TRUE if we want the drawbridge to be opened. X */ X Xboolean Xcreate_drawbridge(x,y,dir,flag) Xint x,y,dir; Xboolean flag; X{ X int x2,y2; X uchar wall; X X x2 = x; y2 = y; X switch(dir) { X case DB_NORTH: X wall = HWALL; X y2--; X break; X case DB_SOUTH: X wall = HWALL; X y2++; X break; X case DB_EAST: X wall = VWALL; X x2++; X break; X case DB_WEST: X wall = VWALL; X x2--; X break; X } X if (!IS_WALL(levl[x2][y2].typ)) X return(FALSE); X if (flag) { /* We want the bridge open */ X levl[x][y].typ = DRAWBRIDGE_DOWN; X levl[x2][y2].typ = DOOR; X levl[x2][y2].doormask = D_NODOOR; X } else { X levl[x][y].typ = DRAWBRIDGE_UP; X levl[x2][y2].typ = wall; X /* Beware, drawbridges are non-diggable. */ X levl[x2][y2].diggable = (W_NONDIGGABLE | W_GATEWAY); X } X levl[x][y].drawbridgemask = dir; /* always have DB_MOAT */ X initsym(x,y); X initsym(x2,y2); X return(TRUE); X} X X/* X * Close the drawbridge located at x,y X */ X Xvoid Xclose_drawbridge(x,y) Xint x,y; X{ X register struct rm *lev1, *lev2; X struct monst *mtmp; X struct obj *otmp, *otmp2; X int x2, y2; X X lev1 = &levl[x][y]; X if (lev1->typ != DRAWBRIDGE_DOWN) return; X if (cansee(x,y)) X You("see a drawbridge going up!"); X lev1->typ = DRAWBRIDGE_UP; X x2 = x; y2 = y; X get_wall_for_db(&x2,&y2); X lev2 = &levl[x2][y2]; X switch (lev1->drawbridgemask & DB_DIR) { X case DB_NORTH: X case DB_SOUTH: X lev2->typ = HWALL; X break; X case DB_WEST: X case DB_EAST: X lev2->typ = VWALL; X break; X } X lev2->diggable = (W_NONDIGGABLE | W_GATEWAY); X if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT) { X if (lev1->mmask && !is_flyer((mtmp = m_at(x,y))->data)) { X if (is_swimmer(mtmp->data)) { X if (flags.soundok) You("hear a splash."); X } else { X if (cansee(x,y)) X pline("%s drowns.",Monnam(mtmp)); X else if (flags.soundok) X You("hear a splash!"); X xkilled(mtmp,2); X } X } X if (u.ux == x && u.uy == y && X !(Levitation X# ifdef POLYSELF X || is_flyer(uasmon) X# endif X )) { X /* is the player *THAT* stupid ? */ X You("fall from the drawbridge."); X if (!Wwalking) drown(); X } X } X if (lev2->mmask && !noncorporeal((mtmp = m_at(x2, y2))->data)) { X if (cansee(x2,y2)) X pline("%s is crushed by the portcullis.",Monnam(mtmp)); X else if (flags.soundok) X You("hear a crushing sound."); X xkilled(mtmp,2); X } X if (u.ux == x2 && u.uy == y2) { /* More stupidity ? */ X coord xy; X X You("are crushed by a falling portcullis."); X killer = "closing drawbridge"; X done("died"); X /* So, you didn't die */ X pline("A %s force teleports you away...", X Hallucination ? "normal" : "strange"); X enexto(&xy, x2, y2); X teleds(xy.x, xy.y); X } X redosym(x,y); X for (otmp=fobj;otmp;otmp = otmp2) { X otmp2 = otmp->nobj; X if ((otmp->ox == x && otmp->oy == y) || X (otmp->ox == x2 && otmp->oy == y2)) X delobj(otmp); X } X redosym(x2,y2); X} X X/* X * Open the drawbridge located at x,y X */ X Xvoid Xopen_drawbridge(x,y) Xint x,y; X{ X register struct rm *lev1, *lev2; X int x2, y2; X X lev1 = &levl[x][y]; X if (lev1->typ != DRAWBRIDGE_UP) return; X if (cansee(x,y)) X You("see a drawbridge coming down!"); X lev1->typ = DRAWBRIDGE_DOWN; X x2 = x; y2 = y; X get_wall_for_db(&x2,&y2); X lev2 = &levl[x2][y2]; X lev2->typ = DOOR; X lev2->doormask = D_NODOOR; X if (u.ux == x && u.uy == y) { X if (cansee(x2,y2)) X newsym(x2,y2); X You("are hit by the descending drawbridge!"); X killer = "descending drawbridge"; X done("died"); X } X redosym(x,y); X redosym(x2,y2); X} X X/* X * Let's destroy the drawbridge located at x,y X */ X Xvoid Xdestroy_drawbridge(x,y) Xint x,y; X{ X register struct rm *lev1, *lev2; X int x2, y2; X X lev1 = &levl[x][y]; X if (!IS_DRAWBRIDGE(lev1->typ)) X return; X x2 = x; y2 = y; X get_wall_for_db(&x2,&y2); X lev2 = &levl[x2][y2]; X if ((lev1->drawbridgemask & DB_UNDER) == DB_MOAT) { X if (lev1->typ == DRAWBRIDGE_UP) { X if (cansee(x2,y2)) X pline("The portcullis of the drawbridge falls into the moat!"); X else if (flags.soundok) X You("hear a big *SPLASH*!"); X } else { X if (cansee(x,y)) X pline("The drawbridge collapses into the moat!"); X else if (flags.soundok) X You("hear a big *SPLASH*!"); X } X lev1->typ = MOAT; X if (u.ux == x && u.uy == y && !(Levitation X# ifdef POLYSELF X || is_flyer(uasmon) X# endif X )) { X /* is the player *THAT* stupid ? */ X You("fall from the drawbridge."); X if (!Wwalking) drown(); X } X } else { X if (cansee(x,y)) X pline("The drawbridge disintegrates!"); X else X You("hear a big *CRASH*!"); X lev1->typ = ROOM; X } X lev2->typ = DOOR; X lev2->doormask = D_NODOOR; X if (u.ux == x2 && u.uy == y2) { /* More stupidity ? */ X coord xy; X X You("are crushed by a falling portcullis."); X killer = "collapsing drawbridge"; X done("died"); X /* So, you didn't die */ X pline("A %s force teleports you away...", X Hallucination ? "normal" : "strange"); X enexto(&xy, x2, y2); X teleds(xy.x, xy.y); X } X redosym(x,y); X redosym(x2,y2); X} X X#endif /* STRONGHOLD /**/ END_OF_FILE if test 7852 -ne `wc -c <'src/dbridge.c'`; then echo shar: \"'src/dbridge.c'\" unpacked with wrong size! fi # end of 'src/dbridge.c' fi if test -f 'src/mhitu.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'src/mhitu.c'\" else echo shar: Extracting \"'src/mhitu.c'\" \(42552 characters\) sed "s/^X//" >'src/mhitu.c' <<'END_OF_FILE' X/* SCCS Id: \@(#)mhitu.c 3.0 88/10/28 X/* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ X/* NetHack may be freely redistributed. See license for details. */ X X#include "hack.h" X#ifdef NAMED_ITEMS X# include "artifact.h" X#endif X Xstatic struct obj *otmp; X#ifdef POLYSELF Xstatic void urustm P((struct monst *, struct obj *)); Xstatic int passiveum P((struct permonst *, struct monst *)); X#endif X#ifdef SEDUCE Xstatic void mayberem P((struct obj *, char *)); X#endif Xstatic int hitmu P((struct monst *,struct attack *)); Xstatic int gulpmu P((struct monst *,struct attack *)); Xstatic int explmu P((struct monst *,struct attack *)); Xstatic int gazemu P((struct monst *,struct attack *)); X X#ifdef POLYSELF Xboolean X/* also needed in uhitm.c */ X#else Xstatic boolean X#endif Xincompatible(mon) Xregister struct monst *mon; X{ X return(poly_gender() != 1-gender(mon)); X} X Xboolean Xis_nymph(mon) Xregister struct monst *mon; X{ X return( mon->data->mlet == S_NYMPH ); X} X Xboolean Xsp_melee(mon) Xregister struct monst *mon; X{ X return( X#ifdef SEDUCE X (mon->data == &mons[PM_SUCCUBUS] && !mon->minvis) || X (mon->data == &mons[PM_INCUBUS] && !mon->minvis) || X#endif X is_nymph(mon)); X} X Xstatic void Xhitmsg(mtmp, attyp) Xregister struct monst *mtmp; Xregister uchar attyp; X{ X /* Note: if opposite gender, "seductively" */ X /* If same gender, "engagingly" for nymph, normal msg for others */ X if(sp_melee(mtmp) && !mtmp->mcan) { X if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; X kludge("%s %s you %s.", Monnam(mtmp), X Blind ? "talks to" : "smiles at", X incompatible(mtmp) ? "engagingly" : "seductively"); X } else Xstrike: X switch (attyp) { X case AT_BITE: X kludge("%s bites!", Monnam(mtmp)); X break; X case AT_KICK: X#ifdef POLYSELF X kludge("%s kicks%c", Monnam(mtmp), thick_skinned(uasmon) ? '.' : '!'); X#else X kludge("%s kicks!", Monnam(mtmp)); X#endif X break; X case AT_STNG: X kludge("%s stings!", Monnam(mtmp)); X break; X case AT_BUTT: X kludge("%s butts!", Monnam(mtmp)); X break; X case AT_TUCH: X kludge("%s touches you!", Monnam(mtmp)); X break; X default: X kludge("%s hits!", Monnam(mtmp)); X } X} X Xstatic void Xmissmu(mtmp, nearmiss) /* monster missed you */ Xregister struct monst *mtmp; Xregister boolean nearmiss; X{ X if(sp_melee(mtmp) && !mtmp->mcan) { X if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; X kludge("%s pretends to be friendly.", Monnam(mtmp)); X } else { Xstrike: X if (!flags.verbose || !nearmiss) X kludge("%s misses.", Monnam(mtmp)); X else X kludge("%s just misses!", Monnam(mtmp)); X } X} X Xstatic void Xmswings(mtmp, otemp) /* monster swings obj */ Xregister struct monst *mtmp; Xregister struct obj *otemp; X{ X if (!flags.verbose || Blind || otemp->olet != WEAPON_SYM) return; X pline("%s %s %s %s.", Monnam(mtmp), X (otemp->otyp == SPEAR || X otemp->otyp == LANCE || X otemp->otyp == GLAIVE || X otemp->otyp == TRIDENT) ? "thrusts" : "swings", X is_female(mtmp) ? "her" : X is_human(mtmp->data) ? "his" : "its", X xname(otemp)); X} X Xstatic void Xwildmiss(mtmp) /* monster attacked your displaced image */ X register struct monst *mtmp; X{ X if (!flags.verbose) return; X if (!cansee(mtmp->mx, mtmp->my)) return; X /* maybe it's attacking an image around the corner? */ X if(Invis && !perceives(mtmp->data)) { X if(sp_melee(mtmp) && !mtmp->mcan) { X if(!is_nymph(mtmp) && incompatible(mtmp)) goto strike; X kludge("%s tries to touch you and misses!", Monnam(mtmp)); X } else Xstrike: X switch(rn2(3)) { X case 0: kludge("%s swings wildly and misses!", Monnam(mtmp)); X break; X case 1: kludge("%s attacks a spot beside you.", Monnam(mtmp)); X break; X case 2: kludge("%s strikes at thin air!", Monnam(mtmp)); X break; X default:kludge("%s swings wildly!", Monnam(mtmp)); X break; X } X } X else if(Displaced) { X if(sp_melee(mtmp) && !mtmp->mcan) { X if(!is_nymph(mtmp) && incompatible(mtmp)) goto strikem; X kludge("%s smiles %s at your %sdisplaced image...", X Monnam(mtmp), X incompatible(mtmp) ? "engagingly" : "seductively", X Invis ? "invisible " : ""); X } else Xstrikem: X kludge("%s strikes at your %sdisplaced image and misses you!", X /* Note: if you're both invisible and displaced, X * only monsters which see invisible will attack your X * displaced image, since the displaced image is also X * invisible. X */ X Monnam(mtmp), X Invis ? "invisible " : ""); X } X else impossible("%s attacks you without knowing your location?", X Monnam(mtmp)); X} X Xstatic void Xregurgitates(mtmp) Xregister struct monst *mtmp; X{ X u.ux = mtmp->mx; X u.uy = mtmp->my; X u.uswallow = 0; X u.ustuck = 0; X mnexto(mtmp); X setsee(); X docrt(); X spoteffects(); X /* to cover for a case where mtmp is not in a next square */ X if(um_dist(mtmp->mx,mtmp->my,1)) X pline("Brrooaa... You land hard at some distance."); X} X X/* X * mattacku: monster attacks you X * returns 1 if monster dies (e.g. "yellow light"), 0 otherwise X * Note: if you're displaced or invisible the monster might attack the X * wrong position... X * Assumption: it's attacking you or an empty square; if there's another X * monster which it attacks by mistake, the caller had better X * take care of it... X */ Xint Xmattacku(mtmp) X register struct monst *mtmp; X{ X struct attack *mattk; X int i, j, tmp, sum[NATTK]; X struct permonst *mdat = mtmp->data; X boolean ranged = (dist(mtmp->mx, mtmp->my) > 3); X /* Is it near you? Affects your actions */ X boolean range2 = (dist2(mtmp->mx, mtmp->my, mtmp->mux, mtmp->muy) > 3); X /* Does it think it's near you? Affects its actions */ X boolean foundyou = (mtmp->mux==u.ux && mtmp->muy==u.uy); X /* Is it attacking you or your image? */ X boolean youseeit = (cansee(mtmp->mx, mtmp->my)); X /* Necessary since if it's attacking your image around a X * corner, you might not see it X */ X X if(!ranged) nomul(0); X if(mtmp->mhp <= 0) return(0); X X /* If swallowed, can only be affected by u.ustuck */ X if(u.uswallow) { X if(mtmp != u.ustuck) X return(0); X u.ustuck->mux = u.ux; X u.ustuck->muy = u.uy; X range2 = 0; X foundyou = 1; X /* This is not impossible! */ X /* If the swallowing monster changes into a monster X * that is not capable of swallowing you, you get X * regurgitated - dgk X */ X for(i = 0; i < NATTK; i++) X if(mdat->mattk[i].aatyp == AT_ENGL) goto doattack; X X You("get regurgitated!"); X regurgitates(mtmp); X return(0); X } Xdoattack: X#ifdef POLYSELF X if (u.uundetected && !range2 && foundyou) { X u.uundetected = 0; X if (u.usym == S_PIERCER) { X coord cc; /* maybe we need a unexto() function? */ X X unpmon(mtmp); X levl[mtmp->mx][mtmp->my].mmask = 0; X mtmp->mx = u.ux; mtmp->my = u.uy; X levl[mtmp->mx][mtmp->my].mmask = 1; X pmon(mtmp); X enexto(&cc, u.ux, u.uy); X /* Luckily piercers cannot walk through walls, so this X * will work. If they can (i.e., if someone adds a potion X * of phasing), we gotta change this... X */ X teleds(cc.x, cc.y); X You("fall from the ceiling!"); X if (is_mercenary(mtmp->data) && m_carrying(mtmp,HELMET)) { X kludge("Your blow glances off %s's helmet.", X mon_nam(mtmp)); X } else { X if (3 + mtmp->data->ac <= rnd(20)) { X kludge("%s is hit by a falling piercer (you)!", X Monnam(mtmp)); X if ((mtmp->mhp -= d(3,6)) < 1) X killed(mtmp); X } else X kludge("%s is almost hit by a falling piercer (you)!", X Monnam(mtmp)); X } X } else { X if (Blind) pline("It tries to move where you are hiding."); X else X pline("Wait, %s! There's a %s named %s hiding under %s!", X mtmp->mnamelth ? NAME(mtmp) : mtmp->data->mname, X uasmon->mname, plname, X levl[u.ux][u.uy].omask ? doname(o_at(u.ux,u.uy)) : X "some gold"); X prme(); X } X return(0); X } X if (u.usym == S_MIMIC_DEF && !range2 && foundyou) { X if (Blind) pline("It gets stuck on you."); X else pline("Wait, %s! That's a %s named %s!", X mtmp->mnamelth ? NAME(mtmp) : mtmp->data->mname, X uasmon->mname, plname); X u.ustuck = mtmp; X u.usym = S_MIMIC; X prme(); X return(0); X } X#endif X/* Work out the armor class differential */ X tmp = u.uac + 10; /* tmp ~= 0 - 20 */ X/* give people with Ac < -9 at least some vulnerability */ X/* negative AC gives an actual AC of somewhere from -1 to the AC */ X if (tmp < 10) tmp = 10 - rnd(10-tmp); X tmp += mtmp->m_lev; X if(multi < 0) tmp += 4; X if((Invis && !perceives(mdat)) || !mtmp->mcansee) X tmp -= 2; X if(mtmp->mtrapped) tmp -= 2; X if(tmp <= 0) tmp = 1; X X /* make eels visible the moment they hit/miss us */ X if(mdat->mlet == S_EEL && mtmp->minvis && cansee(mtmp->mx,mtmp->my)) { X mtmp->minvis = 0; X pmon(mtmp); X } X X/* Special demon handling code */ X if(!mtmp->cham && is_demon(mdat) && !range2 X#ifdef HARD X && mtmp->data != &mons[PM_BALROG] X && mtmp->data != &mons[PM_SUCCUBUS] X && mtmp->data != &mons[PM_INCUBUS] X#endif X ) X if(!mtmp->mcan && !rn2(13)) dsummon(mdat); X X/* Special lycanthrope handling code */ X if(!mtmp->cham && is_were(mdat) && !range2) { X X if(is_human(mdat)) { X if(!rn2(5 - (night() * 2)) && !mtmp->mcan) new_were(mtmp); X } else if(!rn2(30) && !mtmp->mcan) new_were(mtmp); X X if(!rn2(10) && !mtmp->mcan) { X if(!Blind) { X pline("%s summons help!",youseeit ? X Monnam(mtmp) : "It"); X } else X You("feel hemmed in."); X /* Technically wrong; we really should check if you can see the X * help, but close enough... X */ X if (!were_summon(mdat,FALSE) && !Blind) X pline("But none comes."); X } X } X X for(i = 0; i < NATTK; i++) { X X mattk = &(mdat->mattk[i]); X switch(mattk->aatyp) { X case AT_CLAW: /* "hand to hand" attacks */ X case AT_KICK: X case AT_BITE: X case AT_STNG: X case AT_TUCH: X case AT_BUTT: X if(!range2) { X if (!foundyou) { X wildmiss(mtmp); X sum[i] = 0; X } else if(tmp > (j = rnd(20+i))) X#ifdef POLYSELF X if (mattk->aatyp == AT_KICK && X thick_skinned(uasmon)) sum[i] = 0; X else X#endif X sum[i] = hitmu(mtmp, mattk); X else { X missmu(mtmp, (tmp == j)); X sum[i] = 0; X } X } else sum[i] = 0; X break; X X case AT_HUGS: /* automatic if prev two attacks succeed */ X /* Note: if displaced, prev attacks never succeeded */ X if(!range2) { X if(sum[i-1] && sum[i-2]) X sum[i]= hitmu(mtmp, mattk); X else sum[i] = 0; X } else sum[i] = 0; X break; X X case AT_GAZE: /* can affect you either ranged or not */ X if (!youseeit) sum[i] = 0; X /* Displaced and around a corner so not visible */ X else sum[i] = gazemu(mtmp, mattk); X break; X X case AT_EXPL: /* automatic hit if next to, and aimed at you */ X if(!range2) { X if (!foundyou) { X if (!mtmp->mcan) { X pline("%s explodes at a spot in thin air!", X youseeit ? Monnam(mtmp) : "It"); X mondead(mtmp); X sum[i] = 2; X } else sum[i] = 0; X } else sum[i] = explmu(mtmp, mattk); X } else sum[i] = 0; X break; X X case AT_ENGL: X if (!range2) { X if(foundyou) { X if(u.uswallow || tmp > (j = rnd(20+i))) { X /* Force swallowing monster to be X * displayed even when player is X * moving away */ X nscr(); X sum[i] = gulpmu(mtmp, mattk); X } else { X missmu(mtmp, (tmp == j)); X sum[i] = 0; X } X } else pline("%s gulps some air!", youseeit ? X Monnam(mtmp) : "It"); X } else sum[i] = 0; X break; X case AT_BREA: X if(range2) sum[i] = breamu(mtmp, mattk); X /* Note: breamu takes care of displacement */ X else sum[i] = 0; X break; X case AT_SPIT: X if(range2) sum[i] = spitmu(mtmp); X /* Note: spitmu takes care of displacement */ X else sum[i] = 0; X break; X case AT_WEAP: X if(range2) { X#ifdef REINCARNATION X if (dlevel != rogue_level) X#endif X sum[i] = thrwmu(mtmp); X } else { X if (!foundyou) { X wildmiss(mtmp); X sum[i] = 0; X } else { X set_uasmon(); X otmp = select_hwep(mtmp); X if(otmp) { X tmp += hitval(otmp, uasmon); X mswings(mtmp, otmp); X } X if(tmp > (j = rnd(20+i))) X sum[i] = hitmu(mtmp, mattk); X else { X missmu(mtmp, (tmp == j)); X sum[i] = 0; X } X } X } X break; X case AT_MAGC: X if(!range2) { X if (!foundyou) { X pline("%s casts a spell at thin air!", X youseeit ? Monnam(mtmp) : "It"); X sum[i] = 0; X /* Not totally right since castmu allows other X * spells, such as the monster healing itself, X * that should work even when not next to you-- X * but the previous code was just as wrong. X * --KAA X */ X } else sum[i] = castmu(mtmp, mattk); X } else sum[i] = buzzmu(mtmp, mattk); X break; X X default: /* no attack */ X sum[i] = 0; X break; X } X if(flags.botl) bot(); X if(sum[i] == 2) return(1); /* attacker dead */ X } X return(0); X} X X/* X * hitmu: monster hits you X * returns 2 if monster dies (e.g. "yellow light"), 0 otherwise X */ Xstatic Xint Xhitmu(mtmp, mattk) X register struct monst *mtmp; X register struct attack *mattk; X{ X register struct permonst *mdat = mtmp->data; X register int dmg, ctmp, ptmp; X register boolean getbronze; X char buf[BUFSZ]; X#ifdef POLYSELF X struct permonst *olduasmon = uasmon; X int res; X#endif X X/* If the monster is undetected & hits you. You should know where X * the attack came from. X */ X if(mtmp->mhide && mtmp->mundetected) { X mtmp->mundetected = 0; X if(!(Blind ? Telepat : (HTelepat & WORN_HELMET))) { X register struct obj *obj; X X if(levl[mtmp->mx][mtmp->my].omask == 1) { X if(obj = o_at(mtmp->mx,mtmp->my)) X pline("%s was hidden under %s!", X Xmonnam(mtmp), doname(obj)); X } else if (levl[mtmp->mx][mtmp->my].gmask == 1) X pline("%s was hidden under some gold!", X Xmonnam(mtmp)); X } X } X X/* First determine the base damage done */ X dmg = d((int)mattk->damn, (int)mattk->damd); X if(is_undead(mdat) && midnight()) X dmg += d((int)mattk->damn, (int)mattk->damd); /* extra damage */ X X/* Next a cancellation factor */ X/* Use ctmp when the cancellation factor takes into account certain X * armor's special magic protection. Otherwise just use !mtmp->mcan. X */ X ctmp = !mtmp->mcan && X (!uarm || (rn2(3) >= objects[uarm->otyp].a_can) || !rn2(50)) X && (!uarmc || (rn2(3) >= objects[uarmc->otyp].a_can) || !rn2(50)); X X/* Now, adjust damages via resistances or specific attacks */ X switch(mattk->adtyp) { X case AD_PHYS: X if(mattk->aatyp == AT_HUGS X#ifdef POLYSELF X && !sticks(uasmon) X#endif X ) { X if(!u.ustuck && rn2(2)) { X u.ustuck = mtmp; X kludge("%s grabs you!", Monnam(mtmp)); X } else if(u.ustuck == mtmp) X You("are being %s.", X#ifdef GOLEMS X (mtmp->data == &mons[PM_ROPE_GOLEM]) X ? "choked" : X#endif /* GOLEMS */ X "crushed"); X X } else { /* hand to hand weapon */ X hitmsg(mtmp,mattk->aatyp); X if(mattk->aatyp == AT_WEAP && otmp) { X dmg += dmgval(otmp, uasmon); X if (dmg <= 0) dmg = 1; X#ifdef NAMED_ITEMS X if (spec_ability(otmp, SPFX_DRLI) X# ifdef POLYSELF X && !resists_drli(uasmon) X# endif X ) { X pline("The %s blade drains your life!", X Hallucination ? hcolor() : black); X losexp(); X } X#endif X#ifdef POLYSELF X if (u.mh > 1 && u.mh > ((u.uac>0) ? dmg : dmg+u.uac) && X (u.umonnum==PM_BLACK_PUDDING X || u.umonnum==PM_BROWN_PUDDING)) { X /* This redundancy necessary because you have to X * take the damage _before_ being cloned. X */ X if (u.uac < 0) dmg += u.uac; X if (dmg < 1) dmg = 1; X u.mh -= dmg; X flags.botl = 1; X dmg = 0; X if(cloneu()) X kludge("You divide as %s hits you!",mon_nam(mtmp)); X } X urustm(mtmp, otmp); X#endif X } X } X break; X case AD_DISE: X hitmsg(mtmp, mattk->aatyp); X You("feel very sick."); X make_sick((long)rn1(25-ACURR(A_CON),15),FALSE); X u.usick_cause = mdat->mname; X break; X case AD_FIRE: X hitmsg(mtmp,mattk->aatyp); X if(ctmp && rn2(2)) { X pline("You're on fire!"); X if (Fire_resistance) { X pline("The fire doesn't feel hot!"); X dmg = 0; X } X if(mtmp->m_lev > rn2(20)) X destroy_item(SCROLL_SYM, AD_FIRE); X if(mtmp->m_lev > rn2(20)) X destroy_item(POTION_SYM, AD_FIRE); X#ifdef SPELLS X if(mtmp->m_lev > rn2(25)) X destroy_item(SPBOOK_SYM, AD_FIRE); X#endif X } X break; X case AD_COLD: X hitmsg(mtmp,mattk->aatyp); X if(ctmp && rn2(2)) { X pline("You're covered in frost!"); X if (Cold_resistance) { X pline("The frost doesn't seem cold!"); X dmg = 0; X } X if(mtmp->m_lev > rn2(20)) X destroy_item(POTION_SYM, AD_COLD); X } X break; X case AD_ELEC: X hitmsg(mtmp,mattk->aatyp); X if(ctmp && rn2(2)) { X You("get zapped!"); X if (Shock_resistance) { X pline("The zap doesn't shock you!"); X dmg = 0; X } X if(mtmp->m_lev > rn2(20)) X destroy_item(WAND_SYM, AD_ELEC); X if(mtmp->m_lev > rn2(20)) X destroy_item(RING_SYM, AD_ELEC); X } X break; X case AD_SLEE: X hitmsg(mtmp,mattk->aatyp); X if(ctmp && multi >= 0 && !rn2(5)) { X if (Sleep_resistance) break; X nomul(-rnd(10)); X if (Blind) You("are put to sleep!"); X else You("are put to sleep by %s!",mon_nam(mtmp)); X } X break; X case AD_DRST: X ptmp = A_STR; X goto dopois; X case AD_DRDX: X ptmp = A_DEX; X goto dopois; X case AD_DRCO: X ptmp = A_CON; Xdopois: X hitmsg(mtmp,mattk->aatyp); X if(ctmp && !rn2(8)) { X Sprintf(buf, "%s's %s", X Hallucination ? rndmonnam() : mdat->mname, X (mattk->aatyp == AT_BITE) ? "bite" : "sting"); X poisoned(buf, ptmp, mdat->mname); X } X break; X case AD_PLYS: X hitmsg(mtmp, mattk->aatyp); X if(ctmp && multi >= 0 && !rn2(3)) { X if (Blind) You("are frozen!"); X else You("are frozen by %s!", mon_nam(mtmp)); X nomul(-rnd(10)); X } X break; X case AD_DRLI: X hitmsg(mtmp, mattk->aatyp); X if (ctmp && !rn2(3) X#ifdef POLYSELF X && !resists_drli(uasmon) X#endif X#ifdef NAMED_ITEMS X && !defends(AD_DRLI, uwep) X#endif X ) losexp(); X break; X case AD_LEGS: X { register long side = rn2(2) ? RIGHT_SIDE : LEFT_SIDE; X if (mtmp->mcan) { X pline("%s nuzzles against your %s %s!", Monnam(mtmp), X (side == RIGHT_SIDE) ? "right" : "left", X body_part(LEG)); X } else { X if (uarmf) { X pline("%s scratches your %s boot!", Monnam(mtmp), X (side == RIGHT_SIDE) ? "right" : "left"); X break; X } X pline("%s pricks your %s %s!", Monnam(mtmp), X (side == RIGHT_SIDE) ? "right" : "left", X body_part(LEG)); X set_wounded_legs(side, rnd(60-ACURR(A_DEX))); X } X break; X } X case AD_STON: /* at present only a cockatrice */ X hitmsg(mtmp,mattk->aatyp); X if(!rn2(3) && !Stoned) { X if (mtmp->mcan) { X if (flags.soundok) X You("hear a cough from %s!", mon_nam(mtmp)); X } else { X if (flags.soundok) X You("hear %s's hissing!", mon_nam(mtmp)); X if((!rn2(10) || X (flags.moonphase == NEW_MOON && X !carrying(DEAD_LIZARD))) X#ifdef POLYSELF X && !resists_ston(uasmon) X#endif X ) { X Stoned = 5; X return(1); X /* You("turn to stone..."); */ X /* done_in_by(mtmp); */ X } X } X } X break; X case AD_STCK: X hitmsg(mtmp,mattk->aatyp); X if(ctmp && !u.ustuck X#ifdef POLYSELF X && !sticks(uasmon) X#endif X ) u.ustuck = mtmp; X break; X case AD_WRAP: X if(ctmp X#ifdef POLYSELF X && !sticks(uasmon) X#endif X ) { X if(!u.ustuck && !rn2(10)) { X pline("%s swings itself around you!", X Monnam(mtmp)); X u.ustuck = mtmp; X } else if(u.ustuck == mtmp) { X if (is_pool(mtmp->mx,mtmp->my) X#ifdef POLYSELF X && !is_swimmer(uasmon) X#endif X ) { X pline("%s drowns you...", Monnam(mtmp)); X done("drowned"); X } else if(mattk->aatyp == AT_HUGS) X You("are being crushed."); X } else dmg = 0; X } else dmg = 0; X break; X case AD_WERE: X hitmsg(mtmp,mattk->aatyp); X#ifdef POLYSELF X if (ctmp && !rn2(4) && u.ulycn == -1 X# ifdef NAMED_ITEMS X && !defends(AD_WERE,uwep) X# endif X ) { X You("feel feverish."); X u.ulycn = monsndx(mdat); X } X#endif X break; X case AD_SGLD: X hitmsg(mtmp,mattk->aatyp); X#ifdef POLYSELF X if (u.usym == mdat->mlet) break; X#endif X if(!mtmp->mcan) stealgold(mtmp); X break; X X case AD_SITM: /* for now these are the same */ X case AD_SEDU: X#ifdef POLYSELF X if (dmgtype(uasmon, AD_SEDU) X# ifdef SEDUCE X || dmgtype(uasmon, AD_SSEX) X# endif X ) { X if (mtmp->minvent) X pline("%s brags about the goods some dungeon explorer provided.", X Monnam(mtmp)); X else X pline("%s makes some remarks about how difficult theft is lately.", X Monnam(mtmp)); X rloc(mtmp); X } else X#endif X if(mtmp->mcan) { X if (!Blind) { X pline("%s tries to %s you, but you seem %s.", X Amonnam(mtmp, "plain"), X flags.female ? "charm" : "seduce", X flags.female ? "unaffected" : "uninterested"); X } X if(rn2(3)) rloc(mtmp); X } else if(steal(mtmp)) { X rloc(mtmp); X mtmp->mflee = 1; X } X break; X#ifdef SEDUCE X case AD_SSEX: X if(!mtmp->mcan && !mtmp->minvis) doseduce(mtmp); X break; X#endif X case AD_SAMU: X hitmsg(mtmp,mattk->aatyp); X /* when the Wiz hits, 1/20 steals the amulet */ X if (!carrying(AMULET_OF_YENDOR)) break; X if (!rn2(20)) stealamulet(mtmp); X break; X X case AD_TLPT: X hitmsg(mtmp,mattk->aatyp); X if(ctmp) { X if(flags.verbose) X Your("position suddenly seems very uncertain!"); X tele(); X } X break; X case AD_RUST: X hitmsg(mtmp,mattk->aatyp); X if (mtmp->mcan) break; X#ifdef POLYSELF X#ifdef GOLEMS X if (u.umonnum == PM_IRON_GOLEM) { X You("rust!"); X rehumanize(); X break; X } X#endif /* GOLEMS */ X#endif X /* What the following code does: it keeps looping until it X * finds a target for the rust monster. X * Head, feet, etc... not covered by metal, or covered by X * rusty metal, are not targets. However, your body always X * is, no matter what covers it. X */ X getbronze = (mdat == &mons[PM_BLACK_PUDDING] && X uarm->otyp == BRONZE_PLATE_MAIL); X while (1) { X switch(rn2(5)) { X case 0: X if (!rust_dmg(uarmh, "helmet", 1, FALSE)) continue; X break; X case 1: X if (uarmc) break; X /* Note the difference between break and continue; X * break means it was hit and didn't rust; continue X * means it wasn't a target and though it didn't rust X * something else did. X */ X if (getbronze) X (void)rust_dmg(uarm, "bronze armor", 3, TRUE); X else X (void)rust_dmg(uarm, "armor", 1, TRUE); X break; X case 2: X if (!rust_dmg(uarms, "shield", 1, FALSE)) continue; X break; X case 3: X if (!rust_dmg(uarmg, "metal gauntlets", 1, FALSE)) X continue; X break; X case 4: X if (!rust_dmg(uarmf, "metal boots", 1, FALSE)) continue; X break; X } X break; /* Out of while loop */ X } X break; X case AD_DCAY: X hitmsg(mtmp,mattk->aatyp); X if (mtmp->mcan) break; X#ifdef POLYSELF X#ifdef GOLEMS X if (u.umonnum == PM_WOOD_GOLEM || X u.umonnum == PM_LEATHER_GOLEM) { X You("rot!"); X rehumanize(); X break; X } X#endif /* GOLEMS */ X#endif X while (1) { X switch(rn2(5)) { X case 0: X if (!rust_dmg(uarmh, "leather helmet", 2, FALSE)) X continue; X break; X case 1: X if (uarmc) break; X (void)rust_dmg(uarm, "leather armor", 2, TRUE); X break; X case 2: X if (!rust_dmg(uarms, "wooden shield", 2, FALSE)) X continue; X break; X case 3: X if (!rust_dmg(uarmg, "gloves", 2, FALSE)) continue; X break; X case 4: X if (!rust_dmg(uarmf, "boots", 2, FALSE)) continue; X break; X } X break; /* Out of while loop */ X } X break; X case AD_HEAL: X if(!uwep X#ifdef SHIRT X && !uarmu X#endif X && !uarm && !uarmh && !uarms && !uarmg && !uarmc && !uarmf) { X kludge("%s hits! (I hope you don't mind.)", Monnam(mtmp)); X#ifdef POLYSELF X if (u.mtimedone) { X u.mh += rnd(7); X if(!rn2(7)) u.mhmax++; X if(u.mh > u.mhmax) u.mh = u.mhmax; X if(u.mh == u.mhmax && !rn2(50)) mongone(mtmp); X } else { X#endif X u.uhp += rnd(7); X if(!rn2(7)) u.uhpmax++; X if(u.uhp > u.uhpmax) u.uhp = u.uhpmax; X if(u.uhp == u.uhpmax && !rn2(50)) mongone(mtmp); X#ifdef POLYSELF X } X#endif X flags.botl = 1; X if(!rn2(50)) rloc(mtmp); X dmg = 0; X } else X if(pl_character[0] == 'H') { X if (flags.soundok && !(moves % 5)) X pline("'Doc, I can't help you unless you cooperate.'"); X dmg = 0; X } else hitmsg(mtmp,mattk->aatyp); X break; X case AD_CURS: X hitmsg(mtmp,mattk->aatyp); X if(!night() && mdat == &mons[PM_GREMLIN]) break; X if(!mtmp->mcan && !rn2(10)) { X if (flags.soundok) X if (Blind) You("hear laughter."); X else pline("%s chuckles.", Monnam(mtmp)); X#ifdef POLYSELF X#ifdef GOLEMS X if (u.umonnum == PM_CLAY_GOLEM) { X pline("Some writing vanishes from your head!"); X rehumanize(); X break; X } X#endif /* GOLEMS */ X#endif X attrcurse(); X } X break; X case AD_STUN: X hitmsg(mtmp,mattk->aatyp); X if(!mtmp->mcan && !rn2(4)) { X make_stunned(HStun + dmg, TRUE); X dmg /= 2; X } X break; X case AD_ACID: X hitmsg(mtmp,mattk->aatyp); X if(!mtmp->mcan && !rn2(3)) X#ifdef POLYSELF X if (resists_acid(uasmon)) { X pline("You're covered in acid, but it seems harmless."); X dmg = 0; X } else X#endif X pline("You're covered in acid! It burns!"); X else dmg = 0; X break; X case AD_SLOW: X hitmsg(mtmp,mattk->aatyp); X if(!ctmp && (Fast & (INTRINSIC|TIMEOUT)) && !rn2(4)) { X Fast &= ~(INTRINSIC|TIMEOUT); X You("feel yourself slowing down."); X } X break; X case AD_DREN: X hitmsg(mtmp,mattk->aatyp); X#ifdef SPELLS X if(!ctmp && !rn2(4)) drain_en(dmg); X#endif X dmg = 0; X break; X case AD_CUSS: X if(flags.soundok && !rn2(3)) cuss(mtmp); X dmg = 0; X break; X#ifdef HARD /* a non-gaze AD_CONF exists only for one of the demons */ X case AD_CONF: X hitmsg(mtmp,mattk->aatyp); X if(!mtmp->mcan && !rn2(4) && !mtmp->mspec_used) { X mtmp->mspec_used += (dmg + rn2(6)); X if(Confusion) X You("are getting even more confused."); X else You("are getting confused."); X make_confused(HConfusion + dmg, FALSE); X } X#endif X /* fall through to next case */ X default: dmg = 0; X break; X } X if(u.uhp < 1) done_in_by(mtmp); X X/* Negative armor class reduces damage done instead of fully protecting X * against hits. X */ X if (dmg && u.uac < 0) { X dmg -= rnd(-u.uac); X if (dmg < 1) dmg = 1; X } X X if(dmg) mdamageu(mtmp, dmg); X X#ifdef POLYSELF X res = passiveum(olduasmon, mtmp); X stop_occupation(); X return res; X#else X stop_occupation(); X return 1; X#endif X} X Xstatic Xint Xgulpmu(mtmp, mattk) /* monster swallows you, or damage if u.uswallow */ X register struct monst *mtmp; X register struct attack *mattk; X{ X int tmp = d((int)mattk->damn, (int)mattk->damd); X int tim_tmp; X#ifdef WALKIES X int i; X#endif X X if(!u.uswallow) { /* swallow him */ X levl[mtmp->mx][mtmp->my].mmask = 0; X mtmp->mx = u.ux; X mtmp->my = u.uy; X levl[mtmp->mx][mtmp->my].mmask = 1; X u.ustuck = mtmp; X pmon(mtmp); X kludge("%s engulfs you!", Monnam(mtmp)); X#ifdef WALKIES X if((i = number_leashed()) > 0) { X pline("The leash%s snap%s loose...", X (i > 1) ? "es" : "", X (i > 1) ? "" : "s"); X unleash_all(); X } X#endif X#ifdef POLYSELF X if (u.umonnum==PM_COCKATRICE) { X kludge("%s turns to stone!", Monnam(mtmp)); X stoned = 1; X xkilled(mtmp, 0); X return 2; X } X#endif X more(); X seeoff(1); X u.uswallow = 1; X /*assume that u.uswldtim always set >=0*/ X u.uswldtim = (tim_tmp = X (-u.uac + 10 + rnd(25 - (int)mtmp->m_lev)) >> 1) > 0 ? X tim_tmp : 0; X swallowed(1); X } else { X X if(mtmp != u.ustuck) return(0); X switch(mattk->adtyp) { X X case AD_DGST: X if(!u.uswldtim) { /* a3 *//*no cf unsigned <=0*/ X kludge("%s totally digests you!", Monnam(mtmp)); X tmp = u.uhp; X } else { X kludge("%s digests you!", Monnam(mtmp)); X } X break; X case AD_PHYS: X You("are pummeled with debris!"); X break; X case AD_ACID: X#ifdef POLYSELF X if (resists_acid(uasmon)) { X You("are covered with a seemingly harmless goo."); X tmp = 0; X } else X#endif X if (Hallucination) pline("Ouch! You've been slimed!"); X else You("are covered in slime! It burns!!!"); X break; X case AD_BLND: X if(!Blind) { X You("can't see in here!"); X make_blinded((long)tmp,FALSE); X } else make_blinded(Blinded+1,FALSE); /* keep him blind until disgorged */ X tmp = 0; X break; X case AD_ELEC: X if(!mtmp->mcan && rn2(2)) { X pline("The air around you crackles with electricity."); X if (Shock_resistance) { X shieldeff(u.ux, u.uy); X You("seem unhurt."); X#if defined(POLYSELF) && defined(GOLEMS) X ugolemeffects(AD_ELEC,tmp); X#endif X tmp = 0; X } X } else tmp = 0; X break; X case AD_COLD: X if(!mtmp->mcan && rn2(2)) { X if (Cold_resistance) { X shieldeff(u.ux, u.uy); X You("feel mildly chilly."); X#if defined(POLYSELF) && defined(GOLEMS) X ugolemeffects(AD_COLD,tmp); X#endif X tmp = 0; X } else You("are freezing to death!"); X } else tmp = 0; X break; X case AD_FIRE: X if(!mtmp->mcan && rn2(2)) { X if (Fire_resistance) { X shieldeff(u.ux, u.uy); X You("feel mildly hot."); X#if defined(POLYSELF) && defined(GOLEMS) X ugolemeffects(AD_FIRE,tmp); X#endif X tmp = 0; X } else You("are burning to a crisp!"); X } else tmp = 0; X break; X#ifdef HARD X case AD_DISE: X if (!Sick) You("feel very sick."); X make_sick(Sick + (long)rn1(25-ACURR(A_CON),15),FALSE); X u.usick_cause = mtmp->data->mname; X break; X#endif X default: tmp = 0; X break; X } X } X X mdamageu(mtmp, tmp); X if(u.uswldtim) --u.uswldtim; X if(!u.uswldtim X#ifdef POLYSELF X || u.umonnum==PM_COCKATRICE X#endif X ) { X#ifdef POLYSELF X if (u.umonnum == PM_COCKATRICE) { X kludge("%s very hurriedly regurgitates you!", X Monnam(mtmp)); X u.uswldtim = 0; X } else { X#endif X You("get regurgitated!"); X if(flags.verbose) X kludge("Obviously %s doesn't like your taste.", X mon_nam(mtmp)); X#ifdef POLYSELF X } X#endif X regurgitates(mtmp); X } X return(1); X} X Xstatic Xint Xexplmu(mtmp, mattk) /* monster explodes in your face */ X register struct monst *mtmp; X register struct attack *mattk; X{ X register int tmp = d((int)mattk->damn, (int)mattk->damd); X X if(mtmp->mcan) return(0); X if(!Blind) kludge("%s explodes!", Monnam(mtmp)); X else pline("It explodes!"); X X switch(mattk->adtyp) { X case AD_COLD: X if(Cold_resistance) { X You("seem unaffected by it."); X#if defined(POLYSELF) && defined(GOLEMS) X ugolemeffects(AD_COLD,tmp); X#endif X tmp = 0; X } else { X if(ACURR(A_DEX) > rnd(20)) { X if (!flags.verbose) X You("are caught in the blast!"); X } else { X You("duck the blast..."); X tmp /= 2; X } X } X break; X case AD_BLND: X if(!Blind X#ifdef POLYSELF X && u.usym != S_YLIGHT X#endif X ) { X You("are blinded by a blast of light!"); X make_blinded((long)tmp,FALSE); X } X tmp = 0; X break; X default: break; X } X mdamageu(mtmp, tmp); X mondead(mtmp); X return(2); /* it dies */ X} X Xstatic Xint Xgazemu(mtmp, mattk) /* monster gazes at you */ X register struct monst *mtmp; X register struct attack *mattk; X{ X switch(mattk->adtyp) { X case AD_STON: X if (mtmp->mcan) { X You("notice that %s isn't all that ugly.",mon_nam(mtmp)); X break; X } X if (canseemon(mtmp)) { X You("look upon %s.", mon_nam(mtmp)); X#ifdef POLYSELF X if (resists_ston(uasmon)) { X pline("So what?"); X break; X } X#endif X You("turn to stone..."); X killer = mons[PM_MEDUSA].mname; X done("stoned"); X } X break; X case AD_CONF: X if(!mtmp->mcan && canseemon(mtmp) && mtmp->mcansee && X !mtmp->mspec_used && rn2(5)) { X int conf = d(3,4); X X mtmp->mspec_used += (conf + rn2(6)); X if(!Confusion) X pline("%s's gaze confuses you!", Monnam(mtmp)); X else X You("are getting more and more confused."); X make_confused(HConfusion + conf, FALSE); X } X break; X default: impossible("Gaze attack %d?", mattk->adtyp); X break; X } X return(1); X} X Xvoid Xmdamageu(mtmp, n) /* mtmp hits you for n points damage */ X register struct monst *mtmp; X register int n; X{ X#ifdef POLYSELF X if (u.mtimedone) { X u.mh -= n; X flags.botl = 1; X if (u.mh < 1) rehumanize(); X return; X } X#endif X u.uhp -= n; X flags.botl = 1; X if(u.uhp < 1) X done_in_by(mtmp); X} X X#ifdef POLYSELF Xstatic void Xurustm(mon, obj) Xregister struct monst *mon; Xregister struct obj *obj; X{ X boolean vis = cansee(mon->mx, mon->my); X X if (!mon || !obj) return; /* just in case */ X if (u.umonnum == PM_RUST_MONSTER && X objects[obj->otyp].oc_material == METAL && X obj->spe > -2) { X if(obj->rustfree) { X if (vis) X pline("The rust vanishes from %s's weapon!", X mon_nam(mon)); X } else if(obj->blessed && rn2(3)) { X if (vis) X pline("Somehow, %s's weapon is not affected!", X mon_nam(mon)); X } else { X if (vis) X pline("%s's %s!", Monnam(mon), aobjnam(obj,"corrode")); X obj->spe--; X } X } X} X#endif X X#ifdef SEDUCE Xvoid Xdoseduce(mon) Xregister struct monst *mon; X{ X register struct obj *ring; X boolean fem = (mon->data == &mons[PM_SUCCUBUS]); /* otherwise incubus */ X X if (fem == poly_gender() || poly_gender()==2) return; X X if (mon->mcan || mon->mspec_used) { X pline("%s acts as though %s has got a %sheadache.", X Blind ? "It" : Monnam(mon), Blind ? "it" : X fem ? "she" : "he", X mon->mcan ? "severe " : ""); X return; X } X X if (unconscious()) { X kludge("%s seems dismayed at your lack of response.", X Monnam(mon)); X return; X } X X if (Blind) pline("It caresses you..."); X else You("feel very attracted to %s.", mon_nam(mon)); X X for(ring = invent; ring; ring = ring->nobj) { X if (ring->otyp != RIN_ADORNMENT) continue; X if (fem) { X if (rn2(20) < ACURR(A_CHA)) { X pline("\"That %s looks pretty. May I have it?\" ", X xname(ring)); X makeknown(RIN_ADORNMENT); X if (yn() == 'n') continue; X } else pline("%s decides she'd like your %s, and takes it.", X Blind ? "She" : Monnam(mon), xname(ring)); X if (ring->known) makeknown(RIN_ADORNMENT); X if (ring==uleft || ring==uright) Ring_gone(ring); X if (ring==uwep) setuwep((struct obj *)0); X freeinv(ring); X mpickobj(mon,ring); X } else { X char buf[BUFSZ]; X X if (uleft && uright && uleft->otyp == RIN_ADORNMENT X && uright->otyp==RIN_ADORNMENT) X break; X if (ring==uleft || ring==uright) continue; X if (rn2(20) < ACURR(A_CHA)) { X pline("\"That %s looks pretty. Would you wear it for me?\" ", X xname(ring)); X makeknown(RIN_ADORNMENT); X if (yn() == 'n') continue; X } else { X pline("%s decides you'd look prettier wearing your %s,", X Blind ? "He" : Monnam(mon), xname(ring)); X pline("and puts it on your finger."); X } X makeknown(RIN_ADORNMENT); X if (!uright) { X pline("%s puts the %s on your right hand.", X Blind ? "He" : Monnam(mon), xname(ring)); X setworn(ring, RIGHT_RING); X } else if (!uleft) { X pline("%s puts the %s on your left hand.", X Blind ? "He" : Monnam(mon), xname(ring)); X setworn(ring, LEFT_RING); X } else if (uright && uright->otyp != RIN_ADORNMENT) { X Strcpy(buf, xname(uright)); X pline("%s replaces your %s with your %s.", X Blind ? "He" : Monnam(mon), buf, xname(ring)); X Ring_gone(uright); X setworn(ring, RIGHT_RING); X } else if (uleft && uleft->otyp != RIN_ADORNMENT) { X Strcpy(buf, xname(uleft)); X pline("%s replaces your %s with your %s.", X Blind ? "He" : Monnam(mon), buf, xname(ring)); X Ring_gone(uleft); X setworn(ring, LEFT_RING); X } else impossible("ring replacement"); X Ring_on(ring); X prinv(ring); X } X } X X pline("%s murmurs in your ear, while helping you undress.", X Blind ? (fem ? "She" : "He") : Monnam(mon)); X mayberem(uarmc, "cloak"); X if(!uarmc) X mayberem(uarm, "suit"); X mayberem(uarmf, "boots"); X mayberem(uarmg, "gloves"); X mayberem(uarms, "shield"); X#ifdef SHIRT X if(!uarmc && !uarm) X mayberem(uarmu, "shirt"); X#endif X X if (uarm || uarmc) { X pline("\"You're such a %s; I wish...\"", X flags.female ? "sweet lady" : "nice guy"); X rloc(mon); X return; X } X#define ALIGNLIM (5L + (moves/200L)) /* from pray.c */ X if (u.ualigntyp == U_CHAOTIC && u.ualign < ALIGNLIM) u.ualign++; X X /* by this point you have discovered mon's identity, blind or not... */ X pline("Time stands still while you and %s lie in each other's arms...", X mon_nam(mon)); X if (rn2(35) > ACURR(A_CHA) + ACURR(A_INT)) { X /* Don't bother with mspec_used here... it didn't get tired! */ X pline("%s seems to have enjoyed it more than you...", X Monnam(mon)); X#ifdef SPELLS X switch (rn2(5)) { X case 0: You("feel drained of energy."); X u.uen = 0; X u.uenmax -= rnd(10); X if (u.uenmax < 0) u.uenmax = 0; X break; X#else X switch (rnd(4)) { X#endif X case 1: You("are down in the dumps."); X adjattrib(A_CON, -1, TRUE); X flags.botl = 1; X break; X case 2: Your("senses are dulled."); X adjattrib(A_WIS, -1, TRUE); X flags.botl = 1; X break; X case 3: X#ifdef POLYSELF X if (resists_drli(uasmon)) X You("have a curious feeling..."); X else { X#endif X You("feel out of shape."); X losexp(); X#ifdef POLYSELF X } X#endif X break; X case 4: You("feel exhausted."); X losehp(5+rnd(10), "bout of exhaustion"); X break; X } X } else { X mon->mspec_used = rnd(100); /* monster is worn out */ X You("seem to have enjoyed it more than %s...", mon_nam(mon)); X#ifdef SPELLS X switch (rn2(5)) { X case 0: You("feel raised to your full potential."); X u.uen = (u.uenmax += rnd(5)); X break; X#else X switch (rnd(4)) { X#endif X case 1: You("feel good enough to do it again."); X adjattrib(A_CON, 1, TRUE); X flags.botl = 1; X break; X case 2: You("will always remember %s...", mon_nam(mon)); X adjattrib(A_WIS, 1, TRUE); X flags.botl = 1; X break; X case 3: pline("That was a very educational experience."); X pluslvl(); X break; X case 4: You("feel restored to health!"); X u.uhp = u.uhpmax; X#ifdef POLYSELF X if (u.mtimedone) u.mh = u.mhmax; X#endif X flags.botl = 1; X break; X } X } X X if (mon->mtame) /* don't charge */ ; X else if (rn2(20) < ACURR(A_CHA)) { X pline("%s demands that you pay %s, but you refuse...", X Monnam(mon), (fem ? "her" : "him")); X } X#ifdef POLYSELF X else if (u.umonnum == PM_LEPRECHAUN) X pline("%s tries to take your money, but fails...", X Monnam(mon)); X#endif X else { X long cost = (long)rnd( X (int)(u.ugold > 32767L ? 32767 : u.ugold) +10) + 500; X X if (mon->mpeaceful) { X cost /= 5; X if (!cost) cost=1; X } X if (cost > u.ugold) cost = u.ugold; X if (!cost) pline("%s says: \"It's on the house!\"", Monnam(mon)); X else { X pline("%s takes %ld Zorkmid%s for services rendered!", X Monnam(mon), cost, (cost==1) ? "" : "s"); X u.ugold -= cost; X mon->mgold += cost; X flags.botl = 1; X } X } X if (!rn2(25)) mon->mcan = 1; /* monster is worn out */ X rloc(mon); X} X Xstatic void Xmayberem(obj, str) Xregister struct obj *obj; Xchar *str; X{ X if (!obj || !obj->owornmask) return; X X if (rn2(20) < ACURR(A_CHA)) { X pline("\"Shall I remove your %s, %s?\" ", X str, X (!rn2(2) ? "lover" : !rn2(2) ? "dear" : "sweetheart")); X if (yn() == 'n') return; X } else pline("\"Take off your %s; %s.\"", str, X (obj == uarm) ? "let's get a little closer" : X (obj == uarmc) ? "it's in the way" : X (obj == uarmf) ? "let me rub your feet" : X (obj == uarmg) ? "they're too clumsy" : X#ifdef SHIRT X (obj == uarmu) ? "let me massage you" : X#endif X /* obj == uarmh */ X "so I can run my fingers through your hair"); X X if (obj == uarm) (void) Armor_off(); X else if (obj == uarmc) (void) Cloak_off(); X else if (obj == uarmf) (void) Boots_off(); X else if (obj == uarmg) (void) Gloves_off(); X else if (obj == uarmh) (void) Helmet_off(); X else setworn((struct obj *)0, obj->owornmask & W_ARMOR); X} X#endif /* SEDUCE */ X X#ifdef POLYSELF Xstatic int Xpassiveum(olduasmon,mtmp) Xstruct permonst *olduasmon; Xregister struct monst *mtmp; X{ X register struct permonst *mdat = mtmp->data; X int dam = 0; X X if (olduasmon->mattk[0].aatyp != AT_NONE) return 1; X X /* These affect the enemy even if you were "killed" (rehumanized) */ X switch(olduasmon->mattk[0].adtyp) { X case AD_ACID: X if (!rn2(2)) { X kludge("%s is splashed by your acid!", Monnam(mtmp)); X if(!resists_acid(mdat)) X dam = d((int)olduasmon->mlevel+1, X (int)olduasmon->mattk[0].damd); X else pline("%s is not affected.", Monnam(mtmp)); X } X break; X default: X break; X } X if (!u.mtimedone) return 1; X X /* These affect the enemy only if you are still a monster */ X if (rn2(3)) switch(uasmon->mattk[0].adtyp) { X case AD_PLYS: /* Floating eye */ X if (!mtmp->mblinded && rn2(3)) { X if (Blind) X pline("As a blind %s, you cannot defend yourself.", X uasmon->mname); X else { X pline("%s is frozen by your gaze!", Monnam(mtmp)); X mtmp->mfroz = 1; X } X } X break; X case AD_COLD: /* Brown mold or blue jelly */ X dam = d((int)uasmon->mlevel+1, (int)uasmon->mattk[0].damd); X if(resists_cold(mdat)) { X shieldeff(mtmp->mx, mtmp->my); X kludge("%s is mildly chilly.", Monnam(mtmp)); X#ifdef GOLEMS X golemeffects(mtmp, AD_COLD, dam); X#endif /* GOLEMS */ X dam = 0; X break; X } X kludge("%s is suddenly very cold!", Monnam(mtmp)); X u.mh += dam / 2; X if (u.mhmax < u.mh) u.mhmax = u.mh; X if (u.mhmax > ((uasmon->mlevel+1) * 8)) { X register struct monst *mon; X X if (mon = cloneu()) { X mon->mhpmax = u.mhmax /= 2; X if (Blind) X You("multiply from its heat!"); X else X You("multiply from %s's heat!", mon_nam(mtmp)); X } X } X break; X case AD_STUN: /* Yellow mold */ X if (!mtmp->mstun) { X mtmp->mstun = 1; X kludge("%s staggers...", Monnam(mtmp)); X } X break; X case AD_FIRE: /* Red mold */ X dam = d((int)uasmon->mlevel+1, (int)uasmon->mattk[0].damd); X if(resists_fire(mdat)) { X shieldeff(mtmp->mx, mtmp->my); X kludge("%s is mildly warm.", Monnam(mtmp)); X#ifdef GOLEMS X golemeffects(mtmp, AD_FIRE, dam); X#endif /* GOLEMS */ X dam = 0; X break; X } X kludge("%s is suddenly very hot!", Monnam(mtmp)); X } X X if((mtmp->mhp -= dam) <= 0) { X kludge("%s dies!", Monnam(mtmp)); X xkilled(mtmp,0); X return(2); X } X return 1; X} X X#include "edog.h" Xstruct monst * Xcloneu() X{ X register struct monst *mon; X register int nmlth = strlen(plname) + 1; X X if (u.mh <= 1) return(struct monst *)0; X uasmon->pxlth += sizeof(struct edog) + nmlth; X mon = makemon(uasmon, u.ux, u.uy); X uasmon->pxlth -= sizeof(struct edog) + nmlth; X mon->mxlth = sizeof(struct edog); X Strcpy(NAME(mon), plname); X mon->mnamelth = nmlth; X initedog(mon); X mon->m_lev = uasmon->mlevel; X mon->mhp = u.mh /= 2; X mon->mhpmax = u.mhmax; X return(mon); X} X#endif /* POLYSELF */ END_OF_FILE if test 42552 -ne `wc -c <'src/mhitu.c'`; then echo shar: \"'src/mhitu.c'\" unpacked with wrong size! fi # end of 'src/mhitu.c' fi echo shar: End of archive 3 \(of 38\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 38 archives. rm -f ark[1-9]isdone ark[1-9][0-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0